From: vsr Date: Thu, 9 Aug 2012 10:03:55 +0000 (+0000) Subject: Merge from V6_main_20120808 08Aug12 X-Git-Tag: V7_0_0~4 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=bd4e115a78b52e3fbc016e5e30bb0e19b2a9e7d6;p=modules%2Fsmesh.git Merge from V6_main_20120808 08Aug12 --- diff --git a/Makefile.am b/Makefile.am index 507a6f312..c887e3f82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 28/06/2001 @@ -28,8 +26,8 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am if SMESH_ENABLE_GUI ACLOCAL_AMFLAGS = -I adm_local/unix/config_files \ - -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \ + -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files else !SMESH_ENABLE_GUI @@ -39,17 +37,19 @@ else !SMESH_ENABLE_GUI -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files endif -SUBDIRS = idl adm_local resources src doc bin +SUBDIRS = idl adm_local resources src bin doc -DIST_SUBDIRS = idl adm_local resources src doc bin +DIST_SUBDIRS = idl adm_local resources src bin doc -DISTCLEANFILES = a.out aclocal.m4 configure +DISTCLEANFILES = a.out aclocal.m4 configure local-install.sh hack_libtool salomeinclude_DATA = SMESH_version.h EXTRA_DIST += \ build_configure \ clean_configure \ + build_cmake \ + build_cmake.bat \ LICENCE dist-hook: diff --git a/SMESH_version.h.in b/SMESH_version.h.in index d9b835afa..76a669881 100644 --- a/SMESH_version.h.in +++ b/SMESH_version.h.in @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_version.h // Author : Vadim SANDLER // Module : SALOME @@ -32,5 +33,6 @@ #define SMESH_VERSION_STR "@VERSION@" #define SMESH_VERSION @XVERSION@ +#define SMESH_DEVELOPMENT @VERSION_DEV@ #endif // __SMESH_VERSION_H__ diff --git a/adm_local/Makefile.am b/adm_local/Makefile.am index f35273fac..6d9ac170c 100644 --- a/adm_local/Makefile.am +++ b/adm_local/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS = unix +SUBDIRS = unix cmake_files diff --git a/adm_local/cmake_files/FindSMESH.cmake b/adm_local/cmake_files/FindSMESH.cmake new file mode 100644 index 000000000..edcba9d22 --- /dev/null +++ b/adm_local/cmake_files/FindSMESH.cmake @@ -0,0 +1,42 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SET(SMESH_CXXFLAGS -I${SMESH_ROOT_DIR}/include/salome) + +FIND_LIBRARY(GeomSelectionTools GeomSelectionTools ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MEFISTO2D MEFISTO2D ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MeshDriverDAT MeshDriverDAT ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MeshDriverMED MeshDriverMED ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MeshDriver MeshDriver ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MeshDriverSTL MeshDriverSTL ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MeshDriverUNV MeshDriverUNV ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SalomeIDLSMESH SalomeIDLSMESH ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMDS SMDS ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHClient SMESHClient ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHControls SMESHControls ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHDS SMESHDS ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHEngine SMESHEngine ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHFiltersSelection SMESHFiltersSelection ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHimpl SMESHimpl ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHObject SMESHObject ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESH SMESH ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(StdMeshersEngine StdMeshersEngine ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(StdMeshersGUI StdMeshersGUI ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(StdMeshers StdMeshers ${SMESH_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SMESHUtils SMESHUtils ${SMESH_ROOT_DIR}/lib/salome) diff --git a/adm_local/cmake_files/Makefile.am b/adm_local/cmake_files/Makefile.am new file mode 100644 index 000000000..59484d20f --- /dev/null +++ b/adm_local/cmake_files/Makefile.am @@ -0,0 +1,25 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +admlocal_cmakedir = $(admlocaldir)/cmake_files + +dist_admlocal_cmake_DATA = \ +FindSMESH.cmake diff --git a/adm_local/unix/Makefile.am b/adm_local/unix/Makefile.am index 5f6d5f753..0d5ee76b8 100644 --- a/adm_local/unix/Makefile.am +++ b/adm_local/unix/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + include $(top_srcdir)/adm_local/unix/make_common_starter.am SUBDIRS = config_files diff --git a/adm_local/unix/config_files/Makefile.am b/adm_local/unix/config_files/Makefile.am index 0ed70f5f8..938083baa 100644 --- a/adm_local/unix/config_files/Makefile.am +++ b/adm_local/unix/config_files/Makefile.am @@ -1,27 +1,24 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + include $(top_srcdir)/adm_local/unix/make_common_starter.am dist_admlocalm4_DATA = \ check_SMESH.m4 \ - check_f77.m4 \ - check_Platform.m4 + check_Platform.m4 diff --git a/adm_local/unix/config_files/check_Platform.m4 b/adm_local/unix/config_files/check_Platform.m4 index ff6606562..93c7267e7 100755 --- a/adm_local/unix/config_files/check_Platform.m4 +++ b/adm_local/unix/config_files/check_Platform.m4 @@ -1,24 +1,25 @@ -dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE dnl -dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl 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 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 You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + AC_DEFUN([CHECK_PLATFORM],[ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CPP])dnl diff --git a/adm_local/unix/config_files/check_SMESH.m4 b/adm_local/unix/config_files/check_SMESH.m4 index 4c0cdb6e4..9096571c1 100644 --- a/adm_local/unix/config_files/check_SMESH.m4 +++ b/adm_local/unix/config_files/check_SMESH.m4 @@ -1,24 +1,25 @@ -dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE dnl -dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl 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 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 You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + # Check availability of SMesh binary distribution # # Author : Nicolas REJNERI (OPEN CASCADE, 2003) diff --git a/adm_local/unix/config_files/check_cgal.m4 b/adm_local/unix/config_files/check_cgal.m4 new file mode 100644 index 000000000..2ec433615 --- /dev/null +++ b/adm_local/unix/config_files/check_cgal.m4 @@ -0,0 +1,101 @@ +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl + +AC_DEFUN([CHECK_CGAL],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_BOOST]) + +AC_CHECKING(for CGAL) + +AC_ARG_WITH(cgal, + [ --with-cgal=DIR root directory path to CGAL installation ], + [CGALHOME="$withval" + AC_MSG_RESULT("select $withval as path to CGAL") + ]) + +AC_SUBST(CGAL_INCLUDES) +AC_SUBST(CGAL_LIBS) +AC_SUBST(CGALHOME) + +CGAL_INCLUDES="" +CGAL_LIBS="" + +cgal_ok=no + +LOCAL_INCLUDES="" +LOCAL_LIBS="-lCGAL" + +if test "x$CGALHOME" != "xno"; then + if test "x$CGALHOME" == "xyes"; then + CGALHOME="" + fi + if test -z $CGALHOME + then + AC_MSG_WARN(undefined CGALHOME variable which specify CGAL library installation directory) + AC_PATH_PROG(BINDIR, cgal_create_cmake_script) + if test "x$BINDIR" != "x" ; then + CGALHOME=$BINDIR + CGALHOME=`echo ${CGALHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + CGALHOME=`echo ${CGALHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + fi + fi + if test ! -z $CGALHOME + then + cgal_ok=yes + LOCAL_INCLUDES="-I$CGALHOME/include" + if test "x$CGALHOME" != "x/usr"; then + LOCAL_LIBS="-L$CGALHOME/lib $LOCAL_LIBS" + fi + fi + +dnl check cgallib header + + # CPPFLAGS_old=$CPPFLAGS + # CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES -I$BOOSTDIR/include" + + # AC_CHECK_HEADER(algorithm.h,cgal_ok=yes ,cgal_ok=no) + + # CPPFLAGS=$CPPFLAGS_old +fi + +# if test "x$cgal_ok" = "xyes" +# then +# dnl check cgal library +# LIBS_old="$LIBS" +# LIBS="$LIBS $LOCAL_LIBS" +# AC_CHECK_LIB(cgns,cg_open,cgns_ok=yes,cgns_ok=no) +# LIBS="$LIBS_old" +# fi + +if test "x$cgal_ok" = "xyes" +then + CGAL_LIBS="$LOCAL_LIBS" + CGAL_INCLUDES="$LOCAL_INCLUDES" + CPPFLAGS="-DWITH_CGAL $CPPFLAGS" +fi + +AC_MSG_RESULT(for CGAL: $cgal_ok) + +AM_CONDITIONAL(WITH_CGAL, [test x"$cgal_ok" = xyes]) + +])dnl diff --git a/adm_local/unix/config_files/check_cgns.m4 b/adm_local/unix/config_files/check_cgns.m4 new file mode 100644 index 000000000..4e25e27c6 --- /dev/null +++ b/adm_local/unix/config_files/check_cgns.m4 @@ -0,0 +1,103 @@ +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl + +AC_DEFUN([CHECK_CGNS],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_HDF5])dnl + +AC_CHECKING(for CGNS) + +AC_ARG_WITH(cgns, + [ --with-cgns=DIR root directory path to CGNS installation ], + [CGNSHOME="$withval" + AC_MSG_RESULT("select $withval as path to CGNS") + ]) + +AC_SUBST(CGNS_INCLUDES) +AC_SUBST(CGNS_LIBS) + +CGNS_INCLUDES="" +CGNS_LIBS="" + +cgns_ok=no + +LOCAL_INCLUDES="" +LOCAL_LIBS="-lcgns $HDF5_LIBS" + +if test "x$CGNSHOME" != "xno"; then + if test "x$CGNSHOME" == "xyes"; then + CGNSHOME="" + fi + if test -z $CGNSHOME + then + AC_MSG_WARN(undefined CGNSHOME variable which specify CGNS library installation directory) + AC_PATH_PROG(BINDIR, cgnsversion) + if test "x$BINDIR" != "x" ; then + CGNSHOME=$BINDIR + CGNSHOME=`echo ${CGNSHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + CGNSHOME=`echo ${CGNSHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + fi + fi + if test ! -z $CGNSHOME + then + LOCAL_INCLUDES="-I$CGNSHOME/include" + if test "x$CGNSHOME" != "x/usr"; then + LOCAL_LIBS="-L$CGNSHOME/lib $LOCAL_LIBS" + fi + fi + +dnl check cgnslib header + + CPPFLAGS_old=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES" + + AC_CHECK_HEADER(cgnslib.h,cgns_ok=yes ,cgns_ok=no) + + CPPFLAGS=$CPPFLAGS_old +fi + +if test "x$cgns_ok" = "xyes" +then + +dnl check cgns library + + LIBS_old="$LIBS" + LIBS="$LIBS $LOCAL_LIBS" + AC_CHECK_LIB(cgns,cg_open,cgns_ok=yes,cgns_ok=no) + + LIBS="$LIBS_old" + +fi + +if test "x$cgns_ok" = "xyes" +then + CGNS_LIBS="$LOCAL_LIBS" + CGNS_INCLUDES="$LOCAL_INCLUDES" + CPPFLAGS="-DWITH_CGNS $CPPFLAGS" +fi + +AC_MSG_RESULT(for CGNS: $cgns_ok) + +AM_CONDITIONAL(WITH_CGNS, [test x"$cgns_ok" = xyes]) + +])dnl diff --git a/adm_local/unix/config_files/check_f77.m4 b/adm_local/unix/config_files/check_f77.m4 index e03c6c165..64d3288ab 100644 --- a/adm_local/unix/config_files/check_f77.m4 +++ b/adm_local/unix/config_files/check_f77.m4 @@ -1,23 +1,23 @@ -dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE dnl -dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl 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 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 You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl AC_DEFUN([CHECK_F77],[ diff --git a/adm_local/unix/config_files/check_padder.m4 b/adm_local/unix/config_files/check_padder.m4 new file mode 100644 index 000000000..ab30fecab --- /dev/null +++ b/adm_local/unix/config_files/check_padder.m4 @@ -0,0 +1,69 @@ +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl + +AC_DEFUN([CHECK_PADDER],[ +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([CHECK_CGAL]) + +AC_CHECKING(for PADDER) + +padder_ok=no + +AC_ARG_WITH(padder, + [ --with-padder=DIR root directory path to PADDER installation ], + [PADDERHOME="$withval" + AC_MSG_RESULT("select $withval as path to PADDER") + ]) + +if test "x$PADDERHOME" != "xno"; then + if test "x$PADDERHOME" == "xyes"; then + PADDERHOME="" + fi + if test -z $PADDERHOME + then + AC_MSG_WARN(undefined PADDERHOME variable which specify PADDER installation directory) + AC_PATH_PROG(BINDIR, padder.exe) + if test "x$BINDIR" != "x" ; then + PADDERHOME=$BINDIR + PADDERHOME=`echo ${PADDERHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + PADDERHOME=`echo ${PADDERHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + fi + fi + if test ! -z $PADDERHOME + then + AC_CHECK_FILE($PADDERHOME/padder.env,padder_ok=yes,padder_ok=no) + fi +fi + +if test "x$padder_ok" = "xyes" +then + CPPFLAGS="-DWITH_PADDER $CPPFLAGS" +fi + +AC_SUBST(PADDERHOME) + +AC_MSG_RESULT(for PADDER: $padder_ok) + +AM_CONDITIONAL(WITH_PADDER, [test x"$padder_ok" = xyes]) + +])dnl diff --git a/adm_local/unix/config_files/check_qwt.m4 b/adm_local/unix/config_files/check_qwt.m4 new file mode 100644 index 000000000..b15142068 --- /dev/null +++ b/adm_local/unix/config_files/check_qwt.m4 @@ -0,0 +1,187 @@ +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_QWT],[ +AC_REQUIRE([CHECK_QT])dnl +AC_REQUIRE([AC_LINKER_OPTIONS])dnl + +AC_CHECKING(for qwt) + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +qwt_ok=yes + +dnl where is qwt ? + +AC_ARG_WITH(qwt, + [ --with-qwt=DIR directory path to QWT installation ], + [QWTHOME="$withval" + AC_MSG_RESULT("select $withval as path to QWT") + ]) + +AC_ARG_WITH(qwt_inc, + [ --with-qwt_inc=DIR directory path to QWT includes ], + [QWT_INCDIR="$withval" + AC_MSG_RESULT("select $withval as path to QWT includes") + ]) + +libqwt_name=qwt +if test -z $QWTHOME; then + AC_MSG_RESULT(QWTHOME not defined) + AC_MSG_NOTICE(Trying native Qwt...) + exist_ok=no + if test "x$exist_ok" = "xno"; then + for d in /usr /usr/local ; do + for extension in qwt-qt4 qwt; do + AC_CHECK_FILE(${d}/lib${LIB_LOCATION_SUFFIX}/lib${extension}.so,exist_ok=yes,exist_ok=no) + if test "x$exist_ok" = "xyes"; then + QWTHOME=$d + AC_MSG_RESULT(lib${extension}.so detected in $d/lib) + libqwt_name=${extension} + dnl break, libqwt-qt4.so is choosen before libqwt.so since it is surely the Qt4 version. + break + fi + done + if test "x$exist_ok" = "xyes"; then + break + fi + done + fi + if test "x$exist_ok" = "xno"; then + for d in `echo $LD_LIBRARY_PATH | sed -e "s/:/ /g"` ; do + if test -f $d/libqwt.so ; then + AC_MSG_RESULT(libqwt.so detected in $d) + QWTHOME=$d + QWTHOME=`echo ${QWTHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"` + exist_ok=yes + break + fi + done + fi + if test "x$exist_ok" = "xyes"; then + if test -z $QWT_INCDIR; then + QWT_INCDIR=$QWTHOME"/include/qwt-qt4" + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=/usr/include/qwt + fi + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=$QWTHOME"/include" + fi + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=/usr/lib/qt4/include/qwt + fi + if test ! -f $QWT_INCDIR/qwt.h ; then + QWT_INCDIR=/usr/include/qwt-qt4 + fi + fi + else + qwt_ok=no + fi +else + AC_MSG_NOTICE(Trying Qwt from $QWTHOME ...) + if test -z $QWT_INCDIR; then + QWT_INCDIR="$QWTHOME/include" + fi +fi + +if test "x$qwt_ok" = xno -o ! -d "$QWTHOME" ; then + AC_MSG_RESULT(no) + AC_MSG_WARN(qwt not found) + qwt_ok=no +else + CPPFLAGS_old=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $QT_INCLUDES -I$QWT_INCDIR" + + AC_CHECK_HEADER(qwt.h,qwt_ok=yes,qwt_ok=no) + CPPFLAGS=$CPPFLAGS_old + + AC_MSG_CHECKING(include of qwt headers) + + if test "x$qwt_ok" = xno ; then + AC_MSG_RESULT(no) + AC_MSG_WARN(qwt not found) + else + AC_MSG_RESULT(yes) + QWT_INCLUDES=-I$QWT_INCDIR + fi + + # + # test Qwt libraries + # + if test "x$qwt_ok" = "xyes" ; then + AC_MSG_CHECKING(linking qwt library) + + LIBS_old=$LIBS + LIBS="$LIBS $QT_LIBS" + if test "x$QWTHOME" = "x/usr" ; then + LIBS="$LIBS -l${libqwt_name}" + else + LIBS="$LIBS -L$QWTHOME/lib -l${libqwt_name}" + fi + + CXXFLAGS_old=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $QT_INCLUDES $QWT_INCLUDES" + + AC_CACHE_VAL(salome_cv_lib_qwt,[ + AC_TRY_LINK( +#include +#include +, int n; + char **s; + QApplication a(n, s); + QwtPlot p; + p.resize( 600, 400 ); + p.show(); + a.exec();, + eval "salome_cv_lib_qwt=yes",eval "salome_cv_lib_qwt=no") + ]) + qwt_ok="$salome_cv_lib_qwt" + + if test "x$qwt_ok" = "xno" ; then + AC_MSG_RESULT(unable to link with qwt library) + AC_MSG_RESULT(QWTHOME environment variable may be wrong) + else + AC_MSG_RESULT(yes) + if test "x$QWTHOME" = "x/usr" ; then + QWT_LIBS=" -l${libqwt_name}" + else + QWT_LIBS="-L$QWTHOME/lib -l${libqwt_name}" + fi + fi + + LIBS=$LIBS_old + CXXFLAGS=$CXXFLAGS_old + fi +fi + +AC_SUBST(QWT_INCLUDES) +AC_SUBST(QWT_LIBS) + +AC_LANG_RESTORE + +AC_MSG_RESULT(for qwt: $qwt_ok) + +# Save cache +AC_CACHE_SAVE + +])dnl +dnl diff --git a/adm_local/unix/make_common_starter.am b/adm_local/unix/make_common_starter.am index 36ad8c3a7..295f19f81 100644 --- a/adm_local/unix/make_common_starter.am +++ b/adm_local/unix/make_common_starter.am @@ -1,24 +1,30 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 # -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +# ============================================================ +# The following is to avoid PACKAGE_... env variable +# redefinition compilation warnings +# ============================================================ # +AM_CXXFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h +AM_CPPFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h + # ============================================================ # This file defines the common definitions used in several # Makefile. This file must be included, if needed, by the file @@ -33,6 +39,12 @@ salomescriptdir = $(bindir) salomepythondir = $(pythondir)/salome salomepyexecdir = $(pyexecdir)/salome +# Root directory of the python packages of SMESH +smeshpypkgdir = $(salomepythondir)/salome/smesh + +# Directory for installing SALOME plugins files +salomepluginsdir = $(prefix)/share/salome/plugins/@MODULE_NAME@ + # Directory for installing idl files salomeidldir = $(prefix)/idl/salome diff --git a/bin/Makefile.am b/bin/Makefile.am index dc7848fe5..7e1eea667 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Guillaume Boulant (CSSI) # Module : SMESH @@ -28,5 +26,9 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am # non-distributed files nodist_salomescript_DATA = VERSION +# python files +dist_salomescript_PYTHON = \ + smesh_setenv.py + # distributed files dist_salomescript_SCRIPTS = diff --git a/bin/VERSION.in b/bin/VERSION.in index fa49d303f..de81461c8 100755 --- a/bin/VERSION.in +++ b/bin/VERSION.in @@ -1 +1,3 @@ -THIS IS SALOME - SMESH VERSION: @VERSION@ +[SALOME SMESH] : @VERSION@ +[DEVELOPMENT] : @VERSION_DEV@ +[DESCRIPTION] : SALOME Mesh module diff --git a/bin/smesh_setenv.py b/bin/smesh_setenv.py new file mode 100644 index 000000000..a58406c1e --- /dev/null +++ b/bin/smesh_setenv.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +import os, sys +from setenv import add_path, get_lib_dir, salome_subdir + +# ----------------------------------------------------------------------------- + +def set_env(args): + """Add to the PATH-variables modules specific paths""" + psep = os.pathsep + python_version="python%d.%d" % sys.version_info[0:2] + + + if not os.environ.has_key("SALOME_StdMeshersResources"): + os.environ["SALOME_StdMeshersResources"] \ + = os.path.join(os.environ["SMESH_ROOT_DIR"],"share",salome_subdir,"resources","smesh") + pass + + # find plugins + plugin_list = [] + resource_path_list = [] + for env_var in os.environ.keys(): + value = os.environ[env_var] + if env_var[-9:] == "_ROOT_DIR" and value: + plugin_root = value + plugin = env_var[:-9] # plugin name may have wrong case + + # look for NAMEOFPlugin.xml file among resource files + resource_dir = os.path.join(plugin_root,"share",salome_subdir,"resources",plugin.lower()) + if not os.access( resource_dir, os.F_OK ): continue + for resource_file in os.listdir( resource_dir ): + if not resource_file.endswith( ".xml") or \ + resource_file.lower() != plugin.lower() + ".xml": + continue + # use "resources" attribute of "meshers-group" as name of plugin in a right case + from xml.dom.minidom import parse + xml_doc = parse( os.path.join( resource_dir, resource_file )) + meshers_nodes = xml_doc.getElementsByTagName("meshers-group") + if not meshers_nodes or not meshers_nodes[0].hasAttribute("resources"): continue + plugin = meshers_nodes[0].getAttribute("resources") + if plugin in plugin_list: continue + + # add paths of plugin + plugin_list.append(plugin) + if not os.environ.has_key("SALOME_"+plugin+"Resources"): + resource_path = os.path.join(plugin_root,"share",salome_subdir,"resources",plugin.lower()) + os.environ["SALOME_"+plugin+"Resources"] = resource_path + resource_path_list.append( resource_path ) + add_path(os.path.join(plugin_root,get_lib_dir(),python_version, "site-packages",salome_subdir), "PYTHONPATH") + add_path(os.path.join(plugin_root,get_lib_dir(),salome_subdir), "PYTHONPATH") + + if sys.platform == "win32": + add_path(os.path.join(plugin_root,get_lib_dir(),salome_subdir), "PATH") + add_path(os.path.join(plugin_root,"bin",salome_subdir), "PYTHONPATH") + else: + add_path(os.path.join(plugin_root,get_lib_dir(),salome_subdir), "LD_LIBRARY_PATH") + add_path(os.path.join(plugin_root,"bin",salome_subdir), "PYTHONPATH") + add_path(os.path.join(plugin_root,"bin",salome_subdir), "PATH") + pass + pass + break + plugin_list.append("StdMeshers") + os.environ["SMESH_MeshersList"] = ":".join(plugin_list) + os.environ["SalomeAppConfig"] = os.environ["SalomeAppConfig"] + psep + psep.join(resource_path_list) + diff --git a/build_cmake b/build_cmake new file mode 100755 index 000000000..01bb2ac7f --- /dev/null +++ b/build_cmake @@ -0,0 +1,27 @@ +#!/bin/sh +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +CURRENT_DIR=`pwd` +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} +python $KERNEL_ROOT_DIR/salome_adm/cmake_files/am2cmake.py --smesh +status=$? +cd ${CURRENT_DIR} +exit $status diff --git a/build_cmake.bat b/build_cmake.bat new file mode 100644 index 000000000..890adcdff --- /dev/null +++ b/build_cmake.bat @@ -0,0 +1,20 @@ +@REM Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +@REM +@REM This library is free software; you can redistribute it and/or +@REM modify it under the terms of the GNU Lesser General Public +@REM License as published by the Free Software Foundation; either +@REM version 2.1 of the License. +@REM +@REM This library is distributed in the hope that it will be useful, +@REM but WITHOUT ANY WARRANTY; without even the implied warranty of +@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@REM Lesser General Public License for more details. +@REM +@REM You should have received a copy of the GNU Lesser General Public +@REM License along with this library; if not, write to the Free Software +@REM Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +@REM +@REM See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +@REM + +%PYTHONBIN% %KERNEL_ROOT_DIR%\salome_adm\cmake_files\am2cmake.py --smesh diff --git a/build_configure b/build_configure index d135d9e8d..ce47d8056 100755 --- a/build_configure +++ b/build_configure @@ -1,25 +1,26 @@ #!/bin/bash -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tool for updating list of .in file for the SALOME project # and regenerating configure script # Author : Marc Tajchman - CEA @@ -29,7 +30,6 @@ # ORIG_DIR=`pwd` CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` -SMESH_WITH_GUI="yes" ######################################################################## # Test if the KERNEL_ROOT_DIR is set correctly @@ -46,28 +46,6 @@ fi # exit #fi -for option -do - case $option in - -with-gui | --with-gui) - SMESH_WITH_GUI="yes" - break;; - -without-gui | --without-gui | -with-gui=no | --with-gui=no) - SMESH_WITH_GUI="no" - break;; - esac -done - -######################################################################## -# Test if the GUI_ROOT_DIR is set correctly - -if test ${SMESH_WITH_GUI} = yes; then - if test ! -d "${GUI_ROOT_DIR}"; then - echo "failed : GUI_ROOT_DIR variable is not correct !" - exit - fi -fi - ######################################################################## # Test if the MED_ROOT_DIR is set correctly @@ -89,61 +67,41 @@ cd ${CONF_DIR} ABS_CONF_DIR=`pwd` ####################################################################### -# Update configure.ac script: to set SMESH_WITH_GUI variable -sed -e s/SMESH_WITH_GUI=[a-z]*/SMESH_WITH_GUI=${SMESH_WITH_GUI}/g configure.ac > configure.tmp -mv -f configure.tmp configure.ac - -mkdir -p salome_adm/unix/config_files -#cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files/* salome_adm/unix/config_files -#cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/pythonbe.py salome_adm/unix - -cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/SALOMEconfig.h.in salome_adm/unix - -#cp -f ${GUI_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files -#cp -f ${MED_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files -#cp -f ${GEOM_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files - -# remove KERNEL deprecated configure files -#for deprecated in ac_cc_warnings.m4 ac_cxx_partial_specialization.m4 \ -# check_mico.m4 config.guess ltmain.sh ac_cxx_bool.m4 ltconfig ac_cxx_typename.m4 \ -# check_pthreads.m4 config.sub libtool.m4 ac_cxx_mutable.m4 missing -# do -# rm -f salome_adm/unix/config_files/${deprecated} -# done - # ____________________________________________________________________ # aclocal creates the aclocal.m4 file from the standard macro and the -# custom macro embedded in the directory salome_adm/unix/config_files -# and KERNEL config_files directory. +# custom macro embedded in the directory adm_local/unix/config_files, +# KERNEL salome_adm/unix/config_files, GEOM and MED adm_local/unix/config_files +# directories. # output: # aclocal.m4 # autom4te.cache (directory) echo "====================================================== aclocal" -if test ${SMESH_WITH_GUI} = yes; then +if test -d "${GUI_ROOT_DIR}"; then aclocal -I adm_local/unix/config_files \ -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ - -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \ - -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ - -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1 + -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \ + -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ + -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1 else aclocal -I adm_local/unix/config_files \ -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ - -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ - -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1 + -I ${MED_ROOT_DIR}/adm_local/unix/config_files \ + -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1 fi + # ____________________________________________________________________ # libtoolize creates some configuration files (ltmain.sh, # config.guess and config.sub). It only depends on the libtool # version. The files are created in the directory specified with the # AC_CONFIG_AUX_DIR() tag (see configure.ac). # output: -# salome_adm/unix/config_files/config.guess -# salome_adm/unix/config_files/config.sub -# salome_adm/unix/config_files/ltmain.sh -#echo "====================================================== libtoolize" +# adm_local/unix/config_files/config.guess +# adm_local/unix/config_files/config.sub +# adm_local/unix/config_files/ltmain.sh +echo "==================================================== libtoolize" libtoolize --force --copy --automake || exit 1 @@ -163,11 +121,11 @@ autoconf # AC_CONFIG_AUX_DIR() tag (see configure.ac). This step also # creates the Makefile.in files from the Makefile.am files. # output: -# salome_adm/unix/config_files/compile -# salome_adm/unix/config_files/depcomp -# salome_adm/unix/config_files/install-sh -# salome_adm/unix/config_files/missing -# salome_adm/unix/config_files/py-compile +# adm_local/unix/config_files/compile +# adm_local/unix/config_files/depcomp +# adm_local/unix/config_files/install-sh +# adm_local/unix/config_files/missing +# adm_local/unix/config_files/py-compile # Makefile.in (from Makefile.am) echo "====================================================== automake" diff --git a/clean_configure b/clean_configure index f57f7b3bf..09bfbd7bd 100755 --- a/clean_configure +++ b/clean_configure @@ -1,25 +1,23 @@ #!/bin/sh -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + rm -rf autom4te.cache aclocal.m4 configure make_config find . -name "*~" -print -exec rm {} \; find . -name "*.pyc" -print -exec rm {} \; @@ -30,6 +28,8 @@ find bin -name Makefile.in | xargs rm -f find doc -name Makefile.in | xargs rm -f find idl -name Makefile.in | xargs rm -f find resources -name Makefile.in | xargs rm -f -find salome_adm -name Makefile.in | xargs rm -f +find adm_local -name Makefile.in | xargs rm -f find src -name Makefile.in | xargs rm -f rm -f Makefile.in +cd adm_local/unix/config_files +rm -f config.* depcomp install-sh l*.m4 ltmain.sh missing py-compile diff --git a/configure.ac b/configure.ac index 4aeb847b6..65f1a6852 100644 --- a/configure.ac +++ b/configure.ac @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Author : Marc Tajchman (CEA) # Date : 28/06/2001 # Modified by : Patrick GOLDBRONN (CEA) @@ -26,14 +24,16 @@ # Modified by : Alexander BORODIN (OCN) - autotools usage # Created from configure.in.base # -AC_INIT([Salome2 Project SMESH module], [5.1.0], [webmaster.salome@opencascade.com], [SalomeSMESH]) -AC_CONFIG_AUX_DIR(salome_adm/unix/config_files) +AC_INIT([Salome2 Project SMESH module], [6.5.0], [webmaster.salome@opencascade.com], [SalomeSMESH]) +AC_CONFIG_AUX_DIR(adm_local/unix/config_files) AC_CANONICAL_HOST AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([-Wno-portability]) XVERSION=`echo $VERSION | awk -F. '{printf("0x%02x%02x%02x",$1,$2,$3)}'` AC_SUBST(XVERSION) +VERSION_DEV=1 +AC_SUBST(VERSION_DEV) # set up MODULE_NAME variable for dynamic construction of directories (resources, etc.) MODULE_NAME=smesh @@ -81,12 +81,13 @@ echo AC_PROG_MAKE_SET AC_PROG_INSTALL +AC_LOCAL_INSTALL dnl dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + pour les librairies dynamiques ! echo echo --------------------------------------------- -echo Coniguring production +echo Configuring production echo --------------------------------------------- echo AC_ENABLE_DEBUG(yes) @@ -107,7 +108,7 @@ 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='\${ROOT_BUILDDIR}'/salome_adm/unix/config_files/install-sh + INSTALL='\${ROOT_BUILDDIR}'/adm_local/unix/config_files/install-sh ;; esac @@ -166,7 +167,15 @@ dnl testing MPICH dnl --------------------------------------------- dnl -CHECK_MPICH +dnl CHECK_MPICH + +echo +echo --------------------------------------------- +echo testing MPI +echo --------------------------------------------- +echo + +CHECK_MPI echo echo --------------------------------------------- @@ -212,10 +221,6 @@ echo ENABLE_PTHREADS -SMESH_WITH_GUI=yes - -AM_CONDITIONAL(SMESH_ENABLE_GUI, [test "${SMESH_WITH_GUI}" = "yes"]) - if test "x${GUI_DISABLE_CORBA}" != "xyes" ; then echo echo --------------------------------------------- @@ -255,8 +260,34 @@ dnl CHECK_MICO fi +echo +echo --------------------------------------------- +echo Testing GUI +echo --------------------------------------------- +echo + +CHECK_GUI_MODULE + +gui_ok=no +if test "${SalomeGUI_need}" != "no" -a "${FullGUI_ok}" = "yes" ; then + gui_ok=yes +fi + +AM_CONDITIONAL(SMESH_ENABLE_GUI, [test "${gui_ok}" = "yes"]) + +if test "${SalomeGUI_need}" == "yes"; then + if test "${FullGUI_ok}" != "yes"; then + AC_MSG_WARN(For configure SMESH module necessary full GUI!) + fi +elif test "${SalomeGUI_need}" == "auto"; then + if test "${FullGUI_ok}" != "yes"; then + AC_MSG_WARN(Full GUI not found. Build will be done without GUI!) + fi +elif test "${SalomeGUI_need}" == "no"; then + echo Build without GUI option has been chosen +fi -if test "${SMESH_WITH_GUI}" = "yes"; then +if test "${gui_ok}" = "yes"; then echo echo --------------------------------------------- echo testing openGL @@ -275,33 +306,37 @@ if test "${SMESH_WITH_GUI}" = "yes"; then echo echo --------------------------------------------- - echo testing VTK + echo testing sip echo --------------------------------------------- echo - CHECK_VTK + CHECK_SIP echo echo --------------------------------------------- - echo Testing GUI + echo testing pyqt echo --------------------------------------------- echo - CHECK_SALOME_GUI + CHECK_PYQT echo echo --------------------------------------------- - echo Testing full GUI + echo Testing qwt 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 + CHECK_QWT fi +echo +echo --------------------------------------------- +echo testing VTK +echo --------------------------------------------- +echo + +CHECK_VTK + echo echo --------------------------------------------- echo testing HDF5 @@ -310,6 +345,14 @@ echo CHECK_HDF5 +echo +echo --------------------------------------------- +echo testing MED3 +echo --------------------------------------------- +echo + +CHECK_MED3 + echo echo --------------------------------------------- echo BOOST Library @@ -326,25 +369,28 @@ echo CHECK_CAS -if test "${SMESH_WITH_GUI}" = "yes"; then - echo echo --------------------------------------------- -echo Testing qwt +echo Testing html generators echo --------------------------------------------- echo -CHECK_QWT - -fi +CHECK_HTML_GENERATORS echo echo --------------------------------------------- -echo Testing html generators +echo testing sphinx echo --------------------------------------------- echo +CHECK_SPHINX -CHECK_HTML_GENERATORS +echo +echo --------------------------------------------- +echo testing libxm +echo --------------------------------------------- +echo +dnl Check the libxml that will be required to use the SALOME launcher +CHECK_LIBXML echo echo --------------------------------------------- @@ -372,6 +418,31 @@ CHECK_MED CHECK_PLATFORM +echo +echo --------------------------------------------- +echo Testing CGNS library +echo --------------------------------------------- +echo + +CHECK_CGNS + +echo +echo --------------------------------------------- +echo Testing PADDER library +echo --------------------------------------------- +echo + +CHECK_CGAL +CHECK_PADDER + +echo +echo --------------------------------------------- +echo Testing TBB library +echo --------------------------------------------- +echo + +CHECK_TBB + echo echo --------------------------------------------- echo Summary @@ -379,12 +450,13 @@ echo --------------------------------------------- echo echo Configure -if test "${SMESH_WITH_GUI}" = "yes"; then -variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok qwt_ok Kernel_ok Geom_ok Med_ok SalomeGUI_ok" -fi -if test "${SMESH_WITH_GUI}" = "no"; then -variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok" +if test "${gui_ok}" = "yes"; then + variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok cgns_ok tbb_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok qwt_ok Kernel_ok Geom_ok Med_ok gui_ok" +elif test "${SalomeGUI_need}" != "no"; then + variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok vtk_ok hdf5_ok cgns_ok tbb_ok med3_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok Kernel_ok Geom_ok Med_ok gui_ok" +else + variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok vtk_ok hdf5_ok cgns_ok tbb_ok med3_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok Kernel_ok Geom_ok Med_ok" fi for var in $variables @@ -397,6 +469,16 @@ echo echo "Default ORB : $DEFAULT_ORB" echo +echo "Optionnal products (for plugins):" +optional_vars="cgal_ok padder_ok" +for var in $optional_vars +do + printf " %10s : " `echo \$var | sed -e "s,_ok,,"` + eval echo \$$var +done + + + 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 @@ -414,6 +496,9 @@ dnl AM_CONDITIONAL(ENABLE_OCCVIEWER, [test "$DISABLE_OCCVIEWER" = no]) dnl AM_CONDITIONAL(ENABLE_VTKVIEWER, [test "$DISABLE_VTKVIEWER" = no]) dnl AM_CONDITIONAL(ENABLE_SALOMEOBJECT, [test "$DISABLE_SALOMEOBJECT" = no]) +dnl Build with SMESH cancel compute feature +AC_DEFINE(WITH_SMESH_CANCEL_COMPUTE) + echo echo --------------------------------------------- echo generating Makefiles and configure files @@ -425,49 +510,91 @@ echo # chmod +x ./bin/salome/*; \ #]) +AC_HACK_LIBTOOL +AC_CONFIG_COMMANDS([hack_libtool],[ +sed -i "s%^CC=\"\(.*\)\"%hack_libtool (){ \n\ + $(pwd)/hack_libtool \1 \"\$[@]\" \n\ +}\n\ +CC=\"hack_libtool\"%g" libtool +sed -i "s%\(\s*\)for searchdir in \$newlib_search_path \$lib_search_path \$sys_lib_search_path \$shlib_search_path; do%\1searchdirs=\"\$newlib_search_path \$lib_search_path \$sys_lib_search_path \$shlib_search_path\"\n\1for searchdir in \$searchdirs; do%g" libtool +sed -i "s%\(\s*\)searchdirs=\"\$newlib_search_path \$lib_search_path \(.*\)\"%\1searchdirs=\"\$newlib_search_path \$lib_search_path\"\n\1sss_beg=\"\"\n\1sss_end=\"\2\"%g" libtool +sed -i "s%\(\s*\)\(for searchdir in \$searchdirs; do\)%\1for sss in \$searchdirs; do\n\1 if ! test -d \$sss; then continue; fi\n\1 ssss=\$(cd \$sss; pwd)\n\1 if test \"\$ssss\" != \"\" \&\& test -d \$ssss; then\n\1 case \$ssss in\n\1 /usr/lib | /usr/lib64 ) ;;\n\1 * ) sss_beg=\"\$sss_beg \$ssss\" ;;\n\1 esac\n\1 fi\n\1done\n\1searchdirs=\"\$sss_beg \$sss_end\"\n\1\2%g" libtool +],[]) + # This list is initiated using autoscan and must be updated manually # when adding a new file .in to manage. When you execute # autoscan, the Makefile list is generated in the output file configure.scan. # This could be helpfull to update de configuration. AC_OUTPUT([ \ - ./salome_adm/unix/SALOMEconfig.h \ - ./adm_local/Makefile \ - ./adm_local/unix/Makefile \ - ./adm_local/unix/config_files/Makefile \ - ./bin/VERSION \ - ./bin/Makefile \ - ./SMESH_version.h \ - ./doc/Makefile \ - ./doc/salome/Makefile \ - ./doc/salome/gui/Makefile \ - ./doc/salome/gui/SMESH/Makefile \ - ./doc/salome/gui/SMESH/doxyfile \ - ./doc/salome/gui/SMESH/doxyfile_py \ - ./doc/salome/tui/Makefile \ - ./doc/salome/tui/doxyfile \ - ./src/Makefile \ - ./src/Controls/Makefile \ - ./src/Driver/Makefile \ - ./src/DriverDAT/Makefile \ - ./src/DriverMED/Makefile \ - ./src/DriverSTL/Makefile \ - ./src/DriverUNV/Makefile \ - ./src/MEFISTO2/Makefile \ - ./src/OBJECT/Makefile \ - ./src/SMDS/Makefile \ - ./src/SMESH/Makefile \ - ./src/SMESHClient/Makefile \ - ./src/SMESHDS/Makefile \ - ./src/SMESHFiltersSelection/Makefile \ - ./src/SMESHGUI/Makefile \ - ./src/SMESH_I/Makefile \ - ./src/SMESH_SWIG/Makefile \ - ./src/SMESH_SWIG_WITHIHM/Makefile \ - ./src/StdMeshers/Makefile \ - ./src/StdMeshersGUI/Makefile \ - ./src/StdMeshers_I/Makefile \ - ./resources/Makefile \ - ./resources/SMESHCatalog.xml \ - ./idl/Makefile \ + adm_local/Makefile \ + adm_local/cmake_files/Makefile \ + adm_local/unix/Makefile \ + adm_local/unix/config_files/Makefile \ + bin/VERSION \ + bin/Makefile \ + SMESH_version.h \ + doc/Makefile \ + doc/docutils/Makefile \ + doc/docutils/conf.py \ + doc/salome/Makefile \ + doc/salome/gui/Makefile \ + doc/salome/gui/SMESH/Makefile \ + doc/salome/gui/SMESH/doxyfile \ + doc/salome/gui/SMESH/doxyfile_py \ + doc/salome/gui/SMESH/static/header.html \ + doc/salome/gui/SMESH/static/header_py.html \ + doc/salome/tui/Makefile \ + doc/salome/tui/doxyfile \ + doc/salome/tui/static/header.html \ + src/Makefile \ + src/Controls/Makefile \ + src/Driver/Makefile \ + src/DriverDAT/Makefile \ + src/DriverMED/Makefile \ + src/DriverSTL/Makefile \ + src/DriverUNV/Makefile \ + src/DriverCGNS/Makefile \ + src/MEFISTO2/Makefile \ + src/OBJECT/Makefile \ + src/PluginUtils/Makefile \ + src/SMDS/Makefile \ + src/SMESH/Makefile \ + src/SMESHUtils/Makefile \ + src/SMESHClient/Makefile \ + src/SMESHDS/Makefile \ + src/SMESHFiltersSelection/Makefile \ + src/SMESHGUI/Makefile \ + src/SMESH_I/Makefile \ + src/SMESH_SWIG/Makefile \ + src/SMESH_SWIG_WITHIHM/Makefile \ + src/StdMeshers/Makefile \ + src/StdMeshersGUI/Makefile \ + src/StdMeshers_I/Makefile \ + src/SMESH_PY/Makefile \ + src/Tools/Makefile \ + src/Tools/MeshCut/Makefile \ + src/Tools/padder/Makefile \ + src/Tools/padder/meshjob/Makefile \ + src/Tools/padder/meshjob/idl/Makefile \ + src/Tools/padder/meshjob/impl/Makefile \ + src/Tools/padder/spadderpy/Makefile \ + src/Tools/padder/spadderpy/padder.cfg \ + src/Tools/padder/spadderpy/gui/Makefile \ + src/Tools/padder/spadderpy/plugin/Makefile \ + src/Tools/padder/spadderpy/plugin/envPlugins.sh \ + src/Tools/padder/resources/Makefile \ + src/Tools/padder/resources/appligen/Makefile \ + src/Tools/padder/resources/appligen/appligen.sh \ + src/Tools/padder/resources/appligen/config_appli.xml \ + src/Tools/padder/resources/padderexe/Makefile \ + src/Tools/padder/resources/padderexe/envPadder.sh \ + src/Tools/padder/unittests/Makefile \ + src/Tools/padder/unittests/autotest.sh \ + src/Tools/padder/doc/Makefile \ + src/Tools/padder/doc/doxyfile \ + resources/Makefile \ + resources/SMESHCatalog.xml \ + resources/SalomeApp.xml \ + idl/Makefile \ Makefile ]) diff --git a/doc/Makefile.am b/doc/Makefile.am index 1902d9d21..6d2dfb201 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 30/11/2001 @@ -26,7 +24,8 @@ # $Header$ # source path # -SUBDIRS = salome +SUBDIRS = salome docutils +#SUBDIRS = salome usr_docs: (cd salome && $(MAKE) $(AM_MAKEFLAGS) usr_docs) diff --git a/doc/docutils/Makefile.am b/doc/docutils/Makefile.am new file mode 100644 index 000000000..1775115ee --- /dev/null +++ b/doc/docutils/Makefile.am @@ -0,0 +1,97 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +pydocdir = $(docdir)/tui/SMESH/docutils + +RSTFILES = \ + index.rst \ + overview.rst \ + docapi.rst + +EXTRA_DIST += $(RSTFILES) + +SPHINXOPTS = +SOURCEDIR = $(srcdir) +SPHINXBUILD = sphinx-build +PAPEROPT_a4 = -D latex_paper_size=a4 +ALLSPHINXOPTS = -d doctrees $(PAPEROPT_a4) $(SPHINXOPTS) $(SOURCEDIR) + +if SMESH_ENABLE_GUI +SPHINX_PYTHONPATH = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(prefix)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(GUI_ROOT_DIR)/lib/salome:$(GUI_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(GUI_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages:$(OMNIORB_ROOT)/lib64/python$(PYTHON_VERSION)/site-packages +else !SMESH_ENABLE_GUI +SPHINX_PYTHONPATH = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(prefix)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages:$(OMNIORB_ROOT)/lib64/python$(PYTHON_VERSION)/site-packages +endif + +if SMESH_ENABLE_GUI +SPHINX_LD_LIBRARY_PATH = $(GUI_ROOT_DIR)/lib/salome:$(KERNEL_ROOT_DIR)/lib/salome:$(OMNIORB_ROOT)/lib +else !SMESH_ENABLE_GUI +SPHINX_LD_LIBRARY_PATH = $(KERNEL_ROOT_DIR)/lib/salome:$(OMNIORB_ROOT)/lib +endif + + +.PHONY: latex + +if SPHINX_IS_OK + +html/index.html:$(RSTFILES) + mkdir -p html doctrees + PYTHONPATH=$(SPHINX_PYTHONPATH):${PYTHONPATH} \ + LD_LIBRARY_PATH=$(SPHINX_LD_LIBRARY_PATH):${LD_LIBRARY_PATH} \ + $(SPHINXBUILD) -c $(top_builddir)/doc/docutils -W -b html $(ALLSPHINXOPTS) html + @echo + @echo "Build finished. The HTML pages are in html." + +else + +html/index.html: + @echo "Documentation for Python package not built. Sphinx was not present at configure time." + +endif + +latex: + mkdir -p latex doctrees + PYTHONPATH=$(SPHINX_PYTHONPATH):${PYTHONPATH} \ + LD_LIBRARY_PATH=$(SPHINX_LD_LIBRARY_PATH):${LD_LIBRARY_PATH} \ + $(SPHINXBUILD) -c $(top_builddir)/doc/docutils -W -b latex $(ALLSPHINXOPTS) latex + @echo + @echo "Build finished; the LaTeX files are in latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +install-data-local: html/index.html + test -z $(pydocdir) || mkdir -p $(DESTDIR)$(pydocdir) + if test -d "html"; then b=; else b="$(srcdir)/"; fi; \ + cp -rf $$b"html"/* $(pydocdir) ; \ + if test -f $$b"latex"/smeshpy.pdf; then cp -f $$b"latex"/smeshpy.pdf $(pydocdir) ; fi; + +uninstall-local: + -test -d $(pydocdir) && chmod -R +w $(pydocdir) && rm -rf $(pydocdir)/* + +clean-local: + -rm -rf html latex doctrees + if test -d "html"; then rm -rf html ; fi + +dist-hook: + -test -d html && cp -Rp html $(distdir) diff --git a/doc/docutils/conf.py.in b/doc/docutils/conf.py.in new file mode 100644 index 000000000..1aea4dc54 --- /dev/null +++ b/doc/docutils/conf.py.in @@ -0,0 +1,200 @@ +# -*- coding: iso-8859-1 -*- +# +# yacs documentation build configuration file, created by +# sphinx-quickstart on Fri Aug 29 09:57:25 2008. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed automatically). +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If your extensions are in another directory, add it here. If the directory +# is relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +#sys.path.append(os.path.abspath('.')) + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc'] + +# Uncomment the following line to build the links with Python documentation +# (you might need to set http_proxy environment variable for this to work) +#extensions += ['sphinx.ext.intersphinx'] + +# Intersphinx mapping to add links to modules and objects in the Python +# standard library documentation +intersphinx_mapping = {'http://docs.python.org': None} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +source_encoding = 'utf-8' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'SMESH python packages' +copyright = '2010 EDF R&D' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '@VERSION@' +# The full version, including alpha/beta/rc tags. +release = '@VERSION@' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = 'en' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directory, that shouldn't be searched +# for source files. +exclude_trees = ['.build','ref','images','CVS','.svn'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# Options for HTML output +# ----------------------- + +# The theme to use for HTML and HTML Help pages. Major themes that come with +# Sphinx are currently 'default' and 'sphinxdoc'. +html_theme = 'default' +#html_theme = 'nature' +#html_theme = 'agogo' +#html_theme = 'sphinxdoc' +#html_theme = 'omadoc' + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = ['themes'] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +html_use_modindex = False + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, the reST sources are included in the HTML build as _sources/. +html_copy_source = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'smeshpydoc' + + +# Options for LaTeX output +# ------------------------ + +# The paper size ('letter' or 'a4'). +latex_paper_size = 'a4' + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, document class [howto/manual]). +latex_documents = [ + ('index', 'smeshpy.tex', 'Documentation of the SMESH python packages', 'EDF R\&D', 'manual') +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = '@srcdir@/../salome/tui/images/head.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = True + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +latex_use_modindex = False diff --git a/doc/docutils/docapi.rst b/doc/docutils/docapi.rst new file mode 100644 index 000000000..b39c124dc --- /dev/null +++ b/doc/docutils/docapi.rst @@ -0,0 +1,17 @@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + Documentation of the programming interface (API) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +This section describes the python packages and modules of the +``salome.smesh`` python package. The main part is generated from the +code documentation included in source python files. + +:mod:`salome.smesh` -- Package containing the SMESH python utilities +==================================================================== + +:mod:`smeshstudytools` -- Tools to access SMESH objects in the study +-------------------------------------------------------------------- + +.. automodule:: salome.smesh.smeshstudytools + :members: diff --git a/doc/docutils/index.rst b/doc/docutils/index.rst new file mode 100644 index 000000000..4863e8288 --- /dev/null +++ b/doc/docutils/index.rst @@ -0,0 +1,10 @@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + Documentation of the SMESH python package +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +.. toctree:: + :maxdepth: 3 + + overview.rst + docapi.rst diff --git a/doc/docutils/overview.rst b/doc/docutils/overview.rst new file mode 100644 index 000000000..ce82cc812 --- /dev/null +++ b/doc/docutils/overview.rst @@ -0,0 +1,24 @@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +General presentation of the SMESH python package +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +The SMESH python package contains (today) helper functions to +manipulate mesh elements and interact with these elements. + +Note that these functions either encapsulate the python programming +interface of SMESH core (the CORBA or SWIG interface for example) or +extend existing utilities as the ``smesh.py`` module. + +The functions are distributed in the python package +``salome.smesh``. + +The specification of the programming interface of this package is +detailled in the part :doc:`Documentation of the programming interface +(API)` of this documentation. + +.. note:: + The main package ``salome`` contains other sub-packages that are + distributed with the other SALOME modules. For example, the KERNEL + module provides the python package ``salome.kernel`` and GEOM the + package ``salome.geom``. diff --git a/doc/salome/Makefile.am b/doc/salome/Makefile.am index 5a92861e5..8bf9f392d 100644 --- a/doc/salome/Makefile.am +++ b/doc/salome/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 30/11/2001 diff --git a/doc/salome/gui/Makefile.am b/doc/salome/gui/Makefile.am index 0e41ee5ff..9582cd97e 100644 --- a/doc/salome/gui/Makefile.am +++ b/doc/salome/gui/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : Makefile.in # Author : Vasily Rusyaev (Open Cascade NN) # Modified by : Alexander BORODIN (OCN) - autotools usage diff --git a/doc/salome/gui/SMESH/Makefile.am b/doc/salome/gui/SMESH/Makefile.am index a93b57ccb..cc3ddb251 100755 --- a/doc/salome/gui/SMESH/Makefile.am +++ b/doc/salome/gui/SMESH/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : Makefile.in # Author : Vasily Rusyaev (Open Cascade NN) # Modified by : Alexander BORODIN (OCN) - autotools usage @@ -26,48 +24,50 @@ # include $(top_srcdir)/adm_local/unix/make_common_starter.am -EXTRA_DIST += images input static +EXTRA_DIST += images input static/footer.html static/doxygen.css + +guidocdir = $(docdir)/gui/SMESH +guidoc_DATA = images/head.png + usr_docs: doxyfile_py doxyfile - echo "===========================================" ; \ - echo "Generating Python interface documentation"; \ - echo "===========================================" ; \ - $(DOXYGEN) doxyfile_py ; \ - echo "===========================================" ; \ - echo "Replacing smeshDC by smesh" ; \ - echo "===========================================" ; \ - files=`find smeshpy_doc -type f` ; \ - for filen in $${files} ; do \ - sed -e "s/\/smesh/g" -e "s/smesh\.smesh/smesh/g" \ - -e "s/smesh::smesh/smesh/g" $${filen} > $${filen}_ ; \ - mv -f $${filen}_ $${filen} ; \ - done ; \ - echo "===========================================" ; \ - echo "Generating GUI documentation" ; \ - echo "===========================================" ; \ - $(DOXYGEN) doxyfile ; + echo "===========================================" ; \ + echo "Replacing smeshDC by smesh" ; \ + echo "===========================================" ; \ + awk '/^class Mesh:/ { mesh_found=1 } // { if (mesh_found) {print $$0; next} } /^ +(def|#)/ { match( $$0, /^ +/); print substr( $$0, 1+RLENGTH ); next } /^class smeshDC/ { next } //' \ + $(top_srcdir)/src/SMESH_SWIG/smeshDC.py > ./smesh.py ; \ + echo "===========================================" ; \ + echo "Generating Python interface documentation"; \ + echo "===========================================" ; \ + $(DOXYGEN) doxyfile_py ; \ + echo "===========================================" ; \ + echo "Generating GUI documentation" ; \ + echo "===========================================" ; \ + $(DOXYGEN) doxyfile ; \ + rm -f ./smesh.py docs: usr_docs clean-local: - @for filen in `find . -maxdepth 1` ; do \ + @for filen in `find . -maxdepth 1` ; do \ case $${filen} in \ ./Makefile | ./doxyfile | ./doxyfile_py ) ;; \ - . | .. ) ;; \ + . | .. | ./static ) ;; \ *) echo "Removing $${filen}" ; rm -rf $${filen} ;; \ esac ; \ done ; install-data-local: usr_docs $(INSTALL) -d $(DESTDIR)$(docdir)/gui/SMESH - @for filen in `find . -maxdepth 1` ; do \ + @for filen in `find . -maxdepth 1` ; do \ case $${filen} in \ ./Makefile | ./doxyfile | ./doxyfile_py ) ;; \ ./doxyfile.bak | ./doxyfile_py.bak ) ;; \ - . | .. ) ;; \ + . | .. | ./static ) ;; \ *) echo "Installing $${filen}" ; cp -rp $${filen} $(DESTDIR)$(docdir)/gui/SMESH ;; \ esac ; \ - done ; + done ; \ + cp -rp $(srcdir)/images/head.png $(DESTDIR)$(docdir)/gui/SMESH/smeshpy_doc ; uninstall-local: rm -rf $(DESTDIR)$(docdir)/gui/SMESH diff --git a/doc/salome/gui/SMESH/doxyfile.in b/doc/salome/gui/SMESH/doxyfile.in index b084396ba..bceb23d55 100755 --- a/doc/salome/gui/SMESH/doxyfile.in +++ b/doc/salome/gui/SMESH/doxyfile.in @@ -1,28 +1,29 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = "Mesh Module Reference Manual v.@VERSION@" +PROJECT_NAME = "SALOME Mesh User's Guide" OUTPUT_DIRECTORY = . CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English @@ -37,10 +38,10 @@ WARNINGS = YES #--------------------------------------------------------------------------- #Input related options #--------------------------------------------------------------------------- -INPUT = @srcdir@/input +INPUT = @srcdir@/input @top_srcdir@/src/Tools/padder/doc/input FILE_PATTERNS = *.doc EXCLUDE = -IMAGE_PATH = @srcdir@/images +IMAGE_PATH = @srcdir@/images @top_srcdir@/src/Tools/padder/doc/images EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG #--------------------------------------------------------------------------- @@ -48,18 +49,25 @@ EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = . -HTML_HEADER = @srcdir@/static/header.html +HTML_HEADER = @builddir@/static/header.html HTML_FOOTER = @srcdir@/static/footer.html -#HTML_STYLESHEET = @srcdir@/static/doxygen.css +HTML_STYLESHEET = @srcdir@/static/doxygen.css TOC_EXPAND = YES DISABLE_INDEX = NO GENERATE_TREEVIEW = YES TREEVIEW_WIDTH = 300 +#--------------------------------------------------------------------------- +#SORT related options +#--------------------------------------------------------------------------- +SORT_GROUP_NAMES = NO + + #--------------------------------------------------------------------------- #LaTeX related option #--------------------------------------------------------------------------- GENERATE_LATEX = NO +EXTRA_PACKAGES = amsmath #--------------------------------------------------------------------------- #RTF related options @@ -69,4 +77,6 @@ GENERATE_RTF = NO #--------------------------------------------------------------------------- #External reference options #--------------------------------------------------------------------------- -TAGFILES = smeshpy_doc.tag=smeshpy_doc +TAGFILES = smeshpy_doc.tag=../SMESH/smeshpy_doc #rnv: 07.04.2011 Workaround for the doxygen 1.7.3: + #because it wrongly defines location of the html files for search. +SEARCHENGINE = YES diff --git a/doc/salome/gui/SMESH/doxyfile_py.in b/doc/salome/gui/SMESH/doxyfile_py.in index c35d4aaa7..19e21b96e 100755 --- a/doc/salome/gui/SMESH/doxyfile_py.in +++ b/doc/salome/gui/SMESH/doxyfile_py.in @@ -1,28 +1,29 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = "Mesh Module Reference Manual v.@VERSION@" +PROJECT_NAME = "SALOME Mesh User's Guide" OUTPUT_DIRECTORY = . CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English @@ -98,8 +99,8 @@ EXAMPLE_RECURSIVE = NO #--------------------------------------------------------------------------- #Input related options #--------------------------------------------------------------------------- -INPUT = @top_srcdir@/src/SMESH_SWIG -FILE_PATTERNS = smeshDC.py +INPUT = smesh.py @top_srcdir@/src/SMESH_SWIG/StdMeshersDC.py +FILE_PATTERNS = IMAGE_PATH = @srcdir@/images RECURSIVE = NO EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG @@ -109,11 +110,11 @@ EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = smeshpy_doc -HTML_HEADER = @srcdir@/static/header.html +HTML_HEADER = @builddir@/static/header_py.html HTML_FOOTER = @srcdir@/static/footer.html -#HTML_STYLESHEET = @srcdir@/static/doxygen.css +HTML_STYLESHEET = @srcdir@/static/doxygen.css TOC_EXPAND = YES -DISABLE_INDEX = YES +DISABLE_INDEX = NO GENERATE_TREEVIEW = NO #--------------------------------------------------------------------------- @@ -143,6 +144,7 @@ CALL_GRAPH = NO GRAPHICAL_HIERARCHY = NO DIRECTORY_GRAPH = NO DOT_IMAGE_FORMAT = jpg +DOT_FONTNAME = Arial DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 @@ -157,3 +159,4 @@ DOT_CLEANUP = YES #External reference options #--------------------------------------------------------------------------- GENERATE_TAGFILE = smeshpy_doc.tag +SEARCHENGINE = YES diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png b/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png new file mode 100644 index 000000000..e0c8ca5cf Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png differ diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_ico.png b/doc/salome/gui/SMESH/images/2d_from_3d_ico.png new file mode 100644 index 000000000..b0842d3e7 Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_ico.png differ diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_menu.png b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png new file mode 100644 index 000000000..acb7b349e Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png differ diff --git a/doc/salome/gui/SMESH/images/a-arithmetic1d.png b/doc/salome/gui/SMESH/images/a-arithmetic1d.png index d34a5e24c..aa43beb5f 100755 Binary files a/doc/salome/gui/SMESH/images/a-arithmetic1d.png and b/doc/salome/gui/SMESH/images/a-arithmetic1d.png differ diff --git a/doc/salome/gui/SMESH/images/a-averagelength.png b/doc/salome/gui/SMESH/images/a-averagelength.png index 70e2afd26..c8ca5ac77 100755 Binary files a/doc/salome/gui/SMESH/images/a-averagelength.png and b/doc/salome/gui/SMESH/images/a-averagelength.png differ diff --git a/doc/salome/gui/SMESH/images/a-clipping2.png b/doc/salome/gui/SMESH/images/a-clipping2.png index bfac4cea5..9d1249c68 100755 Binary files a/doc/salome/gui/SMESH/images/a-clipping2.png and b/doc/salome/gui/SMESH/images/a-clipping2.png differ diff --git a/doc/salome/gui/SMESH/images/a-creategroup.png b/doc/salome/gui/SMESH/images/a-creategroup.png index d23ee825d..ee2b6baa4 100755 Binary files a/doc/salome/gui/SMESH/images/a-creategroup.png and b/doc/salome/gui/SMESH/images/a-creategroup.png differ diff --git a/doc/salome/gui/SMESH/images/a-createpolyhedralvolume.png b/doc/salome/gui/SMESH/images/a-createpolyhedralvolume.png index 26403226c..6c6bb615d 100755 Binary files a/doc/salome/gui/SMESH/images/a-createpolyhedralvolume.png and b/doc/salome/gui/SMESH/images/a-createpolyhedralvolume.png differ diff --git a/doc/salome/gui/SMESH/images/a-nbsegments1.png b/doc/salome/gui/SMESH/images/a-nbsegments1.png index 27668505c..0cd778fc4 100755 Binary files a/doc/salome/gui/SMESH/images/a-nbsegments1.png and b/doc/salome/gui/SMESH/images/a-nbsegments1.png differ diff --git a/doc/salome/gui/SMESH/images/a-nbsegments2.png b/doc/salome/gui/SMESH/images/a-nbsegments2.png index 8d4f277d9..2a7c9fcaa 100755 Binary files a/doc/salome/gui/SMESH/images/a-nbsegments2.png and b/doc/salome/gui/SMESH/images/a-nbsegments2.png differ diff --git a/doc/salome/gui/SMESH/images/a-startendlength.png b/doc/salome/gui/SMESH/images/a-startendlength.png index 947567d7f..ba29d91df 100755 Binary files a/doc/salome/gui/SMESH/images/a-startendlength.png and b/doc/salome/gui/SMESH/images/a-startendlength.png differ diff --git a/doc/salome/gui/SMESH/images/a-transparency.png b/doc/salome/gui/SMESH/images/a-transparency.png index 370ef3026..df10f7a98 100755 Binary files a/doc/salome/gui/SMESH/images/a-transparency.png and b/doc/salome/gui/SMESH/images/a-transparency.png differ diff --git a/doc/salome/gui/SMESH/images/add0delement.png b/doc/salome/gui/SMESH/images/add0delement.png new file mode 100644 index 000000000..ed27488c9 Binary files /dev/null and b/doc/salome/gui/SMESH/images/add0delement.png differ diff --git a/doc/salome/gui/SMESH/images/add_0delement.png b/doc/salome/gui/SMESH/images/add_0delement.png new file mode 100644 index 000000000..fa1075b68 Binary files /dev/null and b/doc/salome/gui/SMESH/images/add_0delement.png differ diff --git a/doc/salome/gui/SMESH/images/add_ball.png b/doc/salome/gui/SMESH/images/add_ball.png new file mode 100644 index 000000000..1fe4f645c Binary files /dev/null and b/doc/salome/gui/SMESH/images/add_ball.png differ diff --git a/doc/salome/gui/SMESH/images/addball.png b/doc/salome/gui/SMESH/images/addball.png new file mode 100644 index 000000000..c38c9faf8 Binary files /dev/null and b/doc/salome/gui/SMESH/images/addball.png differ diff --git a/doc/salome/gui/SMESH/images/addedge.png b/doc/salome/gui/SMESH/images/addedge.png index f142dffb2..7a5a03063 100755 Binary files a/doc/salome/gui/SMESH/images/addedge.png and b/doc/salome/gui/SMESH/images/addedge.png differ diff --git a/doc/salome/gui/SMESH/images/addhexahedron.png b/doc/salome/gui/SMESH/images/addhexahedron.png index 78ea3b50f..0cf7fe819 100755 Binary files a/doc/salome/gui/SMESH/images/addhexahedron.png and b/doc/salome/gui/SMESH/images/addhexahedron.png differ diff --git a/doc/salome/gui/SMESH/images/addinfo_group.png b/doc/salome/gui/SMESH/images/addinfo_group.png new file mode 100644 index 000000000..9f26c9af8 Binary files /dev/null and b/doc/salome/gui/SMESH/images/addinfo_group.png differ diff --git a/doc/salome/gui/SMESH/images/addinfo_mesh.png b/doc/salome/gui/SMESH/images/addinfo_mesh.png new file mode 100644 index 000000000..91fbc38ad Binary files /dev/null and b/doc/salome/gui/SMESH/images/addinfo_mesh.png differ diff --git a/doc/salome/gui/SMESH/images/addinfo_submesh.png b/doc/salome/gui/SMESH/images/addinfo_submesh.png new file mode 100644 index 000000000..4811c9902 Binary files /dev/null and b/doc/salome/gui/SMESH/images/addinfo_submesh.png differ diff --git a/doc/salome/gui/SMESH/images/addnode.png b/doc/salome/gui/SMESH/images/addnode.png index 1f5375b9a..1fd9a9f8a 100755 Binary files a/doc/salome/gui/SMESH/images/addnode.png and b/doc/salome/gui/SMESH/images/addnode.png differ diff --git a/doc/salome/gui/SMESH/images/addnode_notebook.png b/doc/salome/gui/SMESH/images/addnode_notebook.png index 4abab3358..804f806df 100755 Binary files a/doc/salome/gui/SMESH/images/addnode_notebook.png and b/doc/salome/gui/SMESH/images/addnode_notebook.png differ diff --git a/doc/salome/gui/SMESH/images/addpolygon.png b/doc/salome/gui/SMESH/images/addpolygon.png index 5d02dd70d..200999d8d 100755 Binary files a/doc/salome/gui/SMESH/images/addpolygon.png and b/doc/salome/gui/SMESH/images/addpolygon.png differ diff --git a/doc/salome/gui/SMESH/images/addquadrangle.png b/doc/salome/gui/SMESH/images/addquadrangle.png index 3e5c87c42..bd2462273 100755 Binary files a/doc/salome/gui/SMESH/images/addquadrangle.png and b/doc/salome/gui/SMESH/images/addquadrangle.png differ diff --git a/doc/salome/gui/SMESH/images/addtetrahedron.png b/doc/salome/gui/SMESH/images/addtetrahedron.png index 37dc29659..0a6a74084 100755 Binary files a/doc/salome/gui/SMESH/images/addtetrahedron.png and b/doc/salome/gui/SMESH/images/addtetrahedron.png differ diff --git a/doc/salome/gui/SMESH/images/addtriangle.png b/doc/salome/gui/SMESH/images/addtriangle.png index 52a644e51..67682c8cf 100755 Binary files a/doc/salome/gui/SMESH/images/addtriangle.png and b/doc/salome/gui/SMESH/images/addtriangle.png differ diff --git a/doc/salome/gui/SMESH/images/advanced_mesh_infos.png b/doc/salome/gui/SMESH/images/advanced_mesh_infos.png index 2dc9f8f48..ddd305f58 100755 Binary files a/doc/salome/gui/SMESH/images/advanced_mesh_infos.png and b/doc/salome/gui/SMESH/images/advanced_mesh_infos.png differ diff --git a/doc/salome/gui/SMESH/images/aqt.png b/doc/salome/gui/SMESH/images/aqt.png index ae8e0d081..46ee94dae 100755 Binary files a/doc/salome/gui/SMESH/images/aqt.png and b/doc/salome/gui/SMESH/images/aqt.png differ diff --git a/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png new file mode 100644 index 000000000..6b7ead85e Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png differ diff --git a/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png new file mode 100644 index 000000000..a1e799aa2 Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png differ diff --git a/doc/salome/gui/SMESH/images/blsurf_parameters.png b/doc/salome/gui/SMESH/images/blsurf_parameters.png deleted file mode 100644 index 22d038ac5..000000000 Binary files a/doc/salome/gui/SMESH/images/blsurf_parameters.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/blsurf_parameters_advanced.png b/doc/salome/gui/SMESH/images/blsurf_parameters_advanced.png deleted file mode 100644 index 0f2c07dc3..000000000 Binary files a/doc/salome/gui/SMESH/images/blsurf_parameters_advanced.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/bnd_box.png b/doc/salome/gui/SMESH/images/bnd_box.png new file mode 100644 index 000000000..6761a76ff Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box.png differ diff --git a/doc/salome/gui/SMESH/images/bnd_box_preview.png b/doc/salome/gui/SMESH/images/bnd_box_preview.png new file mode 100644 index 000000000..902101cf3 Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box_preview.png differ diff --git a/doc/salome/gui/SMESH/images/cartesian3D_hyp.png b/doc/salome/gui/SMESH/images/cartesian3D_hyp.png new file mode 100644 index 000000000..b8373ed6d Binary files /dev/null and b/doc/salome/gui/SMESH/images/cartesian3D_hyp.png differ diff --git a/doc/salome/gui/SMESH/images/cartesian3D_sphere.png b/doc/salome/gui/SMESH/images/cartesian3D_sphere.png new file mode 100644 index 000000000..45bffdabe Binary files /dev/null and b/doc/salome/gui/SMESH/images/cartesian3D_sphere.png differ diff --git a/doc/salome/gui/SMESH/images/colors_size.png b/doc/salome/gui/SMESH/images/colors_size.png new file mode 100755 index 000000000..15060edfe Binary files /dev/null and b/doc/salome/gui/SMESH/images/colors_size.png differ diff --git a/doc/salome/gui/SMESH/images/controls_popup.png b/doc/salome/gui/SMESH/images/controls_popup.png new file mode 100755 index 000000000..c32f9eada Binary files /dev/null and b/doc/salome/gui/SMESH/images/controls_popup.png differ diff --git a/doc/salome/gui/SMESH/images/convert.png b/doc/salome/gui/SMESH/images/convert.png index 4a71cac99..2ebbedc3a 100644 Binary files a/doc/salome/gui/SMESH/images/convert.png and b/doc/salome/gui/SMESH/images/convert.png differ diff --git a/doc/salome/gui/SMESH/images/copy_mesh_dlg.png b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png new file mode 100644 index 000000000..db9c929b5 Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png differ diff --git a/doc/salome/gui/SMESH/images/copy_mesh_icon.png b/doc/salome/gui/SMESH/images/copy_mesh_icon.png new file mode 100644 index 000000000..263479f3b Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_icon.png differ diff --git a/doc/salome/gui/SMESH/images/create_groups_from_geometry.png b/doc/salome/gui/SMESH/images/create_groups_from_geometry.png index 17d54dec3..f20d4a724 100644 Binary files a/doc/salome/gui/SMESH/images/create_groups_from_geometry.png and b/doc/salome/gui/SMESH/images/create_groups_from_geometry.png differ diff --git a/doc/salome/gui/SMESH/images/creategroup.png b/doc/salome/gui/SMESH/images/creategroup.png index 2fb825cc8..ec24a4fed 100755 Binary files a/doc/salome/gui/SMESH/images/creategroup.png and b/doc/salome/gui/SMESH/images/creategroup.png differ diff --git a/doc/salome/gui/SMESH/images/creategroup_on_filter.png b/doc/salome/gui/SMESH/images/creategroup_on_filter.png new file mode 100644 index 000000000..0a494c097 Binary files /dev/null and b/doc/salome/gui/SMESH/images/creategroup_on_filter.png differ diff --git a/doc/salome/gui/SMESH/images/custom_point_marker.png b/doc/salome/gui/SMESH/images/custom_point_marker.png new file mode 100755 index 000000000..a46e33ed9 Binary files /dev/null and b/doc/salome/gui/SMESH/images/custom_point_marker.png differ diff --git a/doc/salome/gui/SMESH/images/dialog.png b/doc/salome/gui/SMESH/images/dialog.png index 1fa2c4263..c9cc22cab 100755 Binary files a/doc/salome/gui/SMESH/images/dialog.png and b/doc/salome/gui/SMESH/images/dialog.png differ diff --git a/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png b/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png index 7dea248c6..83c086b43 100755 Binary files a/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png and b/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png differ diff --git a/doc/salome/gui/SMESH/images/distributionwithtabledensity.png b/doc/salome/gui/SMESH/images/distributionwithtabledensity.png index 3bd40bc45..60847cde5 100755 Binary files a/doc/salome/gui/SMESH/images/distributionwithtabledensity.png and b/doc/salome/gui/SMESH/images/distributionwithtabledensity.png differ diff --git a/doc/salome/gui/SMESH/images/double_faces.png b/doc/salome/gui/SMESH/images/double_faces.png new file mode 100644 index 000000000..47bed1fab Binary files /dev/null and b/doc/salome/gui/SMESH/images/double_faces.png differ diff --git a/doc/salome/gui/SMESH/images/double_nodes.png b/doc/salome/gui/SMESH/images/double_nodes.png new file mode 100644 index 000000000..27a209b74 Binary files /dev/null and b/doc/salome/gui/SMESH/images/double_nodes.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate01.png b/doc/salome/gui/SMESH/images/duplicate01.png new file mode 100644 index 000000000..80a4a2ba9 Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate01.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate02.png b/doc/salome/gui/SMESH/images/duplicate02.png new file mode 100644 index 000000000..0e5014125 Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate02.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate_nodes.png b/doc/salome/gui/SMESH/images/duplicate_nodes.png new file mode 100644 index 000000000..61ff32bcd Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate_nodes.png differ diff --git a/doc/salome/gui/SMESH/images/editgroup.png b/doc/salome/gui/SMESH/images/editgroup.png index ac9e8a2c1..fb102242e 100755 Binary files a/doc/salome/gui/SMESH/images/editgroup.png and b/doc/salome/gui/SMESH/images/editgroup.png differ diff --git a/doc/salome/gui/SMESH/images/elem_info.png b/doc/salome/gui/SMESH/images/elem_info.png new file mode 100644 index 000000000..9937d6d88 Binary files /dev/null and b/doc/salome/gui/SMESH/images/elem_info.png differ diff --git a/doc/salome/gui/SMESH/images/eleminfo1.png b/doc/salome/gui/SMESH/images/eleminfo1.png index 3aae250c8..3cd439b76 100755 Binary files a/doc/salome/gui/SMESH/images/eleminfo1.png and b/doc/salome/gui/SMESH/images/eleminfo1.png differ diff --git a/doc/salome/gui/SMESH/images/eleminfo2.png b/doc/salome/gui/SMESH/images/eleminfo2.png index 9ead335b8..54fe12df8 100755 Binary files a/doc/salome/gui/SMESH/images/eleminfo2.png and b/doc/salome/gui/SMESH/images/eleminfo2.png differ diff --git a/doc/salome/gui/SMESH/images/extr_along_wire_after.png b/doc/salome/gui/SMESH/images/extr_along_wire_after.png new file mode 100644 index 000000000..eb39bdd08 Binary files /dev/null and b/doc/salome/gui/SMESH/images/extr_along_wire_after.png differ diff --git a/doc/salome/gui/SMESH/images/extr_along_wire_before.png b/doc/salome/gui/SMESH/images/extr_along_wire_before.png new file mode 100644 index 000000000..2f30ceeab Binary files /dev/null and b/doc/salome/gui/SMESH/images/extr_along_wire_before.png differ diff --git a/doc/salome/gui/SMESH/images/extrusion1.png b/doc/salome/gui/SMESH/images/extrusion1.png index 9f34a0feb..540bce24a 100644 Binary files a/doc/salome/gui/SMESH/images/extrusion1.png and b/doc/salome/gui/SMESH/images/extrusion1.png differ diff --git a/doc/salome/gui/SMESH/images/extrusion2.png b/doc/salome/gui/SMESH/images/extrusion2.png deleted file mode 100755 index 527b67a17..000000000 Binary files a/doc/salome/gui/SMESH/images/extrusion2.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/extrusionalongaline1.png b/doc/salome/gui/SMESH/images/extrusionalongaline1.png index 76a60bd34..95a26ca90 100755 Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline1.png and b/doc/salome/gui/SMESH/images/extrusionalongaline1.png differ diff --git a/doc/salome/gui/SMESH/images/extrusionalongaline2.png b/doc/salome/gui/SMESH/images/extrusionalongaline2.png index fb0456250..8c1662396 100755 Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline2.png and b/doc/salome/gui/SMESH/images/extrusionalongaline2.png differ diff --git a/doc/salome/gui/SMESH/images/findelement1.png b/doc/salome/gui/SMESH/images/findelement1.png new file mode 100644 index 000000000..1c11a031a Binary files /dev/null and b/doc/salome/gui/SMESH/images/findelement1.png differ diff --git a/doc/salome/gui/SMESH/images/findelement2.png b/doc/salome/gui/SMESH/images/findelement2.png new file mode 100644 index 000000000..c9898b50a Binary files /dev/null and b/doc/salome/gui/SMESH/images/findelement2.png differ diff --git a/doc/salome/gui/SMESH/images/findelement3.png b/doc/salome/gui/SMESH/images/findelement3.png new file mode 100644 index 000000000..26cfff2d7 Binary files /dev/null and b/doc/salome/gui/SMESH/images/findelement3.png differ diff --git a/doc/salome/gui/SMESH/images/formula1.png b/doc/salome/gui/SMESH/images/formula1.png index 2f8d2f518..b3468a15a 100644 Binary files a/doc/salome/gui/SMESH/images/formula1.png and b/doc/salome/gui/SMESH/images/formula1.png differ diff --git a/doc/salome/gui/SMESH/images/formula2.png b/doc/salome/gui/SMESH/images/formula2.png index ff189aa8e..dd45fbfb1 100644 Binary files a/doc/salome/gui/SMESH/images/formula2.png and b/doc/salome/gui/SMESH/images/formula2.png differ diff --git a/doc/salome/gui/SMESH/images/formula4.png b/doc/salome/gui/SMESH/images/formula4.png index 170f25558..3a5d31f6f 100644 Binary files a/doc/salome/gui/SMESH/images/formula4.png and b/doc/salome/gui/SMESH/images/formula4.png differ diff --git a/doc/salome/gui/SMESH/images/formula5.png b/doc/salome/gui/SMESH/images/formula5.png new file mode 100644 index 000000000..8cd035fad Binary files /dev/null and b/doc/salome/gui/SMESH/images/formula5.png differ diff --git a/doc/salome/gui/SMESH/images/free_nodes.png b/doc/salome/gui/SMESH/images/free_nodes.png index c1d23c1d3..ea043eac3 100644 Binary files a/doc/salome/gui/SMESH/images/free_nodes.png and b/doc/salome/gui/SMESH/images/free_nodes.png differ diff --git a/doc/salome/gui/SMESH/images/ghs3d_parameters_advanced.png b/doc/salome/gui/SMESH/images/ghs3d_parameters_advanced.png deleted file mode 100644 index 4f36203ba..000000000 Binary files a/doc/salome/gui/SMESH/images/ghs3d_parameters_advanced.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/ghs3d_parameters_basic.png b/doc/salome/gui/SMESH/images/ghs3d_parameters_basic.png deleted file mode 100644 index 0cce50bb8..000000000 Binary files a/doc/salome/gui/SMESH/images/ghs3d_parameters_basic.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/head.png b/doc/salome/gui/SMESH/images/head.png new file mode 100755 index 000000000..307d9ef9a Binary files /dev/null and b/doc/salome/gui/SMESH/images/head.png differ diff --git a/doc/salome/gui/SMESH/images/hyp_source_edges.png b/doc/salome/gui/SMESH/images/hyp_source_edges.png new file mode 100644 index 000000000..2305e178b Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_edges.png differ diff --git a/doc/salome/gui/SMESH/images/hyp_source_faces.png b/doc/salome/gui/SMESH/images/hyp_source_faces.png new file mode 100644 index 000000000..fe9e6c62c Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_faces.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png b/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png new file mode 100755 index 000000000..74276bd96 Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_1.png b/doc/salome/gui/SMESH/images/hypo_quad_params_1.png new file mode 100755 index 000000000..44233b23e Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_1.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_2.png b/doc/salome/gui/SMESH/images/hypo_quad_params_2.png new file mode 100644 index 000000000..9f6fa251e Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_2.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png b/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png new file mode 100644 index 000000000..3cd442a8d Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_res.png b/doc/salome/gui/SMESH/images/hypo_quad_params_res.png new file mode 100644 index 000000000..8aae27601 Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_res.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_res_2.png b/doc/salome/gui/SMESH/images/hypo_quad_params_res_2.png new file mode 100644 index 000000000..6dc37e298 Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_res_2.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_radquad_dlg.png b/doc/salome/gui/SMESH/images/hypo_radquad_dlg.png new file mode 100755 index 000000000..e658a6889 Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_radquad_dlg.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_sets.png b/doc/salome/gui/SMESH/images/hypo_sets.png new file mode 100644 index 000000000..2a9859d23 Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_sets.png differ diff --git a/doc/salome/gui/SMESH/images/image146.png b/doc/salome/gui/SMESH/images/image146.png index 2fb825cc8..a952f5fcc 100755 Binary files a/doc/salome/gui/SMESH/images/image146.png and b/doc/salome/gui/SMESH/images/image146.png differ diff --git a/doc/salome/gui/SMESH/images/image152.png b/doc/salome/gui/SMESH/images/image152.png index ef8ef087d..79e264f62 100755 Binary files a/doc/salome/gui/SMESH/images/image152.png and b/doc/salome/gui/SMESH/images/image152.png differ diff --git a/doc/salome/gui/SMESH/images/image42.png b/doc/salome/gui/SMESH/images/image42.png new file mode 100755 index 000000000..d0120fa1e Binary files /dev/null and b/doc/salome/gui/SMESH/images/image42.png differ diff --git a/doc/salome/gui/SMESH/images/image43.png b/doc/salome/gui/SMESH/images/image43.png new file mode 100755 index 000000000..7b6b895a1 Binary files /dev/null and b/doc/salome/gui/SMESH/images/image43.png differ diff --git a/doc/salome/gui/SMESH/images/image49.png b/doc/salome/gui/SMESH/images/image49.png index 74926d244..6e5b3176b 100755 Binary files a/doc/salome/gui/SMESH/images/image49.png and b/doc/salome/gui/SMESH/images/image49.png differ diff --git a/doc/salome/gui/SMESH/images/image79.jpg b/doc/salome/gui/SMESH/images/image79.jpg index 6d164167f..0efc73695 100755 Binary files a/doc/salome/gui/SMESH/images/image79.jpg and b/doc/salome/gui/SMESH/images/image79.jpg differ diff --git a/doc/salome/gui/SMESH/images/image99.gif b/doc/salome/gui/SMESH/images/image99.gif index 4959ed825..2672e99f3 100755 Binary files a/doc/salome/gui/SMESH/images/image99.gif and b/doc/salome/gui/SMESH/images/image99.gif differ diff --git a/doc/salome/gui/SMESH/images/image_octa12.png b/doc/salome/gui/SMESH/images/image_octa12.png new file mode 100644 index 000000000..1a5ed8c0a Binary files /dev/null and b/doc/salome/gui/SMESH/images/image_octa12.png differ diff --git a/doc/salome/gui/SMESH/images/max_element_length_2d.png b/doc/salome/gui/SMESH/images/max_element_length_2d.png new file mode 100755 index 000000000..012d552f5 Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_2d.png differ diff --git a/doc/salome/gui/SMESH/images/max_element_length_3d.png b/doc/salome/gui/SMESH/images/max_element_length_3d.png new file mode 100755 index 000000000..fdf1b7688 Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_3d.png differ diff --git a/doc/salome/gui/SMESH/images/mergeelems.png b/doc/salome/gui/SMESH/images/mergeelems.png index c5e160884..eaa5a9323 100755 Binary files a/doc/salome/gui/SMESH/images/mergeelems.png and b/doc/salome/gui/SMESH/images/mergeelems.png differ diff --git a/doc/salome/gui/SMESH/images/mergeelems_auto.png b/doc/salome/gui/SMESH/images/mergeelems_auto.png new file mode 100644 index 000000000..f8ef74f13 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mergeelems_auto.png differ diff --git a/doc/salome/gui/SMESH/images/mergenodes.png b/doc/salome/gui/SMESH/images/mergenodes.png index d14620101..54cb3d17a 100755 Binary files a/doc/salome/gui/SMESH/images/mergenodes.png and b/doc/salome/gui/SMESH/images/mergenodes.png differ diff --git a/doc/salome/gui/SMESH/images/mergenodes_auto.png b/doc/salome/gui/SMESH/images/mergenodes_auto.png new file mode 100644 index 000000000..71511d22e Binary files /dev/null and b/doc/salome/gui/SMESH/images/mergenodes_auto.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_evaluation_succeed.png b/doc/salome/gui/SMESH/images/mesh_evaluation_succeed.png new file mode 100755 index 000000000..b9aeb522f Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_evaluation_succeed.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_fixedpnt.png b/doc/salome/gui/SMESH/images/mesh_fixedpnt.png new file mode 100755 index 000000000..5d044ab63 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_fixedpnt.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_123.png b/doc/salome/gui/SMESH/images/mesh_order_123.png new file mode 100644 index 000000000..952f20796 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_123.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_123_res.png b/doc/salome/gui/SMESH/images/mesh_order_123_res.png new file mode 100644 index 000000000..02208a052 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_123_res.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_213.png b/doc/salome/gui/SMESH/images/mesh_order_213.png new file mode 100644 index 000000000..959ca384e Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_213.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_213_res.png b/doc/salome/gui/SMESH/images/mesh_order_213_res.png new file mode 100644 index 000000000..8706fb45c Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_213_res.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_321.png b/doc/salome/gui/SMESH/images/mesh_order_321.png new file mode 100644 index 000000000..7ad61fabd Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_321.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_321_res.png b/doc/salome/gui/SMESH/images/mesh_order_321_res.png new file mode 100644 index 000000000..7a5f0172e Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_321_res.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_no_concurrent.png b/doc/salome/gui/SMESH/images/mesh_order_no_concurrent.png new file mode 100644 index 000000000..6df59a1f1 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_no_concurrent.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_order_preview.png b/doc/salome/gui/SMESH/images/mesh_order_preview.png new file mode 100644 index 000000000..f4b5e3b98 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_preview.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_radquad_01.png b/doc/salome/gui/SMESH/images/mesh_radquad_01.png new file mode 100755 index 000000000..dfd8eb5a7 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_radquad_01.png differ diff --git a/doc/salome/gui/SMESH/images/mesh_radquad_02.png b/doc/salome/gui/SMESH/images/mesh_radquad_02.png new file mode 100755 index 000000000..63432ebe2 Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_radquad_02.png differ diff --git a/doc/salome/gui/SMESH/images/meshcomputationfail.png b/doc/salome/gui/SMESH/images/meshcomputationfail.png index 781a59a64..61f3a433a 100644 Binary files a/doc/salome/gui/SMESH/images/meshcomputationfail.png and b/doc/salome/gui/SMESH/images/meshcomputationfail.png differ diff --git a/doc/salome/gui/SMESH/images/meshcut_plugin.png b/doc/salome/gui/SMESH/images/meshcut_plugin.png new file mode 100644 index 000000000..305e920d0 Binary files /dev/null and b/doc/salome/gui/SMESH/images/meshcut_plugin.png differ diff --git a/doc/salome/gui/SMESH/images/meshtopass.png b/doc/salome/gui/SMESH/images/meshtopass.png index 9a5c62e24..1c426783e 100755 Binary files a/doc/salome/gui/SMESH/images/meshtopass.png and b/doc/salome/gui/SMESH/images/meshtopass.png differ diff --git a/doc/salome/gui/SMESH/images/min_distance.png b/doc/salome/gui/SMESH/images/min_distance.png new file mode 100644 index 000000000..765522e88 Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance.png differ diff --git a/doc/salome/gui/SMESH/images/min_distance_preview.png b/doc/salome/gui/SMESH/images/min_distance_preview.png new file mode 100644 index 000000000..c5373d99f Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance_preview.png differ diff --git a/doc/salome/gui/SMESH/images/moving_nodes1.png b/doc/salome/gui/SMESH/images/moving_nodes1.png index 2bae38850..295b3a38f 100755 Binary files a/doc/salome/gui/SMESH/images/moving_nodes1.png and b/doc/salome/gui/SMESH/images/moving_nodes1.png differ diff --git a/doc/salome/gui/SMESH/images/moving_nodes2.png b/doc/salome/gui/SMESH/images/moving_nodes2.png index b65e57ae9..a89e8b36b 100755 Binary files a/doc/salome/gui/SMESH/images/moving_nodes2.png and b/doc/salome/gui/SMESH/images/moving_nodes2.png differ diff --git a/doc/salome/gui/SMESH/images/netgen2d.png b/doc/salome/gui/SMESH/images/netgen2d.png deleted file mode 100644 index 29e09ef13..000000000 Binary files a/doc/salome/gui/SMESH/images/netgen2d.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/netgen3d_simple.png b/doc/salome/gui/SMESH/images/netgen3d_simple.png deleted file mode 100644 index 959ec02c8..000000000 Binary files a/doc/salome/gui/SMESH/images/netgen3d_simple.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/over_constrained_faces.png b/doc/salome/gui/SMESH/images/over_constrained_faces.png new file mode 100644 index 000000000..9d584e8ac Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_faces.png differ diff --git a/doc/salome/gui/SMESH/images/over_constrained_volumes.png b/doc/salome/gui/SMESH/images/over_constrained_volumes.png new file mode 100644 index 000000000..761144382 Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_volumes.png differ diff --git a/doc/salome/gui/SMESH/images/pattern2d.png b/doc/salome/gui/SMESH/images/pattern2d.png new file mode 100644 index 000000000..ff488eb8f Binary files /dev/null and b/doc/salome/gui/SMESH/images/pattern2d.png differ diff --git a/doc/salome/gui/SMESH/images/point_marker_widget1.png b/doc/salome/gui/SMESH/images/point_marker_widget1.png new file mode 100755 index 000000000..13b8e6dab Binary files /dev/null and b/doc/salome/gui/SMESH/images/point_marker_widget1.png differ diff --git a/doc/salome/gui/SMESH/images/point_marker_widget2.png b/doc/salome/gui/SMESH/images/point_marker_widget2.png new file mode 100755 index 000000000..dbb81b40e Binary files /dev/null and b/doc/salome/gui/SMESH/images/point_marker_widget2.png differ diff --git a/doc/salome/gui/SMESH/images/pref21.png b/doc/salome/gui/SMESH/images/pref21.png new file mode 100755 index 000000000..d30add416 Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref21.png differ diff --git a/doc/salome/gui/SMESH/images/pref22.png b/doc/salome/gui/SMESH/images/pref22.png new file mode 100755 index 000000000..b56c4e540 Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref22.png differ diff --git a/doc/salome/gui/SMESH/images/pref23.png b/doc/salome/gui/SMESH/images/pref23.png new file mode 100755 index 000000000..07858d726 Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref23.png differ diff --git a/doc/salome/gui/SMESH/images/pref24.png b/doc/salome/gui/SMESH/images/pref24.png new file mode 100755 index 000000000..f1cdcf8fc Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref24.png differ diff --git a/doc/salome/gui/SMESH/images/projection_1d.png b/doc/salome/gui/SMESH/images/projection_1d.png index 5af29afb8..611532763 100644 Binary files a/doc/salome/gui/SMESH/images/projection_1d.png and b/doc/salome/gui/SMESH/images/projection_1d.png differ diff --git a/doc/salome/gui/SMESH/images/projection_2d.png b/doc/salome/gui/SMESH/images/projection_2d.png index d7380ec1d..e13730994 100644 Binary files a/doc/salome/gui/SMESH/images/projection_2d.png and b/doc/salome/gui/SMESH/images/projection_2d.png differ diff --git a/doc/salome/gui/SMESH/images/projection_3d.png b/doc/salome/gui/SMESH/images/projection_3d.png index 5f6b907b8..03eedc3ab 100644 Binary files a/doc/salome/gui/SMESH/images/projection_3d.png and b/doc/salome/gui/SMESH/images/projection_3d.png differ diff --git a/doc/salome/gui/SMESH/images/remove_nodes_icon.png b/doc/salome/gui/SMESH/images/remove_nodes_icon.png new file mode 100644 index 000000000..0818837ef Binary files /dev/null and b/doc/salome/gui/SMESH/images/remove_nodes_icon.png differ diff --git a/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png b/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png new file mode 100644 index 000000000..16df2e592 Binary files /dev/null and b/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png differ diff --git a/doc/salome/gui/SMESH/images/removeorphannodes.png b/doc/salome/gui/SMESH/images/removeorphannodes.png new file mode 100644 index 000000000..fdf839559 Binary files /dev/null and b/doc/salome/gui/SMESH/images/removeorphannodes.png differ diff --git a/doc/salome/gui/SMESH/images/reorient_2d_face.png b/doc/salome/gui/SMESH/images/reorient_2d_face.png new file mode 100644 index 000000000..b143ac4eb Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_2d_face.png differ diff --git a/doc/salome/gui/SMESH/images/reorient_2d_point.png b/doc/salome/gui/SMESH/images/reorient_2d_point.png new file mode 100644 index 000000000..844ac09ef Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_2d_point.png differ diff --git a/doc/salome/gui/SMESH/images/reorient_faces_face.png b/doc/salome/gui/SMESH/images/reorient_faces_face.png new file mode 100644 index 000000000..23c241fcf Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_faces_face.png differ diff --git a/doc/salome/gui/SMESH/images/revolution2.png b/doc/salome/gui/SMESH/images/revolution2.png deleted file mode 100755 index 7d5777c9e..000000000 Binary files a/doc/salome/gui/SMESH/images/revolution2.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/rotation.png b/doc/salome/gui/SMESH/images/rotation.png index ae6df4b9f..c8f11e66b 100755 Binary files a/doc/salome/gui/SMESH/images/rotation.png and b/doc/salome/gui/SMESH/images/rotation.png differ diff --git a/doc/salome/gui/SMESH/images/scalar_bar_dlg.png b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png new file mode 100755 index 000000000..59ca53065 Binary files /dev/null and b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png differ diff --git a/doc/salome/gui/SMESH/images/scale01.png b/doc/salome/gui/SMESH/images/scale01.png new file mode 100644 index 000000000..685bbc1bf Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale01.png differ diff --git a/doc/salome/gui/SMESH/images/scale02.png b/doc/salome/gui/SMESH/images/scale02.png new file mode 100644 index 000000000..982f468b0 Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale02.png differ diff --git a/doc/salome/gui/SMESH/images/scale03.png b/doc/salome/gui/SMESH/images/scale03.png new file mode 100644 index 000000000..891ae8d17 Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale03.png differ diff --git a/doc/salome/gui/SMESH/images/scale04.png b/doc/salome/gui/SMESH/images/scale04.png new file mode 100644 index 000000000..a0428342a Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale04.png differ diff --git a/doc/salome/gui/SMESH/images/scale06.png b/doc/salome/gui/SMESH/images/scale06.png new file mode 100644 index 000000000..2bd8219d2 Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale06.png differ diff --git a/doc/salome/gui/SMESH/images/scale07.png b/doc/salome/gui/SMESH/images/scale07.png new file mode 100644 index 000000000..8ee0923bd Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale07.png differ diff --git a/doc/salome/gui/SMESH/images/scale09.png b/doc/salome/gui/SMESH/images/scale09.png new file mode 100644 index 000000000..2816bac4b Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale09.png differ diff --git a/doc/salome/gui/SMESH/images/scaleinit01.png b/doc/salome/gui/SMESH/images/scaleinit01.png new file mode 100644 index 000000000..97990a868 Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleinit01.png differ diff --git a/doc/salome/gui/SMESH/images/scaleinit02.png b/doc/salome/gui/SMESH/images/scaleinit02.png new file mode 100644 index 000000000..008d2e321 Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleinit02.png differ diff --git a/doc/salome/gui/SMESH/images/scaleres03.png b/doc/salome/gui/SMESH/images/scaleres03.png new file mode 100644 index 000000000..99b65d72a Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres03.png differ diff --git a/doc/salome/gui/SMESH/images/scaleres04.png b/doc/salome/gui/SMESH/images/scaleres04.png new file mode 100644 index 000000000..0880989cb Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres04.png differ diff --git a/doc/salome/gui/SMESH/images/scaleres06.png b/doc/salome/gui/SMESH/images/scaleres06.png new file mode 100644 index 000000000..059fa97f4 Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres06.png differ diff --git a/doc/salome/gui/SMESH/images/scaleres07.png b/doc/salome/gui/SMESH/images/scaleres07.png new file mode 100644 index 000000000..b75f83c3c Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres07.png differ diff --git a/doc/salome/gui/SMESH/images/scaleres09.png b/doc/salome/gui/SMESH/images/scaleres09.png new file mode 100644 index 000000000..4708be51f Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres09.png differ diff --git a/doc/salome/gui/SMESH/images/split_into_tetra.png b/doc/salome/gui/SMESH/images/split_into_tetra.png new file mode 100644 index 000000000..fce071e7d Binary files /dev/null and b/doc/salome/gui/SMESH/images/split_into_tetra.png differ diff --git a/doc/salome/gui/SMESH/images/split_into_tetra_icon.png b/doc/salome/gui/SMESH/images/split_into_tetra_icon.png new file mode 100644 index 000000000..b113c304d Binary files /dev/null and b/doc/salome/gui/SMESH/images/split_into_tetra_icon.png differ diff --git a/doc/salome/gui/SMESH/images/std_point_marker.png b/doc/salome/gui/SMESH/images/std_point_marker.png new file mode 100755 index 000000000..2a6269309 Binary files /dev/null and b/doc/salome/gui/SMESH/images/std_point_marker.png differ diff --git a/doc/salome/gui/SMESH/images/symmetry1.png b/doc/salome/gui/SMESH/images/symmetry1.png index b37fb0ab1..879a41d9d 100755 Binary files a/doc/salome/gui/SMESH/images/symmetry1.png and b/doc/salome/gui/SMESH/images/symmetry1.png differ diff --git a/doc/salome/gui/SMESH/images/symmetry2.png b/doc/salome/gui/SMESH/images/symmetry2.png index 9304d6734..83d233820 100755 Binary files a/doc/salome/gui/SMESH/images/symmetry2.png and b/doc/salome/gui/SMESH/images/symmetry2.png differ diff --git a/doc/salome/gui/SMESH/images/symmetry3.png b/doc/salome/gui/SMESH/images/symmetry3.png index f15c5fcaa..865465993 100755 Binary files a/doc/salome/gui/SMESH/images/symmetry3.png and b/doc/salome/gui/SMESH/images/symmetry3.png differ diff --git a/doc/salome/gui/SMESH/images/translation1.png b/doc/salome/gui/SMESH/images/translation1.png index b7e811645..790e365cf 100755 Binary files a/doc/salome/gui/SMESH/images/translation1.png and b/doc/salome/gui/SMESH/images/translation1.png differ diff --git a/doc/salome/gui/SMESH/images/translation2.png b/doc/salome/gui/SMESH/images/translation2.png index c0bbad0a5..5df23cc40 100755 Binary files a/doc/salome/gui/SMESH/images/translation2.png and b/doc/salome/gui/SMESH/images/translation2.png differ diff --git a/doc/salome/gui/SMESH/images/use_existing_face_sample_mesh.png b/doc/salome/gui/SMESH/images/use_existing_face_sample_mesh.png new file mode 100644 index 000000000..2110540e4 Binary files /dev/null and b/doc/salome/gui/SMESH/images/use_existing_face_sample_mesh.png differ diff --git a/doc/salome/gui/SMESH/images/using_notebook_smesh.png b/doc/salome/gui/SMESH/images/using_notebook_smesh.png new file mode 100644 index 000000000..0946bff07 Binary files /dev/null and b/doc/salome/gui/SMESH/images/using_notebook_smesh.png differ diff --git a/doc/salome/gui/SMESH/images/viscous_layers_hyp.png b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png new file mode 100644 index 000000000..843ff5d09 Binary files /dev/null and b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png differ diff --git a/doc/salome/gui/SMESH/images/viscous_layers_mesh.png b/doc/salome/gui/SMESH/images/viscous_layers_mesh.png new file mode 100644 index 000000000..9373a5e46 Binary files /dev/null and b/doc/salome/gui/SMESH/images/viscous_layers_mesh.png differ diff --git a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc index 705354692..367a0d0b5 100644 --- a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc +++ b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc @@ -5,12 +5,13 @@
  • \ref arithmetic_1d_anchor "Arithmetic 1D"
  • -
  • \ref average_length_anchor "Average Length"
  • +
  • \ref average_length_anchor "Local Length"
  • \ref max_length_anchor "Max Size"
  • \ref deflection_1d_anchor "Deflection 1D"
  • \ref number_of_segments_anchor "Number of segments"
  • \ref start_and_end_length_anchor "Start and end length"
  • \ref automatic_length_anchor "Automatic Length"
  • +
  • \ref fixed_points_1d_anchor "Fixed points 1D"

@@ -21,6 +22,12 @@ length that changes in arithmetic progression (Lk = Lk-1 + d) beginning from a given starting length and up to a given end length. +The direction of the splitting is defined by the orientation of the underlying geometrical edge. +"Reverse Edges" list box allows to specify the edges for which the splitting should be made +in the direction opposing to their orientation. This list box is enabled only if the geometry object +is selected for the meshing. In this case the user can select edges to be reversed either directly +picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser. + \image html a-arithmetic1d.png \image html b-ithmetic1d.png "Arithmetic 1D hypothesis - the size of mesh elements gradually increases" @@ -50,9 +57,9 @@ locations and 1D mesh elements are constructed on segments.
\anchor average_length_anchor -

Average Length hypothesis

+

Local Length hypothesis

-Average Length hypothesis can be applied for meshing of edges +Local Length hypothesis can be applied for meshing of edges composing your geometrical object. Definition of this hypothesis consists of setting the \b length of segments, which will split these edges, and the \b precision of rounding. The points on the edges @@ -72,10 +79,10 @@ integer. Default value is 1e-07. \image html a-averagelength.png -\image html b-erage_length.png "Average length hypothesis - all 1D mesh elements are roughly equal" +\image html b-erage_length.png "Local Length hypothesis - all 1D mesh elements are roughly equal" See Also a sample TUI Script of a -\ref tui_average_length "Defining Average Length" hypothesis +\ref tui_average_length "Defining Local Length" hypothesis operation.
\anchor max_length_anchor @@ -106,6 +113,12 @@ edges generated by these segments will represent nodes of your mesh. Later these nodes will be used for meshing of the faces abutting to these edges. +The direction of the splitting is defined by the orientation of the underlying geometrical edge. +"Reverse Edges" list box allows to specify the edges for which the splitting should be made +in the direction opposing to their orientation. This list box is enabled only if the geometry object +is selected for the meshing. In this case the user can select edges to be reversed either directly +picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser. + \image html image46.gif You can set the type of distribution for this hypothesis in the @@ -144,11 +157,17 @@ operation. Start and End Length hypothesis allows to divide a geometrical edge into segments so that the first and the last segments have a specified -length. The length medium segments changes with automatically chosen +length. The length of medium segments changes with automatically chosen geometric progression. Then mesh nodes are constructed at segment ends location and 1D mesh elements are constructed on them. +The direction of the splitting is defined by the orientation of the underlying geometrical edge. +"Reverse Edges" list box allows to specify the edges for which the splitting should be made +in the direction opposing to their orientation. This list box is enabled only if the geometry object +is selected for the meshing. In this case the user can select edges to be reversed either directly +picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser. + \image html a-startendlength.png \image html b-art_end_length.png "The lengths of the first and the last segment are strictly defined" @@ -175,4 +194,32 @@ minimum and maximum value of this parameter. \image html image147.gif "Example of a very rough mesh. Automatic Length works for 0." \image html image148.gif "Example of a very fine mesh. Automatic Length works for 1." + +
+\anchor fixed_points_1d_anchor +

Fixed points 1D hypothesis

+ +Fixed points 1D hypothesis allows splitting edges through a +set of points parameterized on the edge (from 1 to 0) and a number of segments for each +interval limited by the points. + +\image html hypo_fixedpnt_dlg.png + +It is possible to check in Same Nb. Segments for all intervals +option and to define one value for all intervals. + +The splitting direction is defined by the orientation of the +underlying geometrical edge. "Reverse Edges" list box allows to +specify the edges for which the splitting should be made in the +direction opposite to their orientation. This list box is enabled only +if the geometrical object is selected for meshing. In this case it is +possible to select the edges to be reversed either directly picking them in +the 3D viewer or selecting the edges or groups of edges in the +Object browser. + +\image html mesh_fixedpnt.png "Example of a submesh on the edge built using Fixed points 1D hypothesis" + +See Also a sample TUI Script of a +\ref tui_fixed_points "Defining Fixed Points" hypothesis operation. + */ diff --git a/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc b/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc index 6d89e53d5..d72e4d504 100644 --- a/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc +++ b/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc @@ -6,8 +6,7 @@
  • \ref max_element_area_anchor "Max Element Area"
  • \ref length_from_edges_anchor "Length from Edges"
  • -
  • \ref quadrangle_preference_anchor "Quadrangle Preference"
  • -
  • \ref triangle_preference_anchor "Triangle Preference"
  • +
  • \ref hypo_quad_params_anchor "Quadrangle parameters"

@@ -22,6 +21,8 @@ which will compose the mesh of these 2D faces. \image html a-maxelarea.png +\n + \image html max_el_area.png "In this example, Max. element area is very small compared to the 1D hypothesis" See Also a sample TUI Script of a @@ -39,24 +40,63 @@ length calculated as an average edge length for a given wire. \ref tui_length_from_edges "Length from Edges" hypothesis operation.
-\anchor quadrangle_preference_anchor -

Quadrangle Preference

+\anchor hypo_quad_params_anchor +

Quadrangle parameters

-This algorithm can be used only together with Quadrangle (Mapping) -algorithm. It allows to build quadrangular meshes even if the number -of nodes at the opposite edges of a meshed face is not equal, -otherwise this mesh will contain some triangular elements. -
-This hypothesis has one restriction on its work: the total quantity of -segments on all four sides of the face must be even (divisible by 2). +\image html hypo_quad_params_dialog.png "Quadrangle parameters creation/edition dialog" -
-\anchor triangle_preference_anchor -

Triangle Preference

+Quadrangle parameters is a hypothesis for Quadrangle (Mapping). + +Base vertex parameter allows using Quadrangle (Mapping) +algorithm for meshing of triangular faces. In this case it is +necessary to select the vertex, which will be used as the fourth edge +(degenerated). + +\image html hypo_quad_params_1.png "A face built from 3 edges" + +\image html hypo_quad_params_res.png "The resulting mesh" + +This parameter can be also used to mesh a segment of a circular face. +Please, consider that there is a limitation on the selection of the +vertex for the faces built with the angle > 180 degrees (see the picture). + +\image html hypo_quad_params_2.png "3/4 of a circular face" + +In this case, selection of a wrong vertex for the Base vertex +parameter will generate a wrong mesh. The picture below +shows the good (left) and the bad (right) results of meshing. + +\image html hypo_quad_params_res_2.png "The resulting meshes" + +Type parameter is used on faces with a different number of +segments on opposite sides to define the algorithm of transition +between them. The following types are available: + +
    +
  • Standard is the default case, when both triangles and quadrangles + are possible in the transition area along the finer meshed sides.
  • +
  • Triangle preference forces building only triangles in the + transition area along the finer meshed sides. + This type corresponds to Triangle Preference additional + hypothesis, which is obsolete now.
  • +
  • Quadrangle preference forces building only quadrangles in the + transition area along the finer meshed sides. This hypothesis has a + restriction: the total quantity of segments on all + four sides of the face must be even (divisible by 2).
  • + This type corresponds to Quadrangle Preference + additional hypothesis, which is obsolete now. +
  • Quadrangle preference (reversed) works in the same way and +with the same restriction as Quadrangle preference, but + the transition area is located along the coarser meshed sides.
  • +
  • Reduced type forces building only quadrangles and the transition + between the sides is made gradually, layer by layer. This type has + a limitation on the number of segments: one pair of opposite sides must have + the same number of segments, the other pair must have an even difference + between the numbers of segments on the sides.
  • +
+ +See Also a sample TUI Script of a +\ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis. -This algorithm can be used only together with Quadrangle (Mapping) -algorithm. It allows to build triangular mesh faces in the refinement -area if the number of nodes at the opposite edges of a meshed face is not equal, -otherwise refinement area will contain some quadrangular elements.
*/ diff --git a/doc/salome/gui/SMESH/input/about_filters.doc b/doc/salome/gui/SMESH/input/about_filters.doc new file mode 100644 index 000000000..22d88635f --- /dev/null +++ b/doc/salome/gui/SMESH/input/about_filters.doc @@ -0,0 +1,31 @@ +/*! + +\page filters_page About filters + +\b Filters allow picking only the mesh elements satisfying to a +specific condition or a set of conditions. Filters can be used to create +or edit mesh groups, remove elements from the mesh object, control +mesh quality by different parameters, etc. + +Several filters can be combined together by using logical operators \a +AND and \a OR. In addition, applied filter criterion can be reverted +using logical operator \a NOT. + +Mesh filters use the functionality of \ref quality_page "mesh quality controls" +to filter mesh nodes / elements by specific characteristic (Area, Length, etc). + +The functinality of mesh filters is available in both GUI and TUI +modes: + +- In GUI, filters are available in some dialog boxes via an additional +"Set Filters" button, clicking on which opens the dialog box +allowing to specify the list of filter criterions to be applied to the +current selection. See \subpage selection_filter_library_page page to learn more +about selection filters and their usage in GUI. + +- In Python scripts, filters can be used to choose only some mesh + entities (nodes and/or elements) for the operations, which require the + list of entities as input parameter (create/modify group, remove + nodes/elements, etc). The page \ref tui_filters_page provides + examples of the filters usage in Python scripts. +*/ diff --git a/doc/salome/gui/SMESH/input/about_hypo.doc b/doc/salome/gui/SMESH/input/about_hypo.doc index 578823bd6..5690ff36c 100644 --- a/doc/salome/gui/SMESH/input/about_hypo.doc +++ b/doc/salome/gui/SMESH/input/about_hypo.doc @@ -17,7 +17,7 @@ them, you operate numerical values): edges):
  • \ref arithmetic_1d_anchor "Arithmetic 1D"
  • -
  • \ref average_length_anchor "Average Length"
  • +
  • \ref average_length_anchor "Local Length"
  • \ref max_length_anchor "Max Size"
  • \ref deflection_1d_anchor "Deflection 1D"
  • \ref number_of_segments_anchor "Number of segments"
  • @@ -28,8 +28,7 @@ them, you operate numerical values):
    • \ref max_element_area_anchor "Max Element Area"
    • \ref length_from_edges_anchor "Length from Edges"
    • -
    • \ref quadrangle_preference_anchor "Quadrangle Preference"
    • -
    • \ref triangle_preference_anchor "Triangle Preference"
    • +
    • \ref hypo_quad_params_anchor "Quadrangle Parameters"
  • 3D Hypothesis (for meshing of volumes):
    • @@ -37,22 +36,15 @@ them, you operate numerical values):
-Some hypotheses are strictly combined with plug-in -meshers and thus, work only with definite algorithms. -
    -
  • \subpage netgen_2d_3d_hypo_page
  • - work with NetGen algorithm. -
  • \subpage ghs3d_hypo_page
  • - works with GHS3D algorithm. -
  • \subpage ghs3dprl_hypo_page
  • - works with GHS3DPRL (tepal) algorithm. -
  • \subpage blsurf_hypo_page
  • - works with BLSURF algorithm. -
- There also exist \subpage additional_hypo_page "Additional Hypotheses" used together with other hypotheses:
    -
  • Propagation of 1D Hypothesis on opposite edges
  • -
  • Non conform mesh allowed
  • -
  • Quadratic mesh
  • +
  • \ref propagation_anchor "Propagation of 1D Hypothesis on opposite edges"
  • +
  • \ref viscous_layers_anchor "Viscous layers"
  • +
  • \ref quadratic_mesh_anchor "Quadratic mesh"
  • +
  • \ref non_conform_allowed_anchor "Non conform mesh allowed"
  • +
  • \ref quadrangle_preference_anchor "Quadrangle preference"
The choice of a hypothesis depends on: diff --git a/doc/salome/gui/SMESH/input/about_meshes.doc b/doc/salome/gui/SMESH/input/about_meshes.doc index 61865173b..7474e0f62 100644 --- a/doc/salome/gui/SMESH/input/about_meshes.doc +++ b/doc/salome/gui/SMESH/input/about_meshes.doc @@ -5,20 +5,24 @@ \n \b MESH represents a discretization of a geometrical CAD model into a set of entities with a simple topology. -Meshes are stored in DAT, MED and UNV formats and can be +Meshes are stored in DAT, MED, UNV, STL, CGNS and SAUVE formats and can be \subpage importing_exporting_meshes_page "imported from and exported to" the file in these formats. -However, it is possible to \subpage constructing_meshes_page "construct meshes" +It is possible to \subpage constructing_meshes_page "construct meshes" on the basis of geometrical shapes produced in the GEOM module. -It is also possible to \subpage constructing_submeshes_page "create mesh on a part of the geometrical object", -for example, a face. +It is also possible to \subpage constructing_submeshes_page "mesh on a part of the geometrical object", +for example, a face, with different meshing parameters than the whole mesh. -Several created meshes can be \subpage building_compounds_page "combined into mesh compounds". +Several created meshes can be \subpage building_compounds_page "combined into another mesh". -All created meshes and submeshes can be \subpage editing_meshes_page "edited". +The whole mesh or it's part can be \subpage copy_mesh_page "copied" into another mesh. -Meshes can be also using the MESH functions destined for +Meshing parameters of meshes and sub-meshes can be +\subpage editing_meshes_page "edited", then only a path of mesh +depending on changed parameters will be re-computed. + +Meshes can be edited using the MESH functions destined for \ref modifying_meshes_page "modification" of generated meshes. The \b topology of a mesh is described by the relationships between its @@ -26,31 +30,34 @@ entities including:
  • \b Node — 0D object of a mesh presented by a point with coordinates (x, y, z).
  • +
  • \b 0D element — element of a mesh defined by one node.
  • \b Edge — 1D element of a mesh defined by two nodes.
  • \b Face — 2D element of a mesh defined by three or four edges (closed contour).
  • \b Volume — 3D element of a mesh defined by several faces.
  • +
  • \b Ball element — discrete element of a mesh defined by a node and a diameter.
        These entities are considered as topological entities and they don't imply any geometric representation. Only \b Nodes reference geometric representations of points with definite coordinates. The node entity -will contain additional information about its position in the space +contains additional information about its position in the space and its relations with the meshed CAD model. Its position could be described in the following way:
    -
  • 2D position. It is a free position defined by only two coordinates x,y.
  • -
  • 3D position. It is a free position defined by three coordinates x,y and z.
  • +
  • 3D position. It characterizes the position of a node in a + solid geometry and is defined by three coordinates x,y and z and a + reference to the solid geometrical entity.
  • Surface position. It characterizes the position of a node on a -geometric surface and is defined by the u,v position in the parametric -space of the corresponding surface.
  • + geometric surface and is defined by the u,v position in the parametric + space of the corresponding surface.
  • Line position. It characterizes the position of a node on a -geometric curve and is defined by the u parameter and the -corresponding curve.
  • + geometric curve and is defined by the u parameter and the + corresponding curve.
  • Vertex position. It characterizes the position of a node on a -geometric point of the meshed CAD model and is defined by the x,y,z -coordinates of the corresponding vertex.
  • + geometric point of the meshed CAD model and is defined by the x,y,z + coordinates of the corresponding vertex.

Connections

diff --git a/doc/salome/gui/SMESH/input/about_quality_controls.doc b/doc/salome/gui/SMESH/input/about_quality_controls.doc index 7f7fa95db..1e170e440 100644 --- a/doc/salome/gui/SMESH/input/about_quality_controls.doc +++ b/doc/salome/gui/SMESH/input/about_quality_controls.doc @@ -13,23 +13,29 @@ the meshing elements and these calculated values is shown with the help of a scalar bar, which is displayed near the presentation of your mesh. -There are 0D, 1D, 2D and 3D quality controls. +There are four types of quality controls, corresponding to node, edge, +face and volume entity type. -0D mesh quality controls: +Node quality controls:
    -
  • \ref free_nodes_page "Free nodes"
  • +
  • \subpage free_nodes_page "Free nodes"
  • +
  • \subpage double_nodes_control_page "Double nodes"
-1D mesh quality controls: +Edge quality controls:
    +
  • \subpage free_edges_page "Free edges"
  • \subpage free_borders_page "Free borders"
  • -
  • \subpage borders_at_multi_connection_page "Borders at multi-connection"
  • \subpage length_page "Length"
  • +
  • \subpage borders_at_multi_connection_page "Borders at multi-connection"
  • +
  • \subpage double_elements_page "Double edges"
-2D mesh quality controls: +Face quality controls:
    -
  • \subpage free_edges_page "Free edges"
  • +
  • \subpage free_faces_page "Free faces"
  • +
  • \subpage bare_border_faces_page "Bare border faces"
  • +
  • \subpage over_constrained_faces_page "Over-constrained faces"
  • \subpage length_2d_page "Length 2D"
  • \subpage borders_at_multi_connection_2d_page "Borders at multi-connection 2D"
  • \subpage area_page "Area"
  • @@ -38,13 +44,34 @@ There are 0D, 1D, 2D and 3D quality controls.
  • \subpage minimum_angle_page "Minimum angle"
  • \subpage warping_page "Warping"
  • \subpage skew_page "Skew"
  • +
  • \subpage max_element_length_2d_page "Element Diameter 2D"
  • +
  • \ref double_elements_page "Double faces"
-3D mesh quality controls: +Volume quality controls:
  • \subpage aspect_ratio_3d_page "Aspect ratio 3D"
  • \subpage volume_page "Volume"
  • -
  • \subpage free_faces_page "Free faces"
  • +
  • \subpage max_element_length_3d_page "Element Diameter 3D"
  • +
  • \subpage bare_border_volumes_page "Bare border volumes"
  • +
  • \subpage over_constrained_volumes_page "Over-constrained volumes"
  • +
  • \ref double_elements_page "Double volumes"
+To manage the quality controls call pop-up in the VTK viewer and select "Controls" sub-menu +\image html controls_popup.png + +
    +
  • Reset switches off quality controls;
  • +
  • Node Controls provides access to the node quality controls;
  • +
  • Edge Controls provides access to the edge quality controls;
  • +
  • Face Controls provides access to the face quality controls;
  • +
  • Volume Controls provides access to the volume quality controls;
  • +
  • Scalar Bar Properties allows setting \subpage scalar_bar_dlg;
  • +
  • Distribution -> Export ... allows saving the distribution of quality control values in the text file;
  • +
  • Distribution -> Show Shows/Hides the distribution histogram of the quality control values in the VTK Viewer.
  • +
  • Distribution -> Plot Plots the distribution histogram of the quality control values in the Plot 2D Viewer.
  • +
+ + */ diff --git a/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc b/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc index 179e7885a..a51bbdde4 100644 --- a/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc +++ b/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc @@ -6,12 +6,15 @@
  • \ref adding_nodes_anchor "Nodes"
  • +
  • \ref adding_0delems_anchor "0D Elements"
  • +
  • \ref adding_balls_anchor "Ball Elements"
  • \ref adding_edges_anchor "Edges"
  • \ref adding_triangles_anchor "Triangles"
  • \ref adding_quadrangles_anchor "Quadrangles"
  • \ref adding_polygons_anchor "Polygons"
  • \ref adding_tetrahedrons_anchor "Tetrahedrons"
  • \ref adding_hexahedrons_anchor "Hexahedrons"
  • +
  • \ref adding_octahedrons_anchor "Hexagonal prism"
  • \ref adding_polyhedrons_anchor "Polyhedrons"
@@ -25,6 +28,25 @@ following associated submenu will appear: \image html image146.png From this submenu select the type of element which you would like to add to your mesh. + +\note All dialogs for new node or element adding to the mesh (except for +the dialog for 0D elements) provide the possibility to automatically add +a node or element to the specified group or to create the anew using +Add to group box, that allows choosing an existing group for +the created node or element or giving the name to a new group. By +default, the Add to group check box is switched off. If the user +swiches this check box on, the combo box listing all currently +existing groups of the corresponding type becomes available. By +default, no group is selected. In this case, when the user presses +Apply or Apply & Close button, the warning message box +informs the user about the necessity to input new group name. The +combo box lists both \ref standalone_group "standalone groups" +and \ref group_on_geom "groups on geometry". If the user chooses a +group on geometry, he is warned and proposed to +\ref convert_to_standalone "convert this group to standalone". +If the user rejects conversion operation, it is cancelled and +a new node/element is not created! + See Also sample TUI Scripts of @@ -43,10 +65,29 @@ created: \image html add_node.png -\note You can also use variables defined in the SALOME \b NoteBook -to specify coordinates of the node: +
+\anchor adding_0delems_anchor +

Adding 0D elements

+ +\image html add0delement.png + +In this dialog box specify the node which will form your 0d element by +selecting it in the 3D viewer and click the \b Apply or +Apply and Close button. Your 0D element will be created: + +\image html add_0delement.png + +\anchor adding_balls_anchor +

Adding ball elements

-\image html addnode_notebook.png +\image html addball.png + +In this dialog box specify the node which will form your ball element +either by selecting it in the 3D viewer or by manual entering its ID, +specify a ball diameter and click the \b Apply or Apply and +Close button. Your ball element will be created: + +\image html add_ball.png
\anchor adding_edges_anchor @@ -120,6 +161,16 @@ the \b Apply or Apply and Close button. Your hexahedron will be created: \image html image71.jpg +
+\anchor adding_octahedrons_anchor +

Adding hexagonal prism

+ +In the Add Hexagonal Prism dialog box specify the nodes which will +form your hexagonal prism by selecting them in the 3D viewer with pressed Shift button and click +the \b Apply or Apply and Close button. Your hexagonal prism will be created: + +\image html image_octa12.png +
\anchor adding_polyhedrons_anchor

Adding polyhedrons

@@ -142,4 +193,4 @@ button. If you've managed to obtain the necessary result, click the \image html add_polyhedron.png -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc b/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc index afe9b77b5..921948630 100644 --- a/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc +++ b/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc @@ -2,7 +2,7 @@ \page adding_quadratic_elements_page Adding Quadratic Elements -\n MESH modules allows you to work with Quadratic Elements. +\n MESH module allows you to work with Quadratic Elements. Quadratic Edge is not a straight but a broken line and can be defined by three points: first, middle and last. All more complex \b Quadratic @@ -18,6 +18,25 @@ one of the following: \image html image152.png +\note All dialogs for quadratic element adding to the mesh +provide the possibility to automatically add an element +to the specified group or to create the group anew using +Add to group box, that allows choosing an existing group for +the created node or element or giving the name to a new group. By +default, the Add to group check box is switched off. If the user +swiches this check box on, the combo box listing all currently +existing groups of the corresponding type becomes available. By +default, no group is selected. In this case, when the user presses +Apply or Apply & Close button, the warning message box +informs the user about the necessity to input a new group name. The +combo box lists both \ref standalone_group "standalone groups" +and \ref group_on_geom "groups on geometry". If the user chooses a +group on geometry, he is warned and proposed to +\ref convert_to_standalone "convert this group to standalone". +If the user rejects conversion operation, it is cancelled and +a new quadratic element is not created. + + To create any Quadratic Element specify the nodes which will form your triangle by selecting them in the 3D viewer with pressed Shift button. Their numbers will appear in the dialog box as Corner Nodes diff --git a/doc/salome/gui/SMESH/input/additional_hypo.doc b/doc/salome/gui/SMESH/input/additional_hypo.doc index 9687bdf2d..61ac4800c 100644 --- a/doc/salome/gui/SMESH/input/additional_hypo.doc +++ b/doc/salome/gui/SMESH/input/additional_hypo.doc @@ -9,18 +9,21 @@ To define an Additional Hypothesis simply select it in Create Mesh menu. These hypotheses are actually changes in the rules of mesh creation and as such don't possess adjustable values. +\anchor non_conform_allowed_anchor

Non Conform mesh allowed hypothesis

Non Conform mesh allowed hypothesis allows to generate non-conform meshes (that is, meshes having some edges ending on an edge or face of adjacent elements). +\anchor quadratic_mesh_anchor

Quadratic Mesh

Quadratic Mesh hypothesis allows to build a quadratic mesh (whose edges are not straight but broken lines and can be defined by three points: first, middle and last) instead of an ordinary one. +\anchor propagation_anchor

Propagation of 1D Hypothesis on opposite edges

Propagation of 1D Hypothesis on opposite edges allows to propagate a @@ -28,8 +31,49 @@ hypothesis onto an opposite edge. If a local hypothesis and propagation are defined on an edge of a quadrangular face, the opposite edge will have the same hypothesis, unless another hypothesis has been locally defined on the opposite edge. - +
See Also a sample TUI Script of a -\ref tui_propagation "Propagation hypothesis" operation. +\ref tui_propagation "Propagation hypothesis" operation + +\anchor quadrangle_preference_anchor +

Quadrangle Preference

+ +This additional hypothesis can be used together with 2D triangulation algorithms. +It allows 2D triangulation algorithms to build quadrangular meshes. + +When used with "Quadrangle (Mapping)" meshing algorithm, that is obsolete + since introducing \ref hypo_quad_params_anchor "Quadrangle parameters" +hypothesis, this hypothesis has one restriction on its work: the total quantity of +segments on all four sides of the face must be even (divisible by 2). + +\anchor viscous_layers_anchor +

Viscous Layers

+ +Viscous Layers additional hypothesis can be used together with +some 3D algorithms, Hexahedron(i,j,k) for example. This +hypothesis allows creation of layers of highly stretched prisms near +mesh boundary, which is beneficial for high quality viscous +computations. The prisms constructed on the quadrangular mesh faces are +actually the hexahedrons. + + +\image html viscous_layers_hyp.png + +
    +
  • Name - allows to define the name of the hypothesis.
  • +
  • Total thicknes - gives the total thickness of prism layers.
  • +
  • Number of layers - defines the number of prism layers.
  • +
  • Stretch factor - defines the growth factor of prism height +from the mesh boundary inwards.
  • +
  • Faces without layers - defines geometrical faces on which +prism layers should not be constructed. By default the prism layers +are not constructed on geometrical faces shared by solids.
  • +
+ +\image html viscous_layers_mesh.png A group containing viscous layer prisms. + +
See also a sample TUI script of a \ref tui_viscous_layers +"Viscous layers construction". + -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/area.doc b/doc/salome/gui/SMESH/input/area.doc index bef0c0f8a..f650a3fd6 100644 --- a/doc/salome/gui/SMESH/input/area.doc +++ b/doc/salome/gui/SMESH/input/area.doc @@ -11,7 +11,8 @@ quadrangles).
  1. Display your mesh in the viewer.
  2. -
  3. Choose Controls > Area or click "Area" button. +
  4. Choose Controls > Face Controls > Area or click +"Area" button. \image html image35.png
    "Area" button
    diff --git a/doc/salome/gui/SMESH/input/aspect_ratio.doc b/doc/salome/gui/SMESH/input/aspect_ratio.doc index 070d377cc..af1057ddd 100644 --- a/doc/salome/gui/SMESH/input/aspect_ratio.doc +++ b/doc/salome/gui/SMESH/input/aspect_ratio.doc @@ -13,22 +13,23 @@ nodes is calculated by the formula: \image html formula4.png -- The Aspect Ratio of a \b quadrangle 2D element consisting of - 4 nodes is the worst (i.e. the greatest) value from all triangles - which can be built taking three nodes of the quadrangle. There are - four triangles to consider: +- The Aspect Ratio of a \b quadrangle 2D element consisting of 4 +nodes is calculated using The Verdict Geometric Quality Library +available within VTK. The calculation formula is: -\image html image138.gif +\image html formula5.png To apply the Aspect Ratio quality criterion to your mesh:
    1. Display your mesh in the viewer.
    2. -
    3. Choose Controls > Aspect Ratio or click "Aspect -Ratio" button in the toolbar. +
    4. Choose Controls > Face Controls > Aspect Ratio or click +"Aspect Ratio" button in the toolbar. +
      \image html image37.png -
      "Aspect Ratio" button
      +"Aspect Ratio" button +
      Your mesh will be displayed in the viewer with its elements colored according to the applied mesh quality control criterion: diff --git a/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc b/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc index 751e41102..2ea62f1f8 100644 --- a/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc +++ b/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc @@ -7,8 +7,8 @@ parameter as the \ref aspect_ratio_page "Aspect ratio" criterion, but it is applied to 3D mesh elements: tetrahedrons, pentahedrons, hexahedrons, etc. -- The Aspect Ratio of a \b tetrahedron 3D element is calculated -by the formula: +- The Aspect Ratio of a \b tetrahedron 3D element defined by +vertices {a,b,c,d } is calculated by the formula: \image html formula1.png @@ -21,8 +21,8 @@ by the formula:
      1. Display your mesh in the viewer.
      2. -
      3. Choose Controls > Aspect Ratio 3D or click "Aspect Ratio 3D" -button of the toolbar. +
      4. Choose Controls > Volume Controls > Aspect Ratio 3D or click +"Aspect Ratio 3D" button of the toolbar. \image html image144.png
        "Aspect Ratio 3D" button
        diff --git a/doc/salome/gui/SMESH/input/bare_border_face.doc b/doc/salome/gui/SMESH/input/bare_border_face.doc new file mode 100644 index 000000000..2115d3249 --- /dev/null +++ b/doc/salome/gui/SMESH/input/bare_border_face.doc @@ -0,0 +1,15 @@ +/*! + +\page bare_border_faces_page Bare border faces + +This mesh quality control highlights the faces having the border not +shared with other faces (free border) and missing an edge based on +nodes of the free border. The faces with bare border are shown with a +color different from the color of shared faces. + +\image html bare_border_faces_smpl.png + +\sa A sample TUI Script making a group of faces highlighted in the +picture is \ref tui_bare_border_faces "Bare border faces Control". + +*/ diff --git a/doc/salome/gui/SMESH/input/bare_border_volumes.doc b/doc/salome/gui/SMESH/input/bare_border_volumes.doc new file mode 100644 index 000000000..d0dd894ba --- /dev/null +++ b/doc/salome/gui/SMESH/input/bare_border_volumes.doc @@ -0,0 +1,15 @@ +/*! + +\page bare_border_volumes_page Bare border volumes + +This mesh quality control highlights the volumes having the border not +shared with other volumes (free border) and missing a face based on +nodes of the free border. The volumes with bare border are shown with a +color different from the color of shared volumes. + +\image html bare_border_volumes_smpl.png + +\sa A sample TUI Script making a group of volumes highlighted in the +picture is \ref tui_bare_border_volumes "Bare border volumes Control". + +*/ diff --git a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc index 1fd311d84..a4ebe1c8a 100644 --- a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc +++ b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc @@ -21,9 +21,8 @@ shape of a mesh.
      5. For meshing of 2D entities (faces):
        • -
        • Triangle meshing algorithms (Mefisto, Netgen 1D-2D and BLSUFR ) - Faces -are split into triangular elements.
        • -
        • Quadrangle meshing algorithm (Mapping) - Faces are split into +
        • Triangle meshing algorithms (Mefisto) - Faces are split into triangular elements.
        • +
        • Quadrangle meshing algorithm (Mapping) - quadrilateral Faces are split into quadrangular elements.
        @@ -34,10 +33,12 @@ quadrangular elements.
      6. For meshing of 3D entities (volume objects):
        • -
        • Hexahedron meshing algorithm (i,j,k) - Volumes are split into +
        • Hexahedron meshing algorithm (i,j,k) - 6-sided Volumes are split into hexahedral (cubic) elements.
        • -
        • Tetrahedron (Netgen and GHS3D) meshing algorithms - Volumes are split into -tetrahedral (pyramidal) elements.
        • +
        • \subpage cartesian_algo_page
        • +internal parts of Volumes are split into hexahedral elements forming a +Cartesian grid; polyhedra and other types of elements are generated +where the geometrical boundary intersects Cartesian cells.
        \image html image125.gif "Example of a tetrahedral 3D mesh" @@ -45,16 +46,25 @@ tetrahedral (pyramidal) elements. \image html image126.gif "Example of a hexahedral 3D mesh" -\Note that BLSURF and GHS3D are commercial meshers and require a -license to be used within the Mesh module. +Some of 3D meshing algorithms also can generate 3D meshes from 2D meshes, working without +geometrical objects. Such algorithms are +
          +
        • Hexahedron meshing algorithm (i,j,k),
        • + +
        There is also a number of more specific algorithms:
        • \subpage projection_algos_page "for meshing by projection of another mesh"
        • +
        • \subpage import_algos_page "for meshing by importing elements from another mesh"
        • \subpage radial_prism_algo_page "for meshing geometrical objects with cavities"
        • \subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"
        • \subpage prism_3d_algo_page "for meshing prismatic shapes"
        • +
        • \subpage radial_quadrangle_1D2D_algo_page "for meshing special 2d faces (circles and part of circles)"
        +\ref use_existing_anchor "Use existing edges" and +\ref use_existing_anchor "Use existing faces" algorithms can be +used to create an 1D or a 2D mesh in a python script. \ref constructing_meshes_page "Constructing meshes" page describes in detail how to apply meshing algorithms. @@ -62,4 +72,4 @@ detail how to apply meshing algorithms.
        See Also a sample TUI Script of a \ref tui_defining_meshing_algos "Define Meshing Algorithm" operation. -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/blsurf_hypo.doc b/doc/salome/gui/SMESH/input/blsurf_hypo.doc deleted file mode 100644 index b392f3b72..000000000 --- a/doc/salome/gui/SMESH/input/blsurf_hypo.doc +++ /dev/null @@ -1,222 +0,0 @@ -/*! - -\page blsurf_hypo_page BLSURF Parameters hypothesis - -\n BLSURF Parameters hypothesis works only with BLSURF 2d -algorithm. This algorithm is a commercial software. - -\image html blsurf_parameters.png - -
          -
        • Name - allows defining the name of the hypothesis (BLSURF -Parameters_n by default).
        • - -
        • Physical Mesh - if set to "Custom", allows user input in te -in User size, Max Physical Size and Min Physical -Size fields. -
        • - -
        • User size - defines the size of the generated mesh elements.
        • - -
        • Max Physical Size - defines the upper limit of mesh element size.
        • - -
        • Min Physical Size - defines the lower limit of mesh element size.
        • - -
        • Geometrical mesh - if set to "Custom", allows user input in - Angle Mesh S, Angle Mesh C and -Gradation fields. These fields control -computation of the element size, so called geometrical size, conform to -the surface geometry considering local curvatures. \n -If both the User size and the geometrical size are defined, the - eventual element size correspond to the least of the two.
        • - -
        • Angle Mesh S - maximum angle between the mesh face and the -tangent to the geometrical surface at each mesh node, in degrees.
        • - -
        • Angle Mesh C - maximum angle between the mesh edge and the -tangent to the geometrical curve at each mesh node, in degrees.
        • - -
        • Max Geometrical Size - defines the upper limit of the geometrical size.
        • - -
        • Min Geometrical Size - defines the lower limit of the geometrical size.
        • - -
        • Gradation - maximum ratio between the lengths of -two adjacent edges.
        • - -
        • Allow Quadrangles - if checked, allows the creation of quadrilateral elements.
        • - -
        • Patch independent - if checked, geometrical -edges are not respected and all geometrical faces are meshed as one -hyper-face.
        • - -\image html blsurf_parameters_advanced.png - -
        • Topology - allows creation of a conform mesh on a shell of -not sewed faces. -
            -
          • "From CAD" means that mesh conformity is assured by conformity - of a shape.
          • -
          • "Pre-process" and "Pre-process++" allow the BLSURF software to - pre-process the geometrical model to eventually produce a conform - mesh.
          • -
          - -
        • Verbosity level - Defines the percentage of "verbosity" of -BLSURF [0-100].
        • - -
        • Add option - provides the choice of multiple advanced -options, which appear, if selected, in a table where it is possible to -input the value of the option and to edit it later.
        • - -
        • Clear option - removes the option selected in the table. - -
        - -\n -The following options are commonly usable. The notion of diag -used in the descriptions means -the diagonal of the bounding box of the geometrical object to mesh. - -
          -
        • topo_eps1 (real) - is the tolerance level inside a CAD -patch. By default is equal to diag × 10-4. This tolerance is used to -identify nodes to merge within one geometrical face when \b Topology -option is to pre-process. Default is diag/10.0.
        • - -
        • topo_eps2 (real) - is the tolerance level between two CAD -patches. By default is equal to diag × 10-4. This tolerance is used to -identify nodes to merge over different geometrical faces when -\b Topology option is to pre-process. Default is diag/10.0.
        • - -
        • \b LSS (real) - is an abbreviation for "length of sub-segment". It is -a maximal allowed length of a mesh edge. Default is 0.5.
        • - -
        • \b frontal (integer) -
            -
          • 1 - the mesh generator inserts points with an advancing front method.
          • -
          • 0 - it inserts them with an algebraic method (on internal edges). This method is -slightly faster but generates less regular meshes.
          • -
          -Default is 0.
        • - -
        • \b hinterpol_flag (integer) - determines the computation of an -interpolated value v between two points P1 and P2 on a -curve. Let h1 be the value at point P1, h2 be the value at point -P2, and t be a parameter varying from 0 to 1 when moving from P1 -to P2 . -
            -
          • 0 - the interpolation is linear: v = h1 + t (h2 - h1 )
          • -
          • 1 - the interpolation is geometric: v = h1 * pow( h2/h1, t)
          • -
          • 2 - the interpolation is sinusoidal: v = (h1+h2)/2 + -(h1-h2)/2*cos(PI*t)
          • -
          -Default is 0.
        • - -
        • \b hmean_flag (integer) - determines the computation of the average of several -values:
            -
          • -1 - the minimum is computed.
          • -
          • 0 or 2 - the arithmetic average computed. -
          • 1 - the geometric average is computed.
          • -
          -Default is 0.
        • - -
        • \b CheckAdjacentEdges, \b CheckCloseEdges and \b CheckWellDefined -(integers) - gives the number of calls of equally named subroutines the -purpose of which is to improve the mesh of domains having narrow -parts. At each iteration,\b CheckCloseEdges decreases the sizes of the -edges when two boundary curves are neighboring,\b CheckAdjacentEdges -balances the sizes of adjacent edges, and \b CheckWellDefined checks if -the parametric domain is well defined. Default values are 0.
        • - - -
        • \b CoefRectangle (real)- defines the relative thickness of the rectangles -used by subroutine \b CheckCloseEdges (see above). Default is 0.25.
        • - -
        • \b eps_collapse (real) - if more than 0.0, BLSURF removes -curves whose lengths are less than \b eps_collapse. To obtain an -approximate value of the length of a curve, it is arbitrarily -split into 20 edges. Default is 0.0.
        • - -
        • \b eps_ends (real) - is used to detect the curves whose lengths are very -small, which sometimes constitutes an error. A message is printed -if fabs(P2-P1) < eps_ends, where P1 and P2 are the -extremities of a curve. Default is diag/500.0.
        • - -
        • \b prefix (char) - is a prefix of the files generated by -BLSURF. Default is "x".
        • - -
        • \b refs (integer) - reference of a surface, used when exporting -files. Default is 1.
        • -
        - -\n -The following advanced options are not documented and you can use them -at your own risk. -\n\n Interger variables: -
          -
        • addsurf_ivertex
        • -
        • background
        • -
        • coiter
        • -
        • communication
        • -
        • decim
        • -
        • export_flag
        • -
        • file_h
        • -
        • gridnu
        • -
        • gridnv
        • -
        • intermedfile
        • -
        • memory
        • -
        • normals
        • -
        • optim
        • -
        • pardom_flag
        • -
        • pinch
        • -
        • rigid
        • -
        • surforient
        • -
        • tconf
        • -
        • topo_collapse
        • -
        -Real variables: -
          -
        • addsurf_angle
        • -
        • addsurf_R
        • -
        • addsurf_H
        • -
        • addsurf_FG
        • -
        • addsurf_r
        • -
        • addsurf_PA
        • -
        • angle_compcurv
        • -
        • angle_ridge
        • -
        • eps_pardom
        • -
        -String variables: -
          -
        • export_format
        • -
        • export_option
        • -
        • import_option
        • -
        - - -\n -Currently BLSURF plugin has the following limitations. -
          -
        • The created mesh will contain inverted elements if it is based on a shape, - consisting of more than one face (box, cone, torus...) and if - the option "Allow Quadrangles (Test)" has been checked before - computation.
        • - -
        • SIGFPE exception is raised at the attempt to compute the mesh - based on a box when the option "Patch independent" is checked.
        • - -
        • BLSURF algorithm cannot be used as a local algorithm (on - sub-meshes) or as a provider of a low-level - mesh for some 3D algorithms, because the BLSURF mesher (and - consequently plugin) does not provide the information on node - parameters on edges (U) and faces (U,V). For example the - following combinations of algorithms are impossible: -
            -
          • global MEFISTO or Quadrangle(mapping) + local BLSURF;
          • -
          • BLSUFR + Projection 2D from faces meshed by BLSURF;
          • -
          • local BLSURF + Extrusion 3D;
          • -
          -
        • -
        - -*/ diff --git a/doc/salome/gui/SMESH/input/building_compounds.doc b/doc/salome/gui/SMESH/input/building_compounds.doc index faf636b82..98a20c470 100644 --- a/doc/salome/gui/SMESH/input/building_compounds.doc +++ b/doc/salome/gui/SMESH/input/building_compounds.doc @@ -47,4 +47,6 @@ for this operation. \image html image160.gif "Example of a compound of two meshed cubes" +See Also a sample +\ref tui_building_compound "TUI Example of building compounds." */ diff --git a/doc/salome/gui/SMESH/input/cartesian_algo.doc b/doc/salome/gui/SMESH/input/cartesian_algo.doc new file mode 100644 index 000000000..3240150c7 --- /dev/null +++ b/doc/salome/gui/SMESH/input/cartesian_algo.doc @@ -0,0 +1,75 @@ +/*! + +\page cartesian_algo_page Body Fitting 3D meshing algorithm + +Body Fitting algorithm generates hexahedrons of a Cartesian grid in +the internal part of geometry and polyhedrons and other types of +elements at the intersection of Cartesian cells with the geometrical +boundary. + +\image html cartesian3D_sphere.png "A shpere meshed by Body Fitting algorithm" + +The meshing algorithm is as follows. +
          +
        1. Lines of a Cartesian structured grid defined by +\ref cartesian_hyp_anchor "Body Fitting Parameters" hypothesis are +intersected with the geometry boundary, thus nodes lying on the +boundary are found. This step also allows finding out for each node of +the Cartesian grid if it is inside or outside the geometry.
        2. +
        3. For each cell of the grid, check how many of its nodes are outside +of the geometry boundary. Depending on a result of this check +
            +
          • skip a cell, if all its nodes are outside
          • +
          • skip a cell, if it is too small according to Size + Threshold parameter
          • +
          • add a hexahedron in the mesh, if all nodes are inside
          • +
          • add a polyhedron or another cell type in the mesh, if some +nodes are inside and some outside.
          • +
          +
        4. +
        +To apply this algorithm when you define your mesh, select Body + Fitting in the list of 3D algorithms and click "Add + Hypothesis" button and "Body Fitting Parameters"" menu + item. Dialog of Body Fitting Parameters + hypothesis will appear. + +
        +\anchor cartesian_hyp_anchor +

        Body Fitting Parameters hypothesis

        + +\image html cartesian3D_hyp.png "Body Fitting Parameters hypothesis dialog" + +This dialog allows to define +
          +
        • \b Name of the algorithm
        • +
        • Minimal size of a cell truncated by the geometry boundary. If the + size of a truncated grid cell is \b Threshold times less than a + initial cell size, then a mesh element is not created.
        • +
        • Cartesian structured grid. Each grid axis is defined + individually. Definition mode chooses a way of grid + definition:
            +
          • You can specify the \b Coordinates of grid nodes. \b Insert button + inserts a node at distance \b Step (negative or positive) from a + selected node. \b Delete button removes a selected node. Double + click on a coordinate in the list enables its edition. A grid + defined by \b Coordinates should enclose the geometry, else the + algorithm will fail.
          • +
          • You can define the \b Spacing of a grid as an algebraic formula + f(t) where \a t is a position along a grid axis + normalized at [0.0,1.0]. The whole range of geometry can be + divided into sub-ranges with their own spacing formulas to apply; + \a t varies between 0.0 and 1.0 within each sub-range. \b Insert button + divides a selected range into two ones. \b Delete button adds the + selected sub-range to the previous one. Double click on a range in + the list enables edition of its right boundary. Double click on a + function in the list enables its edition. +
          +
        • +
        + +
        +See Also a sample TUI Script of a +\ref tui_cartesian_algo "Usage of Body Fitting algorithm". + +*/ diff --git a/doc/salome/gui/SMESH/input/changing_orientation_of_elements.doc b/doc/salome/gui/SMESH/input/changing_orientation_of_elements.doc index 410245b04..416f9514c 100644 --- a/doc/salome/gui/SMESH/input/changing_orientation_of_elements.doc +++ b/doc/salome/gui/SMESH/input/changing_orientation_of_elements.doc @@ -2,8 +2,7 @@ \page changing_orientation_of_elements_page Changing orientation of elements -\n Orientation of an element is changed by reverting the order of -nodes of the selected elements. +\n Orientation of an element is changed by reverting the order of its nodes. To change orientation of elements:
          @@ -11,13 +10,16 @@ nodes of the selected elements.
        1. In the \b Modification menu select the \b Orientation item or click Orientation button in the toolbar. +
          \image html image79.png -
          "Orientation" button
          +"Orientation" button +
          The following dialog box will appear: +
          \image html orientaation1.png - +
          • The main list shall contain the elements which will be reoriented. You can click on an element in the 3D viewer and it will diff --git a/doc/salome/gui/SMESH/input/clipping.doc b/doc/salome/gui/SMESH/input/clipping.doc index f3b19f374..2bfa8292b 100644 --- a/doc/salome/gui/SMESH/input/clipping.doc +++ b/doc/salome/gui/SMESH/input/clipping.doc @@ -9,12 +9,20 @@ To start, click on the \em New button. \image html a-clipping2.png -Now you can define the parameters of your cross-section: \b Orientation -(X-Y, X-Z or Y-Z); \b Distance between the opposite extremities of the -object, if it is set to 0.5 the object is split in two halves; and -\b Rotation (in angle degrees) around X (Y to Z) and around Y (X to -Z). If the Show preview button is on, you can see the clipping plane -in the 3D Viewer. +Now you can define the parameters of cross-section: +
              +
            • List of meshes, sub-meshes and groups to which the cross-section will be applied. +/n Select all button allows to select and deselect all available +objects at once).
            • +
            • \b Orientation (X-Y, X-Z or Y-Z).
            • +
            • \b Distance between the opposite extremities of the boundary box +of selected objects, if it is set +to 0.5 the boundary box is split in two halves.
            • +
            • \b Rotation (in angle +degrees) around X (Y to Z) and around Y (X to Z).
            • +
            • If the Show preview button is on, you can see the clipping plane +in the 3D Viewer.
            • +
            \image html image79.jpg "The plane and the cut object" diff --git a/doc/salome/gui/SMESH/input/colors_size.doc b/doc/salome/gui/SMESH/input/colors_size.doc new file mode 100644 index 000000000..f953b37c6 --- /dev/null +++ b/doc/salome/gui/SMESH/input/colors_size.doc @@ -0,0 +1,37 @@ +/*! + +\page colors_size_page Properties + +\image html colors_size.png + +Using this dialog you can define the following set of mesh visualization +parameters: +
              +
            • Elements
            • +
                +
              • Surface color - surface color of elements (seen in Shading mode).
              • +
              • Back surface color - interior surface color of elements. Use slider to select this color +generated on base of the Surface color by changing its brightness and saturation.
              • +
              • Outline color - color of element borders.
              • +
              • Wireframe color - color of element borders in wireframe mode.
              • +
              • 0D slements - color of 0D elements.
              • +
              • Size of 0D slements - size of 0D elements.
              • +
              • Line width - width of lines (edges and borders of elements).
              • +
              • Shrink coef. - relative space of elements compared to gaps between + them in shrink mode.
              • +
              +
            • Nodes
            • +
                +
              • Color - color of nodes.
              • +
              • Marker - group of options allowing to change the representation of + points (see \subpage point_marker_page "Point Marker" page).
              • +
              +
            • Orientation of faces
            • +
                +
              • Color - color of orientation vertors.
              • +
              • Scale - size of orientation vectors.
              • +
              • 3D vectors - allows to choose between 2D planar and 3D vectors.
              • +
              +
            + +*/ diff --git a/doc/salome/gui/SMESH/input/constructing_meshes.doc b/doc/salome/gui/SMESH/input/constructing_meshes.doc index d62feac7c..adf63c6a1 100644 --- a/doc/salome/gui/SMESH/input/constructing_meshes.doc +++ b/doc/salome/gui/SMESH/input/constructing_meshes.doc @@ -2,83 +2,250 @@ \page constructing_meshes_page Constructing meshes -\n Construction of a mesh consists of: +\n Construction of a mesh on some geometry consists of:
              -
            • Selecting a geometrical object for meshing
            • -
            • Applying \subpage basic_meshing_algos_page "meshing algorithms" and -\subpage about_hypo_page "hypotheses" which will be used at computation of -this mesh.
            • +
            • \ref create_mesh_anchor "Creating of a mesh object"
            • +
            • \ref evaluate_anchor "Evaluating mesh size"
            • +
            • \ref preview_anchor "Previewing the mesh"
            • +
            • \ref submesh_order_anchor "Changing submesh priority"
            • +
            • \ref compute_anchor "Computing the mesh"
            +Mesh can be \ref use_existing_anchor "computed using your own meshing algorithms" +written in Python. + +\anchor create_mesh_anchor +

            Creation of a mesh object

            To construct a mesh:
              -
            1. In the \b Mesh menu select Create Mesh or click "Create -Mesh" button in the toolbar. +
            2. Select a geometrical object for meshing.
            3. +
            4. In the \b Mesh menu select Create Mesh or click "Create + Mesh" button in the toolbar. + + \image html image32.png + "Create Mesh" button + + The following dialog box will appear: + + \image html createmesh-inv.png +
              +
            5. +
            6. Apply \subpage basic_meshing_algos_page "meshing algorithms" and + \subpage about_hypo_page "hypotheses" which will be used at computation of + this mesh. + + For example, you need to mesh a 3D object. + + First, type the name for your mesh in the \b Name box, by default, + it is "Mesh_1". Then select the geometrical object you wish to + mesh in the Object Browser and click "Select" button near \b Geometry + field (if name of the object not yet appeared in \b Geometry field). + + \image html image120.png + "Select" button + + Now you can define 3D Algorithm and 3D Hypotheses, which will be + applied to solids of your geometrical object. Click the "Add + Hypothesis" button to add a hypothesis. + + \image html image121.png + "Add Hypothesis" button + + Click the "Edit Hypothesis" button to change values for the + current hypothesis. + + \image html image122.png + "Edit Hypothesis" button + + Most standard 2D and 3D algorithms can work without hypotheses + using some default parameters. The use of additional hypotheses + is optional (i.e. you may leave "None" in this box). + + Proceed in the same way with 2D and 1D Algorithms and Hypotheses that + will be used to mesh faces and edges of your geometry. (Note + that any object has edges, even if their existence is not + apparent, for example, a sphere has 4 edges). Note that the + choice of hypotheses and of an algorithm of lower dimension depends on + the algorithm. + + Some algorithms generate mesh of several dimensions while others, of + only one dimension. In the latter case there must be one Algorithm and zero or several + Hypotheses for each dimension of your object, otherwise you will + not get any mesh at all. Of course, if you wish to mesh a face, + which is a 2D object, you don't need to define 3D Algorithm and + Hypotheses. + + In the Object Browser the structure of the new mesh will be + displayed as follows: + + \image html image88.jpg + + It contains: +
                +
              • a reference to the geometrical object on the basis of + which the mesh has been constructed;
              • +
              • Applied hypotheses folder containing the references + to the hypotheses applied at the construction of the mesh;
              • +
              • Applied algorithms folder containing the references + to the algorithms applied at the construction of the mesh.
              • +
              + + There is an alternative way to assign Algorithms and Hypotheses by + clicking Assign a set of hypotheses button and selecting among + pre-defined sets of hypotheses. In addition to the standard + sets of hypotheses, it is possible to create custom sets by editing + CustomMeshers.xml file located in the home directory. CustomMeshers.xml + file must describe sets of hypotheses in the + same way as ${SMESH_ROOT_DIR}/share/salome/resources/smesh/StdMeshers.xml + file does (sets of hypotheses are enclosed between + tags). + + \image html hypo_sets.png + List of sets of hypotheses: [custom] + automatically added to the sets defined by the user +
            7. +
            + +Consider trying a sample script for construction of a mesh from our +\ref tui_creating_meshes_page "TUI Scripts" section. + +\anchor evaluate_anchor +

            Evaluating mesh size

            + +After the mesh object is created and all hypotheses are assigned and +before \ref compute_anchor "Compute" operation, it is possible to +calculate the eventual mesh size. For this, select the mesh in +the Object Browser and from the \b Mesh menu select \b +Evaluate. The result of evaluation will be displayed in the following +information box: + +\image html mesh_evaluation_succeed.png + +\anchor preview_anchor +

            Previewing the mesh

            + +Before \ref compute_anchor "the mesh computation", it is also possible +to see the mesh preview. -\image html image32.png -
            "Create Mesh" button
            +For this, select the mesh in the Object Browser. From the \b Mesh menu +select \b Preview or click "Preview" button in the toolbar or activate +"Preview" item from the pop-up menu. -The following dialog box will appear: +\image html mesh_precompute.png +"Preview" button -\image html createmesh-inv.png -
          • -
          • For example, you need to mesh a 3d object. -\n First, type the name for your mesh in the "Name" box, by default, -it is "Mesh_1". Then select the object you wish to mesh in the Object -Browser and click the "Add" button. +Select 1D mesh or 2D mesh preview mode in the Preview dialog. -\image html image120.png -
            "Add" button
            +\image html preview_mesh_1D.png "1D mesh preview shows nodes computed on geometry edges" +
            +\image html preview_mesh_2D.png "2D mesh preview shows edge mesh elements, computed on geometry faces" -Now you can define 1d Algorithm and 1d Hypotheses, which will be -applied to the edges of your object. (Note that any object has edges, -even if their existence is not apparent, for example, a sphere has 4 -edges). Click the "Add Hypothesis" button to add a hypothesis. +Compute button computes the whole mesh. -\image html image121.png -
            "Add Hypothesis" button
            +When the Preview dialog is closed, the question about the storage of temporarily +created mesh elements appers: -Click the "Edit Hypothesis" button to define values for the -current hypothesis. +\image html preview_tmp_data.png -\image html image122.png -
            "Edit Hypothesis" button
            +These elements can be kept in the mesh. -The use of additional hypotheses is optional (i.e. you may leave -"None" in this box). -Proceed in the same way with 2d and 3d Algorithms and Hypotheses, note -that the choice of hypotheses depends on the algorithm. There must be -one Algorithm and one or several Hypotheses for each dimension of your -object, otherwise you will not get any mesh at all. Of course, if you -wish to mesh a face, which is a 2d object, you don't need to define 3d -Algorithm and Hypotheses. -\n In the Object Browser the structure of the new mesh will be -displayed as follows: +\anchor submesh_order_anchor +

            Changing submesh priority

            -\image html image88.jpg +If the mesh contains concurrent \ref constructing_submeshes_page "submeshes", +it is possible to change the priority of their computation, i.e. to +change the priority of applying algorithms to the shared sub-shapes of +the Mesh shape. -It contains: +To change submesh priority: + +Choose "Change submesh priority" from the Mesh menu or a pop-up +menu. The opened dialog shows a list of submeshes in the order of +their priority. + +There is an example of submesh order modifications of the Mesh created on a Box +shape. The main Mesh object: +
              +
            • 1D Wire discretisation with Number of Segments=20
            • +
            • 2D Triangle (Mefisto) with HypothesisMax Element Area +
            • +
            +The first submesh object Submesh_1 created on Face_1 is: +
              +
            • 1D Wire discretisation with Number of Segments=4
            • +
            • 2D Triangle (Mefisto) with HypothesisMaxElementArea=1200
            • +
            +The second submesh object Submesh_2 created on Face_2 is: +
              +
            • 1D Wire discretisation with Number of Segments=8
            • +
            • 2D Triangle (Mefisto) with HypothesisMaxElementArea=1200
            • +
            + +And the last submesh object Submesh_3 created on Face_3 is:
              -
            • a reference to the geometrical object on the basis of which the mesh has been constructed;
            • -
            • Applied hypotheses folder containing the references to the -hypotheses applied to the construction of the mesh;
            • -
            • Applied algorithms folder containing the references to the -algorithms applied to the construction of the mesh.
            • +
            • 1D Wire discretisation with Number of Segments=12
            • +
            • 2D Triangle (Mefisto) with HypothesisMaxElementArea=1200
            -There is an alternative way to create a mesh on an object simply by -clicking Assign a set of hypotheses button and selecting between -Automatic Tetrahedralization or Hexahedralization. The program will -automatically generate a 3D mesh with the most appropriate -settings. In the same way you can apply this functionality for meshing -2D objects, in which case 3D algorithms are not applied.
          • -
          • Now, when everything is ready, select your mesh in the Object -Browser. From the \b Mesh menu select \b Compute or click "Compute" button of the -toolbar. +The sub-meshes become concurrent if they share sub-shapes that can be +meshed with different algorithms (or different hypothesises). In the +example, we have three submeshes with concurrent algorithms, because +they have different hypotheses. + +The first mesh computation is made with: +
            +\image html mesh_order_123.png +"Mesh order SubMesh_1, SubMesh_2, SubMesh_3"
            +
            +\image html mesh_order_123_res.png +"Result mesh with order SubMesh_1, SubMesh_2, SubMesh_3 "
            + +The next mesh computation is made with: +
            +\image html mesh_order_213.png +"Mesh order SubMesh_2, SubMesh_1, SubMesh_3"
            +
            +\image html mesh_order_213_res.png +"Result mesh with order SubMesh_2, SubMesh_1, SubMesh_3 "
            + +And the last mesh computation is made with: +
            +\image html mesh_order_321.png +"Mesh order SubMesh_3, SubMesh_2, SubMesh_1"
            +
            \image html mesh_order_321_res.png +"Result mesh with order SubMesh_3, SubMesh_2, SubMesh_1 "
            + +As we can see, each mesh computation has a different number of result +elements and a different mesh discretisation on the shared edges (the edges +that are shared between Face_1, Face_2 and Face_3) + +Additionally, submesh priority (the order of applied algorithms) can +be modified not only in a separate dialog box, but also in +the Preview. This helps to preview different mesh results, +modifying the order of submeshes. +
            +\image html mesh_order_preview.png +"Preview with submesh priority list box"
            + +If there are no concurrent submeshes under the Mesh object, the user +will see the following information. +
            +\image html mesh_order_no_concurrent.png +"No concurrent submeshes detected"
            + + +\anchor compute_anchor +

            Computing the mesh

            + +It is equally possible to skip \ref evaluate_anchor "the Evaluation" +and \ref preview_anchor "the Preview" and to \b Compute the mesh after +the hypotheses are assigned. For this, select your mesh in +the Object Browser. From the \b Mesh menu select \b Compute or +click "Compute" button of the toolbar. \image html image28.png -
            "Compute" button
            +"Compute" button The Mesh Computation information box appears. @@ -89,33 +256,58 @@ failure is provided. \image html meshcomputationfail.png -After you select the error, Show Subshape button allows -visualizing the geometrical entity that causes it. +After you select the error, Show Sub-shape button allows +visualizing in magenta the geometrical entity that causes it. -\image html failed_computation.png "Example of the invalid input mesh" +\image html failed_computation.png +3D algorithm failed to compute mesh on a box shown using Show + Sub-shape button -\Note Mesh Computation Information box does not appear if you set + +\note Mesh Computation Information box does not appear if you set "Mesh computation/Show a computation result notification" preference to the "Never" value. This option gives the possibility to control mesh computation reporting. There are the following possibilities: always show information box, only if an error occurs or never. By default, the information box is always shown after mesh computation operation. -Publish Subshape button publishes the subshape, whose meshing +Publish Sub-shape button publishes the sub-shape, whose meshing failed, in GEOM component as a child of the mesh geometry, which allows analyzing the problem geometry and creating a submesh on it in order to locally tune hypotheses. -NOTE It is possible to define a 1D or a 2D mesh in a -python script and then use such submeshes in the construction of a 3D -mesh. For this, there exist two algorithms: Use existing edges and Use -existing faces. They are not entirely usable from the GUI, so a -mesh created using these algorithms should be exported into a python -script, edited and then imported into the GUi. +If a cause of failure is an invalid input mesh and the algorithm has +provided information on what mesh entities are bad Show bad Mesh +button appears in the dialog. Clicked, it shows bad mesh entities in +the Viewer in magenta. Sometimes the shown mesh entities are too small +or/and hidden by other mesh elements, to see them it can be helpful to +switch the mesh to Wireframe visualization mode or to switch off +visualization of faces and volumes (if any). -Consider trying a sample script for construction of a mesh from our -\ref tui_creating_meshes_page "TUI Scripts" section. -
          • -
        +\anchor use_existing_anchor +

        "Use existing edges" and "Use existing faces" algorithms

        + +It is possible to create an 1D or a 2D mesh in a python script +(using AddNode, AddEdge and AddFace commands) and +then use such sub-meshes in the construction of a 2D or a 3D mesh. For +this, there exist two algorithms: Use existing edges and Use + existing faces. Scenario of their usage is following. For +example, you want to use standard algorithms to generate 1D and 3D +meshes and to create 2D mesh by your python code. Then you +
          +
        • create a mesh object, assign an 1D algorithm,
        • +
        • invoke \b Compute command, which computes an 1D mesh,
        • +
        • assign Use existing faces and a 3D algorithm,
        • +
        • run your python code, which creates a 2D mesh,
        • +
        • invoke \b Compute command, which computes a 3D mesh.
        • +
        + +Consider trying a sample script demonstrating usage of +\ref tui_use_existing_faces "Use existing faces" algorithm for +construction of a 2D mesh using Python commands. + +\image html use_existing_face_sample_mesh.png + Mesh computed by \ref tui_use_existing_faces "the sample script" + shown in a Shrink mode. -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/constructing_submeshes.doc b/doc/salome/gui/SMESH/input/constructing_submeshes.doc index a17569f7c..f300d6f50 100644 --- a/doc/salome/gui/SMESH/input/constructing_submeshes.doc +++ b/doc/salome/gui/SMESH/input/constructing_submeshes.doc @@ -1,41 +1,43 @@ /*! -\page constructing_submeshes_page Constructing submeshes +\page constructing_submeshes_page Constructing sub-meshes -Submesh is a mesh on a geometrical subobject created with algorithms +Sub-mesh is a mesh on a geometrical sub-object created with algorithms and/or hypotheses other than the algorithms and hypotheses assigned to the parent mesh on the parent object.

        -If a geometrical subobject belongs to several geometrical objects -having different meshes or submeshes, it will be meshed with the -hypotheses of a submesh of a lower dimension.
        -For example, a face of a box is meshed with a submesh using algorithms +If a geometrical sub-object belongs to several geometrical objects +having different meshes or sub-meshes, it will be meshed with the +hypotheses of a sub-mesh of a lower dimension.
        +For example, a face of a box is meshed with a sub-mesh using algorithms and hypotheses other than the parent mesh on the whole box. The face and the box share four edges, which will be meshed with algorithms and -hypotheses of the submesh on the face, because the face is a 2D object +hypotheses of the sub-mesh on the face, because the face is a 2D object while the box is a 3D object.
        If the dimensions are the same, an arbitrary algorithm/hypothesis will be used. This means that an edge shared by two faces each having - its own different submesh, will be meshed using algorithms and - hypotheses of any of the two, chosen randomly.
        + its own different sub-mesh, will be meshed using algorithms and + hypotheses of any of the two, chosen randomly. This indeterminacy can + be fixed by defining \ref submesh_order_anchor "Sub-mesh priority". +
        -\n Construction of a submesh consists of: +\n Construction of a sub-mesh consists of:
          -
        • Selecting a mesh which will encapsulate your submesh
        • +
        • Selecting a mesh which will encapsulate your sub-mesh
        • Selecting a geometrical object for meshing
        • Applying one or several previously described \ref about_hypo_page "hypotheses" and \ref basic_meshing_algos_page "meshing algorithms" which will be used -at computation of this submesh
        • +at computation of this sub-mesh
        -
        To construct a submesh: +
        To construct a sub-mesh: \par -From the \b Mesh menu select Create Submesh or click "Create +From the \b Mesh menu select Create Sub-mesh or click "Create Sum-mesh" button in the toolbar. \image html image33.gif -
        "Create Submesh" button
        +
        "Create Sub-mesh" button
        \par The following dialog box will appear: @@ -45,11 +47,11 @@ The following dialog box will appear: \par It allows to define the \b Name, the parent \b Mesh and the \b Geometry (e.g. a face if the parent mesh has been built on box) of the -submesh. You can define algorithms and hypotheses in the same way as +sub-mesh. You can define algorithms and hypotheses in the same way as in \ref constructing_meshes_page "Create mesh" menu. \par -In the Object Browser the structure of the new submesh will be +In the Object Browser the structure of the new sub-mesh will be displayed as follows: \image html image10.jpg @@ -57,14 +59,14 @@ displayed as follows: \par It contains:
          -
        • a reference to the geometrical object on the basis of which the submesh has been constructed;
        • +
        • a reference to the geometrical object on the basis of which the sub-mesh has been constructed;
        • Applied hypotheses folder containing the references to the -hypotheses applied to the construction of the submesh;
        • +hypotheses applied to the construction of the sub-mesh;
        • Applied algorithms folder containing the references to the -algorithms applied to the construction of the submesh.
        • +algorithms applied to the construction of the sub-mesh.

        See Also a sample TUI Script of a -\ref tui_construction_submesh "Construct Submesh" operation. +\ref tui_construction_submesh "Construct Sub-mesh" operation. */ diff --git a/doc/salome/gui/SMESH/input/convert_to_from_quadratic_mesh.doc b/doc/salome/gui/SMESH/input/convert_to_from_quadratic_mesh.doc index 072a91f7a..66f850664 100644 --- a/doc/salome/gui/SMESH/input/convert_to_from_quadratic_mesh.doc +++ b/doc/salome/gui/SMESH/input/convert_to_from_quadratic_mesh.doc @@ -2,14 +2,20 @@ \page convert_to_from_quadratic_mesh_page Convert to/from Quadratic Mesh -\n This functionality allows you to transtorm standard meshes to -quadratic and vice versa. See \ref adding_quadratic_elements_page "Adding quadratic elements" +\n This functionality allows transforming standard meshes (or +sub-meshes) to quadratic and vice versa. +See \ref adding_quadratic_elements_page "Adding quadratic elements" for more information about quadratic meshes. +Note that conversion of a sub-mesh most probably will +produce a non-conformal mesh. Elements on the boundary between +quadratic and linear sub-meshes become (or remain) quadratic. To produce a conversion:
          -
        1. From the Modification menu choose the Convert to/from Quadratic -Mesh item, or click "Convert to/from quadratic" button in the +
        2. Select a mesh or a sub-mesh in the Object Browser or in the +Viewer.
        3. +
        4. From the Modification menu choose Convert to/from Quadratic +Mesh item , or click "Convert to/from quadratic" button in the toolbar. \image html image154.png @@ -20,11 +26,17 @@ The following dialog box will appear: \image html convert.png
        5. -
        6. In this dialog box you should select: +
        7. In this dialog box specify:
            -
          • if you wish to convert standard mesh to quadratic or quadratic to standard;
          • -
          • if you wish to place medium nodes of the quadratic mesh on the geometry (meshed object).
          • +
          • if it is necessary to convert a standard mesh to quadratic or a quadratic +mesh to standard. Note that the choice is available only if the selected mesh +(or sub-mesh) contains both quadratic and linear elements, else the +direction of conversion is selected automatically.
          • + +
          • if it is necessary to place medium nodes of the quadratic mesh on the +geometry (meshed object). This option is relevant for conversion to +quadratic provided that the mesh is based on a geometry (not imported from file).
          \image html image156.gif @@ -37,4 +49,6 @@ The following dialog box will appear:
        8. Click the \b Apply or \b OK button.
        -*/ \ No newline at end of file +
        See Also a sample TUI Script of a \ref tui_quadratic "Convert to/from quadratic" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/copy_mesh.doc b/doc/salome/gui/SMESH/input/copy_mesh.doc new file mode 100644 index 000000000..2c65ab8d0 --- /dev/null +++ b/doc/salome/gui/SMESH/input/copy_mesh.doc @@ -0,0 +1,56 @@ +/*! + +\page copy_mesh_page Copy Mesh + +\n A mesh can be created by copying a part of or the whole other mesh. + +To make a copy of a mesh: + +\par +From the \b Mesh menu select Copy Mesh or click "Copy Mesh" +button in the toolbar. + +\image html copy_mesh_icon.png +
        "Copy Mesh" button
        + +\par +The following dialog box will appear: + +\image html copy_mesh_dlg.png + +\par +In the dialog: +
          +
        • specify the part of mesh to copy: + +
            +
          • Select the whole mesh, submesh or group by mouse activating +this checkbox; or
          • +
          • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
          • +
          • input the Source Element IDs directly in this field. The +selected elements will be highlighted in the viewer; or
          • +
          • apply Filters. Set filter button allows to apply a filter +to the selection of elements. See more about filters in the \ref +selection_filter_library_page "Selection filter library" page.
          • +
          +
        • + +
        • specify the New Mesh Name;
        • + +
        • specify the conditions of copying: +
            +
          • activate Generate groups checkbox to copy the groups of +elements of the source mesh to the newly created mesh.
          • +
          • activate Preserve IDs of elements checkbox to keep +the IDs of new nodes and elements the same as the IDs of source nodes +and elements.
          • +
          +
        • + +
        • Click \b Apply or Apply and Close button to confirm the operation.
        • +
        + +See Also a sample +\ref tui_copy_mesh "TUI Example of mesh copying." +*/ diff --git a/doc/salome/gui/SMESH/input/create_groups_from_geometry.doc b/doc/salome/gui/SMESH/input/create_groups_from_geometry.doc new file mode 100755 index 000000000..a09272c98 --- /dev/null +++ b/doc/salome/gui/SMESH/input/create_groups_from_geometry.doc @@ -0,0 +1,17 @@ +/*! + +\page create_groups_from_geometry_page Create Groups from Geometry + +To use this operation, select in the \b Mesh menu Create Groups from Geometry. + +\image html create_groups_from_geometry.png + +This operation allows creating on a selected geometry several groups consisting of +elements of all types. + +The group names will be the same as the names of geometrical objects. +The Type of group of mesh elements is defined automatically by the nature of +the Geometric object. + + +*/ diff --git a/doc/salome/gui/SMESH/input/creating_groups.doc b/doc/salome/gui/SMESH/input/creating_groups.doc index 0e89b980d..966e091fe 100644 --- a/doc/salome/gui/SMESH/input/creating_groups.doc +++ b/doc/salome/gui/SMESH/input/creating_groups.doc @@ -2,12 +2,13 @@ \page creating_groups_page Creating groups -\n In MESH you can create groups of elements of different types. To -create a group of elements in the \b Mesh menu select Create -Group. -\n To create any group you should define the following: +\n In MESH you can create a group of elements of a certain type. The +contents of the group can be defined in different ways. To create a group, in the \b +Mesh menu select Create Group item (also available in the +context menu of the mesh).
        +To create a group of any type you should define the following:
          -
        • Mesh - the name of the mesh whose elements will form your +
        • Mesh - the mesh whose elements will form your group. You can select your mesh in the Objet Browser or in the 3D viewer.
        • Elements Type - set of radio buttons allows to select the type of @@ -19,131 +20,121 @@ elements which will form your group:
        • Volumes
      7. Name field allows to enter the name of your new group.
      8. +
      9. Color - allows to assign to the group a certain color, for +example, defining boundary conditions. The chosen color is used to +display the elements of the group. The color attribute of the group is +not persistent, it is lost if you save and then load the study from +the file.
      10. -SALOME Platform distinguishes between the two Group types: -Standalone Group and Group on Geometry. +SALOME Platform distinguishes between the three Group types: +Standalone Group, Group on Geometry and Group on Filter. -

        Standalone Group

        +\anchor standalone_group

        "Standalone Group"

        -Standalone Group consists of mesh elements, which you can define in -two possible ways. +Standalone Group contains a list of mesh elements, which you can define in +the following ways:
          -
        • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted. After -that click the \b Add button and the ID of this element will be added to -the list.
        • -
        • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements of your group. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
        • +
        • By adding all entities of the chosen type existing in the + mesh. For this, turn on the Select All check box. In this mode + all controls, which allow selecting the entities in other ways, are + disabled.
        • +
        • By applying the Filter. The Set filter button allows to + define the filter for selection of the elements for your group. See more + about filters on the + \ref selection_filter_library_page "Selection filter library" page.
          + If the Enable manual edition check box is turned off, the + filter entirely defines the group contents. In this mode, the filter is + applied to all elements of the mesh. If there are no entities + corresponding to the filter, the \b Apply button is disabled.
          + If the Enable manual edition check box is turned on, the defined + filter can be used to for selection of entities for the group.
        • +
        • By choosing entities manually with the mouse in the 3D Viewer. For + this, turn on the Enable manual edition check box. You can + click on an element in the 3D viewer and it will be highlighted. After + that click the \b Add button and the ID of this element will be + added to the list.
        • +
        • By adding entities from either a submesh or an existing + group. For this, turn on the Enable manual edition check + box. Select from set of fields allows to select a submesh or + a group of the appropriate type.
        • +
        +In the manual edition mode you can +
          +
        • click the \b Remove button to remove the selected elements from the list
        • +
        • click the Sort List button to sort the list of IDs of +mesh elements.
        -To remove a selected element or elements from the list click the -\b Remove button. The Sort List button allows to sort the list of IDs of -mesh elements. -\n Select from set of fields allows to choose a submesh or an existing -group whose elements of the previously defined type will be added to -the list of elements which will form your group. -\n Color - allows to assign to the group a certain color, for -example, defining boundary conditions. This feature introduces a -useful element of preprocessing in Mesh module. Note that Color attribute defines -the colors used for the display of the elements of the group. -\n Warning The Med Color group interface may change in future versions of Salome. - \image html creategroup.png + +For example, to create a new group containing all faces of an +existing group and some other faces selected in the viewer: +
          +
        • Select the \b Face type of entities and input the name of the new group.
        • +
        • Check the \b Group checkbox in Select From group.
        • +
        • Select the existing group of faces in the object browser or in the viewer
        • +
        • Click \b Add in \b Content group. Id Elements list will be filled +with IDs of faces belonging to the exising group.
        • +
        • Select other faces in the viewer.
        • +
        • Click \b Add in \b Content group.
        • +
        • Click \b Apply button to create the new group.
        • +
        + +Please note that the new group does not have references to the source +group. It contains only the list of face IDs. So if the source group +is changed, the new one is not updated accordingly. + + \image html image130.gif -
        In this picture the brown cells belong to a group defined manually.
        +
        In this picture the brown cells belong to a group defined + manually.
        \image html image131.gif -
        In this picture the brown cells belong to the group defined by the criterion -Taper > 0.
        +
        In this picture the brown cells belong to the group defined by + the criterion Taper > 0.
        See Also a sample TUI Script of a \ref tui_create_standalone_group "Create a Standalone Group" operation. -

        Group on Geometry

        - -To create a group on geometry check Group on geometry in the \b Group -\b type field. Group on geometry contains the elements of a certain type -belonging to the selected geometrical object. To define a group select -in the Objet Browser or in the 3D viewer a geometrical object from -which the elements will be taken. After confirmation of the operation -a new group of mesh elements will be created. -\image html a-creategroup.png +\anchor group_on_geom

        "Group on Geometry"

        -

        -To create multiple groups on geometry of both nodes and elements of -any type at once, in the \b Mesh menu select Create Groups from -Geometry.
        -Group names are same as those of geometrical objects. -Type of group of mesh elements is defined automatically by -Geometrical object nature. +To create a group on geometry check Group on geometry in the \b +Group \b type field. The group on geometry contains the elements +of a certain type generated on the selected geometrical object. Group +contents are dynamically updated if the mesh is modified.
        +To define a group, select in the Objet Browser or in the 3D viewer a +geometrical object from which the elements will be taken. After +confirmation of the operation a new group of mesh elements will be +created. -\image html create_groups_from_geometry.png +\image html a-creategroup.png \image html image132.gif -
        In this picture the cells which belong to a certain face are -selected in green.
        +
        In this picture the cells which belong to a certain + geometrical face are selected in green.
        See Also a sample TUI Script of a \ref tui_create_group_on_geometry "Create a Group on Geometry" operation. -

        Creation of groups using existing groups and sub-meshes.

        - -Application provides possibility to create new standalone groups using existing standalone groups, groups on geometry and sub-meshes. This functionality is implemented using "Select from" group box of "Create group" dialog box described above. - -This functionality is described on the example of creating new group from existing standalone groups and groups on geometry. - -Imagine there are group G1. It can be standalone group or group on geometry. -To create group G2 containing all entities of group G1 and a faces graphically selected in 3D view following steps can be performed: -
          -
        • User opens "Create group" dialog box.
        • -
        • The user specifies "Face" type of entities and "G2" name of group.
        • -
        • The user checks "Group" check-box of "Select From" group box.
        • -
        • The user selects G1 group in object browser or 3D view.
        • -
        • The user presses "Add" push button of "Content" group box. "Id Elements" list-box is filled with identifiers of faces belonging to group G1.
        • -
        • The user selects other faces in 3D view.
        • -
        • The user presses "Apply" button. System creates group G2.
        • -
        - -Please note that group G2 does not have a references to source group G1. It contains list of faces identifiers only. So if G1 group will be changed group G2 will remain unmodified. - -
        -\anchor gui_create_dim_group -

        Creating groups of entities from existing groups of superior dimensions

        - -Application provides possibility for creating groups of entities from existing groups of superior dimensions. For example, it is possible to create group of nodes using list of existing groups of faces. - -To create groups of entities from existing groups of superior dimensions, in the \b Mesh menu select Group of underlying entities.
        - -The following dialog box will appear: - -\image html dimgroup_dlg.png +\anchor group_on_filter

        "Group on Filter"

        -In this dialog box you should specify the name of the resulting group, types of entities and set of source groups. +To create a group on filter check Group on filter in the +Group type field. The group on filter contains the elements +of a certain type satisfying the defined filter. Group contents are +dynamically updated if the mesh is modified.
        To define a group, +click the Set filter button and define criteria of the +filter in the opened dialog. After confirmation of the operation a +new group of mesh elements will be created. See more about filters on +the \ref selection_filter_library_page "Selection filter library" page. -For example, we have two source Volume groups illustrated on the figure below - -\image html dimgroup_src.png -
        Source groups
        - -In this case we obtain following results for Faces, Edges and Nodes. - -\image html dimgroup_2d.png -
        Faces
        - -\image html dimgroup_1d.png -
        Edges
        - -\image html dimgroup_0d.png -
        Nodes
        +\image html creategroup_on_filter.png See Also a sample TUI Script of a -\ref tui_create_dim_group "Creating groups of entities from existing groups of superior dimensions" -operation. -*/ \ No newline at end of file +\ref tui_create_group_on_filter "Create a Group on Filter" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/cut_mesh_by_plane.doc b/doc/salome/gui/SMESH/input/cut_mesh_by_plane.doc new file mode 100644 index 000000000..9befdbbeb --- /dev/null +++ b/doc/salome/gui/SMESH/input/cut_mesh_by_plane.doc @@ -0,0 +1,55 @@ +/*! + +\page cut_mesh_by_plane_page Cut a tetrahedron mesh by a plane + +\n MeshCut works only with MED files and produces MED files, and is a standalone program. +It can be used either directly from a command shell outside SALOME, or with a GUI interface in SMESH, +provided in a python plugin that needs to be installed in your SALOME application. + +\n MeshCut allows to cut a mesh constituted of linear tetrahedrons by a plane. +\n The tetrahedrons intersected by the plane are cut and replaced by elements of various types, +(tetrahedron, pyramid, pentahedron). + +
        +\anchor meshcut_standalone +

        Using MeshCut as a standalone program, outside SALOME

        + +\n MeshCut is a standalone program, reading and producing med files. +\n +\n Syntax: +\code +MeshCut input.med output.med resuMeshName aboveGroup belowGroup nx ny nz px py pz T +\endcode + +\n +\n where: +\n input.med = name of the original mesh file in med format +\n output.med = name of the result mesh file in med format +\n resuMeshName = name of the result mesh +\n aboveGroup = name of the group of volumes above the cut plane +\n belowGroups = name of the group of volumes below the cut plane +\n nx ny nz = vector normal to the cut plane +\n px py pz = a point of the cut plane +\n T = 0 < T < 1 : vertices of a tetrahedron are considered as belonging to +\n the cut plane if their distance from the plane is inferior to L*T, +\n where L is the mean edge size of the tetrahedron + +
        +\anchor meshcut_plugin +

        Using MeshCut inside SALOME

        + +When the MeshCut plugin is installed, it can be found in the Mesh menu, sub-menu SMESH_plugins. +\n If the plugin is not installed, the file meshcut_plugin.py is in +SMESH installation in subdirectory bin/salome/meshcut_plugin.py. + +\n If there are already plugins defined in a smesh_plugins.py file, + this file should be added at the end. + if not, copied as ${HOME}/Plugins/smesh_plugins.py or ${APPLI}/Plugins/smesh_plugins.py + or in ${PLUGINPATH} Directory. + +From the Mesh menu, sub-menu SMESH_plugins, choose "MeshCut" item +The following dialog box will appear: +\image html meshcut_plugin.png "MeshCut Plugin dialog box" + +See above for the meaning of the parameters. +*/ diff --git a/doc/salome/gui/SMESH/input/deleting_groups.doc b/doc/salome/gui/SMESH/input/deleting_groups.doc index 21eea88df..86addcf5d 100644 --- a/doc/salome/gui/SMESH/input/deleting_groups.doc +++ b/doc/salome/gui/SMESH/input/deleting_groups.doc @@ -1,8 +1,8 @@ /*! -\page deleting_groups_page Deleting Groups +\page deleting_groups_page Deleting groups with content -\n To delete a group in the Main Menu select Mesh -> Delete Groups and +\n To delete groups and their content in the Main Menu select Modification -> Remove -> Delete groups with Contents and select one or several groups you wish to delete in the 3D viewer or in the Object Browser. \n The selected groups will be listed in Delete groups with contents @@ -16,4 +16,4 @@ elements. To delete a group and leave its elements intact, right-click on the group in the Object Browser and select \b Delete in the pop-up menu or select the group and choose Edit -> Delete in the Main Menu. -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/double_elements_control.doc b/doc/salome/gui/SMESH/input/double_elements_control.doc new file mode 100644 index 000000000..63ee0e762 --- /dev/null +++ b/doc/salome/gui/SMESH/input/double_elements_control.doc @@ -0,0 +1,14 @@ +/*! + +\page double_elements_page Double edge, Double faces and Double volumes + +These mesh quality controls highlight the mesh elements basing on the same set of nodes. + +\image html double_faces.png + +In this picture some faces are coincident after copying all elements +with translation with subsequent Merge of nodes. + +\sa A sample TUI Script of a \ref filter_double_elements "Filters of Double Elements". + +*/ diff --git a/doc/salome/gui/SMESH/input/double_nodes_control.doc b/doc/salome/gui/SMESH/input/double_nodes_control.doc new file mode 100644 index 000000000..75fd2928b --- /dev/null +++ b/doc/salome/gui/SMESH/input/double_nodes_control.doc @@ -0,0 +1,16 @@ +/*! + +\page double_nodes_control_page Double nodes + +This mesh quality control highlights the nodes which are coincident +with other nodes (within a given tolerance). Distance at which two +nodes are considered coincident is defined by "Quality Controls/Double +nodes tolerance" preference. + +\image html double_nodes.png + +In this picture some nodes are coincident after copying all elements with translation. + +\sa A sample TUI Script of a \ref tui_double_nodes_control "Double Nodes" filter. + +*/ diff --git a/doc/salome/gui/SMESH/input/double_nodes_page.doc b/doc/salome/gui/SMESH/input/double_nodes_page.doc new file mode 100644 index 000000000..a8a93d1f9 --- /dev/null +++ b/doc/salome/gui/SMESH/input/double_nodes_page.doc @@ -0,0 +1,72 @@ +/*! + +\page double_nodes_page Duplicate Nodes + +\n This operation allows to duplicate nodes of your mesh, which can be +useful to emulate a crack in the model. +Duplication consists in replacement of an existing mesh element by another one. +Lower level elements of the duplicated ones are cloned automatically. + +To duplicate nodes: +
          +
        1. From the \b Modification menu choose \b Transformation -> \b Duplicate +\b Nodes item or click "Duplicate Nodes" button in the toolbar. +
          +\image html duplicate_nodes.png "Duplicate Nodes button" +
        2. +
        3. Check in the dialog box one of two radio buttons corresponding to +the type of nodes duplication operation you would like to perform.
        4. +
        5. Fill the other fields available in the dialog box (depends on the chosen + operation mode).
        6. +
        7. Click the \b Apply or Apply and Close button to perform the operation of nodes + duplication.
        8. +
        + +\n "Duplicate Nodes" dialog has two working modes: +
          +
        • \ref mode_without_elem_anchor "Without the duplication of border elements"
        • +
        • \ref mode_with_elem_anchor "With the duplication of border elements"
        • +
        + +
        +\anchor mode_without_elem_anchor +

        Without duplication of border elements

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

        With duplication of border elements

        + +In this mode the dialog looks like: + +\image html duplicate02.png + +Parameters to be defined in this mode: +
          +
        • Group of elements to duplicate (mandatory): these elements will be duplicated.
        • +
        • Group of nodes at not to duplicate (optional): group of nodes at crack bottom + which will not be duplicated.
        • +
        • Group of elements to replace nodes with new ones (mandatory): the duplicated nodes + will be associated with these elements.
        • +
        • Construct group with newly created elements option (checked by default): + if checked - the group of just created elements will be built.
        • +
        • Construct group with newly created nodes option (checked by default): + if checked - the group of just created nodes will be built.
        • +
        + + +
        See Also a sample TUI Script of a \ref tui_duplicate_nodes "Duplicate nodes" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/editing_groups.doc b/doc/salome/gui/SMESH/input/editing_groups.doc index b5031468a..ca9b7a222 100644 --- a/doc/salome/gui/SMESH/input/editing_groups.doc +++ b/doc/salome/gui/SMESH/input/editing_groups.doc @@ -2,7 +2,7 @@ \page editing_groups_page Editing groups -\n To edit an existing group of elements: +To edit an existing group of elements:
        1. Select your group in the Object Browser and in the \b Mesh menu click the Edit Group item or "Edit Group" button in the toolbar.
        2. @@ -14,28 +14,34 @@ The following dialog box will appear: \image html editgroup.png -In this dialog box you can modify the name of your group and add or -remove the elements forming it. For more information see +In this dialog box you can modify the name and the color of your group +despite of its type. You can add or remove the elements forming a +standalone group. You can change criteria of the filter of +the group on filter. For more information see \ref creating_groups_page "Creating Groups" page. -
        3. Click the \b Apply or Apply and Close button to confirm modification of the -group.
        4. + +
        5. Click the \b Apply or Apply and Close button to confirm +modification of the group.
        -\n To convert an existing group on geometry into standalone group -of elements and modify: +\anchor convert_to_standalone +To convert an existing group on geometry or a group on filer into +a standalone group of elements and modify:
          -
        1. Select your group on geometry in the Object Browser and in the \b Mesh menu click -the Edit Group as Standalone item.
        2. +
        3. Select your group on geometry (or your group on filter) in the +Object Browser and in the \b Mesh menu click the Edit Group as +Standalone item.
        4. \image html image74.gif
          "Edit Group as Standalone" button
          -The group on geometry will be converted into standalone group and can -be modified as group of elements +The selected group will be converted into a standalone group and +its contents can be modified. +
        5. Click the \b Apply or Apply and Close button to confirm modification of the group.
        6. +
        -
        See Also a sample TUI Script of an -\ref tui_edit_group "Edit Group" operation. +\sa A sample TUI Script of an \ref tui_edit_group "Edit Group" operation. */ diff --git a/doc/salome/gui/SMESH/input/extrusion.doc b/doc/salome/gui/SMESH/input/extrusion.doc index ea25158f1..1b3438084 100644 --- a/doc/salome/gui/SMESH/input/extrusion.doc +++ b/doc/salome/gui/SMESH/input/extrusion.doc @@ -16,38 +16,45 @@ and Hexahedron solids respectively. \image html image91.png
        "Extrusion" button
        -The following dialog box will appear: +The following dialog common for line and planar elements will appear: \image html extrusionalongaline1.png \image html extrusionalongaline2.png + -
      11. In this dialog box you should select: +
      12. In this dialog:
          -
        • the type of elements which will be extruded (1D or 2D),
        • -
        • specify the IDs of the elements which will be extruded by -selecting them in the 3D viewer or select the whole mesh or -submesh, +
        • select the type of elements which will be extruded (0D, 1D or 2D),
        • +
        • specify the IDs of the elements which will be extruded:
            -
          • Check on Select the whole mesh, submesh or group option -
          • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
          • -
          • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
          • +
          • Select the whole mesh, submesh or group activating this +checkbox; or
          • +
          • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
          • +
          • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
          • +
          • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
        • +
        • If the Extrude to Distance radio button is selected
        • +
          • specify the distance at which the elements will be extruded,
          • -
          • specify the vector along which the elements will be extruded,
          • -
          • number of steps.
          -
        • Generate Groups checkbox allows copying the groups of +
        • If the Extrude Along Vector radio button is selected
        • +
            +
          • specify the coordinates of the vector along which the elements will be extruded, or select the face (the normal to the face will define the vector)
          • +
          • specify the distance of extrusion along the vector,
          • +
          +
        • specify the number of steps;
        • +
        • activate Generate Groups checkbox if it is necessary to copy the groups of elements of the source mesh to the newly created one.
        • +
        -
      13. Click the \b Apply or \b OK button.
      14. +
      15. Click \b Apply or Apply and Close button to confirm the operation.
      \image html image77.jpg "The mesh with an edge selected for extrusion" diff --git a/doc/salome/gui/SMESH/input/extrusion_along_path.doc b/doc/salome/gui/SMESH/input/extrusion_along_path.doc index d35d23315..e391111d8 100644 --- a/doc/salome/gui/SMESH/input/extrusion_along_path.doc +++ b/doc/salome/gui/SMESH/input/extrusion_along_path.doc @@ -4,13 +4,14 @@ \n In principle, Extrusion along a path works in the same way as \b Extrusion, the main difference is that we define not a vector, -but a path of extrusion which must be a meshed edge. To get an idea of -how this algorithm works, examine several examples, starting from the -most simple case of extrusion along a straight edge. In all examples -the same mesh will be extruded along different paths and with -different parameters. This sample 2D mesh has two quadrangle faces and -seven edges. Look at the picture, where white digits are the node -numbers and green are the element numbers: +but a path of extrusion which must be a 1D mesh or 1D sub-mesh. +To get an idea of how this algorithm works, examine several examples, +starting from the most simple case of extrusion along a straight edge. +In the examples the sample mesh will be extruded along different +paths and with different parameters. +This 2D mesh has two quadrangle faces and seven edges. Look +at the picture, where white digits are the node numbers and green +are the element numbers: \image html mesh_for_extr_along_path.png @@ -40,29 +41,17 @@ been selected as Start node. \image html curvi_angles_after.png
      The same, but using angles {45, 45, 45, 0, -45, -45, -45}
      -

      Extrusion along a sub-mesh

      +

      Extrusion of a 2D face along a mesh built on a wire

      -In this example the path mesh has been built on a wire (polyline with -six edges). The first edge of the wire was used as Shape (edge), node -#1 as Start node. The angles have been defined as {10, 10, 10}. The -middle edge (#4) of the initial mesh has been extruded. +In this example the path mesh has been built on a wire containing 3 +edges. Node 1 is a start node. Linear angle variation by 180 degrees +has also been applied. -\image html edge_wire_before.png +\image html extr_along_wire_before.png +
      Meshed wire
      -\image html edge_wire_after.png - -

      Extrusion of 2d elements along a sub-mesh

      - -This extrusion bases on the same path mesh as in the previous example -but the third edge of the wire was set as Shape (edge) and node -#4 as Start node. Please note, that the extrusion has been done -in direction from node #4 to node #3, i.e. against the wire -direction. In this example both faces of the initial mesh have been -extruded. - -\image html edge_wire_3d_before.png - -\image html edge_wire_3d_after.png +\image html extr_along_wire_after.png +
      The resulting extrusion

      Extrusion of 2d elements along a closed path

      @@ -88,36 +77,36 @@ path item or click "Extrusion along a path" button in the toolbar. \image html image101.png
      "Extrusion along a path" button
      -The following dialog box will appear: +The following dialog common for line and planar elements will appear: \image html extrusion1.png - -\image html extrusion2.png
    5. -
    6. In the dialog box you should: +
    7. In this dialog:
      • select the type of elements which will be extruded (1D or 2D),
      • specify the IDs of the elements which will be extruded +
          -
        • Check on Select the whole mesh, submesh or group option -
        • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
        • -
        • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
        • +
        • Select the whole mesh, submesh or group activating this +checkbox; or
        • +
        • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
        • +
        • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
        • +
        • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
        +
      • define the Path along which the elements will be extruded, \n Path definition consists of several elements:
          -
        • \b Mesh - containing a 1D sub-mesh on the edge, along which proceeds the extrusion
        • -
        • Shape (edge) - as the mesh can be complex, the edge is used to define the sub-mesh for the path
        • -
        • Start node - the first or the last node on the edge. It is used to define the direction of extrusion
        • +
        • Mesh or submesh - 1D mesh or sub-mesh, along which proceeds the extrusion
        • +
        • Start node - the start node. It is used to define the direction of extrusion
      • -
      • Generate Groups checkbox allows copying the groups of +
      • activate Generate Groups checkbox if it is necessary to copy the groups of elements of the source mesh to the newly created one.
    8. @@ -149,7 +138,9 @@ At each step the shape will be rotated by angle/nb. of steps. -
    9. Click the \b Apply or \b OK button. Mesh edges will be extruded into + +
    10. Click \b Apply or Apply and Close button to confirm the operation. +Mesh edges will be extruded into faces, faces into volumes. The external surface of the resulting 3d mesh (if faces have been extruded) is covered with faces, and corners with edges. If the path is closed, the resulting mesh can contain diff --git a/doc/salome/gui/SMESH/input/find_element_by_point.doc b/doc/salome/gui/SMESH/input/find_element_by_point.doc new file mode 100644 index 000000000..191aa4307 --- /dev/null +++ b/doc/salome/gui/SMESH/input/find_element_by_point.doc @@ -0,0 +1,41 @@ +/*! + +\page find_element_by_point_page Find Element by Point + +\n This functionality allows you to find all mesh elements to which +belongs a certain point. + +To find the elements: +
        +
      1. Select a mesh or a group
      2. +
      3. Select from the Mesh menu or from the context menu the Find +Element by Point item. + +\image html findelement3.png +
        "Find Element by Point" button
        + +The following dialog box will appear: + +\image html findelement2.png + +
      4. +
      5. In this dialog box you should select: + +
          +
        • the coordinates of the point;
        • +
        • the type of elements to be found; it is also possible to find elements +of all types related to the reference point. Choose type "All" to find +elements of any type except for nodes and 0D elements.
        • +
        + +
      6. +
      7. Click the \b Find button. +
      + +\image html findelement1.png +
      The reference point and the related elements.
      + + +
      See Also a sample TUI Script of a \ref tui_find_element_by_point "Find Element by Point" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/free_faces.doc b/doc/salome/gui/SMESH/input/free_faces.doc index 4a87b992a..d35caa9ac 100644 --- a/doc/salome/gui/SMESH/input/free_faces.doc +++ b/doc/salome/gui/SMESH/input/free_faces.doc @@ -2,16 +2,17 @@ \page free_faces_page Free faces -\n This mesh quality control highlights faces which are connected -less than to two mesh volume elements. Free faces are shown with a color differs from -the color of shared faces. +This mesh quality control highlights the faces connected to +less than two mesh volume elements. The free faces are shown with a +color different from the color of shared faces. \image html free_faces.png -
      In this picture some volume mesh element are removed as -a result some faces become connected only to one -volume. i.e. become free. -
      See Also a sample TUI Script of a -\ref tui_free_faces "Free Faces quality control" operation. +In this picture some volume mesh elements have been removed, as +a result some faces became connected only to one +volume. i.e. became free. + +\sa A sample TUI Script of a \ref tui_free_faces "Free Faces quality control" +operation. */ diff --git a/doc/salome/gui/SMESH/input/free_nodes.doc b/doc/salome/gui/SMESH/input/free_nodes.doc index 13f314309..8a06fe3de 100644 --- a/doc/salome/gui/SMESH/input/free_nodes.doc +++ b/doc/salome/gui/SMESH/input/free_nodes.doc @@ -2,15 +2,15 @@ \page free_nodes_page Free nodes -\n This mesh quality control highlights nodes which are not connected -to any mesh element. Free nodes are shown with a color differs from -the color of nodes. +This mesh quality control highlights the nodes which are not connected +to any mesh element. \image html free_nodes.png -
      In this picture some nodes don't connected to a mesh element as -a result of deleting elements and adding several isolated nodes. -
      See Also a sample TUI Script of a -\ref tui_free_nodes "Free Nodes quality control" operation. +In this picture some nodes are not connected to any mesh +element after deleting some elements and adding several isolated nodes. + +\sa A sample TUI Script of a \ref tui_free_nodes "Free Nodes quality control" +operation. */ diff --git a/doc/salome/gui/SMESH/input/generate_flat_elements.doc b/doc/salome/gui/SMESH/input/generate_flat_elements.doc new file mode 100644 index 000000000..7cfdbf90b --- /dev/null +++ b/doc/salome/gui/SMESH/input/generate_flat_elements.doc @@ -0,0 +1,12 @@ +/*! + +\page generate_flat_elements_page Generate flat elements on group boundaries or on faces + +\n These functionalities, used in some mechanics calculations, +allow to generate flat volume elements on the boundaries of a list +of groups of volumes, or on a list of groups of faces. +\n These functionalities are only available in python scripts. + +
      See a sample TUI Script of \ref tui_double_nodes_on_group_boundaries "Generate flat elements" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/ghs3d_hypo.doc b/doc/salome/gui/SMESH/input/ghs3d_hypo.doc deleted file mode 100644 index 414e342fa..000000000 --- a/doc/salome/gui/SMESH/input/ghs3d_hypo.doc +++ /dev/null @@ -1,69 +0,0 @@ -/*! - -\page ghs3d_hypo_page GHS3D Parameters hypothesis - -\n GHS3D Parameters hypothesis works only with Tetrahedron (GHS3D) -algorithm. This algorithm is a commercial software. - -\image html ghs3d_parameters_basic.png - -
        -
      • Name - allows to define the name of the hypothesis (GHS3D -Parameters by default).
      • - -
      • To mesh holes - if checked, the algorithm will -create mesh in the holes inside a solid shape, else only the outermost -shape will be meshed. Volumic elements created within holes are bound -to the solid.
      • - -
      • Optimization level - allows choosing the required -optimization level: none, light, medium or strong. Higher level of -optimisation provides better mesh, but can be time-consuming. -
      • - -\image html ghs3d_parameters_advanced.png - -
      • Maximum memory size - launches ghs3d software with -work space limited to the specified amount of RAM, in Mbytes. If this option is -checked off, the software will be launched with 7O% of the total RAM space.
      • - -
      • Initial memory size - starts ghs3d software with -the specified amount of work space, in Mbytes. If this option is checked off, the -software will be started with 100 Megabytes of working space.
      • - -
      • Working directory - allows defining the folder for input and output -files of ghs3d software, which are the files starting with "GHS3D_" prefix.
      • - -
      • Keep working files - allows checking input and output files -of ghs3d software, while usually these files are removed after the -launch of the mesher.
      • - -
      • Verbose level - to choose verbosity level in the range from -0 to 10. -
        • 0, no standard output, -
        • 2, prints the data, quality statistics of the skin and final -meshes and indicates when the final mesh is being saved. In addition -the software gives indication regarding the CPU time. -
        • 10, same as 2 plus the main steps in the computation, quality -statistics histogram of the skin mesh, quality statistics histogram -together with the characteristics of the final mesh. -
      • - -
      • To create new nodes - if this option is checked off, ghs3d -tries to create tetrahedrons using only the nodes of the 2D mesh.
      • - -
      • To use boundary recovery version - enables using a -boundary recovery module which tries to -create volume meshes starting from very poor quality surface meshes -(almost flat triangles on the surface, high density propagation, -extreme aspect ratios, etc.) which fails with the standard version. The -resulting volume mesh will however most likely have a very poor -quality (poor aspect ratio of elements, tetrahedra with a very small -positive volume).
      • - -
      • Option as text - allows input of any text as command line -for ghs3d. This allows the input of advanced options in a free from.
      • - -
      - -*/ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/ghs3dprl_hypo.doc b/doc/salome/gui/SMESH/input/ghs3dprl_hypo.doc deleted file mode 100644 index 40ffb918c..000000000 --- a/doc/salome/gui/SMESH/input/ghs3dprl_hypo.doc +++ /dev/null @@ -1,392 +0,0 @@ -/*! - -\page ghs3dprl_hypo_page GHS3DPRL Parameters hypothesis - -\n GHS3DPRL Parameters hypothesis works only with Tetrahedron (Tepal with TetMesh-GHS3D) algorithm. -\n -\n This algorithm is a commercial software, its use requires a licence (http://www.distene.com/fr/build/offer.html). -\n The advantage of Tepal is the possibility to generate (for example) a partitioned -200 million tetrahedra mesh on a not-so-big memory computer (2Go RAM) -...in something like 50 hours of one CPU (Xeon, 2008). -This is an alternative to Pluging GHS3D where you should need something like a not-so-common CPU with 64Go RAM -to try to do a one-partitionned 200 million tetrahedra mesh ...in a much less time indeed. -\n -\n Notes: -\n This Plugin doesn't load in Memory the supposed plentiful big resulting meshes. -It's user choice: (in GUI Mesh mode) menu File-Import-MED Files. -\n Beware, to load one 5 millions tetrahedra MED file, GUI Salome needs 2Go RAM. -\n A new true parallel faster version of Tepal, using MPI, is expected in 2009. - -\image html ghs3dprl_parameters_basic.png - -
        -
      • -Name - allows to define the name of the hypothesis (GHS3DPRL Parameters by default). -
      • -
      • -MED_Name - allows to define the path and the basename of the -generated resulted MED files ("DOMAIN" by default). -Undefined path means environment variable $SALOME_TMP_DIR (or $TMP by default). -
      • -
      • -Nb_Part - allows to define the number of MED files generated, -the initial skin (triangles) will be meshed (tetrahedra) and partitioned -in Nb_Part by the elementary algorithm implemented in Tepal.
        -Beware, the (expected) number of total tetrahedra versus this parameter -involves the maximum tepal RAM use. -
      • -
      • -Keep_Files - if this box is checked, input files of Tepal -(GHS3DPRL.points and GHS3DPRL.faces) are deleted after use (...if no backgrounding). -
      • -
      • -Tepal_in_Background - if this box is checked, for big meshes, -launch Tepal execution and MED file generation in background, -allows user exiting of Salome. In this case, beware of the -job Tepal is "killSalome.py" independent, sometimes on other host. -
      • -
      • -To_Mesh_Holes - if this box is checked, force parameter component -of tetmesh-ghs3d to mesh holes. -
      • - -

        Modifying GHS3DPRL Advanced Parameters


        -GHS3DPRL Plugin launches standalone binary executable tepal2med which launches binary executable tepal.
        -tepal2med launches tepal, wait for the end of computation, and converts resulting output tepal files in expected MED files.
        -Some advanced optional parameters are accessibles as arguments.
        -If keep_files checked you a posteriori can always re-launch tepal2med in a Terminal as a command with yours parameters.
        Idem for tepal.

        -
      • -Advanced tepal2med Parameters - type "tepal2med --help" in a Terminal.

        - -\verbatim -myname@myhost > /export/home/myname/salome_5/GHS3DPRLPLUGIN_5/bin/salome/tepal2med --help -Available options: - --help : produces this help message - --casename : path and name of input tepal2med files which are - - output files of tepal .msg .noboite .faces .points .glo - - output file of GHS3DPRL_Plugin casename_skin.med (optional) - with initial skin and its initial groups - --number : number of partitions - --medname : path and name of output MED files - --limitswap : max size of working cpu memory (Mo) (before swapping on .temp files) - --verbose : trace of execution (0->6) - --test : more tests about joints, before generation of output files - --menu : a GUI menu for option number - --launchtepal : also launch tepal on files casename.faces and casename.points and option number - --meshholes : force parameter component of tetmesh-ghs3d to mesh holes - --background : force background mode from launch tepal and generation of final MED files (big meshes) - --deletegroups : regular expression (see QRegExp) which matches unwanted groups in final MED files - (try --deletegroups="(\bAll_Nodes|\bAll_Faces)" - (try --deletegroups="((\bAll_|\bNew_)(N|F|T))" -example: - tepal2med --casename=/tmp/GHS3DPRL --number=2 --medname=DOMAIN --limitswap=1000 - --verbose=0 --test=yes --menu=no --launchtepal=no - -\endverbatim - -

      • -
      • -

        -Advanced tepal Parameters - type "tepal" in a Terminal.

        - -\verbatim -myname@myhost > tepal - ===================================== - GHS3D-TEPAL 1.4.2 (Dec, 2006) 10-Dec-2008 AT 12:59:48 - ===================================== - - Distene SAS - Pole Teratec - BARD-1 - Domaine du Grand Rue - 91680 Bruyeres le Chatel - FRANCE - Phone: +33(0)1-69-26-62-10 Fax: +33(0)1-69-26-90-33 - EMail: support@distene.com - - COPYRIGHT (C)2006 DISTENE ALL RIGHTS RESERVED - - -USAGE : tepal options - -With options in : - --filename name (-f name) : - Basename of the input case (MANDATORY) - - --ndom n (-n n) : - Number of subdomains to make (MANDATORY) - - --ghs3d ghs3d options (-g ghs3d options) : - Run temesh ghs3d on a previously generated subdomain. (ghs3d options must be "quoted") - - --memory m (-m m) : - Max amount of memory (megabytes) allowed for ghs in the cutting process. (default is 0 : unlimited) - - --mesh_only (-Z ) : - Only (re)mesh all subdomains and update communications messages - - --mesh_call command (-c command) : - Call the user specified command for meshing all the subomains after their skin was generated - - --stats_only (-S ) : - Only compute and show some statistics on subdomains - - --rebuild (-r ) : - Merge final subdomains skins - - --rebuild_tetra (-R ) : - Merge final subdomains skins and tetraedra - - --rebuild_iface (-i ) : - Include interfaces in final subdomains merge - - --rebuild_retag (-t ) : - Tag vertices, faces (and tetra if selected) with their subdomain number in final subdomains merge (keeps the lowest tag for shared elements) - - --rebuild_ensight_parts (-e ) : - Build ensight geom file with parts - - --tetmesh_args str (-G str) : - Arguments to pass to Tetmesh during cutting process - - ============================================================================== - GHS3D-TEPAL SOFTWARE 1.4.2 (Dec, 2006) - END OF SESSION - COPYRIGHT (C)2006 DISTENE ALL RIGHTS RESERVED - ============================================================================== - ( Distene SAS - Phone: +33(0)1-69-26-62-10 Fax: +33(0)1-69-26-90-33 - EMail: support@distene.com ) - -\endverbatim - -

      • -
      • -

        -Advanced ghs3d Parameters (through tepal's --tetmesh_args) - type "ghs3d -h" in a Terminal.

        - -\verbatim -myname@myhost > ghs3d -h - -USE - /export/home/myname/ghs3d-4.0/DISTENE/Tools/TetMesh-GHS3D4.0/bin/Linux/ghs3dV4.0 - [-u] [-m memory>] [-M MEMORY] [-f prefix] [-v verbose] - [-c component] [-p0] [-C] [-E count] [-t] [-o level] - [-I filetype] [-a/-b] [-O n m] - -DESCRIPTION - - -u (-h) : prints this message. - - -m memory : launches the software with memory Megabytes of work space. - The default value of this parameter is 64 Megabytes and its - minimum value is 10 Megabytes. - It is also possible to set this parameter with the - environment variable GHS3D_MEMORY by means of an operation - equivalent to: - setenv GHS3D_MEMORY memory, - the value specified in the command line has the priority on - the environment variable. - - -M MEMORY : uses the automatic memory adjustment feature. - If MEMORY is zero, the size of the work space is initially - guessed from the input. If MEMORY is not zero, the - software starts with MEMORY Megabytes of work space. - The software then reallocates more and more memory as - needed. - The starting value when MEMORY equals 0 is 64 Megabytes, - the maximum is given with memory of the -m option if used - and the actual memory available. - - -f prefix : defines the generic prefix of the files. - - -v verbose : sets the output level parameter (the verbose parameter - must be in the range 0 to 10). - - -c component : chooses the meshed component. If component is - 0, all components to be meshed - 1, only the main (outermost) component to be meshed - - -p0 : disables creation of internal points. - - -C : uses alternate boundary recovery version. To be used only - when the boundary recovery of the standard version fails. - - -E count : sets the extended output for error messages. If -E is used, - the error messages found will be printed, up to a maximum - count of errors between 1 and 100. - - -t : generates an error file prefix.Log - - -o level : sets the desired optimisation level. - Valid optimisation levels are: - none, light, medium or standard, strong, - in increasing order of "quality vs speed" ratio. - - -I filetype : defines the input mesh format as follows: - -IP input files are ascii files, named prefix.points - and prefix.faces - this is the default - -IPb input files are binary files, named prefix.pointsb - and prefix.facesb - -IM input file is ascii file, named prefix.mesh - where prefix is given with the -f option - - -a/-b : selects the output file type: - -a for ascii (the default) and - -b for binary. - - -On : saves a NOPO file in addition. NOPO is the mesh data - structure of the Simail and Modulef software packages. - -Om : saves a mesh file in addition. - -Omn : saves both NOPO and mesh files. - - ============================================================================== - TETMESH-GHS3D SOFTWARE 4.0-3 (December, 2006) - END OF SESSION - COPYRIGHT (C)1989-2006 INRIA ALL RIGHTS RESERVED - ============================================================================== - ( Distene SAS - Phone: +33(0)1-69-26-62-10 Fax: +33(0)1-69-26-90-33 - EMail: support@distene.com ) - -\endverbatim - -

      • -

        Saving user's preferred GHS3DPRL Advanced Parameters


        -GHS3DPRL Plugin launches standalone binary executable tepal2med.
        -you may rename tepal2med as tepal2med.exe for example, and replace tepal2med by a shell script at your convenience to overriding parameters.
        ... or else $PATH modification... .
        Idem for tepal.

        -
      • -Advanced tepal2med Parameters - overriding parameter deletegroups

        - -\code -#!/bin/bash -#script tepal2med overriding parameter deletegroups -#we have renamed binary executable tepal2med as tepal2med.exe -#echo tepal2med initial parameters are $1 $2 $3 $4 ... or $* -#$0 is ignored - -tepal2med.exe $* --deletegroups="(\bAll_Nodes|\bAll_Faces)" - -\endcode - -

      • -
      • -

        -Advanced tepal Parameters - overriding parameter component of ghs3d (to mesh holes).

        - -\code -#!/bin/bash -#script tepal overriding parameter component of tetmesh-ghs3d -#we have renamed binary executable tepal as tepal.exe - -#optionnaly we could set licence only for us -DISTENE_LICENSE_FILE="Use global envvar: DLIM8VAR" -DLIM8VAR="dlim8 1:1:29030@is142356/0016175ef08c::a1ba1...etc...e19" -SIMULOGD_LICENSE_FILE=29029@is142356 - -tepal.exe $* --tetmesh_args "-c 0" - -\endcode - -

      • -
      • -

        -Advanced tepal Parameters - overriding launching tepal on other host.

        - -\code -#!/bin/bash -#script tepal overriding launching tepal on other host (tepal run 64 bits only) -#we have renamed binary executable tepal as tepal.exe -#common file system (same path) otherwise scp... on input or result files -#ssh -keygen -t rsa done and files id_rsa et id-rsa.pub move in ~/.ssh - -#example of typical command -#tepal -f /home/myname/tmp/GHS3DPRL -n 4 > /home/myname/tmp/tepal.log -#echo parameters $1 $2 $3 $4 ... or $* - -#tepal licence ought to be known on otherhost -ssh otherhost "tepal.exe $* > /home/myname/tmp/tepal.log" - -#or more and more -#ssh otherhost "tepal.exe $* --tetmesh_args \"-c 0\"" > /home/myname/tmp/tepal.log - -\endcode - -

      • - -

        TUI use.


        - -
      • -

        -example ex30_tepal.py.

        - -\code - -#!/bin/python -import os - -import geompy -import smesh - -# Parameters -# ---------- - -results = "/tmp/ZZ" - -radius = 50 -height = 200 - -# Build a cylinder -# ---------------- - -base = geompy.MakeVertex(0, 0, 0) -direction = geompy.MakeVectorDXDYDZ(0, 0, 1) - -cylinder = geompy.MakeCylinder(base, direction, radius, height) - -geompy.addToStudy(cylinder, "Cylinder") - -# Define a mesh on a geometry -# --------------------------- - -m = smesh.Mesh(cylinder) - -# 2D mesh with BLSURF -# ------------------- - -algo2d = m.Triangle(smesh.BLSURF) - -algo2d.SetPhysicalMesh(1) -algo2d.SetPhySize(5) - -algo2d.SetGeometricMesh(0) - -# 3D mesh with tepal -# ------------------ - -algo3d = m.Tetrahedron(smesh.GHS3DPRL) - -algo3d.SetMEDName(results) -algo3d.SetNbPart(4) -algo3d.SetBackground(False) -algo3d.SetKeepFiles(False) -algo3d.SetToMeshHoles(True) - -# Launch meshers -# -------------- - -status = m.Compute() - -# Test if ok -# ---------- - -if os.access(results+".xml", os.F_OK): - print "Ok: tepal" -else: - print "KO: tepal" -\endcode - -

      • -
      - - -*/ diff --git a/doc/salome/gui/SMESH/input/group_of_underlying_elements.doc b/doc/salome/gui/SMESH/input/group_of_underlying_elements.doc new file mode 100755 index 000000000..a6a1b91ff --- /dev/null +++ b/doc/salome/gui/SMESH/input/group_of_underlying_elements.doc @@ -0,0 +1,34 @@ +/*! + +\page group_of_underlying_elements_page Create Group of Underlying Elements + + +To create groups of entities from existing groups of superior dimensions, in the \b Mesh menu select Group of underlying entities.
      + +The following dialog box will appear: + +\image html dimgroup_dlg.png + +In this dialog box specify the name of the resulting group, types of entities and set of source groups. + +In the figure below, there are two source Volume groups: + +\image html dimgroup_src.png +
      Source groups
      + +In this case the following results for Faces, Edges and Nodes are obtained: + +\image html dimgroup_2d.png +
      Faces
      + +\image html dimgroup_1d.png +
      Edges
      + +\image html dimgroup_0d.png +
      Nodes
      + +See Also a sample TUI Script of a +\ref tui_create_dim_group "Creating groups of entities from existing groups of superior dimensions" +operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/grouping_elements.doc b/doc/salome/gui/SMESH/input/grouping_elements.doc index 56fe14c0d..9615ad4c3 100644 --- a/doc/salome/gui/SMESH/input/grouping_elements.doc +++ b/doc/salome/gui/SMESH/input/grouping_elements.doc @@ -2,30 +2,37 @@ \page grouping_elements_page Grouping elements -In Mesh module it is possible to \subpage creating_groups_page "create groups of mesh elements": -nodes, edges, faces or volumes: -
        -
      • by selecting the elements of the specified kind by their IDs or -directly on the presentation in the VTK viewer - Standalone group tab of Create group -dialog.
      • -
      • by creating a group of elements of the selected type from all -such elements of the chosen geometrical object - Group on -geometry tab of Create group dialog.
      • -
      • by creating several groups of elements (nodes, -edges, faces and volumes) from the chosen submesh - using Mesh -> Construct -Group Menu item. In this case groups of elements are created automatically.
      • -
      +In Mesh module it is possible to create groups of mesh elements: +nodes, edges, faces or volumes. One group contains elements of only +one type. The following ways of creation are possible: + +- by selecting the elements using filters and/or directly on the + presentation in the VTK viewer, and/or by using elements of other + mesh objects - \ref standalone_group "Standalone group" + tab of \ref creating_groups_page "Create group" dialog. +- by creating a group of elements generated on the chosen geometrical + object - \ref group_on_geom "Group on geometry" tab of + \subpage creating_groups_page "Create group" dialog and + \subpage create_groups_from_geometry_page "Create Groups from Geometry" + dialog. +- by creating a group of elements satisfying to certain criteria - + \ref group_on_filter "Group on filter" tab of + \subpage creating_groups_page "Create group" dialog. +- by creating groups of nodes and elements from the chosen submesh + (type of elements depends on dimension of submesh geometry) - + using Mesh -> Construct Group menu item (available in context + menu as well). +- by creating groups of entities from existing groups of superior + dimensions - using \subpage group_of_underlying_elements_page + "Create Group of Underlying Elements" dialog. The created groups can be later: -
        -
      • \subpage editing_groups_page "Edited"
      • -
      • \subpage using_operations_on_groups_page "Subjected to Boolean operations", or
      • -
      • \subpage deleting_groups_page "Deleted"
      • -
      +- \subpage editing_groups_page "Edited" +- \subpage using_operations_on_groups_page "Subjected to Boolean operations" +- \subpage deleting_groups_page "Deleted" An important tool, providing filters for creation of \b Standalone -groups is \subpage selection_filter_library_page
    11. . - +groups is \ref selection_filter_library_page. */ diff --git a/doc/salome/gui/SMESH/input/importing_exporting_meshes.doc b/doc/salome/gui/SMESH/input/importing_exporting_meshes.doc index dbf96ab89..52ff261e3 100644 --- a/doc/salome/gui/SMESH/input/importing_exporting_meshes.doc +++ b/doc/salome/gui/SMESH/input/importing_exporting_meshes.doc @@ -3,15 +3,15 @@ \page importing_exporting_meshes_page Importing and exporting meshes \n In MESH there is a functionality allowing importation/exportation -of meshes from \b MED, \b UNV (I-DEAS 10), \b DAT (Nastran) and STL -format files. +of meshes from/to \b MED, \b UNV (I-DEAS 10), \b DAT (Nastran), \b STL +and \b CGNS format files. You can also export a group as a whole mesh. To import a mesh:
      1. From the \b File menu choose the \b Import item, from its sub-menu -select the corresponding format (MED, UNV and DAT) of the file containing +select the corresponding format (MED, UNV, DAT, STL and CGNS) of the file containing your mesh.
      2. In the standard Search File dialog box find the file for importation. It is possible to select multiple files to be imported all at once.
      3. @@ -21,13 +21,13 @@ importation. It is possible to select multiple files to be imported all at once. \image html meshimportmesh.png -To export a mesh: +To export a mesh or a group:
        1. Select the object you wish to export.
        2. From the \b File menu choose the \b Export item, from its sub-menu -select the format (MED, UNV, DAT and STL) of the file which will contain your -exported mesh.
        3. +select the format (MED, UNV, DAT, STL and CGNS) of the file which will +contain your exported mesh.
        4. In the standard Search File select a location for the exported file and enter its name.
        5. Click the \b OK button.
        6. diff --git a/doc/salome/gui/SMESH/input/index.doc b/doc/salome/gui/SMESH/input/index.doc index 2de722d16..798237b4b 100644 --- a/doc/salome/gui/SMESH/input/index.doc +++ b/doc/salome/gui/SMESH/input/index.doc @@ -6,22 +6,31 @@ \n \b MESH module of SALOME is destined for:
            -
          • \ref importing_exporting_meshes_page "import and export of meshes in MED format";
          • +
          • \ref importing_exporting_meshes_page "import and export of meshes in different formats";
          • \subpage about_meshes_page "meshing geometrical models" previously created or imported by the Geometry component;
          • \subpage viewing_meshes_overview_page "viewing created meshes" in the VTK viewer;
          • \subpage grouping_elements_page "creating groups of mesh elements";
          • -
          • applying to meshes \subpage quality_page "Quality Controls" , -allowing to highlight important elements: +
          • applying to meshes \subpage quality_page "Quality Controls", +allowing to highlight important elements; +
          • filtering sub-sets of mesh entities (nodes elements) using +\subpage filters_page "Filters" functionality;
          • \subpage modifying_meshes_page "modifying meshes" with a vast -array of dedicated operations.
          • -
          • \subpage using_notebook_mesh_page.
          • +array of dedicated operations; +
          • different \subpage measurements_page "measurements" of the mesh objects; +
          • easily setting parameters via the variables predefined in +\subpage using_notebook_mesh_page "Salome notebook".
          +Mesh module preferences are described in the \subpage mesh_preferences_page section of SALOME Mesh Help. + Almost all mesh module functionalities are accessible via \subpage smeshpy_interface_page "Mesh module Python interface". +Other functions are available in salome.smesh python package. + + \image html image7.jpg "Example of MESH module usage for engineering tasks" */ diff --git a/doc/salome/gui/SMESH/input/length_2d.doc b/doc/salome/gui/SMESH/input/length_2d.doc index def8afa95..4ed5b69e6 100644 --- a/doc/salome/gui/SMESH/input/length_2d.doc +++ b/doc/salome/gui/SMESH/input/length_2d.doc @@ -10,8 +10,8 @@ of your mesh.
          1. Display your mesh in the viewer.
          2. -
          3. Choose Controls > Length 2D or click "Length 2D" -button in the toolbar. +
          4. Choose Controls > Face Controls > Length 2D or click +"Length 2D" button in the toolbar. \image html image34.png
            "Length 2D" button
            diff --git a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc new file mode 100644 index 000000000..a53257eef --- /dev/null +++ b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc @@ -0,0 +1,52 @@ +/*! + +\page make_2dmesh_from_3d_page Generate boundary elements + +\n This functionality allows to generate mesh elements on the borders of +elements of a higher dimension. + +To generate border elements: +
              +
            1. Select a mesh or group in the Object Browser or in the 3D Viewer
            2. +
            3. From the Modification menu choose "Create boundary elements" +item, or click "Create boundary elements" button in the toolbar + +\image html 2d_from_3d_ico.png "Create boundary elements icon" + +The following dialog box will appear: +\image html 2d_from_3d_dlg.png "Create boundary elements dialog box". +
            4. +
            5. Check in the dialog box one of two radio buttons corresponding to +the type of operation you would like to perform.
            6. +
            7. Fill the other fields available in the dialog box.
            8. +
            9. Click the \b Apply or Apply and Close button to perform the operation.
            10. +
            + +\n "Create boundary elements" dialog allows creation of boundary elements +of two types. +
              +
            • 2D from 3D creates mesh faces on free facets of volume elements
            • +
            • 1D from 2D creates mesh edges on free edges of mesh faces
            • +
            +Here a free facet means a facet shared by only one volume, a free edge +means an edge shared by only one mesh face. + +In this dialog: +
              +
            • specify the Target mesh, where the boundary elements will + be created. +
                +
              • This mesh adds elements in the selected mesh.
              • +
              • New mesh adds elements to a new mesh. The new mesh appears + in the Object Browser with the name that you can change in the adjacent box.
              • +
            • +
            • activate Copy source mesh checkbox to copy all elements of +the selected mesh to the new mesh, else the new mesh will contain only +boundary elements (old and created by this operation).
            • +
            • activate Create group checkbox to create a group to which + all the boundary elements (old and new) are added. The new group appears + in the Object Browser with the name that you can change in the adjacent box.
            • +
            +
            See Also a sample TUI Script of a \ref tui_make_2dmesh_from_3d "Create boundary elements" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/max_element_length_2d.doc b/doc/salome/gui/SMESH/input/max_element_length_2d.doc new file mode 100644 index 000000000..6ec4f7116 --- /dev/null +++ b/doc/salome/gui/SMESH/input/max_element_length_2d.doc @@ -0,0 +1,28 @@ +/*! + +\page max_element_length_2d_page Element Diameter 2D + +\n This quality control criterion consists in calculation of the length of +edges and diagonals combining 2D mesh elements (triangles and quadrangles). + +To apply the Element Diameter 2D quality criterion to your mesh: +
              +
            1. Display your mesh in the viewer.
            2. + +
            3. Choose Controls > Face Controls > Element Diameter 2D or click +"Element Diameter 2D" button in the toolbar. + +\image html image42.png +
              "Element Diameter 2D" button
              + +Your mesh will be displayed in the viewer with its elements colored according to the +applied mesh quality control criterion: + +\image html max_element_length_2d.png +
            4. +
            + +
            See Also a sample TUI Script of a +\ref tui_max_element_length_2d "Element Diameter 2D quality control" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/max_element_length_3d.doc b/doc/salome/gui/SMESH/input/max_element_length_3d.doc new file mode 100644 index 000000000..7aa70ad7b --- /dev/null +++ b/doc/salome/gui/SMESH/input/max_element_length_3d.doc @@ -0,0 +1,29 @@ +/*! + +\page max_element_length_3d_page Element Diameter 3D + +\n This quality control criterion consists in calculation of the length of +edges and diagonals combining 3D mesh elements +(tetrahedrons, pyramids, pentahendrons, hexahedrons and polyhedrons). + +To apply the Element Diameter 3D quality criterion to your mesh: +
              +
            1. Display your mesh in the viewer.
            2. + +
            3. Choose Controls > Volume Controls > Element Diameter 3D or click +"Element Diameter 3D" button in the toolbar. + +\image html image43.png +
              "Element Diameter 3D" button
              + +Your mesh will be displayed in the viewer with its elements colored according to the +applied mesh quality control criterion: + +\image html max_element_length_3d.png +
            4. +
            + +
            See Also a sample TUI Script of a +\ref tui_max_element_length_3d "Element Diameter 3D quality control" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/measurements.doc b/doc/salome/gui/SMESH/input/measurements.doc new file mode 100644 index 000000000..6514cf287 --- /dev/null +++ b/doc/salome/gui/SMESH/input/measurements.doc @@ -0,0 +1,70 @@ +/*! + +\page measurements_page Measurements + +Mesh module provides the possibility to perform different measurements +of the selected mesh data. + +All measurement operations are available via \b Measurements +top-level menu. Access to the measurements operations is +implemented via a single dialog box, where each operation is represented +as a separate tab page. + +\section min_distance_anchor Minimum Distance + +This operation allows measuring the distance between two objects. +Currently only node-to-node and node-to-origin operations are +available, but this operation will be extended in the future to support +other mesh objects - elements, meshes, sub-meshes and groups. + +To start Minimum Distance operation, select Minimum Distance +item from \b Measurements menu. + +\image html min_distance.png + +In the dialog box choose the first target and the second target mode by +switching the corresponding radio buttons, then select the objects the distance +between which is to be calculated (or input their IDs directly +in case of nodes/elements) and press \em Compute button. + +The following types of targets are supported: +- \em Node: single mesh node; +- \em Element: single mesh element (not available in this version); +- \em Object: mesh, sub-mesh or group object (not available in this +version); +- \em Origin: origin of the global co-ordinate system. + +The result will +be shown in the bottom area of the dialog box. In addition, a simple +preview will be shown in the 3D viewer. + +\image html min_distance_preview.png + +\section bounding_box_anchor Bounding Box + +This operation allows to calculate the bounding box of the selected +object(s). + +To start Bounding Box operation, select Bounding Box +item from \b Measurements menu. + +\image html bnd_box.png + +In the dialog box choose the required type of the object by switching the +corresponding radio button, select the object(s) and press \em Compute button. + +The following types of input are available: +- \em Objects: select one or several mesh, sub-mesh or group objects; +- \em Nodes: select a set of mesh nodes; +- \em Elements: select a set of mesh elements. + +The result of calculation will be shown in the bottom area of the +dialog box. In addition, a simple preview will be shown in the 3D +viewer. + +\image html bnd_box_preview.png + +See Also a sample TUI Script of a +\ref tui_measurements_page "Measurement operations". + +*/ diff --git a/doc/salome/gui/SMESH/input/merging_elements.doc b/doc/salome/gui/SMESH/input/merging_elements.doc index 821f6f9f2..50513d58f 100644 --- a/doc/salome/gui/SMESH/input/merging_elements.doc +++ b/doc/salome/gui/SMESH/input/merging_elements.doc @@ -5,42 +5,58 @@ \n This functionality allows to merge coincident elements of a mesh selectable in the dialog box. - \image html mergeelems_ico.png "Merge elements button" +
              +
            1. Choose in the main menu \b Modification -> \b Transformation -> Merge elements item. The following dialog box +shall appear:
            2. -\image html mergeelems.png +\image html mergeelems_auto.png +
              +
                +
              • \b Name is the name of the mesh whose elements will be merged.
              • +
              • \b Automatic or \b Manual Mode allows choosing how the elements +are processed. +
              + +
            3. Automatic mode: +
                +
              • In the \b Automatic Mode the elements created on the same nodes will be merged.
              • +
              +
            4. + +
            5. If the \b Manual Mode is selected, additional controls are +available: +\image html mergeelems.png +
              +
                +
              • \b Detect button generates the list of coincident elements for the given \b Tolerance.
              • +
              • Coincident elements is a list of groups of elements for +merging. All elements of each group will form one after the operation.
                  -
                • \b Name is the name of the mesh whose elements will be merged.
                • -
                • \b Tolerance is a maximum distance between elements sufficient for merging. -
                    -
                  • \b Detect button generates the list of coincident elements for the given \b Tolerance.
                  • -
                • -
                • Coincident elements is a list of groupes of elements for - merging. All elements of each group will form one after the operation. -
                    -
                  • \b Remove button deletes the selected group from the list.
                  • -
                  • \b Add button adds to the list a group of elements selected in the - viewer with pressed "Shift" key.
                  • -
                  • Select all checkbox selects all groups.
                  • -
                • -
                • Edit selected group list allows editing the selected group: -

                  - \image html add.png -
                  adds to the group the element selected in the viewer.
                  -
                  - \image html remove.png -
                  removes from the group the selected element.
                  -
                  - \image html sort.png -
                  moves the selected element to the first position in the - group. This means that all other elements will be merged into this - one.
                  -
                  -
                • -
                • To confirm your choice click \b Apply or Apply and Close button.
                • +
                • \b Remove button deletes the selected group from the list.
                • +
                • \b Add button adds to the list a group of elements selected in the +viewer with pressed "Shift" key.
                • +
                • Select all checkbox selects all groups.
                • +
              • +
              • Edit selected group list allows editing the selected group: +

                +\image html add.png +
                adds to the group the element selected in the viewer.
                +
                +\image html remove.png +
                removes from the group the selected element.
                +
                +\image html sort.png +
                moves the selected element to the first position in the +group. This means that all other elements will be merged into this +one.
                +
                +
              • +
              • To confirm your choice click \b Apply or Apply and Close button.
              +
            In this picture you see a triangle which coincides with one of the elements of the mesh. After we apply Merge Elements functionality, the diff --git a/doc/salome/gui/SMESH/input/merging_nodes.doc b/doc/salome/gui/SMESH/input/merging_nodes.doc index fb88fb89e..3b1bbeaaf 100644 --- a/doc/salome/gui/SMESH/input/merging_nodes.doc +++ b/doc/salome/gui/SMESH/input/merging_nodes.doc @@ -2,29 +2,43 @@ \page merging_nodes_page Merging nodes -\n This functionality allows user to detect groups of coincident nodes -with desirable tolerance, edit these groups and merge. +This functionality allows user to detect groups of coincident nodes +with specified tolerance; each group of the coincident nodes can be +then converted to the single node. \image html mergenodes_ico.png "Merge nodes button" To merge nodes of your mesh:
              -
            1. From the \b Modification choose \b Transformation and from its +
            2. From the \b Modification choose \b Transformation and from its sub-menu select the Merge nodes item. The following dialog box -shall appear: - -\image html mergenodes.png - +shall appear:
            3. +
              +\image html mergenodes_auto.png +
              • \b Name is the name of the mesh whose nodes will be merged.
              • +
              • \b Automatic or \b Manual Mode allows choosing how the nodes are +processed.
              • \b Tolerance is a maximum distance between nodes sufficient for -merging. +merging.
              • +
              • Exclude Groups group box allows to ignore the nodes which +belong to the specified mesh groups. +
              + +
            4. Automatic mode: +
              +
                +
              • In the \b Automatic Mode all Nodes within the indicated tolerance +will be merged. The nodes which belong to the groups specified in the +Exclude Groups will be not taken into account.
              • +
              +

            5. +
            6. If the \b Manual Mode is selected, additional controls are available:
              • \b Detect button generates the list of coincident nodes for the given \b Tolerance.
              • -
              -
            7. -
            8. Coincident nodes is a list of groupes of nodes for +
            9. Coincident nodes is a list of groups of nodes for merging. All nodes of each group will form one after the operation.
                @@ -33,6 +47,10 @@ operation. viewer with pressed "Shift" key.
              • Select all checkbox selects all groups.
              + +
              +\image html mergenodes.png +
            10. Edit selected group list allows editing the selected group: @@ -60,4 +78,4 @@ one.

              See Also a sample TUI Script of a \ref tui_merging_nodes "Merge Nodes" operation. -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/mesh_infos.doc b/doc/salome/gui/SMESH/input/mesh_infos.doc index 37a3deaf4..06a02d2cc 100644 --- a/doc/salome/gui/SMESH/input/mesh_infos.doc +++ b/doc/salome/gui/SMESH/input/mesh_infos.doc @@ -1,65 +1,105 @@ /*! -\page mesh_infos_page Mesh infos +\page mesh_infos_page Mesh Information -\n There are three information boxes: Standard Mesh -Infos, Advanced Mesh Infos and Mesh Element Info. +The user can obtain information about the selected mesh object +(mesh, sub-mesh or group) using Mesh Information dialog box. -
              -\anchor standard_mesh_infos_anchor -

              Standard Mesh Infos

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

              Base Information

              -\image html a-standmeshinfo.png +The Base Info tab page of the dialog box provides general +information on the selected object - mesh, sub-mesh or mesh group: +name, type, total number of nodes and elements separately for each +type: 0D elements, edges, faces and volumes. + +\image html advanced_mesh_infos.png +
              "Base Info" page
              +\anchor mesh_element_info_anchor +

              Mesh Element Information

              + +The Element Info tab page of the dialog box gives basic +information about the type, coordinates and connectivity of the +selected mesh node or element. + +\image html eleminfo1.png +
              "Element Info" page, node information

              -\anchor advanced_mesh_infos_anchor -

              Advanced Mesh Infos

              +\image html eleminfo2.png +
              "Element Info" page, element information
              -The Advanced Mesh Infos box gives more information about the mesh, -including the total number of faces and volumes and their geometrical -types. -\n To view the Advanced Mesh Infos, select your mesh or submesh -in the Object Browser and select Advanced Mesh Infos -from the \b Mesh menu or click "Advanced Mesh Infos" button -in the toolbar. +The use can either input the ID of a node or element he wants to +analyze directly in the dialog box or select the node or element in +the 3D viewer. -\image html image50.gif -
              "Advanced Mesh Infos" button
              +\anchor mesh_addition_info_anchor +

              Additional Information

              -The following information will be displayed: +The Additional Info tab page of the dialog box provides an +additional information on the selected object: mesh, sub-mesh or +group. -\image html advanced_mesh_infos.png +For a mesh object, the following information is shown: +- Name +- Type: based on geomerty, imported, standalone +- Shape (if mesh is based on geometry) +- File (if mesh is imported from the file) +- Groups +- Sub-meshes -In case you get Mesh Infos via a \ref tui_viewing_mesh_infos "TUI script", -the information is displayed in Python Console. +\image html addinfo_mesh.png +
              "Additional Info" page, mesh information
              +
              -\image html b-mesh_infos.png +For a sub-mesh object, the following information is shown: +- Name +- Parent mesh +- Shape +\image html addinfo_submesh.png +
              "Additional Info" page, sub-mesh information

              -\anchor mesh_element_info_anchor -

              Mesh Element Info

              -The Mesh Element Info box gives basic information about the -type and the coordinates of the selected mesh element. -\n It is possible to input the Element ID or to select the Element in -the Viewer. +For a group object, the following information is shown: +- Name +- Parent mesh +- Type: standalone, group on geometry, group on filter +- Entity type: node, edge, face, volume +- Size +- Color +- Number of underlying nodes (for non-nodal groups) + +\image html addinfo_group.png +
              "Additional Info" page, group information
              +
              -\image html eleminfo1.png +\note For the performance reasons, the number of underlying nodes is +computed only by demand. For this, the user should press the "Compute" +button (see picture). Also, the number of underlying nodes is +automatically calculated if the size of the group does not exceed +the "Automatic nodes compute limit" set via the "Mesh information" +preferences (zero value means no limit). -\image html eleminfo2.png +In case you get Mesh Information via a TUI script, the information is +displayed in the Python Console. +See the \ref tui_viewing_mesh_infos "TUI Example". -*/ \ No newline at end of file +*/ + diff --git a/doc/salome/gui/SMESH/input/mesh_preferences.doc b/doc/salome/gui/SMESH/input/mesh_preferences.doc new file mode 100644 index 000000000..1b1b2f96c --- /dev/null +++ b/doc/salome/gui/SMESH/input/mesh_preferences.doc @@ -0,0 +1,203 @@ +/*! + +\page mesh_preferences_page Mesh preferences + +In the Mesh module you can set mesh preferences, which can be used in +later sessions with this module. + +

              General Preferences

              + +\image html pref21.png + +
                +
              • Automatic Update
              • +
                  +
                • If you toggle Automatic Update checkbox, the model in your +viewer automatically updated whenever you make changes in it.
                • +
                • Size limit (elements) - allows to specify the maximum +number of elements in the resulting mesh for which the automatic updating +of the presentation is performed. This option affects only +Compute operation. Zero value means "no limit". Default value +is 500 000 mesh elements. +
                +
              • Quality Controls
              • +
                  +
                • If you toggle Display entity, both faces and edges of an +object will be displayed in the viewer by default.
                • +
                • If you toggle Use precision checkbox, you can display numbers in +Quality Control diagrams at the necessary level of precision.
                • +
                • Number of digits after point - defines precision for Quality Controls. By default, numbers in Quality Control +diagrams are presented as integers.
                • +
                • Double nodes tolerance defines the maximal distance between two +mesh nodes, at which they are considered coincident by Double nodes +quality control. +
                +
              • Display mode - allows to set Wireframe, Shading, Nodes or Shrink +presentation mode as default.
              • +
              • Representation of the 2D quadratic elements
              • +
                  +
                • Representation of the 2D quadratic elements combobox - allows +to select lines or arcs for representation of quadratic elements.
                • +
                • Maximum Angle - maximum deviation angle used by the +application to build arcs.
                • +
                +
              • Mesh export
              • +
                  +
                • If you toggle Automatically create groups for MED export checkbox, +this operation will be carried out automatically.
                • +
                • If you toggle Automatic renumbering checkbox, the exported +mesh will be renumbered automatically
                • +
                +
              • Mesh computation
              • +
                  +
                • Show a computation result notification combobox allows to +select the notification mode about a mesh computation result. +There are 3 possible modes:
                • +
                    +
                  • Never - do not show the result dialog at all;
                  • +
                  • Errors only - the result dialog will be shown if there were +some errors during a mesh computation;
                  • +
                  • Always - show the result dialog after each mesh +computation. This is a default mode.
                  • +
                +
              • Mesh information
              • +
                  +
                • Mesh element information
                • - Change the way mesh element +information is shown: +
                    +
                  • Simple - as a plain text
                  • +
                  • Tree - in a tree-like form
                  • +
                  +
                • Automatic nodes compute limit
                • - allows to define the size limit for the +mesh groups for which the number of underlying nodes is calculated +automatically. If the group size exceeds the value set in the preferences, +the user will have to press \em Compute button explicitly. Zero value +means "no limit". By default the value is set to 100 000 mesh elements. +
                +
              • Automatic Parameters
              • +
                  +
                • Ratio Bounding Box Diagonal / Max Size - this parameter is +used for automatic meshing: ratio between the bounding box of the +meshed object and the Max Size of segments.
                • +
                • Default Number of Segments - allows defining the default +number of segments on each edge
                • +
                +
              • Mesh loading
              • +
                  +
                • If No mesh loading from study file at hypothesis modification + checkbox is on, the mesh data will not be loaded from the study file + when a hypothesis is modified. This allows saving time by omitting + loading data of a large mesh that is planned to be recomputed with other parameters.
                • +
                +
              • Input fields precision
              • +
                  +
                • Length precision - allows to adjust input precision of coordinates and dimensions.
                • +
                • Angular precision - allows to adjust input precision of angles.
                • +
                • Length tolerance precision - allows to adjust input precision of tolerance of coordinates and dimensions.
                • +
                • Parametric precision - allows to adjust input precision of parametric values.
                • +
                • Area precision - allows to adjust input precision of mesh element area.
                • +
                • Volume precision - allows to adjust input precision of mesh element volume.
                • +
                +
              • Python Dump
              • +
                  +
                • Historical python dump checkbox allows switching between + \a Historical and \a Snapshot dump mode. In \a + Historical mode, Python Dump script includes all commands + performed by SMESH engine. In \a Snapshot mode, the commands + relating to objects removed from the Study as well as the commands + not influencing the current state of meshes are excluded from the script.
                • +
                +
              + +

              Mesh Preferences

              + +\image html pref22.png + +
                +
              • Nodes
              • +
                  +
                • Color - allows to select the color of nodes. Click on the +colored line to access to the Select Color dialog box.
                • +
                • Type of marker - allows to define the shape of nodes.
                • +
                • Scale of marker - allows to define the size of nodes.
                • +
                +
              • Elements
              • +
                  +
                • Surface color - allows to select the surface color of elements +(seen in Shading mode). Click on the colored line to access to the Select Color dialog box.
                • +
                • Back surface color - allows to select the interior surface color +of elements. Use the slider to select the color generated basing on +the Surface color by changing its brightness and saturation.
                • +
                • Outline color - allows to select the color of element +borders. Click on the colored line to access to the Select Color dialog box.
                • +
                • Wireframe color - allows to select the color of borders of +elements in the wireframe mode. Click on the colored line to access to the Select Color dialog box.
                • +
                • Width - allows to define the width of lines (edges and borders of elements).
                • +
                • Shrink coef. - allows to define relative space of elements +compared to gaps between them in shrink mode.
                • +
                +
              • Orientation of Faces - allows to define the behavior of +Orientation of faces functionality
              • +
                  +
                • \b Color - allows to define the color of orientation vertors;
                • +
                • \b Scale - allows to define the size of orientation vectors;
                • +
                • 3D Vector checkbox allows to choose between 2D planar +and 3D vectors.
                • +
                +
              + +

              Selection Preferences

              + +\image html pref23.png + +
                +
              • Selection - performed with mouse-indexing (preselection) +and left-clicking on an object, whose appearance changes as defined in +the Preferences.
              • +
                  +
                • Object Color - allows to select the color of mesh (edges and +borders of meshes) of the selected entity. Click on the colored line +to access to the Select Color dialog +box.
                • +
                • Element color - allows to select the color of surface of selected +elements (seen in Shading mode). Click on the colored line to access +to the Select Color dialog box.
                • +
                +
              • Preselection - performed with mouse-indexing on an object, +whose appearance changes as defined in the Preferences.
              • +
                  +
                • Highlight Color - allows to select the color of mesh (edges and +borders of meshes) of the entity . Click on the colored line to access +to the Select Color dialog box.
                • +
                +
              • Precision - in this menu you can set the value of precision +used for Nodes, Elements and Objects.
              • +
              + +

              Scalar Bar Preferences

              + +\image html pref24.png + +
                +
              • Font - in this menu you can set type, face and color for +the font of Title and Labels.
              • +
              • Colors & Labels - in this menu you can set the number of +colors and the number of labels in use.
              • +
              • Orientation - here you can choose between vertical and +horizontal orientation of the Scalar Bar
              • . +
              • Origin & Size Vertical & Horizontal - allows to define +placement (X and Y) and lookout (Width and +Height) of Scalar Bars
              • +
                  +
                • X: abscissa of the point of origin (from the left +side)
                • +
                • Y: ordinate of the origin of the bar (from the bottom)
                • +
                +
              • Distribution in this menu you can Show/Hide distribution histogram of the values of the Scalar Bar and specify the Coloring Type of the histogram
              • +
                  +
                • Multicolor the histogram is colored as Scalar Bar
                • +
                • Monocolor the histogram is colored as selected with Distribution color selector
                • +
                +
              + +*/ diff --git a/doc/salome/gui/SMESH/input/mesh_through_point.doc b/doc/salome/gui/SMESH/input/mesh_through_point.doc index cd0d68ea9..968bfbc0b 100644 --- a/doc/salome/gui/SMESH/input/mesh_through_point.doc +++ b/doc/salome/gui/SMESH/input/mesh_through_point.doc @@ -1,34 +1,37 @@ /*! -\page mesh_through_point_page Mesh through point +\page mesh_through_point_page Moving nodes -\n In mesh you can define a node at a certain point either by creation -of a new node, by movement of the node closest to the point or by +\n In mesh you can define a node at a certain point either +by movement of the node closest to the point or by movement of any node to the point. -To create a mesh passing through a point: +To displace a node:
                -
              1. From the \b Modification menu choose the Mesh through point item or -click "Mesh to pass through a point" button in the toolbar. +
              2. From the \b Modification menu choose the Move node item or +click "Move Node" button in the toolbar. -\image html mesh_node_to_point.png -
                "Mesh to pass through a point" button
                +\image html image67.png +
                "Move Node" button
                The following dialog box shall appear: \image html meshtopass.png
              3. -
              4. Enter the coordinates of the point.
              5. -
              6. Choose one of several methods: you can either \b Create a new node at -the indicated point or Move the existing node to the point. In the -latter case you can check in Automatic search of the closest node or -select the necessary node manually. \b Preview check-box allows to see -the results of the operation.
              7. -
              8. Click the \b Apply or \b OK button.
              9. +
              10. Enter the coordinates of the destination point.
              11. +
              12. Check in Find closest to destination option or +select the necessary node manually (X, Y, Z, dX, dY, dZ fields allow +to see original coordinates and displacement of the node to move). +\b Preview check-box allows to see the results of the operation.
              13. +
              14. Click the \b Apply or Apply and Close button.
              +\image html moving_nodes1.png "The initial mesh" + +\image html moving_nodes2.png "The modified mesh" +
              See Also a sample TUI Script of a -\ref tui_mesh_through_point "Mesh through point" operation. +\ref tui_moving_nodes "Moving Nodes" operation. */ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/minimum_angle.doc b/doc/salome/gui/SMESH/input/minimum_angle.doc index af631b0ec..4236d6562 100644 --- a/doc/salome/gui/SMESH/input/minimum_angle.doc +++ b/doc/salome/gui/SMESH/input/minimum_angle.doc @@ -10,7 +10,8 @@ element (triangle or quadrangle).
              1. Display your mesh in the viewer.
              2. -
              3. Choose Controls > Minimum angle or click "Minimum Angle" button. +
              4. Choose Controls > Face Controls > Minimum angle or click +"Minimum Angle" button. \image html image38.png
                "Minimum Angle" button
                diff --git a/doc/salome/gui/SMESH/input/modifying_meshes.doc b/doc/salome/gui/SMESH/input/modifying_meshes.doc index d3149b730..36c4e0abb 100644 --- a/doc/salome/gui/SMESH/input/modifying_meshes.doc +++ b/doc/salome/gui/SMESH/input/modifying_meshes.doc @@ -18,24 +18,27 @@ elements of the mesh.
              5. its elements.
              6. \subpage rotation_page "Rotate" by the indicated axis and angle the mesh or some of its elements.
              7. -
              8. Create a \subpage symmetry_page "symmetrical copy" of the mesh +
              9. \subpage scale_page "Scale" the mesh or some of its +elements.
              10. +
              11. \subpage symmetry_page "Mirror" the mesh through a point or a vector of symmetry.
              12. +
              13. \subpage double_nodes_page "Duplicate nodes" to emulate a crack in the model.
              14. Unite meshes by \subpage sewing_meshes_page "sewing" free borders, conform free borders, border to side or side elements.
              15. -
              16. \subpage merging_nodes_page "Merge Notes", considered coincident +
              17. \subpage merging_nodes_page "Merge Nodes", considered coincident within the indicated tolerance.
              18. \subpage merging_elements_page "Merge Elements", considered coincident within the indicated tolerance.
              19. -
              20. \subpage moving_nodes_page "Move Nodes" to an arbitrary location +
              21. \subpage mesh_through_point_page "Move Nodes" to an arbitrary location with consequent transformation of all adjacent elements and edges.
              22. -
              23. \subpage mesh_through_point_page "Make node at a point", existing -or created anew.
              24. \subpage diagonal_inversion_of_elements_page "Invert an edge" between neighboring triangles.
              25. \subpage uniting_two_triangles_page "Unite two triangles".
              26. \subpage uniting_set_of_triangles_page "Unite several adjacent triangles".
              27. \subpage changing_orientation_of_elements_page "Change orientation" of the selected elements.
              28. +
              29. \subpage reorient_faces_page "Reorient faces by vector".
              30. \subpage cutting_quadrangles_page "Cut a quadrangle" into two triangles.
              31. +
              32. \subpage split_to_tetra_page "Split" volumic elements into tetrahedra.
              33. \subpage smoothing_page "Smooth" elements, reducung distortions in them by adjusting the locations of element corners.
              34. Create an \subpage extrusion_page "extrusion" along a vector.
              35. @@ -45,6 +48,12 @@ of the selected node or edge.
              36. Apply \subpage pattern_mapping_page "pattern mapping".
              37. \subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic", or vice versa.
              38. +
              39. \subpage make_2dmesh_from_3d_page "Generate boundary elements".
              40. +
              41. \subpage generate_flat_elements_page "Generate flat elements on group boundaries or on faces".
              42. +
              43. \subpage cut_mesh_by_plane_page "Cut a tetrahedron mesh by a plane".
              44. -*/ \ No newline at end of file +\note It is possible to use the variables defined in the SALOME \b NoteBook + to specify the numerical parameters used for modification of any object. + +*/ diff --git a/doc/salome/gui/SMESH/input/moving_nodes.doc b/doc/salome/gui/SMESH/input/moving_nodes.doc deleted file mode 100644 index d44ddc249..000000000 --- a/doc/salome/gui/SMESH/input/moving_nodes.doc +++ /dev/null @@ -1,36 +0,0 @@ -/*! - -\page moving_nodes_page Moving nodes - -\n In MESH you can change the location of any node of your mesh. In -this case all adjacent elements (edges) will be also transformed right -after the displaced node. - -To displace a node: -
                  -
                1. From the \b Modification menu choose the Move node item or -click "Move Node" button in the toolbar. - -\image html image67.png -
                  "Move Node" button
                  - -The following dialog box shall appear: - -\image html movenodes.png - -
                2. -
                3. Enter the ID of the required node in the Node ID field or -select this node in the 3D viewer. The coordinates of your node will -be automatically displayed in the \b Coordinates set of fields.
                4. -
                5. Set new coordinates for your node in the \b Coordinates set of fields.
                6. -
                7. Click the \b Apply or Apply and Close button.
                8. -
                - -\image html moving_nodes1.png "The initial mesh" - -\image html moving_nodes2.png "The node has been moved, transforming all adjacent edges" - -
                See Also a sample TUI Script of a -\ref tui_moving_nodes "Moving Nodes" operation. - -*/ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc b/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc deleted file mode 100644 index f81ed2618..000000000 --- a/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc +++ /dev/null @@ -1,67 +0,0 @@ -/*! - -\page netgen_2d_3d_hypo_page Netgen 2D and 3D hypotheses - -\n Netgen 2D and Netgen 3D hypotheses work only with Netgen 1D-2D and -Netgen 1D-2D-3D algorithms. These algorithms do not require -definition of lower-level hypotheses and algorithms (2D and 1D for -meshing 3D objects and 1D for meshing 2D objects). They prove to be -useful if lower-level meshing is homogeneous for all wires and faces -of the meshed object. - -\image html netgen2d.png - -
                  -
                • Name - allows to define the name for the algorithm (Netgen -2D (or 3D) Parameters by default).
                • -
                • Max Size - maximum linear dimensions for mesh cells.
                • -
                • Second Order - if this box is checked in, the algorithm will -create second order nodes on the mesh, which actually will become -\ref adding_quadratic_elements_page "Quadratic".
                • -
                • Fineness - ranging from Very Coarse to Very Fine allows to set the -level of meshing detalization using the three parameters below. You -can select Custom to define them manually.
                • -
                • Growth rate - allows to define how much the linear dimensions of -two adjacent cells can differ (i.e. 0.3 means 30%).
                • -
                • Nb. Segs per Edge and Nb Segs per Radius - allows to define the -minimum number of mesh segments in which edges and radiuses will be -split.
                • -
                • Allow Quadrangles - allows to use quadrangle elements in a -triangle 2D mesh. This checkbox is not present in Netgen 3D parameters -because currently building a tetrahedral mesh with quadrangle faces is -not possible.
                • -
                • Optimize - if this box is checked in, the algorithm will try to -create regular (possessing even sides) elements.
                • -
                - -\image html netgen3d_simple.png - -Netgen 2D simple parameters and Netgen 3D simple parameters allow defining the size of elements for each dimension. Note that Netgen algorithm does not strictly follow the input parameters. The actual mesh can be more or less dense than required.
                - -\b 1D group allows defining the size of 1D elements in either of two ways: -
                  -
                • Number of Segments has the same sense as \ref -number_of_segments_anchor "Number of segments" hypothesis with -equidistant distribution.
                • -
                • Average Length has the same sense as \ref -average_length_anchor "Average Length" hypothesis.
                • -
                - -\b 2D group allows defining the size of 2D elements -
                  -
                • Length from edges if checked in, acts like \ref -length_from_edges_anchor "Length from Edges" hypothesis, else
                • -
                • Max. Element Area defines the maximum element area like \ref -max_element_area_anchor "Max Element Area" hypothesis.
                • -
                - -\b 3D groups allows defining the size of 3D elements. -
                  -
                • Length from faces if checked in, the area of sides of -volumic elements will be equal to an average area of 2D elements, else
                • -
                • Max. Element Volume defines the maximum element volume like -\ref max_element_volume_hypo_page "Max Element Volume" -hypothesis.
                • -
                    - -*/ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/over_constrained_faces.doc b/doc/salome/gui/SMESH/input/over_constrained_faces.doc new file mode 100644 index 000000000..6c026f84a --- /dev/null +++ b/doc/salome/gui/SMESH/input/over_constrained_faces.doc @@ -0,0 +1,19 @@ +/*! + +\page over_constrained_faces_page Over-constrained faces + +\n This mesh quality control highlights faces sharing only one border +with other faces. In other words, the faces having all thier nodes on +the external border of the mesh are highlighted. + +\note The highlighted faces are actually over-constrained only if, at the computation time, +the boundary conditions on the borders where the nodes are located are all Dirichlet boundary conditions. + +\image html over_constrained_faces.png + +In this picture the over-constrained face is displayed in red. + +
                    See Also a sample TUI Script of a +\ref tui_over_constrained_faces "Over-constrained faces" filter. + +*/ diff --git a/doc/salome/gui/SMESH/input/over_constrained_volumes.doc b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc new file mode 100644 index 000000000..7f1ba280d --- /dev/null +++ b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc @@ -0,0 +1,18 @@ +/*! + +\page over_constrained_volumes_page Over-constrained volumes + +\n This mesh quality control highlights volumes sharing only one border with other volumes. +In other words, the volumes having all their nodes on the external border of the mesh are highlighted. + +\note The highlighted volumes are actually over-constrained only if, at the computation time, +the boundary conditions on the borders where the nodes are located are all Dirichlet boundary conditions. + +\image html over_constrained_volumes.png + +In this picture the over-constrained volume is displayed in red. + +
                    See Also a sample TUI Script of a +\ref tui_over_constrained_volumes "Over-constrained volumes" filter. + +*/ diff --git a/doc/salome/gui/SMESH/input/pattern_mapping.doc b/doc/salome/gui/SMESH/input/pattern_mapping.doc index cf556d51b..ef7f8ba66 100644 --- a/doc/salome/gui/SMESH/input/pattern_mapping.doc +++ b/doc/salome/gui/SMESH/input/pattern_mapping.doc @@ -5,36 +5,87 @@

                    About patterns

                    The pattern describes a mesh to generate: positions of nodes within a -geometrical domain and nodal connectivity of elements. As well, a -pattern specifies the so-called key-points, i.e. nodes that will be -located at geometrical vertices. Pattern description is stored in +geometrical domain and nodal connectivity of elements. A +pattern also specifies the so-called key-points, i.e. the nodes that will be +located at geometrical vertices. The pattern description is stored in \.smp file. The smp file contains 4 sections: -
                      -
                    1. The first line holds the number of nodes (N).
                    2. -
                    3. The next N lines describe nodes coordinates. Each line holds 2 -coordinates of a node.
                    4. - -
                    5. A key-points line: indices of nodes to be mapped on geometrical -vertices. An index n refers to a node described on an n-th line of -section 2. The first node index is zero.
                    6. - -
                    7. The rest lines describe nodal connectivity of elements, one line -for an element. A line holds indices of nodes forming an element. An -index n refers to a node described on an n-th line of the section -2. The first node index is zero. There must be 3 or 4 indices on a -line: only 2d elements are allowed.
                    8. -
                    - -The 2D pattern must contain at least one element and at least one -key-point. All key-points must lay on boundaries. - -An example of a simple smp file and a preview of a pattern described -in this file: - -\image html image94.gif +-# The first line indicates the total number of pattern nodes (N). +-# The next N lines describe nodes coordinates. Each line contains 2 +node coordinates for a 2D pattern or 3 node cordinates for a 3D pattern. +Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1]. +-# The key-points line contains the indices of the nodes to be mapped on geometrical +vertices (for a 2D pattern only). Index n refers to the node described +on the n-th line of section 2. The index of the first node zero. For a 3D pattern the key points are not specified. +-# The remaining lines describe nodal connectivity of elements, one line +for each element. Each line holds indices of nodes forming an element. +Index n refers to the node described on the n-th line of section 2. +The first node index is zero. There must be 3 or 4 indices on each +line for a 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8 +indices for a 3D pattern (only 3d elements are allowed). + +A 2D pattern must contain at least one element and at least one +key-point. All key-points must lie on boundaries. + +A 3D pattern must contain at least one element. + +An example of a simple 2D pattern smp file: + +\code +!!! SALOME 2D mesh pattern file +!!! +!!! Nb of points: +9 + 200 0 !- 0 + 100 0 !- 1 + 0 0 !- 2 + 0 -100 !- 3 + 0 -200 !- 4 + 100 -200 !- 5 + 200 -200 !- 6 + 200 -100 !- 7 + 100 -100 !- 8 +!!! Indices of 4 key-points + 2 0 4 6 +!!! Indices of points of 6 elements + 0 1 8 + 8 5 6 7 + 2 3 8 + 8 3 4 5 + 8 7 0 + 8 1 2 +\endcode + +The image below provides a preview of the above pattern: + +\image html pattern2d.png + +An example of a simple 3D pattern smp file: + +\code +!!! SALOME 3D mesh pattern file +!!! +!!! Nb of points: +9 + 0 0 0 !- 0 + 1 0 0 !- 1 + 0 1 0 !- 2 + 1 1 0 !- 3 + 0 0 1 !- 4 + 1 0 1 !- 5 + 0 1 1 !- 6 + 1 1 1 !- 7 + 0.5 0.5 0.5 !- 8 +!!! Indices of points of 6 elements: + 0 1 5 4 8 + 7 5 1 3 8 + 3 2 6 7 8 + 2 0 4 6 8 + 0 2 3 1 8 + 4 5 7 6 8 +\endcode

                    Application of pattern mapping

                    @@ -46,90 +97,122 @@ From the \b Modification menu choose the Pattern Mapping item or click \image html image98.png
                    "Pattern mapping" button
                    -The following dialog box shall appear: +The following dialog box will appear: + +\n For a 2D pattern \image html patternmapping1.png +In this dialog you should specify: + +
                      +
                    • \b Pattern, which can be loaded from .smp pattern file previously +created manually or generated automatically from an existing mesh or submesh.
                    • +
                    • \b Face with the number of vertices equal to the number of + key-points in the pattern; the number of key-points on internal + boundaries of the pattern must also be equal to the number of vertices + on internal boundaries of the face;
                    • +
                    • \b Vertex to which the first key-point should be mapped;
                    • +Alternatively, it is possible to select Refine selected mesh elements +checkbox and apply the pattern to +
                    • Mesh Face instead of a geometric Face
                    • +
                    • and select \b Node instead of vertex.
                    • + +Additionally it is possible to: +
                    • Reverse the order of key-points By default, the vertices of + a face are ordered counterclockwise.
                    • +
                    • Enable to Create polygons near boundary
                    • +
                    • and Create polyhedrons near boundary
                    • +
                    + +\n For a 3D pattern + \image html patternmapping2.png -To apply a pattern to a geometrical object, you should specify: +In this dialog you should specify:
                      -
                    • a face having the number of vertices equal to the number of -key-points in the pattern; the number of key-points on internal -boundaries of a pattern must also be equal to the number of vertices -on internal boundaries of a face;
                    • -
                    • a vertex to which the first key-point should be mapped;
                    • -
                    • reverse or not the order of key-points. (The order of vertices of -a face is counterclockwise looking from outside).
                    • +
                    • \b Pattern, which can be loaded from .smp pattern file previously +created manually or generated automatically from an existing mesh or submesh.
                    • +
                    • A 3D block (Solid) object;
                    • +
                    • Two vertices that specify the order of nodes in the resulting mesh.
                    • +Alternatively, it is possible to select Refine selected mesh elements +checkbox and apply the pattern to +
                    • One or several Mesh volumes instead of a geometric 3D +object
                    • +
                    • and select two /b Nodes instead of vertices.
                    • +Additionally it is possible to: +
                    • Enable to Create polygons near boundary
                    • +
                    • and Create polyhedrons near boundary
                    -Then you either load a .smp pattern file previously created manually -by clicking on the "Load pattern" button, or click on the \b -New button for automatic generation. -\n For an automatic generation you just specify a geometrical face -having a mesh built on it. Mesh nodes lying on face vertices become -key-points. Additionally, you may choose the way of getting nodes -coordinates by projecting nodes on the face instead of using -"positions on face" generated by mesher (if there is any). Faces -having a seam edge can?t be used for automatic pattern creation. - -When creating a pattern from an existing mesh, there are two possible -cases: -
                      -
                    1. A sub-mesh on face is selected. A pattern is created from the 2d -elements bound to a face by mesher. Node coordinates are either -"positions on face" computed by mesher, or coordinates got by node -projection on a geometrical surface, according to your choice.
                    2. -
                    3. A mesh where the main shape is a face, is selected. A pattern is -created from all the 2d elements in a mesh. If all mesh elements are -build by mesher, the user can select the way of getting nodes -coordinates, else all nodes are projected on a face surface.
                    4. -
                    - -\image html a-patterntype.png +\n Automatic Generation + +To generate a pattern automatically from an existing mesh or submesh, +click \b New button. + +The following dialog box will appear: \image html a-patterntype1.png -

                    Mapping algorithm

                    +In this dialog you should specify: -The mapping algorithm is as follows: -
                      -
                    1. Key-points are set in the order that they are encountered when -walking along a pattern boundary so that elements are on the left. The -first key-point is preserved. -
                    2. +
                        +
                      • Mesh or Submesh, which is a meshed geometrical face (for a +2D pattern) or a meshed solid (for a 3D pattern). Mesh nodes lying on +the face vertices become key-points of the pattern.
                      • +
                      • A custom Pattern Name
                      • +
                      • Additionally, for a 2D pattern you may choose to +Project nodes on the face to get node coordinates instead of using +"positions on face" generated by the mesher (if there is any). The faces +having a seam edge cannot be used for automatic pattern creation.
                      • +
                      -
                    3. Find geometrical vertices corresponding to key-points by vertices -order in a face boundary; here, "Reverse order of key-points" flag is -taken into account. +When a pattern is created from an existing mesh, two cases are possible: -\image html image95.gif -
                    4. +- A sub-mesh on a face/solid is selected. The pattern is created from the 2d/3d +elements bound to the face/solid by the mesher. For a 2D pattern, the node coordinates are either +"positions on face" computed by the mesher, or coordinates got by node +projection on a geometrical surface, according to the user choice. For +a 3D pattern, the node coordinates correspond to the nodes computed by +the mesher. +- A mesh, where the main shape is a face/solid, is selected. The pattern is +created from all 2d/3d elements in a mesh. In addition, if all mesh +elements of a 2D pattern are built by the mesher, the user can select +how to get node coordinates, otherwise all nodes are projected on +a face surface. -
                    5. Boundary nodes of a pattern are mapped onto edges of a face: a -node located between certain key-points on a pattern boundary is -mapped on a geometrical edge limited by corresponding geometrical -vertices. Node position on an edge reflects its distance from two -key-points. -\image html image96.gif -
                    6. - -
                    7. Coordinates of a non-boundary node in a parametric space of a face -are defined as following. In a parametric space of a pattern, a node -lays at the intersection of two iso-lines, each of which intersects a -pattern boundary at least at two points. Knowing mapped positions of -boundary nodes, we find where isoline-boundary intersection points are -mapped to, and hence we can find mapped isolines direction and then, -two node positions on two mapped isolines. The eventual mapped -position of a node is found as an average of positions on mapped -isolines. +

                      Mapping algorithm

                      + +The mapping algorithm for a 2D case is as follows: +- The key-points are set counterclockwise in the order corresponding + to their location on the pattern boundary. The first key-point is preserved. +- The geometrical vertices corresponding to the key-points are found + on face boundary. Here, "Reverse order of key-points" flag is set. +\image html image95.gif +- The boundary nodes of the pattern are mapped onto the edges of the face: a + node located between two key-points on the pattern boundary is + mapped on the geometrical edge limited by the corresponding geometrical + vertices. The node position on the edge depends on its distance from the + key-points. +\image html image96.gif +- The cordinates of a non-boundary node in the parametric space of the face + are defined in the following way. In the parametric space of the + pattern, the node lies at the intersection of two iso-lines. Both + of them intersect the pattern boundary at two + points at least. If the mapped positions of boundary nodes are known, it is + possible to find, where the points at the intersection of isolines + and boundaries are mapped. Then it is possible to find + the direction of mapped isolinesection and, filally, the poitions of + two nodes on two mapped isolines. The eventual mapped + position of the node is found as an average of the positions on mapped + isolines. \image html image97.gif -
                    8. -
                    -
                    See Also a sample TUI Script of a +The 3D algorithm is similar. + +See Also a sample TUI Script of a \ref tui_pattern_mapping "Pattern Mapping" operation. -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/point_marker.doc b/doc/salome/gui/SMESH/input/point_marker.doc new file mode 100644 index 000000000..40c2b932b --- /dev/null +++ b/doc/salome/gui/SMESH/input/point_marker.doc @@ -0,0 +1,53 @@ +/*! + +\page point_marker_page Point Marker + +\n You can change the representation of points in +the 3D viewer either by selecting one of the predefined +shapes or by loading a custom texture from an external file. + +- Standard point markers + +The Mesh module provides a set of predefined point marker shapes +which can be used to display points in the 3D viewer. +Each standard point marker has two attributes: type (defines shape +form) and scale factor (defines shape size). + +\image html point_marker_widget1.png + +
                    + +\image html std_point_marker.png "Mesh presentation with standard point markers" + +- Custom point markers + +It is also possible to load a point marker shape from an external file. +This file should provide a description of the point texture as a set +of lines; each line is represented as a sequence of "0" and "1" symbols, +where "1" symbol means an opaque pixel and "0" symbol means a +transparent pixel. The width of the texture corresponds to the length +of the longest line in the file, expanded to the nearest byte-aligned +value. The height of the texture is equal to the number of non-empty +lines in the file. Note that missing symbols are replaced by "0". + +Here is a texture file sample: + +
                    +00111100
                    +00111100
                    +11111111
                    +11111111
                    +11111111
                    +11111111
                    +00111100
                    +00111100
                    +
                    + +\image html point_marker_widget2.png + +
                    + +\image html custom_point_marker.png "Mesh presentation with custom point markers" + +*/ + diff --git a/doc/salome/gui/SMESH/input/preview_meshes.doc b/doc/salome/gui/SMESH/input/preview_meshes.doc deleted file mode 100644 index 92a4cca27..000000000 --- a/doc/salome/gui/SMESH/input/preview_meshes.doc +++ /dev/null @@ -1,36 +0,0 @@ -/*! - -\page preview_meshes_page Preview and Compute meshes - -Before whole mesh computation it is allowed to see the mesh preview. -When mesh object is already created and all hypotheses assigned, -select your mesh in the Object Browser. From the -\b Mesh menu select \b Preview or click "Preview" button of the -toolbar or activate "Preview" item from pop-up menu. - -\image html mesh_precompute.png -
                    "Preview" button
                    - -The Mesh Preview dialog box appears. In this dialog box you can select -preview mode 1D mesh or 2D mesh depending on assigned -hypotheses to mesh. - -The 1D mesh preview shows as nodes computed on geometry edges - -\image html preview_mesh_1D.png - -The 2D mesh preview shows edge mesh elements, computed on geometry faces - -\image html preview_mesh_2D.png - -Pressing Compute button leads to whole mesh computation -process. -During exit from Preview dialog box, the question about storage temporary -created mesh elements appers: - -\image html preview_tmp_data.png - -Note, that computed temporary mesh elements can be reused during next -mesh computation process. - -*/ diff --git a/doc/salome/gui/SMESH/input/prism_3d_algo.doc b/doc/salome/gui/SMESH/input/prism_3d_algo.doc index 837923ac1..5589ba3a7 100644 --- a/doc/salome/gui/SMESH/input/prism_3d_algo.doc +++ b/doc/salome/gui/SMESH/input/prism_3d_algo.doc @@ -4,9 +4,9 @@ 3D extrusion algorithm can be used for meshing prisms, i.e. 3D Shapes defined by two opposing faces having the same number of vertices and -edges and meshed using the \ref projection_algos_page "2D Projection" -algorithm. These two faces should be connected by quadrangle "side" -faces. +edges and meshed using, for example, the \ref projection_algos_page +"2D Projection" algorithm. These two faces should be connected by +quadrangle "side" faces. The opposing faces can be meshed with either quadrangles or triangles, while the side faces should be meshed with quadrangles only. @@ -17,4 +17,8 @@ As you can see, the 3D extrusion algorithm permits to build and to have in the same 3D mesh such elements as hexahedrons, prisms and polyhedrons. -*/ \ No newline at end of file +\note This algorithm works correctly only if the opposing faces have +the same (or similar) meshing topography. Otherwise, 3D extrusion +algorithm can fail to build mesh volumes. + +*/ diff --git a/doc/salome/gui/SMESH/input/projection_algos.doc b/doc/salome/gui/SMESH/input/projection_algos.doc index 422b40993..dcbae8db4 100644 --- a/doc/salome/gui/SMESH/input/projection_algos.doc +++ b/doc/salome/gui/SMESH/input/projection_algos.doc @@ -17,14 +17,18 @@ The following dialog box will appear: \image html projection_1d.png In this menu you can define the \b Name of the algorithm, the already -meshed source \b Edge and the \b Mesh (optional, use it if there are several -different meshes on the same edge). It could also be necessary to -define the orientation of edges, which is done by indicating the -Source Vertex being the first point of the Source Edge and the -Target Vertex being the first point of the created \b Edge. For -a group of edges, Source and Target vertices should be -shared by only one edge of the group. If Source and -Target vertices are specified, the elements of the group must be ajacent. +meshed source \b Edge and the \b Mesh (It can be omitted only when +projecting a submesh on another one from the same global Mesh). +It could also be necessary to define the orientation of edges, +which is done by indicating the Source Vertex being the first point +of the Source Edge and the Target Vertex being the first point of +the created \b Edge. +
                    +For a group of edges, Source and Target vertices should be +shared by one edge of the group. If Source and Target +vertices are specified, the elements of the group must be adjacent. +The source and target groups must contain equal number of edges +and they must form topologically equal structures. \n Projection 2D algorithm allows to define the mesh of a face (or group of faces) by the @@ -42,17 +46,26 @@ following dialog box will appear: \image html projection_2d.png In this menu you can define the \b Name of the algorithm, the already -meshed source \b Face and the \b Mesh (optional, use it if there are several -different meshes on the same face). It could also be necessary to -define the orientation of mesh on the face, which is done by -indicating two Source Vertices, which belong to the same edge of the -source face, and two Target Vertices, which belong to the same edge of -the created \b Face. +meshed source \b Face and the \b Mesh (It can be omitted only when +projecting a submesh on another one from the same global Mesh). +It could also be necessary to define the orientation of mesh on the +face, which is done by indicating two Source Vertices, which +belong to the same edge of the source face, and two Target +Vertices, which belong to the same edge of the created \b Face. +For groups of face, they must contain equal number of faces +and they must form topologically equal structures. + +\n Projection 1D-2D algorithm differs from Projection 2D +algorithm in one aspect: it generates mesh segments on edges of +the face according to the projected 2D elements; thus it does not +require the edges to be meshed by any other 1D algorithm; moreover it +does not allow to mesh edges of the face using another algorithm via +definition of sub-meshes. \n Projection 3D algorithm allows to define the mesh of a shape by the projection of another already meshed shape. This algorithm works -only if all faces and edges of the target face have been meshed as 1D -Projections of the faces and edges of the source face. Another +only if all faces and edges of the target shape have been meshed as 1D-2D +Projections of the faces and edges of the source shape. Another limitation is that this algorithm currently works only on boxes. To apply this algorithm select the solid to be meshed (indicated in @@ -63,12 +76,15 @@ following dialog box will appear: \image html projection_3d.png In this menu you can define the \b Name of the algorithm, the already -meshed source 3D shape and the \b Mesh (optional, use it if there are -several different meshes on the same shape). It could also be -necessary to define the orientation of mesh on the shape, which is +meshed source 3D shape and the \b Mesh (It can be omitted only when +projecting a submesh on another one from the same global Mesh). +It could also be necessary to define the orientation of mesh on the shape, which is done by indicating two Source Vertices, which belong to the same edge of the source 3D Shape, and two Target Vertices, which belong to the same edge of the source 3D Shape. +
                    See Also a sample TUI Script of a +\ref tui_projection "Projection Algorithms". + */ diff --git a/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc b/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc new file mode 100644 index 000000000..0854941ea --- /dev/null +++ b/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc @@ -0,0 +1,29 @@ +/*! + +\page radial_quadrangle_1D2D_algo_page Radial Quadrangle 1D2D + +\n This algorithm applies to the meshing of 2D shapes under the +following conditions: the face must be a full circle or a part of circle +(i.e. the number of edges is less or equal to 3 and one of them is a circle curve). +The resulting mesh consists of triangles (near the center point) and +quadrangles. + +This algorithm is optionally parametrized by the hypothesis indicating the number +of mesh layers along the radius. The distribution of layers can be set with any 1D Hypothesis. + +If no own hypothesis of the algorithm is assigned, any local or global hypothesis is used +by the algorithm to discretize edges. Note that if the geometrical face has two radial edges, +they must be meshed with equal number of segments. + +If no 1D hypothesis is assigned to an edge, "Default Number of Segments" preferences parameter +is used to discretize the edge. + +\image html hypo_radquad_dlg.png + +\image html mesh_radquad_01.png "Radial Quadrangle 2D mesh on the top and the bottom faces of a cylinder" + +\image html mesh_radquad_02.png "Radial Quadrangle 2D mesh on a part of circle" + +\sa A sample \ref tui_radial_quadrangle "TUI Script". + +*/ diff --git a/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc b/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc index 6e0f7f804..0a48ee65e 100644 --- a/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc +++ b/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc @@ -6,6 +6,7 @@
                    • \ref removing_nodes_anchor "Nodes"
                    • +
                    • \ref removing_orphan_nodes_anchor "Orphan Nodes"
                    • \ref removing_elements_anchor "Elements"
                    • \ref clear_mesh_anchor "Clear Mesh Data"
                    @@ -18,32 +19,58 @@
                    1. Select your mesh in the Object Browser or in the 3D viewer.
                    2. -
                    3. From the Modification menu choose Remove and from the associated -submenu select the Remove nodes, or just click "Remove nodes" +
                    4. From the Modification menu choose Remove and from the associated +submenu select the Nodes, or just click "Remove nodes" button in the toolbar. -\image html image88.gif +\image html remove_nodes_icon.png
                      "Remove nodes" button
                      The following dialog box will appear: \image html removenodes.png -In this dialog box you can specify one or several nodes +In this dialog box you can specify one or several nodes:
                        -
                      • Choosing them manually with the mouse in the 3D Viewer. You can -click on a node in the 3D viewer and it will be highlighted
                      • -
                      • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the nodes. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
                      • +
                      • choose mesh nodes with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                      • +
                      • input the node IDs directly in ID Elements field. The selected nodes will be highlighted in the +viewer; or
                      • +
                      • apply Filters. Set filter button allows to apply a filter to the selection of nodes. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                      + +
                    \note Be careful while removing nodes because if you remove a definite node of your mesh all adjacent elements will be also deleted. +
                    +\anchor removing_orphan_nodes_anchor +

                    Removing orphan nodes

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

                    Removing elements

                    @@ -52,8 +79,8 @@ node of your mesh all adjacent elements will be also deleted.
                    1. Select your mesh in the Object Browser or in the 3D viewer.
                    2. -
                    3. From the \b Modification menu choose \b Remove and from the -associated submenu select the Remove elements, or just click +
                    4. From the Modification menu choose Remove and from the +associated submenu select the Elements, or just click "Remove elements" button in the toolbar. \image html remove_elements_icon.png @@ -65,13 +92,14 @@ The following dialog box will appear: In this dialog box you can specify one or several elements
                        -
                      • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
                      • -
                      • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
                      • +
                      • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                      • +
                      • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
                      • +
                      • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                      +
                    5. Click \b Apply or Apply and Close to confirm deletion of the specified elements.
                    @@ -91,7 +119,7 @@ about filters on the
                  • From the Modification menu choose Remove and from the associated submenu select the Clear Mesh Data, or just click "Clear Mesh Data" button in the toolbar. You can also right-click on the mesh in the -Object Browser and select Clear Mesh Data in the pop-up menu. +Object Browser and select Clear Mesh Data in the pop-up menu.
              \image html mesh_clear.png diff --git a/doc/salome/gui/SMESH/input/reorient_faces.doc b/doc/salome/gui/SMESH/input/reorient_faces.doc new file mode 100644 index 000000000..f637aecfd --- /dev/null +++ b/doc/salome/gui/SMESH/input/reorient_faces.doc @@ -0,0 +1,61 @@ +/*! + +\page reorient_faces_page Reorient faces by vector + +\n This operation allows changing orientation of a set of neighboring +faces. The desired orientation is defined by a vector. Since direction +of face normals in the set can be even opposite, it is necessary to +specify a control face whose normal will be compared with the vector. This +face can be specified either explicitly or can be found by closeness to +a given point. + +Orientation of a face is changed by reverting the order of its nodes. + +To change orientation of faces: +
                +
              1. In the \b Modification menu select the Reorient faces by + vector item or click Reorient faces by + vector button in the toolbar. + +
                +\image html reorient_faces_face.png +"Reorient faces by vector" button +
                + +The following dialog box will appear: + +
                +\image html reorient_2d_point.png +\image html reorient_2d_face.png +
                + +
              2. In this dialog +
                  +
                • Specify a way of selection of the control face: by point or + explicitely.
                • +
                • Select an \b Object containing faces to reorient, either in the Object + Browser or in the 3D Viewer; it can be either
                    +
                  • group of faces,
                  • +
                  • sub-mesh of faces or
                  • +
                  • mesh.
                  • +
                • +
                • Specify either coordinates of a \b Point by which the control face + will be found or the control \b Face it-self. You can easy specify the \b + Point by either picking a node in the 3D Viewer or by selecting a vertex + in the Object Browser. The \b Face can be either picked by mouse in + the 3D Viewer or its ID can be entered by typing.
                • +
                • Set up a \b Direction to be compared with the normal of the + control face. You can either pick a node in the 3D Viewer then a \b Direction + from the coordinate system origin to the selected node will be set, + or you can pick two nodes (holding Shift button) then a \b Direction + from the first to the second node will be set.
                • +
                +
              3. + +
              4. Click the \b Apply or Apply and Close button to confirm the operation.
              5. +
              + +
              See Also a sample TUI Script of a +\ref tui_reorient_faces "Reorient faces by vector" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/revolution.doc b/doc/salome/gui/SMESH/input/revolution.doc index 67dfdb374..1d13bb23a 100644 --- a/doc/salome/gui/SMESH/input/revolution.doc +++ b/doc/salome/gui/SMESH/input/revolution.doc @@ -16,31 +16,42 @@ on the revolution axis). \image html image92.png
              "Revolution" button
              -The following dialog box shall appear: +The following dialog common for line and planar elements will appear: \image html revolution1.png -\image html revolution2.png
            11. -In this dialog box you should specify: +In this dialog you should specify:
              • the type of elements which will be extruded (1D or 2D),
              • -
              • specify the IDs of the elements which will be revolved +
              • specify the IDs of the elements which will be revolved: + + +
                  +
                • Select the whole mesh, submesh or group activating this +checkbox; or
                • +
                • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                • +
                • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
                • +
                • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                • +
                +
              • + +
              • specify the axis of revolution:
                  -
                • Check on Select the whole mesh, submesh or group option -
                • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
                • -
                • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
                • +
                • specify the cooordinates of the start \b Point of the vector of revolution;
                • +
                • specify the \b Vector of revolution through the coordinates of its +end point with respect to the coordinates of the start +point. Alternatively, it is possible to specify the vector through the +normal to the selected face.
              • -
              • specify the axis (point and vector) around which the elements will -be revolved,
              • -
              • angle of rotation and number of steps,
              • + +
              • specify the angle of revolution and the number of revolution steps,
                • Angle by Step - the elements are extruded by the specified angle at each step (i.e. for Angle=30 and Number of Steps=2, the elements will be extruded by 30 degrees twice for a total of 30*2=60)
                • @@ -52,15 +63,18 @@ be revolved, \image html revolutionsn1.png "Example of Revolution with Total Angle"
                -
              • tolerance of rotation
              • -
              +
            12. -
            13. Preview checkbox allows showing the results of parameter-setting in the viewer
            14. -
            15. Generate Groups checkbox allows copying the groups of +
            16. specify the tolerance for the operation
            17. + +
            18. activate Preview checkbox to show the parameter-setting in the viewer
            19. +
            20. activate Generate Groups checkbox to copy the groups of elements of the source mesh to the newly created one.
            21. + -
            22. Click the \b Apply or \b OK button.
            23. +
            24. Click \b Apply or Apply and Close button to confirm the +operation.
            diff --git a/doc/salome/gui/SMESH/input/rotation.doc b/doc/salome/gui/SMESH/input/rotation.doc index e64357276..cb46359fd 100644 --- a/doc/salome/gui/SMESH/input/rotation.doc +++ b/doc/salome/gui/SMESH/input/rotation.doc @@ -2,41 +2,70 @@ \page rotation_page Rotation -\n This operation allows to rotate in space your mesh or +\n This operation allows to rotate in space the mesh or some of its elements. +To rotate the mesh: + +
              +
            1. From the \b Modification menu choose \b Transformation -> \b Rotation item or click +"Rotation" button in the toolbar. + \image html rotation_ico.png "Rotation button" -To rotate your mesh: -\par -From the \b Modification choose \b Transformation and from its sub-menu -select the \b Rotation item. The following dialog box shall appear: +The following dialog will appear: \image html rotation.png -\par -In this dialog box you can specify the elements which should be -rotated + +
            2. + +
            3. +In this dialog: +
                +
              • specify the IDs of the elements which will be rotated: +
                  -
                • Check on Select the whole mesh, submesh or group option -
                • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
                • -
                • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
                • +
                • Select the whole mesh, submesh or group activating this +checkbox; or
                • +
                • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                • +
                • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
                • +
                • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                - and the rotation parameters: +
              • + +
              • specify the axis of rotation:
                  -
                • \b Axis: point and vector
                • -
                • \b Angle of rotation
                • +
                • specify the cooordinates of the start \b Point of the vector of rotation;
                • +
                • specify the \b Vector of rotation through the coordinates of its +end point with respect to the coordinates of the start point;
                +
              • +
              • specify the \b Angle of rotation
              • -\n Toggle the corresponding checkbox to Select whole mesh, submesh or group. -\n When Move elements radio button is selected, the source mesh (or elements) is created at the new location and erased from its previous location -\n When Copy elements radio button is selected,the source mesh (or elements) is created at the new location, but it also remains at its previous location and is considered one and single mesh with the result of the rotation. -\n When Create as new mesh radio button is selected, the source mesh (or elements) remains at its previous location and a new mesh is created at the new location and appears in the Object Browser with the default name MeshName_rotated (you can change this name in the adjacent box). -\n Copy groups checkbox allows copying the groups of elements of the source mesh to the newly created one. -\par +
              • specify the conditions of rotation: +
                  +
                • activate Move elements radio button to create the source +mesh (or elements) at the new location and erase it from the previous location;
                • +
                • activate Copy elements radio button to create the source +mesh (or elements) at the new location, but leave it at the previous +location, the source mesh will be considered one and single mesh with the result of the rotation;
                • +
                • activate Create as new mesh radio button to leave the +source mesh (or elements) at its previous location and create a new +mesh at the new location, the new mesh appears in the Object Browser +with the default name MeshName_rotated (it is possible to change this +name in the adjacent box);
                • +
                • activate Copy groups checkbox to copy the groups of elements of the source mesh to the newly created mesh.
                • +
                +
              • + +
              • activate Preview checkbox to show the result of transformation in the viewer
              • +
              • click \b Apply or Apply and Close button to confirm the +operation.
              • +
              +
            \image html rotation1.png "The initial mesh" diff --git a/doc/salome/gui/SMESH/input/scalar_bar.doc b/doc/salome/gui/SMESH/input/scalar_bar.doc new file mode 100755 index 000000000..146a7fa78 --- /dev/null +++ b/doc/salome/gui/SMESH/input/scalar_bar.doc @@ -0,0 +1,40 @@ +/*! + +\page scalar_bar_dlg Scalar Bar properties + +In this dialog you can specify the properties of the scalar bar + +\image html scalar_bar_dlg.png + +
              +
            • Scalar Range in this menu you can specify +Min value and Max value of the Scalar Bar
            • + +
            • Font - in this menu you can set type, face and color for +the font of Title and Labels of the Scalar +Bar
            • + +
            • Colors & Labels - in this menu you can set the number of +colors and the number of labels of the Scalar +Bar
            • + +
            • Orientation - allows choosing between vertical and +horizontal orientation of the Scalar Bar
            • . + +
            • Origin & Size Vertical & Horizontal - allows defining the +location (X and Y) and size (Width and +Height) of Scalar Bar
            • +
                +
              • X: abscissa of the origin (from the left +side)
              • +
              • Y: ordinate of the origin (from the bottom)
              • +
              +
            • Distribution in this menu you can Show/Hide distribution histogram of the values of the Scalar Bar and specify histogram properties
            • +
                +
              • Multicolor the histogram is colored as Scalar Bar
              • +
              • Monocolor the histogram is colored as selected with Distribution color selector
              • +
              +
            + + +*/ diff --git a/doc/salome/gui/SMESH/input/scale.doc b/doc/salome/gui/SMESH/input/scale.doc new file mode 100644 index 000000000..57626fd78 --- /dev/null +++ b/doc/salome/gui/SMESH/input/scale.doc @@ -0,0 +1,134 @@ +/*! + +\page scale_page Scale + +\n This geometrical operation allows to scale in space your mesh +or some of its elements. + +To scale a mesh: + +
              +
            1. From the \b Modification menu choose \b Transformation -> \b Scale +\b Transform item. + +One of the following dialogs will appear: + +With one scale factor: +\image html scale01.png + +Or with different scale factors for axes: +\image html scale02.png + +
            2. + +
            3. +In the dialog: +
                +
              • specify the IDs of the translated elements: + +
                  +
                • Select the whole mesh, submesh or group activating this +checkbox; or
                • +
                • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                • +
                • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
                • +
                • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                • +
                +
              • + +
              • specify the base point for scale
              • + +
              • specify the scale factor
              • + +
              • specify the conditions of scale: +
                  +
                • activate Move elements radio button to scale the selected +mesh (or elements) without creating a copy;
                • +
                • activate Copy elements radio button to duplicate the selected +mesh (or elements) and to apply scaling to the copy within the same mesh;
                • +
                • activate Create as new mesh radio button to leave the +selected mesh (or elements) at its previous location and create a new +mesh of the scaled copy of the selected elements; the new mesh appears in the Object Browser +with the default name MeshName_scaled (it is possible to change this +name in the adjacent box);
                • +
                • activate Copy groups checkbox to copy the groups of +elements existing in the source mesh to the newly created mesh.
                • +
                +
              • + + + +
              • activate Preview checkbox to show the result of transformation in the viewer
              • +
              • click \b Apply or Apply and Close button to confirm the operation.
              • +
              +
            + + + +Example of using: + +1. Create quandrangle mesh 3x3 on a simple planar face (200x200) + +\image html scaleinit01.png + +and union 3 faces (along axis Z) to group "gr_faces" + +\image html scaleinit02.png + + + +2. Perform scale operation for the whole mesh and create a new mesh: + +\image html scale03.png + +result after operation: + +\image html scaleres03.png + + + +3. Perform scale operation for the whole mesh and copy elements: + +\image html scale04.png + +result after operation: + +\image html scaleres04.png + + + +4. Perform scale operation for a group of faces and copy elements: + +\image html scale06.png + +result after operation: + +\image html scaleres06.png + + + +5. Perform scale operation for two edges and move elements: + +\image html scale07.png + +result after operation: + +\image html scaleres07.png + + + +6. Perform scale operation for one face and move elements: + +\image html scale09.png + +result after operation: + +\image html scaleres09.png + + +
            See Also a sample TUI Script of a \ref tui_scale "Scale" operation. + + +*/ diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc index 66c72a0e8..4e58dcee0 100644 --- a/doc/salome/gui/SMESH/input/selection_filter_library.doc +++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc @@ -9,8 +9,8 @@ via Tools / Selection filter library. \image html selectionfilterlibrary.png Library file name shows the path and the file name where your -filters will be stored. By clicking the Browse button you can load an -existing filter library. +filters will be stored. By clicking the Browse button you can +load an existing filter library. \n Names of filters lists the filters created or uploaded for the current study. You can \b Add or \b Delete filters. \n In Filter name box you can specify the name for your @@ -31,18 +31,28 @@ specify logical relations between criteria using \b Binary operators Or and And. \n Some criteria should have the additional parameter of \b Tolerance. -When we create a Standalone Group using filters (for this click -Set Filters button in the Create Group menu), the menu -for setting filters looks a bit differently. Toggling Insert filter -in viewer checkbox enables to preview the group selected with your -current filter in the viewer. -\n In the \b Source field you choose if the filter will be applied to -the whole \b Mesh, the Initial Selection or the Current Group. -\n Copy from... button gives you a possibility to load an +When we create a group using filters (for this click +Set Filters button in the Create Group dialog), the menu +for setting filters looks a bit differently (see below). Switching +on Insert filter in viewer checkbox limits selection of elements +in the Viewer using your current filter. +
            +In the \b Source field you choose if the filter will be applied to +the whole \b Mesh, the Initial Selection or the Current +Group. If \b Mesh is chosen, the elements satisfying the filter +will be selected in the 3D Viewer. If Initial Selection is +chosen, the filter will be applied to the selected elements and the +elements rejected by the filter will be deseleced. If Current +Group is chosen, the filter will be applied to the list of +elements in the Greate Croup dialog and the elements rejected +by the filter will be removed from the list. +
            +Copy from... button gives you a possibility to load an existing filter from Selection filter library and Add to... button gives you a possibility to save your current filter in the Library. -\n Note: If the button Apply and Close is disabled, there +
            +Note: If the button Apply and Close is disabled, there is no selected mesh in the Object Browser and the filter can not be created. You have to select the mesh and the button will be enabled. @@ -66,20 +76,19 @@ shape, the algorithm works slower. IDs. Threshold Value can be, for example: "1,2,3,50-60,63,67,70-78"
          5. -Color of Group allows selection of entities belonging to Group with -specified color defined by the Threshold Value. +Color of Group allows selection of entities belonging to the Group with +the color defined by the Threshold Value.
          6. -Some criteria are applicable to all Entity types: except for +Some criteria are applicable to all Entity types, except for Nodes
            • -Linear allows selection of Linear or Quadratic (in case of -Unary set to "Not" state) +Linear allows selection of Linear or Quadratic elements (if Unary is set to "Not")
            • Geometry type allows selection of elements by their geometric type defined by the Threshold Value. The list of available geometric -types depends on element entity type defined by the Threshold Value. +types depends on the element entity type defined by the Threshold Value.
            @@ -97,12 +106,25 @@ specified arbitrary surface within a given Tolerance. -Additional criteria to select mesh Edges are the following: +The following criteria allow selecting mesh Nodes: +
            • +Free nodes selects nodes not belonging to any mesh element. +
            • +Double nodes selects a node coincident with other nodes +(within a given Tolerance). +See also \ref tui_double_nodes_control "Double Nodes quality control". +
            • +
            + +The following criteria allow selecting mesh Edges:
            • Free Borders selects free 1D mesh elements, i.e. edges belonging to one face only. See also a \ref free_borders_page "Free Borders quality control".
            • +Double edges selects 1D mesh elements basing on the same set of nodes. +See also \ref filter_double_elements "Double Elements quality control". +
            • Borders at Multi-Connections selects edges belonging to several faces. The number of faces should be more, less or equal (within a given Tolerance) to the predefined Threshold Value. See also a @@ -115,7 +137,7 @@ See also a
            -Additional criteria to select mesh Faces are the following: +The following criteria allow selecting mesh Faces:
            • Aspect ratio selects 2D mesh elements with an aspect ratio (see also an \ref aspect_ratio_page "Aspect Ratio quality control"), which is more, less or equal @@ -145,8 +167,17 @@ Additional criteria to select mesh Faces are the following: one element of mesh only. See also a \ref free_edges_page "Free Edges quality control".
            • -Free faces selects 3D mesh elements wich belong less than to -two volumes. +Free faces selects 2D mesh elements wich belong to less than two volumes. +
            • +Double faces selects 2D mesh elements basing on the same set of nodes. +See also \ref filter_double_elements "Double Elements quality control". +
            • +Faces with bare border selects 2D mesh elements having a free border without an edge on it. +See also \ref bare_border_faces_page "Bare border faces quality control". +
            • +Over-constrained faces selects 2D mesh elements having only one border shared +with other 2D elements. +See also \ref over_constrained_faces_page "Over-constrained faces quality control".
            • Borders at Multi-Connections 2D selects cells consisting of edges belonging to several elements of mesh. The number of mesh elements should be more, less or equal @@ -158,10 +189,21 @@ See also a length, which is more, less or equal (within a given Tolerance) to the predefined Threshold Value. See also a \ref length_2d_page "Length 2D quality control". +
            • +Coplanar faces selects mesh faces neighboring the one selected +by ID in Threshold Value field, if the angle between the +normal to the neighboring face and the normal to the selected face is less then the +angular tolerance (defined in degrees). Selection continues among all neighbor faces of already +selected ones.
              +
            • +Element Diameter 2D selects triangles and quadrangles composed of the edges and +diagonals with a value of length, which is more, less or equal +(within a given Tolerance) to the predefined Threshold Value. See also a +\ref max_element_length_2d_page "Element Diameter 2D quality control".
            -Additional criteria to select mesh Volumes are the following: +The following criteria allow selecting mesh Volumes:
            • Aspect ratio 3D selects 3D mesh elements with an aspect ratio (see also an \ref aspect_ratio_3d_page "Aspect Ratio 3D quality control"), which is more, less or equal @@ -171,8 +213,23 @@ Additional criteria to select mesh Volumes are the following: \ref volume_page "Volume quality control"), which is more, less or equal (within a given Tolerance) to the predefined Threshold Value.
            • +Element Diameter 3D selects 3D mesh elements composed of the edges and +diagonals with a value of length, which is more, less or equal +(within a given Tolerance) to the predefined Threshold Value. See also a +\ref max_element_length_3d_page "Element Diameter 3D quality control". +
            • +Double volumes selects 3D mesh elements basing on the same set of nodes. +See also \ref filter_double_elements "Double Elements quality control". +
            • Bad oriented volume selects mesh volumes, which are incorrectly oriented from the point of view of MED convention. +
            • +Over-constrained volumes selects mesh volumes having only one border shared +with other volumes. +See also \ref over_constrained_volumes_page "Over-constrained volumes quality control". +
            • +Volumes with bare border selects 3D mesh elements having a free border without a face on it. +See also \ref bare_border_volumes_page "Bare border volumes quality control".
            diff --git a/doc/salome/gui/SMESH/input/skew.doc b/doc/salome/gui/SMESH/input/skew.doc index 5235b4ddd..036c70d83 100644 --- a/doc/salome/gui/SMESH/input/skew.doc +++ b/doc/salome/gui/SMESH/input/skew.doc @@ -14,7 +14,8 @@ criterion can be applied to elements composed of 4 and 3 nodes
            1. Display your mesh in the viewer.
            2. -
            3. Choose Controls > Skew or click "Skew" button of the toolbar. +
            4. Choose Controls > Face Controls > Skew or click +"Skew" button of the toolbar. \image html image40.png
              "Skew" button
              diff --git a/doc/salome/gui/SMESH/input/smeshpy_interface.doc b/doc/salome/gui/SMESH/input/smeshpy_interface.doc index 17255212c..e725ef99c 100644 --- a/doc/salome/gui/SMESH/input/smeshpy_interface.doc +++ b/doc/salome/gui/SMESH/input/smeshpy_interface.doc @@ -2,128 +2,137 @@ \page smeshpy_interface_page Python interface -\n Python package smesh defines several classes, destined for easy and +Python package smesh defines several classes, destined for easy and clear mesh creation and edition. -\n Documentation for smesh package is available in two forms: - -\n The structured - documentation for smesh package, where all methods and - classes are grouped by their functionality, like it is done in the GUI documentation -\n and the \ref smeshDC "linear documentation for smesh package" - grouped only by classes, declared in the smesh.py file. - -\n The main page of the \ref smeshDC "linear documentation for smesh package" - contains a list of data structures and a list of - functions, provided by the package smesh.py. The first item in - the list of data structures (\ref smeshDC::smeshDC "class smesh") - also represents documentation for the methods of the package smesh.py itself. - -\n The package smesh.py provides an interface to create and handle - meshes. Use it to create an empty mesh or to import it from the data file. - -\n Once a mesh has been created, it is possible to manage it via its own - methods, described at \ref smeshDC::Mesh "class Mesh" documentation - (it is also accessible by the second item "class Mesh" in the list of data structures). - -\n Class Mesh allows assigning algorithms to a mesh. -\n Please note, that some algorithms, - included in the standard Salome installation are always available: - - REGULAR(1D), COMPOSITE(1D), MEFISTO(2D), Quadrangle(2D), Hexa(3D), etc. - -\n There are also some algorithms, which can be installed optionally, -\n some of them are based on open-source meshers: - - NETGEN(1D-2D,2D,1D-2D-3D,3D), - -\n others are based on commercial meshers: - - GHS3D(3D), BLSURF(2D). - -\n To add hypotheses, use the interfaces, provided by the assigned +Documentation for smesh package is available in two forms: + +The structured +documentation for smesh package, where all methods and +classes are grouped by their functionality, like it is done in the GUI documentation +and the \ref smeshDC "linear documentation for smesh package" +grouped only by classes, declared in the smesh.py file. + +The main page of the \ref smeshDC "linear documentation for smesh package" +contains a list of data structures and a list of +functions, provided by the package smesh.py. The first item in +the list of data structures (\ref smeshDC::smeshDC "class smesh") +also represents documentation for the methods of the package smesh.py itself. + +The package smesh.py provides an interface to create and handle +meshes. Use it to create an empty mesh or to import it from the data file. + +Once a mesh has been created, it is possible to manage it via its own +methods, described at \ref smeshDC::Mesh "class Mesh" documentation +(it is also accessible by the second item "class Mesh" in the list of data structures). + +Class \b Mesh allows assigning algorithms to a mesh. +Please note, that some algorithms, included in the standard SALOME +distribution are always available: +- REGULAR (1D) +- COMPOSITE (1D) +- MEFISTO (2D) +- Quadrangle (2D) +- Hexa(3D) +- etc... + +To add hypotheses, use the interfaces, provided by the assigned algorithms. -\n Below you can see an example of usage of the package smesh for 3d mesh generation. +Below you can see an example of usage of the package smesh for 3d mesh generation. -

              Example of 3d mesh generation with NETGEN:

              +\anchor example_3d_mesh +

              Example of 3d mesh generation:

              -\n from geompy import * -\n import smesh +\code +from geompy import * +import smesh -# Geometry -\n # an assembly of a box, a cylinder and a truncated cone meshed with tetrahedral. +### +# Geometry: an assembly of a box, a cylinder and a truncated cone +# meshed with tetrahedral +### -# Define values -\n name = "ex21_lamp" -\n cote = 60 -\n section = 20 -\n size = 200 -\n radius_1 = 80 -\n radius_2 = 40 -\n height = 100 +# Define values +name = "ex21_lamp" +cote = 60 +section = 20 +size = 200 +radius_1 = 80 +radius_2 = 40 +height = 100 -# Build a box -\n box = MakeBox(-cote, -cote, -cote, +cote, +cote, +cote) +# Build a box +box = MakeBox(-cote, -cote, -cote, +cote, +cote, +cote) -# Build a cylinder -\n pt1 = MakeVertex(0, 0, cote/3) -\n di1 = MakeVectorDXDYDZ(0, 0, 1) -\n cyl = MakeCylinder(pt1, di1, section, size) +# Build a cylinder +pt1 = MakeVertex(0, 0, cote/3) +di1 = MakeVectorDXDYDZ(0, 0, 1) +cyl = MakeCylinder(pt1, di1, section, size) -# Build a truncated cone -\n pt2 = MakeVertex(0, 0, size) -\n cone = MakeCone(pt2, di1, radius_1, radius_2, height) +# Build a truncated cone +pt2 = MakeVertex(0, 0, size) +cone = MakeCone(pt2, di1, radius_1, radius_2, height) -# Fuse -\n box_cyl = MakeFuse(box, cyl) -\n piece = MakeFuse(box_cyl, cone) +# Fuse +box_cyl = MakeFuse(box, cyl) +piece = MakeFuse(box_cyl, cone) -# Add in study -\n addToStudy(piece, name) +# Add to the study +addToStudy(piece, name) -# Create a group of faces -\n group = CreateGroup(piece, ShapeType["FACE"]) -\n group_name = name + "_grp" -\n addToStudy(group, group_name) -\n group.SetName(group_name) +# Create a group of faces +group = CreateGroup(piece, ShapeType["FACE"]) +group_name = name + "_grp" +addToStudy(group, group_name) +group.SetName(group_name) -# Add faces in the group -\n faces = SubShapeAllIDs(piece, ShapeType["FACE"]) -\n UnionIDs(group, faces) +# Add faces to the group +faces = SubShapeAllIDs(piece, ShapeType["FACE"]) +UnionIDs(group, faces) -# Create a mesh +### +# Create a mesh +### -# Define a mesh on a geometry -\n tetra = smesh.Mesh(piece, name) +# Define a mesh on a geometry +tetra = smesh.Mesh(piece, name) -# Define 1D hypothesis -\n algo1d = tetra.Segment() -\n algo1d.LocalLength(10) +# Define 1D hypothesis +algo1d = tetra.Segment() +algo1d.LocalLength(10) -# Define 2D hypothesis -\n algo2d = tetra.Triangle() -\n algo2d.LengthFromEdges() +# Define 2D hypothesis +algo2d = tetra.Triangle() +algo2d.LengthFromEdges() -# Define 3D hypothesis -\n algo3d = tetra.Tetrahedron(smesh.NETGEN) -\n algo3d.MaxElementVolume(100) +# Define 3D hypothesis +algo3d = tetra.Tetrahedron() +algo3d.MaxElementVolume(100) -# Compute the mesh -\n tetra.Compute() +# Compute the mesh +tetra.Compute() -# Create a groupe of faces -\n tetra.Group(group) +# Create a groupe of faces +tetra.Group(group) -\n Examples of Python scripts for all Mesh operations are available by -the following links: +\endcode -
                -
              • \subpage tui_creating_meshes_page
              • -
              • \subpage tui_viewing_meshes_page
              • -
              • \subpage tui_defining_hypotheses_page
              • -
              • \subpage tui_quality_controls_page
              • -
              • \subpage tui_grouping_elements_page
              • -
              • \subpage tui_modifying_meshes_page
              • -
              • \subpage tui_transforming_meshes_page
              • -
              +Examples of Python scripts for all Mesh operations are available by +the following links: +- \subpage tui_creating_meshes_page +- \subpage tui_cartesian_algo +- \subpage tui_viewing_meshes_page +- \subpage tui_defining_hypotheses_page +- \subpage tui_quality_controls_page +- \subpage tui_filters_page +- \subpage tui_grouping_elements_page +- \subpage tui_modifying_meshes_page +- \subpage tui_transforming_meshes_page +- \subpage tui_notebook_smesh_page +- \subpage tui_measurements_page +- \subpage tui_generate_flat_elements_page +- \subpage tui_work_on_objects_from_gui */ diff --git a/doc/salome/gui/SMESH/input/smoothing.doc b/doc/salome/gui/SMESH/input/smoothing.doc index 77a59f880..dc15270a8 100644 --- a/doc/salome/gui/SMESH/input/smoothing.doc +++ b/doc/salome/gui/SMESH/input/smoothing.doc @@ -7,38 +7,40 @@ To apply smoothing to the elements of your mesh:
                -
              1. Display a mesh or a submesh in the 3D viewer.
              2. +
              3. In the \b Modification menu select the \b Smoothing item or click "Smoothing" button in the toolbar. \image html image84.png
                "Smoothing" button
                -The dialog box contains the following fields which should be -specified: +The following dialog will appear: \image html smoothing.png +
              4. +
              5. In this dialog:
                  -
                • Id Elements field allows to specify the elements which -should be smoothed +
                • specify the IDs of the elements which will be smoothed:
                    -
                  • Check on Select the whole mesh, submesh or group option -
                  • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
                  • -
                  • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
                  • +
                  • Select the whole mesh, submesh or group activating this +checkbox; or
                  • +
                  • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                  • +
                  • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
                  • +
                  • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                • -Fixed nodes ids: some nodes keep their location during -smoothing. If a mesh is built on a geometry shape, the nodes built on -geometrical edges are always fixed. If smoothing is applied to a part -of a mesh then the boundary nodes of an elements set are also -fixed. Any other nodes may be additionally fixed. Fixed nodes can be -selected manually or by filters too. -
                • Smoothing Method: + +
                • define the Fixed nodes ids that should remain at their location during +smoothing. If a mesh is built on a shape, the nodes built on its +geometric edges are always fixed. If the smoothing is applied to a part +of the mesh, the nodes of boundary elements are also +fixed. It is possible to additionally fix any other nodes. The fixed nodes can be +selected manually or by filters, just as the smoothed elements.
                • +
                • choose the Smoothing Method:
                  • \b Laplacian smoothing pulls a node toward the center of surrounding nodes directly connected to that node along an element @@ -47,32 +49,29 @@ edge. element-area-weighted centroid of the surrounding elements.
                  • Typically, the Laplacian method will produce the mesh with the least element -distortion. It is also the faster method.Centroidal smoothing usually -produces a mesh that has more uniform element sizes. Both methods +distortion. It is also the fastest method. Centroidal smoothing usually +produces a mesh with more uniform element sizes. Both methods produce good results with "free" meshes.
                  \image html image83.gif
                • -
                • Iteration limit: both of the smoothing methods use an -iterative procedure to converge toward a smoothed mesh. All nodes are -smoothed according to one of the techniques shown above. Then the -smoothing is reevaluated with the updated nodal locations. This -process continues until the maximum number of iterations has been -exceeded, or all elements has aspect ratio less or equal than the +
                • specify the Iteration limit. Both smoothing methods +iterate through a number of steps to produce the resulting smoothed +mesh. At each new step the smoothing is reevaluated with the updated nodal locations. This +process continues till the limit of iterations has been +exceeded, or till the aspect ratio of all element is less than or equal to the specified one.
                • -
                • Max. aspect ratio allows to define the quality at which the -smoothing algorithm should stop the iterations as the target of the -operation has been reached.
                • -
                • When in parametric space radio button is checked, the -algorithm tries to improve the shape of faces in the parametric space +
                • specify the Max. aspect ratio - the target mesh quality at which the +smoothing algorithm should stop the iterations.
                • +
                • activate in parametric space checkbox if it is necessary to +to improve the shape of faces in the parametric space of geometrical surfaces on which they are generated, else the shape of faces in the 3D space is improved.
                -
              6. -
              7. Click the \b Apply or \b OK button to confirm the operation.
              8. +
              9. Click \b Apply or Apply and Close button to confirm the operation.
              \image html smoothing1.png "The initial mesh" diff --git a/doc/salome/gui/SMESH/input/split_to_tetra.doc b/doc/salome/gui/SMESH/input/split_to_tetra.doc new file mode 100644 index 000000000..325c30c11 --- /dev/null +++ b/doc/salome/gui/SMESH/input/split_to_tetra.doc @@ -0,0 +1,55 @@ +/*! + +\page split_to_tetra_page Splitting volumes into tetrahedra + +\n This operation allows to split volumic elements into tetrahedra. +2D mesh is modified accordingly. + +To split volumes: +
                +
              1. Display a mesh or a submesh in the 3D viewer.
              2. +
              3. In the \b Modification menu select the Split into Tetrahedra item or +click "Split into Tetrahedra" button in the toolbar. + +\image html split_into_tetra_icon.png +
                "Split into Tetrahedra" button
                + +The following dialog box will appear: + +\image html split_into_tetra.png + +\par +
                  +
                • The main list contains the list of volumes. You can click on +a volume in the 3D viewer and it will be highlighted (lock Shift +keyboard button to select several volumes). Click \b Add button and +the ID of this volume will be added to the list. To remove the +selected element or elements from the list click \b Remove button. Sort +list button allows to sort the list of IDs. \b Filter button allows to +apply a definite filter to the selection of volumes. +
                  Note: If you split not all adjacent non-tetrahedral volumes, your mesh becomes +non-conform.
                • +
                • Apply to all radio button allows to split all +volumes of the currently displayed mesh or submesh.
                • +
                + +
                  +
                • \b Split hexahedron + +
                    +
                  • Into 5 tetrahedra, Into 6 tetrahedra and Into 24 tetrahedra allows to +specify the number of tetrahedra a hexahedron will be split into. If the specified method does +not allow to get a conform mesh, a generic solution is applied: an additional node +is created at the gravity center of a hexahedron, serving an apex of tetrahedra, all quadrangle sides of the hexahedron are split into two triangles each serving a base of a new tetrahedron.
                  • +
                  + +
                • + +
                • Select from a set of fields allows to choose a submesh or an +existing group whose elements will be automatically added to the +list.
                • +
                + +
              4. Click the \b Apply or Apply and Close button to confirm the operation.
              5. +
              +*/ diff --git a/doc/salome/gui/SMESH/input/symmetry.doc b/doc/salome/gui/SMESH/input/symmetry.doc index 67068e981..924e4eeb0 100644 --- a/doc/salome/gui/SMESH/input/symmetry.doc +++ b/doc/salome/gui/SMESH/input/symmetry.doc @@ -5,48 +5,81 @@ \n This geometrical operation allows to perform a symmetrical copy of your mesh or some of its elements. +To create a symmetrical copy of the mesh: + +
                +
              1. From the \b Modification menu choose \b Transformation -> \b Symmetry item or click +"Symmetry" button in the toolbar. + \image html symmetry.png "Symmetry button" -To apply symmetry to your mesh: -\par -From the \b Modification choose \b Transformation and from its -sub-menu select the \b Symmetry item. The following dialog box shall -appear: +One of the following dialogs will appear: -\image html symmetry1.png +It is possible to mirror a mesh or some of its elements through: +\image html symmetry1.png "a point (defined by a point and a vector)" +\image html symmetry2.png "an axis" +\image html symmetry3.png "a plane (defined by a point and a normal to the plane)" -\image html symmetry2.png +
              2. -\image html symmetry3.png +
              3. In the dialog: +
                  +
                • specify the IDs of the elements for the symmetry operation: + +
                    +
                  • Select the whole mesh, submesh or group activating this +checkbox; or
                  • +
                  • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                  • +
                  • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
                  • +
                  • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                  • +
                  +
                • -\par -This operation has three options, you can symmetrically copy your mesh -or some of its elements specifying: +
                • depending on the nature of the mirror object: +
                    +
                  • if the mesh is mirrored through a point, specify the coordinates +of the point
                  • +
                  • if the mesh is mirrored through an axis:
                      -
                    • one point
                    • -
                    • one axis (point and vector)
                    • -
                    • one plane (point and normal)
                    • +
                    • specify the cooordinates of the start \b Point of the axis vector;
                    • +
                    • specify the axis \b Vector through the coordinates of its +end point with respect to the coordinates of the start point;
                    +
                  • +
                  • if the mesh is mirrored through a plane:
                      -
                    • Select elements for the symmetry operation +
                    • specify the cooordinates of the \b Point lying on the plane;
                    • +
                    • specify the axis \b Vector through the coordinates of its +end point with respect to the coordinates of the start point.
                    • +
                    +
                  • + +
                  • specify the conditions of symmetry operation:
                      -
                    • Check on Select the whole mesh, submesh or group option -
                    • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
                    • -
                    • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
                    • +
                    • activate Move elements radio button to create the source +mesh (or elements) at the new location and erase it from the previous location;
                    • +
                    • activate Copy elements radio button to create the source +mesh (or elements) at the new location, but leave it at the previous +location, the source mesh will be considered one and single mesh with the result of the rotation;
                    • +
                    • activate Create as new mesh radio button to leave the +source mesh (or elements) at its previous location and create a new +mesh at the new location, the new mesh appears in the Object Browser +with the default name MeshName_rotated (it is possible to change this +name in the adjacent box);
                    • +
                    • activate Copy groups checkbox to copy the groups of elements of the source mesh to the newly created mesh.
                  • -
                  • When Move elements radio button is selected, the source mesh (or elements) is created at the new location and erased from its previous location
                  • -
                  • When Copy elements radio button is selected,the source mesh (or elements) is created at the new location, but it also remains at its previous location and is considered one and single mesh with the result of the translation.
                  • -
                  • When Create as new mesh radio button is selected, the source mesh (or elements) remains at its previous location and a new mesh is created at the new location and appears in the Object Browser with the default name MeshName_mirrored (you can change this name in the adjacent box).
                  • -
                  • Copy groups checkbox allows copying the groups of elements of the source mesh to the newly created one.
                  • +
                  +
                • activate Preview checkbox to show the result of transformation in the viewer
                • +
                • click \b Apply or Apply and Close button to confirm the +operation.
                -\par +

              See Also a sample TUI Script of a \ref tui_symmetry "Symmetry" operation. diff --git a/doc/salome/gui/SMESH/input/taper.doc b/doc/salome/gui/SMESH/input/taper.doc index d2c4dd2b4..86472eabe 100644 --- a/doc/salome/gui/SMESH/input/taper.doc +++ b/doc/salome/gui/SMESH/input/taper.doc @@ -13,8 +13,8 @@ for elements consisting of 4 nodes.
              1. Display your mesh in the viewer.
              2. -
              3. Choose Controls > Taper or click "Taper" button in -the toolbar. +
              4. Choose Controls > Face Controls > Taper or click +"Taper" button in the toolbar. \image html image36.png
                "Taper" button
                diff --git a/doc/salome/gui/SMESH/input/translation.doc b/doc/salome/gui/SMESH/input/translation.doc index 45565acaa..56c1dfb05 100644 --- a/doc/salome/gui/SMESH/input/translation.doc +++ b/doc/salome/gui/SMESH/input/translation.doc @@ -5,45 +5,70 @@ \n This geometrical operation allows to translate in space your mesh or some of its elements. +To translate a mesh: + +
                  +
                1. From the \b Modification menu choose \b Transformation -> \b Translation item or click +"Translation" button in the toolbar. + \image html translation.png "Translation button" -To translate your mesh: -\par -From the \b Modification choose \b Transformation and from its -sub-menu select the \b Translation item. The following dialog box -shall appear: +One of the following dialogs will appear: + +It is possible to define the vector of thanslation: +\image html translation1.png "by two points" -\image html translation1.png +\image html translation2.png "by the vector from the origin of coordinates" -\image html translation2.png +
                2. + +
                3. +In the dialog: +
                    +
                  • specify the IDs of the translated elements: -\par -This operation has two options, you can translate in space your mesh -or some of its elements specifying:
                      -
                    • two points (starting and ending)
                    • -
                    • one vector
                    • +
                    • Select the whole mesh, submesh or group activating this +checkbox; or
                    • +
                    • choose mesh elements with the mouse in the 3D Viewer. It is +possible to select a whole area with a mouse frame; or
                    • +
                    • input the element IDs directly in ID Elements field. The selected elements will be highlighted in the +viewer; or
                    • +
                    • apply Filters. Set filter button allows to apply a filter to the selection of elements. See more +about filters in the \ref selection_filter_library_page "Selection filter library" page.
                    +
                  • +
                  • specify the vector of translation:
                      -
                    • Select elements for the translation operation +
                    • specify the cooordinates of the start and end \b Points of the +vector of translation; or
                    • +
                    • specify the end point of the \b Vector of rotation starting at the +origin of coordinates.
                    • +
                    +
                  • + +
                  • specify the conditions of translation:
                      -
                    • Check on Select the whole mesh, submesh or group option -
                    • Choosing them manually with the mouse in the 3D Viewer. You can -click on an element in the 3D viewer and it will be highlighted
                    • -
                    • Applying Filters. The Set filter button allows to apply a -definite filter to selection of the elements. See more -about filters on the -\ref selection_filter_library_page "Selection filter library" page.
                    • +
                    • activate Move elements radio button to create the source +mesh (or elements) at the new location and erase it from the previous location;
                    • +
                    • activate Copy elements radio button to create the source +mesh (or elements) at the new location, but leave it at the previous +location, the source mesh will be considered one and single mesh with the result of the rotation;
                    • +
                    • activate Create as new mesh radio button to leave the +source mesh (or elements) at its previous location and create a new +mesh at the new location, the new mesh appears in the Object Browser +with the default name MeshName_rotated (it is possible to change this +name in the adjacent box);
                    • +
                    • activate Copy groups checkbox to copy the groups of elements of the source mesh to the newly created mesh.
                  • -
                  • When Move elements radio button is selected, the source mesh (or elements) is created at the new location and erased from its previous location
                  • -
                  • When Copy elements radio button is selected,the source mesh (or elements) is created at the new location, but it also remains at its previous location and is considered one and single mesh with the result of the translation.
                  • -
                  • When Create as new mesh radio button is selected, the source mesh (or elements) remains at its previous location and a new mesh is created at the new location and appears in the Object Browser with the default name MeshName_translated (you can change this name in the adjacent box).
                  • -
                  • Copy groups checkbox allows copying the groups of elements of the source mesh to the newly created one.
                  • + +
                  • activate Preview checkbox to show the result of transformation in the viewer
                  • +
                  • click \b Apply or Apply and Close button to confirm the operation.
                  +
                -
                See Also a sample TUI Script of a -\ref tui_translation "Translation" operation. +
                See Also a sample TUI Script of a \ref tui_translation "Translation" operation. */ diff --git a/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc b/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc new file mode 100644 index 000000000..f1218439b --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc @@ -0,0 +1,49 @@ +/*! + +\page tui_cartesian_algo Usage of Body Fitting algorithm + +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +# create a sphere +sphere = geompy.MakeSphereR( 50 ) +geompy.addToStudy( sphere, "sphere" ) + +# create a mesh and assign a "Body Fitting" algo +mesh = Mesh( sphere ) +cartAlgo = mesh.BodyFitted() + +# define a cartesian grid using Coordinates +coords = range(-100,100,10) +cartHyp = cartAlgo.SetGrid( coords,coords,coords, 1000000) + +# compute the mesh +mesh.Compute() +print "nb hexahedra",mesh.NbHexas() +print "nb tetrahedra",mesh.NbTetras() +print "nb polyhedra",mesh.NbPolyhedrons() +print + +# define the grid by sitting constant spacing +cartHyp = cartAlgo.SetGrid( "10","10","10", 1000000) + +mesh.Compute() +print "nb hexahedra",mesh.NbHexas() +print "nb tetrahedra",mesh.NbTetras() +print "nb polyhedra",mesh.NbPolyhedrons() + + +# define the grid by sitting different spacing in 2 sub-ranges of geometry +spaceFuns = ["5","10+10*t"] +cartAlgo.SetGrid( [spaceFuns, [0.5]], [spaceFuns, [0.5]], [spaceFuns, [0.25]], 2 ) + +mesh.Compute() +print "nb hexahedra",mesh.NbHexas() +print "nb tetrahedra",mesh.NbTetras() +print "nb polyhedra",mesh.NbPolyhedrons() +print + +\endcode + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_creating_meshes.doc b/doc/salome/gui/SMESH/input/tui_creating_meshes.doc index 9048afef1..24161d483 100644 --- a/doc/salome/gui/SMESH/input/tui_creating_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_creating_meshes.doc @@ -2,7 +2,7 @@ \page tui_creating_meshes_page Creating Meshes -\n First of all see \ref introduction_to_mesh_python_page "Example of 3d mesh generation", +\n First of all see \ref example_3d_mesh "Example of 3d mesh generation", which is an example of good python script style for Mesh module.
                @@ -25,7 +25,7 @@ algo1D.NumberOfSegments(7) algo2D = tetra.Triangle() algo2D.MaxElementArea(800.) -algo3D = tetra.Tetrahedron(smesh.NETGEN) +algo3D = tetra.Tetrahedron() algo3D.MaxElementVolume(900.) # compute the mesh @@ -82,6 +82,68 @@ quadra.Compute() \endcode +
                +

                Change priority of submeshes in Mesh

                + +\code +import salome +import geompy +import smesh +import SMESH + +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +[Face_1,Face_2,Face_3,Face_4,Face_5,Face_6] = geompy.SubShapeAllSorted(Box_1, geompy.ShapeType["FACE"]) + +# create Mesh object on Box shape +Mesh_1 = smesh.Mesh(Box_1) + +# assign mesh algorithms +Regular_1D = Mesh_1.Segment() +Nb_Segments_1 = Regular_1D.NumberOfSegments(20) +Nb_Segments_1.SetDistrType( 0 ) +MEFISTO_2D = Mesh_1.Triangle() +Max_Element_Area_1 = MEFISTO_2D.MaxElementArea(1200) +Tetrahedron = Mesh_1.Tetrahedron() +Max_Element_Volume_1 = Tetrahedron.MaxElementVolume(40000) + +# create submesh and assign algorithms on Face_1 +Regular_1D_1 = Mesh_1.Segment(geom=Face_1) +Nb_Segments_2 = Regular_1D_1.NumberOfSegments(4) +Nb_Segments_2.SetDistrType( 0 ) +MEFISTO_2D_1 = Mesh_1.Triangle(algo=smesh.MEFISTO,geom=Face_1) +Length_From_Edges_2D = MEFISTO_2D_1.LengthFromEdges() +SubMesh_1 = MEFISTO_2D_1.GetSubMesh() + +# create submesh and assign algorithms on Face_2 +Regular_1D_2 = Mesh_1.Segment(geom=Face_2) +Nb_Segments_3 = Regular_1D_2.NumberOfSegments(8) +Nb_Segments_3.SetDistrType( 0 ) +MEFISTO_2D_2 = Mesh_1.Triangle(algo=smesh.MEFISTO,geom=Face_2) +Length_From_Edges_2D_1 = MEFISTO_2D_2.LengthFromEdges() +SubMesh_2 = MEFISTO_2D_2.GetSubMesh() + +# create submesh and assign algorithms on Face_3 +Regular_1D_3 = Mesh_1.Segment(geom=Face_3) +Nb_Segments_4 = Regular_1D_3.NumberOfSegments(12) +Nb_Segments_4.SetDistrType( 0 ) +MEFISTO_2D_3 = Mesh_1.Triangle(algo=smesh.MEFISTO,geom=Face_3) +Length_From_Edges_2D_2 = MEFISTO_2D_3.LengthFromEdges() +SubMesh_3 = MEFISTO_2D_3.GetSubMesh() + +# check exisiting submesh priority order +[ [ SubMesh_1, SubMesh_3, SubMesh_2 ] ] = Mesh_1.GetMeshOrder() +# set new submesh order +isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_1, SubMesh_2, SubMesh_3 ] ]) +# compute mesh +isDone = Mesh_1.Compute() + +# clear mesh result and compute with other submesh order +Mesh_1.Clear() +isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_2, SubMesh_1, SubMesh_3 ] ]) +isDone = Mesh_1.Compute() + +\endcode +
                \anchor tui_editing_mesh

                Editing of a mesh

                @@ -162,7 +224,7 @@ algo1D.NumberOfSegments(7) algo2D = tetra.Triangle() algo2D.MaxElementArea(800.) -algo3D = tetra.Tetrahedron(smesh.NETGEN) +algo3D = tetra.Tetrahedron() algo3D.MaxElementVolume(900.) # compute the mesh @@ -170,6 +232,11 @@ tetra.Compute() # export the mesh in a MED file tetra.ExportMED("/tmp/meshMED.med", 0) + +# export a group in a MED file +face = geompy.SubShapeAll( box, geompy.ShapeType["FACE"])[0] # a box side +group = tetra.GroupOnGeom( face, "face group" ) # group of 2D elements on the +tetra.ExportMED("/tmp/groupMED.med", meshPart=group) \endcode
                @@ -188,4 +255,48 @@ demonstrating the resulting mesh. \skipline import geompy \until #end +
                +\anchor tui_copy_mesh +

                Mesh Copying

                +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +# make geometry of a box +box = geompy.MakeBoxDXDYDZ(100,100,100) +face = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])[0] + +# generate 3D mesh +mesh = Mesh(box) +localAlgo = mesh.Triangle(face) +mesh.AutomaticHexahedralization() + +# objects to copy +fGroup = mesh.GroupOnGeom( face, "2D on face") +nGroup = mesh.GroupOnGeom( face, "nodes on face", NODE) +subMesh = localAlgo.GetSubMesh() + +# make a new mesh by copying different parts of the mesh + +# 1. copy the whole mesh +newMesh = CopyMesh( mesh, "whole mesh copy") + +# 2. copy a group of 2D elements along with groups +newMesh = CopyMesh( fGroup, "face group copy with groups",toCopyGroups=True) + +# 3. copy a group of nodes with preseving their ids +newMesh = CopyMesh( nGroup, "node group copy", toKeepIDs=True) + +# 4. copy some faces +faceIds = fGroup.GetIDs()[-10:] +newMesh = CopyMesh( mesh.GetIDSource( faceIds, FACE ), "some faces copy") + +# 5. copy some nodes +nodeIds = nGroup.GetIDs()[-10:] +newMesh = CopyMesh( mesh.GetIDSource( nodeIds, NODE), "some nodes copy") + +# 6. copy a sub-mesh +newMesh = CopyMesh( subMesh, "submesh copy" ) +\endcode + */ diff --git a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc index bd9fbbb10..e98eca6b4 100644 --- a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc +++ b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc @@ -22,8 +22,12 @@ hexa = smesh.Mesh(box, "Box : hexahedrical mesh") # create a Regular 1D algorithm for edges algo1D = hexa.Segment() +# optionally reverse node distribution on certain edges +allEdges = geompy.SubShapeAllSortedIDs( box, geompy.ShapeType["EDGE"]) +reversedEdges = [ allEdges[0], allEdges[4] ] + # define "Arithmetic1D" hypothesis to cut all edges in several segments with increasing arithmetic length -algo1D.Arithmetic1D(1, 4) +algo1D.Arithmetic1D(1, 4, reversedEdges) # create a quadrangle 2D algorithm for faces hexa.Quadrangle() @@ -124,7 +128,7 @@ hexa.Compute()
                \anchor tui_average_length -

                Average Length

                +

                Local Length

                \code from geompy import * @@ -227,7 +231,7 @@ tetra = smesh.Mesh(cyl, "Cylinder : tetrahedrical mesh") # assign algorithms algo1D = tetra.Segment() algo2D = tetra.Triangle() -algo3D = tetra.Tetrahedron(smesh.NETGEN) +algo3D = tetra.Tetrahedron() # assign 1D and 2D hypotheses algo1D.NumberOfSegments(7) @@ -359,8 +363,8 @@ algo1D = tetra.Segment() # create a Mefisto 2D algorithm for faces algo2D = tetra.Triangle() -# create a Netgen 3D algorithm for solids -algo3D = tetra.Tetrahedron(smesh.NETGEN) +# create a 3D algorithm for solids +algo3D = tetra.Tetrahedron() # define hypotheses algo1D.Arithmetic1D(1, 4) @@ -369,17 +373,338 @@ algo2D.LengthFromEdges() # compute the mesh tetra.Compute() -# 3. Create a tetrahedral mesh on the box with NETGEN_2D3D algorithm -tetraN = smesh.Mesh(box, "Box : tetrahedrical mesh by NETGEN_2D3D") +\endcode -# create a Netgen_2D3D algorithm for solids -algo3D = tetraN.Tetrahedron(smesh.FULL_NETGEN) +
                +\anchor tui_projection +

                Projection Algorithms

                -# define hypotheses -n23_params = algo3D.Parameters() +\code +# Project prisms from one meshed box to another mesh on the same box + +from smesh import * + +# Prepare geometry + +# Create a parallelepiped +box = geompy.MakeBoxDXDYDZ(200, 100, 70) +geompy.addToStudy( box, "box" ) + +# Get geom faces to mesh with triangles in the 1ts and 2nd meshes +faces = geompy.SubShapeAll(box, geompy.ShapeType["FACE"]) +# 2 adjacent faces of the box +f1 = faces[2] +f2 = faces[0] +# face opposite to f2 +f2opp = faces[1] + +# Get vertices used to specify how to associate sides of faces at projection +[v1F1, v2F1] = geompy.SubShapeAll(f1, geompy.ShapeType["VERTEX"])[:2] +[v1F2, v2F2] = geompy.SubShapeAll(f2, geompy.ShapeType["VERTEX"])[:2] +geompy.addToStudyInFather( box, v1F1, "v1F1" ) +geompy.addToStudyInFather( box, v2F1, "v2F1" ) +geompy.addToStudyInFather( box, v1F2, "v1F2" ) +geompy.addToStudyInFather( box, v2F2, "v2F2" ) + +# Make group of 3 edges of f1 and f2 +edgesF1 = geompy.CreateGroup(f1, geompy.ShapeType["EDGE"]) +geompy.UnionList( edgesF1, geompy.SubShapeAll(f1, geompy.ShapeType["EDGE"])[:3]) +edgesF2 = geompy.CreateGroup(f2, geompy.ShapeType["EDGE"]) +geompy.UnionList( edgesF2, geompy.SubShapeAll(f2, geompy.ShapeType["EDGE"])[:3]) +geompy.addToStudyInFather( box, edgesF1, "edgesF1" ) +geompy.addToStudyInFather( box, edgesF2, "edgesF2" ) + + +# Make the source mesh with prisms +src_mesh = Mesh(box, "Source mesh") +src_mesh.Segment().NumberOfSegments(9,10) +src_mesh.Quadrangle() +src_mesh.Hexahedron() +src_mesh.Triangle(f1) # triangular sumbesh +src_mesh.Compute() + + +# Mesh the box using projection algoritms + +# Define the same global 1D and 2D hypotheses +tgt_mesh = Mesh(box, "Target mesh") +tgt_mesh.Segment().NumberOfSegments(9,10,UseExisting=True) +tgt_mesh.Quadrangle() + +# Define Projection 1D algorithm to project 1d mesh elements from group edgesF2 to edgesF1 +# It is actually not needed, just a demonstration +proj1D = tgt_mesh.Projection1D( edgesF1 ) +# each vertex must be at the end of a connected group of edges (or a sole edge) +proj1D.SourceEdge( edgesF2, src_mesh, v2F1, v2F2 ) + +# Define 2D hypotheses to project triangles from f1 face of the source mesh to +# f2 face in the target mesh. Vertices specify how to associate sides of faces +proj2D = tgt_mesh.Projection2D( f2 ) +proj2D.SourceFace( f1, src_mesh, v1F1, v1F2, v2F1, v2F2 ) + +# 2D hypotheses to project triangles from f2 of target mesh to the face opposite to f2. +# Association of face sides is default +proj2D = tgt_mesh.Projection2D( f2opp ) +proj2D.SourceFace( f2 ) + +# 3D hypotheses to project prisms from the source to the target mesh +proj3D = tgt_mesh.Projection3D() +proj3D.SourceShape3D( box, src_mesh, v1F1, v1F2, v2F1, v2F2 ) +tgt_mesh.Compute() + +# Move the source mesh to visualy compare the two meshes +src_mesh.TranslateObject( src_mesh, MakeDirStruct( 210, 0, 0 ), Copy=False) + +\endcode + +
                + +\anchor tui_fixed_points + +

                1D Mesh with Fixed Points example

                + +\code +import salome +import geompy +import smesh +import StdMeshers + +# Create face and explode it on edges +face = geompy.MakeFaceHW(100, 100, 1) +edges = geompy.SubShapeAllSorted(face, geompy.ShapeType["EDGE"]) +geompy.addToStudy( face, "Face" ) + +# get the first edge from exploded result +edge1 = geompy.GetSubShapeID(face, edges[0]) + +# Define Mesh on previously created face +Mesh_1 = smesh.Mesh(face) + +# Create Fixed Point 1D hypothesis and define parameters. +# Note: values greater than 1.0 and less than 0.0 are not taken into account; +# duplicated values are removed. Also, if not specified explicitly, values 0.0 and 1.0 +# add added automatically. +# The number of segments should correspond to the number of points (NbSeg = NbPnt-1); +# extra values of segments splitting parameter are not taken into account, +# while missing values are considered to be equal to 1. +Fixed_points_1D_1 = smesh.CreateHypothesis('FixedPoints1D') +Fixed_points_1D_1.SetPoints( [ 1.1, 0.9, 0.5, 0.0, 0.5, -0.3 ] ) +Fixed_points_1D_1.SetNbSegments( [ 3, 1, 2 ] ) +Fixed_points_1D_1.SetReversedEdges( [edge1] ) + +# Add hypothesis to mesh and define 2D parameters +Mesh_1.AddHypothesis(Fixed_points_1D_1) +Regular_1D = Mesh_1.Segment() +Quadrangle_2D = Mesh_1.Quadrangle() +# Compute mesh +Mesh_1.Compute() +\endcode + +\anchor tui_radial_quadrangle +

                Radial Quadrangle 1D2D example

                +\code +from smesh import * + +SetCurrentStudy(salome.myStudy) + +# Create face from the wire and add to study +Face = geompy.MakeSketcher("Sketcher:F 0 0:TT 20 0:R 90:C 20 90:WF", [0, 0, 0, 1, 0, 0, 0, 0, 1]) +geompy.addToStudy(Face,"Face") +edges = geompy.SubShapeAllSorted(Face, geompy.ShapeType["EDGE"]) +circle, radius1, radius2 = edges +geompy.addToStudyInFather(Face, radius1,"radius1") +geompy.addToStudyInFather(Face, radius2,"radius2") +geompy.addToStudyInFather(Face, circle,"circle") + + +# Define geometry for mesh, and Radial Quadrange algorithm +mesh = smesh.Mesh(Face) +radial_Quad_algo = mesh.Quadrangle(algo=RADIAL_QUAD) + +# The Radial Quadrange algorithm can work without any hypothesis +# In this case it uses "Default Nb of Segments" preferences parameter to discretize edges +mesh.Compute() + +# The Radial Quadrange uses global or local 1d hypotheses if it does +# not have its own hypotheses. +# Define global hypotheses to discretize radial edges and a local one for circular edge +global_Nb_Segments = mesh.Segment().NumberOfSegments(5) +local_Nb_Segments = mesh.Segment(circle).NumberOfSegments(10) +mesh.Compute() + +# Define own parameters of Radial Quadrange algorithm +radial_Quad_algo.NumberOfLayers( 4 ) +mesh.Compute() +\endcode + +\anchor tui_quadrangle_parameters +

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

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

                Quadrangle Parameters example 2 (using different types)

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

                "Use Existing Elements" example

                +\code + +from smesh import * +SetCurrentStudy(salome.myStudy) + +# Make a patritioned box + +box = geompy.MakeBoxDXDYDZ(100,100,100) + +N = geompy.MakeVectorDXDYDZ( 1,0,0 ) +O = geompy.MakeVertex( 50,0,0 ) +plane = geompy.MakePlane( O, N, 200 ) # plane YOZ + +shape2boxes = geompy.MakeHalfPartition( box, plane ) +boxes = geompy.SubShapeAllSorted(shape2boxes, geompy.ShapeType["SOLID"]) + +geompy.addToStudy( boxes[0], "boxes[0]") +geompy.addToStudy( boxes[1], "boxes[1]") +midFace0 = geompy.SubShapeAllSorted(boxes[0], geompy.ShapeType["FACE"])[5] +geompy.addToStudyInFather( boxes[0], midFace0, "middle Face") +midFace1 = geompy.SubShapeAllSorted(boxes[1], geompy.ShapeType["FACE"])[0] +geompy.addToStudyInFather( boxes[1], midFace1, "middle Face") + +# Mesh one of boxes with quadrangles. It is a source mesh + +srcMesh = Mesh(boxes[0], "source mesh") # box coloser to CS origin +nSeg1 = srcMesh.Segment().NumberOfSegments(4) +srcMesh.Quadrangle() +srcMesh.Compute() +srcFaceGroup = srcMesh.GroupOnGeom( midFace0, "src faces", FACE ) + +# Import faces from midFace0 to the target mesh + +tgtMesh = Mesh(boxes[1], "target mesh") +importAlgo = tgtMesh.UseExisting2DElements(midFace1) +import2hyp = importAlgo.SourceFaces( [srcFaceGroup] ) +tgtMesh.Segment().NumberOfSegments(3) +tgtMesh.Quadrangle() +tgtMesh.Compute() + +# Import the whole source mesh with groups +import2hyp.SetCopySourceMesh(True,True) +tgtMesh.Compute() +\endcode + +\anchor tui_viscous_layers +

                Viscous layers construction

                + +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +X = geompy.MakeVectorDXDYDZ( 1,0,0 ) +O = geompy.MakeVertex( 100,50,50 ) +plane = geompy.MakePlane( O, X, 200 ) # plane YZ + +box = geompy.MakeBoxDXDYDZ(200,100,100) + +shape = geompy.MakeHalfPartition( box, plane ) + +faces = geompy.SubShapeAllSorted(shape, geompy.ShapeType["FACE"]) +face1 = faces[1] +ignoreFaces = [ faces[0], faces[-1]] + +geompy.addToStudy( shape, "shape" ) +geompy.addToStudyInFather( shape, face1, "face1") + + +mesh = Mesh(shape, "CFD") + +mesh.Segment().NumberOfSegments( 4 ) + +mesh.Triangle() +mesh.Quadrangle(face1) +mesh.Compute() +algo3D = mesh.Tetrahedron() + +thickness = 20 +numberOfLayers = 10 +stretchFactor = 1.5 +layersHyp = algo3D.ViscousLayers(thickness,numberOfLayers,stretchFactor,ignoreFaces) + +mesh.Compute() + +mesh.MakeGroup("Tetras",VOLUME,FT_ElemGeomType,"=",Geom_TETRA) +mesh.MakeGroup("Pyras",VOLUME,FT_ElemGeomType,"=",Geom_PYRAMID) +mesh.MakeGroup("Prims",VOLUME,FT_ElemGeomType,"=",Geom_PENTA) -# compute the mesh -tetraN.Compute() \endcode -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/tui_filters.doc b/doc/salome/gui/SMESH/input/tui_filters.doc new file mode 100755 index 000000000..0eb41dd28 --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_filters.doc @@ -0,0 +1,770 @@ +/*! + +\page tui_filters_page Filters usage + +Filters allow picking only the mesh elements satisfying to a +specific condition or a set of conditions. Filters can be used to create +or edit mesh groups, remove elements from the mesh object, control +mesh quality by different parameters, etc. + +Several filters can be combined together by using logical operators \a +AND and \a OR. In addition, applied filter criterion can be reverted +using logical operator \a NOT. + +Mesh filters use the functionality of mesh quality controls to filter +mesh nodes / elements by a specific characteristic (Area, Length, etc). + +This page provides a short description of the existing mesh filters, +describes required parameters and gives simple examples of usage in +Python scripts. + +\sa \ref tui_quality_controls_page + +\section filter_aspect_ratio Aspect ratio + +Filter 2D mesh elements (faces) according to the aspect ratio value: +- element type should be \a smesh.FACE +- functor type should be \a smesh.FT_AspectRatio +- threshold is floating point value (aspect ratio) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with aspect ratio > 6.5 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_AspectRatio, smesh.FT_MoreThan, 6.5) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with aspect ratio > 6.5:", len(ids) +\endcode + +\sa \ref tui_aspect_ratio + +\section filter_aspect_ratio_3d Aspect ratio 3D + +Filter 3D mesh elements (volumes) according to the aspect ratio value: +- element type is \a smesh.VOLUME +- functor type is \a smesh.FT_AspectRatio3D +- threshold is floating point value (aspect ratio) + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron() +mesh.Compute() +# get volumes with aspect ratio < 2.0 +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_AspectRatio3D, smesh.FT_LessThan, 2.0) +ids = mesh.GetIdsFromFilter(filter) +print "Number of volumes with aspect ratio < 2.0:", len(ids) +\endcode + +\sa \ref tui_aspect_ratio_3d + +\section filter_warping_angle Warping angle + +Filter 2D mesh elements (faces) according to the warping angle value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Warping +- threshold is floating point value (warping angle) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with warping angle = 2.0e-13 with tolerance 5.0e-14 +criterion = smesh.GetCriterion(smesh.FACE, smesh.FT_Warping, smesh.FT_EqualTo, 2.0e-13) +criterion.Tolerance = 5.0e-14 +filter = smesh.CreateFilterManager().CreateFilter() +filter.SetCriteria([criterion]) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with warping angle = 2.0e-13 (tolerance 5.0e-14):", len(ids) +\endcode + +\sa \ref tui_warping + +\section filter_minimum_angle Minimum angle + +Filter 2D mesh elements (faces) according to the minimum angle value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_MinimumAngle +- threshold is floating point value (minimum angle) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with minimum angle > 75 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_MinimumAngle,">", 75) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with minimum angle > 75:", len(ids) +\endcode + +\sa \ref tui_minimum_angle + +\section filter_taper Taper + +Filter 2D mesh elements (faces) according to the taper value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Taper +- threshold is floating point value (taper) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with taper < 1.e-15 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_Taper, smesh.FT_LessThan, 1.e-15) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with taper < 1.e-15:", len(ids) +\endcode + +\sa \ref tui_taper + +\section filter_skew Skew + +Filter 2D mesh elements (faces) according to the skew value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Skew +- threshold is floating point value (skew) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with skew > 50 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_Skew, smesh.FT_MoreThan, 50) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with skew > 50:", len(ids) +\endcode + +\sa \ref tui_skew + +\section filter_area Area + +Filter 2D mesh elements (faces) according to the area value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Area +- threshold is floating point value (area) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with area > 60 and < 90 +criterion1 = smesh.GetCriterion(smesh.FACE, smesh.FT_Area, smesh.FT_MoreThan, 60,\ + smesh.FT_Undefined, smesh.FT_LogicalAND) +criterion2 = smesh.GetCriterion(smesh.FACE, smesh.FT_Area, smesh.FT_LessThan, 90) +filter = smesh.CreateFilterManager().CreateFilter() +filter.SetCriteria([criterion1,criterion2]) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with area in range (60,90):", len(ids) +\endcode + +\sa \ref tui_area + +\section filter_volume Volume + +Filter 3D mesh elements (volumes) according to the volume value: +- element type is \a smesh.VOLUME +- functor type is \a smesh.FT_Volume3D +- threshold is floating point value (volume) + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron() +mesh.Compute() +# get volumes faces with volume > 100 +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_Volume3D, smesh.FT_MoreThan, 100) +ids = mesh.GetIdsFromFilter(filter) +print "Number of volumes with volume > 100:", len(ids) +\endcode + +\sa \ref tui_volume + +\section filter_free_borders Free borders + +Filter 1D mesh elements (edges) which represent free borders of a mesh: +- element type is \a smesh.EDGE +- functor type is \a smesh.FT_FreeBorders +- threshold value is not required + +\code +# create mesh +import geompy, smesh, StdMeshers +face = geompy.MakeFaceHW(100, 100, 1) +geompy.addToStudy( face, "quadrangle" ) +mesh = smesh.Mesh(face) +mesh.Segment().NumberOfSegments(10) +mesh.Triangle().MaxElementArea(25) +mesh.Compute() +# get all free borders +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeBorders) +ids = mesh.GetIdsFromFilter(filter) +print "Number of edges on free borders:", len(ids) +\endcode + +\sa \ref tui_free_borders + +\section filter_free_edges Free edges + +Filter 2D mesh elements (faces) consisting of edges belonging to one +element of mesh only: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_FreeEdges +- threshold value is not required + +\code +# create mesh +import geompy, smesh, StdMeshers +face = geompy.MakeFaceHW(100, 100, 1) +geompy.addToStudy( face, "quadrangle" ) +mesh = smesh.Mesh(face) +mesh.Segment().NumberOfSegments(10) +mesh.Triangle().MaxElementArea(25) +mesh.Compute() +# get all faces with free edges +filter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeEdges) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with free edges:", len(ids) +\endcode + +\sa \ref tui_free_edges + +\section filter_free_nodes Free nodes + +Filter free nodes: +- element type is \a smesh.NODE +- functor type is \a smesh.FT_FreeNodes +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +# add node +mesh.AddNode(0,0,0) +# get all free nodes +filter = smesh.GetFilter(smesh.NODE, smesh.FT_FreeNodes) +ids = mesh.GetIdsFromFilter(filter) +print "Number of free nodes:", len(ids) +\endcode + +\sa \ref tui_free_nodes + +\section filter_free_faces Free faces + +Filter free faces: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_FreeFaces +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +# get all free faces +filter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeFaces) +ids = mesh.GetIdsFromFilter(filter) +print "Number of free faces:", len(ids) +\endcode + +\sa \ref tui_free_faces + +\section filter_bare_border_faces Bare border faces + +Filter faces with bare borders: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_BareBorderFace +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +# remove some faces to have faces with bare borders +mesh.RemoveElements( mesh.GetElementsByType(FACE)[0:5] ) +# get all faces bare borders +filter = smesh.GetFilter(smesh.FACE, smesh.FT_BareBorderFace) +ids = mesh.GetIdsFromFilter(filter) +print "Faces with bare borders:", ids +\endcode + +\sa \ref tui_bare_border_faces + +\section filter_coplanar_faces Coplanar faces + +Filter faces with bare borders: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_CoplanarFaces +- threshold value is the face ID +- tolerance is in degrees + +\code +# create mesh +from SMESH_mechanic import * +faceID = mesh.GetElementsByType(FACE)[0] +# get all faces co-planar to the first face with tolerance 5 degrees +filter = smesh.GetFilter(smesh.FACE, smesh.FT_CoplanarFaces,faceID,Tolerance=5.0) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces coplanar with the first one:", len(ids) +\endcode + +\section filter_over_constrained_faces Over-constrained faces + +Filter over-constrained faces: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_OverConstrainedFace +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +# get all over-constrained faces +filter = smesh.GetFilter(smesh.FACE, smesh.FT_OverConstrainedFace) +ids = mesh.GetIdsFromFilter(filter) +print "Over-constrained faces:", ids +\endcode + +\sa \ref tui_over_constrained_faces + +\section filter_double_elements Double edges, Double faces, Double volumes + +filter mesh elements basing on the same set of nodes: +- element type is either \a smesh.EGDE, \a smesh.FACE or \a smesh.VOLUME +- functor type is either \a smesh.FT_EqualEdges, \a + smesh.FT_EqualFaces or \a smesh.FT_EqualVolumes, +- threshold value is not required + +\code +from smesh import * +# make a mesh on a box +box = geompy.MakeBoxDXDYDZ(100,100,100) +mesh = Mesh( box, "Box" ) +mesh.Segment().NumberOfSegments(10) +mesh.Quadrangle() +mesh.Hexahedron() +mesh.Compute() +# copy all elements with translation and Merge nodes +mesh.TranslateObject( mesh, MakeDirStruct( 10,0,0), Copy=True ) +mesh.MergeNodes( mesh.FindCoincidentNodes(1e-7) ) +# create filters to find equal elements +equalEdgesFilter = GetFilter(SMESH.EDGE, FT_EqualEdges) +equalFacesFilter = GetFilter(SMESH.FACE, FT_EqualFaces) +equalVolumesFilter = GetFilter(SMESH.VOLUME, FT_EqualVolumes) +# get equal elements +print "Number of equal edges:", len( mesh.GetIdsFromFilter( equalEdgesFilter )) +print "Number of equal faces:", len( mesh.GetIdsFromFilter( equalFacesFilter )) +print "Number of equal volumes:", len( mesh.GetIdsFromFilter( equalVolumesFilter )) +\endcode + + +\section tui_double_nodes_control Double nodes + +filters mesh nodes which are coincident with other nodes (within a given tolerance): +- element type is \a smesh.NODE +- functor type is \a smesh.FT_EqualNodes +- threshold value is not required +- default tolerance is 1.0e-7 + +\code +from smesh import * +# make a mesh on a box +box = geompy.MakeBoxDXDYDZ(100,100,100) +mesh = Mesh( box, "Box" ) +mesh.Segment().NumberOfSegments(10) +mesh.Quadrangle() +mesh.Hexahedron() +mesh.Compute() +# copy all elements with translation +mesh.TranslateObject( mesh, MakeDirStruct( 10,0,0), Copy=True ) +# create filters to find nodes equal within tolerance of 1e-5 +filter = GetFilter(SMESH.NODE, FT_EqualNodes, Tolerance=1e-5) +# get equal nodes +print "Number of equal nodes:", len( mesh.GetIdsFromFilter( filter )) +\endcode + + +\section filter_borders_multiconnection Borders at multi-connection + +Filter border 1D mesh elements (edges) according to the specified number of +connections (faces belonging the border edges) +- element type is \a smesh.EDGE +- functor type is \a smesh.FT_MultiConnection +- threshold is integer value (number of connections) + +\code +# create mesh +from SMESH_mechanic import * +# get border edges with number of connected faces = 5 +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_MultiConnection, 5) +ids = mesh.GetIdsFromFilter(filter) +print "Number of border edges with 5 faces connected:", len(ids) +\endcode + +\sa \ref tui_borders_at_multiconnection + +\section filter_borders_multiconnection_2d Borders at multi-connection 2D + +Filter 2D mesh elements (faces) which consist of edges belonging +to the specified number of mesh elements +- element type is \a smesh.FACE +- functor type is \a smesh.FT_MultiConnection2D +- threshold is integer value (number of connections) + +\code +# create mesh +from SMESH_mechanic import * +# get faces which consist of edges belonging to 2 mesh elements +filter = smesh.GetFilter(smesh.FACE, smesh.FT_MultiConnection2D, 2) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces consisting of edges belonging to 2 faces:", len(ids) +\endcode + +\sa \ref tui_borders_at_multiconnection_2d + +\section filter_length Length + +Filter 1D mesh elements (edges) according to the edge length value: +- element type should be \a smesh.EDGE +- functor type should be \a smesh.FT_Length +- threshold is floating point value (length) + +\code +# create mesh +from SMESH_mechanic import * +# get edges with length > 14 +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_Length, smesh.FT_MoreThan, 14) +ids = mesh.GetIdsFromFilter(filter) +print "Number of edges with length > 14:", len(ids) +\endcode + +\sa \ref tui_length_1d + +\section filter_length_2d Length 2D + +Filter 2D mesh elements (faces) corresponding to the maximum length. +value of its edges: +- element type should be \a smesh.FACE +- functor type should be \a smesh.FT_Length2D +- threshold is floating point value (edge length) + +\code +# create mesh +from SMESH_mechanic import * +# get all faces that have edges with length > 14 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_Length2D, smesh.FT_MoreThan, 14) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with maximum edge length > 14:", len(ids) +\endcode + +\sa \ref tui_length_2d + +\section filter_max_element_length_2d Element Diameter 2D + +Filter 2D mesh elements (faces) corresponding to the maximum length +value of its edges and diagonals: +- element type should be \a smesh.FACE +- functor type should be \a smesh.FT_MaxElementLength2D +- threshold is floating point value (edge/diagonal length) + +\code +# create mesh +from SMESH_mechanic import * +# get all faces that have elements with length > 10 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with maximum element length > 10:", len(ids) +\endcode + +\sa \ref tui_max_element_length_2d + +\section filter_max_element_length_3d Element Diameter 3D + +Filter 3D mesh elements (volumes) corresponding to the maximum length +value of its edges and diagonals: +- element type should be \a smesh.VOLUME +- functor type should be \a smesh.FT_MaxElementLength3D +- threshold is floating point value (edge/diagonal length) + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron() +mesh.Compute() +# get all volumes that have elements with length > 10 +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, 10) +ids = mesh.GetIdsFromFilter(filter) +print "Number of volumes with maximum element length > 10:", len(ids) +\endcode + +\sa \ref tui_max_element_length_3d + +\section filter_bare_border_volumes Bare border volumes + +Filter 3D mesh elements with bare borders: +- element type is \a smesh.VOLUME +- functor type is \a smesh.FT_BareBorderVolume +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +mesh.Tetrahedron() +mesh.Compute() +# remove some volumes to have volumes with bare borders +mesh.RemoveElements( mesh.GetElementsByType(VOLUME)[0:5] ) +# get all volumes with bare borders +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_BareBorderVolume) +ids = mesh.GetIdsFromFilter(filter) +print "Volumes with bare borders:", ids +\endcode + +\sa \ref tui_bare_border_volumes + +\section filter_over_constrained_volumes Over-constrained volumes + +Filter over-constrained volumes: +- element type is \a smesh.VOLUME +- functor type is \a smesh.FT_OverConstrainedVolume +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +mesh.Tetrahedron() +mesh.Compute() +# get all over-constrained volumes +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_OverConstrainedVolume) +ids = mesh.GetIdsFromFilter(filter) +print "Over-constrained volumes:", ids +\endcode + +\sa \ref tui_over_constrained_faces + +\section filter_belong_to_geom Belong to Geom + +Filter mesh entities (nodes or elements) which all nodes lie on the +shape defined by threshold value: +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type should be \a smesh.FT_BelongToGeom +- threshold is geometrical object + +\code +# create mesh +from SMESH_mechanic import * +# get all faces which nodes lie on the face sub_face3 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToGeom, sub_face3) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces which nodes lie on sub_face3:", len(ids) +\endcode + +\section filter_lying_on_geom Lying on Geom + +Filter mesh entities (nodes or elements) at least one node of which lies on the +shape defined by threshold value: +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type should be \a smesh.FT_LyingOnGeom +- threshold is geometrical object + +\code +# create mesh +from SMESH_mechanic import * +# get all faces at least one node of each lies on the face sub_face3 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_LyingOnGeom, sub_face3) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces at least one node of each lies on sub_face3:", len(ids) +\endcode + +\section filter_belong_to_plane Belong to Plane + +Filter mesh entities (nodes or elements) which all nodes belong to the +plane defined by threshold value with the given tolerance: +- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE +- functor type should be \a smesh.FT_BelongToPlane +- threshold is geometrical object (plane) +- default tolerance is 1.0e-7 + +\code +# create mesh +from SMESH_mechanic import * +# create plane +import geompy +plane_1 = geompy.MakePlane(p3,seg1,2000) +geompy.addToStudy(plane_1, "plane_1") +# get all nodes which lie on the plane \a plane_1 +filter = smesh.GetFilter(smesh.NODE, smesh.FT_BelongToPlane, plane_1) +ids = mesh.GetIdsFromFilter(filter) +print "Number of nodes which lie on the plane plane_1:", len(ids) +\endcode + +\section filter_belong_to_cylinder Belong to Cylinder + +Filter mesh entities (nodes or elements) which all nodes belong to the +cylindrical face defined by threshold value with the given tolerance: +- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE +- functor type should be \a smesh.FT_BelongToCylinder +- threshold is geometrical object (cylindrical face) +- default tolerance is 1.0e-7 + +\code +# create mesh +from SMESH_mechanic import * +# get all faces which lie on the cylindrical face \a sub_face1 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToCylinder, sub_face1) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces which lie on the cylindrical surface sub_face1:", len(ids) +\endcode + +\section filter_belong_to_surface Belong to Surface + +Filter mesh entities (nodes or elements) which all nodes belong to the +arbitrary surface defined by threshold value with the given tolerance: +- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE +- functor type should be \a smesh.FT_BelongToGenSurface +- threshold is geometrical object (arbitrary surface) +- default tolerance is 1.0e-7 + +\code +# create mesh +from SMESH_mechanic import * +# create b-spline +spline_1 = geompy.MakeInterpol([p4,p6,p3,p1]) +surface_1 = geompy.MakePrismVecH( spline_1, vz, 70.0 ) +geompy.addToStudy(surface_1, "surface_1") +# get all nodes which lie on the surface \a surface_1 +filter = smesh.GetFilter(smesh.NODE, smesh.FT_BelongToGenSurface, surface_1) +ids = mesh.GetIdsFromFilter(filter) +print "Number of nodes which lie on the surface surface_1:", len(ids) +\endcode + +\section filter_range_of_ids Range of IDs + +Filter mesh entities elements (nodes or elements) according to the +specified identifiers range: +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type is \a smesh.FT_RangeOfIds +- threshold is string listing required IDs and/or ranges of IDs, e.g."1,2,3,50-60,63,67,70-78" + +\code +# create mesh +from SMESH_mechanic import * +# get nodes with identifiers [5-10] and [15-30] +criterion1 = smesh.GetCriterion(smesh.NODE, smesh.FT_RangeOfIds, Treshold="5-10",\ + BinaryOp=smesh.FT_LogicalOR) +criterion2 = smesh.GetCriterion(smesh.NODE, smesh.FT_RangeOfIds, Treshold="15-30") +filter = smesh.CreateFilterManager().CreateFilter() +filter.SetCriteria([criterion1,criterion2]) +ids = mesh.GetIdsFromFilter(filter) +print "Number of nodes in ranges [5-10] and [15-30]:", len(ids) +\endcode + +\section filter_bad_oriented_volume Badly oriented volume + +Filter 3D mesh elements (volumes), which are incorrectly oriented from +the point of view of MED convention. +- element type should be \a smesh.VOLUME +- functor type is \a smesh.FT_BadOrientedVolume +- threshold is not required + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron() +mesh.Compute() +# get all badly oriented volumes +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_BadOrientedVolume) +ids = mesh.GetIdsFromFilter(filter) +print "Number of badly oriented volumes:", len(ids) +\endcode + +\section filter_linear_or_quadratic Linear / quadratic + +Filter linear / quadratic mesh elements: +- element type should be any element type, e.g.: \a smesh.EDGE, \a smesh.FACE, \a smesh.VOLUME +- functor type is \a smesh.FT_LinearOrQuadratic +- threshold is not required +- if unary operator is set to smesh.FT_LogicalNOT, the quadratic +elements are selected, otherwise (by default) linear elements are selected + +\code +# create mesh +from SMESH_mechanic import * +# get number of linear and quadratic edges +filter_linear = smesh.GetFilter(smesh.EDGE, smesh.FT_LinearOrQuadratic) +filter_quadratic = smesh.GetFilter(smesh.EDGE, smesh.FT_LinearOrQuadratic, smesh.FT_LogicalNOT) +ids_linear = mesh.GetIdsFromFilter(filter_linear) +ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic) +print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic) +# convert mesh to quadratic +print "Convert to quadratic..." +mesh.ConvertToQuadratic(True) +# get number of linear and quadratic edges +ids_linear = mesh.GetIdsFromFilter(filter_linear) +ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic) +print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic) +\endcode + +\section filter_group_color Group color + +Filter mesh entities, belonging to the group with the color defined by the threshold value. +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type is \a smesh.FT_GroupColor +- threshold should be of SALOMEDS.Color type + +\code +# create mesh +from SMESH_mechanic import * +# create group of edges +all_edges = mesh.GetElementsByType(smesh.EDGE) +grp = mesh.MakeGroupByIds("edges group", smesh.EDGE, all_edges[:len(all_edges)/4]) +import SALOMEDS +c = SALOMEDS.Color(0.1, 0.5, 1.0) +grp.SetColor(c) +# get number of the edges not belonging to the group with the given color +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_GroupColor, c, smesh.FT_LogicalNOT) +ids = mesh.GetIdsFromFilter(filter) +print "Number of edges not beloging to the group with color (0.1, 0.5, 1.0):", len(ids) +\endcode + +\section filter_geom_type Geometry type + +Filter mesh elements by the geometric type defined with the threshold +value. The list of available geometric types depends on the element +entity type. +- element type should be any element type, e.g.: \a smesh.EDGE, \a smesh.FACE, \a smesh.VOLUME +- functor type should be \a smesh.FT_ElemGeomType +- threshold is of smesh.GeometryType value + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron() +mesh.Compute() +# get all triangles, quadrangles, tetrahedrons, pyramids +filter_tri = smesh.GetFilter(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_TRIANGLE) +filter_qua = smesh.GetFilter(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_QUADRANGLE) +filter_tet = smesh.GetFilter(smesh.VOLUME, smesh.FT_ElemGeomType, smesh.Geom_TETRA) +filter_pyr = smesh.GetFilter(smesh.VOLUME, smesh.FT_ElemGeomType, smesh.Geom_PYRAMID) +ids_tri = mesh.GetIdsFromFilter(filter_tri) +ids_qua = mesh.GetIdsFromFilter(filter_qua) +ids_tet = mesh.GetIdsFromFilter(filter_tet) +ids_pyr = mesh.GetIdsFromFilter(filter_pyr) +print "Number of triangles:", len(ids_tri) +print "Number of quadrangles:", len(ids_qua) +print "Number of tetrahedrons:", len(ids_tet) +print "Number of pyramids:", len(ids_pyr) +\endcode + +\section combining_filters How to combine filters with Criterion structures? + +Filters can be combined by making use of "criteria". + +Example : + +\code +# create mesh +from SMESH_mechanic import * +# get all the quadrangle faces ... +criterion1 = smesh.GetCriterion(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_QUADRANGLE, smesh.FT_LogicalAND) +# ... AND do NOT get those from sub_face3 +criterion2 = smesh.GetCriterion(smesh.FACE, smesh.FT_BelongToGeom, sub_face3, smesh.FT_LogicalNOT) +filter = smesh.CreateFilterManager().CreateFilter() +filter.SetCriteria([criterion1,criterion2]) +ids = mesh.GetIdsFromFilter(filter) + +myGroup = mesh.MakeGroupByIds("Quads_on_cylindrical_faces",smesh.FACE,ids) +\endcode + + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_generate_flat_elements.doc b/doc/salome/gui/SMESH/input/tui_generate_flat_elements.doc new file mode 100644 index 000000000..eaf544556 --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_generate_flat_elements.doc @@ -0,0 +1,82 @@ +/*! + +\page tui_generate_flat_elements_page Generate flat elements + +
                +\anchor tui_double_nodes_on_group_boundaries +

                Double nodes on groups boundaries

                + +\n Double nodes on shared faces between groups of volumes and create flat elements on demand. +\n The list of groups must describe a partition of the mesh volumes. The nodes of the internal +faces at the boundaries of the groups are doubled. Optionally, the internal faces are replaced +by flat elements. +\n Triangles are transformed into prisms, and quadrangles into hexahedrons. +\n The flat elements are stored in groups of volumes. + +\n +\n This example represents an iron cable (a thin cylinder) in a concrete bloc (a big cylinder). +The big cylinder is defined by two geometric volumes. + +\code +import geompy +import smesh +import SMESH +# geometry + +O = geompy.MakeVertex(0, 0, 0) +OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) +Vertex_1 = geompy.MakeVertex(50, 0, 0) +Cylinder_1 = geompy.MakeCylinder(O, OX, 10, 500) +Cylinder_2 = geompy.MakeCylinder(Vertex_1, OX, 100, 400) +Vertex_2 = geompy.MakeVertex(-200, -200, -200) +Vertex_3 = geompy.MakeVertex(250, 200, 200) +Box_1 = geompy.MakeBoxTwoPnt(Vertex_2, Vertex_3) +Fuse_1 = geompy.MakeFuse(Cylinder_1, Cylinder_2) +Partition_1 = geompy.MakePartition([Fuse_1], [Cylinder_1, Box_1], [], [], geompy.ShapeType["SOLID"], 0, [], 0) +[Solid_1,Solid_2] = geompy.GetShapesOnShape(Cylinder_1, Partition_1, geompy.ShapeType["SOLID"], geompy.GEOM.ST_IN) +[Solid_3,Solid_4] = geompy.GetShapesOnShape(Cylinder_2, Partition_1, geompy.ShapeType["SOLID"], geompy.GEOM.ST_IN) +Vertex_4 = geompy.MakeVertex(450, 0, 0) +Vertex_5 = geompy.MakeVertex(500, 0, 0) +Vertex_6 = geompy.MakeVertex(550, 0, 0) +vec1 = geompy.MakeVector(Vertex_4, Vertex_5) +vec2 = geompy.MakeVector(Vertex_5, Vertex_6) +[Face_1] = geompy.GetShapesOnPlane(Partition_1, geompy.ShapeType["FACE"], vec1, geompy.GEOM.ST_ON) +[Face_2] = geompy.GetShapesOnPlane(Partition_1, geompy.ShapeType["FACE"], vec2, geompy.GEOM.ST_ON) + +# meshing (we have linear tetrahedrons here, but other elements are OK) + +Mesh_1 = smesh.Mesh(Partition_1) +Regular_1D = Mesh_1.Segment() +Nb_Segments_1 = Regular_1D.NumberOfSegments(15) +MEFISTO_2D = Mesh_1.Triangle(algo=smesh.MEFISTO) +Length_From_Edges_2D = MEFISTO_2D.LengthFromEdges() +ALGO3D = Mesh_1.Tetrahedron() +isDone = Mesh_1.Compute() + +# relevant groups of volumes and faces + +Solid_1_1 = Mesh_1.GroupOnGeom(Solid_1,'Solid_1',SMESH.VOLUME) +Solid_2_1 = Mesh_1.GroupOnGeom(Solid_2,'Solid_2',SMESH.VOLUME) +Solid_3_1 = Mesh_1.GroupOnGeom(Solid_3,'Solid_3',SMESH.VOLUME) +Solid_4_1 = Mesh_1.GroupOnGeom(Solid_4,'Solid_4',SMESH.VOLUME) +Face_1_1 = Mesh_1.GroupOnGeom(Face_1,'Face_1',SMESH.FACE) +Face_2_1 = Mesh_1.GroupOnGeom(Face_2,'Face_2',SMESH.FACE) + +\endcode + +\n Here, the 4 groups of volumes [Solid_1_1, Solid_2_1, Solid_3_1, Solid_4_1] constitute a partition of the mesh. +The flat elements on group boundaries and on faces are built with the following code. +\n If the last argument (Boolean) in DoubleNodesOnGroupBoundaries is set to 1, +the flat elements are built, otherwise, there is only a duplication of the nodes. + +\code +Mesh_1.DoubleNodesOnGroupBoundaries([Solid_1_1, Solid_2_1, Solid_3_1, Solid_4_1], 1) + +Mesh_1.CreateFlatElementsOnFacesGroups([Face_1_1, Face_2_1]) +\endcode + +\n To observe flat element groups, save the resulting mesh on a MED file and reload it. + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_grouping_elements.doc b/doc/salome/gui/SMESH/input/tui_grouping_elements.doc index e03433f1c..a163d13f5 100644 --- a/doc/salome/gui/SMESH/input/tui_grouping_elements.doc +++ b/doc/salome/gui/SMESH/input/tui_grouping_elements.doc @@ -19,7 +19,11 @@ aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_Area, smesh.FT_MoreThan, 100.) anIds = mesh.GetIdsFromFilter(aFilter) # create a group consisting of faces with area > 100 -aGroup = mesh.MakeGroupByIds("Area > 100", smesh.FACE, anIds) +aGroup1 = mesh.MakeGroupByIds("Area > 100", smesh.FACE, anIds) + +# create a group that contains all nodes from the mesh +aGroup2 = mesh.CreateEmptyGroup(smesh.NODE, "all nodes") +aGroup2.AddFrom(mesh.mesh) salome.sg.updateObjBrowser(1) \endcode @@ -70,6 +74,51 @@ aSmeshGroup2 = quadra.GroupOnGeom(aGeomGroupE) salome.sg.updateObjBrowser(1) \endcode +
                +\anchor tui_create_group_on_filter + +

                Create a Group on Filter

                + +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +box = geompy.MakeBoxDXDYDZ(10,10,10) + +# make a mesh with quadrangles of different area in range [1,16] +mesh = Mesh(box,"Quad mesh") +hyp1D = mesh.Segment().StartEndLength( 1, 4 ) +mesh.Quadrangle() +mesh.Compute() + +# create a group on filter selecting faces of medium size +critaria = [ \ + GetCriterion(FACE, FT_Area, ">", 1.1, BinaryOp=FT_LogicalAND ), + GetCriterion(FACE, FT_Area, "<", 15.0 ) + ] +filt = GetFilterFromCriteria( critaria ) +filtGroup = mesh.GroupOnFilter( FACE, "group on filter", filt ) +print "Group on filter conatains %s elemens" % filtGroup.Size() + +# group on filter is updated if the mesh is modified +hyp1D.SetStartLength( 2.5 ) +hyp1D.SetEndLength( 2.5 ) +mesh.Compute() +print "After mesh change, group on filter conatains %s elemens" % filtGroup.Size() + +# set a new filter defining the group +filt2 = GetFilter( FACE, FT_RangeOfIds, "1-50" ) +filtGroup.SetFilter( filt2 ) +print "With a new filter, group on filter conatains %s elemens" % filtGroup.Size() + +# group is updated at modification of the filter +filt2.SetCriteria( [ GetCriterion( FACE, FT_RangeOfIds, "1-70" )]) +filtIDs3 = filtGroup.GetIDs() +print "After filter modification, group on filter conatains %s elemens" % filtGroup.Size() + +salome.sg.updateObjBrowser(1) +\endcode +
                \anchor tui_edit_group

                Edit a Group

                @@ -318,13 +367,13 @@ salome.sg.updateObjBrowser(1) \endcode \image html dimgroup_tui1.png -
                Source groups of faces<\center> +
                Source groups of faces
                \image html dimgroup_tui2.png -
                Result groups of edges and nodes<\center> +
                Result groups of edges and nodes
                -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/tui_measurements.doc b/doc/salome/gui/SMESH/input/tui_measurements.doc new file mode 100644 index 000000000..aabf0b317 --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_measurements.doc @@ -0,0 +1,84 @@ +/*! + +\page tui_measurements_page Measurements + +\section tui_min_distance Minimum Distance + +\code + +import smesh +from SMESH_mechanic import mesh as mesh1 +from SMESH_test1 import mesh as mesh2 + +mesh1.Compute() +mesh2.Compute() + +# compute min distance from mesh1 to the origin (not available yet) +smesh.MinDistance(mesh1) + +# compute min distance from node 10 of mesh1 to the origin +smesh.MinDistance(mesh1, id1=10) +# ... or +mesh1.MinDistance(10) + +# compute min distance between nodes 10 and 20 of mesh1 +smesh.MinDistance(mesh1, id1=10, id2=20) +# ... or +mesh1.MinDistance(10, 20) + +# compute min distance from element 100 of mesh1 to the origin (not available yet) +smesh.MinDistance(mesh1, id1=100, isElem1=True) +# ... or +mesh1.MinDistance(100, isElem1=True) + +# compute min distance between elements 100 and 200 of mesh1 (not available yet) +smesh.MinDistance(mesh1, id1=100, id2=200, isElem1=True, isElem2=True) +# ... or +mesh1.MinDistance(100, 200, True, True) + +# compute min distance from element 100 to node 20 of mesh1 (not available yet) +smesh.MinDistance(mesh1, id1=100, id2=20, isElem1=True) +# ... or +mesh1.MinDistance(100, 20, True) + +# compute min distance from mesh1 to mesh2 (not available yet) +smesh.MinDistance(mesh1, mesh2) + +# compute min distance from node 10 of mesh1 to node 20 of mesh2 +smesh.MinDistance(mesh1, mesh2, 10, 20) + +# compute min distance from node 10 of mesh1 to element 200 of mesh2 (not available yet) +smesh.MinDistance(mesh1, mesh2, 10, 200, isElem2=True) + +# etc... + +\endcode + +\section tui_bounding_box Bounding Box + +\code + +import smesh +from SMESH_mechanic import mesh as mesh1 +from SMESH_test1 import mesh as mesh2 + +mesh1.Compute() +mesh2.Compute() + +# compute bounding box for mesh1 +mesh1.BoundingBox() + +# compute bounding box for list of nodes of mesh1 +mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381]) + +# compute bounding box for list of elements of mesh1 +mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381], isElem=True) + +# compute common bounding box of mesh1 and mesh2 +smesh.BoundingBox([mesh1, mesh2]) + +# etc... + +\endcode + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc b/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc index bc7b78c89..922d15969 100644 --- a/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc @@ -22,6 +22,26 @@ if new_id == 0: print "KO node addition." else: print "New Node has been added with ID ", new_id \endcode +
                +\anchor tui_add_0DElement +

                Add 0D Element

                + +\code +import SMESH_mechanic + +mesh = SMESH_mechanic.mesh + +# add node +node_id = mesh.AddNode(50, 10, 0) + +# add 0D Element +new_id = mesh.Add0DElement(node_id) + +print "" +if new_id == 0: print "KO node addition." +else: print "New 0D Element has been added with ID ", new_id +\endcode +
                \anchor tui_add_edge

                Add Edge

                @@ -262,35 +282,40 @@ else: print "KO Elements removing." \endcode
                -\anchor tui_renumbering_nodes_and_elements -

                Renumbering Nodes and Elements

                +\anchor tui_removing_orphan_nodes +

                Removing Orphan Nodes

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

                Moving Nodes

                +\anchor tui_renumbering_nodes_and_elements +

                Renumbering Nodes and Elements

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

                Mesh through point

                +\anchor tui_moving_nodes +

                Moving Nodes

                \code from geompy import * @@ -324,16 +349,11 @@ n = mesh.FindNodeClosestTo( -1,-1,-1 ) if not n == node000: raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 ) -# check if any node will be found for a point inside a box -n = mesh.FindNodeClosestTo( 100, 100, 100 ) -if not n > 0: - raise "FindNodeClosestTo( 100, 100, 100 ) fails" - # move node000 to a new location x,y,z = -10, -10, -10 -n = mesh.MeshToPassThroughAPoint( x,y,z ) -if not n == node000: - raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 ) +n = mesh.MoveNode( n,x,y,z ) +if not n: + raise "MoveNode() returns " + n # check the coordinates of the node000 xyz = mesh.GetNodeXYZ( node000 ) @@ -768,7 +788,6 @@ mesh.RotationSweepObject(GroupRotate, axisXYZ, angle45, 4, 1e-5) \code import geompy - import smesh # define the geometry @@ -802,17 +821,151 @@ algo2D.MaxElementArea(240) isDone = Mesh_2.Compute() if not isDone: print 'Mesh Mesh_2 : computation failed' -# create a pattern +# create a 2d pattern pattern = smesh.GetPattern() isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), Face_2, 0) if (isDone != 1): print 'LoadFromFace :', pattern.GetErrorCode() # apply the pattern to a face of the first mesh -pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), [17], 0, 0) - +facesToSplit = Mesh_1.GetElementsByType(smesh.SMESH.FACE) +print "Splitting %d rectangular face(s) to %d triangles..."%(len(facesToSplit), 2*len(facesToSplit)) +pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), facesToSplit, 0, 0) isDone = pattern.MakeMesh(Mesh_1.GetMesh(), 0, 0) if (isDone != 1): print 'MakeMesh :', pattern.GetErrorCode() + +# create quadrangle mesh +Mesh_3 = smesh.Mesh(Box_1) +Mesh_3.Segment().NumberOfSegments(1) +Mesh_3.Quadrangle() +Mesh_3.Hexahedron() +isDone = Mesh_3.Compute() +if not isDone: print 'Mesh Mesh_3 : computation failed' + +# create a 3d pattern (hexahedrons) +pattern_hexa = smesh.GetPattern() + +smp_hexa = """!!! Nb of points: +15 + 0 0 0 !- 0 + 1 0 0 !- 1 + 0 1 0 !- 2 + 1 1 0 !- 3 + 0 0 1 !- 4 + 1 0 1 !- 5 + 0 1 1 !- 6 + 1 1 1 !- 7 + 0.5 0 0.5 !- 8 + 0.5 0 1 !- 9 + 0.5 0.5 0.5 !- 10 + 0.5 0.5 1 !- 11 + 1 0 0.5 !- 12 + 1 0.5 0.5 !- 13 + 1 0.5 1 !- 14 + !!! Indices of points of 4 elements: + 8 12 5 9 10 13 14 11 + 0 8 9 4 2 10 11 6 + 2 10 11 6 3 13 14 7 + 0 1 12 8 2 3 13 10""" + +pattern_hexa.LoadFromFile(smp_hexa) + +# apply the pattern to a mesh +volsToSplit = Mesh_3.GetElementsByType(smesh.SMESH.VOLUME) +print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 4*len(volsToSplit)) +pattern_hexa.ApplyToHexahedrons(Mesh_3.GetMesh(), volsToSplit,0,3) +isDone = pattern_hexa.MakeMesh(Mesh_3.GetMesh(), True, True) +if (isDone != 1): print 'MakeMesh :', pattern_hexa.GetErrorCode() + +# create one more quadrangle mesh +Mesh_4 = smesh.Mesh(Box_1) +Mesh_4.Segment().NumberOfSegments(1) +Mesh_4.Quadrangle() +Mesh_4.Hexahedron() +isDone = Mesh_4.Compute() +if not isDone: print 'Mesh Mesh_4 : computation failed' + +# create another 3d pattern (pyramids) +pattern_pyra = smesh.GetPattern() + +smp_pyra = """!!! Nb of points: +9 + 0 0 0 !- 0 + 1 0 0 !- 1 + 0 1 0 !- 2 + 1 1 0 !- 3 + 0 0 1 !- 4 + 1 0 1 !- 5 + 0 1 1 !- 6 + 1 1 1 !- 7 + 0.5 0.5 0.5 !- 8 + !!! Indices of points of 6 elements: + 0 1 5 4 8 + 7 5 1 3 8 + 3 2 6 7 8 + 2 0 4 6 8 + 0 2 3 1 8 + 4 5 7 6 8""" + +pattern_pyra.LoadFromFile(smp_pyra) + +# apply the pattern to a face mesh +volsToSplit = Mesh_4.GetElementsByType(smesh.SMESH.VOLUME) +print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 6*len(volsToSplit)) +pattern_pyra.ApplyToHexahedrons(Mesh_4.GetMesh(), volsToSplit,1,0) +isDone = pattern_pyra.MakeMesh(Mesh_4.GetMesh(), True, True) +if (isDone != 1): print 'MakeMesh :', pattern_pyra.GetErrorCode() +\endcode + +
                +\anchor tui_quadratic +

                Convert mesh to/from quadratic

                + +\code +import geompy +import smesh + +# create sphere of radius 100 + +Sphere = geompy.MakeSphereR( 100 ) +geompy.addToStudy( Sphere, "Sphere" ) + +# create simple trihedral mesh + +Mesh = smesh.Mesh(Sphere) +Regular_1D = Mesh.Segment() +Nb_Segments = Regular_1D.NumberOfSegments(5) +MEFISTO_2D = Mesh.Triangle() +Tetrahedron = Mesh.Tetrahedron() + +# compute mesh + +isDone = Mesh.Compute() + +# convert to quadratic +# theForce3d = 1; this results in the medium node lying at the +# middle of the line segments connecting start and end node of a mesh +# element + +Mesh.ConvertToQuadratic( theForce3d=1 ) + +# revert back to the non-quadratic mesh + +Mesh.ConvertFromQuadratic() + +# convert to quadratic +# theForce3d = 0; this results in the medium node lying at the +# geometrical edge from which the mesh element is built + +Mesh.ConvertToQuadratic( theForce3d=0 ) + +# to convert not the whole mesh but a sub-mesh, provide it as +# an additional argument to the functions: +# Mesh.ConvertToQuadratic( 0, subMesh ) +# Mesh.ConvertFromQuadratic( subMesh ) +# +# Note that the mesh becomes non-conformal at conversion of sub-mesh. + \endcode -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/tui_notebook_smesh.doc b/doc/salome/gui/SMESH/input/tui_notebook_smesh.doc new file mode 100644 index 000000000..a300ee633 --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_notebook_smesh.doc @@ -0,0 +1,47 @@ +/*! + +\page tui_notebook_smesh_page Using SALOME NoteBook + +\anchor tui_notebook_smesh + +\code +import geompy +import smesh +import salome_notebook + +# set variables +notebook = salome_notebook.notebook +notebook.set("Length", 100) +notebook.set("Width", 200) +notebook.set("Offset", 50) + +notebook.set("NbSegments", 7) +notebook.set("MaxElementArea", 800) +notebook.set("MaxElementVolume", 900) + +# create a box +box = geompy.MakeBoxDXDYDZ("Length", "Width", 300) +idbox = geompy.addToStudy(box, "Box") + +# create a mesh +tetra = smesh.Mesh(box, "MeshBox") + +algo1D = tetra.Segment() +algo1D.NumberOfSegments("NbSegments") + +algo2D = tetra.Triangle() +algo2D.MaxElementArea("MaxElementArea") + +algo3D = tetra.Tetrahedron() +algo3D.MaxElementVolume("MaxElementVolume") + +# compute the mesh +ret = tetra.Compute() + +# translate the mesh +point = smesh.PointStruct("Offset", 0., 0.) +vector = smesh.DirStruct(point) +tetra.TranslateObject(tetra, vector, 0) +\endcode + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_quality_controls.doc b/doc/salome/gui/SMESH/input/tui_quality_controls.doc index 57d52c69e..bc99172aa 100644 --- a/doc/salome/gui/SMESH/input/tui_quality_controls.doc +++ b/doc/salome/gui/SMESH/input/tui_quality_controls.doc @@ -2,9 +2,7 @@ \page tui_quality_controls_page Quality Controls -
                -\anchor tui_free_borders -

                Free Borders

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

                Borders at Multiconnection

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

                Length 1D

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

                Free Edges

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

                Free Nodes

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

                Free Faces

                +\section tui_free_faces Free Faces \code import salome @@ -281,13 +268,12 @@ geompy.addToStudy( Plane_2, "Plane_2" ) import smesh import StdMeshers -import NETGENPlugin Mesh_1 = smesh.Mesh(Partition_1) Regular_1D = Mesh_1.Segment() Max_Size_1 = Regular_1D.MaxSize(34.641) MEFISTO_2D = Mesh_1.Triangle() -Tetrahedron_Netgen = Mesh_1.Tetrahedron(algo=smesh.NETGEN) +Tetrahedronn = Mesh_1.Tetrahedron() isDone = Mesh_1.Compute() # create a group of free faces @@ -298,11 +284,11 @@ aGroup = Mesh_1.CreateEmptyGroup(smesh.FACE, "Free_faces") aGroup.Add(aFaceIds) # print the result -print "Criterion: Free nodes Nb = ", len(anNodeIds) +print "Criterion: Free faces Nb = ", len(aFaceIds) j = 1 for i in range(len(aFaceIds)): if j > 20: j = 1; print "" - print anNodeIds[i], + print aFaceIds[i], j = j + 1 pass print "" @@ -322,10 +308,91 @@ aGroup.Add(aFaceIds) salome.sg.updateObjBrowser(1) \endcode +\section tui_bare_border_faces Bare border faces + +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +box = geompy.MakeBoxDXDYDZ(100, 100, 100) +geompy.addToStudy( box, "box" ) + +mesh = smesh.Mesh(box) +mesh.Segment().NumberOfSegments(3) +mesh.Quadrangle() +mesh.Compute() + +# remove 2 faces +allFaces = mesh.GetElementsByType(FACE) +mesh.RemoveElements( allFaces[0:2]) + +bareGroup = mesh.MakeGroup("bare faces", FACE, FT_BareBorderFace) +assert(bareGroup.Size() == 3) +\endcode + +\section tui_bare_border_volumes Bare border volumes + +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +box = geompy.MakeBoxDXDYDZ(100, 30, 10) +# the smallest face of the box +face = geompy.SubShapeAllSorted( box, geompy.ShapeType["FACE"])[0] + +geompy.addToStudy( box, "box" ) +geompy.addToStudyInFather( box, face, "face" ) + +mesh = Mesh(box) +mesh.AutomaticHexahedralization(); + +# remove half of mesh faces from the smallest face +faceFaces = mesh.GetSubMeshElementsId(face) +faceToRemove = faceFaces[: len(faceFaces)/2] +mesh.RemoveElements( faceToRemove ) + +# make a group of volumes missing the removed faces +bareGroup = mesh.MakeGroup("bare volumes", VOLUME, FT_BareBorderVolume) +assert(bareGroup.Size() == len( faceToRemove)) +\endcode + +\section tui_over_constrained_faces Over-constrained faces +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +mesh = Mesh() +faceFilter = GetFilter(FACE,FT_OverConstrainedFace) + +#make an edge +n1 = mesh.AddNode(0,0,0) +n2 = mesh.AddNode(10,0,0) +edge = mesh.AddEdge([n1,n2]) +assert( not mesh.GetIdsFromFilter( faceFilter )) -
                -\anchor tui_length_2d -

                Length 2D

                +# make faces +mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 5) +assert( 2 == len( mesh.GetIdsFromFilter( faceFilter ))) +\endcode + +\section tui_over_constrained_volumes Over-constrained volumes +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +mesh = Mesh() +volumeFilter = GetFilter(VOLUME,FT_OverConstrainedVolume) + +# make volumes by extrusion of one face +n1 = mesh.AddNode(0,0,0) +n2 = mesh.AddNode(10,0,0) +edge = mesh.AddEdge([n1,n2]) +mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 1) +mesh.ExtrusionSweep( mesh.GetElementsByType(FACE), MakeDirStruct(0,0,5), 7) +assert( 2 == len( mesh.GetIdsFromFilter( volumeFilter ))) +\endcode + +\section tui_length_2d Length 2D \code import salome @@ -372,9 +439,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
                -\anchor tui_borders_at_multiconnection_2d -

                Borders at Multiconnection 2D

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

                Area

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

                Taper

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

                Aspect Ratio

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

                Minimum Angle

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

                Warping

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

                Skew

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

                Aspect Ratio 3D

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

                Volume

                +\section tui_volume Volume \code import SMESH_mechanic_tetra @@ -706,4 +788,37 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode +\section tui_max_element_length_3d Element Diameter 3D + +\code +import SMESH_mechanic_tetra + +smesh = SMESH_mechanic_tetra.smesh +mesh = SMESH_mechanic_tetra.mesh +salome = SMESH_mechanic_tetra.salome + +# Criterion : ELEMENT DIAMETER 3D > 10 +mel_3d_margin = 10 + +aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, mel_3d_margin) + +anIds = mesh.GetIdsFromFilter(aFilter) + +# print the result +print "Criterion: Element Diameter 3D Ratio > ", mel_3d_margin, " Nb = ", len(anIds) +j = 1 +for i in range(len(anIds)): + if j > 20: j = 1; print "" + print anIds[i], + j = j + 1 + pass +print "" + +# create a group +aGroup = mesh.CreateEmptyGroup(smesh.FACE, "Element Diameter 3D > " + `mel_3d_margin`) +aGroup.Add(anIds) + +salome.sg.updateObjBrowser(1) +\endcode + */ diff --git a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc index 163afe0e4..a4c6df87d 100644 --- a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc @@ -44,6 +44,37 @@ angle270 = 1.5 * math.pi mesh.Rotate([], axisXYZ, angle270, 1) \endcode +
                +\anchor tui_scale +

                Scale

                + +\code +import geompy +Box = geompy.MakeBoxDXDYDZ(200, 200, 200) +f = geompy.SubShapeAllSorted(Box, geompy.ShapeType["FACE"]) + +import smesh,SMESH +import StdMeshers +Mesh1 = smesh.Mesh(f[0]) +Regular_1D = Mesh1.Segment() +Nb_Segments_1 = Regular_1D.NumberOfSegments(3) +Nb_Segments_1.SetDistrType( 0 ) +Quadrangle_2D = Mesh1.Quadrangle() +isDone = Mesh1.Compute() + +#Perform scale opration for the whole mesh and creation of a new mesh +newMesh = Mesh1.ScaleMakeMesh(Mesh1,SMESH.PointStruct(100,100,200),[0.5,0.3,0.7],True,"ScaledMesh") + +#Perform scale operation for the whole mesh and copy elements +Mesh1.Scale(Mesh1,SMESH.PointStruct(200,100,100),[0.5,0.5,0.5],True,True) + +#Perform scale opration for two edges and move elements +Mesh1.Scale([1,2],SMESH.PointStruct(-100,100,100),[0.8,1.0,0.7],False) + +#Perform scale opration for one face and move elements +Mesh1.Scale([21],SMESH.PointStruct(0,200,200),[0.7,0.7,0.7],False) +\endcode +
                \anchor tui_symmetry

                Symmetry

                @@ -319,4 +350,237 @@ mesh.Compute() mesh.SewSideElements([69, 70, 71, 72], [91, 92, 89, 90], 8, 38, 23, 58) \endcode -*/ \ No newline at end of file +
                +\anchor tui_duplicate_nodes +

                Duplicate nodes

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

                Create boundary elements

                + +\code +from smesh import * +SetCurrentStudy(salome.myStudy) + +box = geompy.MakeBoxDXDYDZ(100, 100, 100) +gFaces = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"]) +f1,f2 = gFaces[0],gFaces[1] +geompy.addToStudy(box,"box") +geompy.addToStudyInFather(box,f1,"face1") +geompy.addToStudyInFather(box,f2,"face2") + +twoFaces = geompy.MakeCompound([f1,f2]) + +## ----------- +## +## 2D from 3D +## +## ----------- +dim = SMESH.BND_2DFROM3D + +init_mesh = Mesh(box, "box") +init_mesh.AutomaticHexahedralization() # it makes 3 x 3 x 3 hexahedrons + +# remove some faces +faces = init_mesh.GetElementsByType( SMESH.FACE ) +nb_faces = len( faces ) +rm_face = faces[ : nb_faces/2] +init_mesh.RemoveElements( rm_face ) + +# restore boundary in this mesh +mesh = CopyMesh( init_mesh, "2D from 3D") +groupName = "bnd 2D" +nb, new_mesh, new_group = mesh.MakeBoundaryElements(dim, groupName) + +# restore boundary (only) in other mesh +meshName = "2D boundary of " + init_mesh.GetName() +nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName) + +# restore boundary in mesh copy +meshName = init_mesh.GetName() + " + boundary" +nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName, toCopyAll=True) + + +## ----------- +## +## 1D from 2D +## +## ----------- +dim = SMESH.BND_1DFROM2D + +init_mesh = Mesh(f1, "2D mesh") +init_mesh.AutomaticHexahedralization() + +# remove some edges +edges = init_mesh.GetElementsByType( SMESH.EDGE ) +nb_edges = len( edges ) +rm_edge = edges[ : nb_edges/2] +init_mesh.RemoveElements( rm_edge ) + + +# restore boundary edges in this mesh +mesh = CopyMesh( init_mesh, "1D from 2D") +groupName = "bnd 1D" +nb, new_mesh, new_group = mesh.MakeBoundaryElements(dim, groupName) + +# restore boundary edges (only) in other mesh +meshName = "1D boundary of " + init_mesh.GetName() +nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName) + +# restore boundary edges in mesh copy +meshName = init_mesh.GetName() + " + boundary" +nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName, toCopyAll=True) + + + +## ------------------ +## +## 1D from 2D GROUPS +## +## ------------------ +dim = SMESH.BND_1DFROM3D + +init_mesh = Mesh(box, "box") +init_mesh.AutomaticHexahedralization() # it makes 3 x 3 x 3 hexahedrons +# remove all edges +rm_edges = init_mesh.GetElementsByType( SMESH.EDGE ) +init_mesh.RemoveElements( rm_edges ) + +# make groups of faces +fGroup1 = init_mesh.Group( f1, "f1" ) +fGroup2 = init_mesh.Group( f2, "f2" ) + +# make 1D boundary around groups in this mesh +mesh = CopyMesh( init_mesh, "1D from 2D groups", toCopyGroups=True) +groups = mesh.GetGroups() +nb, new_mesh, new_group = mesh.MakeBoundaryElements(dim, groupName,groups=groups) + +# make 1D boundary (only) in other mesh +meshName = "boundary from groups of " + init_mesh.GetName() +groups = init_mesh.GetGroups() +nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName,groups=groups) + +# make 1D boundary in mesh copy +meshName = init_mesh.GetName() + " + boundary from groups" +nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName, + groups=groups, toCopyAll=True) + +\endcode + +
                +\anchor tui_reorient_faces +

                Reorient faces by vector

                + +\code +import smesh, geompy, SMESH + +# create a geometry consisting of two faces +box = geompy.MakeBoxDXDYDZ( 10, 10, 10 ) +faces = geompy.SubShapeAllSorted( box, geompy.ShapeType["FACE"]) + +shape = geompy.MakeCompound( faces[:2] ) +faces = geompy.SubShapeAll( shape, geompy.ShapeType["FACE"] ) +geompy.addToStudy( shape, "shape") +geompy.addToStudyInFather( shape, faces[0], "faces[0]") +geompy.addToStudyInFather( shape, faces[1], "faces[1]") + +# create a 2D mesh +mesh = smesh.Mesh( shape, "test_Reorient2D") +mesh.AutomaticHexahedralization(0.5) +localAlgo = mesh.Segment(faces[0]) +localAlgo.NumberOfSegments( 11 ) +mesh.Compute() +group = mesh.Group( faces[1] ) + +vec = geompy.MakeVectorDXDYDZ( 1, 1, 1 ) + +# Each of arguments of Reorient2D() function can be of different types: +# +# 2DObject - the whole mesh +# Direction - a GEOM object (vector) +# FaceOrPoint - an ID of face +mesh.Reorient2D( mesh, vec, mesh.NbElements() ) +# +# 2DObject - a sub-mesh +# Direction - components of a vector +# FaceOrPoint - a GEOM object (vertex) +mesh.Reorient2D( localAlgo.GetSubMesh(), [ 1, -1, 1 ], geompy.GetFirstVertex( vec )) +# +# 2DObject - a group of faces +# Direction - a SMESH.DirStruct structure +# FaceOrPoint - coordinates of a point +mesh.Reorient2D( group, smesh.MakeDirStruct( -10, 1, 10 ), [0,0,0]) +# +# FaceOrPoint - a SMESH.PointStruct structure +mesh.Reorient2D( localAlgo.GetSubMesh().GetIDs(), [10,1,0], SMESH.PointStruct(0,0,0)) + +\endcode + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_use_existing_faces.doc b/doc/salome/gui/SMESH/input/tui_use_existing_faces.doc new file mode 100644 index 000000000..8b9c7325a --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_use_existing_faces.doc @@ -0,0 +1,124 @@ +/*! + +\page tui_use_existing_faces Use existing faces + +This sample demonstrates how to use Use existing faces algorithm, +which is actulally just a stub allowing to use your own 2D algoritm +implemented in Python. + + +\code +import smesh, geompy +import numpy as np + +# define my 2D algorithm +def my2DMeshing( geomFace ): + + # find gravity center of geomFace + gcXYZ = geompy.PointCoordinates( geompy.MakeCDG( geomFace )) + + # define order and orientation of edges + sortedEdges = [] + geomEdges = geompy.SubShapeAll( geomFace, geompy.ShapeType["EDGE"]) + sortedEdges.append(( geomEdges.pop(0), True )) + while geomEdges: + prevEdge_rev = sortedEdges[ -1 ] + prevVV = geompy.SubShapeAll( prevEdge_rev[0], geompy.ShapeType["VERTEX"]) + prevV2 = prevVV[ prevEdge_rev[1] ] + found = False + for iE in range( len( geomEdges )): + v1,v2 = geompy.SubShapeAll( geomEdges[ iE ], geompy.ShapeType["VERTEX"]) + same1,same2 = [( geompy.MinDistance( prevV2, v ) < 1e-7 ) for v in [v1,v2] ] + if not same1 and not same2: continue + sortedEdges.append(( geomEdges.pop( iE ), same1 )) + found = True + break + assert found + sortedEdges.reverse() + + # put nodes on edges in a right order + nodes = [] + for edge, isForward in sortedEdges: + v1,v2 = geompy.SubShapeAll( edge, geompy.ShapeType["VERTEX"]) + edgeNodes = mesh.GetSubMeshNodesId( v2, all=False ) + \ + mesh.GetSubMeshNodesId( edge, all=False ) + \ + mesh.GetSubMeshNodesId( v1, all=False ) + if not isForward: edgeNodes.reverse() + nodes.extend( edgeNodes[:-1] ) + + # create nodes inside the geomFace + r1 = 0.6 + r2 = 1 - r1 + nodesInside = [] + for n in nodes: + nXYZ = mesh.GetNodeXYZ( n ) + newXYZ = np.add( np.multiply( r1, gcXYZ ), np.multiply( r2, nXYZ )) + nodesInside.append( mesh.AddNode( newXYZ[0], newXYZ[1], newXYZ[2] )) + mesh.SetNodeOnFace( nodesInside[-1], geomFace, 0, 0 ) + + # find out orientation of faces to create + # geomFace normal + faceNorm = geompy.GetNormal( geomFace ) + v1,v2 = [ geompy.PointCoordinates( v ) \ + for v in geompy.SubShapeAll( faceNorm, geompy.ShapeType["VERTEX"]) ] + faceNormXYZ = np.subtract( v2, v1 ) + outDirXYZ = np.subtract( v1, [ 50, 50, 50 ] ) + if np.dot( faceNormXYZ, outDirXYZ ) < 0: # reversed face + faceNormXYZ = np.multiply( -1., faceNormXYZ ) + # mesh face normal + e1 = np.subtract( mesh.GetNodeXYZ( nodes[0] ), mesh.GetNodeXYZ( nodes[1] )) + e2 = np.subtract( mesh.GetNodeXYZ( nodes[0] ), mesh.GetNodeXYZ( nodesInside[0] )) + meshNorm = np.cross( e1, e2 ) + # faces orientation + reverse = ( np.dot( faceNormXYZ, meshNorm ) < 0 ) + + # create mesh faces + iN = len( nodes ) + while iN: + n1, n2, n3, n4 = nodes[iN-1], nodes[iN-2], nodesInside[iN-2], nodesInside[iN-1] + iN -= 1 + if reverse: + f = mesh.AddFace( [n1, n2, n3, n4] ) + else: + f = mesh.AddFace( [n4, n3, n2, n1] ) + # new faces must be assigned to geometry to allow 3D algorithm finding them + mesh.SetMeshElementOnShape( f, geomFace ) + + if reverse: + nodesInside.reverse() + polygon = mesh.AddPolygonalFace( nodesInside ) + mesh.SetMeshElementOnShape( polygon, geomFace ) + + return + +# create geometry and get faces to mesh with my2DMeshing() +box = geompy.MakeBoxDXDYDZ( 100, 100, 100 ) +f1 = geompy.SubShapeAll( box, geompy.ShapeType["FACE"])[0] +f2 = geompy.GetOppositeFace( box, f1 ) +geompy.addToStudy( box, "box" ) +geompy.addToStudy( f1, "f1" ) +geompy.addToStudy( f2, "f2" ) + +# compute 1D mesh +mesh = smesh.Mesh( box ) +mesh.Segment().NumberOfSegments( 5 ) +mesh.Compute() + +# compute 2D mesh +mesh.Quadrangle() +mesh.UseExistingFaces(f1) # UseExistingFaces() allows using my2DMeshing() +mesh.UseExistingFaces(f2) +my2DMeshing( f1 ) +my2DMeshing( f2 ) +assert mesh.Compute() + +# compute 3D mesh +mesh.Prism() +assert mesh.Compute() + +\endcode + +Resulting mesh: +\image html use_existing_face_sample_mesh.png + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_viewing_meshes.doc b/doc/salome/gui/SMESH/input/tui_viewing_meshes.doc index 59681c16b..fc0094e4b 100644 --- a/doc/salome/gui/SMESH/input/tui_viewing_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_viewing_meshes.doc @@ -9,10 +9,12 @@ \code import geompy import smesh +import SMESH # create a box box = geompy.MakeBox(0., 0., 0., 20., 20., 20.) geompy.addToStudy(box, "box") +[Face_1,Face_2,Face_3,Face_4,Face_5,Face_5] = geompy.SubShapeAll(box, geompy.ShapeType["FACE"]) # create a mesh tetra = smesh.Mesh(box, "MeshBox") @@ -23,13 +25,25 @@ algo1D.NumberOfSegments(3) algo2D = tetra.Triangle() algo2D.MaxElementArea(10.) -algo3D = tetra.Tetrahedron(smesh.NETGEN) +algo3D = tetra.Tetrahedron() algo3D.MaxElementVolume(900.) +# Creation of SubMesh +Regular_1D_1_1 = tetra.Segment(geom=Face_1) +Nb_Segments_1 = Regular_1D_1_1.NumberOfSegments(5) +Nb_Segments_1.SetDistrType( 0 ) +Quadrangle_2D = tetra.Quadrangle(geom=Face_1) +isDone = tetra.Compute() +submesh = Regular_1D_1_1.GetSubMesh() + # compute the mesh tetra.Compute() -# print information about the mesh +# Creation of group +group = tetra.CreateEmptyGroup( SMESH.FACE, 'Group' ) +nbAdd = group.Add( [ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 ] ) + +# Print information about the mesh print "Information about mesh:" print "Number of nodes : ", tetra.NbNodes() print "Number of edges : ", tetra.NbEdges() @@ -43,5 +57,83 @@ print " hexahedrons : ", tetra.NbHexas() print " prisms : ", tetra.NbPrisms() print " pyramids : ", tetra.NbPyramids() print " polyhedrons : ", tetra.NbPolyhedrons() + +# Get Information About Mesh by GetMeshInfo +print "\nInformation about mesh by GetMeshInfo:" +info = smesh.GetMeshInfo(tetra) +keys = info.keys(); keys.sort() +for i in keys: + print " %s : %d" % ( i, info[i] ) + pass + +# Get Information About Group by GetMeshInfo +print "\nInformation about group by GetMeshInfo:" +info = smesh.GetMeshInfo(group) +keys = info.keys(); keys.sort() +for i in keys: + print " %s : %d" % ( i, info[i] ) + pass + +# Get Information About SubMesh by GetMeshInfo +print "\nInformation about Submesh by GetMeshInfo:" +info = smesh.GetMeshInfo(submesh) +keys = info.keys(); keys.sort() +for i in keys: + print " %s : %d" % ( i, info[i] ) + pass +\endcode + + + +
                +\anchor tui_find_element_by_point +

                Find Element by Point

                + +\code +import geompy +import smesh +import SMESH + +# Create a geometry to mesh +box = geompy.MakeBoxDXDYDZ(100,100,100) + +# Create a mesh +mesh = Mesh(box,"Mesh") +mesh.AutomaticHexahedralization() +mesh.Compute() + +# Create a point +x,y,z = 0, 0, 1 + +# Find all elements (except 0D ones) located at the point +all_elems_except_0D = mesh.FindElementsByPoint(x,y,z) +assert( len(all_elems_except_0D) == 4) + +# Find nodes at the point +nodes = mesh.FindElementsByPoint(x,y,z, SMESH.NODE ) +assert( len(nodes) == 0) +assert( len( mesh.FindElementsByPoint(x,y,0, SMESH.NODE)) == 1) + +# Find an edge at the point +edges = mesh.FindElementsByPoint(x,y,z, SMESH.EDGE ) +assert( len(edges) == 1) + +# Find faces at the point +edges = mesh.FindElementsByPoint(x,y,z, SMESH.FACE ) +assert( len(edges) == 2) + +# Find a volume at the point +vols = mesh.FindElementsByPoint(x,y,z, SMESH.VOLUME ) +assert( len(vols) == 1) + +# Find 0D elements at the point +elems0d = mesh.FindElementsByPoint(x,y,z, SMESH.ELEM0D ) +assert( len(elems0d) == 0) + +# Find edges within a group +group1D = mesh.MakeGroupByIds("1D", SMESH.EDGE, [1,2] ) +edges = mesh.FindElementsByPoint(x,y,z, SMESH.EDGE, group1D ) + \endcode -*/ \ No newline at end of file + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_work_on_objects_from_gui.doc b/doc/salome/gui/SMESH/input/tui_work_on_objects_from_gui.doc new file mode 100644 index 000000000..abc51d95b --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_work_on_objects_from_gui.doc @@ -0,0 +1,27 @@ +/*! + +\page tui_work_on_objects_from_gui How to work with objects from the GUI ? + +It is sometimes useful to work alternatively in the GUI of SALOME and in the Python Console. To fetch an object from the TUI simply type: + +\code +myMesh_ref = salome.IDToObject("ID") +// were ID is the number that appears in the object browser in the Entry column +// ( If hidden show it by right clicking and checking the checkbox Entry) +myMesh = smesh.Mesh(myMesh_ref) +\endcode +or +\code +myMesh_ref = salome.myStudy.FindObjectByPath("/Mesh/myMesh").GetObject() +// "/Mesh/myMesh" is the path to the desired object in the object browser +myMesh = smesh.Mesh(myMesh_ref) +\endcode + +All the methods documented in these pages can then be used on myMesh + +\note The first statement only gives you access to a reference to the object created via the GUI. +\n But the methods available on this reference are not exactly the same as those documented in these help pages. +This Python API is meant to be used on smesh.Mesh instances. +\n That's why you'll have to create such an instance with the second statement. + +*/ diff --git a/doc/salome/gui/SMESH/input/use_existing_algos.doc b/doc/salome/gui/SMESH/input/use_existing_algos.doc new file mode 100644 index 000000000..3634ccf60 --- /dev/null +++ b/doc/salome/gui/SMESH/input/use_existing_algos.doc @@ -0,0 +1,66 @@ +/*! + +\page import_algos_page Use Existing Elements Algorithms + +\n Use Existing Elements algorithms allow to define the mesh of a geometrical +object by importing suitably located mesh elements from another +mesh. The mesh elements to import from the other mesh should be contained in +groups. If several groups are used to mesh the same geometry, validity of +nodal connectivity of result mesh must be assured by connectivity of +the source mesh; no geometrical checks are performed to merge +different nodes at same locations. +
                The source elements must totally cover the meshed geometry. +The source elements lying partially over the geometry will not be used. +
                +These algorithms can be used to mesh a very complex geometry part by +part, by storing meshes of parts in files and then fusing them +together using these algorithms. +
                + +Use Existing 1D Elements algorithm allows to define the mesh of +a geometrical edge (or group of edges) +by importing mesh edges contained in a group (or groups) from another mesh. +\n To apply this algorithm select the edge to be meshed (indicated in +the field \b Geometry of Create mesh dialog box), +Use existing 1D elements in the list of 1D algorithms and click the +"Add Hypothesis" button. +The following dialog box will appear: + +\image html hyp_source_edges.png + +In this dialog box you can define +
                  +
                • The \b Name of the algorithm.
                • +
                • The Groups of Edges to import 1D elements from. +
                • To copy mesh checkbox allows to import not only the edges of +the selected Groups of Edges, but the whole source +mesh. In this case To copy groups checkbox allows to create +the same groups as in the imported source mesh.
                • +
                + +Use Existing 2D Elements algorithm allows to define the mesh of +a geometrical face (or group of faces) +by importing mesh faces contained in a group (or groups) from another mesh. +\n To apply this algorithm select the geometrical face to be meshed (indicated in +the field \b Geometry of Create mesh dialog box), +Use existing 2D elements in the list of 2D algorithms and click the +"Add Hypothesis" button. +The following dialog box will appear: + +\image html hyp_source_faces.png + +In this dialog box you can define +
                  +
                • The \b Name of the algorithm.
                • +
                • The Groups of Edges to import 1D elements from. +
                • To copy mesh checkbox allows to import not only the edges of +the selected Groups of Edges, but the whole source +mesh. In this case To copy groups checkbox allows to create +the same groups as in the imported source mesh.
                • +
                + +
                See Also a sample TUI Script of a +\ref tui_import "Use Existing Elements Algorithms". + +*/ + diff --git a/doc/salome/gui/SMESH/input/using_notebook_smesh_page.doc b/doc/salome/gui/SMESH/input/using_notebook_smesh_page.doc index 2968a27be..aac0c9052 100644 --- a/doc/salome/gui/SMESH/input/using_notebook_smesh_page.doc +++ b/doc/salome/gui/SMESH/input/using_notebook_smesh_page.doc @@ -2,9 +2,14 @@ \page using_notebook_mesh_page Using SALOME NoteBook -It is possible to use variables defined through SALOME NoteBook for -creation and modification of objects in the MESH module with the following -limitations: +SALOME NoteBook allows defining variables to be used for +creation and modification of objects. + +\image html using_notebook_smesh.png "Setting of variables in SALOME NoteBook" + +\image html addnode_notebook.png "Use of variables to add a node in MESH module" + +The following limitations on the use of variables still exist:
                • \ref radial_prism_algo_page "Distribution of Layers" hypothesis - @@ -28,6 +33,10 @@ limitations: values (indices of nodes) are correctly applied, but they are not restored after "Update study" operation.
                • \ref clipping_page "Clipping" dialog box. -
                • Colors / Size dialog box. +
                • Properties dialog box.
                + +Our TUI Scripts provide you with useful examples of +\ref tui_notebook_smesh "Using SALOME NoteBook". + */ diff --git a/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc b/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc index 01a272de2..376da99b0 100644 --- a/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc +++ b/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc @@ -17,13 +17,16 @@ right-clicking on the selected mesh. \image html dialog.png
                  +
                • Rename - allows to rename the object in the Object browser.
                • Hide all - allows to hide all objects in the viewer.
                • Update - refreshes the presentation of your mesh in the Object Browser, applying all recent changes.
                • -
                • \subpage mesh_infos_page "Mesh Infos" - provides +
                • \subpage mesh_infos_page "Mesh Information" - provides information about the mesh.
                • -
                • \ref mesh_element_info_anchor "Mesh Element Info" - provides basic -information about the selected element of the mesh.
                • +
                • \subpage find_element_by_point_page "Find Element by Point" - +allows to find all mesh elements, to which belongs a point with the +given coordinates.
                • +
                • Auto Color - switch on / off auto-assigning colors for the groups.
                • \subpage numbering_page "Numbering" - allows to display the ID numbers of all meshing elements or nodes composing your mesh in the viewer.
                • @@ -31,19 +34,27 @@ viewer. Wireframe, Shading and Nodes presentation.
                • \subpage display_entity_page "Display Entity" - allows to display Faces, Edges or both.
                • +
                • 2D Quadratic - allows to select between the representation +of quadratic edges as broken lines or as arcs
                • Orientation of faces - shows vectors of orientation of -faces of the selected mesh
                • -
                • Colors / Size - allows to select color and size of -meshes.
                • +faces of the selected mesh. The orientation vector is shown for each 2D mesh element +and for each free face of a 3D mesh element. the vector direction is calculated by +the first three nodes of the face produced by vectors n1-n2 and n1-n3. +
                • \subpage colors_size_page "Properties" - allows to define several properties, including color of elements, shrink size, ....
                • \subpage transparency_page "Transparency" - allows to change the transparency of mesh elements.
                • -
                • \subpage clipping_page "Clipping" - allows to create cross-sections of the selected objects.
                • -
                • \ref about_quality_controls_page "Controls" - graphically +
                • \ref quality_page "Controls" - graphically presents various information about meshes.
                • Hide - allows to hide the selected mesh from the viewer.
                • Show Only -allows to display only the selected mesh, hiding all other from the viewer.
                • +
                • \subpage clipping_page "Clipping" - allows to create cross-sections of the selected objects.
                • Dump view - exports an object from the viewer in bmp, png, jpg or jpeg image format.
                • -
                • Change background - allows to redefine the background color. By default it is black.
                • +
                • Change background - allows to redefine the background +color. By default it is black.
                • +
                • View Operations checkbox - allows to show/hide the +visualization toolbar in the viewer window.
                • +
                • Recording Operations - allows to show/hide the recording +toolbar in the viewer window.
                */ diff --git a/doc/salome/gui/SMESH/input/volume.doc b/doc/salome/gui/SMESH/input/volume.doc index ba99c193e..4d74fcbf0 100644 --- a/doc/salome/gui/SMESH/input/volume.doc +++ b/doc/salome/gui/SMESH/input/volume.doc @@ -9,8 +9,8 @@
                1. Display your mesh in the viewer.
                2. -
                3. Choose Controls > Volume or click "Volume" button -in the toolbar. +
                4. Choose Controls > Volume Controls > Volume or click +"Volume" button in the toolbar. \image html image145.png
                  "Volume" button
                  diff --git a/doc/salome/gui/SMESH/input/warping.doc b/doc/salome/gui/SMESH/input/warping.doc index 83bfaa3ac..86ba0c905 100644 --- a/doc/salome/gui/SMESH/input/warping.doc +++ b/doc/salome/gui/SMESH/input/warping.doc @@ -24,8 +24,8 @@ projection height ?h? to the half edge length ?l?.
                  1. Display your mesh in the viewer.
                  2. -
                  3. Choose Controls > Warping Angle or click "Warping angle" -button of the toolbar. +
                  4. Choose Controls > Face Controls > Warping Angle or click +"Warping angle" button of the toolbar. \image html image39.png
                    "Warping angle" button
                    diff --git a/doc/salome/gui/SMESH/static/doxygen.css b/doc/salome/gui/SMESH/static/doxygen.css index 88e613d23..7a2dcbde8 100755 --- a/doc/salome/gui/SMESH/static/doxygen.css +++ b/doc/salome/gui/SMESH/static/doxygen.css @@ -1,170 +1,836 @@ -H1 { - text-align: center; +/* The standard CSS for doxygen */ + +body, table, div, p, dl { + font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size: 12px; +} + +/* @group Heading Levels */ + +h1 { + font-size: 150%; +} + +h2 { + font-size: 120%; +} + +h3 { + font-size: 100%; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + padding: 2px; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code { + color: #4665A2; +} + +a.codeRef { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +.fragment { + font-family: monospace, fixed; + font-size: 105%; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.version { + border:1px solid #0000FF; + color: #CCCCCC; + font-family: Arial, Helvetica, sans-serif; + font-size: 9pt; + text-align: center; + width:100px; + -moz-border-radius: 8px; + margin: 5px; +} + +div.footer1 { + background-color: #DFE5F1; + border: 1px solid #AAAAAA; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + padding: 10px; + margin-top: 15px; +} + + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 10px; + margin-right: 10px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memItemLeft, .memItemRight, .memTemplParams { + border-top: 1px solid #C4CFE5; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.memitem { + padding: 0; + margin-bottom: 10px; +} + +.memname { + white-space: nowrap; + font-weight: bold; + margin-left: 6px; +} + +.memproto { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 8px; + border-top-left-radius: 8px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 8px; + -moz-border-radius-topleft: 8px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 8px; + -webkit-border-top-left-radius: 8px; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + +} + +.memdoc { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 2px 5px; + background-color: #FBFCFD; + border-top-width: 0; + /* opera specific markup */ + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; } -CAPTION { - font-weight: bold +.paramname { + color: #602020; + white-space: nowrap; } +.paramname em { + font-style: normal; +} + +.params, .retval, .exception, .tparams { + border-spacing: 6px 2px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + + + -/* Link in the top navbar */ -A.qindex {} +/* @end */ -A.qindexRef {} +/* @group Directory (tree) */ -/* Link to any cross-referenced Doxygen element */ -A.el { - text-decoration: none; - font-weight: bold +/* for the tree view */ + +.ftvtree { + font-family: sans-serif; + margin: 0px; +} + +/* these are for tree view when used as main index */ + +.directory { + font-size: 9pt; + font-weight: bold; + margin: 5px; } -A.elRef { - font-weight: bold +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; } -/* Link to any cross-referenced Doxygen element inside a code section - (ex: header) +/* +The following two styles can be used to replace the root node title +with an image of your choice. Simply uncomment the next two styles, +specify the name of your image and be sure to set 'height' to the +proper pixel height of your image. +*/ + +/* +.directory h3.swap { + height: 61px; + background-repeat: no-repeat; + background-image: url("yourimage.gif"); +} +.directory h3.swap span { + display: none; +} */ -A.code { - text-decoration: none; - font-weight: normal; - color: #4444ee + +.directory > h3 { + margin-top: 0; +} + +.directory p { + margin: 0px; + white-space: nowrap; +} + +.directory div { + display: none; + margin: 0px; +} + +.directory img { + vertical-align: -30%; +} + +/* these are for tree view when not used as main index */ + +.directory-alt { + font-size: 100%; + font-weight: bold; +} + +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +.directory-alt > h3 { + margin-top: 0; +} + +.directory-alt p { + margin: 0px; + white-space: nowrap; +} + +.directory-alt div { + display: none; + margin: 0px; +} + +.directory-alt img { + vertical-align: -30%; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; +} + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + padding-left: 5px; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.title { + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +dl +{ + padding: 0 0 0 10px; +} + +dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug +{ + border-left:4px solid; + padding: 0 0 0 6px; +} + +dl.note +{ + border-color: #D0D000; +} + +dl.warning, dl.attention +{ + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + border-color: #00D000; +} + +dl.deprecated +{ + border-color: #505050; } -A.codeRef { - font-weight: normal; - color: #4444ee +dl.todo +{ + border-color: #00C0E0; } -A:hover { - text-decoration: none; - background-color: lightblue +dl.test +{ + border-color: #3030E0; } -DL.el { - margin-left: -1cm +dl.bug +{ + border-color: #C08050; } -/* A code fragment (ex: header) */ -DIV.fragment { - width: 100%; - border: none; - background-color: #CCCCCC +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + background-color: #175783; + border: 1px solid; + height: 80px; + background-repeat: no-repeat; +/* font: 300% arial,sans-serif;*/ + margin: 0px; + padding: 0px; +} + +#projectbrief +{ + font: 120% arial,sans-serif; + margin: 0px; + padding: 0px; } -/* In the alpha list (coumpound index), style of an alphabetical index letter */ -DIV.ah { - background-color: #CCCCCC; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px +#projectnumber +{ + font: 50% arial,sans-serif; + margin: 0px; + padding: 0px; } -/* Method name (+ type) */ -TD.md { - background-color: lightblue; - font-weight: bold; +#titlearea +{ + background: url("head.png"); + background-color: #175783; + border: 1px solid; + height: 80px; + background-repeat: no-repeat; + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; } -/* Method parameter (some of them) */ -TD.mdname1 { - background-color: lightblue; - font-weight: bold; color: #602020; -} - -/* Method parameter (some of them) */ -TD.mdname { - background-color: lightblue; - font-weight: bold; - color: #602020; - width: 600px; -} - -/* Separator between methods group (usually empty, seems not supported by IE) */ -DIV.groupHeader { - margin-left: 16px; - margin-top: 12px; - margin-bottom: 6px; - font-weight: bold -} - -DIV.groupText { - margin-left: 16px; - font-style: italic; - font-size: smaller -} - -BODY { - background: #FFFFFF; -} - -/*div.div-page { - background-color: #FFFFFF; - margin-left: 1em; - margin-right: 1em; - margin-top: 1em; - margin-bottom: 0.1em; - - padding-left: 1em; - padding-right: 1em; - padding-top: 0.5em; - padding-bottom: 0.5em; - - border: 2px solid #0D299A; - border-width: 2px; - border-color: #0D299A; -}*/ - -div.tabs { - text-align: justify; - margin-left : 2px; - margin-right : 2px; - margin-top : 2px; - margin-bottom : 2px - font-weight: bold; - color: #FFFFFF; -} - -DIV.div-footer { - margin-left: 1em; - margin-right: 1em; - margin-bottom: 0.2em; - text-align: right; - font-size: 9pt; -} - -/* In File List, Coumpound List, etc, 1st column of the index */ -TD.indexkey { - background-color: #CCCCCC; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} - -/* In File List, Coumpound List, etc, 2nd column of the index */ -TD.indexvalue { - background-color: #CCCCCC; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} - -span.keyword { color: #008000 } -span.keywordtype { color: #604020 } -span.keywordflow { color: #e08000 } -span.comment { color: #800000 } -span.preprocessor { color: #806020 } -span.stringliteral { color: #002080 } -span.charliteral { color: #008080 } diff --git a/doc/salome/gui/SMESH/static/footer.html b/doc/salome/gui/SMESH/static/footer.html index 9211d570f..4c89a2ba1 100755 --- a/doc/salome/gui/SMESH/static/footer.html +++ b/doc/salome/gui/SMESH/static/footer.html @@ -1,10 +1,12 @@ - - - - - -
                    -
                    Copyright © 2003-2009 CEA, EDF
                    -
                    +
                  5. + + +
                    +
                    + Copyright © 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
                    + Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
                    +
                    +
                    + \ No newline at end of file diff --git a/doc/salome/gui/SMESH/static/header.html b/doc/salome/gui/SMESH/static/header.html deleted file mode 100755 index a70a95e30..000000000 --- a/doc/salome/gui/SMESH/static/header.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - $title - - -
                    -
                    -SALOME documentation central -
                    -
                    diff --git a/doc/salome/gui/SMESH/static/header.html.in b/doc/salome/gui/SMESH/static/header.html.in new file mode 100755 index 000000000..4571b4363 --- /dev/null +++ b/doc/salome/gui/SMESH/static/header.html.in @@ -0,0 +1,20 @@ + + + + + +$title + +$treeview +$search +$mathjax + + + + +
                    +
                    Version: @VERSION@
                    + +
                    diff --git a/doc/salome/gui/SMESH/static/header_py.html.in b/doc/salome/gui/SMESH/static/header_py.html.in new file mode 100644 index 000000000..61414bb57 --- /dev/null +++ b/doc/salome/gui/SMESH/static/header_py.html.in @@ -0,0 +1,21 @@ + + + + + +$title + +$treeview +$search +$mathjax + + + + +
                    +
                    Version: @VERSION@
                    + + +
                    diff --git a/doc/salome/tui/Makefile.am b/doc/salome/tui/Makefile.am index b8cd5eee5..987d26a43 100644 --- a/doc/salome/tui/Makefile.am +++ b/doc/salome/tui/Makefile.am @@ -1,39 +1,32 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : Makefile.in # Author : Vasily Rusyaev (Open Cascade NN) # Module : doc # include $(top_srcdir)/adm_local/unix/make_common_starter.am -EXTRA_DIST += images static - -dist_doc_DATA = \ - extra/AddNetgenInSalome2.pdf \ - extra/AddNetgenInSalome2.ps \ - extra/AddNetgenInSalome2.sxw \ - extra/PluginMeshers.html +EXTRA_DIST += input images static/doxygen.css static/footer.html -EXTRA_DIST += extra/PluginMeshers.txt +tuidocdir = $(docdir)/tui/SMESH +tuidoc_DATA = images/head.png images/smeshscreen.png dev_docs: doxyfile echo "Running doxygen in directory: "`pwd`; \ @@ -49,4 +42,13 @@ install-data-local: fi; uninstall-local: - rm -rf $(DESTDIR)$(docdir)/tui/SMESH + @test -d $(DESTDIR)$(tuidocdir) && chmod -R +w $(DESTDIR)$(tuidocdir) ; \ + for filen in `find $(DESTDIR)$(tuidocdir) -mindepth 1 -maxdepth 1` dummy ; do \ + case $${filen} in \ + dummy ) ;; \ + $(DESTDIR)$(tuidocdir)/docutils ) ;; \ + $(DESTDIR)$(tuidocdir)/head.png ) ;; \ + $(DESTDIR)$(tuidocdir)/smeshscreen.png ) ;; \ + * ) echo "removing $${filen}" && rm -rf $${filen} ;; \ + esac ; \ + done diff --git a/doc/salome/tui/doxyfile.in b/doc/salome/tui/doxyfile.in index bd927280e..a4143bfee 100755 --- a/doc/salome/tui/doxyfile.in +++ b/doc/salome/tui/doxyfile.in @@ -1,37 +1,36 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# Doxyfile 1.4.6 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = "Mesh Module Programming Guide v.@VERSION@" +PROJECT_NAME = "SALOME Mesh Module Developer" PROJECT_NUMBER = OUTPUT_DIRECTORY = SMESH CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = NO +REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = YES INLINE_INHERITED_MEMB = YES @@ -40,6 +39,7 @@ STRIP_FROM_PATH = @top_srcdir@ @top_builddir@ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES @@ -69,7 +69,7 @@ CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES -SORT_MEMBER_DOCS = NO +SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES @@ -91,7 +91,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = +WARN_LOGFILE = log.txt #--------------------------------------------------------------------------- # configuration options related to the input files @@ -99,8 +99,9 @@ WARN_LOGFILE = INPUT = @top_srcdir@/src \ @top_srcdir@/bin \ @top_srcdir@/idl \ - @top_builddir@/bin -FILE_PATTERNS = *.idl *.hxx *.cxx *.h *.c *.hh *.cc @DOXYGEN_PYTHON_EXTENSION@ + @top_builddir@/bin \ + @srcdir@/input +FILE_PATTERNS = *.idl *.hxx *.cxx *.h *.c *.hh *.cc @DOXYGEN_PYTHON_EXTENSION@ *.doc RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO @@ -116,19 +117,19 @@ FILTER_SOURCE_FILES = YES #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO +SOURCE_BROWSER = YES +INLINE_SOURCES = YES STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO +REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES -USE_HTAGS = NO +#USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 3 +COLS_IN_ALPHA_INDEX = 2 IGNORE_PREFIX = #--------------------------------------------------------------------------- @@ -137,7 +138,7 @@ IGNORE_PREFIX = GENERATE_HTML = YES HTML_OUTPUT = . HTML_FILE_EXTENSION = .html -HTML_HEADER = @srcdir@/static/myheader.html +HTML_HEADER = @builddir@/static/header.html HTML_FOOTER = @srcdir@/static/footer.html HTML_STYLESHEET = @srcdir@/static/doxygen.css HTML_ALIGN_MEMBERS = YES @@ -145,8 +146,8 @@ GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO -BINARY_TOC = YES -TOC_EXPAND = YES +BINARY_TOC = NO +TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO @@ -212,14 +213,14 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = NO +SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references @@ -238,26 +239,29 @@ HIDE_UNDOC_RELATIONS = NO HAVE_DOT = YES CLASS_GRAPH = YES COLLABORATION_GRAPH = NO -GROUP_GRAPHS = NO +GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = NO +INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = jpg +DOT_IMAGE_FORMAT = png +DOT_FONTNAME = Arial DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1200 -MAX_DOT_GRAPH_DEPTH = 0 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = NO +GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO + + diff --git a/doc/salome/tui/extra/AddNetgenInSalome2.pdf b/doc/salome/tui/extra/AddNetgenInSalome2.pdf deleted file mode 100644 index d736a6ded..000000000 Binary files a/doc/salome/tui/extra/AddNetgenInSalome2.pdf and /dev/null differ diff --git a/doc/salome/tui/extra/AddNetgenInSalome2.ps b/doc/salome/tui/extra/AddNetgenInSalome2.ps deleted file mode 100644 index a81aa9658..000000000 --- a/doc/salome/tui/extra/AddNetgenInSalome2.ps +++ /dev/null @@ -1,13935 +0,0 @@ -%!PS-Adobe-3.0 -%%BoundingBox: 0 0 595 842 -%%Creator: OpenOffice.org 1.0.2 -%%For: nadir -%%CreationDate: Tue Dec 9 10:49:18 2003 -%%Title: Proc?dure de rajout de DATA dans le produit SalomePro -%%LanguageLevel: 2 -%%DocumentData: Clean7Bit -%%Pages: (atend) -%%PageOrder: Ascend -%%EndComments -%%BeginProlog -/ISO1252Encoding [ -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef -/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle -/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash -/zero /one /two /three /four /five /six /seven -/eight /nine /colon /semicolon /less /equal /greater /question -/at /A /B /C /D /E /F /G -/H /I /J /K /L /M /N /O -/P /Q /R /S /T /U /V /W -/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore -/grave /a /b /c /d /e /f /g -/h /i /j /k /l /m /n /o -/p /q /r /s /t /u /v /w -/x /y /z /braceleft /bar /braceright /asciitilde /unused -/Euro /unused /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl -/circumflex /perthousand /Scaron /guilsinglleft /OE /unused /Zcaron /unused -/unused /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash -/tilde /trademark /scaron /guilsinglright /oe /unused /zcaron /Ydieresis -/space /exclamdown /cent /sterling /currency /yen /brokenbar /section -/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron -/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered -/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown -/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla -/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis -/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply -/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls -/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla -/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis -/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide -/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] def - -/psp_definefont { exch dup findfont dup length dict begin { 1 index /FID ne -{ def } { pop pop } ifelse } forall /Encoding 3 -1 roll def -currentdict end exch pop definefont pop } def - -/pathdict dup 8 dict def load begin -/rcmd { { currentfile 1 string readstring pop 0 get dup 32 gt { exit } -{ pop } ifelse } loop dup 126 eq { pop exit } if 65 sub dup 16#3 and 1 -add exch dup 16#C and -2 bitshift 16#3 and 1 add exch 16#10 and 16#10 -eq 3 1 roll exch } def -/rhex { dup 1 sub exch currentfile exch string readhexstring pop dup 0 -get dup 16#80 and 16#80 eq dup 3 1 roll { 16#7f and } if 2 index 0 3 --1 roll put 3 1 roll 0 0 1 5 -1 roll { 2 index exch get add 256 mul } -for 256 div exch pop exch { neg } if } def -/xcmd { rcmd exch rhex exch rhex exch 5 -1 roll add exch 4 -1 roll add -1 index 1 index 5 -1 roll { moveto } { lineto } ifelse } def end -/readpath { 0 0 pathdict begin { xcmd } loop end pop pop } def - -systemdict /languagelevel known not { -/xshow { exch dup length 0 1 3 -1 roll 1 sub { dup 3 index exch get -exch 2 index exch get 1 string dup 0 4 -1 roll put currentpoint 3 -1 -roll show moveto 0 rmoveto } for pop pop } def -/rectangle { 4 -2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0 -rlineto closepath } def -/rectfill { rectangle fill } def -/rectstroke { rectangle stroke } def } if - -/psp_lzwfilter { currentfile /ASCII85Decode filter /LZWDecode filter } def -/psp_ascii85filter { currentfile /ASCII85Decode filter } def -/psp_lzwstring { psp_lzwfilter 1024 string readstring } def -/psp_ascii85string { psp_ascii85filter 1024 string readstring } def -/psp_imagedict { -/psp_bitspercomponent { 3 eq { 1 }{ 8 } ifelse } def -/psp_decodearray { [ [0 1 0 1 0 1] [0 255] [0 1] [0 255] ] exch get } -def 7 dict dup -/ImageType 1 put dup -/Width 7 -1 roll put dup -/Height 5 index put dup -/BitsPerComponent 4 index psp_bitspercomponent put dup -/Decode 5 -1 roll psp_decodearray put dup -/ImageMatrix [1 0 0 1 0 0] dup 5 8 -1 roll put put dup -/DataSource 4 -1 roll 1 eq { psp_lzwfilter } { psp_ascii85filter } ifelse put -} def -%%EndProlog -%%Page: 0 0 -%%PageBoundingBox: 18 18 577 824 -%%BeginSetup -% -%%BeginFeature: *PageSize A4 -<> setpagedevice -%%EndFeature -%%EndSetup -%%BeginPageSetup -% -gsave -[0.24 0 0 -0.24 18 824] concat -gsave -%%EndPageSetup -%%BeginResource: font NimbusMonL-Regu -%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle 0.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-Regu def -/PaintType 0 def -/WMode 0 def -/FontBBox {-12 -237 650 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020945 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 -5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E -6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 -87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B -A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 -643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 -C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 -F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 -FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E -61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 -4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C -CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 -2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA -A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC -0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 -4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 -FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 -61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 -3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 -1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 -72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B -B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A -36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC -40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A -4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 -46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 -D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB -B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F -8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 -4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C -F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C -BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB -C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 -966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 -998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 -CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E -C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 -D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 -1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF -1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 -A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 -583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 -7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 -9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 -77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 -7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 -45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 -C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 -EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 -077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 -E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B -1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 -27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 -F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 -FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B -6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 -2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 -FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 -A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 -23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 -56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 -5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF -13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F -FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C -3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 -2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 -C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F -1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 -88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 -8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE -FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA -D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC -2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C -9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F -D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A -EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 -F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 -67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 -A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 -9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D -183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 -BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 -4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 -556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 -1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 -F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 -2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C -FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F -ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 -2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC -ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 -2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 -298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 -BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 -47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE -48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C -BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 -5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 -55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 -2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 -4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D -8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D -69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A -AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE -61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B -834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 -E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D -E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F -46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 -A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 -F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E -185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 -7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 -6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 -B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C -D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 -606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F -AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E -064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C -FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE -874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD -060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C -AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D -D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 -A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE -528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A -302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 -934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 -57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 -71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 -D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 -B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 -48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 -21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 -B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 -CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED -DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 -718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 -5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F -E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC -41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 -5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 -7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 -D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 -D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 -4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC -1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 -374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 -E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF -4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 -AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E -4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 -858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB -EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 -BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F -45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E -050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED -199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 -7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE -B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC -91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 -905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 -E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 -81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 -B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 -9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B -470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 -627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 -2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E -BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 -9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 -8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 -1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 -4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E -06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 -65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 -C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 -52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE -64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 -C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 -17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 -C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE -2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF -1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 -03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 -88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 -37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 -F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 -6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 -59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 -EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E -2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 -24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C -F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE -400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 -1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 -9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 -DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB -7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 -F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F -E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B -727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE -58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 -840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 -EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 -CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A -622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 -D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C -91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 -7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C -5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 -FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E -DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 -54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A -E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD -F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 -A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A -623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA -891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 -7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 -FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B -92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F -01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 -B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 -4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 -F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB -45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 -31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 -FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE -537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E -7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 -9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 -E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D -CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB -9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 -3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F -B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA -A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 -6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 -97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 -4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 -39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 -BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A -C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 -1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 -2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 -8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 -9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 -351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 -3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB -7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 -5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 -3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF -F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 -B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 -7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 -801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 -AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 -9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 -B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 -8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 -014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C -46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C -CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 -6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 -55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 -1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 -141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 -F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 -F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 -F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A -E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 -53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B -31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE -C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D -B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 -723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 -04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 -FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F -2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 -03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A -065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 -6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 -C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E -AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB -E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 -98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C -35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE -A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 -E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 -5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 -B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 -79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 -67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 -8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 -5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 -FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 -9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 -ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 -56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB -384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 -6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 -0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 -12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 -40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 -148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C -AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 -DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 -2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A -457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E -5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A -955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF -F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 -4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A -0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C -44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 -289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 -247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 -CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C -2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 -1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 -F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 -BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 -51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF -28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F -AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 -2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 -2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 -070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D -9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E -3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC -FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 -1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F -C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 -EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D -DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 -0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 -B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C -5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 -7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 -9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 -F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB -AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 -6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB -78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE -F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D -92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 -9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 -E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 -68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE -FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA -304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE -2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 -3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 -02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A -7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B -94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A -1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 -81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D -83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 -01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D -C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 -26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 -860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 -C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 -18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 -2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 -CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 -E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF -2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 -2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E -67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E -E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 -8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA -774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A -53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 -1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 -5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 -389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F -5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 -B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE -7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 -703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 -5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB -250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF -6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 -782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 -FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 -6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 -39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 -3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 -36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 -0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 -5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 -1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 -AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D -EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF -E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 -03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF -4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB -D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B -E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 -71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 -1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 -1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 -84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 -6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 -0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 -2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 -9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD -02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 -F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 -5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC -7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 -F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 -9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C -C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB -85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 -048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED -22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB -41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 -27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 -DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB -388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 -4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 -7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 -343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 -C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 -BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 -5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F -5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 -25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 -AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 -9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 -66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 -29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 -39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D -F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A -279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D -A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 -09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F -2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 -AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 -F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 -1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 -FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF -5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 -961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A -BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA -40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 -08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B -472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 -3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C -87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 -0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D -5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 -FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA -2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 -2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 -15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 -A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C -250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C -8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 -C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE -F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C -9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 -B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 -56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF -A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 -BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 -CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 -175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 -7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A -FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 -E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 -6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 -AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 -4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 -08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B -F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 -958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF -EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 -15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 -CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F -B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 -2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 -8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 -1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 -7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 -D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 -9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E -84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 -C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E -8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC -3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 -AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC -806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 -64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C -ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D -1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E -565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD -540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD -093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B -FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 -2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D -BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 -EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C -C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A -2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 -C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 -F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 -89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B -169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 -ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D -20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 -B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D -E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE -6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC -31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 -33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B -7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C -B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 -4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC -1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 -89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C -212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA -34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 -D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 -38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 -DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 -8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 -212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 -3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 -F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 -1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 -12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 -9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 -B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 -5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 -564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 -5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D -867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 -53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 -3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B -451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C -B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 -CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 -C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 -E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF -64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 -8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 -AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 -BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 -A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 -990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D -B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 -4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 -84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C -F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 -D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 -37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 -D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 -EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 -FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A -DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 -62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 -54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB -AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 -0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 -4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 -2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C -2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC -F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 -BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 -D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 -C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF -46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 -50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED -49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D -20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F -BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A -977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 -EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF -56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 -CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF -3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 -B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 -062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 -D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE -3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 -940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD -6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F -E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 -F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 -DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F -5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D -7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 -695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 -C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 -8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 -39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 -3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD -2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 -6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 -5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C -5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF -B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 -06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 -1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 -6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 -4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 -0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 -B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 -E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A -1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 -354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 -9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 -BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 -F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 -9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 -54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D -092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 -741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 -57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 -C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 -7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 -3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 -82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 -C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 -615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 -B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 -A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 -9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 -FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 -EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F -818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C -715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 -8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 -1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 -707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 -4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D -54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 -2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 -15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 -63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B -81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 -CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 -E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB -2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 -E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 -B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 -AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 -3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A -04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 -151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 -E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 -26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 -3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 -772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF -27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E -DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 -898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 -AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F -C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 -CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D -59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 -4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 -3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 -FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 -90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC -167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 -573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F -C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E -96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 -2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 -7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC -B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E -E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 -51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F -025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 -2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF -C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F -E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 -EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F -DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 -E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 -E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF -C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D -84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C -61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 -33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 -C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 -1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D -CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C -984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 -8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 -596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 -A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 -015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC -0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF -27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 -0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 -46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 -1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 -33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A -77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 -75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 -749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD -77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF -2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 -1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 -703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D -A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 -907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB -9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 -782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 -B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A -A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 -4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 -1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE -2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B -50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 -CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC -39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 -FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE -9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 -E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 -533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D -CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 -8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA -AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 -0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 -8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 -1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E -98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 -F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E -5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 -A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA -3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA -5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 -04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB -84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C -C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB -76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 -27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 -01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE -7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 -6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A -3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F -C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A -9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C -53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 -D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 -92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 -1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 -7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 -009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE -B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F -F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 -789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 -50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF -76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 -AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 -897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 -9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 -5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F -86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 -A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 -F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F -FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 -DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD -77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 -1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F -518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 -47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 -7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A -CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A -B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 -DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 -B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C -33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 -1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 -904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE -17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A -79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF -00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E -BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF -B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 -0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B -E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F -1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E -0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 -0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 -5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 -3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 -81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB -1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 -963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 -4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 -86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 -7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 -2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 -6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B -37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 -84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 -B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 -402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 -C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 -B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 -88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 -49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B -B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 -ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 -5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB -6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 -D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F -E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 -D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB -CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 -5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 -D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D -605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 -3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 -5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A -807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 -FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A -4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 -B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A -CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 -205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 -38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 -F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE -263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 -E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF -207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA -D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC -3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 -66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D -B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E -6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 -EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF -9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC -D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 -860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 -B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 -A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D -9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 -FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 -584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 -6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 -EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 -5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 -4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 -D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E -933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 -7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 -CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF -F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A -DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 -611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 -DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 -40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F -AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE -8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B -C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 -AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 -1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 -C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 -749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 -B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C -CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 -83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B -35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E -A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F -A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 -4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A -B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 -58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D -F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A -69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 -7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 -748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E -5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 -81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 -236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A -9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF -CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 -ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA -26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB -17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 -ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 -60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 -6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 -9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 -4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC -B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 -7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA -00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 -5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB -625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 -38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE -2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 -3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 -79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 -799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A -80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 -411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 -BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 -D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 -D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 -42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 -70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 -B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 -00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 -E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B -A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 -44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D -ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 -3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A -3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 -E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C -9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 -238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 -EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 -7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D -324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 -B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D -B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE -F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD -99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 -A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 -7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A -CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C -A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 -2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 -A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 -B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC -7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 -D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D -057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE -D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 -6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 -8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A -CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 -41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F -01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 -31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 -3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 -696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 -36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB -D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD -0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 -CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB -012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 -006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 -B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 -9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 -85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 -024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 -75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 -CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 -6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A -83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 -4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 -1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A -A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 -E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F -26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 -C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 -9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA -98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 -EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C -2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC -B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 -2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 -10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 -DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 -E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 -7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 -73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E -9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 -EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C -0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 -363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 -6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 -EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 -E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 -09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 -1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 -0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B -195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 -AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 -D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 -05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 -FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A -BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E -2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F -2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B -913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B -C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 -BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F -9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA -112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 -4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 -D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 -292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA -8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 -6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA -F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 -FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 -A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 -1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D -09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 -39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A -6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B -E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 -4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D -8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 -C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C -31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E -0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC -9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 -B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 -BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 -3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 -1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD -F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 -A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 -B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F -FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E -81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 -5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 -1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 -B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C -29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 -8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 -97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A -D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 -3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 -D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE -41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB -44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 -B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A -69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 -84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E -749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 -9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 -D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 -86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 -70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC -151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 -3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE -4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 -CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 -347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E -D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B -BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF -FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E -C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E -D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF -C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE -1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 -859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD -BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA -D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 -1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 -4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D -430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 -A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC -089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 -BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 -143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 -2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 -12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 -331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 -07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 -5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B -1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 -24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 -1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 -FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 -8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 -5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 -FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 -E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 -9F08ABD4F4B0889283E55500702185A841E328 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -/Times-Bold-iso1252 /Times-Bold ISO1252Encoding psp_definefont -/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont -/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont -253 283 moveto -0 0 0 setrgbcolor -/Times-Bold-iso1252 findfont 67 -67 matrix scale makefont setfont -<50726F63E9647572652064652072616A6F75742065742064652074657374206475206D61696C6C -6575722074E974726168E9647269717565204E657467656E> -show -403 361 moveto -<64616E73206C65206D6F64756C6520534D455348206465206C27656E7669726F6E6E656D656E74 -2053616C6F6D652032> -show -220 439 moveto -<202020202020> -show -220 508 moveto -/Times-Bold-iso1252 findfont 58 -58 matrix scale makefont setfont -<20202020205072E9616C61626C65733A> -show -295 566 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4F6E20737570706F736520717565204E657467656E206120E974E920696E7374616C6CE9206461 -6E73206C6120636F6E66696775726174696F6E2073756976616E7465> -show -1647 566 moveto -<20> -show -1659 566 moveto -<3A> -show -312 683 moveto -<6C732020206E657467656E5F696E7374616C6C6174696F6E5F706174682F696E636C756465> -show -312 739 moveto -<6E676C69622E68> -show -312 795 moveto -<6C73206E657467656E5F696E7374616C6C6174696F6E5F706174682F6C69622F4C494E5558> -show -312 851 moveto -<6C69626373672E61202020206C6962677072696D2E61202020206C69626D6573682E6120202020 -202020202020202020206C69626F7074692E61202020202020202020206C69627669732E61> -show -312 907 moveto -<6C696267656E2E61202020206C69626C612E61202020202020202020206C69626E67696E746572 -666163652E61202020206C696273746C67656F6D2E61> -show -312 963 moveto -<6C73206E657467656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E5558> -show -312 1019 moveto -<6469616C6F672E74636C20202020202020206D656E75737461742E74636C202020206E6768656C -702E74636C202020206E672E74636C2020202020202020202020202020706172616D65746572732E -74636C202020207661726961626C65732E74636C> -show -312 1075 moveto -<64726177696E672E74636C202020206E6720202020202020202020202020202020202020206E67 -69636F6E2E74636C202020206E6776697375616C2E74636C20202020737461727475702E74636C> -show -295 1191 moveto -<6FF9206E657467656E5F696E7374616C6C6174696F6E5F7061746820657374206C612064697265 -63746F7279206427696E7374616C6C6174696F6E206465204E657467656E2E204C65732066696368 -69657273> -show -295 1247 moveto -<6E657467656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E55582F2A2E7463 -6C20736F6E74206C657320666963686965727320646520636F6D6D616E642074636C20706F757220 -70696C6F746572206C65> -show -295 1303 moveto -<6D61696C6C657572204E657467656E20E0207472617665727320736F6E2049484D2E206E657467 -656E5F696E7374616C6C6174696F6E5F706174682F62696E2F4C494E55582F6E6720657374> -show -295 1359 moveto -<6C276578E963757461626C65206465204E657467656E206176656320736F6E2049484D20656D62 -61727175E9652E204C6573206C696272616972696573202A2E612064616E73> -show -295 1415 moveto -<6E657467656E5F696E7374616C6C6174696F6E5F706174682F6C69622F4C494E55582F20646F69 -76656E7420EA74726520636F6D70696CE97320656E20656E6C6576616E74206C276F7074696F6E> -show -295 1471 moveto -<2D444F50454E474C20717569206E27657374207574696C652071756520706F7572206C27484D20 -6465204E657467656E2E204C61206C6962726169726965206C69626E67696E746572666163652E61 -20646F6974> -show -295 1528 moveto -<636F6E74656E6972206C276F626A6574206E676C69622E6F206574206E6520646F697420706173 -20636F6E74656E6972206E676E657764656C6574652E6F2E> -show -295 1640 moveto -<4C612070726F63E96475726520E02061646F707465722065737420746F757420642761626F7264 -20646520636F6D70696C6572204E657467656E2028766F6972206C6520524541444D452E494E5354 -414C4C> -show -295 1696 moveto -<76656E616E742061766563206C6120646973747269627574696F6E293B20636520717569207072 -6F6475697261206C276578E963757461626C65206E6720206C696E6BE92073746174697175656D65 -6E742061766563206C6573> -show -295 1752 moveto -<6C696272616972696573202A2E612E205075697320617072E87320696C20666175647261697420 -6D6F646966696572206C657320646966666572656E7473204D616B6566696C6520706F757220656E -6C65766572206C276F7074696F6E20> -show -295 1808 moveto -<2D444F50454E474C2C202072616A6F75746572206C276F626A6574206E676C69622E6F2C206578 -636C757265206C276F626A657420206E676E657764656C6574652E6F20E0206C61206C6962726169 -726965> -show -295 1864 moveto -<6C69626E67696E746572666163652E6120657420656E66696E207265636F6D70696C6572207365 -756C656D656E74206C6573206C6962726169726965732E> -show -343 1984 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -418 1984 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4F6E206120E0206E6F74726520646973706F736974696F6E20286465206C612070617274206465 -204E616469722920756E652061726368697665204E657467656E2E74677A20636F6E74656E616E74 -206C6573> -show -295 2044 moveto -<2020202020202020202020736F757263657320646520534D45534820717569207772617070656E -74206C657320617070656C732061757820726F7574696E6573206465204E657467656E> -show -1779 2044 moveto -<20> -show -1791 2044 moveto -<706F7572206C65> -show -295 2100 moveto -<20202020202020202020206D61696C6C6575722074E974726168E96472697175653A> -show -294 2201 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<63642053414C4F4D45325F524F4F54> -show -294 2245 moveto -<746172207A787666204E657467656E2E74677A> -show -294 2289 moveto -<2E2F534D4553485F5352432F7372632F4E455447454E2F4D616B6566696C652E696E> -show -294 2333 moveto -<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4E455447454E5F33442E63 -7878> -show -294 2377 moveto -<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4E455447454E5F33442E68 -7878> -show -294 2421 moveto -<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4D6178456C656D656E7456 -6F6C756D652E637878> -show -294 2465 moveto -<2E2F534D4553485F5352432F7372632F534D4553482F534D4553485F4D6178456C656D656E7456 -6F6C756D652E687878> -show -294 2509 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4E455447454E5F3344 -5F692E637878> -show -294 2553 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4E455447454E5F3344 -5F692E687878> -show -294 2597 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4D6178456C656D656E -74566F6C756D655F692E637878> -show -294 2641 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4D6178456C656D656E -74566F6C756D655F692E687878> -show -294 2685 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4C656E67746846726F -6D45646765735F692E637878> -show -294 2729 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F492F534D4553485F4C656E67746846726F -6D45646765735F692E687878> -show -294 2773 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F785F7465 -7472612E7079> -show -294 2816 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F78325F74 -657472612E7079> -show -294 2860 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F626F78335F74 -657472612E7079> -show -294 2904 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666978617469 -6F6E5F74657472612E7079> -show -294 2948 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666978617469 -6F6E5F686578612E7079> -show -294 2992 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F506172746974 -696F6E315F74657472612E7079> -show -294 3036 moveto -<2E2F534D4553485F5352432F7372632F534D4553485F535749472F534D4553485F666C69676874 -5F736B696E2E7079> -show -294 3080 moveto -<2E2F> -show -344 3080 moveto -<534D4553485F5352432F> -show -596 3080 moveto -<61646D5F6C6F63616C2F756E69782F636F6E6669675F66696C65732F636865636B5F4E65746765 -6E2E6D34> -show -296 634 1 457 rectfill -2109 634 1 457 rectfill -296 634 1814 1 rectfill -296 1090 1814 1 rectfill -280 2167 1 924 rectfill -2125 2167 1 924 rectfill -280 2167 1846 1 rectfill -280 3090 1846 1 rectfill -showpage -grestore grestore -%%PageTrailer - -%%Page: 1 1 -%%PageBoundingBox: 18 18 577 824 -%%BeginSetup -% -%%EndSetup -%%BeginPageSetup -% -gsave -[0.24 0 0 -0.24 18 824] concat -gsave -%%EndPageSetup -%%BeginResource: font NimbusMonL-ReguObli -%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular Oblique) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle -12.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-ReguObli def -/PaintType 0 def -/WMode 0 def -/FontBBox {-61 -237 774 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020947 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1 -94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211 -9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB -B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466 -AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1 -25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A -C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC -45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246 -D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566 -9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A -E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698 -53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736 -05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66 -5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341 -6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF -4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2 -4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482 -9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D -FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4 -DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3 -CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D -B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28 -7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A -1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68 -1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A -8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4 -16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365 -F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12 -41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22 -5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D -BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080 -65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827 -C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45 -EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559 -872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103 -AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF -8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E -1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A -7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A -DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610 -38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356 -A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F -67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5 -492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1 -5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD -A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551 -D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3 -C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252 -CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097 -60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A -F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA -37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8 -F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E -18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0 -9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118 -73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0 -837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D -9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E -9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC -85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3 -AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F -719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1 -496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88 -EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C -6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7 -37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB -F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C -D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2 -63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15 -565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE -18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E -2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841 -55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44 -58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551 -837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3 -0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE -9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C -155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8 -BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16 -8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879 -1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C -4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA -492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3 -155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704 -1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3 -5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0 -5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC -CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0 -BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E -DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311 -98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E -DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6 -F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C -93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504 -78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9 -F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F -9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4 -3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2 -52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A -A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0 -F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB -1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F -2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8 -D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD -879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319 -1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD -BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122 -007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C -5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F -013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D -BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA -6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338 -670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C -0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13 -C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172 -6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807 -91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600 -8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F -8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D -AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94 -202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E -DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68 -85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315 -70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF -80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581 -217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12 -E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA -9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519 -1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5 -3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED -B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4 -FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC -797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D -2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7 -E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364 -A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71 -8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C -BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0 -9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1 -3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B -E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75 -BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428 -4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B -69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6 -D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8 -FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387 -7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4 -A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF -51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A -DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515 -D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A -FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0 -5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A -96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB -92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF -37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812 -3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726 -62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3 -D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550 -7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752 -4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734 -B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363 -141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303 -86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83 -9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726 -B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B -737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43 -46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7 -0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9 -A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744 -69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8 -222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6 -855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF -F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1 -6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A -8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453 -3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6 -67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A -AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C -30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4 -29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04 -26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1 -3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B -667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177 -D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17 -070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180 -7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8 -C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D -E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD -E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51 -C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E -EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA -11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385 -1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C -FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8 -96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C -0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C -6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120 -835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C -5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC -7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A -78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21 -6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8 -2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099 -9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE -C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0 -DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054 -16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B -D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3 -984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA -B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33 -7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219 -1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26 -DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66 -1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA -4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27 -94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350 -45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915 -E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36 -6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5 -F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538 -B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2 -3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705 -796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8 -40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494 -44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5 -C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59 -6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14 -AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130 -6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68 -6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952 -35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7 -08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217 -4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218 -52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95 -41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C -77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8 -65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB -73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81 -234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F -982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9 -184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885 -A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD -0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34 -7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2 -E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC -AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB -8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09 -1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF -EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED -8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F -A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F -87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B -33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7 -B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559 -2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C -6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC -56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED -884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262 -348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1 -106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B -13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07 -E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30 -41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687 -F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604 -3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1 -467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95 -993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F -7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083 -4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3 -41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941 -2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F -BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F -486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8 -249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325 -D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D -4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4 -AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E -1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D -13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367 -DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020 -749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C -5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39 -0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1 -71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D -FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6 -F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4 -D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2 -182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137 -33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE -48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1 -5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA -5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C -4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173 -A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731 -5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938 -731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C -15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3 -D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E -E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7 -97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC -7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369 -DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171 -CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878 -B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343 -1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4 -7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A -FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93 -12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E -31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28 -8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35 -FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA -AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F -970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1 -837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080 -02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29 -3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E -57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5 -8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765 -EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB -43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE -5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F -7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C -39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2 -A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2 -56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158 -C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951 -23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34 -37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE -BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9 -2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9 -BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594 -6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6 -5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE -CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D -3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65 -77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B -DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7 -63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB -EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69 -B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB -438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D -7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245 -4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B -F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1 -8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2 -F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C -C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B -47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326 -6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1 -564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692 -C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24 -870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81 -1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211 -D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601 -196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0 -CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53 -41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4 -5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47 -B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD -B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947 -1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D -DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6 -A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED -5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3 -E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA -649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B -220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729 -E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7 -5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524 -4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01 -486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195 -CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2 -1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14 -50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6 -B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25 -B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F -58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7 -77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202 -42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2 -79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179 -08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101 -EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A -A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171 -0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC -50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16 -D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938 -A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B -A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476 -63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444 -5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E -4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598 -54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62 -3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C -1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC -1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269 -743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA -94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD -02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F -03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5 -403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006 -54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63 -8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67 -5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108 -DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C -2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB -197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4 -6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918 -0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C -F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D -05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC -E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E -4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC -7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717 -80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9 -4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158 -8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62 -0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF -540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6 -A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957 -270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911 -F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E -4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D -41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967 -6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654 -BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B -7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C -52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB -4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97 -146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B -D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD -52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559 -187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616 -F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174 -CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963 -4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D -0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5 -4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE -A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070 -169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72 -6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092 -402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C -EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B -77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0 -02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9 -73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421 -B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4 -D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806 -E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70 -BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A -79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7 -787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8 -88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F -F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52 -6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D -6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB -C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744 -1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296 -75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391 -26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A -0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379 -928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4 -77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806 -4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E -9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70 -89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E -E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17 -01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506 -FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735 -2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B -3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D -6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C -2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928 -C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA -35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67 -F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F -CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6 -4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714 -54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228 -603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB -2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9 -F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2 -106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC -32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA -60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431 -F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892 -370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950 -78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D -CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE -F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A -75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847 -C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A -41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1 -5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9 -5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441 -DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1 -639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A -3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464 -81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463 -DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6 -DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB -02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84 -E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54 -0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824 -16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D -F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320 -79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0 -F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF -74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8 -5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD -AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02 -DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E -7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC -0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119 -32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438 -DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97 -6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A -4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7 -A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA -ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693 -CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA -683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853 -BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3 -8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499 -907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D -403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49 -A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9 -4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C -EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2 -0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF -885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A -4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC -8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E -0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9 -8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF -E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC -2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09 -5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731 -28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1 -1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA -BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367 -4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD -E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956 -507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13 -24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35 -8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D -8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339 -E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE -0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D -25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1 -10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888 -4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2 -2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678 -9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55 -43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91 -3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E -EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E -D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B -B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2 -86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2 -376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB -76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A -5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490 -D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684 -8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842 -9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839 -0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688 -1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8 -D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674 -F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A -96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D -31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD -63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81 -0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF -DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88 -30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7 -835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E -115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A -9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C -80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63 -6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210 -C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE -CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED -8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37 -CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA -71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209 -8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA -BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E -722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C -4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC -52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2 -802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88 -A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE -43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2 -BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382 -5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3 -F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E -1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821 -4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E -34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44 -400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408 -999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E -8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436 -BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497 -5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09 -6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814 -E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F -D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8 -F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C -E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725 -EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB -009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9 -4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5 -5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5 -86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988 -A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847 -EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E -3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10 -324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E -FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495 -0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E -ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12 -8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD -4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF -CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D -DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD -B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD -D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8 -FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E -B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA -E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551 -98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9 -FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C -D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40 -19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C -2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0 -DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0 -ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B -2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C -4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C -BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C -46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E -690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A -BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399 -270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4 -9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268 -10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65 -95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3 -AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0 -9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B -D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754 -94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1 -67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8 -BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E -07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94 -D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4 -1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4 -95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA -91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D -30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE -C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B -3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7 -AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273 -38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F -9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1 -B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65 -89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B -163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2 -56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B -186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE -19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C -4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5 -03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28 -B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24 -4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34 -8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3 -71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1 -EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5 -083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31 -D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200 -458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0 -11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1 -0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C -397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560 -A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82 -0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591 -EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4 -4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C -1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033 -109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213 -18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2 -C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3 -47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605 -8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB -7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754 -E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D -AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D -5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89 -7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E -AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604 -388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C -540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2 -3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D -E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40 -61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA -73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921 -9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127 -4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A -4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6 -F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1 -BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0 -39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910 -B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314 -54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A -EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734 -EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079 -CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE -718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C -D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA -9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A -53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E -A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7 -7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237 -CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55 -311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357 -F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B -E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643 -15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C -001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0 -0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D -CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55 -AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A -ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E -77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252 -346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD -12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF -2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A -C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427 -AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B -61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0 -BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C -484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82 -94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2 -E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827 -A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE -5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12 -66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2 -B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72 -E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E -168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF -BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999 -4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA -252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B -87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C -0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074 -EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135 -ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912 -999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4 -C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA -4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152 -692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014 -69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F -F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840 -301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624 -B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E -86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1 -1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED -70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D -B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37 -5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803 -35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651 -C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A -D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A -C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528 -4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154 -02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492 -83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C -BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65 -64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738 -9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60 -7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694 -45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F -C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB -55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766 -2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1 -7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419 -5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB -1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E -17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3 -5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217 -F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A -9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120 -2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8 -ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8 -0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1 -1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006 -F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0 -000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9 -9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789 -ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B -02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963 -189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE -EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2 -C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268 -6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C -390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2 -922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8 -D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86 -70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962 -F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB -268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886 -B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9 -6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07 -A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649 -B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663 -AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F -A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA -0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816 -495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7 -E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA -D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE -B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C -0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C -7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B -6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86 -EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6 -08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6 -6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC -1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2 -E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D -3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C -122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2 -F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6 -154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954 -9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182 -B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8 -9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1 -85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47 -B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46 -E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED -839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A -9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5 -E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4 -FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D -D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A -1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278 -AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA -239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062 -3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02 -F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD -7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405 -77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA -BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C -80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09 -9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E -DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9 -703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D -F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F -6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76 -CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6 -EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A -B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306 -23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7 -3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB -01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E -93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80 -3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C -4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB -0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF -AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C -05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396 -06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB -87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA -A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69 -50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03 -AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024 -FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18 -C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777 -3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA -F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E -59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D -A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C -4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677 -206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071 -5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A -4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89 -18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6 -7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096 -84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5 -6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9 -C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9 -684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3 -70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297 -040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345 -7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37 -F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C -1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD -F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA -E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3 -3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8 -580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1 -D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6 -645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3 -7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905 -3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60 -670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0 -BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F -2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381 -1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB -CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5 -E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB -669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C -0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF -6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F -67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2 -5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657 -C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451 -CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6 -CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25 -B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C -76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1 -A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB -5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A -6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5 -AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3 -37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2 -631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639 -567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28 -47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6 -4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD -585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB -39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0 -D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF -4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F -C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B -1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2 -2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206 -CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568 -75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88 -114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B -F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338 -6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63 -9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77 -6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B -D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0 -BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49 -E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E -DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A -7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284 -89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4 -8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46 -BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8 -34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A -3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30 -43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A -D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5 -43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD -BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2 -9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7 -31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3 -5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9 -8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97 -E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1 -1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D -082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E -BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9 -3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0 -FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77 -312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2 -74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5 -B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4 -CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9 -BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1 -4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5 -9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33 -92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B -09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B -8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802 -7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0 -5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83 -4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547 -71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC -01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464 -76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76 -41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD -7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD -C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926 -E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7 -8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC -F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43 -29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5 -243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2 -1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75 -F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC -102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36 -45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20 -352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D -17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6 -6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D -EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7 -50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC -3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0 -011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5 -FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A -7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A -3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF -7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18 -218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6 -0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC -112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB -80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65 -05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5 -A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F -5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A -289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2 -F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315 -A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D -75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244 -C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B -C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B -479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8 -0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD -3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45 -1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401 -CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338 -D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A -AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1 -BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0 -DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37 -178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF -77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F -8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A -27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808 -488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D -A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D -321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A -7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB -F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE -922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526 -75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB -09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2 -BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB -B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373 -6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379 -59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62 -8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9 -21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30 -026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022 -C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E -E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF -44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1 -8A31BE4E82B384 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -%%BeginResource: font NimbusMonL-Regu -%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle 0.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-Regu def -/PaintType 0 def -/WMode 0 def -/FontBBox {-12 -237 650 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020945 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 -5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E -6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 -87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B -A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 -643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 -C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 -F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 -FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E -61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 -4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C -CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 -2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA -A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC -0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 -4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 -FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 -61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 -3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 -1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 -72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B -B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A -36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC -40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A -4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 -46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 -D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB -B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F -8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 -4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C -F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C -BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB -C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 -966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 -998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 -CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E -C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 -D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 -1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF -1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 -A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 -583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 -7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 -9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 -77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 -7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 -45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 -C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 -EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 -077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 -E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B -1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 -27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 -F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 -FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B -6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 -2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 -FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 -A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 -23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 -56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 -5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF -13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F -FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C -3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 -2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 -C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F -1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 -88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 -8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE -FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA -D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC -2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C -9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F -D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A -EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 -F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 -67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 -A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 -9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D -183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 -BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 -4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 -556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 -1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 -F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 -2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C -FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F -ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 -2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC -ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 -2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 -298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 -BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 -47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE -48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C -BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 -5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 -55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 -2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 -4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D -8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D -69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A -AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE -61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B -834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 -E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D -E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F -46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 -A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 -F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E -185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 -7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 -6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 -B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C -D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 -606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F -AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E -064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C -FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE -874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD -060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C -AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D -D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 -A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE -528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A -302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 -934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 -57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 -71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 -D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 -B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 -48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 -21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 -B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 -CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED -DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 -718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 -5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F -E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC -41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 -5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 -7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 -D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 -D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 -4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC -1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 -374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 -E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF -4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 -AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E -4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 -858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB -EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 -BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F -45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E -050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED -199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 -7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE -B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC -91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 -905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 -E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 -81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 -B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 -9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B -470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 -627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 -2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E -BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 -9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 -8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 -1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 -4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E -06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 -65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 -C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 -52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE -64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 -C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 -17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 -C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE -2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF -1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 -03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 -88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 -37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 -F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 -6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 -59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 -EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E -2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 -24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C -F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE -400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 -1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 -9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 -DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB -7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 -F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F -E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B -727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE -58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 -840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 -EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 -CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A -622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 -D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C -91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 -7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C -5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 -FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E -DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 -54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A -E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD -F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 -A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A -623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA -891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 -7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 -FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B -92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F -01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 -B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 -4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 -F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB -45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 -31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 -FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE -537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E -7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 -9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 -E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D -CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB -9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 -3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F -B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA -A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 -6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 -97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 -4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 -39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 -BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A -C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 -1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 -2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 -8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 -9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 -351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 -3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB -7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 -5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 -3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF -F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 -B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 -7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 -801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 -AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 -9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 -B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 -8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 -014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C -46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C -CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 -6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 -55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 -1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 -141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 -F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 -F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 -F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A -E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 -53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B -31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE -C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D -B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 -723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 -04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 -FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F -2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 -03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A -065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 -6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 -C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E -AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB -E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 -98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C -35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE -A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 -E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 -5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 -B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 -79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 -67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 -8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 -5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 -FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 -9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 -ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 -56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB -384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 -6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 -0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 -12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 -40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 -148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C -AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 -DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 -2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A -457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E -5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A -955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF -F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 -4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A -0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C -44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 -289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 -247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 -CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C -2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 -1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 -F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 -BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 -51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF -28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F -AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 -2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 -2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 -070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D -9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E -3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC -FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 -1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F -C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 -EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D -DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 -0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 -B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C -5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 -7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 -9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 -F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB -AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 -6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB -78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE -F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D -92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 -9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 -E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 -68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE -FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA -304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE -2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 -3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 -02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A -7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B -94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A -1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 -81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D -83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 -01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D -C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 -26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 -860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 -C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 -18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 -2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 -CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 -E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF -2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 -2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E -67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E -E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 -8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA -774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A -53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 -1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 -5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 -389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F -5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 -B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE -7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 -703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 -5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB -250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF -6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 -782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 -FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 -6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 -39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 -3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 -36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 -0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 -5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 -1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 -AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D -EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF -E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 -03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF -4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB -D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B -E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 -71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 -1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 -1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 -84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 -6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 -0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 -2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 -9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD -02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 -F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 -5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC -7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 -F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 -9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C -C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB -85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 -048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED -22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB -41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 -27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 -DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB -388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 -4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 -7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 -343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 -C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 -BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 -5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F -5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 -25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 -AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 -9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 -66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 -29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 -39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D -F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A -279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D -A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 -09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F -2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 -AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 -F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 -1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 -FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF -5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 -961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A -BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA -40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 -08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B -472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 -3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C -87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 -0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D -5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 -FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA -2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 -2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 -15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 -A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C -250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C -8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 -C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE -F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C -9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 -B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 -56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF -A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 -BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 -CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 -175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 -7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A -FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 -E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 -6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 -AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 -4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 -08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B -F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 -958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF -EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 -15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 -CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F -B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 -2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 -8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 -1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 -7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 -D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 -9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E -84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 -C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E -8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC -3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 -AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC -806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 -64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C -ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D -1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E -565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD -540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD -093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B -FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 -2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D -BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 -EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C -C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A -2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 -C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 -F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 -89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B -169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 -ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D -20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 -B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D -E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE -6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC -31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 -33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B -7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C -B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 -4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC -1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 -89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C -212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA -34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 -D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 -38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 -DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 -8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 -212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 -3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 -F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 -1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 -12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 -9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 -B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 -5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 -564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 -5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D -867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 -53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 -3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B -451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C -B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 -CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 -C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 -E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF -64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 -8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 -AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 -BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 -A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 -990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D -B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 -4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 -84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C -F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 -D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 -37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 -D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 -EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 -FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A -DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 -62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 -54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB -AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 -0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 -4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 -2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C -2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC -F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 -BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 -D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 -C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF -46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 -50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED -49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D -20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F -BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A -977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 -EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF -56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 -CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF -3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 -B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 -062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 -D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE -3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 -940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD -6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F -E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 -F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 -DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F -5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D -7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 -695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 -C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 -8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 -39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 -3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD -2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 -6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 -5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C -5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF -B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 -06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 -1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 -6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 -4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 -0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 -B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 -E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A -1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 -354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 -9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 -BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 -F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 -9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 -54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D -092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 -741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 -57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 -C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 -7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 -3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 -82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 -C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 -615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 -B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 -A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 -9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 -FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 -EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F -818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C -715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 -8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 -1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 -707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 -4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D -54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 -2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 -15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 -63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B -81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 -CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 -E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB -2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 -E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 -B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 -AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 -3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A -04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 -151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 -E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 -26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 -3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 -772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF -27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E -DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 -898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 -AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F -C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 -CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D -59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 -4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 -3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 -FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 -90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC -167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 -573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F -C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E -96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 -2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 -7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC -B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E -E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 -51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F -025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 -2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF -C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F -E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 -EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F -DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 -E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 -E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF -C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D -84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C -61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 -33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 -C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 -1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D -CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C -984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 -8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 -596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 -A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 -015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC -0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF -27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 -0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 -46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 -1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 -33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A -77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 -75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 -749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD -77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF -2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 -1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 -703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D -A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 -907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB -9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 -782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 -B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A -A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 -4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 -1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE -2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B -50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 -CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC -39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 -FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE -9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 -E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 -533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D -CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 -8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA -AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 -0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 -8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 -1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E -98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 -F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E -5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 -A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA -3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA -5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 -04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB -84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C -C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB -76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 -27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 -01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE -7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 -6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A -3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F -C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A -9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C -53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 -D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 -92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 -1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 -7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 -009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE -B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F -F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 -789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 -50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF -76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 -AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 -897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 -9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 -5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F -86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 -A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 -F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F -FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 -DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD -77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 -1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F -518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 -47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 -7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A -CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A -B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 -DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 -B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C -33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 -1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 -904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE -17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A -79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF -00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E -BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF -B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 -0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B -E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F -1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E -0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 -0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 -5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 -3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 -81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB -1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 -963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 -4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 -86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 -7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 -2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 -6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B -37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 -84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 -B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 -402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 -C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 -B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 -88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 -49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B -B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 -ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 -5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB -6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 -D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F -E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 -D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB -CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 -5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 -D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D -605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 -3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 -5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A -807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 -FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A -4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 -B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A -CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 -205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 -38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 -F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE -263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 -E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF -207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA -D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC -3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 -66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D -B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E -6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 -EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF -9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC -D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 -860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 -B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 -A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D -9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 -FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 -584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 -6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 -EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 -5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 -4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 -D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E -933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 -7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 -CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF -F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A -DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 -611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 -DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 -40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F -AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE -8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B -C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 -AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 -1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 -C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 -749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 -B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C -CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 -83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B -35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E -A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F -A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 -4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A -B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 -58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D -F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A -69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 -7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 -748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E -5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 -81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 -236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A -9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF -CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 -ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA -26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB -17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 -ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 -60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 -6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 -9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 -4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC -B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 -7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA -00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 -5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB -625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 -38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE -2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 -3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 -79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 -799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A -80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 -411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 -BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 -D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 -D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 -42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 -70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 -B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 -00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 -E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B -A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 -44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D -ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 -3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A -3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 -E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C -9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 -238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 -EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 -7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D -324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 -B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D -B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE -F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD -99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 -A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 -7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A -CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C -A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 -2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 -A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 -B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC -7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 -D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D -057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE -D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 -6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 -8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A -CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 -41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F -01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 -31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 -3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 -696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 -36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB -D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD -0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 -CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB -012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 -006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 -B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 -9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 -85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 -024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 -75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 -CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 -6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A -83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 -4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 -1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A -A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 -E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F -26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 -C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 -9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA -98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 -EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C -2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC -B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 -2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 -10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 -DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 -E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 -7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 -73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E -9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 -EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C -0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 -363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 -6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 -EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 -E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 -09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 -1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 -0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B -195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 -AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 -D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 -05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 -FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A -BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E -2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F -2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B -913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B -C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 -BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F -9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA -112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 -4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 -D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 -292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA -8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 -6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA -F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 -FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 -A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 -1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D -09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 -39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A -6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B -E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 -4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D -8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 -C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C -31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E -0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC -9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 -B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 -BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 -3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 -1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD -F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 -A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 -B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F -FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E -81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 -5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 -1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 -B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C -29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 -8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 -97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A -D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 -3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 -D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE -41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB -44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 -B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A -69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 -84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E -749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 -9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 -D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 -86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 -70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC -151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 -3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE -4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 -CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 -347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E -D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B -BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF -FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E -C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E -D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF -C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE -1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 -859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD -BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA -D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 -1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 -4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D -430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 -A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC -089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 -BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 -143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 -2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 -12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 -331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 -07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 -5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B -1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 -24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 -1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 -FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 -8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 -5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 -FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 -E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 -9F08ABD4F4B0889283E55500702185A841E328 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont -/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont -/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont -/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont -295 321 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4C61> -show -362 321 moveto -<6469726563746F7279> -show -556 321 moveto -<53414C4F4D45325F524F4F54> -show -962 321 moveto -<657374> -show -1032 321 moveto -<737570706F73E965> -show -1230 321 moveto - -show -1318 321 moveto -<6C61> -show -1369 321 moveto -<6469726563746F7279> -show -1564 321 moveto -<636F6E74656E616E74> -show -1772 321 moveto -<746F7573> -show -1870 321 moveto -<6C6573> -show -1940 321 moveto -<6D6F64756C6573> -show -295 377 moveto -<6465> -show -358 377 moveto -<6C61> -show -411 377 moveto -<706C617465666F726D65> -show -644 377 moveto -<53414C4F4D45> -show -866 377 moveto -<322E> -show -920 377 moveto -<4C6573> -show -1009 377 moveto -<6669636869657273> -show -1175 377 moveto -<2A4D6178456C656D656E74566F6C756D652A> -show -1661 377 moveto -<736F6E74> -show -1761 377 moveto -<64E96AE0> -show -1861 377 moveto -<64616E73> -show -1969 377 moveto -<6C61> -show -2021 377 moveto -<62617365> -show -295 433 moveto -<6D616973206E6520636F6E7469656E6E656E74207269656E206465207369676E696669616E742E> -show -295 551 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 551 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -659 551 moveto -<6475> -show -738 551 moveto -<66696368696572> -show -896 551 moveto -1 0 0 setrgbcolor -/NimbusMonL-ReguObli-iso1252 findfont 50 -50 matrix scale makefont setfont -<636F6E6669677572652E696E2E62617365> -show -1434 551 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -1553 551 moveto -<72616A6F75746572> -show -1737 551 moveto -<6C61> -show -1801 551 moveto -<76E972696669636174696F6E> -show -2060 551 moveto -<6475> -show -370 611 moveto -<66696368696572> -show -535 611 moveto -<696E636C756465> -show -716 611 moveto -<6E676C69622E68> -show -891 611 moveto -<6574> -show -962 611 moveto -<646573> -show -1063 611 moveto -<64696666E972656E746573> -show -1310 611 moveto -<6C696272616972696573> -show -1522 611 moveto -<4E657467656E2C> -show -1714 611 moveto -<766961> -show -1809 611 moveto -<6C65> -show -1880 611 moveto -<66696368696572> -show -2045 611 moveto -<6D34> -show -370 668 moveto -<636865636B5F4E657467656E2E6D342E> -show -309 769 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<6563686F2074657374696E67206E657467656E> -show -309 813 moveto -<6563686F202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D -2D2D2D2D2D2D2D2D2D> -show -309 857 moveto -<6563686F> -show -309 901 moveto -<434845434B5F4E455447454E> -show -309 945 moveto -<6563686F> -show -309 989 moveto -<6563686F202D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D -2D2D2D2D2D2D2D2D2D> -show -295 1106 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 1106 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E206475206669636869657220> -show -849 1106 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D616B6566696C652E696E20> -show -1087 1106 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<20> -show -1099 1106 moveto -0 0 0 setrgbcolor -<706F757220706F75766F6972207574696C69736572206C652064657373696E> -show -370 1166 moveto -<6D6573685F747265655F616C676F5F74657472612E706E672064616E73206C2749484D20646520 -534D4553482028766F6972206C61206D6F64696620E020666169726520737572> -show -370 1222 moveto -<20534D45534847554929206574206C61204272657020666C696768745F736F6C69642E62726570 -206461616E73206C65207465737420534D4553485F666C696768745F736B696E2E70792E> -show -294 1323 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<5245534F55524345535F46494C4553203D205C> -show -294 1367 moveto -<20202020202E> -show -294 1411 moveto -<20202020202E> -show -294 1455 moveto -<20202020202E> -show -294 1499 moveto -<6D6573685F747265655F616C676F5F74657472612E706E67205C> -show -294 1543 moveto -<666C696768745F736F6C69642E62726570> -show -295 1660 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 1660 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4C65206669636869657220> -show -578 1660 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<61646D> -show -664 1660 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -677 1660 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<756E69782F6D616B655F636F6D6D656E63652E696E202020> -show -1207 1660 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<646F697420617573736920EA747265206D6F64696669E920E02063657474652066696E> -show -1862 1660 moveto -<20> -show -1874 1660 moveto -<3A> -show -309 1765 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<69666571202840574954484E455447454E402C79657329> -show -309 1809 moveto -<202041434C4F43414C5F535243202B3D20636865636B5F6E657467656E2E6D34> -show -309 1853 moveto -<656E646966> -show -295 1971 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 1971 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -662 1971 moveto -<6475> -show -744 1971 moveto -<66696368696572> -show -905 1971 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F535243> -show -1178 1971 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1190 1971 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<737263> -show -1251 1971 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1264 1971 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D616B6566696C652E696E> -show -1552 1971 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -1675 1971 moveto -<72616A6F75746572> -show -1861 1971 moveto -<6C61> -show -1928 1971 moveto -<6469726563746F7279> -show -370 2031 moveto -<4E455447454E> -show -592 2031 moveto -<6FF9> -show -664 2031 moveto -<6C61> -show -723 2031 moveto -<6C6962726169726965> -show -904 2031 moveto -<64796E616D69717565> -show -1149 2031 moveto -<6C69624E455447454E2E736F> -show -1481 2031 moveto -<7661> -show -1550 2031 moveto - -show -1648 2031 moveto -<636F6E73747275697465> -show -1868 2031 moveto - -show -1912 2031 moveto -<706172746972> -show -2043 2031 moveto -<646573> -show -370 2087 moveto -<6C69627261697269657320737461746963206465204E657467656E2E> -show -294 2188 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<69666571202840574954484E455447454E402C79657329> -show -294 2232 moveto -<2020534244495253203D204F424A45435420534D445320534D4553484453204472697665722044 -72697665724D45442044726976657244415420447269766572554E56205C> -show -294 2276 moveto -<20202020202020202020204D45464953544F204E455447454E20534D45534820534D4553485F49 -20534D45534846696C7465727353656C656374696F6E20534D455348475549205C> -show -294 2320 moveto -<2020202020202020202020534D4553485F53574947> -show -294 2364 moveto -<656E646966> -show -295 2481 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 2481 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -665 2481 moveto -<6475> -show -750 2481 moveto -<66696368696572> -show -915 2481 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F535243> -show -1187 2481 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1200 2481 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<737263> -show -1261 2481 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1274 2481 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D455348> -show -1432 2481 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1445 2481 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D616B6566696C652E696E> -show -1738 2481 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -1864 2481 moveto -<72616A6F75746572> -show -2054 2481 moveto -<6C6573> -show -370 2541 moveto -<6669636869657273> -show -541 2541 moveto -<717569> -show -626 2541 moveto -<7772617070656E74> -show -834 2541 moveto -<6C6573> -show -910 2541 moveto -<617070656C73> -show -1059 2541 moveto -<6175> -show -1128 2541 moveto -<6D61696C6C657572> -show -1315 2541 moveto -<74E974726168E9647269717565> -show -1600 2541 moveto -<6465> -show -1669 2541 moveto -<4E657467656E> -show -1835 2541 moveto -<6574> -show -1893 2541 moveto -<6C6573> -show -1969 2541 moveto -<626F6E6E6573> -show -370 2597 moveto -<6F7074696F6E7320646520636F6D70696C6174696F6E2F6C696E6B6167652E> -show -294 2698 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<69666571202840574954484E455447454E402C79657329> -show -294 2742 moveto -<20204558504F52545F48454144455253202B3D20534D4553485F4E455447454E5F33442E687878> -show -294 2786 moveto -<20204C49425F535243202B3D20534D4553485F4E455447454E5F33442E637878> -show -294 2830 moveto -<20204E455447454E5F494E434C554445533D404E455447454E5F494E434C5544455340> -show -294 2874 moveto -<2020435050464C414753202B3D2024284E455447454E5F494E434C5544455329> -show -294 2918 moveto -<2020435858464C414753202B3D2024284E455447454E5F494E434C5544455329> -show -294 2962 moveto -<20204C44464C414753202B3D202D6C4E455447454E> -show -294 3006 moveto -<656E646966> -show -295 735 1 264 rectfill -2125 735 1 264 rectfill -295 735 1831 1 rectfill -295 998 1831 1 rectfill -280 1289 1 265 rectfill -2125 1289 1 265 rectfill -280 1289 1846 1 rectfill -280 1553 1846 1 rectfill -295 1732 1 132 rectfill -2125 1732 1 132 rectfill -295 1732 1831 1 rectfill -295 1863 1831 1 rectfill -280 2154 1 220 rectfill -2125 2154 1 220 rectfill -280 2154 1846 1 rectfill -280 2373 1846 1 rectfill -280 2665 1 352 rectfill -2125 2665 1 352 rectfill -280 2665 1846 1 rectfill -280 3016 1846 1 rectfill -showpage -grestore grestore -%%PageTrailer - -%%Page: 2 2 -%%PageBoundingBox: 18 18 577 824 -%%BeginSetup -% -%%EndSetup -%%BeginPageSetup -% -gsave -[0.24 0 0 -0.24 18 824] concat -gsave -%%EndPageSetup -%%BeginResource: font NimbusMonL-Regu -%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle 0.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-Regu def -/PaintType 0 def -/WMode 0 def -/FontBBox {-12 -237 650 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020945 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 -5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E -6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 -87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B -A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 -643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 -C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 -F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 -FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E -61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 -4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C -CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 -2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA -A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC -0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 -4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 -FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 -61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 -3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 -1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 -72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B -B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A -36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC -40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A -4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 -46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 -D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB -B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F -8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 -4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C -F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C -BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB -C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 -966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 -998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 -CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E -C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 -D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 -1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF -1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 -A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 -583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 -7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 -9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 -77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 -7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 -45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 -C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 -EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 -077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 -E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B -1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 -27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 -F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 -FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B -6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 -2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 -FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 -A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 -23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 -56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 -5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF -13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F -FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C -3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 -2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 -C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F -1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 -88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 -8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE -FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA -D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC -2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C -9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F -D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A -EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 -F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 -67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 -A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 -9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D -183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 -BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 -4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 -556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 -1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 -F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 -2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C -FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F -ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 -2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC -ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 -2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 -298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 -BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 -47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE -48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C -BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 -5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 -55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 -2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 -4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D -8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D -69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A -AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE -61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B -834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 -E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D -E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F -46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 -A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 -F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E -185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 -7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 -6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 -B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C -D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 -606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F -AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E -064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C -FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE -874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD -060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C -AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D -D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 -A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE -528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A -302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 -934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 -57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 -71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 -D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 -B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 -48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 -21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 -B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 -CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED -DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 -718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 -5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F -E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC -41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 -5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 -7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 -D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 -D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 -4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC -1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 -374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 -E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF -4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 -AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E -4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 -858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB -EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 -BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F -45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E -050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED -199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 -7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE -B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC -91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 -905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 -E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 -81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 -B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 -9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B -470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 -627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 -2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E -BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 -9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 -8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 -1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 -4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E -06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 -65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 -C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 -52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE -64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 -C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 -17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 -C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE -2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF -1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 -03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 -88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 -37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 -F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 -6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 -59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 -EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E -2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 -24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C -F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE -400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 -1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 -9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 -DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB -7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 -F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F -E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B -727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE -58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 -840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 -EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 -CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A -622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 -D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C -91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 -7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C -5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 -FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E -DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 -54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A -E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD -F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 -A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A -623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA -891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 -7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 -FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B -92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F -01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 -B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 -4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 -F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB -45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 -31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 -FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE -537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E -7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 -9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 -E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D -CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB -9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 -3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F -B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA -A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 -6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 -97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 -4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 -39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 -BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A -C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 -1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 -2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 -8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 -9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 -351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 -3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB -7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 -5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 -3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF -F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 -B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 -7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 -801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 -AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 -9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 -B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 -8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 -014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C -46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C -CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 -6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 -55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 -1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 -141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 -F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 -F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 -F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A -E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 -53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B -31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE -C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D -B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 -723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 -04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 -FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F -2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 -03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A -065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 -6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 -C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E -AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB -E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 -98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C -35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE -A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 -E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 -5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 -B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 -79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 -67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 -8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 -5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 -FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 -9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 -ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 -56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB -384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 -6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 -0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 -12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 -40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 -148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C -AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 -DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 -2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A -457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E -5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A -955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF -F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 -4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A -0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C -44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 -289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 -247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 -CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C -2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 -1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 -F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 -BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 -51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF -28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F -AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 -2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 -2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 -070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D -9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E -3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC -FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 -1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F -C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 -EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D -DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 -0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 -B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C -5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 -7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 -9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 -F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB -AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 -6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB -78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE -F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D -92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 -9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 -E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 -68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE -FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA -304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE -2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 -3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 -02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A -7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B -94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A -1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 -81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D -83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 -01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D -C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 -26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 -860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 -C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 -18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 -2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 -CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 -E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF -2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 -2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E -67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E -E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 -8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA -774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A -53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 -1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 -5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 -389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F -5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 -B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE -7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 -703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 -5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB -250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF -6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 -782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 -FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 -6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 -39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 -3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 -36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 -0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 -5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 -1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 -AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D -EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF -E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 -03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF -4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB -D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B -E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 -71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 -1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 -1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 -84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 -6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 -0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 -2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 -9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD -02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 -F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 -5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC -7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 -F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 -9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C -C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB -85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 -048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED -22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB -41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 -27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 -DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB -388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 -4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 -7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 -343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 -C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 -BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 -5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F -5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 -25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 -AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 -9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 -66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 -29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 -39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D -F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A -279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D -A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 -09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F -2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 -AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 -F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 -1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 -FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF -5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 -961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A -BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA -40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 -08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B -472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 -3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C -87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 -0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D -5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 -FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA -2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 -2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 -15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 -A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C -250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C -8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 -C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE -F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C -9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 -B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 -56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF -A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 -BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 -CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 -175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 -7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A -FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 -E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 -6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 -AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 -4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 -08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B -F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 -958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF -EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 -15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 -CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F -B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 -2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 -8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 -1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 -7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 -D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 -9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E -84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 -C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E -8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC -3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 -AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC -806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 -64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C -ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D -1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E -565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD -540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD -093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B -FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 -2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D -BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 -EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C -C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A -2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 -C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 -F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 -89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B -169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 -ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D -20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 -B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D -E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE -6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC -31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 -33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B -7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C -B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 -4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC -1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 -89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C -212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA -34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 -D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 -38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 -DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 -8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 -212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 -3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 -F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 -1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 -12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 -9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 -B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 -5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 -564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 -5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D -867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 -53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 -3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B -451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C -B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 -CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 -C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 -E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF -64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 -8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 -AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 -BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 -A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 -990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D -B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 -4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 -84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C -F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 -D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 -37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 -D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 -EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 -FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A -DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 -62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 -54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB -AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 -0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 -4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 -2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C -2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC -F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 -BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 -D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 -C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF -46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 -50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED -49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D -20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F -BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A -977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 -EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF -56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 -CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF -3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 -B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 -062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 -D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE -3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 -940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD -6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F -E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 -F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 -DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F -5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D -7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 -695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 -C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 -8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 -39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 -3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD -2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 -6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 -5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C -5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF -B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 -06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 -1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 -6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 -4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 -0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 -B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 -E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A -1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 -354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 -9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 -BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 -F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 -9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 -54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D -092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 -741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 -57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 -C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 -7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 -3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 -82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 -C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 -615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 -B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 -A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 -9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 -FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 -EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F -818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C -715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 -8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 -1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 -707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 -4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D -54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 -2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 -15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 -63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B -81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 -CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 -E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB -2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 -E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 -B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 -AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 -3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A -04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 -151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 -E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 -26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 -3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 -772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF -27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E -DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 -898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 -AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F -C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 -CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D -59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 -4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 -3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 -FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 -90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC -167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 -573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F -C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E -96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 -2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 -7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC -B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E -E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 -51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F -025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 -2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF -C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F -E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 -EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F -DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 -E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 -E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF -C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D -84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C -61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 -33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 -C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 -1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D -CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C -984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 -8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 -596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 -A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 -015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC -0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF -27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 -0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 -46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 -1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 -33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A -77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 -75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 -749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD -77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF -2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 -1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 -703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D -A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 -907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB -9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 -782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 -B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A -A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 -4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 -1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE -2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B -50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 -CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC -39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 -FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE -9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 -E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 -533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D -CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 -8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA -AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 -0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 -8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 -1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E -98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 -F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E -5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 -A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA -3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA -5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 -04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB -84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C -C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB -76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 -27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 -01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE -7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 -6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A -3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F -C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A -9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C -53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 -D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 -92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 -1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 -7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 -009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE -B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F -F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 -789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 -50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF -76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 -AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 -897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 -9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 -5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F -86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 -A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 -F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F -FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 -DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD -77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 -1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F -518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 -47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 -7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A -CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A -B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 -DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 -B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C -33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 -1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 -904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE -17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A -79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF -00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E -BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF -B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 -0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B -E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F -1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E -0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 -0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 -5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 -3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 -81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB -1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 -963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 -4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 -86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 -7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 -2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 -6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B -37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 -84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 -B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 -402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 -C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 -B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 -88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 -49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B -B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 -ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 -5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB -6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 -D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F -E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 -D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB -CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 -5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 -D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D -605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 -3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 -5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A -807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 -FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A -4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 -B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A -CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 -205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 -38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 -F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE -263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 -E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF -207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA -D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC -3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 -66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D -B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E -6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 -EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF -9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC -D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 -860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 -B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 -A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D -9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 -FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 -584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 -6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 -EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 -5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 -4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 -D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E -933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 -7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 -CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF -F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A -DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 -611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 -DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 -40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F -AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE -8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B -C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 -AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 -1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 -C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 -749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 -B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C -CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 -83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B -35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E -A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F -A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 -4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A -B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 -58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D -F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A -69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 -7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 -748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E -5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 -81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 -236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A -9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF -CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 -ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA -26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB -17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 -ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 -60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 -6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 -9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 -4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC -B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 -7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA -00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 -5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB -625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 -38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE -2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 -3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 -79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 -799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A -80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 -411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 -BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 -D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 -D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 -42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 -70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 -B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 -00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 -E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B -A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 -44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D -ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 -3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A -3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 -E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C -9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 -238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 -EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 -7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D -324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 -B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D -B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE -F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD -99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 -A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 -7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A -CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C -A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 -2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 -A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 -B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC -7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 -D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D -057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE -D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 -6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 -8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A -CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 -41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F -01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 -31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 -3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 -696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 -36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB -D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD -0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 -CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB -012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 -006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 -B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 -9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 -85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 -024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 -75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 -CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 -6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A -83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 -4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 -1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A -A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 -E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F -26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 -C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 -9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA -98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 -EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C -2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC -B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 -2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 -10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 -DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 -E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 -7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 -73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E -9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 -EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C -0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 -363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 -6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 -EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 -E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 -09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 -1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 -0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B -195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 -AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 -D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 -05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 -FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A -BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E -2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F -2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B -913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B -C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 -BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F -9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA -112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 -4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 -D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 -292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA -8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 -6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA -F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 -FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 -A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 -1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D -09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 -39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A -6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B -E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 -4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D -8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 -C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C -31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E -0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC -9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 -B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 -BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 -3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 -1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD -F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 -A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 -B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F -FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E -81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 -5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 -1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 -B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C -29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 -8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 -97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A -D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 -3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 -D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE -41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB -44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 -B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A -69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 -84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E -749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 -9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 -D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 -86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 -70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC -151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 -3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE -4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 -CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 -347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E -D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B -BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF -FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E -C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E -D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF -C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE -1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 -859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD -BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA -D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 -1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 -4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D -430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 -A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC -089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 -BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 -143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 -2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 -12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 -331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 -07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 -5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B -1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 -24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 -1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 -FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 -8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 -5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 -FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 -E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 -9F08ABD4F4B0889283E55500702185A841E328 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont -/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont -/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont -295 271 moveto -0 0 0 setrgbcolor -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 271 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -653 271 moveto -<6475> -show -725 271 moveto -<66696368696572> -show -877 271 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F535243> -show -1149 271 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1162 271 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<737263> -show -1223 271 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1236 271 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F49> -show -1435 271 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1448 271 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D616B6566696C652E696E2C> -show -1708 271 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont - -show -1938 271 moveto -<434F524241> -show -370 331 moveto -<6465206C61207072E963E964656E7465206D6F64696669636174696F6E2E> -show -294 433 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<69666571202840574954484E455447454E402C79657329> -show -294 476 moveto -<20204C49425F535243202B3D20534D4553485F4E455447454E5F33445F692E637878> -show -294 520 moveto -<2020> -show -344 520 moveto -<4C44464C414753202B3D202D6C4E455447454E> -show -294 564 moveto -<656E646966> -show -295 682 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 682 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -657 682 moveto -<6475> -show -733 682 moveto -<66696368696572> -show -890 682 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<69646C2F534D4553485F42617369634879706F7468657369732E69646C> -show -1563 682 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -1681 682 moveto -<72616A6F75746572> -show -1863 682 moveto -<6C92616C676F726974686D65> -show -370 742 moveto -<4E455447454E5F33442071756920636F72726573706F6E64206175206D61696C6C6575722074E9 -74726168E9647269717565206465204E657467656E2E> -show -294 887 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<2020> -show -344 887 moveto -<696E7465726661636520534D4553485F4E455447454E5F3344> -show -974 887 moveto -<20> -show -999 887 moveto -<3A20534D4553485F33445F416C676F> -show -294 931 moveto -<20207B> -show -294 975 moveto -<20207D3B> -show -295 1092 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 1092 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -667 1092 moveto -<6475> -show -754 1092 moveto -<66696368696572> -show -921 1092 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F534D4553484755492F534D4553484755495F69636F6E732E70 -6F> -show -2019 1092 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -370 1152 moveto -<72616A6F75746572> -show -556 1152 moveto -<6C92616C676F726974686D65> -show -832 1152 moveto -<4E455447454E5F3344> -show -1149 1152 moveto -<717569> -show -1242 1152 moveto -<636F72726573706F6E64> -show -1495 1152 moveto -<6175> -show -1572 1152 moveto -<6D61696C6C657572> -show -1769 1152 moveto -<74E974726168E9647269717565> -show -2062 1152 moveto -<6465> -show -370 1208 moveto -<4E657467656E2064616E73206C612047554920646520534D4553482028626F75746F6E20646520 -73E96C656374696F6E292E> -show -294 1309 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<236D6573685F747265655F616C676F5F7465747261> -show -294 1353 moveto -<6D736769642049434F4E5F534D4553485F545245455F414C474F5F54657472615F3344> -show -294 1397 moveto -<6D7367737472206D6573685F747265655F616C676F5F74657472612E706E67> -show -295 1515 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 1515 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -651 1515 moveto -<646573> -show -739 1515 moveto -<6669636869657273> -show -910 1515 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F726573736F75726365732F534D4553485F5B656E2C66725D2E786D6C> -show -1843 1515 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -1955 1515 moveto -<72616A6F75746572> -show -370 1575 moveto -<6C6573> -show -445 1575 moveto -<636F6D6D656E746169726573> -show -744 1575 moveto -<737572> -show -824 1575 moveto -<6C6573> -show -898 1575 moveto -<626F75746F6E73> -show -1075 1575 moveto -<6465> -show -1142 1575 moveto -<6C61> -show -1196 1575 moveto -<475549> -show -1305 1575 moveto -<6465> -show -1370 1575 moveto -<534D4553482E> -show -1569 1575 moveto -<436573> -show -1663 1575 moveto -<626F75746F6E73> -show -1840 1575 moveto -<7065726D657474656E74> -show -2073 1575 moveto -<6C65> -show -370 1631 moveto -<63686F6978206475206D61696C6C6575722074E974726168E9647269717565206465204E657467 -656E206574206465206C61207461696C6C652064657320E96CE96D656E747320766F6C756D697175 -65732E> -show -294 1732 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<20202020> -show -394 1732 moveto -<3C> -show -419 1732 moveto -<706F7075702D6974656D206974656D2D69643D93353033339420706F732D69643D9494206C6162 -656C2D69643D944D61782E2048657861686564726F6E206F72> -show -294 1776 moveto -<5465747261686564726F6E20566F6C756D65942069636F6E2D69643D946D6573685F6879706F5F -766F6C756D652E706E679420746F6F6C7469702D69643D949420616363656C2D> -show -294 1820 moveto -<69643D949420746F67676C652D69643D949420657865637574652D616374696F6E3D9494202F> -show -1251 1820 moveto -<3E> -show -294 1864 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1908 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1952 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1996 moveto -<202020203C> -show -420 1996 moveto -<706F7075702D6974656D206974656D2D69643D93353032309420706F732D69643D9494206C6162 -656C2D69643D9448657861686564726F6E2028692C6A2C6B2994> -show -294 2040 moveto -<69636F6E2D69643D946D6573685F616C676F5F686578612E706E679420746F6F6C7469702D6964 -3D949420616363656C2D69643D949420746F67676C652D69643D9494> -show -294 2084 moveto -<657865637574652D616374696F6E3D9494202F> -show -772 2084 moveto -<3E> -show -294 2128 moveto -<202020203C> -show -420 2128 moveto -<706F7075702D6974656D206974656D2D69643D93353032319420706F732D69643D9494206C6162 -656C2D69643D945465747261686564726F6E20284E657467656E2994> -show -294 2171 moveto -<69636F6E2D69643D946D6573685F616C676F5F686578612E706E679420746F6F6C7469702D6964 -3D949420616363656C2D69643D949420746F67676C652D69643D9494> -show -294 2215 moveto -<657865637574652D616374696F6E3D9494202F> -show -772 2215 moveto -<3E> -show -294 2259 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2303 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2347 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2391 moveto -<202020203C746F6F6C627574746F6E> -show -672 2391 moveto -<2D6974656D206974656D2D69643D933530333394206C6162656C2D69643D944D61782E20486578 -61686564726F6E206F72> -show -294 2435 moveto -<5465747261686564726F6E20566F6C756D65942069636F6E2D69643D946D6573685F6879706F5F -766F6C756D652E706E679420746F6F6C7469702D69643D94204D61782E> -show -294 2479 moveto -<48657861686564726F6E206F72205465747261686564726F6E20566F6C756D65204879706F7468 -657369739420616363656C2D69643D949420746F67676C652D69643D9494> -show -294 2523 moveto -<657865637574652D616374696F6E3D9494202F> -show -772 2523 moveto -<3E> -show -294 2567 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2611 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2655 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2699 moveto -<202020203C> -show -420 2699 moveto -<746F6F6C627574746F6E2D6974656D206974656D2D69643D93353032309420706F732D69643D94 -94206C6162656C2D69643D9448657861686564726F6E> -show -294 2743 moveto -<28692C6A2C6B29942069636F6E2D69643D946D6573685F616C676F5F686578612E706E67942074 -6F6F6C7469702D69643D942048657861686564726F6E2028692C6A2C6B29> -show -294 2787 moveto -<416C676F726974686D9420616363656C2D69643D949420746F67676C652D69643D949420657865 -637574652D616374696F6E3D9494202F> -show -1680 2787 moveto -<3E> -show -294 2831 moveto -<202020203C746F6F6C627574746F6E> -show -672 2831 moveto -<2D6974656D206974656D2D69643D93353032319420706F732D69643D9494206C6162656C2D6964 -3D945465747261686564726F6E> -show -294 2875 moveto -<284E657467656E29942069636F6E2D69643D946D6573685F616C676F5F686578612E706E679420 -746F6F6C7469702D69643D94205465747261686564726F6E20284E657467656E29> -show -294 2919 moveto -<416C676F726974686D9420616363656C2D69643D949420746F67676C652D69643D949420657865 -637574652D616374696F6E3D9494202F> -show -1680 2919 moveto -<3E> -show -220 3030 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<417474656E74696F6E> -show -220 3035 188 3 rectfill -408 3030 moveto -<3A20756E2066696368696572202E706E6720206D6573685F616C676F5F74657472612E706E6720 -646F697420EA7472652070726F6475697420706F75722064697374696E67756572206C276963F46E -65206475> -show -220 3086 moveto -<6D61696C6C657572206865786168E96472697175652064652063656C7569206475206D61696C6C -6575722074E974726168E9647269717565202861637475656C6C656D656E7420632765737420756E -652073696D706C65> -show -280 399 1 176 rectfill -2125 399 1 176 rectfill -280 399 1846 1 rectfill -280 574 1846 1 rectfill -280 809 1 176 rectfill -2125 809 1 176 rectfill -280 809 1846 1 rectfill -280 984 1846 1 rectfill -280 1276 1 132 rectfill -2125 1276 1 132 rectfill -280 1276 1846 1 rectfill -280 1407 1846 1 rectfill -280 1698 1 1231 rectfill -2125 1698 1 1231 rectfill -280 1698 1846 1 rectfill -280 2928 1846 1 rectfill -showpage -grestore grestore -%%PageTrailer - -%%Page: 3 3 -%%PageBoundingBox: 18 18 577 824 -%%BeginSetup -% -%%EndSetup -%%BeginPageSetup -% -gsave -[0.24 0 0 -0.24 18 824] concat -gsave -%%EndPageSetup -%%BeginResource: font NimbusMonL-Regu -%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle 0.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-Regu def -/PaintType 0 def -/WMode 0 def -/FontBBox {-12 -237 650 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020945 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 -5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E -6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 -87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B -A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 -643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 -C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 -F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 -FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E -61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 -4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C -CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 -2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA -A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC -0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 -4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 -FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 -61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 -3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 -1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 -72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B -B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A -36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC -40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A -4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 -46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 -D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB -B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F -8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 -4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C -F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C -BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB -C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 -966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 -998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 -CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E -C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 -D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 -1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF -1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 -A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 -583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 -7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 -9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 -77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 -7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 -45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 -C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 -EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 -077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 -E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B -1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 -27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 -F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 -FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B -6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 -2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 -FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 -A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 -23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 -56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 -5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF -13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F -FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C -3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 -2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 -C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F -1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 -88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 -8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE -FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA -D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC -2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C -9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F -D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A -EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 -F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 -67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 -A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 -9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D -183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 -BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 -4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 -556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 -1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 -F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 -2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C -FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F -ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 -2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC -ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 -2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 -298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 -BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 -47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE -48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C -BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 -5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 -55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 -2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 -4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D -8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D -69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A -AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE -61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B -834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 -E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D -E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F -46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 -A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 -F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E -185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 -7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 -6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 -B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C -D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 -606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F -AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E -064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C -FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE -874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD -060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C -AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D -D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 -A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE -528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A -302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 -934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 -57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 -71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 -D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 -B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 -48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 -21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 -B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 -CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED -DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 -718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 -5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F -E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC -41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 -5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 -7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 -D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 -D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 -4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC -1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 -374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 -E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF -4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 -AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E -4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 -858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB -EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 -BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F -45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E -050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED -199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 -7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE -B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC -91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 -905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 -E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 -81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 -B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 -9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B -470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 -627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 -2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E -BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 -9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 -8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 -1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 -4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E -06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 -65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 -C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 -52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE -64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 -C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 -17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 -C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE -2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF -1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 -03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 -88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 -37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 -F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 -6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 -59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 -EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E -2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 -24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C -F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE -400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 -1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 -9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 -DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB -7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 -F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F -E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B -727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE -58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 -840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 -EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 -CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A -622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 -D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C -91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 -7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C -5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 -FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E -DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 -54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A -E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD -F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 -A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A -623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA -891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 -7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 -FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B -92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F -01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 -B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 -4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 -F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB -45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 -31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 -FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE -537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E -7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 -9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 -E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D -CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB -9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 -3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F -B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA -A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 -6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 -97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 -4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 -39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 -BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A -C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 -1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 -2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 -8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 -9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 -351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 -3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB -7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 -5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 -3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF -F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 -B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 -7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 -801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 -AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 -9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 -B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 -8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 -014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C -46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C -CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 -6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 -55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 -1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 -141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 -F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 -F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 -F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A -E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 -53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B -31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE -C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D -B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 -723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 -04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 -FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F -2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 -03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A -065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 -6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 -C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E -AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB -E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 -98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C -35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE -A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 -E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 -5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 -B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 -79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 -67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 -8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 -5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 -FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 -9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 -ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 -56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB -384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 -6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 -0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 -12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 -40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 -148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C -AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 -DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 -2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A -457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E -5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A -955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF -F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 -4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A -0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C -44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 -289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 -247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 -CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C -2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 -1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 -F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 -BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 -51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF -28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F -AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 -2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 -2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 -070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D -9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E -3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC -FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 -1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F -C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 -EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D -DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 -0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 -B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C -5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 -7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 -9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 -F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB -AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 -6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB -78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE -F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D -92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 -9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 -E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 -68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE -FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA -304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE -2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 -3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 -02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A -7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B -94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A -1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 -81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D -83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 -01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D -C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 -26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 -860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 -C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 -18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 -2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 -CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 -E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF -2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 -2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E -67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E -E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 -8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA -774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A -53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 -1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 -5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 -389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F -5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 -B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE -7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 -703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 -5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB -250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF -6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 -782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 -FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 -6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 -39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 -3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 -36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 -0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 -5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 -1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 -AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D -EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF -E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 -03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF -4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB -D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B -E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 -71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 -1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 -1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 -84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 -6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 -0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 -2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 -9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD -02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 -F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 -5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC -7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 -F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 -9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C -C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB -85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 -048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED -22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB -41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 -27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 -DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB -388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 -4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 -7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 -343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 -C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 -BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 -5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F -5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 -25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 -AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 -9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 -66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 -29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 -39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D -F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A -279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D -A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 -09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F -2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 -AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 -F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 -1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 -FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF -5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 -961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A -BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA -40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 -08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B -472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 -3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C -87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 -0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D -5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 -FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA -2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 -2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 -15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 -A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C -250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C -8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 -C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE -F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C -9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 -B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 -56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF -A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 -BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 -CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 -175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 -7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A -FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 -E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 -6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 -AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 -4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 -08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B -F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 -958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF -EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 -15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 -CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F -B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 -2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 -8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 -1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 -7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 -D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 -9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E -84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 -C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E -8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC -3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 -AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC -806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 -64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C -ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D -1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E -565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD -540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD -093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B -FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 -2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D -BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 -EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C -C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A -2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 -C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 -F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 -89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B -169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 -ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D -20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 -B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D -E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE -6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC -31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 -33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B -7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C -B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 -4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC -1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 -89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C -212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA -34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 -D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 -38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 -DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 -8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 -212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 -3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 -F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 -1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 -12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 -9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 -B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 -5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 -564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 -5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D -867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 -53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 -3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B -451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C -B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 -CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 -C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 -E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF -64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 -8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 -AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 -BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 -A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 -990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D -B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 -4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 -84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C -F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 -D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 -37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 -D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 -EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 -FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A -DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 -62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 -54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB -AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 -0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 -4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 -2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C -2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC -F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 -BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 -D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 -C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF -46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 -50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED -49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D -20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F -BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A -977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 -EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF -56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 -CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF -3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 -B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 -062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 -D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE -3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 -940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD -6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F -E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 -F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 -DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F -5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D -7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 -695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 -C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 -8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 -39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 -3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD -2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 -6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 -5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C -5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF -B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 -06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 -1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 -6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 -4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 -0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 -B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 -E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A -1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 -354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 -9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 -BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 -F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 -9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 -54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D -092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 -741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 -57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 -C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 -7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 -3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 -82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 -C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 -615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 -B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 -A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 -9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 -FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 -EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F -818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C -715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 -8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 -1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 -707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 -4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D -54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 -2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 -15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 -63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B -81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 -CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 -E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB -2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 -E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 -B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 -AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 -3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A -04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 -151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 -E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 -26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 -3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 -772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF -27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E -DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 -898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 -AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F -C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 -CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D -59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 -4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 -3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 -FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 -90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC -167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 -573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F -C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E -96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 -2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 -7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC -B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E -E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 -51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F -025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 -2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF -C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F -E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 -EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F -DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 -E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 -E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF -C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D -84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C -61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 -33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 -C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 -1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D -CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C -984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 -8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 -596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 -A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 -015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC -0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF -27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 -0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 -46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 -1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 -33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A -77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 -75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 -749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD -77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF -2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 -1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 -703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D -A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 -907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB -9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 -782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 -B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A -A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 -4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 -1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE -2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B -50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 -CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC -39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 -FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE -9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 -E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 -533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D -CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 -8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA -AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 -0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 -8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 -1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E -98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 -F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E -5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 -A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA -3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA -5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 -04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB -84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C -C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB -76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 -27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 -01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE -7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 -6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A -3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F -C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A -9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C -53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 -D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 -92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 -1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 -7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 -009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE -B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F -F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 -789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 -50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF -76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 -AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 -897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 -9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 -5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F -86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 -A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 -F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F -FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 -DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD -77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 -1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F -518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 -47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 -7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A -CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A -B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 -DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 -B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C -33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 -1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 -904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE -17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A -79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF -00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E -BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF -B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 -0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B -E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F -1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E -0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 -0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 -5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 -3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 -81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB -1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 -963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 -4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 -86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 -7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 -2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 -6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B -37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 -84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 -B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 -402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 -C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 -B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 -88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 -49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B -B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 -ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 -5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB -6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 -D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F -E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 -D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB -CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 -5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 -D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D -605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 -3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 -5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A -807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 -FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A -4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 -B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A -CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 -205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 -38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 -F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE -263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 -E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF -207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA -D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC -3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 -66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D -B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E -6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 -EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF -9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC -D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 -860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 -B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 -A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D -9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 -FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 -584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 -6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 -EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 -5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 -4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 -D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E -933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 -7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 -CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF -F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A -DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 -611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 -DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 -40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F -AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE -8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B -C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 -AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 -1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 -C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 -749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 -B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C -CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 -83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B -35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E -A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F -A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 -4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A -B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 -58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D -F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A -69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 -7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 -748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E -5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 -81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 -236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A -9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF -CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 -ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA -26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB -17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 -ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 -60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 -6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 -9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 -4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC -B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 -7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA -00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 -5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB -625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 -38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE -2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 -3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 -79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 -799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A -80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 -411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 -BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 -D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 -D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 -42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 -70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 -B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 -00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 -E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B -A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 -44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D -ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 -3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A -3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 -E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C -9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 -238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 -EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 -7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D -324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 -B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D -B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE -F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD -99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 -A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 -7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A -CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C -A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 -2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 -A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 -B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC -7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 -D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D -057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE -D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 -6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 -8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A -CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 -41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F -01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 -31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 -3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 -696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 -36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB -D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD -0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 -CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB -012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 -006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 -B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 -9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 -85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 -024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 -75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 -CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 -6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A -83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 -4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 -1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A -A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 -E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F -26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 -C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 -9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA -98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 -EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C -2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC -B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 -2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 -10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 -DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 -E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 -7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 -73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E -9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 -EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C -0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 -363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 -6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 -EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 -E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 -09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 -1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 -0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B -195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 -AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 -D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 -05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 -FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A -BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E -2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F -2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B -913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B -C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 -BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F -9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA -112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 -4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 -D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 -292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA -8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 -6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA -F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 -FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 -A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 -1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D -09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 -39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A -6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B -E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 -4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D -8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 -C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C -31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E -0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC -9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 -B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 -BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 -3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 -1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD -F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 -A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 -B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F -FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E -81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 -5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 -1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 -B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C -29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 -8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 -97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A -D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 -3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 -D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE -41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB -44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 -B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A -69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 -84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E -749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 -9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 -D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 -86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 -70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC -151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 -3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE -4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 -CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 -347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E -D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B -BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF -FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E -C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E -D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF -C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE -1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 -859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD -BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA -D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 -1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 -4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D -430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 -A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC -089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 -BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 -143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 -2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 -12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 -331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 -07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 -5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B -1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 -24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 -1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 -FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 -8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 -5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 -FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 -E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 -9F08ABD4F4B0889283E55500702185A841E328 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -%%BeginResource: font NimbusMonL-ReguObli -%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular Oblique) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle -12.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-ReguObli def -/PaintType 0 def -/WMode 0 def -/FontBBox {-61 -237 774 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020947 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1 -94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211 -9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB -B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466 -AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1 -25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A -C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC -45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246 -D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566 -9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A -E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698 -53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736 -05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66 -5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341 -6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF -4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2 -4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482 -9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D -FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4 -DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3 -CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D -B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28 -7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A -1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68 -1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A -8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4 -16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365 -F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12 -41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22 -5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D -BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080 -65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827 -C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45 -EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559 -872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103 -AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF -8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E -1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A -7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A -DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610 -38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356 -A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F -67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5 -492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1 -5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD -A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551 -D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3 -C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252 -CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097 -60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A -F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA -37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8 -F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E -18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0 -9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118 -73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0 -837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D -9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E -9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC -85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3 -AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F -719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1 -496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88 -EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C -6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7 -37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB -F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C -D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2 -63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15 -565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE -18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E -2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841 -55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44 -58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551 -837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3 -0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE -9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C -155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8 -BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16 -8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879 -1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C -4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA -492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3 -155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704 -1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3 -5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0 -5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC -CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0 -BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E -DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311 -98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E -DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6 -F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C -93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504 -78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9 -F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F -9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4 -3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2 -52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A -A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0 -F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB -1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F -2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8 -D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD -879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319 -1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD -BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122 -007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C -5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F -013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D -BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA -6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338 -670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C -0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13 -C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172 -6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807 -91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600 -8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F -8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D -AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94 -202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E -DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68 -85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315 -70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF -80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581 -217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12 -E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA -9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519 -1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5 -3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED -B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4 -FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC -797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D -2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7 -E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364 -A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71 -8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C -BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0 -9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1 -3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B -E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75 -BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428 -4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B -69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6 -D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8 -FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387 -7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4 -A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF -51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A -DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515 -D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A -FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0 -5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A -96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB -92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF -37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812 -3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726 -62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3 -D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550 -7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752 -4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734 -B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363 -141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303 -86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83 -9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726 -B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B -737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43 -46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7 -0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9 -A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744 -69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8 -222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6 -855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF -F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1 -6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A -8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453 -3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6 -67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A -AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C -30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4 -29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04 -26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1 -3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B -667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177 -D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17 -070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180 -7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8 -C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D -E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD -E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51 -C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E -EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA -11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385 -1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C -FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8 -96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C -0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C -6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120 -835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C -5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC -7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A -78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21 -6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8 -2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099 -9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE -C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0 -DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054 -16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B -D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3 -984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA -B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33 -7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219 -1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26 -DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66 -1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA -4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27 -94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350 -45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915 -E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36 -6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5 -F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538 -B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2 -3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705 -796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8 -40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494 -44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5 -C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59 -6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14 -AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130 -6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68 -6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952 -35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7 -08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217 -4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218 -52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95 -41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C -77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8 -65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB -73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81 -234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F -982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9 -184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885 -A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD -0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34 -7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2 -E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC -AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB -8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09 -1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF -EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED -8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F -A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F -87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B -33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7 -B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559 -2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C -6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC -56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED -884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262 -348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1 -106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B -13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07 -E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30 -41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687 -F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604 -3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1 -467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95 -993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F -7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083 -4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3 -41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941 -2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F -BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F -486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8 -249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325 -D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D -4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4 -AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E -1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D -13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367 -DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020 -749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C -5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39 -0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1 -71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D -FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6 -F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4 -D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2 -182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137 -33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE -48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1 -5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA -5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C -4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173 -A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731 -5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938 -731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C -15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3 -D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E -E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7 -97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC -7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369 -DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171 -CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878 -B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343 -1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4 -7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A -FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93 -12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E -31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28 -8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35 -FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA -AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F -970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1 -837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080 -02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29 -3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E -57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5 -8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765 -EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB -43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE -5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F -7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C -39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2 -A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2 -56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158 -C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951 -23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34 -37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE -BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9 -2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9 -BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594 -6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6 -5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE -CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D -3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65 -77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B -DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7 -63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB -EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69 -B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB -438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D -7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245 -4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B -F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1 -8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2 -F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C -C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B -47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326 -6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1 -564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692 -C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24 -870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81 -1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211 -D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601 -196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0 -CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53 -41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4 -5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47 -B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD -B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947 -1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D -DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6 -A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED -5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3 -E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA -649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B -220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729 -E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7 -5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524 -4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01 -486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195 -CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2 -1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14 -50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6 -B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25 -B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F -58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7 -77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202 -42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2 -79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179 -08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101 -EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A -A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171 -0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC -50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16 -D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938 -A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B -A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476 -63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444 -5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E -4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598 -54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62 -3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C -1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC -1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269 -743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA -94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD -02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F -03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5 -403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006 -54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63 -8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67 -5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108 -DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C -2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB -197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4 -6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918 -0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C -F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D -05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC -E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E -4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC -7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717 -80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9 -4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158 -8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62 -0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF -540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6 -A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957 -270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911 -F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E -4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D -41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967 -6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654 -BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B -7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C -52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB -4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97 -146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B -D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD -52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559 -187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616 -F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174 -CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963 -4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D -0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5 -4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE -A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070 -169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72 -6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092 -402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C -EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B -77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0 -02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9 -73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421 -B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4 -D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806 -E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70 -BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A -79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7 -787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8 -88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F -F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52 -6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D -6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB -C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744 -1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296 -75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391 -26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A -0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379 -928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4 -77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806 -4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E -9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70 -89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E -E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17 -01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506 -FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735 -2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B -3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D -6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C -2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928 -C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA -35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67 -F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F -CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6 -4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714 -54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228 -603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB -2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9 -F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2 -106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC -32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA -60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431 -F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892 -370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950 -78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D -CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE -F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A -75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847 -C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A -41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1 -5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9 -5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441 -DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1 -639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A -3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464 -81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463 -DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6 -DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB -02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84 -E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54 -0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824 -16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D -F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320 -79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0 -F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF -74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8 -5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD -AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02 -DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E -7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC -0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119 -32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438 -DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97 -6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A -4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7 -A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA -ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693 -CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA -683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853 -BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3 -8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499 -907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D -403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49 -A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9 -4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C -EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2 -0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF -885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A -4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC -8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E -0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9 -8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF -E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC -2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09 -5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731 -28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1 -1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA -BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367 -4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD -E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956 -507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13 -24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35 -8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D -8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339 -E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE -0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D -25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1 -10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888 -4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2 -2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678 -9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55 -43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91 -3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E -EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E -D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B -B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2 -86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2 -376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB -76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A -5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490 -D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684 -8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842 -9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839 -0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688 -1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8 -D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674 -F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A -96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D -31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD -63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81 -0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF -DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88 -30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7 -835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E -115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A -9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C -80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63 -6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210 -C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE -CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED -8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37 -CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA -71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209 -8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA -BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E -722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C -4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC -52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2 -802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88 -A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE -43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2 -BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382 -5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3 -F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E -1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821 -4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E -34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44 -400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408 -999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E -8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436 -BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497 -5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09 -6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814 -E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F -D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8 -F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C -E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725 -EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB -009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9 -4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5 -5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5 -86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988 -A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847 -EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E -3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10 -324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E -FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495 -0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E -ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12 -8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD -4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF -CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D -DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD -B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD -D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8 -FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E -B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA -E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551 -98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9 -FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C -D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40 -19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C -2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0 -DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0 -ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B -2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C -4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C -BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C -46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E -690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A -BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399 -270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4 -9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268 -10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65 -95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3 -AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0 -9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B -D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754 -94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1 -67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8 -BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E -07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94 -D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4 -1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4 -95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA -91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D -30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE -C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B -3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7 -AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273 -38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F -9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1 -B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65 -89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B -163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2 -56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B -186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE -19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C -4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5 -03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28 -B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24 -4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34 -8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3 -71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1 -EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5 -083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31 -D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200 -458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0 -11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1 -0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C -397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560 -A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82 -0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591 -EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4 -4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C -1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033 -109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213 -18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2 -C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3 -47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605 -8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB -7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754 -E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D -AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D -5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89 -7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E -AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604 -388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C -540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2 -3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D -E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40 -61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA -73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921 -9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127 -4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A -4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6 -F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1 -BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0 -39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910 -B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314 -54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A -EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734 -EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079 -CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE -718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C -D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA -9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A -53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E -A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7 -7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237 -CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55 -311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357 -F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B -E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643 -15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C -001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0 -0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D -CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55 -AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A -ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E -77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252 -346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD -12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF -2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A -C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427 -AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B -61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0 -BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C -484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82 -94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2 -E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827 -A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE -5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12 -66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2 -B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72 -E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E -168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF -BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999 -4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA -252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B -87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C -0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074 -EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135 -ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912 -999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4 -C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA -4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152 -692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014 -69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F -F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840 -301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624 -B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E -86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1 -1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED -70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D -B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37 -5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803 -35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651 -C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A -D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A -C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528 -4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154 -02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492 -83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C -BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65 -64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738 -9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60 -7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694 -45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F -C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB -55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766 -2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1 -7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419 -5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB -1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E -17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3 -5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217 -F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A -9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120 -2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8 -ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8 -0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1 -1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006 -F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0 -000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9 -9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789 -ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B -02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963 -189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE -EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2 -C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268 -6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C -390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2 -922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8 -D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86 -70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962 -F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB -268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886 -B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9 -6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07 -A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649 -B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663 -AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F -A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA -0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816 -495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7 -E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA -D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE -B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C -0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C -7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B -6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86 -EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6 -08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6 -6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC -1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2 -E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D -3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C -122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2 -F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6 -154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954 -9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182 -B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8 -9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1 -85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47 -B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46 -E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED -839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A -9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5 -E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4 -FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D -D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A -1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278 -AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA -239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062 -3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02 -F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD -7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405 -77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA -BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C -80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09 -9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E -DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9 -703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D -F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F -6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76 -CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6 -EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A -B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306 -23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7 -3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB -01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E -93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80 -3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C -4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB -0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF -AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C -05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396 -06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB -87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA -A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69 -50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03 -AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024 -FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18 -C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777 -3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA -F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E -59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D -A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C -4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677 -206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071 -5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A -4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89 -18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6 -7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096 -84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5 -6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9 -C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9 -684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3 -70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297 -040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345 -7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37 -F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C -1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD -F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA -E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3 -3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8 -580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1 -D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6 -645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3 -7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905 -3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60 -670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0 -BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F -2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381 -1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB -CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5 -E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB -669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C -0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF -6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F -67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2 -5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657 -C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451 -CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6 -CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25 -B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C -76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1 -A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB -5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A -6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5 -AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3 -37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2 -631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639 -567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28 -47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6 -4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD -585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB -39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0 -D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF -4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F -C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B -1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2 -2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206 -CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568 -75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88 -114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B -F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338 -6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63 -9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77 -6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B -D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0 -BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49 -E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E -DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A -7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284 -89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4 -8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46 -BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8 -34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A -3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30 -43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A -D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5 -43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD -BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2 -9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7 -31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3 -5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9 -8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97 -E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1 -1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D -082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E -BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9 -3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0 -FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77 -312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2 -74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5 -B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4 -CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9 -BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1 -4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5 -9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33 -92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B -09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B -8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802 -7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0 -5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83 -4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547 -71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC -01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464 -76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76 -41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD -7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD -C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926 -E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7 -8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC -F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43 -29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5 -243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2 -1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75 -F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC -102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36 -45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20 -352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D -17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6 -6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D -EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7 -50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC -3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0 -011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5 -FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A -7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A -3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF -7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18 -218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6 -0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC -112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB -80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65 -05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5 -A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F -5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A -289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2 -F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315 -A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D -75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244 -C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B -C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B -479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8 -0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD -3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45 -1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401 -CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338 -D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A -AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1 -BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0 -DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37 -178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF -77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F -8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A -27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808 -488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D -A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D -321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A -7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB -F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE -922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526 -75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB -09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2 -BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB -B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373 -6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379 -59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62 -8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9 -21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30 -026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022 -C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E -E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF -44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1 -8A31BE4E82B384 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont -/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont -/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont -/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont -220 265 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<636F706965292E> -show -295 383 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 383 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -671 383 moveto -<6475> -show -763 383 moveto -<66696368696572> -show -934 383 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F534D4553482F534D4553485F4879706F746865736973466163 -746F72792E637878> -show -370 443 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -479 443 moveto -<72616A6F75746572> -show -653 443 moveto -<6C6573> -show -726 443 moveto -<6E6F7576656C6C6573> -show -935 443 moveto -<6879706F7468E8736573> -show -1175 443 moveto -<636F6E6365726E616E74> -show -1411 443 moveto -<6C65> -show -1466 443 moveto -<63686F6978> -show -1595 443 moveto -<6475> -show -1662 443 moveto -<6D61696C6C657572> -show -1846 443 moveto -<74E974726168E9647269717565> -show -370 499 moveto -<6465204E657467656E206574206465206C61207461696C6C652064657320E96CE96D656E747320 -766F6C756D69717565732E> -show -294 601 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<23696E636C75646520> -show -520 601 moveto -<94534D4553485F4D6178456C656D656E74566F6C756D652E68787894> -show -294 645 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 689 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 733 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 776 moveto -<23696E636C7564652094534D4553485F4E455447454E5F332E68787894> -show -294 820 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 864 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 908 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 952 moveto -/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont -<63726561746F724D61705B944D6178456C656D656E74566F6C756D65945D203D> -show -294 996 moveto -<20202020202020206E657720534D4553485F> -show -747 996 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<4879706F74686573697343726561746F72> -show -1175 996 moveto -<3C534D4553485F4D6178456C656D656E74566F6C756D653E3B> -show -294 1040 moveto -<2020202020202020202020202020202020> -show -722 1040 moveto -<2E20202020202020202020202020202020202020202020202020202020202020202020202E> -show -294 1084 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1128 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1172 moveto -/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont -<63726561746F724D61705B944E455447454E5F3344945D203D206E657720534D4553485F> -show -1201 1172 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<4879706F74686573697343726561746F72> -show -1629 1172 moveto -<3C534D4553485F4E455447454E5F33443E3B> -show -295 1289 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 1289 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E2064752066696368696572> -show -370 1349 moveto -<20> -show -382 1349 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F534D4553485F492F534D4553485F4879706F74686573697346 -6163746F72795F692E6378782C> -show -1651 1349 moveto -0 0 0 setrgbcolor -<20E971756976616C656E7420434F524241206465> -show -370 1405 moveto -<6C61206D6F64696669636174696F6E207072E963E964656E7465> -show -906 1405 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2E> -show -294 1507 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<23696E636C7564652094534D4553485F4D6178456C656D656E74566F6C756D655F692E68787894> -show -294 1551 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1595 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1639 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1683 moveto -<23696E636C7564652094534D4553485F4E455447454E5F335F692E68787894> -show -294 1726 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1770 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1814 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1858 moveto -/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont -<63726561746F724D61705B944D6178456C656D656E74566F6C756D65945D203D> -show -294 1902 moveto -<20202020202020206E657720534D4553485F> -show -747 1902 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<4879706F74686573697343726561746F725F69> -show -1225 1902 moveto -<3C534D4553485F4D6178456C656D656E74566F6C756D655F693E3B> -show -294 1946 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1990 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2034 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2078 moveto -/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont -<63726561746F724D61705B944E455447454E5F3344945D203D> -show -294 2122 moveto -<20202020202020206E657720534D4553485F> -show -747 2122 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<4879706F74686573697343726561746F725F69> -show -1225 2122 moveto -<3C534D4553485F4E455447454E5F33445F693E3B> -show -295 2239 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 2239 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -651 2239 moveto -<6475> -show -723 2239 moveto -<66696368696572> -show -874 2239 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F534D4553484755492F534D4553484755492E637878> -show -1843 2239 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -1955 2239 moveto -<72616A6F75746572> -show -370 2299 moveto -<6C6573> -show -443 2299 moveto -<6E6F7576656C6C6573> -show -653 2299 moveto -<6879706F7468E8736573> -show -892 2299 moveto -<636F6E6365726E616E74> -show -1129 2299 moveto -<6C65> -show -1183 2299 moveto -<63686F6978> -show -1311 2299 moveto -<6475> -show -1380 2299 moveto -<6D61696C6C657572> -show -1564 2299 moveto -<74E974726168E9647269717565> -show -1845 2299 moveto -<6465> -show -1910 2299 moveto -<4E657467656E> -show -2073 2299 moveto -<6574> -show -370 2355 moveto -<6465206C61207461696C6C652064657320E96CE96D656E747320766F6C756D6971756573206461 -6E73206C612047554920646520534D4553482E> -show -294 2457 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<656C736520696620282054797065416C676F2E636F6D7061726528944E455447454E5F33449420 -3D3D203029> -show -294 2501 moveto -<2020487970203D206D79436F6D706F6E656E744D6573682D> -show -898 2501 moveto -<3E4372656174654879706F74686573697328> -show -1351 2501 moveto -<54797065416C676F2C206D795374756479496420293B> -show -294 2545 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2589 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2633 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2676 moveto -<20202020202020202020202020202020202020202020202020202020202074722894534D455348 -5F4D41585F454C454D454E545F564F4C554D455F4859504F54484553495394292C> -show -294 2720 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2764 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2808 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 2852 moveto -<2020627265616B3B> -show -294 2896 moveto -<20207D> -show -294 2940 moveto -<6361736520353032313A> -show -294 2984 moveto -<20207B> -show -294 3028 moveto -<2020736D6573684755492D> -show -571 3028 moveto -<3E437265617465416C676F726974686D28> -show -999 3028 moveto -<944E455447454E5F3344942C94546574726168656472616C20284E657467656E2994> -show -1855 3028 moveto -<293B> -show -280 567 1 616 rectfill -2125 567 1 616 rectfill -280 567 1846 1 rectfill -280 1182 1846 1 rectfill -280 1473 1 660 rectfill -2125 1473 1 660 rectfill -280 1473 1846 1 rectfill -280 2132 1846 1 rectfill -280 2423 1 616 rectfill -2125 2423 1 616 rectfill -280 2423 1846 1 rectfill -280 3038 1846 1 rectfill -showpage -grestore grestore -%%PageTrailer - -%%Page: 4 4 -%%PageBoundingBox: 18 18 577 824 -%%BeginSetup -% -%%EndSetup -%%BeginPageSetup -% -gsave -[0.24 0 0 -0.24 18 824] concat -gsave -%%EndPageSetup -%%BeginResource: font NimbusMonL-Regu -%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle 0.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-Regu def -/PaintType 0 def -/WMode 0 def -/FontBBox {-12 -237 650 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020945 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 -5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E -6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 -87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B -A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 -643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 -C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 -F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 -FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E -61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 -4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C -CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 -2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA -A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC -0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 -4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 -FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 -61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 -3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 -1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 -72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B -B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A -36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC -40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A -4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 -46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 -D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB -B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F -8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 -4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C -F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C -BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB -C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 -966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 -998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 -CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E -C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 -D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 -1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF -1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 -A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 -583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 -7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 -9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 -77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 -7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 -45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 -C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 -EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 -077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 -E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B -1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 -27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 -F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 -FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B -6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 -2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 -FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 -A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 -23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 -56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 -5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF -13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F -FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C -3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 -2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 -C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F -1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 -88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 -8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE -FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA -D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC -2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C -9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F -D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A -EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 -F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 -67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 -A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 -9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D -183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 -BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 -4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 -556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 -1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 -F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 -2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C -FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F -ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 -2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC -ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 -2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 -298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 -BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 -47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE -48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C -BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 -5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 -55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 -2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 -4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D -8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D -69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A -AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE -61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B -834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 -E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D -E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F -46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 -A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 -F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E -185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 -7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 -6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 -B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C -D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 -606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F -AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E -064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C -FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE -874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD -060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C -AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D -D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 -A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE -528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A -302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 -934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 -57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 -71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 -D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 -B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 -48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 -21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 -B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 -CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED -DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 -718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 -5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F -E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC -41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 -5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 -7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 -D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 -D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 -4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC -1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 -374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 -E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF -4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 -AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E -4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 -858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB -EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 -BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F -45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E -050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED -199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 -7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE -B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC -91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 -905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 -E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 -81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 -B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 -9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B -470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 -627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 -2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E -BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 -9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 -8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 -1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 -4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E -06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 -65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 -C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 -52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE -64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 -C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 -17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 -C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE -2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF -1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 -03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 -88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 -37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 -F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 -6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 -59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 -EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E -2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 -24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C -F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE -400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 -1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 -9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 -DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB -7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 -F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F -E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B -727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE -58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 -840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 -EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 -CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A -622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 -D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C -91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 -7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C -5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 -FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E -DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 -54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A -E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD -F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 -A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A -623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA -891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 -7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 -FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B -92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F -01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 -B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 -4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 -F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB -45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 -31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 -FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE -537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E -7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 -9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 -E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D -CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB -9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 -3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F -B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA -A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 -6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 -97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 -4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 -39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 -BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A -C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 -1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 -2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 -8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 -9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 -351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 -3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB -7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 -5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 -3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF -F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 -B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 -7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 -801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 -AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 -9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 -B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 -8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 -014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C -46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C -CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 -6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 -55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 -1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 -141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 -F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 -F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 -F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A -E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 -53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B -31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE -C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D -B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 -723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 -04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 -FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F -2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 -03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A -065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 -6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 -C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E -AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB -E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 -98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C -35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE -A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 -E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 -5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 -B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 -79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 -67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 -8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 -5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 -FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 -9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 -ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 -56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB -384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 -6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 -0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 -12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 -40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 -148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C -AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 -DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 -2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A -457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E -5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A -955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF -F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 -4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A -0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C -44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 -289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 -247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 -CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C -2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 -1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 -F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 -BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 -51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF -28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F -AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 -2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 -2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 -070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D -9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E -3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC -FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 -1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F -C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 -EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D -DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 -0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 -B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C -5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 -7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 -9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 -F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB -AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 -6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB -78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE -F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D -92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 -9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 -E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 -68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE -FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA -304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE -2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 -3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 -02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A -7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B -94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A -1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 -81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D -83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 -01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D -C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 -26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 -860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 -C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 -18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 -2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 -CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 -E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF -2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 -2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E -67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E -E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 -8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA -774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A -53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 -1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 -5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 -389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F -5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 -B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE -7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 -703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 -5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB -250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF -6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 -782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 -FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 -6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 -39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 -3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 -36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 -0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 -5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 -1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 -AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D -EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF -E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 -03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF -4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB -D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B -E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 -71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 -1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 -1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 -84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 -6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 -0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 -2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 -9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD -02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 -F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 -5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC -7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 -F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 -9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C -C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB -85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 -048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED -22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB -41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 -27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 -DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB -388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 -4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 -7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 -343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 -C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 -BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 -5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F -5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 -25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 -AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 -9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 -66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 -29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 -39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D -F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A -279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D -A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 -09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F -2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 -AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 -F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 -1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 -FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF -5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 -961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A -BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA -40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 -08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B -472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 -3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C -87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 -0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D -5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 -FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA -2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 -2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 -15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 -A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C -250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C -8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 -C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE -F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C -9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 -B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 -56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF -A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 -BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 -CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 -175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 -7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A -FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 -E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 -6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 -AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 -4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 -08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B -F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 -958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF -EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 -15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 -CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F -B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 -2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 -8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 -1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 -7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 -D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 -9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E -84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 -C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E -8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC -3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 -AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC -806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 -64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C -ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D -1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E -565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD -540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD -093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B -FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 -2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D -BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 -EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C -C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A -2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 -C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 -F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 -89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B -169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 -ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D -20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 -B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D -E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE -6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC -31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 -33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B -7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C -B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 -4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC -1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 -89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C -212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA -34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 -D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 -38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 -DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 -8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 -212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 -3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 -F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 -1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 -12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 -9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 -B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 -5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 -564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 -5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D -867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 -53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 -3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B -451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C -B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 -CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 -C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 -E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF -64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 -8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 -AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 -BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 -A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 -990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D -B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 -4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 -84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C -F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 -D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 -37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 -D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 -EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 -FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A -DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 -62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 -54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB -AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 -0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 -4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 -2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C -2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC -F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 -BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 -D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 -C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF -46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 -50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED -49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D -20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F -BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A -977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 -EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF -56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 -CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF -3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 -B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 -062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 -D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE -3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 -940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD -6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F -E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 -F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 -DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F -5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D -7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 -695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 -C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 -8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 -39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 -3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD -2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 -6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 -5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C -5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF -B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 -06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 -1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 -6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 -4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 -0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 -B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 -E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A -1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 -354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 -9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 -BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 -F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 -9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 -54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D -092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 -741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 -57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 -C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 -7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 -3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 -82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 -C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 -615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 -B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 -A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 -9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 -FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 -EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F -818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C -715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 -8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 -1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 -707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 -4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D -54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 -2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 -15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 -63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B -81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 -CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 -E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB -2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 -E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 -B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 -AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 -3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A -04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 -151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 -E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 -26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 -3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 -772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF -27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E -DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 -898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 -AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F -C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 -CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D -59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 -4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 -3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 -FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 -90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC -167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 -573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F -C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E -96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 -2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 -7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC -B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E -E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 -51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F -025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 -2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF -C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F -E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 -EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F -DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 -E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 -E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF -C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D -84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C -61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 -33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 -C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 -1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D -CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C -984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 -8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 -596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 -A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 -015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC -0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF -27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 -0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 -46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 -1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 -33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A -77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 -75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 -749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD -77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF -2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 -1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 -703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D -A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 -907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB -9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 -782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 -B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A -A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 -4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 -1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE -2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B -50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 -CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC -39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 -FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE -9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 -E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 -533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D -CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 -8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA -AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 -0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 -8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 -1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E -98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 -F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E -5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 -A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA -3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA -5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 -04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB -84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C -C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB -76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 -27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 -01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE -7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 -6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A -3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F -C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A -9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C -53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 -D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 -92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 -1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 -7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 -009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE -B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F -F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 -789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 -50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF -76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 -AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 -897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 -9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 -5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F -86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 -A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 -F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F -FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 -DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD -77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 -1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F -518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 -47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 -7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A -CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A -B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 -DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 -B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C -33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 -1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 -904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE -17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A -79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF -00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E -BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF -B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 -0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B -E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F -1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E -0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 -0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 -5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 -3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 -81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB -1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 -963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 -4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 -86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 -7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 -2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 -6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B -37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 -84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 -B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 -402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 -C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 -B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 -88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 -49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B -B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 -ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 -5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB -6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 -D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F -E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 -D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB -CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 -5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 -D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D -605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 -3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 -5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A -807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 -FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A -4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 -B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A -CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 -205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 -38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 -F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE -263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 -E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF -207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA -D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC -3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 -66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D -B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E -6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 -EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF -9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC -D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 -860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 -B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 -A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D -9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 -FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 -584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 -6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 -EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 -5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 -4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 -D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E -933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 -7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 -CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF -F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A -DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 -611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 -DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 -40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F -AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE -8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B -C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 -AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 -1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 -C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 -749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 -B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C -CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 -83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B -35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E -A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F -A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 -4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A -B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 -58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D -F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A -69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 -7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 -748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E -5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 -81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 -236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A -9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF -CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 -ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA -26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB -17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 -ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 -60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 -6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 -9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 -4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC -B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 -7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA -00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 -5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB -625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 -38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE -2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 -3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 -79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 -799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A -80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 -411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 -BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 -D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 -D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 -42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 -70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 -B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 -00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 -E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B -A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 -44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D -ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 -3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A -3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 -E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C -9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 -238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 -EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 -7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D -324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 -B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D -B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE -F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD -99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 -A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 -7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A -CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C -A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 -2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 -A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 -B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC -7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 -D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D -057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE -D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 -6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 -8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A -CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 -41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F -01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 -31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 -3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 -696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 -36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB -D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD -0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 -CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB -012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 -006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 -B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 -9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 -85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 -024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 -75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 -CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 -6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A -83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 -4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 -1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A -A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 -E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F -26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 -C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 -9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA -98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 -EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C -2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC -B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 -2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 -10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 -DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 -E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 -7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 -73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E -9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 -EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C -0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 -363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 -6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 -EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 -E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 -09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 -1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 -0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B -195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 -AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 -D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 -05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 -FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A -BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E -2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F -2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B -913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B -C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 -BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F -9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA -112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 -4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 -D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 -292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA -8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 -6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA -F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 -FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 -A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 -1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D -09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 -39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A -6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B -E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 -4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D -8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 -C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C -31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E -0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC -9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 -B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 -BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 -3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 -1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD -F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 -A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 -B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F -FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E -81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 -5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 -1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 -B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C -29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 -8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 -97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A -D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 -3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 -D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE -41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB -44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 -B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A -69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 -84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E -749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 -9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 -D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 -86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 -70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC -151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 -3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE -4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 -CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 -347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E -D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B -BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF -FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E -C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E -D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF -C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE -1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 -859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD -BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA -D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 -1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 -4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D -430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 -A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC -089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 -BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 -143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 -2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 -12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 -331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 -07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 -5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B -1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 -24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 -1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 -FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 -8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 -5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 -FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 -E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 -9F08ABD4F4B0889283E55500702185A841E328 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -%%BeginResource: font NimbusMonL-ReguObli -%!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular Oblique) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle -12.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-ReguObli def -/PaintType 0 def -/WMode 0 def -/FontBBox {-61 -237 774 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020947 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A208511C6D0C255B9A5BB2FDEDB4D399C6CF1 -94FFAC236883767C0F68F4EF84EE696B677DE704EC3B097384F2E673A1F51692B7B260693738C211 -9F7D90FFDB21EB715FD5B8134FC87DBA320EE54C2CEC6A4D6BB350555EAFF2EC4F84365CCC0802DB -B3BD0E3F0D9F858647DD637725C2CAF9557FDF842A0DA6A0CA0F1B442EF8EE6CBF2B03858468A466 -AC5883CBBD3815B283343B39205803C02C917D06825C09E2BB14609FA32C28D720C0E14A4B12D4F1 -25FF6281FF324DA33A56FC49987AC7D3AA206540F8127273FFE9A3DACFFE2B1C269D3DB9A811578A -C7D532C2EFC18376F473FBB2B32EF642B19CDEC1D6DE83643723E3C6DFC87F97A7007B6081894BBC -45C955B7001EB36211B26AD7A3D07459CFB33F9C54A40A360CB802FD202C8E93D4DB888B325CE246 -D02D1220ABF55CE646DFB45F07CB848406E470362F80CE4C02D98DD845189877732744CC16C7F566 -9F77EF096EA55AFF98AA103EEAEFB971731EBF3782E6AB725D4E9E35B2968689E8007C038CF25B6A -E69451A4731E79AC22BD268F56942A233E52D71873E83E00A1874E04D3B22E72FB2D0671AF81C698 -53C389B51F4A257373AEBF4DE2DA1E4DA5E2CA88941F81EAE0E32D982064C8AFDD7A9A600D56D736 -05B9463C6240606B3361BAF22AF74EF89AC804A5793BD512DA2D13F4BB1B73EFCA1E621ED2A65D66 -5AAD0AD228B3B7E3D90DBDB6061E172B686E92355A7C7459D83199040A368B5697DDC3B81DDAD341 -6FF4405E1096B1240EDC18A0E9985CA55A0D697972BB11E9F1BC30765D6775BB68C69704BE200EEF -4E11B78ADDB6229D8FA49A6B1525ADADF17122C0FFF51A08AA7AED158724AC4352EBB91ED0C157E2 -4281BDC1FD610195F495E87062A8C38E0D046DA4067EE16E81BC5F87E583315B973184E474064482 -9B2A52E0D37E249BAB31988B906F891AC904D1BB8901F0673AECE60ACEDE97B8DB7935C6488ADE8D -FD898027424AA85A11A3DA494498B084133B857017A6D507D70A3421235486EB3CF7613C59139FD4 -DCB92EADC60BB6225D9CD0599779217BDAF4813A453989B2E56903F4DBB83D83DF4837C86BB4C3D3 -CCF98F07A23EBBF7AB5687C3E1E6792E40F92A7A466DE352294064537505EEF3F9C308C9EB94506D -B02CFAE289F10005A6E42D2DCE43731A7AE368564B2983038DAD6987F67062199018395BC0FCAF28 -7A2B040C71F7325FA1E9A9808979B2FEF19096B98B8A0A728EB98F2BA3D33B49E3C20BE992822C7A -1BCCA5B4E4D1099D456D8D7D83C57ECBA0FF21428024F7572A1470317CB8CBC8679A974E13D88C68 -1338C68C9AC9557F97784F4E1C8C2E61F26023ACF46232CBBDF3C0BCC5583B935FE9FA09A562129A -8927AE73988DB0F7E733C6561CA7C9716DCA9B88208A715166F2FAE6D5EFF289A9B2EDCE813403A4 -16F243F1B57EEDE7D81E10C2DA4065A3082BC92A38B2457368EEC9C3C17296CB09819E9E642D7365 -F9A6EF430FC7DD611EA5FDBDEDFA72634AB599EB666A5DC178B0A0BD1FAB042792115EF3B6222C12 -41DCE36CB38B738F68B1B3CB489FED9E53315553F3C5C3BBCE40451E47B7EA53FD3D3ABA6CE0AD22 -5DAEE734BDFA3BF1D81C1B42C6D856A05D0924E03F7627C5EB24D7FBEA3BD85716207F961B56803D -BE046E81ED5FDC378F9CA52C14FD8544CA7C539201BEE06487EBDC30FF3B28E8264EC7FD5DA7E080 -65B0A9147344CE28DA5182335875E9F8B2347A44E33DFAA167232A5C3E69E8C5B58B7C7216537827 -C936F5741B87FC68753EB0D4A466961D0050DB59DF3195BD3379F5647F8CFED35DA952D7CF2DED45 -EB442DBFE992711D22EB228BDDF36B8D7DBA27062D60D2271EA8E8412F4290B58F5BE26FF06F0559 -872F9DE4DEAABA015EAB4904BA1F509F6D517C6E897312DDD571D769BC474FD378AF4360E8B1F103 -AA75F48721B9E0BA589319E15D74AC0B03D730C3EF708C7C504787483F134EA6297097B46D2680FF -8AA50B7A255563C88D594B912F5574564A1371463674793E4834AF11D14C7991E7FDB3A6ABF8529E -1A4F10CAE79C60D37429579093DBD041ECAF03824DF9C007E96F45595A524B27EF8774A83AEEBD3A -7134AB4435C80944DEFF5C1CBA921B0A41B9651968581DA4834B3C0E6D4DE13C1E792FCEED26A72A -DC4D9E3903661D8803DDB58EB2B929CE31FC9F50A694116B00AC9F3EEF53FFDB1ACA3394BF111610 -38F39917B022394C75A0D467D64B89A44E5505DED7D9C6B8BA6BA098F140C9C00E09200EB4828356 -A2D6BE9EC1D5524B09C06D9C6FCB5E2808050A339B5E5FD4DD6C2035A48FE9674520901EDCAD107F -67AC8C8E508E6003011978D77ED225F361BC0F86A98B6120EEAFB73F7377DB1E7213E02D12C330F5 -492511B4DDE08558D75D5B8AA2D56A3111DCCD257EE96E3446EF1C76F000C8916C4CE261425ED9D1 -5B58CED128DAA6C1300466E7B152BCFB5E6FAAB2519B8A98F26B29F98133AF886A0AA7E586A090BD -A1DC6120DBB5640885C609A8BDADEEFE5DE0DA5B75A8A29E92515E86E7E66BB29581E5AFF8CB6551 -D8D1103DF60D558E7987E6F56126A13DB2C9A04886C655064E68A0A20D1B7DE24DAD22BBFEE1B7C3 -C208D4FD6A58DE78D6A0A6126EFDEE3B1A9713DEE94069A9F0A2B392A2F391C4C75327803B53F252 -CC9EF0323F84929BA4716C50385681FF5B4ED54929821594F9026B7C1297941B178C3F8A704CE097 -60533DBC6CF4B18AFBCBAD039ECB2EBDC7838A9410E7B227924BED7123944675A5DBCA388B710F8A -F6048B03DFB713F881EA0F3B191A5CD989EA150B979059C8AADE403855815D8F7980CE6288F47EAA -37C1097D33F13776F08779063C5217D7408D9835AACBE5C071EA40C9AE6DF685F4A9827B828815D8 -F3A672E73A418E5CB15684EB6C6FE0998A386E124D76620446907F993BE16FE5AFCEC681F585601E -18182EDCFD3024062A3082AF97E803C47D32229D0A24596CF7E03F18229FA631175699E2F0D60FC0 -9C4F1954C5D12D03BFB4395F0E5EB6C6877083807D91D93CA4177A6B5A8D2AA500131FCB670E7118 -73F8A3C77575EC93A3ACBA37EA117DB268CF10D04AD0F079484DB124F6DC14A50AD3B0294F7157D0 -837D8F9A6060FBCB385606066401708C041594E0396A0BE4B8B66FEA141CCE4BD29366A986ADB98D -9A6935C49C57F8CD415E93FF8AE0DF75E463E02AAC68DF064C1B789B685F84E15E512404E065A39E -9E8F5568A7D97671AE1602605FC7E4933975189837586FB1A55007FBB0E91382A629277C36A190BC -85AF49EF3F0F38D4ADD2B5DEE09916B79690EC83473C63E92CF617617A66DF472A49641DA10654E3 -AD3880D060B02A4A6C75B51E4E9917A2B6D8EFDA12D59DE5A8E222DC7E82F02F23A9D3DBF637154F -719B14114DBB102BE5EB76B441D7E9990EF6420C2E80942C8AED5A1D0B19BCE115B5929AB9E145F1 -496753DD6B1798324F5EC1D0C7F26FC3045D7BB46A14110C99BA07A45EC16002CB754C0BAE7A1A88 -EB387BB345FA70B0A38AB4D532C2DE49274D4F86F2582728A2CC54B4C09D26C0CDEB8FEE6A42885C -6207D74953CFCC583ED82DD7C0F29D35BDAE5BB251B8A2D4B1DC97E2264DCE035E359DFBADDE84F7 -37EA6A59C23D1A64D963E635769233624F7682EA34636B595CCD064AAFF3887D916867475731BFCB -F7F96D5E5E1FBE6AABF454C2F504EA4E8EB382911560195295C87793D5F7739AD7EC7176E126413C -D4D1058EBD7D6EBEE14BB94A1ECF28B686411D91E07373E891F78C4C0A05D2E8D90A8AE2614F7FC2 -63A762D0F43485473A54C31726F8547701D4A38D20565ED1707847AED9C805780F062B847E668E15 -565CBA07A72B0BA99F03FB57D26FA26FF579C30EED0AAB6FEC1B5DBEA81AA88F16F0C9BE869505BE -18C1CB79657D91D6706E2A3F0BE9920655B93EBBAE2B4D0B5DF6BE622C951F2CFA42AEDBF7AE649E -2150FE87CDBF5C2685EF36051080BF39D864573A45AE2648AD97662B1F69787031B9BC43511FB841 -55ECDC3D91E2475D072BDE6A5207ACEA1E0D2ECB1DA8A1BC4BEEC335A5C7102963E84B97BE741C44 -58ACC3D72A7E53B1F08C955F33EDC3A0DC3E7308270C0F7FF814B111459985733C62E8863625A551 -837952F3CBF32ADCFD9F345E14B585B23ECC440775310654DAF7F41E56FF45F89701292019A94BF3 -0EB2D65E14B1A1D6BF89D4CC43187ADADF3F6E03A90ED01E5D876BD3AA56E5EE84DBAA4DAD9824DE -9984BD45AF96FB8A56C010B3C3A3C6139D58E9D69D9109DB18561B55EAD6452497840B9AE90C749C -155B6329716F0152A7AD52DBD0B8A25B9995E1416681F38FDBDFA443879B5C4C25AA29E0DCC07DE8 -BB161C36D76EF286EC88D57C74BF44DBCB4FEFF771D3BD82C8F4E233357C48E516EFE3DB9E60EF16 -8E2C45B54651DF9A5ACB5F1790F7929BCB16CE5E9F6A43919AD287DBC8E12D9F9E97E5DBAA592879 -1A5A02D39D259F3CE273A870906A643CC18D86E23F115D2A35DE6926053D8C84B940B362E7DB183C -4905060316B269223DAD309EB5AC96DEBA757BEA45FA3100F77F4765334EDF3D659E09BD1A5552DA -492BE9174DD406F8353A059ECFEE3709422940A8C369919EE1F22F7C02412C995FE93DC4559D32A3 -155DD22D3526D89B16D9ADDC30CB7ADA6E52D62C5F2DFD142D4D7B6E066671EBAD08F54917E31704 -1F410CFD8A3243F8B39459C418B7B7C6494551C6F6753A94072D09E0D812351D62916383C6E061F3 -5ED864923002007E626089772D269B298DCA2CC1F25D9BE43FD8AD62D554C16AFEB7EF6E5DDA66D0 -5A810F003CDDCFD2C02FFF02BB61344968091F67D3862C1499409ECCA137B9A2A9BE314995B818AC -CDAE27ED4AD583BE29DDE4E8C2400C5F8152C85709AD2A4737BAC768FEB70CE81A92C9657DDDB2D0 -BCF9169D272A063C75C150ADDFCBC2F5F2503DE3D13231AA8CFB396DB38E80197A605F6BC20EFA1E -DE40CF424CF221218D51BEACE64A3DC88377E4F3EFE43DB4F4FC0803BF61764104CFF0B618C90311 -98B094E20B0FACFB94240B438B67BA298E31D3F4E31FD190E48BFCE27B1BE29D36E765E7D295E96E -DCE09094FAC43B87E294818FDE9363FC7DC5EA36A1497EE25762D02DFA00A9BE53F87ABE62E52ED6 -F59818FDFCA643042EC13D670DED1980413950EE43372D31AE2694B83DDA42E1FBB049F7E7B7E69C -93FFA3195A2462423DD2C022E5141783FFA07E192AEBC5070F08B23AEC9142EED56DA74F93BDB504 -78DA55DDD0A9987FEA131E4CCA0EFC51064E4B37632728261369C3FEDACA100F1AA78FB718ECE7A9 -F56296C5FB43781E63F36B0E1D34BB748EFF35E1953941F94D1A9B0FA474FD68B47183F2AC53A63F -9F1D30B9B89C5FE54C3765B43DB403D57994701C133E42B950D9BB1CA202F15B5E590EE75598FAE4 -3D5CF1546572770BBA9A6373F100CDC61DB4E5EBBE0A93E0E51C86005E333F69110B1C8E492F2BF2 -52CADD5B73E7D3EBB53E759353F1EF3C9B8B39C230D13AB7158A5D92EE4C452F81F6DFC18803280A -A023832FD0DCB482CE5AF615C952BC3F7E58F6417D69775FC7C0D5B405AAC632857736ACF32B2EE0 -F2A2C0F3B3CAD483C614505BE94706322F2A2830FC5AB592907D0291ED1873377E7A6158140C2CDB -1B0E27EEC9CA50176102200992308045CCB5A169B61EA0546778B8D280737319046716604945A21F -2A1CB9E15E3A5DB31E0FB5A3B0AFDFDF6F3424B7536D473F9756CA3694DEE4301FB1AB1AE47128F8 -D2B461C051C1B999DBB010E78DD13AFCBBA6F7D5226D540527F17881A18F551B3EEF76A7E28B4FDD -879381A2217EF2FF9F9982E9EA70AD2003B862D7C36D57C5FF9FBEAAB56040FEE973EFC3B34D8319 -1960010110BA10694C17B7635AE03CC1CD087C0B05522A7A791F0CA34022A3F5860B536D9551BDFD -BF560A07F63AA4E687407E5E48584E689591F1B52671213E430A708C06A34D2E1D51CFA6B328A122 -007C81B5EB263B967746961BCFC8772F8502DD95898724ABF369B0877F3313A167F3F714023C229C -5757D4D46FCD9B4AFECD093DCABE52B78132CE9AB6225C9A344C4BF8D96F2C50C4272CB9AA0D606F -013B2642F8C880E08EA2822C8CF5097D2CDB64932FE195ABD5FDF36D3BE123AEDD8BA2F82A8A628D -BE3ED6129DC0FDC4BE50D5574AE4FECC65062E70F4703BFECB35EADE196294FE173EA57938679DBA -6D15448FF44C0D1A903B202439DA93C0B0E612110068F8079219AA89F435E44D0464F54833BEB338 -670BD820D941DF4B31F51B895BEDF833F9C43CB7616DB80F988CE72FD3C12C7D49F740CF85B4766C -0ED398EB837695D102DEC16E24B7475A0F5DDE88FBF2D6B94F126417C811E8362B9CCC52D8891C13 -C10937AACC228D621D4712CB9DE0BAB60EDE2A97E9292BE04E42E6D3425594DF56931A61E1F96172 -6AF6E6891D63B240E6E79E5BF30C052091D681BA1102409874CFD8EDC3EE2BE331676E31AC00F807 -91D1019BB789CA4F5907F4823B002AF3581448C352BB67D80FDFFCD1C5BEEF60523330AA2C045600 -8F62DEB55E69AC2F86369FAB1ECC90D2487954E61117A90D9269A65DFBDF297EBD29C3DD1F62755F -8F289C42A534F59650685F8576EA2FC5D26B99B8E3DCD3F1FEEC73131000F99AA9868EA9BAC0B56D -AE2CF46DA6CC1D18C0AB8D77BECFF7B89992175CBA2E22779C13DB9DF53FF5B1C8FE95E164997D94 -202C37175E562C8622989B075CDCDE173452C064274354D5DB8F7D5A78D48AD4A103B9E47500D08E -DC7C51C1F3CFA7F43C3686A3C24A7EB5018B0F419961564F87E212CE0A0741AC68D6822C7AB9FD68 -85F5D0B2AC249CB7F50E2353CC4B0A6A24562F564FBBC7090C3FDF1284AB0EC615E0B3FBE132F315 -70C8A65C814F93910AA4BB80D516CB70D2E1D11969238E6F022D628FA2F33A0A15C4EF0CE7F753DF -80A8AD9494885A1B9ADAE6C38AC9DA6FB0A61696AD3A502630252AD7B574C841117D34BD20BD6581 -217D977B35F5D04E02B933E1E84F5C090F6615AF484D63265D28517BA74BEA8876FDA332A84AEA12 -E6CD82B94AE10A778CD3A216ABC08495EF319F06AD6FF8ADD237D911F846A514FDBFAA8A1EC8E0AA -9F80F11F1CE615519A4B044F3D1CF1A17D7F3D2174222A5FFA8B39F20197FF6CAF250B6ADBDBF519 -1C525070C8D38220FB501C223F493D80F498621A02EBCCD6EFE914F16B2A435D60C0A1A453E288A5 -3D818FE1EDCA7D55A26A017F2EE47A816E90D6C3FCDF0035EEA307DFB06D2BCCE43458A67354A4ED -B6E5C57233DE4FBE41ED07EE5EC77A5DFADC4032138DA9E1B74428CAD02A913E40152F8063A774D4 -FDD4070E4B8A6C089F199AF7C529C277E902195DB760D81EC655DFFD1BB283F3C5AA8BB58F2476BC -797B2892E94414ABBE96D4DB93E280CF7DE23EB852E7CA954D6682A6F1A4BE0507884C2A05AC863D -2BA73F3B54668397B6C54DC2F4183130AB414875F3C3D8792BF7E5FC4D228DF87748BF0B14178DB7 -E3FFB7891D700A1E9520D778B095DA80E4801F53442D5C073EDEB706A5DB8466FFE7E701ABA9C364 -A37169F585C883A83713A61C9C3BD9336A667EA4E3DB5F4DF6BC6A552BE8D3EF093639EC67E5FF71 -8959F9902477F5AA894ED2D1CD312ED82EE417D95C49C96671B23FB0E1738E892ADFFE62EC1C3D4C -BEB6CD089C98DE8D247DF7ED17DFA2959D3662F105E8386D75AD308480536959F8E6CF8F2C6937B0 -9F2E8137C811327D6B165ABE46C51834A955FE8306D10033F8C2A34667F13A8BA831CCF52C7A21C1 -3DB92F3E77B55CE291F6190BB1D194A33FD73151C3F61ABD2D8A0C9BDE90E796BD996D2D0094DB2B -E98657E751BDEEFE8A43EE4501B98F0CC6D80805189438872A60047A8CAA9039893530A3E5F6BD75 -BB466B25165737C939AFF3EA59BFF4A7DB09C2A5B36B8A1F0C6C5E5870C7C9412589877EF44F8428 -4B8A53B5B74315CE72D2EAFC631BC4CC2E5B71DC958B5A6350CB5F615C3A4502E973622E3E18193B -69572DEF1D02303A375ED60ABA1BC8A179FAA0F221A49078FE15AE13383585FB45FF4D5F3BB3D0F6 -D8BF62E9BD6BAB3C9A7D38C8A5AB0BE57ACDADCBD02B1DC7952D73AEF702D406F62719922BEA96B8 -FDC9B879708E794891C7A0A42F2CCD6812C3F4DB030B5178E3A627C3E77621D312CE4EBE815CD387 -7208FAD92761A5396B67E835222609F823728B1C987857CFEAAE21F2AD5EA9D841212993508091A4 -A2C268BF1D8DA1C650F6AB93995E7C13A3F84DB55748C626FD09C0DA1E3325CCB0BF091E996245BF -51EB486680162BAE63B6513C74CE83B92359938439921950D713C69324A87BCE67B45A030C9CF10A -DFA0A82781D49FF224AC57A23C6CB321F95915C5E14E41FA852F66E1E2044A9E7B1DC3BE9E818515 -D28B2C4D2F2210098C39557067062BA4239F2AAE28816D999955910298A450741947A9A1AABCBD8A -FF3530626089978C87DFC73618C044731B6DB8007739A9699ABC354A6F985E03C11D750B8B9E9AE0 -5436205FAAD1B895B159E2C90562B82A62EA1A7FFB501767DCE2B11C51D55A17529EF5ADF0A0EE9A -96D0E7E89F68E50EED813836531B4B46E9071E84AA413F4135CC882CE832BF78ECFA7CAB0C9F64EB -92C86DFCD1152BB7D4AB33831AA0C139B555967F6346068D5C3351A7A4368EEBD2933E6B9F789DAF -37EF536FCF965C397AF1B7F98AF864B301F3F440B7ACF704B59540453678FD6C1504519481893812 -3E2F47B265EC4F5CF2172D394543D84CD4281165CBEB11349B315A85DEB2D1699507B0C8C110C726 -62EA2959C4962FF093AA5EE6F21F89B3CCB0149CEFEF1855B9A48D28BB363416C015A1F4EA1975C3 -D8807F616C5817C8162536176F464A198EBEE6C97029F15F414275A39B8219128B8C8542E9483550 -7FC2D3908BB0EC375771280B9EBE87E827811418EF93E52EF70546891BFC0FB34969FD7DEA4CE752 -4D9EEFF2B46BED908C0FB2E02EFC1D1624642EAEA1CAC1EB4841E020532E88E59AC890E6C3F44734 -B99722E9816402D1D0FDF8045C5481EC055100836EBFB48E9FBC392143032C909853C9BA38A19363 -141BED09DAF02FDF4E7CC9808321CD0708A1B45270BFFCC3A0D7C27F7E781713D5DECE82C72ED303 -86B02D14575A1A6447547ECC7FAAC1BDFF332C92984758E242256C054656CDD2C45D46E67AEC6F83 -9F95D74E222A6EAE12EFAAB723A7C816D4E42D4ED2725A794743F67597F3DB8CCDDE45BAABC25726 -B851E02E56341EBE69E4D91F2A233583EC816F18A1DECBDA4AB69320F55E730617360FCFB8AC2D2B -737675B406297F7F8C4BC370CB084C22BFEC5FEF02E9AB290282F7B153F0A4B1AE569F1E52371A43 -46A748DDE09336CAD1F5337FC3D7CF0677091E59480AB15021E023E356B0E1BAC6C6471AD53625C7 -0206C338536F4D0D40733AB217E2297F86B593717C61458B6C93A16027CC886A8CFDC01EF19C34C9 -A608B95A84B6A2E31454BC03C10FA55CDCB7B1EB7DC16AC1E93981A46DECD7E7F00638DCAC568744 -69A2D9B45CBC81398727E4ED3DB5DB31965F358D8179CBF934EE2C4D652C9CC211807F070C80E3A8 -222B4C31FFEC8DFB9EE07A94C973462254BC1B1581903EE6F9AD91524A787129A63FCE048B45BBE6 -855826750C586B6B23B805FEC3E7AAAC079576949A06F422FC2C826BDB78AE96135E9E2C20C2B2EF -F6171D610B2EB8635ACAB7C5C5ED9C9FFC26CD54D2FD4CB9E4294E178CECA1E16CC8E3FC06518BD1 -6F4D63AE2B435753538834CDD9D8AE7DE624006CE688938031336351A6578C304C2E5480A3FCB43A -8BEE4953DABC30558B7790C6E7A6F0F9FFA557C50417407AC6A0DDA1E736F7070BC89455FC293453 -3DB004AA9070734C8C2608A07330E421A0220DAB99F8A77489132F6413ADB9EA637F3B75948050E6 -67276A55BEB09D4153DC126BBDBE0DB9298AC799A943D72AFB769BFA1488D311BEB86A907EC9385A -AE4F77835DFFE4389E3D9ADED1B08BBC2B1ED6084B3D1074A326CCBF38E06BD026919107BD03BD9C -30470DB779508DFE0DC82DFFD2DED749E872EB7EB9DDF509D5319865070DD76846C34E4E43691AF4 -29AA40DB4BF2CDD50B275589987D8081F7C5A0461AA5D1455A660178A94A0BA0DCB69C3CEBF5EE04 -26D6534F6F919D9795AD6A0E1A1F452AF3B4CB2EA54D6011FA809132421D111EFC51174E223AB6A1 -3596411A9723079231B050CEDAE7659CF168C39AEA9C6902C2CD37D25492CEE00096EDD63DC7643B -667FDFDE5B595DC54F0A72C2650E1E46990584C78A5CEF9BFC3C5F88CFB0C49CD6CADD9DBA675177 -D601927D75C6902B55AAED0E9E3CB52A577C887D581B3CE6201A1C77C9546CEE5A13B92963337F17 -070E2BF9F5C5E86B84225863874618AA50F4DE855DE567BF2AB7163944ED43DBD7F4BBC0E1623180 -7C43DCB47B2EB694E6FEDCFBE26194D2D9943A1BFE32AA1E5305F5E341EA021F91532162978DD1B8 -C5295A5E7551E2DEE46DC2347C6B32197AF430AF3BB676A53BCA9BD1EA88678377DC0A9A86E2AB6D -E29E3E261BFD5573C66FB5687BA9C0544D894A759866B066E1DB5C66E60AE071CC3A1C4AE40197CD -E4EC723F7B80137619DEDC99AF57A5497D6E03C1C9E672E74F48F6C213A3CFACF2699CAE72345A51 -C71C1D69348DE5BC5F443EC0EADE1E76A8A33066922CF3869E3C1D26A3B34E540DC08EA4DA2DDE3E -EB17C16790DA4EF1A3A76D71D34B788A87838BF2A5A3DB8176F9C097D2320050A79EA6C4A94926DA -11ABCDCD26DBA09FD33F30AEED977E8B5AD928F3967F607628859429DCB4ECEC7DA3411BE35A0385 -1017B535985632639D378CDCD13B00FE537A49FD9EB6DF1E3AAF5C41EBE35721FA6833C2FE08AA3C -FFC3477E7FCEBF9EF9F4DAE62FF78F319481C3F1E72999C8A493EC6EE295316B58A5CD62FFAB62C8 -96E521B678342F04BCE1613CF7F6778CBF5227BA20504500D743270771953ACBD5C6586432F3FA6C -0987BAD33B88BC6C15D29C4B3CC54A9DD72A2357AA5BAEB2CB057CDCE72DC80CC98C62B16AC50B4C -6A7641379B766CDDF990DBB2FC7F9CDBBA755B6E3DEA438FD6699C30A99A8B3178E6D613AA938120 -835E517431D28114BCA1AB745C11FE6E52ADB82B9D3D53A33BCC49740C93017D9531ECF43831359C -5C93CB0E926DB440B139E3125CC2E069B1CF6D96EF68407F32DB517242C3AE0BC6723E560B0F45FC -7F87A5E44E1751C8B7F9F669C24AD5CF16F84FB03BA121B86B0694234D8F2C9C947269AF96FCA08A -78F736E4E04ACEA44C5BAAFDE360FCD8BA6A59724CA86160A5527FD564468123D302DB45173C1B21 -6B01DC5B6D3415B13FBDBBD3121A5493374B3357EFB131CABFE5087AA1D2C7472B0377066B3632C8 -2073C6A846285CC953A8F28E131CF587B35217EE498D9A1DB57B063CE068DAF55D8CC1771C0C3099 -9CA4FDC5D67BE4E7E69418F6334BC6149000821B89A7437CCDF9A6A0ED702D5968F1E04F7E4FE9FE -C9D1E994885CB624035BBC5426CB8EDF0456828F8EEE75BE491B45FAC192A405EBA25CAA4F4C66C0 -DC234D7B417628DA5276C08260BE512B2432256C401A66E3B583E69D23E9FD278CD5F2178544D054 -16B9B4F61A88A4728AF2CEED07C08E207F31D644E8E3BA1E4E2F9D8E30936BCB9C6AEB54E37DB46B -D64F2ECC1021336D0564DF0F18E5A6B6BA470233D8D41FDD9D1079706EA685B6D8A740570BFB78E3 -984BB155C3155C69BCCCB41CB51975EEA1C1B4294CB546CFB03DC31BF86EC3BCB1977E8F94A771CA -B09DE12A82F1D6C791FA7800E5A21DF81C9C8FCDA78622ABE75B54AEEA747AA4F26D563200992E33 -7231A430137C720A17D44F3AD6CFFE63B2DE12D3184BD3E151F955786B8DDCCCB290C42718F3A219 -1759DF76371C2FC177544A6C425CAB14AAAB31628A9CF9D71B5257AFF0D59843989CF0D747375A26 -DC9ED29B66AC2147DA0168306C48C2484C70CA92F33C0C138F92F276F5EAF5EA3082A8A1CB12DB66 -1633C2F71E3B69918F509060AC949FCD52C36498A2ABB77D139DF1EB33E3B846A7C1BBDCEF5DEECA -4EF0AD250CEA9C2751E13EF7681E8FAE0491CFA6C144DBAC1FC39D39E76EB12D3EE9CA159AA77D27 -94F0C433345B135BA632F544082BBDC9471E9FA3AED3A7D465AB7158E8AC97F68B1FBC8D368E2350 -45C18EFCCADEE98778D894D96301F903283C5AE355A863BB0DC5809158F7E108662D04A5C1234915 -E7BD5B4C30F9EFA55E702E54F87FCA06FB321507BC57A1E55CC117E21AA4E3A4DFB77C1A949EFE36 -6D93F2BD827EF8CC16D387CA82AC039F77FE995BE6D9AEFC87F8D809E90C1017803BCFA1C737DAD5 -F1A631EBE6894AD20C70791665E7BC71F21C2C3F4462F60FDE75C8A377CF49BE99314663C6ECB538 -B1BF021B2F2174D2B22CF6FAD115EB0ECE8A2E64097A5FB0A2AF666E1EE13276AEC59FD0C9D4BFF2 -3F71E835984E5EEEE36490C54E077AD7355DBC98BDD37DF29B3DDF8C55480B7349C4D17322418705 -796A8C521FFF920DD11773FC44FC631C7D6E9B420D7965D7F62EC7385F2BE30A51E2D796483134F8 -40AEC71FA19ED1272C27F98F2CDC9C7E54DAB585AC1703ED08F5F9E825564902EFD08EDF99DFD494 -44C21FA6BE16CB8A1B6D0C8A5ABF80A50BB8D055483176FD0AA07EBAEAD88FD694F96FEBD60751E5 -C4D8F9BC747D4F4030BCDF9B0370B7A5E0A6923FF60DEA16EF47F886F10CCEE6956ECF41A21F7C59 -6F3BC78299A9657266807E01762B2B2878E551914CA312C2A68D34CD91E4F5115EA1FBE801346E14 -AE529049089B6B0273E258785773A9CE8E4B6C4211CB7C2767319576758F811CBAF3A3FFB41B3130 -6C49F3798B698A47BFA2E3CA0251C4D90C0B02ACA28C611744526906791D9E157E54CE4E1BCF5B68 -6990BA8AB7897D624EF00EAB92CBAC255AE9177DA9F0D86447D35B452CD2F337147B5D3EBBF2B952 -35778A72914EB3707EA78294B3A3BC4ACB19FE87C72AA1D982E4B822F07B115CADF4D3E7EE3D1BA7 -08653BEC6F0A352A0C33252ED0630E7274961896D461EE8BF523D5911BAC1C8AC763E5FB11FDD217 -4E1F129675969C195476C7A5E18A81BF9A11ED9F2336D5301E3BD32174ED5C933E8C85D6272EA218 -52A6F7E2AAB174E0965F73E0EF89E906BAFB181DBCF8B1F5AA0C12D12C6272753C016AFEC2EC9F95 -41B8757874D6F2E061ABBE8B29281677246305B3C41E90418426C575BAA216CEE3C5EC29B2FDEE1C -77C14FDF940792F48A56AE80AA33E370B037CB28A7373F882022AF378F26B6006A049FD3B35074A8 -65C97D153352ACC156992C00DE26AD21C982C71F0EDCFEB61593BB40FA5F2CEBF23C4FF34A4F4BDB -73CA273C269242D1C6117262B7C47771F2619FE5710855134A80FA8F92BB2425CF88940CA3450F81 -234ABF2B11775929B12CFF86442B2AA0F4243D324A5983E5D1829775B3C7A111D5622D1C4E2B2A2F -982FC8A95F789881416DCB34950A393F4F1720D2212F3D343A17683060182355DE9E4718506D76C9 -184F8DAC55788D7E603CFAF4907DDE965A49C323DFF425FE88C09AA4A4D16283F9B14AB9EF1BB885 -A954034710B4A9DA4C88A8A0932B18D139A687303EE562EC9F656F12F3E8F27DAA9C75DB0FA946FD -0E1A982BB58E040BFC0A49A4AD8CD668493FCB573C849EC5474049A693CBEBD4D79AC7515047CC34 -7A9A7570C90861F3ECFB57B9F53AB9C0D6B05C8C570A8F3C04D58555A45524C98FF091B8F8A422F2 -E0E9E5A7B7FF69F1CEFC13E42F1CA276BCD584516D266BA6838D5E9CA9E9854F50C7D92CAED61AAC -AF758A7C7BE59C3BAA82BF32B691ACA3E8EB171E08AD22C39FBE586A54E6E4DE2CD86B31138546BB -8DA5834B2C6E4838547A1B67E651964E43988C8036931088904BBB589CA901E7EBBC094C0DA81E09 -1915D9E46828AD8596FD0FCA39FF12A6C27A359337F973809E81B2E9E3D43B3146F2516667E607FF -EB9AC80FC95A7B7D4DED551FEE0F3561C70DB2D69ABA96673E39E3397F1C3F8FE5F48BAB8AD6E0ED -8901F90F6CFF24E80CB5DCAC498506C4D01033E497C1241E413B022227A3264DA68BC3F91B35781F -A2D018475C199F43CBA7D3A0D5697B45321BAD2C394B207136E1E16B41794975E8903EF2B2E1C33F -87CF72C325C11EC0B92FD3890ACDF60B521DA32596763BDFCDCA837ADC6F26F129B23CA32F9CD39B -33E64576970DF3C05B8DCA4BFE2F17E6C5678B84D69494F1DBA9FE0446AE6AFEAA1FF245C07916C7 -B7569E6267C42B459435A1D116CEC665B311E404171774C0ACC8DDE96B0D9167C8CC7D99C4240559 -2D745C4428755500EB4719340D2FC6BC215B67823F69FA949C08B5EC985D7AA87C9AC1F9BCC8994C -6CBCE6027B7D1E0C22A83A5DE61DBA05D4AF6884C95F46BA7F253E0B2337E312916E163CAF9DB2EC -56C5425990FE73EE53E42B3BCCA1CF642F02B0C5ABD529B568E9ADFF865B9DC190240AD78AD226ED -884BED3C285B4CB0E3929E805C67F1318D186504D92085764B70DE6AB5AB6990F181BDA50FC31262 -348D980EC76608CF08176C2502E065AC2D8EA5CF9E2D44E2B70A7DDC7B922047C471DF8A0B2087D1 -106B5BD8A830EC0E53223CE3C96EF56E5541191167860EEA58D696EC357EC55799438C90156BBF2B -13A0D5C9EE93227746654ED73EA5B9CAB61DAC5BC690F89C87FECAF9AD03BD39E438F43B81D39E07 -E0422F94E8B096AB38C88BC2E1A043811D8141C1A35DD3A6DBE41620E83C8ED3A379CD80D4F9BC30 -41BB44B933DACA7C5D4427AE94A176829F24B5968B713431CB8BD9F53080832C6B784CEA9B515687 -F121983EB9D9C9CE8BD4FA3BEC48AFE64E643B7BD86D8383D07521FE5D091392BE124CCC91113604 -3824B686988E7C83AEBF406D2DA88FD952D0FA9327F4AD04C55FEDBFBFA76ECAE8A176C516479AE1 -467125B7EB3C9E7C5B103BC0C470946346DF271F8EE19DF7E3FF7478C35EE059297F4BF21A5C7B95 -993BE6202E897776952A7ED0613A5CACAFA731FFC633CAB62963150E86EDAC796026CE02EB235B9F -7A54E0B0C5281567138A612BAFE409A818C216DA8EAC5EDF9D1E3A1E3514AE50735A111B4D2AA083 -4EC6C11E290D58FF340F82F0E079F1C7B3566F2336EAA45BF72BCF88569988DB5F65D4C1E59B50F3 -41E45A899656A0B522847ED567B49CD5284FE50E5F8652CDAC1C076804F2B2185F6A51ED19DD4941 -2E65A0D2DBC844B75E2DF71B009776D9F97A4C6F786EFFEB87A307FB6B912BB659DC2BCC6D509A9F -BDE87DE8D716040A8551B6CCFB7743978AD992D14D2B85CA052E87326138DB196C24593F8F7ECD6F -486F85D1666B9DE2ACA6C7900044EE369D223524664A2790B773F9EA26E0A4CDFD709942A44298B8 -249506EB9B77BC887DC0EF947DDDC7CB3CFC6B48F060DBF032A11884E6C226D9D447A5A458CBA325 -D57E144C6DC295262763E7BB8FF6A0CA473EB7661C12E0E8E23EA37E8AB3387B9E54686F3E57765D -4067E521BC1AFAE52394227793C737C19208803F2F2DA920B553E2AAF94EB992AB17E31B58C15CC4 -AA8A1B444DF5B3E7CD937CF03E1F7FAC63342731B4589F16939D16E8E497A74CDE5686F529E9495E -1603D74875288CF53271DB9313A4511B104F80B179FCF213558970A002E945281BF3AE51E668DD6D -13D9E85152747F562CA0B75DDEC8FE9FE31F8D05B0F59E802888A7A4F19B29954A31108D2F041367 -DEBD6AA1CAD856BDD1427E9EFE89956FE28D500CDC6A0CB80A76902A08D0BC6705583243F1DD8020 -749B257EDF4803BCAA653F7FD6D8B91690995BA5EA3EE92FCD367C11601C6B8ADCEDCE67B16C596C -5D200693AC5FA15D4CC6CE9DF7A71C8A925E99F5085313D60FAD25C1BBAAD28D4AC2B69062D68F39 -0530A976319A3904CEE44DC9451E441AAB4780425440F8C499B81460B5D3E268974145117ED843B1 -71BB14AA84C3A084A7D8E07B9979260675D5CE6534DC176DDB60DDE90F6A3674F67462EF78195F8D -FF74FB5882B079DEE31FE92816F16CE1A70D07752EA25FAF5000ADF79BBE7D17EB1BD2F9BF6CDBB6 -F078CAF97986442680A8FC4121866F9CE86C385DE34E30D8B9768A0136D9EEF79A4B38EE99CBB9A4 -D32316564C9D56996E2595753EA71BEF684834FD030D38BB100E2332B026B046316A53270A96DAB2 -182E994E91262FB03D1AFFBAD623F1689228409884F91DBA153030870A7BEB2C7EE2DEC51875B137 -33B7929041F8D23A94904BD54DD4BC9B432DD0C78DD81639F46D686FFAD39AAFBD1B6C1A37E248CE -48F23E12464D5379B4AED0D50B5A41577E6ECB75270E9AD3EA7D0FC09DAB271FB18B51DCFC0069F1 -5D72546E6C51049F3425AD005F88FD7F02042DABE9F097F9D6A076B30D8CD777B1EC12BD163FDABA -5972EAA61E3C87E9AC007A052B1A3FFE14D7D43C7A0ADC89B1DD4CB4F9C762A84A6C0701494B2D8C -4E4E1A9245738BE4111805C2F153A20ED9FECF2DCF4C8F7C3BAF84D60454A7403D4F5F81C6404173 -A7BA81BB0CEAECFD493D877465DC5735D43E3102CEC57B8A589182FC65A4704661A9E351FCCBC731 -5A87E62F65D24EEB9CEE979C6E10DBCF5C162ADB926EC8CC9BFFE381F6B8A3AC0A19D1631BEA2938 -731AFC99E8EAA39BC75DDB3A39D01AD8F0BC1838F4D674B9BEE9F6F7BE4D9C8BD97E8D171EFF330C -15B76614A1FFD25B3BE19E4A201BCC850F926ED51616318C965AD2F0E56F9433B1247C6D5B72EDF3 -D408A3E0674A509BF30BE813A5E669D72B978794683CA8B85E3469EACB167C30F7666DB5E081B81E -E99ECFBC1704B9646B1A29E4A4CE5654CA8409ADD60145DFC54225BDB8485E39CC98CBC3F38FD0A7 -97E5DFC2099452A2418C6636BD2D5F6B24345ACFA65F4E7DBD2D0AA0C1776A4920B4466C509BB5BC -7D6627946C4DCB38A27098B7B5BEEDC2B3BA18F927077F71E38644597719652037621BB350BB5369 -DCCC073954026E6438FD8393DDB3630C4473F06D9FB9E422E435566C396B12FDCD5605DFEA232171 -CD8EF298786806E9159B84599C26D4C7D8C3BB064665CDD072E2083190372AA808B2268B3FEC8878 -B6420CA829BCF995DC20E067EE6B8E44D2869D51BA3AEDD1763F7F8D2CFB8EC41E6E9E0129DE5343 -1457960CC51D546B10B8B6CE08A1C2B79FBA448DF9783D815608A16C55E589DCD8EF6B04C66232F4 -7A473973A35618000D79B8173258B7365C9691DDFE47B16EEB08B28F881828B946FB5D6FE10ECC6A -FC4EA1F762E90B3320403382E42AF4885B183AA48DB5E4DFC9A54E0B4FFBF7C26EB17A4F13B4BB93 -12234434FFF05549E7587BA0373ACB3E31418BFAF400D8938FC6466B94273D1735306AB912AAB13E -31DA3541C1733E2A7E4DA5B82767D37F3084AA7A7C488CDCA7ABEF77D19E42B4448ABBD346E9BC28 -8ABC4540C0A1CFD0BF46C5BC7454B25E27E9906A3E6CBF678BFECAD1B19B4E42398A210CD567EC35 -FB115D5C0DF0EEECE593982056B0E1D14C292F70B3E049984F8881C8B477956AD3140B4AA22256DA -AC0D11C4126808B5B9F922BCC5F24A77FF352E2C621A3941AC07A20E550A69C49B1B87D116EE6F2F -970918F0F1A501166AC4423FC212E4EC8039AC7F9C212D864F418CBB92948FBD588228108FAC1AD1 -837070512305C110F0FC3FAFE6E1529C2BD0DDE868A9EBE5137DFDFC5C12A3D08014BF0EE27B1080 -02AAD6B607F5C5C0F1B1EED3C552919C9A2E97204A8127F97B1066607ECFB47BA95EF2B51F007C29 -3B2F6A63041A9C1120D9CFCD5357222E5B02DFC73CF94CF9B5CB00EAF073E9BF253E30E09B50341E -57BF245A746EA31BFFD0B00201C34CF0881BBD1006BC9BA7D420A48E53686B598BEDB3449924EBA5 -8D5DB1B1B01AE2BA281D5758C99EFE38ADCE18F7B182FBD0D0622A6EA497A4E7C00C7D17299A2765 -EFD8DE376C214D01A21819451FC04A0277EC84A151FF93903D61C78AB7886911E36E12526ED855AB -43F6289C1890222602B8EFBF15782B374AC1E580B6E963403D6D15A051DB8558F2E61C0B9476C6DE -5D4861585CF515CE951732F20D32969F39192FBF1690D242AC04D47E0C53D467D0FE4656B9526C0F -7F852348B0437737CB0F29ECF9B54A5E17185236DD0C16349C3496F3ABA569EA20E343F6D771210C -39DC932DC65ECEF94575C6E76902CDF6C8C8361F9C757A2577DA535187FD526699917CFE0AD438C2 -A758727B306BC7979547E68B94E87ED820614BDBC649D469EF6B4E4E3DD2EAEB5F80B22FE576CED2 -56495467C76A75F589460061E03F3A1B065121A5ABE3E2C51148B3DDC9F624C97889AAF7FB84B158 -C015EDA5670746C6359D27B0C2BD65144F2B88A64331816DA904572BE398E015A9924218B3EEF951 -23AABFC3AC8217B7B4F691219A1C9DD0A3EDD5C04E63ACBDE71B423522532561F4B71B7028415C34 -37E346BE728A415596AB749015C1D59BD8328E39A850CB98085B34B57FB52DD1D154F98FEC49B3AE -BFCB1672762E4D2A1ECF02787F59DF1EBF2625C3631BED849B298C6D226BE4E6EA2AB66A287D2BA9 -2A6C9C612A5F849B3CB3C25F17164BE286F6E4F5E7E4C9EB17BC68AA5EF0190B64696A570442E1D9 -BDD1A30E7692524E30E4B4C3DF84481DCEC6E10E7308E65DE9D90099F3FABB3F4F766BB86CC98594 -6D2003E21287761A7386CD8461615B570BDA015F5EFA23D18E83C325EE444EC166A1A32D9818C2A6 -5A092D44156C06D3FD079B92450B8A491CBB3529DDAC7D95AFE8EAF33777FBB265FEB8A4B9AFF2CE -CEFFF49AFBDCF6C4197497D3B448866D70EF28D8E4B17E7CE95F43F64BB48C4A73EB84B26650F62D -3E5199D64DB0B5B87702650ED0B850FD5D16C848D096E4C7E61BC63B2A3ECFC099CD713E12C91A65 -77A88D6F55D348617C7A49890A86EA8FE2045704B5ED529DB128C9B19EE129E5FE6498CC97087F6B -DE96007C9D01CE9CAF75646E5A5B32BFEAD9362A52223D746943A2D09C536CFAF78E601BC2D2F0B7 -63AD722E3A7AE7069D65F9F2BDED7278511D0120F5EA071D41A69F8C2A2D720D3B24B4BE61C83FFB -EFFAE21B0560A6FD1A44E53E42E0D10E0E93F421A8A7E167BB65F0D7F1DDE2809FA3CDFD931CCC69 -B119C83238C1C00EC100D8E7AB1C7FB02EDE97073C8A5860371A8132BE391EB1C397B61F93876FEB -438C288EF2E38DDCD182A5CFBBA994A94A1BF818312CD8234215FCCD7C240A15AC01A885E1179E5D -7D6305DC2F534BAA141F25EA6A5F356486E5FA0AE3C6980A9F5E8E99E7AE5B95AC42977510970245 -4FC951E4319AE4B1DDC9B07D0998372C0A95ABA6985A4DBE6DC633154FAA30ACE689D36A7F17011B -F29CEDC58A6692A8B3B0A5742E6CEC2F69B255BCEDA762DEE72F125EBA98891CFF4D88AAC14188A1 -8D81424979C9079E44890D94EE094D4CADDC1C7AC5F6791FAB8849CC0240A579ABD800EFE3AA4EE2 -F78119A3C2806C05C2B1F17940BE73984982D1C0065433A9BD658EA31AC819DA9A11B87475BB565C -C294B6F302FE3F7752ED9B963C5279B5F1196762D0E12E6DA46FF9A0CADE3876D7DF695D8965CB4B -47B351FA3F759811269376B2C3134403633FDE27C9B024F6BA81F3E1699CF64A426618428BA6C326 -6BF016C5DAA5FA4CC82FB6DC23FF2D742160518CD3A65ADB38E53F1067076CA1625466E0C64670A1 -564A54CE14DC5C57D24A12283FBCBFFD0FD594AC2A56EE58B552F7586825E4FB1EC23F8221711692 -C8C56F42272B87EBFF3865191F1C11943BB76D8C0CFC53ED452AE49404D2C8193ECC2A7BB8CFBF24 -870ABA38D2CCF7869E9363DC0AD94FACAED5922B324DC3B6FE83E7B34FE29ABC1EAD62B49FFBCB81 -1ADBB5148D5AC2743E3A058386036FADAB6FF071BC1C3B8023F908B6FF48DB0AB1C9C67487C35211 -D40995E1892C8B66AD6C9C6203F6F8B513B11117B10DA8725AB45B4437B5A88A96AF3178D856D601 -196E8162868A83DA64E408FDDEBD14D6591881EA652032CF2F88B3FD6C0479C8F89AC68D14D01AF0 -CEAFD95AD146E68FAE01A07F39E7A0C5E4FFA6D6A91D710827CA5ACFE7D1F946A8D7B67621D60F53 -41F32C12A6EFB03AE5AC5373A382C044A276F6B41C173D0AAAAE0C1DE4C3CC71EC2637225CCBFBD4 -5EAB92BF39357C57195B410F74283585B12B926438AC72AFADAAD2D0FA2CCA728C8E86BD3FE75D47 -B8BEB96AB13B5480F7A3D5741EB51E3E40C21FF2ED7D9221D9877C7D1A8CECF394E4023FCF8C4EFD -B38B839499FF5CD96A46AB4FDB46F35D3B48B91757C0159328120E93CF1F2739E936E28908FB1947 -1D3AD7F6F1AD2BD1EC364986A411CC1B547D0CA104FBC10B1CA7B638A60E75485574034561DB345D -DA68415146AAC632DFA34769B6ED7D7D4694E92CBFF4EFB16B55495908102E85E827FC623CF1BBE6 -A13CBF64E878E1A2A159948B5529B75E071744A5F0E50DF18C110B0AF117CE7F33F8C959D4C98CED -5A9D492AE6F56DA57B0F17495DACB130660BCEFB064FD8309D965ABE8D2BE98F6898C1B7A39CBBE3 -E75DA0FFEF6CC3945CE76DA3BE915546FE8A5310130AE0ACAA9AB73C7E041C00533B4BC7724657AA -649B9388B791AAC5EABFCDDDEA2CC67A0FD0AE9BE37DF9AD40636538EE55A83F60E9E026C64FBD8B -220CEB46E67410144A520FCEACA252E8165448F84D8EA083C793AD09B90B3EE83B73FEFC3365C729 -E3C738894B8C01C2F8AEE0CC8B114E1175EFB44CC4C6CEF5C8754B1CC7CEC200AD8BF1189D741CB7 -5BCA4E88BE959E32216AD33F674F49AB20A354CF3969F1611A95D3934E148831AE7C81A7EBE3C524 -4F743E66A82E10D16CC09F8194EA7A596BC5981D833318AB4F7DBF2ABCE543E410B649D18D146F01 -486159683DF61A3F880F9B21EBFAB77E908C6CFC79F89BA5F51114F0BF7C3CCEC7BF0F3B057C3195 -CFBA6908E31E0DF10DF69163C9DA7BABC00E9A580FA7FAC202910615BD479BBF76FB8068630D1EC2 -1CD2926D351E869E16C2CF1E023CF04D4FC61607DAEFEEEDFF5593E6023492F00029E2AE4B4A2C14 -50954EFA2792F32B4934A768F892171245A1E2F034E2B9F39833F1B331A19A386BAACFEC8C929BA6 -B67CD8922BBC9DC005EC3976575D5B0508D0717C6BF11123EA36D8FD37FA77A6F1F5AA84D4AD8D25 -B2C11D1877A6E2F9B74F3B5829FAEFD4F7209CE9785AA6FDE68672554A6F29D8BF03FE108ED90A7F -58690FAC399A8AD3A26899072B832874DDB629581A51B3325CD9EDFD49E890EA8959DB937DAB83C7 -77F2A426B967AF5888C33A3635B78D647AD6BA441E222C958EA58D61945F781D7EF409771B89B202 -42AD7D07C2EF592CBF413C5FC89EC30FC9EBEE4BC63709AE33B65EE3091CECBE610B847E12C556A2 -79C8B114C3E460822D3330ADFD72BD69F54C08A81848C2002A08326CF3B09B1305490D35AEE59179 -08E1604ECE75BBE811A715AE8AF7EA9C371B322D0428EDF4C893FDEA607E70E1B6F6614947326101 -EAEF18E29BE0557D2A92CF1FC1505E8B434BC368CE07CCAABC0774F8A63E1073FBBCEB3F4052462A -A9008A1E53F188C9EAE339FABA74AFD6D60F47282CD9FF721F64BD51787F3C13B5A6C5A5F7861171 -0111F5E0471E206D72520F1DFA465F4A23C71DCF99A04CEEF11B0E3BDFC35B7461A60753D3AC26DC -50A5956C9195A4F5226388E0953DDD03AF128A98F03BDFA0602CBBAA20AB9ECCDF7255962A332E16 -D4380762E498FDA4885C64FF5F9B480DA487C58E78943DF62616E6E2C69EEC8836DFCFA9EBF58938 -A878F3E792E8BD8C5D6DF557A5D82018DBAE1CA9C64BA5AF8E21BE1B6680FC5DB22422220B776E9B -A0BF1ED2B7212F8BF111EC8C8C77B223C05EB5E5F1CFABD2D037F4BA0F9503E2CD83F4519D180476 -63F09E308883F5DA5228F83045FF41214D2273B2FE0A9017D5E0557BC2A198C35D1E7E81F7965444 -5760CBA1D3F05EA4B90658E53FDF0823BDB1501ED51DA75C47395073D8980D1E3504E3F67DB3259E -4EE73A87CFD96F84E221796573958D364A51E635FC55478C9CBF9AEA16B7D8C25F2115CFE4B7F598 -54E24968833BA0D64D1D332A666DFA2A3FD71B05A26BAB7DA382907B13DE0B80871DF184D3622B62 -3D7E09BC32A4F6EA2E6DA450A906EAD36D53FDEC7F83E101FEF32F4FAEC581B000686D86A0D3861C -1E67F18A4C4647F51F978484D9E3100B37BE9D20AE84C085461C1FBF929C669E936659050C2627AC -1B019837BAA75757F5B0A82E8AE9CF2111931A38BFC94744E2FDE3F8710342AC615286E4ACE7F269 -743AA05463AF537D9416230ECCA859D8C99B7C6E70BE7FE11DB698589BE9E11900C8E9582A4EF5EA -94B5F62820C90DBC022A620EC536E06CB8BE7526A789996D0E741AAD980880A33800A6FE92286CCD -02C9CB407EB31FB95D9C9F4AFF38B37087AC582C1F7B64A7C3D2202BDD62E9AEB31BCA85C4CF323F -03DA9D318B91F78FDC0D266630F7444ED068B55C05461C97552366A82C2E743CEC353D51028FDCF5 -403B3B74D379B82EB69C4380ED40239E15A86B2E5C860891E26781CC111FB5705E3B7C7AF1946006 -54B5FA1B5FC54FD0BA43666E7BABD2C91C859F393ED49F7123EDFB648A3D6152F2C17F7E438C0A63 -8968AC06B4FB3F77F64F358AE063820BD33F0213C85C40E4D97ED100EC2DA1C2E1EA258BF107AF67 -5A9D995F60BFA37222B9C2B325C0052BB8537D2B27DD43A129C7E8FF42757B3AC9B447703D382108 -DA520B8B3BB3E8C7295B776B44ED28F863B8E1F81B0BD1DAEE8A171525D09D2620C04DD3219D880C -2ECC79282DD7B1772A9CBBCA706909AE8BC7798E6EC7375189B6CFCE8A875849176E5913B85A18FB -197A33CA4B5B4058603CF1FA79A56856B43D538E9ECE117D99AFA73B57E307364F553644DE01EDB4 -6234EFAC13046B6E047ECC8F63942F20097AD7ACF0A45C0501A95263DE9439A880D6B5C5214D2918 -0A54D7FE9B2E627EF49E189B59FCC78745E878E45B46C0A648955D3EA8C935113D94F92EC963F66C -F3CF3A526BA71CDF3CD4CA69EFAB08B7389E3390716892A4872BD29DC1E0889A42D7FFB4190E9A8D -05D84EB9C5741BE6B02716BC75E0106F5F94BD3778BE985E03860D27E44088C3CB2A059DEBC420DC -E3A8F4087A9548485E616C409AC400DD1C411CE4B6A229D091B253EB68F06E43511EC5AA6ECA4D6E -4818D6AA2068DA1AEFCA377611BFA816B5215182432D5683294D67A7C1FD76C52233087CA44943EC -7280005E93145F5E7AE50100C18364E1B36741E9647C4DC1F68A58EC44095920FDCF05532F603717 -80F78420077EF5C24D63E26040CDDFF8DFD65D871DB943F50CDE84900C1372EF33FD8AB9889C82F9 -4F61A0E6842219A0F39EC7B232CBF802C4A744F33159432E827006C7CA77E480A48A9B0E6A876158 -8A3102E3F98A77BBD62A3A23150FD140D3941773BF7CBBA2338FF37B9EB640558A2313E8824E8E62 -0331568A9B76F4897198A709F9313F4AC40827D8C3A71F2ABFF02BFD57D30D0B14012FB5C39B85AF -540DDA0ADC27A85B31694E8D7B61F9D9B476571022D98F2D768246550A877293F3FF6ED918A498D6 -A600223E1A61890C49ACFB60265867CE9464F9C32C59E94F7641C3873FB4FA6EB237F8ED94579957 -270D6FD640BD9543E683F2372CCD7B60AAD269E03A72C5CDB732B128818D41A6DDD2BC139F7D3911 -F48E1B1D263DD4AE8E4CE1A686F3A00A2CBF48978631CD243566E22E68F8D7397134A3530EA3745E -4F1EACB4D6A5FD84C3011094F37573F7F9902305020C53926716D4780C6B0A257BF711AD94C83F1D -41A02C1C7DD203A3E6E4B14EDA2FDBB36B063A3E074495F626B0EEA146D22AC33457F44F41675967 -6D2A0566EC2B726D2F0540ABF225339F02F406D4E7A62E5233DDF20AE7C86CA0CDD561F33C422654 -BF2DC3685CA91BB9D4B09AC8B15A24A99FF56E2894F11F7BB4728FE8F0F5B799F74F475D2D01F61B -7E9E0E541F7FEB8A557486D7DF2CE50927515D833BCAA1CD9BF7A650BEE9E003A5951C98ED147C4C -52F64F692AB281984EE65A47E44A4A5FA93D6F18D276D3B01C5E5F6135AC6940524CD713DF4077FB -4943E8AC927A68489EA52ACF7A854393CD027EB52EA2DC6234EF034F3DC742D6DB5A67FC21D22B97 -146B9C268BA97C30161CE01EDC69A6A1F05EFB0E06F22644E1A368F0E2C0C6C1C832878E0614B74B -D645F5CB293CFDB7618B837FFF14A1210AA061C8C81867244305B80DAA73CB25A417228E9559E7BD -52C119B0CCDB7C4DCE7E1B9F7E8EBBCB575E5BD213BDD6DB88769DACB05E5870232F0EF82F448559 -187423409EEF756BA6247493BE24CB1879B5DD822E03D0ADEA1EDBDD83D3FC46759C679B921F0616 -F27212903F728AB44C1784E8A7DCED0DF5625A7D3F48A20FCA34008184CECD145CCD98E31B79E174 -CF107E8F35C40C19D86B40BAEE6164353408801EDF75A619FFC5B6FAF3F3A95F64795CC40C1F8963 -4FD8C13852D265FBCEF834C800AB46E3E8167476B23CDD8AFF6E2F997C99A86A9CB30EF8C853154D -0D89EEE9B9CDC1B4F27BDA32432A4173B55CA8D9FB50ACB2D886AD8E5862FFD5DFF224BA13C8B8A5 -4A7F1A9F987FBBDBC5A3C3D762A5BE309D5D926AE5093C40AA47B3B1BD828797CBB9BC9FEC9D19EE -A73D2A39764816113A8EDC6CFA6E605AD578FC8E30ABD600658A49ABCD5AC54655D29C50FDB72070 -169D1B389F114B7C71EF95A80D82AB537AC8C165D47371FC142A51625029A990A577EB1618480D72 -6DA93C98E5C5F24F622A850CDD94BADAEA91D4BC32CD50CE69E9F00E77DEA8EC1D37916398FB7092 -402605359DF08AFE7B99C76C2A7C70383F28A7C000C696F45291BB8F074791798197CAFF1544C76C -EEA8C9E6D76EDCBD92A86DF889481F3BBFF0865442264F0EA40D3CAA69AE467A08003F9C30FF7F2B -77E767580575398462D5B1171DD441D8986F33BC7BDA17D413EBB6B7A32642E33F20B284BF3EDED0 -02352FC66C6F7741A542155F4A159CD778BE56B9492CD95115C1A06189A216CFD2E6725965A13DE9 -73765A05114D9A5A4BE0615AF8BF6A5EAFF84468B849954D15BEAE1CDD57C435788B331905C01421 -B50F20B184506A0BEF746330BC98E9C89AAA8F9D102F158043BEB6A682059A1C8B8CF67B2F3D7AF4 -D8BBE086254CDE53765E3226BA2F95AE8063649F9F94BD9519411DAF8A0287307335668190638806 -E29484A4FFBC1E46B1800E03B162C23B1DC0B4C0DD3C7ABED2F00762972EF06EEB9BCDC7B3F39C70 -BE32789D366F073AC3280C273DFF2979507671B3E1E7685A9A4F0FD3867F96DD675BF05F25ED986A -79249B75F182FD73CDA2A6A66D693E4CC5AFE3402431B2C816DA1486C34BC9DCA4E2D51C868688A7 -787CD10ABB9ACA14B7181369DE89913CD8FAB58FC84519EA2AA14E54B7A8CE474F213E07CF2DE2E8 -88093DEEC937526816B71C96ED75FA9E2EDC0F9E6E84569C12BB8E39AAEDBF546630745553D6084F -F9524FEC6A7264F88CEB7EC3358E923B392474E3A48865564431662988FEA768CE555AB0DA48BD52 -6A84B0CB17B4584066C1640C1023D91F7869EF0C4D701BE121A6E3C832010427490758AED7A2B30D -6028F2215AA44E86D852FDC67DA5CCBA79EEA863BAC9EDC2535B66AB0E54EC4D4411390FDEB8D1FB -C1743F15C3B68DC92A8659E7A892D5E53872EA51EE8CA7EF51103E87C29A2714E907C79DB9CF3744 -1785D2F73A1EE58550111A4D9BCCBEBF2E39CD3B93DCA300FAC3ED1ADD8215301E5766C30C8CF296 -75746C5A77BF1FE3CD75D25CF193DE8D9AF02AF8F7A6E8F84B548058CDD3C6998ED13463FADE7391 -26D83D3CE2C7201F955382832E32C10DCBCCA35835985B9A93F8E3B0208BE6E92428787C47D3808A -0F77B8F1D76E6BF6A17FF81CDB065180E03809D03638307BD7BF5CEDBF64904E918FC805AC905379 -928B816480F6E3BDEE47042CBA98539DA0E113B1A5F23EAF1A3210BD18561985E6436EAB90395DA4 -77C7A6D7888D2377B3FC4169368357D880CE041E1F7C875E956600DB7D9B35D1EE66BE476E9DD806 -4CC02230276829C2C0A098F051502E828A0CC505AFD8C3DF293DA1508AC4D25866BEEE6BBD5A230E -9C2DCDD4F06883936381F476DDCD86CCFE15C2CE3C3243E148CBE603B8513A7CE7A6910A66A90B70 -89E5CCD4368BEFFF2BCF8E918BFE0A1B069AB2A914CA7BB91A0AC3B3C0B060FA1A0316F6135E890E -E549315897C8464496CC6DEA0F7E3AF43FFA4C3281156067582CA255B1D2E80F999A3AC0402BBD17 -01824C3BB524130F5B82A45275807BC2F3A0655EA208F968B297F98C369192C8ACA26BEBA7DC4506 -FBD1305E2EFA4DBE5375281A88EE2D6FC88FC0A755E72934B4B58F6DD3BDAF7171A4A3C776576735 -2492BFA9A7758504750AB7F38754683B70E9E293CB1CD7B23BA62BD7397ABB84D7EDB22EF6C3F58B -3EEAF656E361747ED04020163253D1CF3F905B5E85F83FFF30AB2778CAE43781667C0F65C8FD404D -6B9202A99EA76AF9AE1236631550B66B063847180B6DCA832EA8DC4A6EFDB674B5A26552A7C7D54C -2799C7D4E03C24F661A91103086DE3A90A774A6988347656344CFBA06065AB22476BB09FB68F9928 -C0045F2764AF643CFEF0516D87FDE6DBF93BAE2829B176CB507BB99835E01BAD5E55C2F8798C93FA -35EB3FEF02CFA31D3D21B030547F86D27B9448D68E2B155A65C742BD2999DAA0C3AED64447B9CC67 -F7AF33B63AFAF25F3CF7EF86657FE8F952288CA4B691D369E8F1935CDA44A180A6767560C2ED3F2F -CC38B6BD7991D4170C7C566D690A8A25BE03212A80871108D18CCEFF246623E653107631F29227D6 -4754B2208D19F84E547799E691CA473780DDD56AE620CD953D5133D135E3D51F237078FEEBB73714 -54EE633CFE238AEA63F9999E32850E6C197687A0EC4E5908D2A18C5349627E336AB5E3185B218228 -603A4B1852069F5EE849D571B8387DCE1F8F8E9FE94FADEF128BA83BDD245F8C1C27C11F2ED1A8AB -2D6D601726842CEE744EE7AAC6B6FA16CCAA39DBF5B3B1D47339F31DFA562671A9CF7DDE6915FEF9 -F19B3E068A464DD350A3AD146D1A241673B5112A4A8768F976723E6E184790C0604506C46591BEF2 -106C40789B733331A80740D59ABED39868F80BECC2AA21C400A0BD0CC326D186FFF9EB37680F1EDC -32AC78F9059280D07B5FF2E354FED545129FA5FA8F3D4317FF21E027602FDB2522F049BB545FF4DA -60248130F81F4E348373142F3148DED038AFBA818F26D5B49FC02DE9800D894E9239C88EE0EDE431 -F8083697CB0BE3B497473473E5714717C914A1A926730C249413FEA2615EF72BDB0906933387A892 -370F77EEBF62D26CD583EE643B02E323821379C0DC966407D36AE3CDF646B95DEDC7D7FD0F28E950 -78F12DFC0D6400B327B743C548A0A3517A175A7ED963ED756B1E107AE7087E2446BA702CD4E26E2D -CDC1A8B697108B5B5E81E9F03105F220C72D4AEBC57665887C8C7964089FBE9424120EFDB14D76EE -F8C6F7A30B13E1AE90CB9D93D2E14BDE47F4A1D05ED5B18D32AA39911B92D24C93976ACEB7EF597A -75161923A73B2CC761785493D0EEDC08B5AFE95F3C006B41438A0785C962B070DE2BD096CB63B847 -C87539880AA3D3FC5C345E0992D7BE77C6CFF4948617FDDA784CC55652192B0ED775129C4EA4245A -41BCF3875BE319DA0EE2DAFEFAE920CD2B6C6C2001762F88C0C5C05053025C0349DB17104360FCE1 -5D7F3A8E30ED13155A74FAF91DC77B8AABDD6FBD5A1EAF255DB209D7F2B90822296B5603FB5E2CC9 -5CBC5F7A6044058B8044ADCE73ACFD896177F1F70EAD2F6534DC3AD755AB2BA87126D63CA2E9C441 -DF0965BDDD6BE494E58D6B5057A561D1E31BD38E92CB73C1465AF6B9C001F7229059BCA4104847D1 -639E124E082F7364B56548BF8112D0EB461B316B2449049F6A476D36D6B7C0C1126C08F2E9A1246A -3B5B21E7C8FAC6E23B82E33A7783E4F31F0240E96E69C9444E7D7A928636CFD086475DF1E0A28464 -81387BB2010655B9F81A0744121699B4905AAEDCC84BC5D5AB3674601DBBB651EDE7B5DF05C8A463 -DAB41F79706D285C4F9063997F7AC8CEF35CAD51FBE5F5BB1B3FA6DA2C3ABF2B3E925581349728D6 -DA0D59C1EF6444539742EE9A23A5727F20CF9377F4F84DEA420607015A30FB14632D084A2DD181BB -02FC3A84FC499B318156B675B9CA3CCABD87FDB2497C6705FA70EBA43ADDB6CF961B30E8F6AB9F84 -E1DD8D6DB3314B34B7F7AA3BBE19D5BDC75ECADFD8EAE19E07B387A1FC586F0F30DB695926764B54 -0D89F1D854B0FF86528AD9523CAF56371E29498C11AFB2F4D5202670C834E930103F039D13348824 -16A49BF93B84FD3CF1209EEF7D4994C8302436C0794497461C11F5B8BA152BACBCC08AF8A15F4A4D -F3EFFB7227CA97FC21D2D0356C93390C749CBE9750B821F1A7BCFAE2C8BC6D9A27F844D8AD088320 -79ABF0EAD8ECD4EA72846DFEED021857F33C1ACE4C07BEC90398B629814C498D33BEB375B9A53DA0 -F926FE6E89E70322C72CB2DDBFB16B13EF7A4F50DF783316584C6AC2BD7D9029124933133B2229BF -74A228868AB30EA5C3E87C78C3F0962199480DBCADBEF53BDDE45849DA857A4FD85B96682F1EDEB8 -5384929DEE4AFAF84C51A09F5D572705673D885070303FDB47DC898F874E103A9E7C1E894115DFDD -AD81549C7375D4AEDCCE2E52C13E5130B47F206F7C5AFAF1F9EE83DA8188D70B473269CA280A6A02 -DE85300B93D8A4F6B402FB5DF58F1327470CE11CC63ECEF2EFAA396A6680A6746A20382D9529B58E -7CE684B39AC00F7086BCB47C2230DF0343BED9B9152A61C9826AEF9E00A1452D91305CF05490D4BC -0BADC9C6FCBFA93FAD52C3A80705A1956890497557C0873EBDCF61CCDD2219354A4F5621AB33B119 -32065C1D990A9B68858331EE7875CAC855F98563B14EF9E1060BEA90F195AFFF94728AE935453438 -DAB35123D0E2699475884DDAFC7307A5CC06920F35341728D85965F5BA86F261CFFCB1E29B429F97 -6970D42D10E6AF6C4B792B4384122AEF2448E22A58D3AA007743C71324EA08D06819FED14AC1F22A -4F0BE4787BC8738E1CEF240677571C65804ED3E748D72E89C94B6F310BE748FAEA31EE246859CAF7 -A1EA17CCB5B246C87EAB771E2AC5D378650191081514DDC2C66878E3766CB20DC49F630F2743A7FA -ECBE9DBE9E815A3CB57DADF2BFF5EF2FCE23A56298A30A2E052FEAEFBD698101F9DB992613706693 -CB0EFAF6F60C8BB5E7D0A50B3392B9831EF3A304A846CD4AF431E9F018FCD3A5B16387552D55DAEA -683D36257418AAA0E7BF8A03ED7BAB114D7C15119E6C71C1946BD7903C1C42E115E954619051B853 -BF05AE316E15E619A7DEE498F771E809D9435969C1056402725EF40C0200E083F3EC6E0EC27B8ED3 -8DFE32EA0E5E156AC36C4BB9AC5ED111A11678339703F1B9299345AEB1F251FCEFA11FB3101CC499 -907DC862B4463D5523B9B25C5B69F70AB6B29CFC1DF1ECAB8227EB3ED1F882E90B12080EE003714D -403EC43B7B54491446B6A3DD6EB641EFBFEF060C45E873E7398025B1CB7065441F1753028F6F8C49 -A96801C0D598E098EADC96A21117F817B6FD6E6947642F93E22425A00E8F6B592AD50B317B69C0F9 -4047386A45E5EBC9504FE55451A01EB29DDF9A41D4BAD85FC84CE280971E834F06CEF49C8C20ED2C -EAC889F158CB14A8C070900478804CFF1D1637CC880C81AA287D8382837FFA8F41FF3C9DF2F22CB2 -0044C171E4815D0D0F6C22D19A52114E780CECD71DAF63427782E85E463DCB333789F496340E8CFF -885A9D9A4250118B439C71C6BE51A9338BE29251AA794EDC67DEEC6337FA63CA9B03C1C9F75E733A -4A918646E7BC9792486CB5A4BCC5F84FBABDFE338C3792254A3EEA3D88903C2C47B91E076259DCCC -8BD3DCA90ECCC832C09C45141C6242026BFE309029A562C3EE0FCCDCD40E5CF265ED9C3DE582884E -0E14819DB98B3AF734B1B3276AC41D43384EBE73003D15CE39FFCC04109583390E470F431B4407F9 -8550E138F96C4564B494E5480F47C853BDD237E27301F55E42A3BED18FADA152572B7B465A581DBF -E7DB2619365CF16D71BF8F091862B9FCF04BF8D0859A76F46E7B5712F2757EDCE332D3213B8A30AC -2CE7D7797EEF6F30904906B0805DFA7CA36D32A20D989858497A66CE72491393DD79332003D55C09 -5A5AB5DF761C4BE5C041FA8407263D604E53091F7B6B15496245DBBEE96A63F10FC2978D99E65731 -28689366FE8B0BADA48B50185B861BAD03E3600F22BAD4274F2542B635F6C7944BEFC3BC741BDEF1 -1A8DD659038CB40FEF2E16AD1AE7EBEDB7D9BA15FDCF26355331505A386DD7399FB999535D6061EA -BC61DD76EF3EB457446F29D0BB6EC2FC0AABAC20B27A3C123C27BC27A76336D0A0A6D456DA070367 -4D959A4AFE428E2206A511BFC80039ECD56E75F69786DA0A8084D81A66644DD98B6018681F1D70AD -E09BD9BF3D16D68DD5D0A03AE26DCF1552549E459FE190B310A8776B2C8468C14CA8B1B9A7AF2956 -507A3B705AD75A17A0EEA7FE089273353CECD07BB8563465EC8DECA0EB42F43FE3664EB5F31E1D13 -24185539B28D508BCD065ED576D8814ED3FD637D576F027927162344AFB0255A91FFC616948E4E35 -8867E9FC76A9AFFACAEBFFE110808C1532A2BBB0DBEF3F010E45FFC73F228D28F12E98478B27397D -8F456781ED9E19711DF2E9EECBC3FE61F7493FDF1A59124668A91BE51F122F93DCA4BBD22DEEA339 -E6EDA3D6EBEE03DF958113E1CA49C8398D2C59DA6764882EE3663F62A55AE50A7E91B4FEAD1B11FE -0D50ACCC5D75F1A515F0C53616A500F1491381DFD0E2477E402AB0CF9F67D501A442629C8593ED5D -25A72EDB9746B02F2B0F0759CC9CDCB4C9D8B4519C8C617E569B432F0CF6890372AA879CA7DE46E1 -10D95E230A4F0E52CF65811C54365DF4A3E40D819E2FD379B47DA3233D0DEF0EFBCE04AD8BAA3888 -4F6A69FE5C373E38AE0FD0241480F2BE7CCD18AF85916D2703A049779FE7398FC47D348454CF03F2 -2EB3FECC064606957898B5643464845445C25C0C7D685C8DB042AF5D5882174374ACE90081C68678 -9BCA96AC602EB41D317BD652293EE628951875641661EC86A2C40A42E8F0813A861D41A0F5178E55 -43651CA0E99150462DB5EE0010F00DE6D55B0D7FD7EC5BAEA24ED3E90A7D6A0589761922B91A6A91 -3A7FEDDD3B68254D89ECF767CE8E27F966426A8B4FB1B4085384FD09D63E288405B78A646F44C87E -EE22C8596B13188085479F75F63D3D97A28F9C8306FD207DBFD38DEDF0FFEB7DD80B2A3292DFBF1E -D605ADF1B33E85B010309E3EC058FCD922B1325FEE71EFF2DBBC2E68DB52D513E024C01D47CF657B -B61C9734649A4AB63C0AF4720EC3EFCD82DD3CA6E80BB63BCF1B8DE810A0C6C517C63B76FE68C0B2 -86867BE102424FC31C4937048B6F323D039618586FC21731005D949E7D802A430DF8D2F0CE99F2A2 -376C2953EFC4184355E4D12F422C9E1E25C4DF38DEA334DBC89B540E14C61A7769D77115CE8968FB -76B27D0863CEA2496783114C24D4CC816DA884D953DA3F9B9D3AF8938BC607BF26A071956CA07E6A -5509EA2F5D80E5CBEB98041B197FAC760976EE75B470DC20AA023BA3F63C2876EB281FF5173BB490 -D6815604517AA1B1FA0631401B3C1A04CA103E2CA4ECCD83874D9CFC8ABC134CC0F9141D9AFA5684 -8BF222342016C556C14B3482482DCE5D0B6EF1AB522AA1812BDD8DD3397E05327EC12748FC480842 -9B97202E24E1DE0C7C0D272C046BA73B37D30930C5DE5A47D96955CB0F5DED8F3AD929A8B42D2839 -0458F5910A0F93610F79EDDB27078943DFE17C716D65F96589769349F3B66AB7B8C004CCC59EF688 -1F745EC7129865A76F9C2D029D4660CCFB4D5F9D412BA3372A27CB175E9D65F759575CF14A5899A8 -D31FF039AC02DBD8391C3397428AC0D5717C005200790785354813C8859BE90E0E17914F6CB9C674 -F1E9A9648657B54E5E1F52756C4F982DF74E73F6E4D40718C71D1D0E2420FB7462FEC9E457C0414A -96E475C6BE2C10437096FCA0C942E995A9ADA789AB637B648781D32DFB68E62E91C2CE7E13680F8D -31ECF8C824885FA7618981CD05FB335AA111B409C59EE337DF4E5F9DCC920A5FC0D620DC07F20DAD -63F4FF5E0EE5A2F390AF1C32122BA7780F210229E5A5E3ED97BC1C3CDDDD456E739CA782EDBF4B81 -0552368E9C734B0C78B0B8E3F8B2DD782862B74318871BB1EF087828CC173D7B049811FCF598B8EF -DE4D9BC5447F4848C98029C854F3AE461B9D46DDAD8CE67A521F3C811A81A396CB0F80F3C8D8EC88 -30532FB7F9624F7CAE0F8C6DF875073333DEB28AAA90AAF486AB8C932553CE697B885E71EC8E40C7 -835CD5D59A2C695DB9E51216FF9B77A15B0DA63717FF25B05B939E45CF7FBE490E51E9344213B32E -115C2DE14D76DFD5845088DE645B0E75042A61D82FB1753C445AD0A956A1263E5A096B681D3BC51A -9FF32EBAFFF7ECA8B59D40F0937EEFF38312AE57462C7BF3B1FE24D2BA8DFE84515270E09063CE3C -80DF4935E409F62EB4F54AF16A186D4329972B9BDF15FB08461B688ED49928429226CAD9F67C9D63 -6D1375CBB7B08A5631956B7FE29CC9EFA8D75C9E4919C8C2C54F401D2E0D7BFBA40C50CAE214D210 -C6F3EA5802339F63FC4C1C1995787617F3EC2C806CE44CF8E29F76606CD5836F6E5A2E423CD791BE -CD3F112F25657DFED9366FC4ADF90B685CCE4A5698E5FE16D7542B913FBC01B288DD13F43DB2B1ED -8CCB80159DBDC90A8132125DF8DF547C4851CA609D1F6F4D647741260E845B457937787827A89E37 -CDA06BB191669AC84B8608EAE132D10177F3FC384980F3A6E439B048A38D0D6B9CEF09F3F2D732AA -71BD058169D6D0F8C9D146D9DA046774027559A8B3843F6116B418427E78476AD8F0F81E8A6B1209 -8060FF7DD686503F972D6C42FD6CC29C083AC3D72E3751F21D2E44A572EEC80E81EE44C90FAA7AFA -BCD3ECEB98FD4068F6C3A4DED0E6CEC523C9A0054D1FC2A8D61A4A26F9BC250B8F302416924AB22E -722297888B85B9C12F8DFD2A744CBD143F9B2514C1CBE988D9CB4E77D90B2EFD5C2A528355A35F7C -4AF039C7D1D756305967B847D4ACBB81263D4992C001E2A262B9FEE2D1F5022BE5B15E1D8F1D67BC -52227344EE912C018CB73E5F47CED54FD202627777BB77AACF3EE6B22706FB2FA9062BEE87E22CD2 -802E7706322648DAA0C624EA885430175F746E1F536F9A8E1C610C4A761D07248426DB63C9319A88 -A3FA449C3FB8AC94C6003C745E6BAD717A3B2EA3862D1E08512A98E57772A62F85F1E2FFBA40E2EE -43AEC11203DA9CE5AFBF673436F2DB6AF85BBE89D802F7A9E5FA25A408DB69E51F0577DD26F94CF2 -BA2FC53EDDD6FBEB534AF15F74F66EF8D14E7FF77D8A5D284C8202DD5A6053CEAA606BF925992382 -5EF4EFFAA8D878652A4CAF2EE43ED26BF3590402686C876F86C1AE95046E527617CDD3C429BD4CC3 -F9654D2C76DD4102471FF746FA9FA379B16DF96BFE3836D43FCC0B8E95120C27370049ACA4AC313E -1D50D72D1814F2566B8B29FA9C9C20D0488743722A766436776783B939171FFFA00E04805A8B5821 -4D4F114F7B9C3C17CE7486AEA2BCC895ECDE809502BDE57981318A93F23016F056A421B733C4590E -34AB08BB348DA4A48F19B6BEFAA1DDD2A49A6C440443028333CDD48C85CD698ADAF3FD8676739E44 -400A98B575BE02350576F96CFA54D4184BA47555B8D12374B86D038D085F7FA51FF4BE2FF5981408 -999B48B2FAF305212ED54B2E371F5A0074CF68D1B0E5CD279BBC8BBAEF694A89A6C43F518D01BB4E -8402AADF34E96E9B3FCCAB4CBEA2741D3FD9ADF7AF32388F7771845AF99965A6078F4DA335EFA436 -BE36903E33A743C112C0267309F266DD44FA998C9A139704E400B89DAB952EECFE2AC09C82D9F497 -5371CCC27DA37890EC84123193314D8A7A707C217FFC951A547EE5B6D1B7C8ED85BEBD9D3F4B9B09 -6A78E5F7DF88C931E3F396973974454E59340CA51DBFEA1A00DE084B64630E26C6D6A3593B828814 -E27DB0186BF2A87EEF268AA1B135AC09B52CFE53051CBCC88CEC5657BD47F603C8E1A6249161684F -D9084AC279F57A4F9BBD0A546A87E147B62AC860911969A29B8AA20E3AAAD0079D64E6BF1B0F2CE8 -F0C54C9019207E1B403358253C2FA93A662F63B9380B65C5173C198D86A3D0DC1800D1F5378DA39C -E8523EB62C6AFAD8A0D7AD1629F2CECAD82B8FDE38975303768C7D3A08B91478EDB3C45A8C6B7725 -EA8596A8ED50B8355FB852FB8966479D12E1086223B1E6523A65FBA81DD106FE254F7309718768AB -009FF7714A8C363B09DDA73CD3F81BF9C0CD3B0C806CF3B7BBFAB73E46FACAD2480EEBA97AE68EC9 -4D3D79AA01ECC22067858EFFA9D7B7F997ABD2CE5AAA8781E5499E8580C405681CC63EEA53BB47E5 -5ECC5BA2A7A3C5472DF034B022F455C60FFF971B01583A29E211A87F7163187B190B0C1083D696B5 -86E9438FD8BAA45101A5EDCD1BE5AB9A585511089DDAC8DF1B1FDBE582ABD945E67F99ADC4452988 -A9859E39C90EF794C5C4E62997085B7A16A0D90107D08610BA175AD66377345662DA7DA4D8FEF847 -EE5D57E3AC54B928A0957CC1C944E7FF14658FE4A641CD26C61105C0F136A75950764B69CA17509E -3C19351D456B22C87C55E8DCC4ACD3E150D936333FF36499AD6B02B6403DE0F12901301ECB2EBA10 -324BA72B58206A13B8F37B0AEB12115D0C12879C8EA8A2EB70E85C95434564BA3DFF481C8972587E -FF74EEBBBAB14FB32B8A84B8FC42EBECA65D25E8C32C19CA5962832BF45DFDA4E871508AEC318495 -0D6DBE89019CEA29E40484C36E33D76B756255531ADD1DB24C03B2A64A47BD8FBA3FDCB1F5B96F8E -ECB60D5834AB001A70740498720AFB6EC03445CC35B51F7987109618C6C78CBE3041BEDC69B6FB12 -8142CEC5C8683B558AFE3024EFF7A12D04EF59A72E156DF11D33ABA08A8EEB16259DD9529CD003AD -4EF4137B6FF1654236473DFB93F597331A5E26C7796F528F65C94FE07B3B4F4DD49034FA0CC189DF -CDFF70C2F1C6D3DF30AE103E2AC5CFF20664AB934CE5C19693292071C93BD590383E0A1931E04D1D -DD18071DAFB628F5D7472E457BF81D6064EDFA8DEBFF91701C5038CB30865D6122076A336732DBCD -B0A625548773D0013648A76F07BBDC9C16284D158EC7A105AE37A62279419C3A2F360D0C7A74D6FD -D0E36DCA2A8BD59945A4196598F690878F84C894852C1811AFEA4BE3B9F6A5219E6628C66669DBD8 -FA9A0CFC2DDE7716A356FC4FB271D8A2CDDC8D4684DE447355BC7A287DC56852A638C5777826EB6E -B72FACCC86F80BEDDD0D649A883CFEEF4D74750172A90B5DD8252592FCFE19FFAAD868E99562DAEA -E70514F5DE296EF7B57E6F193737ABB6AA317956584423817E11664A67389197AD9F8F771EA59551 -98C9EE40A0761639E638CE9D890DF468642670235F1373D3AC6B1F43B5777FC0A91A96E095E89BB9 -FD62614DE456CE7AFD6B855112367573FD9FCBBD4A4F9C676E672D62DDD34A9BFE8311B6175A003C -D143C0DF15E4C0B48C735404086E48AEED6B6FA21FD9F40B84215DFF287F0677904E2DDFDA774A40 -19DF45CC877F553E95A1C65DF1D67BC0C60E0BBA4D205C0DA3DA80229FDD71859F65AD04506B308C -2B783839F31CFE4425263224F08C5C7E98A2C9D3DC8EA5AC1920F4E395413262E0836BC019A092A0 -DECA104EB2DF6B63392AE8E2136379140DE5FC98B0B69860FE8E31DAB5C5DF7807D19BEA34AC14E0 -ABC6F6519C51247B104DE7D912C5BF6EF11B48FC6DF84512E9F5FEBB48F72FF1B722BDC3BB2E835B -2E7CC6324BEE84893996B8DC2D4DC2793A4F69C18E63DAF04A7BB5C0A9076E2D5A343E134CC3C89C -4712900656FFC202E1988526D80C7FD9281FE47FBA8AB5D025E63A84051F6B13167BEC15B346212C -BD051AFE7A98BE3A2491F3C469718A58E783ED91F90E274FB4978F8719E92A99A1E8F142EA7E1F2C -46AFF0A2FB50F4D105130CE8EA309B0E480DC8F80D506172B609EA4BB4E2BBAE98D8882814FB273E -690DA990B60A9CDA20A2418246BD10AE67D846A0FA815AC25858145ADDA106A6778A11877FE59A2A -BE300D7DB9BBAB31CB5B960B7E4EF91D4600886D8795DC361CBDDDDE05EBD54B1941F426F7FA8399 -270D2F54C998BE92D146227270A8E89AF90C48BAFC4ECCCA01E6322AFC165743475E752F39BDAEC4 -9297290510FFA264342A0AFE2985F85DEEC66C36EB4A1D46683EE7C591A89B81569A8566AFBCA268 -10DDB0970577A76EC8A066622606B08315DB0F2E6C671F3259C73637D773D1A180AAD66ADADA2A65 -95B5F481E5F59E51CBA876FA06D21E1D674CFAB46A02D267E20234324D0891E7847C13C69BFCEEA3 -AC55F2EAF753726BCEB0DE1EECF42ADA964BF9E475953302C2FCA804B70B779482DC9319B40381E0 -9C0096460AE113C19A2DC9157FA138CF0E7758F71008E71D0F7599744D647B09B16E3C795C56EE5B -D14D8D63E7A512900D67487975EC9CEAEF69572FC3C2342AC5D365E8A4BCF462006B5268ECC15754 -94CAD9A9E7A9E8D9AFFE49AF647C017743EC7CFD5E66F4E4D845A6BBC836849274FBD270CBF263F1 -67DF7E26BA91F21C60F96257C07523AC37A2193010E976965CBD75751E312817C0564E1C5AE0CBA8 -BD12B01122D07020A0852120680985A8AC987BC33BE863EEC52AF13435B6E4048D951F5BCE36526E -07A8661CF2538F69D1F223BC53BF5896437D1BD46F57D9698F642F0E99C7392D8EE47134E34DCE94 -D392949B418D9821E12CAFA8337323E8469DAC24DADC6AAD4A0DADD7FF65694BA3A27964D28D8EB4 -1179458F91CD3F83B8F119BF5E76184DD29CC4C0718CF7945DCECC993A7A78739363136CEC7F2FB4 -95EEA8CEDB3EBF14373A058758C442939D36774435554851E9519B6F09C31EF26B6CD997DAFA11DA -91FA9759F17B7079164C5B47B99CCB7A876FBAB1D0D5D1E1A2683CD6914E6B3B755939CEF1C9168D -30B2738C4349650CF86C90D2542FC9B90F36A494C035A1C86DD716014AA16E6B9EC7AA03B16554BE -C436511DD3097FAB1FD0CD49EDAB96F74E8FD26400FC748CBD9EE1EEAEE24DA30DB6F8734B52818B -3A5E510AA5C14E42060898033E7E36CBA9A64042CF94A74E4B52E37AC027C0DC69BAC4944CCE12E7 -AD81AEDCE642EC34CA23E3FF07B8CD35DFF19F33C8D4DBB56A52534F8A827BE47AD4AEDCAD83B273 -38409FD1101C4DFF3F12D3DF79AD1FCE65B2F419451DD059C88BF066413E23DE27D3621DAC2DCC8F -9F3620DAD0F4B1A6E8C9E6E8ADB552E1EB2C4B2A3B73986AD53ED9ED8911F82F750DF05CD2EBA3E1 -B0DF208A87FB5ED44C3296B803881C1D9776D13350CD29C3F716F0B5A8B8557812024BA70069BE65 -89AA579EADB1F657712DF2570843D7C5FF7F4009D4D232D3547DC8B92ED5C4DB77B76255E661FF8B -163C6F3856DE5651B597EC7C78B84F0C6C1D6EA3A82286F1D3BB45F708D564E139E81F473C705AB2 -56346328DAA64D1EA8645DC10FD449092E0634D9D7344B2AEC3C75F6B6CD8B3F3867FF3CBB0F556B -186EE9A7C26BD2D17C8A773055D9D5013BD2F937D697A770C57BDB36D922CB911CD14E7FA14160BE -19C1A052E297B1A2D682D4BBC9F1D2493BCD7CAD2FA75D904C5F5479179DAF7DC6A4E0D269BACA2C -4F2430B4C8CF1572FBDC750A05DCD5B09FA3A9CD6F2F2A386E2B3D4D8E257BD43A783B38E63BCEE5 -03EA96FF2C373181744A607F0CB8D281D7DB1A6F4076AA3E2C61914BD796EF8A0873F79F964FDE28 -B792BA99A20C3F1F5ED1FD189FB1867C84DCD6AF43D49420C8B1F3DCE7DBAE71DEB17FE45644DB24 -4F44B1011C7C768EBB7254F4DACA64E9BA87AA7CD0F0C4B2228FFB9EBDCF3DDE4DCED39399FFEB34 -8811547D025320A88B480943A339E2CD2FA3605AAAE87939B1D7901465A1879BCB4C5BE1A179E7E3 -71F1BA2E0844F88AFBAE9B78DCCA47AE8AEDF5BD3D458C7D4A7A08ACCBF880D1F1DC69C636628DF1 -EBDC5C42FF88FF8B66351F3F72D703E52F3CE91E4E00759753A599FDD863788E99858498B66B93E5 -083BC3501C39A9BA928B0D763C28826FD237E949EF0BA85CCA9AA20C405DB6D5612DB718F7B4AD31 -D253AE306E4D7CB615C59AE668D347A4E60FFF7B103F8BD0E7CBDB142A763BE88AB40EEF6B8FC200 -458D728930AD0F94FE52ACBF0657C4907CC7942710AB1FD8BD149A9C9DEF6B8DCA7DB9062AA7B1B0 -11ABB5AAE8B77893A023F9EEEED4A20FBC30F922282A7AE2F1ACFF64151013D6B8AC2EAAE58171A1 -0F80BC18C3BBB5DE1E22EBE6033BF83040629023D74CCBAB3F1923CFA4A6735E1DFA8A1B261FBF1C -397E26F3BA9C2629CFDA84DFA3D1087EBB19DDA7E2D76E30DC2E15B8821D5291DA1DFD73940E5560 -A8A6DC91BE0075E3ED8D9E8CAC85AC20768D868CD2DC45DEADCC8B59AABE6EE5B2F891E0D7CBAE82 -0F83479332BF9707486698FE196C72EF72B52F54314329FC498171782BF160E1110A19B8208FC591 -EF0F0DA71AF657B43A7CC649A8488B759F7B69134B4F9DCF79DAEBC1CE52CC8015F324C9D46320F4 -4E1551EDA6D86139DFD1DB814CF38A22A89FABB4F75FB896B00E769820F763486E86668253CC466C -1529A5A924CC337C48448851A381DCEF63A0A302B65203D6571A1DD1FB9DC0C3BD6AEF4891497033 -109CEB5A481BFE442249940EC54096F1D0F2436D9E60495D0ACFF967A741B30467D24AC6B0032213 -18666B951EFD45324987B10BEF4AAA0FF1DF6887377A7F70F555DFB9FF1001C67438A167A00B05D2 -C37065655173A7ED9AE342DFA1497FB1F2FED6098901249A085D31B66DBB6AC25EF16C106B0A6FF3 -47CDF66434DC3F0012DAADE80B942D522CD59AF4C31C1C062157B3D000B9CB86E2AA7B4A5BF31605 -8A0D5A148EAA2C67977FAA0966E4C3454E08DF14C2498AD76E389AF65D2C139A6D8675298C46ACEB -7DBE6904C373C06E5F71399B2EDA0B40AB96E8BE991DDC39F92F1D24797F9EC9F2FAE25669B43754 -E2498E8EA5C44B176C3FB3E8F7A7A1481275A461F2549AFC4CC73E28417BD8C5212C13105EAB967D -AA679AE822B9B75B372A99C7E82D6BD83AA2BA00314DA4AC51B9CAA30D80507505BE24BAD0A87C5D -5D7336EDF60CCA4CEC8201D243C3932F74D171E2409D789AAD0D04A7BB22FB6DC3AB92AE33FFEA89 -7C484D741039F38C317EA396A0FBB9F15A27D87FCBE007558799BAB73212B6E5FAF2080BA074724E -AC87D88166DBC1464CF5D41B99428851FF1D99246944511CF42C3F9248513E9E51593F253D89C604 -388AD7132D6A169E9DD888E020AC1F8BA606F2E1EBB97977E505D8C40853653D8F398F71CC9F8F9C -540C22A1E6195BA578AE7262FC845FCCF77B33F33EEF266489AF8B81A615D6A13464BCA58BEC16C2 -3F31D678F14A938BEC31272DAC3CCB1B2DAE577A26BED852FC59843176A5FCFCFA0AB7FB00D2309D -E55C82CB9049F44FA61F1E313205A76317C4CF529A4456019D970624129681F46A9CD7950B8B5C40 -61853040113C8115319E68B37F88D864C6957DF813B305D09E6A1716B10F26F2EF5C727FC77AABBA -73E12B5AE6416AB19F6563CE14046B715BD4CB2B1E4D315F42D10F74CDEDE82BCDD524A1A5460921 -9084CF1CDABFE72CC8375478B41614BC18A914903596D6FC2F361EE519F875385F4ECB50F7053127 -4EBDEB14A5DBD906A60817246042E3799BB3AC647CDA7244B7998AE4F3BFBE5C767FD2142E48518A -4217599E0EC2CF5E86C8C270FF8B02F949EE001D6A439BCB4BC7D7F7C8167C3AE0A7E59687FB8BF6 -F37BEAA164541B8EAFD92E9D152E3FD0F413C99CCC34FCD8AA455A0B55DEC846A5874B94FC95CFF1 -BB386B2A1E22CD1C3914264B6D5BD1746972857C9235052D77A6C0DD3019F8A307FBEE63A3EF12B0 -39B224108276FFA84021F1AC5B745C54690B3FF587B4B1710AC3533A67BCEFC503ADF1F4B62B2910 -B31965E364EEC9CC437CC40181A7320CD52BE9C546B8F1DC824312216C2FD8232E2BB8D40EE2E314 -54C09772A387F9520E331456C269F51A078E6ABD9FB6A68BFD5F557215B0BBD2227B8959CBD1BD4A -EEAB094DD18E891C61FB00933C0A0D76174D169C0B6445D34C00DC9E06D85EB086C18F3BE27DF734 -EBB9CF078AFF6514438549CBE92A0C0D25EFE4A527D86F158B4E9D8870C7AC5D6C059643A3298079 -CC20398324CA87273B86ED801057D797D91BC3CF2F96C650EE1566CD3CF8656CC577D38B830201BE -718DC9A494268177A5019546EEEDBF101996BE593631654B638C75A6BAA648CD1E7AA9AC1EA60F4C -D604071C89DCCFF8B3E430A57ED6DE11C5837E78956ED991058F3646219BEAE94E4D9381A33D48CA -9B8FF12B54A73FF869D0EEED7E098D80152295E6016CDD809173C57D1F5FCE908A37010AD4C4471A -53451DE9B4363B63437C374C598F548F145D3D288F42531FCF36A9CDF72521F1C0868FCEEEB1857E -A983F6B75CE245D875BEAD1BCB8819E5464518E04717B78BD6E335F0AD77B832AF5682062A1E2AC7 -7CD5EDD5DC372EE456C96D38BF8BF348DAC2B4EBBB2440F2CE97B4B337F2E23247E3E8423BFA9237 -CA6CEB6FB93F960CAD894A96F0371168A33222052DE9B3BE04B022AB95C0C243486E35197721FC55 -311DC55F87BC72D09B6C940CA36E6640AEB66C394A5949A604E7F15DCE3A008BB41B0EEF2840A357 -F348443B4DCE064B4C15E5EC52E448C985FAA1C3D6526270B1CC691009959A7620C9A6202619A19B -E410FF7BD535A8B2640AAA459DFDCB8F2BB35112626497E8A397D4F9E04788322A738DC8907CB643 -15CF63C95809E90D06EF02F72AB04AA61FE02ECCF7E9049FF9F3EF2258A75656178AAAC9F3C2A26C -001341862D526CC14E92A81BD63502F959066E0BCD659CB9B5A45606153DD77039B8C5D5B13565F0 -0D95A41937CF97089F3938E39659A64DC3D6046D0E9EF66544CAF8A206635DF49926A3EEF3FDBC9D -CCEA2886EC855F1821C4B9CE1D02A19A11BBBEF43A7D4D536715548A62802F64AF30BBCBEA8C7E55 -AD56C801D8A569C8183615A78CD393CA42C103F155941E845712C335F4ACFC7807202B92A983111A -ED241BBB8501F15560E8F2157C29752BDCDB274008137277920053D6D7DCDC626A574A82A8A34F1E -77B2FC8CF7C1A7322F22DFCB450259EB450C52B70DF3584A7C54C813DB41E3DD81253A03B02BC252 -346AF0160716355797B6F8210C453DD7E1E756FF08C7E6A5F4F87605E1DFF35A130D79148A57B7AD -12D94A129FE3F055CF974EBA09A2B13DEECA2E02EA818A58B81E8743004646C7746110BC61B86ADF -2D5D8C45A6A5461EB34497FCCD09E711F47BFA742C73F87B257B53F30CB68D151424DC3C210D3E8A -C67C2495A8236EA2D7985A5E1DEAC699D7B700E6D38EEE2E93B191BAA5A8A2C916D206C63FE63427 -AAAFED2B5784276FC21EEFF2D70E47C8540DCCC3E00134642B703795CD3702631AE2A90E063A218B -61E5B89BBCFFF84F567E37A31A9B349717A8CDB9C9377215BA838FF7469BC486B64EF2B6D92519C0 -BF0826E3652903F40E400689F5749DF86FE3DE178E21E20EDF9053081F6510D8F19ACD021CBA481C -484D30EAD3B84ED0190087EE478A17154B243346C3938FDD5340CF6E47B185E64ABDF44F8CBCDB82 -94492B91929BFEB9DA2B033C3ACEE554F0F1A7F8A56DF7C06A3583C1E9C5CA458D40E550FDF3E2F2 -E7BE8312D5FEE98543388EDC8A04CA29F1B82B7AB4ADABBA3F2C331EFF3521B2B92F99C4377AB827 -A989B423750D36ADDD2E286E7F3B694E29B8BC403693C6F7CAB5FE34F1E48C8D41B47831E8C3F5BE -5ED5142E3C44ACF5180CD41FDA149B1F4AED36812E42BC184227F5034220F74F67830255E1CAEC12 -66DEFA358A87D2E3B4B4E7EF30181570D0B2B43072EE0311C2C157D32EE2BEA8EA4251B59F6B61D2 -B4FDEB654DEB67AA3DFF4AD65B727F0D6B7D61523E4B44D99BA5CD33540F340A35DDD466ABEA4E72 -E504FC9BAAE51D231C33A8CE7DC2970DE4C1FB5B096A3D9C641EF77DC9039886831DDD01C4F21E6E -168E38BBDDA5F4308C959C7BBF36A42D042DA6862937EB20D4FA2E5927741A58DA5CBFFD9553BEFF -BD92E6D64871D8B25D9049F4E71970A8FF5557D1DE83DD24286D6C3E4770EE00F9A1A0B0063C9999 -4AEC75E84D6F9C488434D1F3DCFD0A8BEE9ED8257CA97E75E8B1285747184D6D2228EF95D4A0B8DA -252318ABD35C8398FC6568B294D90AB308A7675F9F160140F0A08C88AD0CA1CA2CF85E4D031CFA3B -87635F1398EB7DBC666A259F02DB6741D13E11B230025DD6DD64C438409AF109090058151E4DFB8C -0E9CD65935C4CC063CC6100FDE70896E23E3661C7FC1B8228B26A55903E997F80207EDD8863FA074 -EE4FF23BE585BAF708040C9F8CFDEB42FB8EB71D4CB6D7757E973E4D8C9DDD082712C23F868E1135 -ECD91250BB4335958B07C12FDA75EEB56BE19D1644C1F76A8811C021122619F751CBBFEB1D3DC912 -999017FA163672A1EF754C5CB78962BAAB76EC48461B492FA88F9897170DE857CC8374C8BAE417D4 -C78A56047024731F4A45145F0393A27CAB614A7FF747BBC28E6880D4D01C0A6CF317A1DE5BB5ADFA -4B5FBFE0C57598C79F25AE57BB797A489D51F85A9B9CF8BEA64293F8FCC43B0D5484DF99DBE19152 -692CE756F6FBE8CE5831CF4B8A5AF47524E272C45C62ACBFBDFE7E60B05BB1A1A6AF0E9210012014 -69B3DBB49EC7B23A363FA68417B7118DCEA71D4ACA2E36F88C6DDEFB70205DF3AB7C74CF65CFD01F -F85FAF99F172689737331D4C6CFF7A29029772F487FBF625F17BDAD89B4AC076948277B4ED687840 -301016C2B7AD4C6D02F81E88C75B7A04D724E234E38A38269351582245E361A42C75B8256AFD5624 -B558ADA2190F960A896BBAE7A8C57E76DA10DC29E69BBF3AA86214C001A27B39C1D17C548DA5601E -86A5CF53E7B1896BF003AAE9387ABA9B102EB1E9002DD3754A378F3E49F2C6EECF47EB1BAC2CFCE1 -1AC0C5CB063672D32733563F3E1E891B6073739BC53AAA0043FC45E90E413DFBD4548DD320B681ED -70A7443A233D79E3F038D26975586E5CDD2115AA614727B1F6DD4024B85CCCFC79D10B7B6AFA789D -B37BD0E8C423C1A4A8681B5FF3A9FA1F61A46E46C4B1836D1AA41A89264A7F4B1C259E4B10ECDF37 -5BD26A1F412FE01FBDC03368FCAF48AA0EC28B1BD603A6A0D0DADE66D14C9B7285569230FAB76803 -35BE104305E4B748FA99FA31F23991608DFDD2097DA292551136F255051C9F7EEF3FB7C7FDB4E651 -C3D03A4CA357B587245236F4FF3252563F6BE08EF8A3EC09BE2BF27B9120F7D37801F6999EFB1C8A -D1A08698CC59CEAE2CFCDBF6BD8F94DEC94F7EBF33AF05F52C85760C63950B455510C6AB9398D09A -C288EFA09E8F631A59B03FBBC75BBDAFD675FFACCCF8ADF71E815A4A49F14BF70E42DB0B7347B528 -4E234C24010E2177DBBD57648E398FA6B54571A37BA8C989503594D03C6E60871A7F964599022154 -02BA168B8D1D2685F5CF8645D5E11A1769473027F42564C2966C10C0DEE1EE1B6975852A4870D492 -83A470E623337544A7CDA5C16FE2855BA2A548511FB4D4FF2E3E78D108E4C734F64EE2F12CC9562C -BDF363EFAF5201B673AD00583FF108AFF6B68055A5F299452D176EAAFB92C84F114C8C22A05EAD65 -64A3371420EA9E646308DE97D40705E1638DF08704FC90249CBC0D2D3E884A4562CC27370B1A9738 -9D8EFD237E644A7370B8B38ED1C377F522C75F981D878A5E87101E621DF9D85C7207BBE5A87CCB60 -7F93A2E52F660E05C83A7A6CE6D01AB4B62A1EF8DA47CF97D4BBA0FA8EFFA9C0F61A325A97ADA694 -45F23AB1FE27A66C271639F839203040D44B11ECC6E805FBE88843B34C4FD52D1D3C6C70FFED433F -C04501FC20536ABDFFA429B8DC8192B2D45DD9D646049CBF40719C3D674773F9676F9FCF32817DCB -55402A72C56D74AA4CE4035687C730B6B44A9CC614BCA5A3FD17C170ED949E588EE45E89E18B0766 -2A6327FB9E8475C43E5DA1B0AF07C23774B19C9EF59281F5D884990D6194170D8293A86DB52A0FE1 -7E88DA82209A00A16BD29B8B2F13FD60AA25FCFA9745F57C8216283C1D6EA1C119CB9B8D57C00419 -5210FFBD56395A3EC2D3098ED38F389EFC0324FD0E55EA339B3892568229D8D3E205A821E8219FCB -1A7713FCF3450F8BEF976CA0BECA47376A8CA73DF85B340C67EFE4534D459617996526B5E5D3D19E -17CC5449E5EF2B82B2C4C2131FF8A19FCFE6A186A9840D872D85C40665A7A04E67EE26B8BC9206C3 -5B44C8F8A1AFC3867D96DC6D48BD45063BE25B882E9BC0D0948C18DC870E6925818E1FE17D336217 -F174EB4481F5C0ED37A3BEAFAF4D46F857811B6728BEC461AE6468D87A736572F4FF95B58B04564A -9D3C22754587DF15495A319D822B838461764B73483C1F7CB930EECC6F7424841EE10E4087E95120 -2FE88A391375C96BEC4480328A54740213F741105B12A39F19808F3823507B88115D468C61B212A8 -ABAE7480E39BA52390A1892C7EC50271156B4E8076FC3ADA222695DF372385DA7B117A29E04CD2B8 -0A320F186D61C963FBDAFE9224E537057C49E82E405196AAB621B5FE4011E1782A747EF935ED8BB1 -1BDA39A141CC0BA42D04AE123383BC95A1D03A85A9440010C3B9613064FFECA76197E10919BA5006 -F35837ED9BCD7DE5E6D968AACB6FC91178091FA467EF6FDEB728E17293DC89DDE5A5261FAA95A2B0 -000FC750E7073900D4D88247DA464613ADC2B3903A6132D96AC0E1C564385FFBF6249DEA76BEA2A9 -9160632DD2FC2B99133E9F2F470F72B45D6F18B45020F604B06CD9174BA3805DB60EB9C5E6A9C789 -ACE76AE9C79C1BD34434E95E501BC968633AF93FF4883C6A596776254C0C74993710327086B2886B -02FD3E42A725A03459CB36EE34A094139AF5FCF487D3DFE63FAD20BF0DFB60DEEDA2ACCA3510E963 -189D1256EABD81253F7FF9D11263FDBC1DCFDA3D1EA2E52005CE3C605C993231258A717423F64BFE -EBC34684EFA676358B9B543C2042BEF954829FE3246A879845B30EBACB43D8DD7A20FCFEDF763AD2 -C5D20A798B69E08722DCE6A5762E249ACE3055B650D9E110599EA30DE5C4FE7200D5A8DA9E1FE268 -6350D0DF334877D0B9F6524C552D0B6DFFAE125EC4C18F7547BD51C14288E4ABB7F8A1A00458596C -390AEEE6FA308AC1F788FAE30D7F8928AFC91D4DE6352D20B19D8D8AB122B7378CB379C5BE7E3CE2 -922FE667EA057B5D7B3F0B51C7BF0C85F87AC2F360D82C38964F4DABCC9104B32F0FB8802235E8E8 -D9A5997D392259074C00AF2CE1D2BF7B8E90E2E2AC34185C68A03BAB8B267778292B227245D7FF86 -70786E3F746F86B9D4D17190DB859A0E144B2A61E6AC9254DE5DBAEF20E2E9DB0B2FF654B996E962 -F55E465DD238BD1643CE59DC2B5A58B1E6E4AE2DDC2D74D79AFF3C34E4E593E051FDA236B79CC0DB -268D2A89B1878051223BB8F33FF99BA87A4811C0B3BCC01171D0A731EB732ECD8749D27952C27886 -B252F9C3D190419FD2900987A0A255B9753FB7AA70C37462134C467A2C4B7920BED9F9E86F8F98B9 -6D00AF8B05A4BD5F14C2A0D914A9A84160D554FD0718F50ECB5DF5E76623065852DAA74C9AD6DA07 -A119DF12C3577FE276AE551D48B1C5CD8A50E84DEC9CB0840520D78FA7F9A7C2071E28CD20EC7649 -B991F3818CDE295CDB6085F24FCF93147E9F4DD084FBD32525326D2EA147ECD5B6C9D9F4A7166663 -AD18BF234E9CB92FF72138A8A49E73E527E9A6488A4CA808AECABC94D693CD2C0C357D285F65006F -A2F9197F61FBCA6EF07B013E2B558AB531D2FD270CEE7FA8E467FAB885E90C5884843AA08E2BBFEA -0AA575643727BA18ACC499FF34E3438645BE2AA71EA491E54687CD305E12BBC94FAEC848311AE816 -495B013BC5075A2D2AE54A7AD7C9105B64356CB51F18C2C28E3A83B9D81A4554DBEC9BEA9A660CF7 -E1BA89E6D4DFB3EEC6A3DE3FCDED9B2D614156EDAE8CFDAD5FF0EFEE31DA3E6A54D94CE9453A1CAA -D9756D91BE85315F6514BAFBC821EE810BB5D8E1B8F05F64F3F72C4B35D424F7E4DC3AB581B74ADE -B6D6297CDE7AA8278909F269FED79B7DFD39B1C0338E01D556C4DB9CA3A8578ACE3EC3D743ED4B9C -0145E4525E8C315F7A1B98584B975C70F0D415708C8CCC13F848B1D36AC8249B73638F95DE0CD27C -7EFB52BED4339EBDA4812564D7A77416DDF4CC88CFB52D07A252D89353C6826CA1832A153242979B -6CEE783ABDE65C8B40CF4EA7B42B8DBCC0E02423DD693108006F6A4AEBF053B666C3CB63D1861F86 -EAACD43BB9BB6F2C3A17293C189331D253B447757EE7CBF4518BABB73A1D44874D7F0625E6A013C6 -08E991B4AD17A9ADB36740D25E3E35B459B422F7370B134CDFFF3F3BCC4C32B4E9EBF6A2478013F6 -6933A1FA9403A2F1161EC632F1F04EDF95ED0F33DAD9665D54DD9DB2564E51DA7B65978CAB50D6DC -1568976E83B056EB0E3A6758518B6E17E9EBFE49B72EB148B472BA144BDC2AC95744C9BF1258F0A2 -E47470AB0EFF90E190A41108914AB8C1ED6B11E0681778521870E80C16AF2AFC723CAD8719ADB62D -3939D3BC8CC1D8A4E07E9D734F54ECA33D936D2C39D5C8055739C33E53359BD40E576C11E93B4B4C -122BDBC9B1BBF44243AF4F0BCDBDFADE68C526B5CD74E29CE3F70D62BA83C489034111FE8E4DAEA2 -F01F9D938ABB532DEEAC0E329F42453FF5C15DEC2AEA8C198323C9E8FEA55B3F5DC4751D2E2E16B6 -154E7F2ADD46860E9CA71DC114C99D80E7EA1DAB51E925DE161CEDD678EE6282AFF38E3CD0E65954 -9C970613209955A3F581E1ABE485E56402A3DB0D1E9B8A9DFD05C4B0B7F97FC6D0EED0B69AD6F182 -B1D028ADD2F24463834B13F5C1307F91D363891824E81108E57CFD5211F86400D3E96B107F3B1FE8 -9C4908649D04A46DC3CEE0DE66AF03A7FF9F4DAFECDD6DF4D93784CC899B527784DBE0718050FCE1 -85BDE3F39DEBCDD660B2488D23AB1CFF87B0546D02B48E7B7724C9E87B71BF34B5D6640E0F6ECE47 -B182D41C89461F712849C6CFDB7E3F5EBC1ACDD12D65A422BA362A8FD6CAAC5104CCC5AB5FC04A46 -E4309ACAC83D659DDDA256CCDDD1BFF9AB3622450C4FBC89C82214F00C42FB0311BCB1B722A691ED -839CAF9024FB1671F18E4639C96D84718C663A4341DEC037175C6BBD288BBF5A0478298CA726567A -9B74C32A527339C666A294A17F6821CBF243D13EA4B1603C292953308B566653423E7301A032E5D5 -E2B93F1C1434893633DD19501AD12728B5A1D9D36635B589FA2E151140B543D7C5E469AFAE8E80C4 -FC1D9CB6C3823CC1BB7EE40AECB58CBC1465792226B19E0FE79235115F6A3AFE19F98C5DB63D372D -D7C041CD940F4F79F2474D9CEEA0334FA04A97DC9773064895CF11CF73F11B4684F06E48F4469F6A -1AEB2CBBC52994DFAB3319DCE3A0C8C2EFA9627496F8CC84D3DF3BDC4FFCB61672780F294F453278 -AEB9262E66486856D37B7647141A82E049364ED3D03F925284A3F1FA3DDF4C0B48B3FE22E7DF9ABA -239D33CD300FFA8FD4B96192BD568FB18D325CAA8E1F1FD4B27527417B034841FD49E4A77F217062 -3CC8B22101166D80361EB15FA9020D24F61007B0A8274DF9DFCD8E97C85568E76D34AD5DB1779B02 -F034A69CCF9D4EBAA188EB3017EEF5B22A0A552696A574907F695098BD8A4849D5C8311F129447CD -7A3CF88B8191AEC0AFF30A38A9AB8135608A7829207A7D242F6E1FA7DDA19F5E4C28560D42DB4405 -77CC0C5F5803EEE897103ECA0BD944E320AC26553BEE7852EAA733BD13DF760056B2F5BD1243BEDA -BC3C1EA0531017D74B47E18F801A60074D6DF849FD0532234545E5B5E112D1E7385341D39A89551C -80DC2DEAED5D5DA2A4BE5015D297324E92BE64C68428132E6EC654DD4BDCC6640C68835FF8A05E09 -9604B8CD43D3AF2B2FE10C8AFEDEC5A70AF8509D12F662338CBF166D9452CD36331758AC4F4CBD7E -DD52139AD27DC52569877FE709F297444C4F31899D1945C81B14ABDECBF31DC463A4148F04EC4FB9 -703C158216C0FBE65CCD450043ABFD4E65BF8B28CC148252E9F3E797EA0B57B8721C94CBC2EA602D -F2C57E87938C887A382D2659226463BC7D6A1DA87F4A341A59BEA458177D3F18D1213539DC0E301F -6EFE0111FCF6921368BE17CCBB7428127E0C059C2C5ADB2A3F0197F0CEAB77FF7F3C027A8EC3EE76 -CF5C986EB47CB60561C773B3A2DA47B5A35394E29373DBD5C3FF4C9213A89AED77CC4F3FCFC49EF6 -EC7557C521979A546983C106B3627B5FD2D71CC5F08A32BF49332A89C5DA71AFBFB94C949A91220A -B1F885C981423AF93F73BC1CA4D92D9DBAE3EFE6A76E2DE3D0F74FD3255820636E3F1A6B7C185306 -23C12AF90CDCD2C0A728521E9B639EB6345D1DE8FFFC3B19C72E7A93823DFE3115E9E7BBBEB28CB7 -3DB121AED8920D47D8CC08EA2E472E39A4CAD5881B5C4204F2B732AF9D5189D25ABF413CC78714CB -01B1D8CA5565169A919DC481F6D2E67F1D490AEBC5CC62A8F62C1A323EBB55ED35AA5C8D6F8B970E -93205C2701CF4817BDA994FC16197B469ECC5F5E9DDF0FA05640C2E571849571CBD26402B1EB1E80 -3FCF423345007B9B52B13E3B034E8CB3984B925EBFFE719ED4F39F3D0E3343316A6FDC26BDBEA88C -4366D3B2F851D2B244CC4408251AE2C77348CCE9DD8BB9C89800B572D38C5D1CC34C740BEEBB5DDB -0A8BB251655FB989840D23205D16311A9FCCF7C85F6DFFEA9704492A4E7A8F6C0BDC29745AAC2ABF -AEBA02B0E7AEFEB92BA63AB0DF844EB09D505C3DFC1058CE42CDD8043B76398401E1DB862FF9F76C -05E8BC6260A4443CF494BC1755913D51745BF45ADF2F8C7A9546D7EF4FB11E9D94E4539632C2A396 -06D04480EE459408D7A2A869807A4C01881C1BB21C296A402B5E6E07093D833C3DFF075F4DD426EB -87B1B8DE16C146DE79F52F5943015331EEB852809CBB8E1D6460AC4D176FE96F8D19F6CCB22ABBBA -A27C4497D91312C3CFB5BB913B314E43D2EC6AB6897BA7C34CF2CAA6DB4BD69EB5DFCEE0AA917D69 -50E36A68A4C22A60DCC69379D47544A58D640EB10DFE120FCA843B588CA8B94F7869F97609A6FE03 -AC86EC1F7CEAD2EC8E81977D1B946E459DFCFEFE65A7BFF67E66F5F78A45D8DF65AF0146DF74E024 -FC042328886CC1DD7779F49CDBB750345CF83CD678A6A8897577299DEB38AD665DC4F21CE1892A18 -C256F318107DD3E9245C1AD3BC93CEF7B7BF057E33EC9A3F953251261AA3D1A8347261E70A46F777 -3A84F3D4D1A0DF6DD22A96429349DE0D180310E17955B10FBF53220EF6483D03C650A8D5C16D63DA -F65C21ADCD6C2D0B5D4ADEB2F5526AACF7CF42F9A8BF4832FB2D4F73F3D5FFD984B572232F87BD3E -59133ED3D2FA19F7856AD812515C74F7D851574019C532C25F8E163E595FC9C83E3E820C3CBF690D -A62578A980FC0803EB6DB9B1E90E3256BD4650816ABE5EA86CE65C2EB418D0ADDA5F3EA04E17AA8C -4536CC471AC20236E66ECA3619F161DFEFA485386C30EBB86A7AD930FD0AADF2DA69DCAF26C0F677 -206E2030E3B15B3662C0AD03DBC1636EBFAD1F2F2C37F5FA9856B0198C5B1D80B69C5EFFD94CE071 -5135C649C26B9BA1266B0A5B270CD08A706166C0B320915C87B27DE21DEB5D7E4806F6E700B7A06A -4E29B629CB40761983E9CA8E34E869ABD04DDA190BFE5A6EE8B22D7E511B84EA584A84211F27AF89 -18DC5AF8A1FF2D360B6BE3CA8E66BA4CD2CE6A25E7E89406684DA83FFBCCCCBFD0844FE3BECD7DE6 -7764C59C022DB1168D585FE25073FE00E30218D1DFE115CA1FC606AFCB04F2A082EF91788B6BD096 -84DEA31F20034A91AB9D971366F97B5009FEFBF1EF0AD941654081B1E8F0B2EA495069A1DDF11DC5 -6857D29533DC857958B49D1A0779732819FD22E437084BD9F3C4F2CDA4D12CA14431937AB63A03F9 -C040AF1D801F367ABDCA7302E18A9050D6026FBA5A5A7FAD44E31593173CDF277CD737D1CEF59FE9 -684252BC0DDD00A80E023B88222494C1C8C0884230AB11D1083225AFDCDBC1E24D4AD5FAB396D2E3 -70E44A7571B230660D510A5076D8E35F7DB72C0566DFC119EE1B8AC3C0406950A3C4A4DA36BDE297 -040A27F70753A87E6CD593DC6BE9962261A99AE5949340C5D45C94A9AA3DD636CE8B497BBB812345 -7C824F443A53B3EE595C38983FE3E07DBDC6ACD55CAE8BE1081AFD4857A5F52A3C925143507A3C37 -F1992CF72ED0D4C48D94AE6CADDC3BC87AC3A3EF035E02181F78449E4B063B0835E827644051551C -1603E2EAB5875F28FC77BEBA6923428D5521C698C6B7F133B0F689F105FDBAC30A8ED2F29F0255DD -F8A037B81F04EDF004CBE639C8DB0F94D0C5DB92D34D66C2FED66CF8B895AFC4E659D08388EA44EA -E83CE459E5BE306750A682B627802990037157339BF142BCB9C08FAFDC3C3FB16DC3544F62C6C7E3 -3E20CC4FC7CA21E2C3F6C546CD78DEE348F1A4C8CB548EF20C049678916771D83ACC9B7B22784AD8 -580134471A3C79BC86B5D6D0D305C32E6204274351C94F9DF45D9B2AD5B5087A89F90D6AA033E4B1 -D1BED022F36147C7ABD2B73134DFFD50907258E610C3B20949E141172B1C6A76DB238C375021CBA6 -645CDC26B717428B5A9B4D3F32A4B1E22FEFF3BB93FD889E1DEF8087718D5E3E650FE4A3330DA9C3 -7E9EB499DF5A342D8BA4C0A033C3347CB25A31BE143ECBF91384F2381E323E7FD3A82A3197C18905 -3200AE2C86B9D01AB0B289841EA7E9E9A26966E0DEF54DE0B85D8DF084B8C590081E444BAF1E1F60 -670FA12AB97159318624F2AF1B5EC7DD83C1073A99398D2143A52D10A13C201FB356BC9E90C63BB0 -BC2D4C42AF4A8B9C8C4D58A1B32E0597C63B3F8B3E893BD3BE8C60231838F1BC78E73A6C8CDD5E7F -2907F897FC8EE99BFFDA7338BCEFB5AEF950E5549ADFD207AEB15846B509FC57989883642498A381 -1B8E5CDE69C05924EFAEC232FA4CEF302EE3251366ECAEF57D25CFA3B4A9E6397D996F421C900BEB -CF73B038FE7B16FD0A1172AC2F40D19CE0B02FCEB8BC47DA5344CB933C7FEC950184F78ACB32D3E5 -E290E84BE753B9E7A7BFC4416CCF29D023760C06CDDEF2505806A65E1508990529245059AFD301DB -669D41BD72BF7A80A9DF66B876B3553FDF4DD38D15289AF7A1AFBC53FFFF135A6348DD784AB42A6C -0D6AA330B069607E2DF3CBEFCE79D6F63E274C9E73A33EB85246D5EBB986BFA923DF68B2B8CF82AF -6C33E785F35B25B1D1D614DE85A4F4510ADFE42D75B5FA5408A59ABE53859E28B3D000EB9C6A7D2F -67C91DD14C895BA87B9CB57B851E5193FCC2A443AF85FE28DF6F39537F23A058BCF81DD8C04CB2C2 -5040300F4C55975E856DCB4E21E2B5481BDCC05601942FB25BB8A6B6F93E2C2A33CD478B44655657 -C557EBB080179EE5D98C5CEBE0B25BFDD952FFEB258014D7A5BC4BCA4F1A23BBA73C454B12960451 -CE1752401B0151CB2E01D5C72595095EAE91D8D3BD55A54A2AEA89239FA176FA7CD6F16BB0733EF6 -CE6E77763A23AAC77DA88C8EFA7BBB2991E472FF2075FB25A75ACFA70A04C28764F4AE4C12051B25 -B120CAD2E3044DA35C1F94135DBD69B10DE147321CBBDC814CE99982AC1D76CE3D3330E41AB31F3C -76BF89B95EAB81AF3464C732D5B1411D97DB36C9063537F64756F205B16ED7058E2CB1D6946C00A1 -A0CDA9EBBE924BDA6C7D7B605C514A98133907B793C74CA858E82DA3519188CD974B34DAA74265DB -5BC8550D5F0B1173ACEB87458BCE2AB1F96996C811699A0FE4A9B849D39023725E2B1EE7E426D30A -6C5C75AE6BCEA6DB41E4EB2035F7F924E6B9F0DCD00EB2BB014222E55FE387FBF5B9B7C04F4688D5 -AE3529FDACB38B5EB0AF5C3A874C1AA6B17CDA8D1E22EEE05A3DA88449200D3D0D002DB86F6C51B3 -37C8E19F338E7BFA01E1202612D50E210140947D5F350E84F790286C3F679A5D7E43BCDC337265C2 -631527FD62D598B7CA1F5835C0441881B97F5197901ECDC4F195BC665A846823D2E41417373F8639 -567B228FE7B73D781F07A361AA49C3E9D80FE5B2A32C4C1E575D194E841967B08D10405FA44EEE28 -47DB9372C5CC931E50469532F1BAF577F680BAB4E30B7E1CFFA8574ABB679789F69A8A1BAC07B7C6 -4EF5CE5EB00E97B36FBEACA9BBA4A13B0293D34BDBC77AD1FF88E5744AF009823BC262511C4724DD -585E7E17D90F230F7A5861B0DFC42F0B4E49A04EE0EE4DADB908479DEF8372F334C53D2BA5D855CB -39DC7C9550F9D0F7F77E82D5A59FBBF34BFFE92DC9E6668B68FEEAA4F20053433D6749162BBAC5D0 -D428DCF2D58D49B127FA2E674EDC7D3613B1342F4D0ABD7F4C5B049FBF78E804D5F16505AE7EDCBF -4D6FA08D72890F5D55199034572AB4B0C9A7E7F6F5A403198864ADF113CAFF5BF9D4AB5B16F81D0F -C2188FC80875E10034D12E30C0364F8F72797F1AED525A2712A40D44210B813DF5A29C84E9F6D51B -1D60A5F6F938FAABF878D29E6AB252D95D05FC1ADF5D4CE1C9E585219112112BC6CD5C766411FBD2 -2731794B5DE0A27AC57D3C57926807469C360372BE529098C350EFE2154B87F1205A57A0B04C5206 -CC4FA66B8793BBBE492CC3271FB4F90A28D0066E0D7F63B8DD01549A05AFA5482C29560ABD628568 -75CAC16100087540162473498C14087B29B86B7BFAD693E81765CEC781F3FC80E9C7B410E9B55B88 -114191A1703C638DFBB469ED1DD8254B1407003A319CE74AD419B077F17047A01F0BC0AC8507191B -F72D77D9333C9DA8C9DA733EFB5305F49CB8C7BC451321ADD7D896395D269DCDFDD084EB3AA70338 -6C0697E962929651164135C094D9BB1C9B949D5EEBD3BB17F02C98C813CCBFB23C2C26218A2F4C63 -9A8B9DFF2C29406037F91938A5E1227310728428B56F48108CDEB33BD3191ECA89F947271983DB77 -6B2BC897A30EECF2601EE3B2A6F0E135397622AAC1F2DF523CE6E6BC720E13CB530CEF4AB9C8273B -D3D81563AC8A8E6C44A195112DAF824BC7A72FCDC4E129A480717BEB01085DEE65EE4344D0B41EC0 -BCDF842566B1D9F5353B1F6A063FFA6CDB06EF634C8BD5A7A63F991D178F56EACA653DD67685CE49 -E98C7554745A4AC533217662D23E1D6937135D13BC2208EB8D50560A2BAAC319DFAE478B6BA4CA5E -DA20222F0E9BDB0806320ED1665B54A347DE0C42E9F77842DE4D188E7E824EB2F0D7AD163F05480A -7FA99C5A603BBC5DBC843774CA66E889B945054C0ED0B1A4BB14324EF901B023C208CB95DFCE9284 -89789690CC45BAB97BE449F8E2F5AA9276C0571303E9788C46E7F789555BFCDC3FA9ED8DA8AD9BA4 -8B3AE09404664391E63A989EF1E24BB464043AA099E4F2D796E352EB277106D8D81BAF2F8562EF46 -BCFD1E0047E8018CBD973021DC1C1D821AF03F083F0B088A62EBCF2BF6C5B0FCFA441AAD1625FDB8 -34F943DD47A5A42EB3E9A5B49641F797C288B799A64897F1346070461B6D535E0C4ED099199C387A -3176AEDC7DA7E7D9E118E55565092A36F7C74ABF281720C0147F4E4F37D49436466C61FF12764E30 -43D8A6D027E70537164F0E7942F4ACA42BB2CB136177EF7197E76F49AB403F741C0EF902FEBC471A -D6C627424320A8C3A1F04C310C511B3F91C3937D9ACF459999C18A33F2C852EC38CA806599C728C5 -43714018C65E2C5F430F6270AF52AD71ED38813B60440779455F9529A4A1623CB9F5422B9216F9CD -BA913B9A1CD95DA225E254E8101216085020660509D03A034B5D7E32E3DB5E5962A9A27711D4C3E2 -9CD84057F7D0D7E8000947AFE896F8523253391D2E11FFFE523366B05C532D5629A90741EAB3D4A7 -31D3F6D4F03FF93233DDF88BB1913ABA22EB9AA6311E3144381DAE29BCC8639958EEE59ACCFA06F3 -5DCCC63E0609F542F3EE5DFB1CF718CA3F328455726F8F65E23ACD970E4049225998371B63E35AE9 -8DC54D8329B8DB0901FAA63129EDE21B158776981D4D094013C096E9CD020315D123C03DEBA21E97 -E4B584B4BC0AF25F5DCE53C2DC0F3E61F99BECAB40799478BE7F5AFD7F68E23EF50AD6645C967EE1 -1206B6E791769428ACDC370D64E4F2B3972E0E4F442297199350663D6E772FC6777A9B9DE215273D -082CCE4E8678FE9948DC8D5B0E459CD02F1645AC5620F3571A40B4D5A17DF5CFF48B6C843DDEAB5E -BF58FE13D7DA08E8AA7902119248B3B151DA583101CF80853B0150FE05BDEDBFB50A7FB0F65728C9 -3B9DF48CE8AF1DF1FAC25C1D58E1AD30274A00EB54CF2F16029E1AC0A0919C0655474B9A6936AEE0 -FB74BD185FE7D70BB84786997D34A40326A74356A4AFAEE67B6B26D1C1A7BCFF8697B55C816CCD77 -312C332A55315DC54F9BC0A0F12500E0A76B3936292A3DA2DDF5AA8CBB9B5DC32EDACC4827D684D2 -74E65B8B76FB2C2B19F7D5607523FA953E34BB39032C05B1C1244304606C55660D3CA8607E764EA5 -B03DB7FCAB5CF7788C6E60EC8C449BCAFD90BCABA4132B6CBCCFF16784FB59B36B77CF0A9EA572E4 -CA0A01C725A6CF2E4500CDDF5BACCB9094D48925434F044118CFDC2696AF5FC0CAB3884107ED17B9 -BDE0C0104B1292A1F8C99B06FC4A6360B24480BD59DF0488641899B0F42B1311B582717BA7ECFEE1 -4143654B5371C8B9B2D80685AD38D897AD1E64875C28C7020A84FBB3A3BBEE16617DCB9BC822B7C5 -9C5A18C0CF7E80163ADFB7AA03B7CDE8497C1697D90F2ED90F813095C5B91657FC294EF0E341DB33 -92ED860CB2E0AA09293D0F99AE9EB54C761CA2DB1E51E1CEAEAB276C7BD916C68510D72D9A67468B -09B3C39A7815628FB126CDFD5EFF59CC8184C0D35A5B5960F824BD175495DD3EB12A4E96008CB13B -8C5745303E66CF8608FF27C4709C1D854EB79608E52F068FEC0151A74C125EDEAEA555C198FC0802 -7BBBB802835E1D435077AE4B1CCDBF722354F6C572BEB1376D3E342195FA80AC9722EB2F46E44DE0 -5F5A227B731B8D4A4B6EDEF04AF2C5DEC2EEF8FF48C5B18710ADE3DBFA0C956505B6DA9CCB7CBB83 -4DB6CC754948855D833670FF0AC42A4773FEA8322BECEE04CA74AC2D66855132D11A51524488C547 -71B5B7A512796D7D7AE0F9C1FBC9CBDBA0831074F4D200349D0CA40537B92496692766F020AC43AC -01DB8B2AA2EFA9D21732BE3A315F6CAA402BB2E61D40DDEBDE11276D90C2C601A935C168BE600464 -76ADED15087D54A14C68EECBBBB590927C1E10D291C9285334CB0C80EDBD392BDE4D535EB61F8E76 -41F58AC1DF5B1C5A5D91E3E27E05CAF7EC97ECF0C85B6425197AA856521ED701E5AEB82A7F52A8BD -7DC97D5B3FB5C99A5DF84D1BAFF89072922509D76BC6EDB15CE5F9EB8F4154BEE1E82020240283BD -C83A8E49AA9A2649B7955D5C058F2818A63BD0BFE7EACED4A49063C489A626277AE1246F721C9926 -E2A2B6C31045FBCD235F3CC58BC4DD6C57FE998EBD1E9FA5154652BE3A1685BCD2EFAA079A3293F7 -8142A6473822FAB627927EACCD61B3E99C3077103D2D19382BC7EE15BAD0FDE489602D055A01DBBC -F91A566974559D1B477C209416887053169C3F8F59955BE4DE82B60558CC9AE15602A93F029F6B43 -29E0E62A03982DB32F5229714EFA1491A7B24AEFE18FEBC2C93DFE50B3F641B51BDD33DA38871BF5 -243C17502D00AEA2D9E9734E80A96788D4CF5BC12A42BC386162FC88A7435EE13200C1C2C6CCC5D2 -1A03941007B4C4291BDB711446CEAF27148104BB240357D5EDA0EA5A5CE27D4A83909D75BFC05D75 -F10AA74A6DE37D7DE15C1DDA3AC3045DA6CD48323D904E716B445E5E096FCB379353ED70CF4B6FAC -102C762711079EFAF13FB74C9B47AF75F3F6BDA2A4647D2AB47ECAB64DA6CC01479F618E8D2D0A36 -45445E8744683CBBC560D47C98078B84206E90EB839B02D37C852B8E284463D4E4D890203C3D5B20 -352110034EAD6BD7F41456B807E1DB1631A9D499E52E9D9853D86728B1A2E511F40F8CA1E4724A0D -17ECD640B52FF6C66E28693D89765FC391612E5889E77423EC85CBD0A038B6BA98B607701DC0C4B6 -6B3B28C7790A1F1EB8D051DC98276DD9CFEFAB3F65C1C928E48A060C992B392A43E56EAA6DED896D -EBCE71F8245BE4687F2F1B8FC0F43ECE8DB0BD0AB0811C5CE73CBE336023A0D66168B34A95B4B0A7 -50B3BF1D197E3C042C7914FA731D7831AF798E9429571CBB977E6258244E84701E5FF91D608F98FC -3D68A4EE5B81D5FF38B6C184F6118B875F022B4CE207DC7B37E1452DFDC591A3E506AE82C7E7BFF0 -011B0A3DBD616A993FBF878FB03B6C9F2055A2B095D29361F8253C2623653687FE0AB98078F6AEE5 -FC2C2BDE0405EABEDB3A33EB7F04CB6837176245F190C6BBBCD64522B12FE7F9CDCF201A1AA8A19A -7BBC4AC064B4958F44AA0F8DDA23835AD28A1FD0EA105DE2F395385DCCFBE2261DC5A89A23AF606A -3985E5038706B1FE0910400E16BF008F250F3BDE3AD806C735495D499F16F99275010478FD2127BF -7CEDD6B5BD505FBE9BD0065B4A7090C9D27CD5B36C3AD33E1B31EB6D44E375003B51B909DA50BD18 -218418B3CD22B43278B144BE78406EAF16C7DF6B6C1C6238004AAB73736B38E168441DC16F9A5CF6 -0793A18633BC43D78674D12D38CC979F7CAADA6EFE807CEA499CB9FE616496682A66E04BBDACE1DC -112B2156B9B0B20A58A8CB43FF0EEDB99805234B9A5789762AC7D65F5A319C33F4F7438CD15E06BB -80A7A97E976E8CEC23F4C646A5821880A82B2F1DC27767F090997E91488BFA15064B702F864FCE65 -05D6CEF87D2A0A12B55BA189AF269811E3B8B850C8401F3906C080D32618D9698A766732A40A9FC5 -A94E5BDDA3D028D823D6B603B6D17DD046DE181FD989EA0F80B4CA62F7973E4DF5E032A31FE6BC8F -5CDA678D4A72787EB8253EA5882C337CDF9AA3E1E7D9536DD09B047CD8962E773F72F6418A3AEF5A -289B3406C152A50CE7BD4B493FFFC27F6AA52F79EA67E362FD92559AA4F94A2F787F6C735DFADCF2 -F08AAF98B80C53CA5607A94F25F04AA65A70A75937840E73055B3D65FB054C63E2E48E68488C9315 -A13EE949E03E46723C11CC759D222CBFAD2E1A87CAD779B23D38F7E2F660DE1388EAF1CF4D18994D -75C6CC63F187FDB949940C18B537A0AFB12AC5F67B0283CA5EFE2E764C4369104B9D3B06490D1244 -C41D6085C85F1106082EC9DB84586230511C05C82412D2CDF3DAFBF4759A775628878F997415296B -C416AC8352A6C6988691FCB831CF95C10BAE691ADB3BA2918B35924BD5C3ACAD8B137397B10AF82B -479800FE16D472CD0CDBDAAB4F882A0649CF561004B8CB7CA32EC129D0A415BE6CB91DA2B65F44E8 -0D138808A127E851A7FCF927E99DAA0EA2D626B77A16C72E37F058A3B882FC4955DC8CB6312434BD -3BCED75780B13590BF4FE8D64ACF0371F9FB1D361B05025852AAB9EDA1A0C997CFA58052C454FD45 -1E6C1F194F4D363114E312F6DC35BBAF357A32CD200A3DD9654155134259887D677ACC44F89AA401 -CA27282DF7DC3F2F04A108CBEF2558DCCE28BAC2D87B8D5B7181EA927F61977764F882626D4AB338 -D95C9477C54E9C36012A3CFFBE199EC8120A99D2D70A21F9D9A0354E4EAC7947990E8A6E0601796A -AF6F14E758CABCABDFBD8204A8E748A3E5FEBA570D36E2BF474C0083229A63F96114182321B2EBE1 -BC76DD193724C4588C1D39D184C332FAEAF4C629F2B3B2F49996E46AA6C9F497428BEA52D58876B0 -DC07B460248BC85CC16773A5DAC36CDE8B152D96057F4EFAAF8B1DC10022038577368057699B3A37 -178A9F1F6C6CC60BAE820B7ADD0717911BD23A6DCDADAFA32473491AA80CFE90F2A77E24CE2826FF -77B18B869C33FA292FE01D6477765044C7D14A548B28B1360125C6933F05C58B0889390537CDD16F -8E967E0B38579449DFC1E07389B7069AA8594C5103465D5041CC929268DE863FADB6925B350AA94A -27D421FB7FCC81C6B35F906F12246B7A5140511A97211BA9BD6831A508E963FE8BE961332F557808 -488F06EAD75E86D60DE3FA2425AE8439ECB9112BC3E4D73747C1C8E87A649919827049832DB0BF6D -A8C85C9A2592AC002809070900ECAD52A56F1BFD456AFE066509694EAC075788456B0B0BDD7C192D -321E9FB6AADCAEF00F570F22CD4A5322FBCE8FA98FAEB681940895426270BB4319C11DA67D88552A -7373398AEC5DA7C9CAA9F3B34581C6E968DAAAB2751CC012199DD897B448986CFFBAE4D412BF9ECB -F46742715A9569932516259D3B3A5431CD7028E42FC751C434E2B714C718202BF02CAF9B8A2075DE -922322EA7CFA605C8376FA958B8FBE43031E1026FBE6126A3775F643EA67EBBD97F239FB3C435526 -75CD08B19CA5EBF53B40D728556B4481C7F73EC71CAB0F89E34D60C69B272FADC22E8E7BDC6210DB -09FDD913E209F49FD28E8712B8508904620250746CA3B21B026EDAE60A2822F59E912E626B93E0D2 -BFB3230DFD0E54E91A1DBA25A609B64D41ABD897A5D21764C351E85F9E87BEAB9E645149AD32AEEB -B3B1161032C701647115F98C1C2AAECE871862D91D321AB90F3E923B1FDEE00D927F897AA9812373 -6536E2E0700F10053D7E6C589BF66029D794883EAE4C8228941CE96565B50D48887B5314A2E55379 -59638222A6CA54C77CBABD460DAC11B063519AE4F50D93DE41763BA7CFBF4C7724360E750478EB62 -8921DAA065858341958E4F3EB5966C6DD77C05EEECDF4B5F6CF19AB507589B4219377959BD258EC9 -21C34FE1DB003F7D0FEA3E2FD6F5DDB0A2D62CA5A2CD3C7AB457DFF25094EFE04A9E1B9CE7AE3F30 -026B1CB039228D309A22899F6E9B9BFF922E117123347967D7C62C670E2C74579C35989925603022 -C17B1DCE378031ABC9B4B437C7B6E64620932E93189754C01D4B280B8B08699B2CA953AE4823BB9E -E34133C5C95B3290E1BF010705AD852C72BE87291E1034B09F44A95B6A2F83FEE8841DCF661770AF -44D0AC7F9CDB280939FC5D953D525E0B41B7BE188D5C794687330CD770D24D9CD53B895A253004E1 -8A31BE4E82B384 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont -/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont -/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont -/NimbusMonL-ReguObli-iso1252 /NimbusMonL-ReguObli ISO1252Encoding psp_definefont -295 271 moveto -0 0 0 setrgbcolor -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 271 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -659 271 moveto -<6475> -show -738 271 moveto -<66696368696572> -show -897 271 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F534D4553485F492F534D4553485F47656E5F692E6378782C> -show -1898 271 moveto -0 0 0 setrgbcolor - -show -370 331 moveto -<434F52424120> -show -543 331 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572206C652067E96EE97261746575722E> -show -294 433 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<23696E636C7564652094534D4553485F4D6178456C656D656E74566F6C756D655F692E68787894> -show -294 476 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 520 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 564 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 608 moveto -<202020202020646F75626C65206C656E6774682C6D6178456C656D656E7473417265612C6D6178 -456C656D656E7473566F6C756D653B> -show -294 652 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 696 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 740 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 784 moveto -<2020202020202020656C73652069662028737472636D70286D794879702D> -show -1050 784 moveto -<3E4765744E616D652C> -show -1276 784 moveto -<944D6178456C656D656E74566F6C756D659429203D3D203029207B> -show -294 828 moveto -<20202020202020202020534D4553483A3A534D4553485F4D6178456C656D656E74566F6C756D65 -5F766172204D4556203D> -show -294 872 moveto -<202020202020202020202020202020202020534D4553483A3A534D4553485F4D6178456C656D65 -6E74566F6C756D653A3A5F6E6172726F7728206D7948797020293B> -show -294 916 moveto -<202020202020202020206D6178456C656D656E74566F6C756D65203D204D45562D> -show -1125 916 moveto -<3E4765744D6178456C656D656E74566F6C756D6528293B> -show -294 960 moveto -<20202020202020202020667072696E7466286465737446696C652C> -show -974 960 moveto -<9425665C6E942C6D6178456C656D656E74566F6C756D65> -show -1553 960 moveto -<293B> -show -294 1004 moveto -<20202020202020207D> -show -294 1048 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1092 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1136 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1180 moveto -<202020202020646F75626C65206C656E6774682C6D6178456C656D656E7473417265612C6D6178 -456C656D656E7473566F6C756D653B> -show -294 1224 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1268 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1312 moveto -<20202020202020202020202020202020202E202020202020202020202020202020202020202020 -20202020202020202020202020202E> -show -294 1356 moveto -<2020202020202020202020656C73652069662028737472636D7028614C696E65> -show -1100 1356 moveto -<2C> -show -1125 1356 moveto -<944D6178456C656D656E74566F6C756D659429203D3D203029207B> -show -294 1400 moveto -<2020202020202020534D4553483A3A534D4553485F4879706F7468657369735F766172206D7948 -7970203D> -show -294 1444 moveto -<2020202020202020202020202020202020746869732D> -show -848 1444 moveto -<3E4372656174654879706F74686573697328614C696E652C73747564794964293B> -show -294 1488 moveto -<2020202020202020534D4553483A3A534D4553485F4D6178456C656D656E74566F6C756D655F76 -6172204D4556203D> -show -294 1531 moveto -<202020202020202020202020202020202020534D4553483A3A534D4553485F4D6178456C656D65 -6E74566F6C756D653A3A5F6E6172726F7728206D7948797020293B> -show -294 1575 moveto -<2020202020202020667363616E66286C6F616446696C652C942573942C614C696E65293B> -show -294 1619 moveto -<20202020202020206D6178456C656D656E74566F6C756D65203D2061746F6628614C696E65293B> -show -294 1663 moveto -<20202020202020204D45562D> -show -596 1663 moveto -<3E5365744D6178456C656D656E74566F6C756D6528> -show -1125 1663 moveto -<6D6178456C656D656E74566F6C756D65> -show -1528 1663 moveto -<293B> -show -294 1707 moveto -<2020202020202020737472696E6720696F72537472696E67203D20> -show -974 1707 moveto -/NimbusMonL-ReguObli-iso1252 findfont 42 -42 matrix scale makefont setfont -<6F7262> -show -1049 1707 moveto -<2D> -show -1074 1707 moveto -<3E6F626A656374> -show -1250 1707 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<746F5F737472696E67284D4556293B> -show -294 1751 moveto -<2020202020202020737072696E7466286F626A65637449642C> -show -924 1751 moveto -<942564942C4D45562D> -show -1150 1751 moveto -<3E47657449642829293B> -show -294 1795 moveto -<2020202020202020534D455348436F7262614F626A5B737472696E6728> -show -1024 1795 moveto -<944879706F5F94> -show -1200 1795 moveto -<292B737472696E67286F626A6563744964295D203D20696F72537472696E673B> -show -294 1839 moveto -<2020202020202020> -show -495 1839 moveto -<7D> -show -295 1956 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 1956 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E20646573206669636869657273> -show -370 2015 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F575F534D44 -535F4D6573682E63787820> -show -1672 2015 moveto -0 0 0 setrgbcolor -<6574> -show -370 2070 moveto -1 0 0 setrgbcolor -<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F575F534D45 -534844535F4D6573682E63787820> -show -1764 2070 moveto -0 0 0 setrgbcolor -<706F7572206C27E96372697475726520E0> -show -370 2125 moveto -<74726176657273> -show -551 2125 moveto -<6C65> -show -627 2125 moveto -<647269766572> -show -789 2125 moveto -<4D4544> -show -937 2125 moveto -<64616E73> -show -1072 2125 moveto -<6C61> -show -1150 2125 moveto -<737472756374757265> -show -1370 2125 moveto -<6465> -show -1458 2125 moveto -<646F6E6EE965> -show -1642 2125 moveto -<534D4453> -show -1809 2125 moveto -<6574> -show -1885 2125 moveto -<534D4553484453> -show -370 2180 moveto -<726573706563746976656D656E742028636573207374727563747572657320736F6E7420696E74 -65726E6573206175206D6F64756C6520534D455348292E> -show -294 2282 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<202020202020636173652034> -show -596 2282 moveto -<20> -show -621 2282 moveto -<3A> -show -294 2326 moveto -<2020202020202020656C656D5F49645B375D2E707573685F6261636B28656C656D2D> -show -1150 2326 moveto -<3E47657449442829293B> -show -294 2370 moveto -<20202020202020206E6D61696C6C65735B375D2B2B3B> -show -294 2414 moveto -<2020202020202020627265616B3B> -show -294 2458 moveto -<2020202020207D> -show -295 2575 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 2575 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E2064752066696368696572> -show -370 2634 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F525F534D44 -535F4D6573682E637878> -show -1712 2634 moveto -0 0 0 setrgbcolor -<706F7572> -show -1838 2634 moveto -<6C61> -show -1909 2634 moveto -<6C656374757265> -show -2080 2634 moveto - -show -370 2689 moveto -<74726176657273206C6520647269766572204D454420737572206C612073747275637475726520 -646520646F6E6EE965206475206D61696C6C61676520534D44532E> -show -280 399 1 1451 rectfill -2125 399 1 1451 rectfill -280 399 1846 1 rectfill -280 1849 1846 1 rectfill -280 2248 1 220 rectfill -2125 2248 1 220 rectfill -280 2248 1846 1 rectfill -280 2467 1846 1 rectfill -showpage -grestore grestore -%%PageTrailer - -%%Page: 5 5 -%%PageBoundingBox: 18 18 577 824 -%%BeginSetup -% -%%EndSetup -%%BeginPageSetup -% -gsave -[0.24 0 0 -0.24 18 824] concat -gsave -%%EndPageSetup -%%BeginResource: font NimbusMonL-Regu -%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle 0.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-Regu def -/PaintType 0 def -/WMode 0 def -/FontBBox {-12 -237 650 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020945 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 -5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E -6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 -87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B -A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 -643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 -C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 -F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 -FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E -61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 -4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C -CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 -2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA -A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC -0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 -4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 -FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 -61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 -3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 -1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 -72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B -B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A -36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC -40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A -4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 -46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 -D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB -B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F -8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 -4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C -F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C -BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB -C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 -966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 -998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 -CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E -C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 -D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 -1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF -1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 -A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 -583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 -7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 -9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 -77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 -7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 -45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 -C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 -EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 -077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 -E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B -1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 -27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 -F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 -FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B -6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 -2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 -FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 -A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 -23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 -56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 -5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF -13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F -FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C -3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 -2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 -C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F -1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 -88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 -8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE -FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA -D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC -2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C -9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F -D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A -EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 -F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 -67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 -A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 -9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D -183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 -BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 -4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 -556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 -1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 -F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 -2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C -FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F -ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 -2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC -ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 -2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 -298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 -BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 -47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE -48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C -BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 -5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 -55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 -2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 -4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D -8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D -69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A -AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE -61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B -834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 -E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D -E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F -46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 -A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 -F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E -185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 -7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 -6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 -B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C -D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 -606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F -AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E -064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C -FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE -874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD -060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C -AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D -D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 -A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE -528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A -302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 -934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 -57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 -71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 -D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 -B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 -48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 -21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 -B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 -CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED -DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 -718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 -5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F -E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC -41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 -5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 -7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 -D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 -D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 -4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC -1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 -374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 -E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF -4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 -AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E -4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 -858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB -EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 -BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F -45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E -050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED -199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 -7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE -B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC -91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 -905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 -E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 -81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 -B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 -9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B -470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 -627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 -2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E -BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 -9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 -8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 -1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 -4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E -06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 -65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 -C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 -52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE -64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 -C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 -17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 -C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE -2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF -1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 -03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 -88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 -37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 -F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 -6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 -59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 -EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E -2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 -24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C -F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE -400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 -1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 -9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 -DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB -7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 -F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F -E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B -727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE -58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 -840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 -EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 -CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A -622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 -D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C -91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 -7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C -5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 -FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E -DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 -54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A -E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD -F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 -A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A -623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA -891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 -7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 -FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B -92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F -01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 -B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 -4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 -F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB -45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 -31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 -FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE -537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E -7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 -9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 -E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D -CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB -9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 -3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F -B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA -A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 -6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 -97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 -4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 -39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 -BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A -C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 -1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 -2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 -8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 -9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 -351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 -3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB -7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 -5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 -3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF -F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 -B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 -7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 -801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 -AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 -9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 -B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 -8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 -014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C -46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C -CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 -6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 -55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 -1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 -141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 -F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 -F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 -F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A -E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 -53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B -31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE -C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D -B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 -723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 -04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 -FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F -2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 -03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A -065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 -6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 -C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E -AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB -E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 -98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C -35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE -A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 -E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 -5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 -B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 -79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 -67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 -8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 -5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 -FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 -9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 -ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 -56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB -384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 -6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 -0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 -12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 -40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 -148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C -AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 -DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 -2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A -457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E -5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A -955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF -F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 -4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A -0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C -44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 -289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 -247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 -CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C -2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 -1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 -F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 -BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 -51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF -28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F -AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 -2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 -2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 -070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D -9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E -3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC -FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 -1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F -C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 -EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D -DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 -0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 -B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C -5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 -7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 -9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 -F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB -AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 -6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB -78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE -F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D -92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 -9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 -E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 -68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE -FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA -304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE -2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 -3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 -02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A -7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B -94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A -1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 -81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D -83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 -01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D -C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 -26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 -860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 -C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 -18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 -2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 -CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 -E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF -2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 -2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E -67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E -E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 -8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA -774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A -53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 -1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 -5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 -389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F -5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 -B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE -7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 -703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 -5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB -250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF -6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 -782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 -FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 -6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 -39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 -3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 -36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 -0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 -5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 -1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 -AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D -EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF -E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 -03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF -4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB -D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B -E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 -71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 -1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 -1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 -84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 -6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 -0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 -2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 -9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD -02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 -F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 -5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC -7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 -F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 -9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C -C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB -85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 -048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED -22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB -41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 -27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 -DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB -388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 -4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 -7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 -343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 -C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 -BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 -5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F -5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 -25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 -AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 -9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 -66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 -29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 -39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D -F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A -279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D -A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 -09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F -2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 -AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 -F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 -1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 -FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF -5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 -961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A -BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA -40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 -08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B -472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 -3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C -87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 -0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D -5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 -FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA -2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 -2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 -15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 -A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C -250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C -8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 -C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE -F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C -9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 -B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 -56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF -A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 -BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 -CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 -175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 -7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A -FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 -E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 -6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 -AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 -4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 -08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B -F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 -958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF -EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 -15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 -CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F -B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 -2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 -8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 -1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 -7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 -D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 -9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E -84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 -C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E -8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC -3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 -AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC -806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 -64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C -ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D -1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E -565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD -540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD -093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B -FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 -2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D -BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 -EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C -C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A -2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 -C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 -F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 -89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B -169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 -ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D -20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 -B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D -E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE -6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC -31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 -33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B -7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C -B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 -4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC -1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 -89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C -212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA -34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 -D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 -38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 -DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 -8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 -212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 -3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 -F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 -1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 -12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 -9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 -B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 -5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 -564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 -5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D -867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 -53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 -3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B -451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C -B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 -CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 -C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 -E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF -64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 -8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 -AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 -BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 -A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 -990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D -B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 -4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 -84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C -F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 -D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 -37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 -D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 -EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 -FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A -DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 -62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 -54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB -AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 -0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 -4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 -2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C -2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC -F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 -BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 -D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 -C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF -46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 -50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED -49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D -20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F -BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A -977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 -EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF -56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 -CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF -3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 -B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 -062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 -D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE -3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 -940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD -6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F -E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 -F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 -DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F -5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D -7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 -695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 -C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 -8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 -39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 -3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD -2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 -6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 -5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C -5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF -B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 -06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 -1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 -6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 -4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 -0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 -B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 -E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A -1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 -354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 -9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 -BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 -F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 -9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 -54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D -092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 -741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 -57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 -C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 -7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 -3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 -82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 -C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 -615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 -B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 -A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 -9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 -FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 -EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F -818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C -715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 -8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 -1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 -707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 -4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D -54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 -2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 -15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 -63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B -81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 -CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 -E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB -2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 -E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 -B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 -AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 -3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A -04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 -151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 -E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 -26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 -3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 -772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF -27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E -DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 -898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 -AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F -C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 -CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D -59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 -4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 -3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 -FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 -90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC -167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 -573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F -C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E -96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 -2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 -7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC -B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E -E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 -51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F -025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 -2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF -C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F -E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 -EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F -DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 -E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 -E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF -C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D -84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C -61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 -33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 -C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 -1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D -CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C -984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 -8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 -596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 -A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 -015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC -0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF -27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 -0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 -46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 -1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 -33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A -77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 -75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 -749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD -77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF -2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 -1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 -703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D -A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 -907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB -9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 -782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 -B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A -A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 -4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 -1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE -2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B -50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 -CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC -39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 -FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE -9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 -E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 -533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D -CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 -8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA -AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 -0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 -8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 -1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E -98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 -F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E -5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 -A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA -3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA -5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 -04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB -84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C -C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB -76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 -27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 -01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE -7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 -6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A -3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F -C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A -9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C -53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 -D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 -92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 -1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 -7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 -009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE -B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F -F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 -789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 -50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF -76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 -AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 -897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 -9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 -5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F -86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 -A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 -F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F -FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 -DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD -77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 -1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F -518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 -47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 -7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A -CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A -B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 -DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 -B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C -33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 -1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 -904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE -17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A -79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF -00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E -BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF -B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 -0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B -E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F -1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E -0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 -0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 -5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 -3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 -81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB -1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 -963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 -4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 -86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 -7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 -2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 -6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B -37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 -84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 -B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 -402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 -C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 -B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 -88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 -49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B -B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 -ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 -5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB -6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 -D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F -E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 -D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB -CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 -5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 -D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D -605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 -3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 -5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A -807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 -FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A -4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 -B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A -CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 -205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 -38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 -F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE -263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 -E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF -207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA -D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC -3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 -66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D -B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E -6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 -EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF -9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC -D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 -860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 -B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 -A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D -9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 -FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 -584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 -6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 -EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 -5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 -4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 -D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E -933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 -7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 -CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF -F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A -DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 -611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 -DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 -40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F -AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE -8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B -C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 -AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 -1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 -C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 -749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 -B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C -CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 -83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B -35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E -A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F -A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 -4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A -B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 -58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D -F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A -69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 -7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 -748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E -5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 -81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 -236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A -9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF -CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 -ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA -26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB -17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 -ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 -60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 -6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 -9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 -4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC -B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 -7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA -00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 -5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB -625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 -38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE -2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 -3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 -79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 -799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A -80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 -411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 -BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 -D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 -D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 -42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 -70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 -B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 -00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 -E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B -A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 -44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D -ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 -3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A -3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 -E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C -9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 -238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 -EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 -7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D -324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 -B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D -B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE -F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD -99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 -A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 -7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A -CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C -A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 -2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 -A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 -B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC -7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 -D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D -057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE -D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 -6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 -8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A -CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 -41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F -01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 -31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 -3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 -696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 -36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB -D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD -0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 -CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB -012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 -006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 -B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 -9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 -85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 -024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 -75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 -CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 -6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A -83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 -4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 -1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A -A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 -E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F -26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 -C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 -9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA -98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 -EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C -2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC -B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 -2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 -10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 -DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 -E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 -7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 -73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E -9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 -EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C -0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 -363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 -6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 -EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 -E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 -09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 -1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 -0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B -195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 -AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 -D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 -05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 -FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A -BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E -2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F -2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B -913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B -C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 -BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F -9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA -112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 -4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 -D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 -292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA -8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 -6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA -F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 -FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 -A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 -1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D -09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 -39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A -6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B -E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 -4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D -8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 -C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C -31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E -0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC -9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 -B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 -BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 -3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 -1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD -F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 -A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 -B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F -FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E -81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 -5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 -1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 -B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C -29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 -8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 -97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A -D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 -3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 -D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE -41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB -44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 -B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A -69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 -84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E -749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 -9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 -D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 -86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 -70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC -151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 -3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE -4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 -CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 -347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E -D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B -BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF -FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E -C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E -D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF -C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE -1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 -859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD -BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA -D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 -1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 -4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D -430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 -A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC -089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 -BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 -143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 -2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 -12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 -331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 -07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 -5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B -1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 -24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 -1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 -FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 -8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 -5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 -FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 -E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 -9F08ABD4F4B0889283E55500702185A841E328 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont -/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont -/Times-Italic-iso1252 /Times-Italic ISO1252Encoding psp_definefont -294 254 moveto -0 0 0 setrgbcolor -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<202020202020> -show -445 254 moveto -<63617365204D45445F544554524134> -show -823 254 moveto -<20> -show -848 254 moveto -<3A207B> -show -294 298 moveto -<202020202020202069662028696E75656C6529207B> -show -294 342 moveto -<20202020202020202020666F7220286A3D303B6A> -show -798 342 moveto -<3C6E6D61696C6C65735B695D3B6A2B2B29207B> -show -294 386 moveto -<202020202020202020202020656C656D5F69643D2A286E756D656C652B6A293B> -show -294 430 moveto -<2020202020202020202020206F6B203D206D794D657368> -show -873 430 moveto -<2D> -show -898 430 moveto -<3E416464566F6C756D65576974684944282A28636F6E6E65637469766974652B6A2A287461696C -6C6529292C> -show -294 474 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B31292C> -show -294 518 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B32292C> -show -294 562 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B33292C> -show -294 606 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -2020656C656D5F6964293B> -show -294 650 moveto -<202020202020202020207D> -show -294 694 moveto -<2020202020202020> -show -495 694 moveto -<7D> -show -294 738 moveto -<2020202020202020656C7365207B> -show -294 782 moveto -<20202020202020202020666F7220286A3D303B6A> -show -798 782 moveto -<3C6E6D61696C6C65735B695D3B6A2B2B29207B> -show -294 826 moveto -<202020202020202020202020> -show -596 826 moveto -<636D70743B> -show -294 870 moveto -<202020202020202020202020> -show -596 870 moveto -<6F6B203D206D794D657368> -show -874 870 moveto -<2D> -show -899 870 moveto -<3E416464566F6C756D65576974684944282A28636F6E6E65637469766974652B6A2A287461696C -6C6529292C> -show -294 914 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -2020> -show -1327 914 moveto -<2A28636F6E6E65637469766974652B6A2A287461696C6C65292B31292C> -show -294 958 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B32292C> -show -294 1002 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -20202A28636F6E6E65637469766974652B6A2A287461696C6C65292B33292C> -show -294 1046 moveto -<202020202020202020202020202020202020202020202020202020202020202020202020202020 -2020636D7074293B> -show -294 1090 moveto -<20202020202020207D> -show -294 1134 moveto -<2020202020202020627265616B3B> -show -294 1178 moveto -<2020202020207D> -show -220 1289 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -507 1289 moveto -<6475> -show -583 1289 moveto -<66696368696572> -show -740 1289 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F5352432F7372632F4472697665724D45442F4472697665724D45445F525F534D45 -534844535F4D6573682E637878> -show -220 1344 moveto -0 0 0 setrgbcolor -<706F7572206C61206C65637475726520E02074726176657273206C6520647269766572204D4544 -20737572206C612073747275637475726520646520646F6E6EE965206475206D61696C6C61676520 -534D45534844532E> -show -294 1445 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<202020202020> -show -445 1445 moveto -<63617365204D45445F544554524134> -show -823 1445 moveto -<20> -show -848 1445 moveto -<3A207B> -show -294 1489 moveto -<202020202020202069662028696E75656C6529207B> -show -294 1533 moveto -<20202020202020202020666F7220286A3D303B6A> -show -798 1533 moveto -<3C6E6D61696C6C65735B695D3B6A2B2B29207B> -show -294 1577 moveto -<202020202020202020202020> -show -596 1577 moveto -<656C656D5F69643D2A286E756D656C652B6A293B> -show -294 1621 moveto -<2020202020202020202020206F6B203D206D79534D45534844534D657368> -show -1050 1621 moveto -<2D> -show -1075 1621 moveto -<3E416464566F6C756D6557697468494428> -show -294 1665 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C652D6E73757029292C> -show -294 1709 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C652D6E737570292B31292C> -show -294 1753 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C652D6E737570292B32292C> -show -294 1797 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C652D6E737570292B33292C> -show -294 1841 moveto -<2020202020202020202020202020202020202020202020202020202020202020> -show -1100 1841 moveto -<656C656D5F6964293B> -show -294 1885 moveto -<202020202020202020207D> -show -294 1929 moveto -<20202020202020207D> -show -294 1973 moveto -<2020202020202020656C7365207B> -show -294 2016 moveto -<20202020202020202020666F7220286A3D303B6A> -show -798 2016 moveto -<3C6E6D61696C6C65735B695D3B6A2B2B29207B> -show -294 2060 moveto -<202020202020202020202020636D70743B> -show -294 2104 moveto -<2020202020202020202020206F6B203D206D79534D45534844534D657368> -show -1050 2104 moveto -<2D> -show -1075 2104 moveto -<3E416464566F6C756D6557697468494428> -show -294 2148 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C6529292C> -show -294 2192 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C65292B31292C> -show -294 2236 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C65292B32292C> -show -294 2280 moveto -<20202020202020202020202020202020202020202020202020202020202020202A28636F6E6E65 -637469766974652B6A2A287461696C6C65292B33292C> -show -294 2324 moveto -<2020202020202020202020202020202020202020202020202020202020202020636D7074293B> -show -294 2368 moveto -<20202020202020207D> -show -294 2412 moveto -<2020202020202020627265616B3B> -show -294 2456 moveto -<2020202020207D> -show -295 2573 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 2573 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D6F64696669636174696F6E> -show -656 2573 moveto -<6475> -show -733 2573 moveto -<66696368696572> -show -889 2573 moveto -1 0 0 setrgbcolor -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F535243> -show -1161 2573 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1174 2573 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<737263> -show -1235 2573 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1248 2573 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<534D4553485F53574947> -show -1550 2573 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<2F> -show -1563 2573 moveto -/Times-Italic-iso1252 findfont 50 -50 matrix scale makefont setfont -<4D616B6566696C652E696E2C> -show -1826 2573 moveto -0 0 0 setrgbcolor -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<706F7572> -show -1943 2573 moveto -<6578706F72746572> -show -370 2633 moveto -<6C6573> -show -465 2633 moveto -<73637269707473> -show -635 2633 moveto -<707974686F6E> -show -813 2633 moveto -<6465> -show -900 2633 moveto -<7465737465> -show -1031 2633 moveto -<6475> -show -1119 2633 moveto -<6D61696C6C657572> -show -1326 2633 moveto -<74E974726168E9647269717565> -show -1589 2633 moveto -<20> -show -1601 2633 moveto -<3A> -show -1654 2633 moveto -<534D4553485F626F785F74657472612E70792C> -show -370 2689 moveto -<534D4553485F626F78325F74657472612E70792C20534D4553485F626F78335F74657472612E70 -792C20534D4553485F6D656368616E69635F74657472612E70792C> -show -370 2745 moveto -<534D4553485F6669786174696F6E5F74657472612E7079> -show -912 2745 moveto -<6574> -show -966 2745 moveto -<534D4553485F506172746974696F6E315F74657472612E70792E> -show -1581 2745 moveto -<534D4553485F6669786174696F6E5F686578612E7079> -show -370 2801 moveto -<657374> -show -468 2801 moveto -<756E> -show -560 2801 moveto -<6175747265> -show -703 2801 moveto -<736372697074> -show -856 2801 moveto -<707974686F6E> -show -1038 2801 moveto -<6465> -show -1127 2801 moveto -<7465737465> -show -1261 2801 moveto -<6475> -show -1354 2801 moveto -<6D61696C6C657572> -show -1563 2801 moveto -<6865786168E9647269717565> -show -1875 2801 moveto -<74616E646973> -show -2037 2801 moveto -<717565> -show -370 2858 moveto -<534D4553485F666C696768745F736B696E2E7079> -show -859 2858 moveto -<657374> -show -933 2858 moveto -<756E> -show -1001 2858 moveto -<6175747265> -show -1120 2858 moveto -<736372697074> -show -1249 2858 moveto -<707974686F6E> -show -1406 2858 moveto -<6465> -show -1472 2858 moveto -<7465737465> -show -1582 2858 moveto -<6475> -show -1650 2858 moveto -<6D61696C6C657572> -show -1835 2858 moveto -<73757266616369717565> -show -2061 2858 moveto -<656E> -show -370 2914 moveto -<747269616E676C65> -show -621 2914 moveto -<7574696C6973616E74> -show -880 2914 moveto -<4D45464953544F5F3244> -show -1279 2914 moveto -<61766563> -show -1469 2914 moveto -<6C276879706F7468E87365> -show -1792 2914 moveto -<6465> -show -1938 2914 moveto -<6D61696C6C616765> -show -370 2970 moveto -<534D4553485F4C656E67746846726F6D45646765732E> -show -1028 2970 moveto -<4427617574726573> -show -1275 2970 moveto -<6669636869657273> -show -1508 2970 moveto -<6465> -show -1637 2970 moveto -<7465737465> -show -1811 2970 moveto -<736F6E74> -show -1977 2970 moveto -<7072E9767573> -show -370 3026 moveto -<534D4553485F506172746974696F6E5B322C332C342C355D2E7079> -show -1000 3026 moveto -<6D616973> -show -1110 3026 moveto -<636575782D6369> -show -1273 3026 moveto -<6EE9636573736974656E74> -show -1509 3026 moveto -<756E> -show -1576 3026 moveto -<616A757374656D656E74> -show -1809 3026 moveto -<646573> -show -1891 3026 moveto -<706172616DE874726573> -show -370 3082 moveto -<6465206D61696C6C6167652E> -show -280 221 1 967 rectfill -2125 221 1 967 rectfill -280 221 1846 1 rectfill -280 1187 1846 1 rectfill -280 1411 1 1056 rectfill -2125 1411 1 1056 rectfill -280 1411 1846 1 rectfill -280 2466 1846 1 rectfill -showpage -grestore grestore -%%PageTrailer - -%%Page: 6 6 -%%PageBoundingBox: 18 18 577 824 -%%BeginSetup -% -%%EndSetup -%%BeginPageSetup -% -gsave -[0.24 0 0 -0.24 18 824] concat -gsave -%%EndPageSetup -%%BeginResource: font NimbusMonL-Regu -%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 -%%CreationDate: Wed Dec 22 1999 -% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development -% (URW)++,Copyright 1999 by (URW)++ Design & Development -% See the file PUBLIC (Aladdin Free Public License) for license conditions. -% As a special exception, permission is granted to include this font -% program in a Postscript or PDF file that consists of a document that -% contains text to be displayed or printed using this font, regardless -% of the conditions or license applying to the document itself. -12 dict begin -/FontInfo 10 dict dup begin -/version (1.05) readonly def -/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file PUBLIC (Aladdin Free Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def -/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def -/FullName (Nimbus Mono L Regular) readonly def -/FamilyName (Nimbus Mono L) readonly def -/Weight (Regular) readonly def -/ItalicAngle 0.0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /NimbusMonL-Regu def -/PaintType 0 def -/WMode 0 def -/FontBBox {-12 -237 650 811} readonly def -/FontType 1 def -/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def -/Encoding StandardEncoding def -/UniqueID 5020945 def -currentdict end -currentfile eexec -E98D09D760A3C22CF119F9DC699A22C35B5B35ED6AA23593C76D54CABB5E942BF7D6DD84F1664B89 -699C74B472DE9F8E6DF925F6C4F204E9F1C639B4DBA988ED2AC419FF2B2BDE605B8EE3264EDD6641 -2D4F21C64AC522BDFC7C5502F9C3F3E5592B3B2093D33C9BFAEDD2D49E89AABAA832E23F062E91A2 -5032519D1868816E44B4E0747795003D7930299D6E1E2A5BFE0D595DC97E140989CE81D8D7F852FF -9CDC7A1B1B598C69131DEE005B415805A16D8A123E6A2261C63C769D2F4B60FA2C438AD7D199D8E4 -5F7E7C9A605C8CA14E21FCD81C9A515FB8DB6F99604534D06EA9D87FE0FAA852899C9D0595C7A97E -6C55F79FAC45CD38E87B10D210CE7501E88C8FCD3444354365FB893A12F596AE2C1E70D5819EE0D0 -87D10BF8DA96F3DABD5405D28C4228C6C31BA4052464859640933FEEFD8071C0C84CDD829A9B1D0B -A01F25A4D50EE2EA2B45160CA6333B2D2800306ED2BEFDFE155E9D9F9342EB8D5B0ADBF2460CCC98 -643FB1287CCD28ABA7B5CAB92EC39EE2E918990372B16F8487EBA30EAE88708B6CF33B6C015D8096 -C7CFE2F139F52052E3925C0D50FD64CE68236D59CB83EF56BFC584150EC38065059F3308AD6F9A99 -F83EF4E6CB13855C8175E31417D190D036B387D3952344A950F4D8C7781B307A094DF1ECAEE4D2C2 -FD747BC6F7F9C6BD0E90C19294F96C8C5CFE88FB34C477574A1B1630B8CC591529E59B20794DA32E -61DECDA8ABBD1AE956CF74012AA01D42EE01E861B0AA6897C864788AE59DEF43C493246FDB1ACA55 -4C12594BC7B33657A9ECC9E3D1472EF826073F632BE540C35FF6FB40566773F3BB2204D3A579A08C -CBC844C14B18C350F003B9DA23A570C362D6003893CA32F86F59B829C78EE3188B6E3F7FA81D7F62 -2825C639638DFB78B7AF1F500F5B450FA54DBFA5CBA277C794ECE93275A3DE0B452FDC8DDC2993BA -A42F28A636008CDCB03EBF71BDCAF35019778993443F88412AD2AD0D7155A3944606463266322DBC -0244B07DA1E9C27A27B59664E8566D7A54CC03E995AAD008B0A17E2C3EF61F720CE7F7788599C4E4 -4C709CD5C31B11107F16AD70B17B9AFE2E8CD922A7428DAC171427FFAF51067307FAB0ADB530E701 -FD22DA22C4CD3064067BD4F6089C4B2C87937DD426E4E9D2F60E608288BAC9056554D04947E69200 -61E379CF5E81BFD32FD37EFAC1F61CEBEE551B0851516471A7472C60DF89DAA9EB1DC5A67E479745 -3E69B9E22BAF4E3CCA4192D603295B018C4AB69D18DE52DFDF15E96B557F290A4B8C5B1E7A6CACA8 -1F2351B97ADFC36995ABA43803A6E5AC04A3C93495F6D38106B8B144449C07D1358210F9176E1565 -72363CFBDE576BFDF99FA329DD1346E83F79E06CF68250CA57A68931BC7F342AD295D0CBA17AA95B -B8EEB53EA6E8E660B814E9F857CECB14F44A43288B69A9E7908D55BF19E844359879D28CAEF1C38A -36420185D20DFB32C2E002202800E8EF3D67C5D50E919657CA958B538D537D503444865331D79BFC -40312068D72364503BD0CC84B5F30A74D8B5B6A26AF2DB764564FB65A6BA8F9051AE2B4EA458D46A -4569F30C6E77DC097356770362E6CF3F1661074778EBB44FF7D1E3B64FF75E77E11FE525BB121C65 -46CFD13300CA1F02D571B82A5825E6226D14FDCF27F06D87452A8B6C5DCA658535CEE2A795E58137 -D48E566B69D53A0C3B766E84C51EAA221C46999CC8065ADB2F129D5B630FAB1814C0C33B5AEA0EFB -B6E994D80941B53079AF96D90A0B924F9B0E319BED9836B8F9053F868363D3CA554CBB181863301F -8CB940872ED5FA7BD18CE39218B5AD8AC57D0F752D941076B1C64D99BE0DB86D7A6D96510D772EB2 -4C587F11779BD21CFE5BDE1F29C1EF9022B2B8BCD7F91153C845906722477829C40111D810480F3C -F62DE8DBA7FD86CD236E656618CAF6FC46827FBC4898EA7672F8C9971AFE43E0E01EC8B77D4AF48C -BF1210E98C1DB15C16D149BFF58AB0270CF015B107A3A50F5DC8F37FFB92EEC8CB6778DDB7CE4AAB -C464C4AFF654223006A550EB52485A23D2B4AA7198D3CD54418102F1E9A4FBDE37B841E56F5C2C53 -966DB9B66B000E4588282E3FB80C2C519339F0002D2F83C979EDC5827A3B3C8EF8810A0F9DACB6B9 -998E9AF6551F56313DC4011904CB979AA2D32B11A811BC248141E4B9734D9FB7982A5671002D8279 -CAB93ABE057474628DEFC95D43890DB1ED34CFA8A20BDC3D874E7679A396158E522ED0AB969A4E3E -C7E4474E192590504D54DEB7B260B7935C4E56548A7D121AC1F741F8CDF259EA1B5813175A77A1D2 -D30BA26F65EB765A04C09ED51F69F41551ADF399E6AA2FC09788137BEA4913F17B8EB838C38FB272 -1FDCB55FD65697FF0B850E7D3D1CE266BF90F7EC06A9A0876BDFE767D3A918B092FC78C775F945CF -1F96E859C03DBF630D9A940939654C3549D8F7921CB94EE23D5A0535DE9DF31EA0F937F860B4F220 -A99ADDFC343D7CF7BFA0B803C12C26403F0DCFFC8EA786D0D8A8D9C367419CA8AE41190CE93A8086 -583A1E6C9D70B612C84D87D2EEAA71EC2DC12F4CDE6A821303D5F6A9BBDB7EEDCD289E80FA3B75F4 -7F481B50719DCF4A142069393593B9AF9CCEEAEC56A35B8787193D7C88113E9E1E221D151E093B01 -9EF89F6118BEC4735103CC8003CC5AD1B6727B3226CD44C497DA7052DD681695DBEC3397F9598C91 -77701C73BF0594CE93F23D50EC5BEE2FB9DA1FC966DF148B27B28EE3C89526DD6625E2887F9FA076 -7C127C609EE315626BC14D274FBEA56528DC06A27B2D476D46E9E7916590B156A5DF04A6CB15E362 -45D77021767B6E5BDFCC679670263FD891446C3371B11BB6E1DF60F960AAB4149D7753E6A5C33810 -C42C8BFF4E935003388506F8278BD7CB672F132E065AE684DCA0B9064D01DD620E7FFDFE04F14277 -EFE8E60159BA0FCA3FE2F28B902D4AC275D19F0AC6971EBE827C4A232D87650D2688345BCA78F879 -077114F0463C5F058107B669566F8171E4E284D278405580F04BFFC9902784216E0C9A17AA9B2935 -E66E18A783F723BE044389B7E9D62AA36818FF2EA406C3C1A9D2F3436F3EE7DB8BE86AFA8DAA6A4B -1B84611350D8D27605509612B515E16AA843164D5D0805E36A2B9EF74C5F6A0B9D59A04B55697123 -27F4B1B30E9587CD103337639967CBDC655AA46E80D2CFD24BEB50815B5338E522B3A7AFE8362AB4 -F05D8BC52BBA9C5089ADA8C89529B0275AF422EB540D31A938B8740860756325B966B36817115213 -FAAF92DE63F6BAE1E0064BFBC5588098B61EB83C71F1C2082436D37DAF1ACBE186FEDC4BE7C1233B -6F18BEC5F99002D21CB7864E4811F7AB3C03003E1E4490AD1AC793BD28FCD5EF0E6CC30EF39A08C5 -2F71939B0CEF620DC69E31E39D6DB969049031B0C92EF2DB653D97F370141456A52985076B268652 -FA2648C792780BAD637C4D7581FB2D62011D57E293719487CF2D1F013CFAA532E1C2D39178D51272 -A6AF041440BCA174B5CC902BD7390C7D3695056CB4BD7791F9FB6D88E7A70DEF2C97869F5DBC5BD8 -23C517C7B7C39D624DF627DC9653EA5347BFDA80B723F05F6DBB4C9EA501D862ACE05B9DBDF21B70 -56FBCD8C6D4B85873DCEE6166C8B5ADC0316CA12D9639F361B15A42F00E1D62EDBCA1111972FA0F4 -5758BECB31DB38316F3CDFE1B41748C93ED58B67E9B57ABBED5924A6D53E99FBC9A994A6489A8BDF -13EB685548B4DC6D62DA7426C22227D4D43B6FFC7B5EA91C896730253E8941AFEE588359C2BECF6F -FC415B9EB6D31CCB0F6C7F85853E6449FA6D627A97A3CE8303F148393ADCCCDFA2FE085C6908BE5C -3C05AF00A6F02840206C3253A559AC5C049BDDFD11AD9B118403B84DA10AE3C470CB9A9A2D1D7B73 -2F59F5FE146DEDA60AE750F551AAC934621B4470E1BC324C436303E25F81D0DC3188BE0D6FEC5414 -C20E4CB18952E12CB6423DF7124627ACDE145500D77A97A8BFD9CB50D1FAA008E2CE2B2505A4749F -1EBBB092C347023714055A9B63353AF9E7FEE05BB54C9843698101F79888A91531773830C2C967B5 -88D3ACD2192883D5CE3962D51084FC653EAE2C5FB2DA41DACEFB5C76812D2EDB5B109677289CD199 -8D457FB1023A19AC67295BBC1A9A20A426B06A368DF3C5DD083CB1180D287F5500F2C635EDE157EE -FCEEC5503447382D15C748C1E35F68753992E5C90F900DE54D18F8E1B355D1076ADFB1F3590135FA -D1A36F028E44F48ABB149B80CA9A54614D467F8D71CB310BBC7AC7100261092DB8C5BFD39E0AC6BC -2C9D6CBC3A8C05FF8A74CB21608EC4A4CFE4CBAA2D056DBA14206106044DECF59F957EF8A9CADE4C -9B19D8D30DD4FDE6A9548E50DB51ACA73330142153FC36B69C1C8D5B26D0C689B7040E81AC2C864F -D7C097C99BE5953843E172C97AB5684F35FB03A725A89DBF371F08DDF40A1531FC1B676DB0E1543A -EC6E97D3D2E4AA3D5831D8B3C952ABBFA112352814FB6FAB61A0D680E6640F6AEC8426200CF61286 -F7422CB2F78C61EBAA36D47EC16D7FAF8B4AF31D090CDFA255D9D7C61D46CFB22A7D6E1758E71ED5 -67E00CBD8E8F468DDFB477F091A2F915627F22FF47B876544BC1F03B6BBB98385F009C20BB1AA2A7 -A78674692B8EAC2E3C8069B79E679338DA57F72976810F845BEB6B9ADD32B95D78E5E60F16DD1668 -9C05FD82D36A3115BE8ED494A74DD211D58A2CDF983FCB9CDC29BF7F0E29988FA23560EDF514BC1D -183F3B2A22C09FB179B47E05ADEF48DF02F31C29875D1915037B19407764A4292FE44E741651A8E3 -BEB5F0D972B6327090F664417C84F84FFBF0AFFF8B1D85C822D90730AB4140C42A51AA8B1DBE4398 -4EA8566040EB8B341CCE23FD3F69DD235A080BA5C69AECB9BC732BC2D7D40617DDA6B79FB6EE40C3 -556C7DF9B23DAD89E94054B1345DB8402AE679FC4655A4A776C0150463F8DB2BFC0608EA1F124E22 -1DDAE6026B5E5D007A7E4A0D6B3B0CF3A2669E67C5E4F01551966A7BC48F2F4B6A87E740D8095E63 -F77C7A027F26B52F2299DE5B8A2F6209BCF3D31CB0235F998F781E5CC81E31DC424E008D46EC0920 -2951E5684804A0592EA47D6C788A20487BEA2EC8F2E6C1D7F378B62DB43CA43C4B366F8B4319631C -FE9854F0E10321CFA3B01C873584863BBEFC23C72C05E695B56E8A52E89AA2DAB543834D34DCAC5F -ED08DC51825C5257AE59850D101D84F4CAA1D29FC932F9E0EFFBF7A9A7F3685F61F0490CD3CC8988 -2DB52A757A6AF4C4E67B407BD2316B1C0FFE7DC54E43C87B874F57E4903334E2140B011484863CDC -ACA331175F2CF3D72E0042855983AAF8853D3015E870FF0807014C31D55060DF3FE1FCE157324481 -2744AB51322444632F9AFDA6706E320FFE82B8CBE242A19DF00CE73EE48E25FF49D5871BD3E60652 -298FE3E8D400609E232E0DDC794C0579ACEF89E841B2EDCA50D51151F65E8C1CC3B01EF1870558F0 -BF5743718C3E068617E81BFE120C6CA16E0924BFC2541177D53671CAA3AB641C41557DCDAE1A3461 -47B5E999C4541B08B4AFCBC187AFD653D5B5F8386DF6AD8FE69E21BD0567DF494F736C6A184FA4DE -48DC9F347787CA96E2E00A296C2DA05C2AD9BC423E9CA428D7F1FA12DC9353A302FB8C529AF8688C -BB543B45B2717EBF8F6C497935F4F3BFFD285E0402AB7544B3CA4643AE5A8B5250ED987A95FC1F27 -5B9707ACD0641BD0EE2AE9758494F8D8A51DCE408A38AC20EAF0852D72D84D0C6BE973326793AEB9 -55EAC6FE0A2813A355DCD22F6F2CE56588D1C055CDDFA98878BCEB6A018DB22922D2B600A20F8184 -2E665DF41013CA0947C4237C2BD60A75E2FD1A3FB8C8FA19485730B87461AD466ACB02DF8CA24091 -4FB090B3D2B41EB6B8FF05E1A59D9FD668AF70BA5BB72778953BA55FC5F9F626043450E1D09BC83D -8605098ABEF884639A37809A32565CBEFB3FF39EE53D6C18C58C272BB928E4410E361E59A50F242D -69747A032617C52DEBBF62364AB5A96EFAF642D9D82BA679B1D70FAC10A4EB62FA5CFC308E86368A -AAD7E75948F43598CD1C544A0D4091374D7E88D4522CBE902391641327E888E7748FA889DCE67ADE -61699E7D77763681CAEE9B1CA8837B2F7EF9C18CBCC538C465C8E2DD34616953CCB6030A222C728B -834911C1A179E2C770289407AB28B303E724D97F747D6134B425216A64C6E0B60F633E2B85300047 -E4C90339CE030A0FAE31E830C8ABA5AB3386A3B69267351A7BFDD66356AE5E57FB2994452993E90D -E7C4E260ABAB93C37831856A650D56E44172FECA01D6C7C380F250B82473960D2A2A5FB6B4DA668F -46E624ACF7FA0FD4490F485D640A3ADFC9F8652E7A38CE5799F770C3606DB4B8B947F93967F779E3 -A3C0572F13A5A187D31D7BD12A5C7BE23CB6ED6192086241B76C5BA6983DB9C93E4B208D707D3760 -F03CD6272EF3A4CE89B8E52E6AC5871A3D03EB975759AB4BE239E5EC7842CBB333E692CC607C722E -185D3C39164DD320C6945629C70FF66A5237C0A9520A1FAD6EB9816069351AB0F135D90CC0982B14 -7D2294AE4A38A527EE40BE9CDE2512AAEBB590E134388BB171D0956A7C4566D65A9A041BE6C4F883 -6B3EC3D2ED1B48B566A783292B15B6127920D247D494F070BB20BEFF60640B11B276DDEEE49706E8 -B2B21BB40B7F00AAFC594C492C25DCA774E0B80D82E927448DE2E74A9D0DC7AC9260096EAF187B6C -D6AEAA6D1DC4205B4411122751A5B22688404EA7C5861730371FFAC10F5AFD4727A0E402AB5EA757 -606B75EB86A05E8F774D6E430A1A3FE2A37EBB06700474239FB1CFA05EE44B91B82244C575B52E7F -AF934B04EEB0D933FEB57EBE326D75821C8B23EAA85B583AED4320B7F04B9F2DC591091216FDE52E -064BAAA9C2C9D9714B95A4558C21F3CEBE624B5403B31508F178581AF6863083ED762F1E2E34A45C -FDD71660D626FF8648F5D6C5E580D4765A67FB6159EC8077A9F0A88038C8D3D7C77FF0926E2123BE -874F7BCAF129D55A5B5960F824BD1728ABCFCC51D23936DE9A25C408D786E44C3A2BAFA4423177AD -060D21D38E15E23EB6FFC0B4120E814695D423EEFC2744A1FC81B4DF89D76F0A6803D8B14E75538C -AAD03A72517B86514F6952F6FD619D9E910D980F00964DB325318C045BDF79647F453D4A5CF4E61D -D5359782827229310405FBCF6107C3AD9DDEF9A9A339D5D5A6EB2E7838A0A43221BD62CBDF732DB0 -A638A52016FB35BA7761AEC846A023D3BF2D1BB183543E81EB7CAC1E5970CDC6F068C5EA118C7AAE -528D1396E6DC939112DA4460C890EAD5C01BDC438F5BB734218BA6270ADD0DC1778FD8AB16831D6A -302B814A1A44B07EDC65956C9E6CF4875DF521F3CE5B422F71081B6D69BD270F739095C9E81C0377 -934A8BC6390C420C4E4CDD9CF7E32544C68D884E15ACA3BCC07FC8C132D8FB9D752C15D75C52C288 -57E2EA461A6FCAD90C56843513F74461F18D7164BC597A28AE4BA7C86EE1703535A9B9ED50122627 -71FC12F102E800E0E1AF7BB46681BD2B14B614CEA91B7B2AAA35235DE76C0E113C92688F8EC81277 -D58C3406778E1EC1CC15F1CD9A137C8FFDAAB99ACE3BFC782916F1A877170589A92DC921E6740A22 -B84DC6BACDABCC76E64C79E3A588D80F8F4D376E1B426F15751CF7391102102F0AFAFD8B22DFDEB5 -48AEB5F30B1673023D22054A13391A0EC08DE6E7B685A0D031AABF20B7C62187C0284892D5EAADF1 -21BA28263EB863D5E36EA9C06A77CCFC0E17F593961591F84D82AF823EFE41044C8D606FEF83CCC7 -B0E961E7994DF8A3CC36B209D953E250ADAB8D22D7F2B4E2C9CA39EFA2D93E56195C1560E30A5190 -CC5B17FAEFCF250DF79F6B624A4B917E11C332222FCCFEC4F6A47BD9E75DA9854FC3F7AE554E91ED -DE144D7AEF38A0E3EDB5E5A5626374DB94F022C8CF549093041DE00D7269B7CE544E748439BA2870 -718C08E58FB4A77D93EBC04B7957D272AE1601D41BF85A2BADAA0DF73B0D3841D4839C85677FB2E1 -5F1D6CE592669FF4BBC9C69DBA334DC37706F2F6BE83D5863E8CD6A30C08640AAC4C233684E66B4F -E6B62D4A8BE9D531E47BEF5640D9B5C27D990092BE1597F6995C8A77BE9C18AAE6C1CF130775DDAC -41D34438FC7AD8E042CB56CBF2944932EBA7D053E9376FF398367450E35A1945FE23E05C921096A1 -5454721FFD0F429A3E06DC3ED36F1C170BE79C66996EF8337AFF85B90C5D3A4A94455AE9FA32E211 -7A63E59001F052D5F6223125BFAFA40901E98960ADF7BB886729DCA82FC3B8CC52B37FF2517299E1 -D769057F8154FB95582F02CB0BECC873A9C71796ADBD3E91324FAA94F2C41CF57C30B5897D031C02 -D256C909E080E70BFD1F32E69EF67031138C2DDCD1A8E4B65E485C23C3E450ABDD9815512D6F34A8 -4B9DB715DB2C7A93BFB424316E1AA44397749CB01088428F149A3B4324737ED9957FD388248462AC -1B2610D72BF5C073ECA567E7385CC959E37CAC7E05470160FFA5A9F63B8E9B082937E911586EA165 -374938F492EDF28CE6020953A5B5CCEC7737F9D9CC8538C4339567AAED3794ABA3B9F4EAE65466E8 -E326F6C399B36355935FBDCB9972F10B13494DC25097FCEC5A6398F275C8C151558E74C5175F7BAF -4155E36B733F75CF9D5C5979B0764F14D8306E06BA24BF791141E404C69F3F8FCCD91B9C58C2C671 -AAE7D4F9E5D6414E46ED633A5F78AA5BF04E652246A066EAD9E582B181CC196EA2D3CFAA383B5D0E -4CAC9336E119C08CC6AC55CBFBAE147C623B400453BBF447E96DE036FC025624384359EED7C7D5F7 -858DC0521377CF647A157FC3F188DE5EEF094DBA125510FDE34C570D7BE76AB5DF0A28BF45DDAADB -EA7EEEDB936332DFE93081E0AFD3FDD46BED08D6914B2EFCFDC41662A33B90B03D76D34F48D30FC6 -BBBB600E90E6AC7243FDF026762A44B4D6E4ECBEF48C9D7B696AF29EEE063E557D8FCF0F09E0136F -45D17E608DA36E59F2AECF8493F8D62536119B5F7E1554DFE3F6E8D7C9A2C6F557D18B4AF92C9F6E -050975C3B5C54F9B5F4E39D600B6FA2CD6DE203A174028CBB2A201AF126D1013C229BB82CFD013ED -199D01E51EE2780FE896E01C63C655087A3E61A7F1029FA5E97EA1872F1B45F22282DDC317E17926 -7368CB52DA9444F6055A3C653659CAD2A1D8712BC2B1B32C1DC6906D957FB88524EE066156ED6BDE -B8D832F9338F9912E29A250A8C4674E667C1C278B677AEC9972BE83CBA3FB779893FCB8F81A323AC -91474BA2A2334A07BB5628E905C518E634F6761A3289056F83D5DD7B3890987EEE1C18FB2D379CC1 -905F1AEB3B3D2AD578F0D6C845D2D40C4BCEE3F71C90E68E5417BB8CDDD878D83BA80AD8485F4067 -E5C3CABF28AB56CBB219C0AAB8FFC6C7E192BEC8CBCA1459AE4450AFCC81B9548F40CE2622E5A7C2 -81F74DCC02DAD57EFD92D072318DDF05BF42F1EA8163071E23949B0179CF7DE64677CA99B23CB926 -B3E294194EC13397EA1DC9A5E1CDCD828156CD71F81B64167D4FB01E6002713BD8AC6F82B20CD369 -9C6CA4704DC5C65A2D66EB155B7AF1C9BB46469416FB49C1C7E17A30A5F045271D7DF3FFF2F42C6B -470701C381E3456A500C6BB3D0E47B4D91C5F34B49BB6272F1F8698B307D89EDA3A1565DAD1C0864 -627560CF922DCF5B34C67860352390B282F95394AA2CDE0E97CE3ED39546A6AF1C52BFCF81A29BE8 -2C47C99E8050E4889E4575B75F39E662F2DB7420673797E2ED3D67CDA7AE2C15D0A0A794D57D168E -BE13214E89E0209AB2C0EB7784E9491AEFA3C02D0DF3AE5365A0FC4AE023CAB528162C7A1B173664 -9DFADDACA8DA5FA18B7D6489E4229E9E24D38A620464A744A5C60F6F9D334B908706B738AED18669 -8A8B278341FA4D65A0A88680BA484694921512F7DE93337FC1C02BBE6E64AF2DAD07603279D87329 -1D1F4D39C1DD6D89C90F65240F4808F6F1115CA55B88E242565E59F3BBF1F10EC7B88872E9AE61D4 -4CAE185463EDFAF7DF63DE4D2207D307AFB61501892965170D2945846FCF5973A1D458607F50C15E -06E5BEC715E0C156259AAA6C735593E5564F65F443B78CC7512EC35A56F126DF9D30974A40872E42 -65E1AE5FD483CFCBBBA26DEE426CDC4721F19C3FDA86ED7AD4FA1120F63669BEFE7002B128CEAFD8 -C63E8AC09943B6CBDFB3D2476A026C00A8FF81B1F651B97F310C82ABA5F388CC1DB5AFCFF5996D52 -52A6A42FA4D972E41EE56088F78CB966F9051171C472C774879AECFFF08BFD9CEA40D7C298922ACE -64F28C14E0B81F4DCADE81D71DE3983D87D905192EF13CEE71B2D3FF1A88AEC671EC318917DF98A3 -C9054E372D22A3CEC82FCC217F47319A40900312F6E32B536B9E7A7FA0837EC65CCDB5FB0D414371 -17596CB39D9382262DE6E65379D3A9709B2CFBABF5FC5D5B352425F06F88CD31012A2A4147B112F0 -C1C0ACCC808CD625E0228EEF66661F70AF96D3DCFECD402700E4F6522AC9A856DA466D55C84F65BE -2810A1565163872D62EB81333A698ED7B68352CACCA2D7AD38AB55C19E4F5582F75818302F5FDADF -1DCED09D94872F2D48FB636C8E38C7563C72C771A08C6B1F041F3532BDB39006C89A33C09BE1E3E6 -03622D891F98010BF1DE5355F557A1E09448D486ADEF565705277B31B8BF2B86761E32631E3435B6 -88B79D566F1747BA456DDB43CD239FB47FF7B425EAA4C657C8EEC26EE01AED07CF916E77D53634C1 -37AEEA009C6B515B6342C54BE2C7B95955B1A9DA277A0ABCDA2346E88018C726F481F71D6011AA42 -F8852F2E5749518FE3B3AB668213FE1A05C10A1C53953D75312631D6BBBA01D418199DFEFF8CF548 -6109B099FE8E2F606165FE30F532C03567785D5362AA873C9D3EECEB20F1945D55F49B0CCAC84967 -59FCC7292E46938943C262D78F3212D3F9D0F7B103157F423D71B1ED54B2A603F4C269029918F238 -EC6828FFCEC66009DB9C9E59534EABB183F31D7AD4C57B1BDF0BD2CE5A421882BC10CC1BCE6A970E -2B586BB221567CCA483989DD0B8DEC424C1D1FF042DCB7834423CF244EDA28D2D969B17440CAEAF0 -24A6119DB010CE366821AFA424D1B8299609C04148275AE6E5257A7ACB3C766C747CE99CBA2D703C -F19B7CF301B634D8B613DDC4AFE4633A4D77BFF8E00CFB5E289EBBCAC90A24307E7941EC1685CBAE -400CADD876FCEF7F6557EEE167D2035A05120293527700DC510B038A496BE1D5CBAEF24ED39F7421 -1A93AADF22214ED606A80582485AFE358E3A46D0671148998A3B3BE209467009B43400870359D418 -9A8CEB4D5866AB52D16D9CEB1EAB71C07E6CAA34B70E3096BF7604C22C40D5FBFEEA616DA3BABD59 -DCDB97D883FC8742B8267A16A99B7953225F7144568D566E64542C92E538AC140C851E5D295528EB -7CBB49909B1CAF6409C9BCCEB325468FA0B5F7CB2987382616B477CCFE4F4AC79E4A6F7165363543 -F04DE5B6F6E1C2E910CDC3CDD6C4C92737198F892337DCB6647BD226C820AC99C65D8E7772BBB74F -E65DCAA8A22C33BC168BF48E40A82700A3A7668C5A9A71E397ACDFEE7D556C5C19467B7AA69C260B -727407AC837BDB7D67DEC055C1F45D8BAC61048C45BC9FB3CEFE7549EAA2992D2EDC126FF7A05EAE -58613332A2BC1465B2BC0429162B907D65F793D236EDDD8D35405866D71B25F62DC4A7E06D4DEE82 -840ACCAABC0774F8A63E9C0F7FC980B3583E7A8B01C46590E3BC04EBA565C2EA94F057D964A78A90 -EA9F52ABFD70F84E44E434BD10A42E98C794065724341F907E35D3CB257161E01C7084E3A0166D15 -CED65DA7BA87DBB2EA33D39BD99AFB93D3548358D08330E807F8552CECF63C84F805205491BA3A1A -622E70C232FADF3BF2DCFD6F0539158D3306506F150B0518371912A25EB96163D73E9EEED42EDC84 -D688BC7F7708D9DCA348FAB4DF62E5809BD094842D0A31DBB7C4B41F94D946810C5EC10B69AABC2C -91A59500B2E5D37F4755DDFB7AE4ABF757F4C5BCF77C7F95E6A616646456FE8F18407080BCABBFA5 -7704287AD26222DF91AB2613951E2D679472F8ADF06EA2A20205EC19972299A78BAC52114334470C -5F5890C2F846B4C6042D73945127F2E3910ECA1C4CD7A16EFE4B4BE38A15AAA710682C3836A8CA83 -FD384970139D8B46FB0AEBB002DD224199672FFA02250FBCFA4E649E335428FC71F50F45E498419E -DB0E970F46894A48F65580881C9C4250FCEF65C9B28699408E18B26FE6DB7F1CBDB767564E73CB59 -54C6D639CE33220C894F36E70F71C9F9AA3FE2AE0AA0E3F2E304EC5ABC661675CDE2E70519E4220A -E26FBACBD01D5169EB844750753E6CED53E3678FDCD08AB93E10067E9C64F38B40B76D99B6CD92BD -F4155A1EA5CC824998B59AAD06E09E5F15EBB2288D66EA71B296616734FEF2796F07FF0D8B047074 -A1111D68B99C2B70FC56E74A51B062F4998ACC85B1943C9477E436E5CD7AB18DBC898D21BB93475A -623BDDA71D7B895BA2D4C10F4B90BF335126F4FD57D73AFA50170F6B3C364922E551D40E35DA75FA -891762FA23401D39260F2E92C7807C746F13BB35CEF9DBF2E76E66A72FEFF095DA482A4DE8A42091 -7065736CF4DE904FB52E649A32255E2030A7B31B686353492F31C064A3C4B0448C4BFD44B8E15384 -FD809B8761EE26A7DFA1758D57CE4F0BC376EB2B3833534B15A83436BA553955ACB5A7A66796AC5B -92DB5388BC53EFA27508B08E82821E5CF669BCE52BB860780F749B4F38ACDF5FF12726BF3EC2743F -01014CDE96FE6B4C40A034E9EAFCA2A35CCC776C2669E6AD138070A40F48ED79136D7FF57E993E09 -B81C543FBADD350FF5B5F7A46F060F88E30FE2D8233832D18B6C323EE017EBC1DF5C838321CDC8A8 -4CABCAB20B60A1A3AA028F36EA6E87C850AF8AF7CD50AA6359038BFA8818821D02CEE8F51DAB8C05 -F7AE9797814D97F3DB8CCDDE45B21DBB15CEE292FAA534A5F317B357F4091F3DA357325B8B9F5EDB -45865415973C143E5E5BAA483FBF2D06CDD4246675EC58B84C6AE65CA743117FF00F229243772561 -31A7F2BA26A9115AFD96C18216CFDF41B7220ED0CB3FCC26C36380007B382A02AEAE428887DC8BE5 -FDD630AC57EE3DC156C7B8B29E687F24442E35CE10BA4087295A641F7139C831F7CCDA6CCEB5DAFE -537CC1A97C5A337D3C48A6AE947F58A30DC08CC7B58DBBB4737AD52783C573FC1E9408F55495A80E -7FDA61F0B9C4F090158F1A416249EBBA936C27BEFDEF19D1BFB839EB70576A010706D8B95657B218 -9C2AE04C11EF9E57FE09880273761FB4302C388BD608FA0C7F00F033C9C00F4E3D5CE2D903E0DA52 -E69C7745EE9FA75E2AD93DC6CB5CCFCD3782A699B807AFC36AD1F62B05856D5DFD6F88831B90EB3D -CD523582A49732E3FD7253126D39E8AFB8458B5F7AD7F94A8DAC13365F433C857AF4A42C0A08C4DB -9887C4957259ED22D13CFDF5995DA957EA5A0F620B0214FBFE08AB6D552DBF048D62CEF6EFF12F15 -3511ECA7833E0E3E95F85E6AC0F95438AC4C126E1F1ECF336ED31CCA7EB216D279877123FD9FCD8F -B5E52B587CFFC4428456DDCA816819A8A4A211D8F1629E5D42BA4C5C356E580C8A22C61D987552FA -A97893816DA73D423686E4EBD44375C257F031318865A20F22115E72BF1EB9F93AAA169C140A33A0 -6C35BD4526A38BE79CF40AD1EFA10411E8F3300A8A8B97AB140EE6734E1BEE6C8EE443D698D34159 -97649C6F10F20ACD80236422E215E146D744A262DA3FC88DC0D86FF66512F49D3F957D3C5CFFEB42 -4823509F33F155057A4C6F37B52F4667767BA94F6B8B62856B553F307E5D230C44CBFDC9A97A45B1 -39FFB2F2565EB0E22026972FAD0FB7B9576FB6F368B61979943A398773600E7EE1DFEFBF26D45D40 -BDA66EBB96A56EE9CAE0B2420C5DD83E24DBA9FF885BB844BF3D2BF93B07325DFF60C0CB5FDCCA0A -C8FB5A2E119D5AF26E53AB8E3B428481C2871DDA26EF0B621CD8572B3C664BC7AAC01A1D05B98F79 -1A7080D294BE81099BDA7982432F3DFF4775C44D23F4F1B2E0162B61A8B2CB5EE8564BF98E2ED403 -2219085FE6194C19DAC98A421826CAED7F1AB1477AB327506010217283894235D7DBFC1153D5ECC4 -8AA7293F19592B4D7E95FE55151889BCD1D7FA7DC2370D2DFE11D7E4EA34B5C7A8E73BD3A348FD38 -9EF45B6167FB90BA44C23E912F9A4F2FC0427ED070592F7110183BFDB2C400393BA7569058227926 -351F07FED4F33633BA03A72AA2DC6B598E49B96021DD868DAD0F352E5722FB714F667C15C68D49C0 -3D822D82677EDFE86FE9668E537DA284068C9B0AED83074C92A5B939296D505B837E6A9DDAB1AEAB -7455A08A114C2222B339284674B74BF4CA9EE0C020BF2A148B439C71C6BE51A94CB64FBE4A7EB295 -5A455047CF5CB348B062ED4F6471CBC3E9ADD9BE9B96879AC7BC71BCE02FD02F17C6063985A5E898 -3D205AA1489DA13C408990ABA1C54F2F501AA172F530480D789C848118C0A74EF98D5F607A067BAF -F6030D887AC6A6497F9A0B38F9705F328AAD4BFBB634F739386177B07F22D5771282444E5EE17335 -B4D0EC86117C697E79A5F4F65FDC08E4904DAEDAB20067EAE2448FD4301849E456D085F392DD1316 -7ADF75CCFDB723E2904A9C0C976D6B84DDEF9D92B0E15FB246C3ECC2D0BF314CFB957757B3A3E8E5 -801F520644E4601D291DA0F7507C06F3B9BB36FC1C70EAA444E14E56C0CFF06C7F853DF36DA9D8B6 -AF2544B853DFFF535A7E5C6FC145250CDDA229956019659D0D253A19A7B51A4E538BDC01F74D7704 -9949C2C97C7EC6392C2E61CCC0992B66DAF1AB08551063E53180D2A67DE496716CCBAA45462D9F91 -B66A22545962DDAB120511FF08627131B95E5DEEB8B4DD9643E7B2AF65C0FDCE11F5F1E8DD468DA1 -8D41C8C4F00EA73836F4F70EC50FC3EC6D358C0658A4261C6D15A582A2C7C994E7882E661855B352 -014576858A265FFBC425160669CE159D07EDAC04D060B44E5800A7AAE8E339C29B929AA81D2F515C -46229D2080D5917AB20AB6B34FDCA8E4AF64ED660A3173786FB1A1D005D575C2A5187D3F7CFDC94C -CC44A38C5CD523E9DA726D8EFA6DA7B6131DFF3435FEE838B2C7D6B97934295F06202D307FF78D90 -6699CB9C5BBB10D1D4DEA5FDA5BFB094E704607083B646D37F5DA1FC7AD21B813F44D8C1AFEAB666 -55AAA19703BEA2E77DF3BF350E17C74B3447A452235919452B5175570A006C7680AC05E8950A62E1 -1D7E3ACA35A397D1E19630D094A86807593C97F4C484E4E06BCFF708B6DCA972E3A0009E1CAC0EA4 -141530F5C1B8AEF5E1B933F37FDDBC4BE22B74FE346D1A3F5FEC0818F8E61765568A2AC04713E828 -F98C449D9A1CCE52D10D61DD8BFD084C8D099A75D89DEA64D5A7CC68BD5B0593D97953DADA976383 -F5015915618AEC56D71D1DCD55B89736395C609B315A3F1E1255432FDBD37F38CC43C354FB4B7C44 -F1A7318B0B7E99C3C08C33B953727B6A6328051783A0A33E3CD9E498346A3CA6A77B517096EDD52A -E443B87643A646C3A7BB97F742888D33F9B3127E61942F4103C1DBDCD8EAC8F9E259773066736CA6 -53CE57E8822651261D847C131321BB9D6626A1AC50D047C0BA47B411DF2A995545BD68EC0287CC9B -31D5DDCA8755EBEB10ACCB3903AB0FD5788E984220443B8459E7C078DA4289F1350905881AD6DFDE -C47302B0ACB0D4AF8CAED02B4B70DF3CF8FEC118F0FC2D3DDE3E494CD160E676E300BC464BD4400D -B50EE43B314E0517037BF971ACD7CD327CB2134893B8A0410E68DDC518F5DEC966C7884CF5FDFE74 -723177F20DEDC039D879056CAAB4BF045062D3904F615C5CFE109AC7A35599C94024B41019B9AFD4 -04A80ACAA4837929F5C9317680A13D157A03B59A5588DF79D2E113F5F51021D6F6F90E8BBBA2C252 -FD10651BE80BAFD59C53A3367BA3C28DB6EB9DABF1EA99F47B503F627E15DCF3FD645FC52C5D5D0F -2F07DB4C25C0D1E1C00146E1C4D973E613CCDBD3F9450CC0F5343D79F05E9492E86A1BB889ADF405 -03BD7F3E7543436859184A5B20BD8A172F350D846B7570803990ADAA48D4B9155A2B4C4BFBEF1E1A -065C08E03928559735BDD442FF1E83E1FA20A5DA57D8BDB2FF5427C034CF0128AF111E6E73099E04 -6E0C240E80A73D7BE72B87834E45898D475521CA3306707631F5C6136199F354632D1A085F12A1C7 -C473868B62E534D15F5484323E63D0574196A19EF175214EB35A90873EFCFB92D6CF68761D45E37E -AA61E1A1979A82009507CA193E44B36A806486665CEDBCF387053ACEAB979BD35D30978FC7659ABB -E844F4ECAB3303318ECE80777A5FA5A9DD91B3D06804C4B4E9B4EFCF07EB89866D0DD8CA390CFD15 -98651417114D78776B1A1D36B4BA17746D6BE7FC123D473EF1EFED1C3BC1D555F914536869FD5B0C -35F9C83F65B0E6BF7A627B9202D787D72C600DDB6BCCE613D88492E13CA0AAAB196E8A49928C62CE -A4FFE2D0208EDA334ACF47F20BD793124D2C5546C03F4A364369A76A0425262F9D9118AF54E37D32 -E33AB25DD533A49DF5FBF1BAF4CEAC2D9D378CDCD13B00FDA432D9042F623DA41AFB80699B5538A2 -5403B0B3EABEC9E8EFCF42FEF3EA9F91766902CD206B0787C187D5370B60AD6DCD002DE2DE8DCDC0 -B4719A797C5E26BAA67665016DA0D967FA1346F9588AEDA174CA001B31213617FE19EA218EC23597 -79D979E2663166489C06993230B0D07973A117C4E3F4A4C93CF8428248DD5389414D679C69644142 -67C7FEA17E35B0CEE456667A9B1875C81B2302BDDEA2818D6019FC1622A82051F60584ABC904CD91 -8676305DC03FFBCC64FDDAC8D8AA9CE2EA00D6C97BC63C8A617DEDFC0E40775649438E9F61AFD179 -5E3B20560B01BE5E0983F136CF48AB206954E41DEE0D9DDD953DFD01CAEB569151D6BC0DFEF29D70 -FAE3E198E7EDD8922C0E0BCB8BCCF1C016142C1A8B337AFA7A05A9D7534B184BF3BF827F371E9BD1 -9A71244ECA1BA73D484CD2FAD54DB2F0EEFBD54B536EBCB5094E6BC2F5B2AAE41F05B4B311115876 -ED42C34F8E643B53372E3F6350DB8A38445822EA9A33E27FB0CC42CEDCD1FE2FDF723FC47C996EE3 -56C402112F24D0AF899B2D00BEA1CFD427998BD22B2A09046D6737814448ACFB10D387547D7009FB -384AF0562C85694C071584236D0F1F3D3FCD0CFB38B77C81889061E668BA7AB37AA60F58A3967DE2 -6F939B79CBF10A9DCC42852561D8D6754F1B660D216AAB1E133FBAA321C56E2584BE5C9BAE20CCF0 -0E8DBE6D9C2FCEBEBAD945C3C04101D2387351F132628786F6D9D4CAB83419288D31F9BC600D9664 -12E6AA457CE6CAD26A4C0671097B98C2384C81DD8B9A3222D4F4BBDA7017895C3EDC26662779AEE7 -40D9D7E24185FB821970B0A3A94041A69E4805EC88EE1EE521981536F2844FB8F5EF645F67D42CE5 -148E2DDE43AD5AEF200EDB3A2C7866C98458A92666E5F9E070178BCC39F65A893102A10564AF4E8C -AAA5075D2F8CD7FAB0401C03AF299EA3515CC93066744EB5AF7CF0ED06675BF049A6E3C211A89E16 -DE5BF0445A7CCA6EE8EB0347454950485D884606651E5887FE8B24323E2AA16DE22FC1FC8C4F06A8 -2A1FDE5758976024068197E1F4506E4D3D8A16D40461A4586338B374A592DC60334402F76388AD6A -457DC3F54E6169CF7AE3959676E966A45609621055EC3AF80E182633300A4418E34A66DDFA6B569E -5A13C9115B5FD3EC1CEBE50FBA247F60803AA83976F00117536342DC3D9890C49B2AC701D370E43A -955118967827760F7091469C5406F08F18D7E3548148CF0E312B1DC71DF67A5E7A1656CF2F47F3AF -F3DD50FFC2FCDAB7177285B29C17CA43019F62AC6FBA52D1493ED7C427526470ACC8389BAE827759 -4958908F517B2863B83292EB5AB3F57FFFB08393CA610FB1FE905D88A0A16AC395E2A2A6DD033D6A -0D68992F830B2E1B95FE357BF672716E88FFB92FFC3D62945D1EAD22BC68C51EE0E10A43011DB94C -44685A5C4576F6EF44CBFB45F2A4BF110A01657DB51FD499767E78058199B31DFD60813F1A344F86 -289F9378231D5B151C92385E3650B4FEB1DC91018EAB8474CBF69FDC1496A4D078D2C351C8196451 -247A9DCF8117E5B637371D8E22E248C64D999015C3FD2311E9950B8EE0922FBDD3D7BFF766BFE9E7 -CE0BE12F318FF2A7B5A9C6D00A54401609304ED2C55F5C1EAC3D4B38355BBD85D66D61636FA6E30C -2E82829376BEC979A6FEEE040E452359768ECF90CC539A546F17AE906C76F14F86FF697797322B05 -1EB311A759FE260C1EEE5DACF383816AAF1294CFFA7BF87A4D9BC595EE8F2C2F86FEEE11AD959D86 -F22FDAF4CEC098942A57E57813A0FA99239E994FFF353C1E781D666B8928CFC648FCF0869FC68468 -BDBDA7D280DFAB8B0B3A4CA35B074B686DE8D372C61FB32305169A1A9912F6541DA16CD6316A6EA4 -51524757BE5CF6E820011BE3859FB8B8578C100FF029680E05F0E0BF11D33FE19460C85EA5E4C0EF -28E29407C8AE6BE01CFA0D5022BF9FB01416FFF722A784DFC8FCE330EC95737A854471D334FDC58F -AB42867A7B62836A8B56466E9A6C1247D46EBAFFB905CD4321970F59FB8D6FF65FDDD34BF913AD32 -2E68455C5FF2D23C1A5EAE687F259BC982B6A384D35440F7C693CF50B9ECAC0B5578CAEE87588B56 -2EB6B7F42034C9F2E545EC866316552354EB3728C7D26527ED75174EAF635E048B08DC5D23E88981 -070AD5641A652F2344956E9CF4C16E652A99F4A644D1787D6D36537489DA4D74E61B2FC4DFDF1D1D -9D58F9C26C5EB63200526AFD168AC57D5611ADE4D4A382FC28BB60F9E7D626A6C67AFBCCD1183C5E -3CF2EF210D0BF5CFA7BB10FA3887BDD4CD96EEEAA8F9219AA2F10ABC0A960C3B57C0EC0313AE10CC -FF1F522124CFC8D2D49BFBB0C193EAFFC5B48FB3FF30B21CB76F0A4C0F1377C9223145BB0468A5D7 -1B9BC25873EA12E1C60334571C67385C00D0B570D3FFC6C7FF0DE62C183C76AEEB12DFFEE1459E0F -C818C621B8D12FA1357E2B55D48935D70BF140B4CFFE8813DEFD479350B20DC2EB1D3CBB1A2D3DC6 -EE975D58C89D61FC50E6A0197DA9A586B72255023DE47DABEFB11E8AA02414C2FF6258A281219B9D -DDFE41BA7D7977D0D6F18224FE22F7D4E9355FDB35BF7ED3418F4F68D093AC48F7D8FE4194FEB6C8 -0B9DC1F74E023C604DEA27089F98C3973FF9F4AD7BF7BAE601DB89B08D5D8139B95EDCF6C885FFA8 -B3E4B0477E7040225733826BACFD1EC4A0DD72DC41734856AB9FB700DF83CA2CE812913BD142D84C -5C83C0B2583768198AF9E885F2BA74877A414233207234AA5F18840557CA11682AABDE8993533887 -7C6D404BDE4153C9827EB16D66C1D73A8143C8A2D3604FF72CE579FAA3C5224BAC48EA83BA848429 -9472007DE96466B5B29ACC7C03B05DCAA38A48BFF9F214DE43146AE4E04FA705421917F99BC54533 -F0EBC01849E396216B9F0794E6F6C6B61B52EF1B1950C0FB609895C3C55FF574163FC8B6B09E66AB -AED1810E698FF37CC1F926B2CDA3B48C7D77790EBD2D514B6F385D397F713EC3AD3954EA9C846158 -6031D369E8B99E53408A79D64C34EB5A56DE8A67DE91837960E98A66FC04DFA0EBDE21DB003234BB -78665B039D0A469A0221BD541AF7149A2A659C300132C14581EF766FFFBECBA8B58A5EB3F95446DE -F49AF863A8113D17B2E7E6ECDEAFC3834D4DF900E3475596E86FBB4E2974C090DB4AD61A737D611D -92B4535AC291C56AD8B1C031D2F9B505BB77517B737D70AB3723DB52AE2ACCD5DD2F617423ED3CC3 -9CA882EF41757BF7151806A9B8B0F312808863E3673FB54DE939B35CDECA7FBC4DC3BDF5A5F47D35 -E345916C39366C8B4F439CE1C6F1835C320BD1E67375B03B5DE18C93256F251761A4C8CEC01019C0 -68E34447BCC503B9571FE8000627A6B3DAD5854CBC0A2D69E5A8F46BC78F6A7B1422334EC7A98ABE -FE9B83E01DCF3C6C9273B346F3240EA225AE4A4083CC7B0EA141A0773FDE940768358EB4B13D82AA -304A1386D450C1C0C6A7D5A8FD2BD313F78F85248B5196241E31E5595F3BC01F37700A2DD3D4A0EE -2DD01A36569CD507130E8F5B1E96CB560BB7DA15560CCADF3B2C9804A11D9E8055C9EC70E48C1D21 -3EB756A1376F2EDCB7189D78CD3D6CA5865537EEC31C17D801605EFD860B0B629472690588D02575 -02C6F7A75B9A1C1B397781329832CF3EC43C09F1559CD562C48FA9500295CD3B0A790DD3FCD4684A -7C7AC49AC9BFFF36B39A9FB148BC28D37907433943CBBF0CBDAB46D3EA86DC8F81C859C52D15302B -94A9B51C199B7104DEEC9D769C2634CECF8B700CE9C04152CC59C9326BDACBEC4312DEED92DD087A -1C4840868D9F97CAC046581F762F75E8D24D6445370A3F1E0AE74A6478D9DAC37E7FA5BEBEC0A1E0 -81AF89C1BBF7F51E3E2E22C8C405E8671BA85F1BF0DF79A465DAC7EC07F731E00632E017D190A99D -83E27E5C2E63D7DABBA23B2E88334C63721AC5A4CBC5D45F4C177259F34C2EADE01FA008AF65EBC6 -01D8DD16436D86AA94C99F3CC0A2F87134E73BF22F108B825A8963B49C6C685474AFE4A542C8641D -C0375D7EFE9AC1168D9700459BE52D0DA399023E141969F25C0DAC4668534B6647EC85454BE945E8 -26B26DE6E3C4584B97A38E2B40A0D23481BCA78084FE80E00A71A790BF31DF468A435ECC88E60A57 -860BBCA3D65930186E9917CBD209C230E8F8255A7ABC7D3F043AE4D7AD63D9980BEDF062B7D5C298 -C40225B6D03F29A0339E0FCA02138E526F06B9EF47F5E7A8068A846CFDE2BFDEBD24F5A73A66C079 -18662AEC80B43246284FA4E2EE0D9AAB172B1E59A6CC46B801149D8C0DF6DEC9A55D8E1B0EFD9D30 -2FF618075944CCCB6831D336B11617107B0530D09885E5CA11A5F1FCC8D69D603DA16BEA51116D42 -CAB1AA1E4D7B9B4D79993F2BFE53EAC904FEB70B2D330A89780EAC10D12CC0C35B8399F218AC2976 -E57A26BAD20CE2FA2AE2363D3FD2A8A971747556F2959DA74A8963C20B504711AE1CB0D0C02457FF -2E9BF696B159AF031DD5155F21C0F5549B0471A3C5DC8918B675CEBCB23E29322B959ABC05283A70 -2E878DE8EF25EA760F3C5C7B7B49D398283DE2ED837FD59F7C22D62C58FE4448B1049FDEBFC8787E -67D7DAFE9774979BB3802254DA59BCC0219F98C219F84D995CA768B8B5D9D4A32525DFECE003675E -E4BD5D8DFFC11025AF2B468F9207B5B2B42349B98232BAC0759758C1F4A283405815BD7145C93FA0 -8F3ED2826655053A3C2559073D8ACD199DEA2C5BA5F616A2E48548B4370EC73493BA07E197165DCA -774438B0766867819C1154D1959FE6E01E6312E0AB91FC2E2BD240FC8652A2D456A1DE7F34EF372A -53794D4C4E050BF3CA5B7BD2F1B8DE93B4C8002485CB219AD2D029739FD3C81CC6E78EDF38723576 -1A57143EEDE5CC887F282FECD261F6A25D0A7E154ECDF5DC38E426811BE86AAA458577E5E0C5F0F7 -5AAFA9C41E5D1DC9D91ECD79B514F8CDF7A5F1A189470D35FDF4F9B8788879CCBD91B427822ED658 -389E981E0EE5F7FB87692A3E3E931DF8A1D1573E3B0166204240B7080089A09EF7487C9AEE2D665F -5A82F94C877FB5B0DC531CEBF1E71C6592CEA2401E4B5122E5091DF03D203DF979B9A6EFBA12E2F6 -B422FDF15D49AC0914D372D21E871DE65CBECD105FD4A3E4714B9CCA5C6803FA39DBB015EA8A88BE -7913502E562E5B170B87BFC8572DC9DF49AD63694311EF1334444BDF0B4CA3245271C1F7A4D7FAF1 -703E3AA0E1EA8D5C6E821B28707EE0C9B4F22F23796FE87356C58AE2CADC191F4C58E1FB58DA03B4 -5A25AC95DBAE13A293474217BDB214742B9D9D6AF35F70FED2891942EACE3E625E55FFB820543FBB -250A062D3D395BC0F219ECFE0D76686AC148BC41476A887BC494DDBD396BE200FD3E03CFA12EC9AF -6B934A283C42AA05589AA6B4A8D16946BB51F50419CABECEAEC5AEF9085C9989289E9B46BAFB6FB2 -782D84DE2B068F91A9744AAB237CEB1BA513E57E4C307108E993C972A3E0A898D5A8D27833155031 -FDB98863C3BE7FEF3004CBAA5CB60A1F2E3EB4D7290FF5FAFA088B1CECCB6CF51A58DAAD998F0839 -6CDFD68F5ABC9C1CCB8F6514107773C69C26873E889D1F79D10E866910E4684186FCD71C965ADF62 -39BA3418B313A27AD632300969B6F284519366ED85E7CD968D64823F8C59B5911A72D0A20EB72B60 -3A61E36F52F256FFCDF706B4560B4DFA5D918FBC530D83A4B3C01BDD3CB4572E24242D141BF9E775 -36693A0407D002E09CDA5B195BF1CCF430AE9824C07928A050D0B460F2704BE8F9E647A4884C4567 -0A81EACF7CC038643EB0FF18A376FF6F32B6FE4F197273327FBBDEC6443A299CAD4B26F7778A99F6 -5A11BDE047153E764039EDB251936AA43DEE50DDFDF8856519056AAFC4C5AE6F2051AF0579A9ACD4 -1D00775D7DBE70022CC263DCA5E0A25B9C7C4F5C418587666B2FE24816B1E0EC92F9074F1403BB83 -AFC3F1D52CA79C387BDEF864366E34C90BE52F7AA09935373A07E4E026224E76F9EC3CB9E7EDE50D -EFDA48248D61F3CEC880A3B8843306375D9711E58645F3625BDB8E87052DA67F9794EF4AF8DB0BCF -E00677C3A26907DC651BC838C40EC39E2B5A5DC0DBD345944A6C32226089D63C52490FA10B215AE7 -03CFB663EB8A47793B84CE7364DA1C4E7FCE32DFEF09490121222774915BA59C78C2275F829D15CF -4D8686B095C38C731B83D48738C25F40B8ADD487C350A2EBE846C3916AE384CB1050F9F5DFE09FCB -D9129C6270FD86D55A459618FDFA4F907E6B4746196BB717865AB378414029017551161A52E9D24B -E4F7EED553A927933D4ABC8F25DF607779A717909CB4D810DE8F5762581900E224E4B91598149BA4 -71CF8068ABE8744356B261600BFCC57FB8BE45036CF6571D9B2A95304933BD4F17215F8EF53F8E08 -1AF61FA7F9583C34EB5655CB0ECB82246959F09091F36989EBDD646BEDCA614B9A61AB7696B3FF18 -1058A150FA6EC1BE2EBC7F64357A3FF2A2B0491D2F4E0B970DE5B7788B467CA678039B5EF55C88A3 -84578D427FD2CB16C87B0BF0A3D37CE8ED43E0F049AF2436344D5F47C948C632C94A287509282561 -6C64C5D262FE5B24916FFEE982A69A6CCF888BD01D62EA591EEC51F4B7DDFAFFBEEA93FE08D736C2 -0129E345D06B10246A5F57151C198D407730713F32299638EFBDC01367E23EB59AAD42A83AB41B43 -2DB462652E29813740F4680A5D4BD47B18328FAE6BDF4200CFA4CE3773809B45E8887C9B2E423698 -9F6C48D64F5986F563D9A7538A8716082F81936AEBD0461E6F4BD470436D8B7656F0FDF89108E6DD -02ABDEF907731D458D690BC608EA9CED09EB1E6E64C0790C7A2378201CE997FFE0317679EE1D4EE9 -F91157449323E53B4ADA8096CD628B5861BF794543A98F2FA2AB54FF0F25A13DAD43DAF9394329B9 -5AA53CA32749FECB0B2BC035DD1EBD53FF9FB5AD8BCE06CD89E5568091C1CC314CFB1D9821D7F9AC -7C55F55E0A16E39A87D43148201B928F3C42B110FC056189DEF183745F3B637441DE8BD4C3C7EF12 -F4258E306B2877ADAEC63441010750DB4E6269A4C78A0AC01BB3603C386651FE814031CB5D8C1F14 -9EEAFF652A53E57BBD4C8C0CE36A84A319A53BC1E5FD3F1ED1EE72F4C1A9BF264B594062FCAFB22C -C1FDE3F2E3D3C17DD3F7FE0E15EBD812D550227C06D01127385374A11438ABD50048E17255FCD2BB -85122A6FB9B7DA9D5E9DE8A747FAE0DA45A1FCEFE92B9E70A5B2CAC668D4D07527A5C1403267D823 -048BE671F725CFC7474B44FC5AAA348420B2D7C23C6CA066666FD6F2208E329878D90CEF1C2E77ED -22D3BEBB9D547810B189F08920A27E7107F208591A84D463CE2576C70C3DFE6643E4EA93F4E1DAEB -41D46F0E2F56FC10C69AD5034FC9859D31CF27A3A1EE256C93111F81C11ACF1FC0CE20B90BAC9AA3 -27A5C85A7985B951519FD4B03C40BE637162AF41B2FDA68F0D1E9B7602FE2659D3D75955C579AC51 -DF6A552EB9581AC3F712F083F19B52A6C4F560F36C59CEEB0C996AAF1728A2AA45DCAD79BD7B23AB -388D5B0B64A2B95154B6259B730B0F4A72C8C7F7CC93C7D64D9D8810D1F63FF8ABD4DB89824E2D26 -4FDEE916C41E299211DB1A53256E1DB5CDD04862F034D9404B73183A99D3D13D642A663F129B6D16 -7095BEB4EAEFD03DF2FF2F0B6B594C1EE90FDB203DA89FACEE23F1BA3901FECC75FE1811BD701259 -343011262B6A0A9707AAA6316BC3C17F787BB80AC8DA5AAC942D90F80C5A3BB59E47EC767244AA95 -C63E50BF809998957936D3BF6ABC24B0A397258F9EB4DC8F65692CB023D9091FB180C69498CD0C08 -BBEBADC84A7E0016E8F8BEA325D924EB0DF82E75D2CC2CCBF039B11934363D4332C5FBC5EC556BE8 -5EE4E707CC2753CCC43D2ED50558E51A104221C9323CDCB0199B7B83454DE3FDC810D0F362C0299F -5DD981B31D8E3DDA284FEF9DC8F9C8DE138D3065437A7FE8C30572AD06D62E8527AD37AE39AAB0B2 -25F76A25F6C6505241ED73BA494CF923E919F688DDEBF193E188F8C4C154F21631080763B4D091E8 -AD1D2FD6649E0CD9360E8D1A67A5B5FAFC67547CA31C95A5EA8D4EB5D68B9F6D6532DB9B54584735 -9558542A2AE58C09F3BD2918EFBE1699E9C8F2C2A11EA4D224C726D2ACD4A8D8ABAEDC6588CF2AE5 -66528B94F55B823A2A1F7BE19000F3E7579D094E047075DF18C8C868760295533B26EB3ED90635B1 -29C17ACA679C3E88B06998CE5A7A2544B700229F5A6A504BD3E45B276471959C8A3F81917A534287 -39B5EF9E3D463B3BA7318448E2A3E79520D2D245A2A72F31FF7070B6E4624E3A5E216BD103640C8D -F387E49D732529C611F8B971073F17EBD2F6EB18F9B74A67E1997926DF178D4C9EDED435B9682F1A -279C81BB9F60DAFE125845A2FF3B02979E5481C78A45C479BEFB9FEF3CE2BA9BC46C77B50B03E48D -A6D17B76F06F3AD118371ADC69E178C52B5FB4B261C9311874ED07DD6D5B3226A005FDD7A6D53848 -09E7063F036CDEA41619122635E835D2D74CBB6AA9B38CAA4D819C26E95115FE0DBAB4198FC5838F -2C91B7A87B07D734C6D4F4F83444C1E90AA9BFC908A2BAC4B3DEF9157AFCA5248F2DA31CA87BD363 -AC25E9E77F741D4B2C6E02F04987A6F49D30E9038CEFC41BA172DD675AED8B392164411144E5B738 -F3210B0E66B17A13CB9631C33D44484E792A7C082DD0A5382F34C5637653261B1EB6D2035B08B4D9 -1FA9AB770CAF40A103629511F7B43F2743D7E583433DECFB19C21FD4FD0AFCC22A4119E77C87BFE6 -FE50068B22479015BE5A9F06BEAB4D37412E062A45E0CBCD7BB39FEE747E96306F79FC4F2E8942DF -5D9DA0E55AACCDA547DA19D30B8404FA121298B44C9CCE198C708C69A8D6BF17591C5C50D3FC5BE6 -961F7ABA8F366DAE957A1C3730DA4A5B4F035A9274675EE3BBF0CA8CE9D8349F50CABB1C3EA4948A -BE6F9F143592F1EA95404E6909A909168E3279A957AE1924245C356331A75E7008BEE92BEAA304BA -40B7C3F48F74D9018B3247DF50EBD7CE541DA48ECCB1B0BE51A455C3C13C279D4D8676078C3EBE43 -08748D52C9B041D3E7244C745B1F2F742D010A9E60695F3EC4FDC1050AC082B905D6A57E8F407A3B -472F731011A5798965B7B1A307E252FE02C8F79CEEDDEB6E165F1A94D7FFF18DDBDF79477F14E9E9 -3981ABD200FE7771B29D1D2D120EE79D28B9543818527039AC74085EAFF241B56D08220C958B5D9C -87C0C04A14D52AFD475B542D391BC54FF33DEF8D9484AFF6873BEED32DDA4B371112B523B6CE22B4 -0D1B416B64C9370F1CDF2C548F4CCBE9E12E21C36CC3EA52DA232DCFB65F66B22B5E2EC04852510D -5E264EE939BB67AEC4764B87062AEB7F680B40BCEE04AD45C7519EB3B6199C9E0E332661463647F2 -FB7EDF303EFEF84891CEBCF0FAC5F723A9D0476C3F8C092604C87FC69C7A90F4D64AE45A478EE8BA -2DF50FB93F55A3546123F0B0E2C1C40C98EAAE9F0F26B8F80FFE6E6B94B7E27D2884D58B8A119662 -2DF6BE608C5569D7864BB756DF2EDD184B90812B44ED4A32D001C31383A40AEEE9743651F7950846 -15C48E402DBC01C818D477EAC0347795CB2792E9C11E8FD4A02E194EED1C919D4598FEC003B6D9A8 -A0BC7D456047A1C0579453FC1D7CB2D158D466939A23D7A7B8ABED7E2777EC7487973E73F2266D9C -250CE30729E3C5223AD93B9AE8443B35711E446A3DC660123ED45CE1942A1A2AD0610467E081CE2C -8B92A6C82F0B17B5D2429E99F1A6268072C6B5AAAA6EB6283A872C54D3694CD825EB2926E57DBBC7 -C1663075E687A144E4D61C225781D80FCAE1497B442342B4A3F1CD6BDB50E31791CC3928C30835FE -F845B6BE5E2D7E3F2F5F085AA3FAEB45CAD0D76BCBB1ED859A9CEBB9F7457036F0BC3F195CB1A98C -9C8648F6583CDBB23894BC719D68C2DBD8003B10D08C8CAA40BCE784D7BFB4EEC9EA5359AC056E57 -B8B0F2EBCB1F4CE40C87FC7861180133E0CB6CE2FC4FE690756D327A2B5AE063E3021C0C0BD420D0 -56F0B941E6B36088A55BA11D0C35FD0132D5F48E5D9673572347171B4328D4807B972831C0D74CFF -A5638C145B89C989E6EC942148207D6DB82257585958034D9F9D4221C7C9F7013790DBD130F277E0 -BC88BB179DD09E27062379ED06F25EEA8B7FB33C35861A0034776E3813D2E9E5C10E227CC569AB36 -CB2D9DF2E7B7B44758F9DC4FFAD7A24AC7E9F47AA850C221048C3CB35A37CE8EA75632AE65FE3212 -175146FECD6334AE3D3C5F492F067F795E1E8FF386BA198CB74F0BB4DC0000DA383BC4CC3F070DE1 -7721431988D69C8B1A5AFDCCC83C22E16A87E01C6D3E79DC7AFA3DB0371B0866EFB8B6F88900472A -FEF1C4A878243C52D4E02E82658979731C841C489A6B97E271C4C93800EC7D91F93EB9B9C659A554 -E1FCE42A5EC65AC39190EF4B66DEAF6FC0569A000A9E1495F42F706FBEA4D32EB7EF11A648910259 -6A65CF899C2F322F5679C6D123469192A9BF1A7F1F2C81C554ADB97BD19ADB746A4F81A4D5559E60 -AB94C483DBABF6CE2F28CDB412D50FF3FCFA3B3DAAACC6A83CFED910CCB3B8D2C19590AFF4D75303 -4A6CE7F4156896A13808E0DFEAC547E69D3C886691728E4A35ACD575B40D721E8FCC5385A2EB28D7 -08101DC50811529528F5CB0C009BA7E3C88468E37768FB0D83895AB54DB2DD5426562AF9D8AF304B -F6EDA54E9C92643DF926F5C3578269750120302A37CB140A18BA56BA01108D4ACACE8FEAE640A6C6 -958EF156B588ADB0EA5F3B0F37BBA12B7BCB221C811415387B024B7076FA4403A3AD6EBB5D9C26EF -EBDB7ADE7C60B444AB9F90EA493B658B7767AE2BE649BDBB3FE85F460F1ED137C61BD95F7CD3D8B0 -15CE45138538930AB62AA0E54B4CE1A5EC5FEC0A2B28B345B67089A4E4AE14D2E1F5A9C8848DA688 -CA298F93860649EC3AAFEF3E820D86988C8E3E5A4D4BB937791827994AA3E81D0BB3EE115EC36D5F -B9A392D09E79AF514D11C7B3A03C9F9C13355CE79E119A19177FFDCA34704D38118A8976D1EE5AA0 -2D14FEB1414419F5E85244ADC5C0A765A522EEF36170064BB19FEE3B5F7B441E4DB967DAE0BAC2C4 -8FC6A836E0EF5A69F073BEE1699F55E9C757EBD6FD8B514E2B49D6333815B7DBD1E0694695FCA3D2 -1320A0C4B852D9706DADD8369A95FDD917328BE93DD33818954DBD2C212D2CA81560ED5BC284EB04 -7A5F389E24E43F4FA8C97FECF46589FA7341076555CF55B1C21B28E0C1CBB00AB8B6F67472F27BC0 -D11148F407824B0159B5188D4BB7386FBDBF1C0FAF34721B7BCB5C0FCB7C4010DCB6A1284E9D7883 -9E3C2111A05D29AB7997073B590A81C6168020F1D48951BC7D8476D5BA593F4F23CAC1F9BB0E091E -84B4E99E5C584D1370DD12DEE8DF16AF8BC6B7B23E2FEABDB7F32779AF8E2B5094A6E9B7A7225F24 -C43A8E5D2B977E1E19E633C26771E23017ED233DBB02C64F8CF03992C6484528D0C8464B46F24F9E -8380F385D5D01B8893C67FC103498983CF939432AA380CA576D09030CD52FD99BDC3BE16C7204CDC -3365BF76294A83A1FC14A236F5FE5321904E779B13232A76F8FE521F425562678436359C2461BEA5 -AB27209541F557AE2AA60009C9CA0A9FC7898C14306CE35A50017BADEFDECBBF94EE2905220706DC -806409EF87DB1D73EAB0698AD2DB72CDCDB293E7FB13C94D9FC87E74502E6927A212F0D7D2F2D194 -64F7A66AC07872E18CB1DDE8F11835DCBC5C4EF039333FFFC0FC1456DAADE7DAE3EC2EE0D3415B0C -ABB69FC5006F4D14A4EE1A5CA99AD4D5E629C0DD1E0F097B5B93DE2DD001A8C418234C9C45E8C13D -1AE04E9466DAB8CF1ECB88A4E059C111A6468D2DABB90DA79C7C79E94DB28F6968B1A632F8C57D9E -565FF91C6916026FFAC0661856B9FB8DE9C81661816221B1FC159CFEF1751E7E403F5F2CE32529DD -540792FC17A12A3DCD7C50D38EEAADBD10ADBF5D8A82442AA900CE6150EB7A4639DD9FB6E385B2FD -093493DCCD9014B23EB172E21AA89643A6CAD1093343D85D81261972DE0ACB16A4C6B5F0BE4C978B -FA12D3CAF0134F9EA49F6E9687C8F99A456745EA252F0BA9968C7F9586E3DD841AA92DC7705BDD68 -2DAE41518A09DF0E209F321D7FA3417202F4BA76A984DA3ADDBC58136885362F02F0A24EBC439B3D -BBDACFFD8498EBD29F88F016B1FEABC10785438EAC860B554525F3266097A675299AA0967BD3B7A0 -EEEE3FC578D1BE99D3533BD91571AED904BFC9DA1A1451FDC5406E1CD614E0C7FBC733563CD6CE6C -C31E9237CA153F1F0411114361D731636BCF98555ABF12848AD109371A42B63675A4130B81E97C2A -2EE2BB5D8FAE2640156001AF0F55D9D5DF8FF23C8AEFE14F120000F14149A36E5C94CD9081DEC277 -C2C34870D05011F99D48B0875A5FF542F067F7E9880109F586BCF2B50522A1F23ECE44349E539E70 -F84E207DC9BEC7CDF856A046F1A03226AA41F541719AD1AF88FF211E57DD0C1275DD0B7B47440DA0 -89B98C6EE92A7D94700B83CEBE19EAEDD8A615F6587587BA8BBA3CE3AA5E8EAFB1FB0F486BE3609B -169EFB178A4292F4C0378AFE5D24EED1CAAB514DDC66C696D8E37F294A6579131DDF5488E9436609 -ACD750C3DB0A940C84FE022B22ADC2676F62E91E8F891225F891FBA537679B24547BBBF35F04915D -20B11739F620D18B5B216921D222F15044368569AA302980B9225BB839F494588481B94B0C724352 -B2DF600A22B062561D86CB8F81514FBDAA4F8A043A0265F992FAB71FC9124A45B8475E1EF3DF6B6D -E35CF329777D45F08325E8505EC0D979F542807AE77E57E453525F23BC59A50740371EFA98678AEE -6C425374AEB745B99DDB5D8D908FDB551FBC0DB15832107BBECC4E11A1A8DEC69358A574A2ED46CC -31D564549EFF23102D92BFDCBB2BB985F78F36033E34F59C0EBAFA3BDD71338736464CEFDBA91398 -33995EDA4207BFD4A9867D32E867FBEB7DE60D132803EF9347CB17BD91315484EF6570892297DD8B -7D966103339535E28A00CB1EECA4A9775F60A9F5FC9BD8B06D78FE8E6318C31DA2E847E3F9CA587C -B01AE2BA0A2EBDE308314413F4F230A758184ED60D4F71F6CEC22A93A01B6C54E0449A3860FCA895 -4A347B7588329A80974ECBECDA1070FBC055666375229F13DD995E99265DF870BC8B8CC6347FADBC -1A6AF64599271A475B9123493D46BEC41289BEEB67EB97A8DED7A9C9730D37C65164CFBDC22E5CA5 -89D2E7954C7136EF4E084C43A6C7F361A3E96989239BDDB9A593CC2A80BA16DE9EE90E95CD39393C -212AB22EECB677FD36D34DEB46C4AD0D21BF7E6D7CBD0C8083842FCD87B18FEA7CECF939987E99BA -34C214E44DD84C176C9CC5A4CEA76D380CB316BB4EF9DE73D73B4AFD4ADB54451591DEF86621D138 -D5A0A29441502BF6C2ADE671CEC3CB5CAB903A657EB2D70C943F976C110E46C5D9D29BC00A875F27 -38E5D22496A43E096E009C5D3CB724B4CABB32838DBE527F83B18CB457E57B092C302EE557FD4F00 -DB9C56E66C9FDF4EC9FFAAB85F60D02BA79694FABA476A199A0331C30A78A92E10417BA236E23364 -8174C826331DC1BAB87C5F95027846130C6A2B4027930EBF9A97BA1B039D386FC51C302648E25980 -212F6A582CDE2778C677A01FBFB3C5D1B8A374ADAF6ADBF7DC94075F25ED66D440B3922C5F255FB2 -3FD8F6E21EA65B1D93BB225684B50F11310E242B087575973345B229BA62C1E2C35BDAEC04D10148 -F5B2F3BCF7399BDFDF1F3F79119714AEA697245BC647316EA157484ECB951BE367234FD02E8B1F09 -1AAC3D29BF282DFF4011BC0CBA8E55234D943DB3017CC7A766720BBC29B2D097A956C0F1067177F0 -12D42ADCB473CDE8D1BA35B4030757FA1D8211989DF3BD22CE5D501C21EF8708FB3449DF47D88650 -9FF7B59B76C0DBAE443F336FEE2D615D7EED1C284F14335BC8A26BF4621E10DE9611FB2F1DBD52E4 -B7565D8C65B54EA36D508BCF0C578A49A2665227CDE1F9768EFE847F9D94F1BBB7DB83701C232198 -5C7283D47B2E40B27A268428AAEFE75F6B2F8764A8494E5827573758CB9CA46FA93208836BCCC8B5 -564A69F5AD882052AF1C1417C3FA7F580569528682C77080F3688B65E7FC24D2A3AEB61574B4A321 -5927281544DDD7A6EE0A3E9388F8F631CE7251724DF70726E5912DDCCC8C652DD6C9608F8462303D -867F589DE0F2F71711B35142EE6EF93B64D6326C4DD7DC83278E057100EE772082E6BA368ED91A55 -53ECFE2293A481E42F83BC8F9148C70EACE91F7B7D9CB8A72415BDB3AF66F68EA733A17ABE9DB005 -3BF148629132969589F38D30EABFA96A01FAC72650B5A6FF3935670198A1EA33810A9B11E330EB8B -451F24F93544263436F669AB5A90A53B16CCEEAC36B1445574EFA7E802DE73522BE725E68704822C -B7D3912717333367895BBFBE06966A5CC653AAB5E9B3596702086BF0010085B900711932A95ACF15 -CA4DC45A754EA334E9EB84D6FC8E3FC4F897456BED64BB93B593549FF0D5352275D8E417172A6664 -C5E0ECED1019494A7ED49AB0B965BEC1A82E5873766BB38D7D856049CCE2FCA65AAF61E961B60634 -E2A69EF059754C9D8163D87F928C222772D070D83FEC6FA5AC734AF65E40BFDE521F7D9CB1650FDF -64754BFF21EA3FF0AF7611A93D525EC9B28C51AFECB04E7FC8323DD6C9B0D8539A34FC3CD8CEB795 -8E8EBBFED4313C77ED469C199552A9FF70BA5423B03B6148D4EAAE17B71C5B39DC436AC53D6BA8A7 -AD81AA8B02335A8B2B11E9F4FA913159A725B8AB60F52F1A2EA50EAF4D56656E615BF382CC68A690 -BF83DFF24FE986570ADC0290ED1A37C1C2AD469CE789E0EA0BB5CE01020100E729721AF3B5BADD33 -A2DAA6C33EB8F9064F5292F715F820B4BBFDD56F76D42E7A1A068C1CBDCE4640082F6E7D582D1939 -990CE6EE8D270015A2C461798B37DCB5798EE9F7512168B76D26C28BE4A49A1BF96C89D235F21A1D -B6A96E5DA474D0B19B808D13D7A11BF39EA8647499C410ED9894A1ADF33D41B6FC2E614D8087F4C8 -4E437B136F3CB32DB8393C49177A0675A0C9E7EECEF448A97AFDBE840FA01FC7E5F2E8FECEDC1884 -84C312E8635CD79195475DDBFDD4D38D5A0246DE2C7F21608F8D2C0DA1371D302E941572E5792A3C -F4E51A33228B93A814D03FD4FC223C314CF3714BB3A34BD4F7ED6348577FEED9DEB082C4049E57B5 -D3CDB7F26629E9F3BA36893E09E3C7463D02A22D7056BE76B87763260E46E48BB832B7EE13F8DC05 -37EC8E81E9BDFEAD8C27EBDF1AD706933EFD11131E12814F236EBB01BE85B7F1B2D627413B324918 -D247604F56EC128909873FEC3857028BEF76A3494364C2A7002D104D486236C30B48E2B75D851C34 -EA50BA7FFEB4E19190898AE21768C157C0CAC628A2181A32796FBC1A7271D2473CD88E5395DDBDB1 -FC3AA8DF0F3D588637F19A8B833AFDEB5F655A8838EECD684E2315B72C75CEEFBCEF94344ACE8D6A -DBE355008EC72FE7CEEAB01363A895F4E73F867639BE0A0BE67333848816B05B419221BE8F9066C3 -62C23FE85B7F392930BFE4C12B9526FF2FDEC38F23A159ED61A0718E7115C24597D849FA76369153 -54A40C965D4D72EC94DA61A03766AB39AAB684E134FD1407A5B1B19BFEBA52AA0DA5D99CBE5C82DB -AA663711E6DEBA180E1D4A39C320516A4350D296BC19BF1BE054859A0889C7E9727A021F3176FE62 -0FB0C837E4141FECE531A950C03D319E3255703220B7185BD20FE5DBA673F8129AB211EFCF36EE39 -4C7E00EB0876624BC840FA86E58B2F584754CB6BFDFD76810E300741EBE4544E5AC17413ADEB21C6 -2F66CA4F075C32381796BA709782DE34A675B717A2C7F6D88104CB924FDE5DF775B4F0B68E0E2E5C -2F788BBDEAF06D8E1FC2105CCBBD5827C0B03FD6CD64F0D073F3192D5F94839644E5EC6C5185BADC -F04112A65F49A8C83174A9AE958E76A2F5AF469E8B76C833782C5FFB8BD7B1BBBB3EA0CB7C9786C3 -BE2ADE5E7AFA8C8F20892659A59BC421E28845A108E34EE17864042EF587A6D67DECDFB3F510EB40 -D2229585347A0035670FCC76C2837A4E4D68304FE113C539B35C1F0234B5079B8E32934546982978 -C5E4DF955A454EA263C3CA5D7101F31A318D82A3F9FCB5A8AFD7A65209663B0FC9DA400B26F285EF -46D0E1EAF8ACB1F1CB805E3986D04BC585073FC64895E4DAE1CCB749BB439CB32EA91176D5C39C36 -50D10AFB9C9884D5FB90183424CEE67EF2175D01D2478D67511EC9F54F88763C152697B06D948BED -49240096EEE3D06AB4575E8E8B2CB8263B5BCF4FA1608720F52B675309833071879DF52C3EC2871D -20F398B5CAC8F8A4D41D0F1D47584DD90DCDAEA4A1CF160C4B3BF1AAB890B5CEB6CB3488672AA68F -BD938281DBC1D8BCFE92FBF514DA5358443CB6E0147254E91B38CE6787B2BB0DEDD2D38F5938737A -977B5EA42892520C58F8FBB53C994B57382379E9490F0D6970B980E1BDF8CF9F4C3C5E0A18F66E86 -EE93FFE7FE546DE50F41364BCB3721B637072571FA1779F1D672FAD260C16D7F13CBDF3E4376E7FF -56D2A710AC5AC35FCBDBCE2C9C17E523BBE6218617B13C1FA6679B308979AE7C61DA6E68369324C6 -CBC7DDEC364E5A86707266C0B459EE7B2C03FE584E529BFFDCE98C90A2F3D9305AA74D3ED8430DBF -3A49FE2ECFD9C4BC9FEFD22618FE9C8A973AD072AB6F713E4DF02DCDA7AC5359B2D652013E131B76 -B3ED6C75FD53BA58D862846264627F6B9E70D8800F6D9B32242B747A67BB2B45675840D34F852AA8 -062FA6B01E31ED24DAE02F6CF788A17F7B9368175195DB0072259CCE0FFB2C1035C1D26E1777CCA3 -D56A827C3242069E76D6DD69B653768614B9ACFF16567FEA61508D51454BC02F6C60F755AEF6AFAE -3536BBFA1823F8E1A53C41124DE983E51CEC92AEF4F99785D554488A51C20885346D1F761DA79017 -940A0C557D93F1DB6B3D00FFD61D08E96FF3AFCE5FEDF545CC9F47A2B1BB26713431D6D1E47FD6BD -6E3C668B0368241F0EBB5FA9C991DF79890E52E83A3675EE699B61BAF869DE91F67278F510061C6F -E41DE2D883F48CD0E068E2A652B244128D82E5CD52F35F210DDAE3054691ED55A7D99088AAE8FB04 -F525C2084AC09F5EDF80A4EFAFE981F74C0DE9D194320709B3464F3FF2C0F6AAEA6D973D9C323F53 -DE3D741F698FBF01036716BBD62957CB32CD81D3A2674560FFBC5BDC5C6E4F547E589AD0B1CFE14F -5E17FED1C4A8ABE4E67CCF8A49F32C4C6044F1431E1CC382E7758722A6D0DF9ED23E51F8AD14D11D -7B6428E27443715EBA4E9C05D6F238378F9498AEF0E7EE4FE6856622CC8E6ED141EE5F109E343CB6 -695C4BE1E0F66601C27975983BF557C04ACFC19227A1AD7E6C44C00529FC7EDD7F886D24B7E029B9 -C395260088BBFB96972199A7B32796D27257DE83A7402291C14FECDF7998C5C96B1EDADE0280F856 -8A8F5007852EED303969180B3329917973C2D32C080C9765B6BAB0673BC7ECFDBBFBEA980C263843 -39B7F1052591D91667D4FEE413AFC23DE2D4B9DA742F4269C6C939F5FC32A38040730A018155AD73 -3F231E4D5B9D01C03A58EAE7B5F590CCFAF25EDC8552CFC8D95C60EBAE1837D7A97CA137E9D4A4BD -2CD34AEFD68D64B3F4F62326AC429921D7FB3C235184FE0899690A0B775F1A566EC29D5830D32372 -6526F7E7F5AFDD71B77E07613DDC4FC63EDF49051AEB59E6337AC0A4B6DD872E776C9CD0CCB86130 -5322D816732124F5978A86C186BF0A0F88E733CE38E4D7C1BA5378C5629B1EFC97806059990ED42C -5CD183BAD7E94070E4058569DA2E51831FFE0D080301AEAB4350BA290318AEC582C78D05DD92E5AF -B4424EA808629BC972E68F4FF2489C245593F07555CA6A2B25964794CF31CBD3AE5C229AB9B8C298 -06C01D116EBD0FF0F159ED2D3D7DFC73EAB4910BFF5B0B0B587CD9EA6E6FC45D63C09766224D8346 -1F0588140B258B1729F70BAE7962189B1554483392988CF230AF4077193E53330519394DD99BA135 -6D4730AB221DC6A66019BFAE564893DDAD7B177DADD16ADD21D396CFA6C3DC818052E2F71149FD59 -4A16DE0C2FFDD366C99B486C55A6E991E4D22CCB15843F0C3363676AF2F5B2D1B7EF66CCF2F12DC5 -0D63776BFFB058D70A9C76DCE96C754872D72C82A0C33F90D49C935402CDD26B6D743B1F43BED5D8 -B539424849C1495DAE73044E885A7D0F307F1816DF6244A6F2D97BFD4E200E93F69B08AF39EA21E6 -E347A47CEEBF803F73B978ADBFCF056789BB8E6E2563DE87DD9A8C877157B934102DCEDAC54D487A -1BB2694F0034093C48F10A17D32E2BDD0C723CAF59ADDD1BE373AF8C9BEB4415AA5AF36310C31F24 -354A53C0B962573148BEF91D994FE3F3D8450DD4D686725799F53C373A0A3E3C060C2E1A3E800504 -9F26D716E1F381B9F83125E4683264A07E2D8938F605978E2513DD2050B3D8A1012797CBA8961632 -BED260916338A812AE751C7B657E086A0C7DDCD3BFDDFF3E48B84751925736D1310C4910FC114387 -F3ED7FE163F91895EBF55FCB425CEF5729D99BD8F2C072E36C310523E75CD8E5DE49C031C4263410 -9D56E91A46C8C8E89FD92012A00C33D0DEC52597B5C6933291A7BDC5CEDA95DCDA5600F9AE1C8250 -54E7EE1067458CCB66610704C58E4A4FC0CB5FC933D0322A716B2CD430A3AD48DAB3D4CBE9D23F2D -092368CFC4E1F5495C133A92942EC62118D45C17723646E69407B4A89DCDFD2AB3FFC099A21D9D29 -741D68270629AA3A414FE58658DC9170C247B6E23F35C4BC5FF83009F462F2EEF4DBAC5FD158A658 -57F9B6DC1F5192DFB169DCB65621CAB2F1B07BD22F4155A8E9E2B6388D430FDE5EC1C834D22EA035 -C52E1E34482EADC36B4CAE902AAE89A7284E62B3C84B608D6BD05F75BC31310B2DD3B2C08A00E073 -7F104F03A41989D5F6B9A2C38B22F1D1803EE5D7A4D8DE44E4ABD496A1DE0C0E12C4BC96D0122846 -3F0EA9CE9509FEE987139F3DD3F9D0DF4313F555BE85433718F6D05F197C41A9D9C7A8B0D2740196 -82D49F58DD5F66B12A6520D9F226D1DF1F1B65CDFA261F980CA25A92645B86B64606293F8BFDE364 -C47D2AF2C709BBE77A70A5712F2CC26F3D66F5BE2C307A48E6F887F681D30121E32BBD87271B5DC4 -615D28C309F15AD263FB37424E56DDA6E17B998B45BE6C7FC6C28E3394A8764C9EB2DF5C06626593 -B5C665D550D4600172791CD208AE9F37BC082B0B242B0A504B751B18F4D7495172B697EE217834A8 -A4FB7CC16D6F9E8BB400BE8AEB0850960283DCE725249FCC4DE97D9886745AB6066C3E2F64DD8AB7 -9AA11667F11188D7965DC11EB760B772E282DBF13249F31986AC6898FEBFE23E3E8B8D2C33E00EA6 -FC493850ECB2E6D831D1EFCA3C2EC8EE2E394599091ED58BEDE97D7A43B6F739EB0F845EAC1DF6B1 -EBFE876009CC5D804B15ED4B56761B3CE1AF59C07B49DC798A44532297AD73D5101ED47F36A3678F -818297CC27F6AAA2AACCC9AA9B6F5459911D8C56CF499E390AE607F3790450B2B9C9BE0F006EDA0C -715B5CA0481734CFB0597478E7602B0D2C1E4F78F03C68C17C70E4B42D7D2D3C95CF40F73488B371 -8E2CB05A549944D86944D78724E266C3319AF89AE430E777E95F0D792B1C654306E421F3D63A26B2 -1E74B6E8B21B2E2B9DC596D013CDA16D08E65E8F24A84B12B2BADC653E6E1110DE2E709C1C1BED13 -707B70A421B384F20CA7A9A9D20324DD383F28B2D3C7A9C53F5D4C6B7C378D26DF11CF55238BE1B2 -4FA70DCC178DAD3D35670FE4919085EB1CD905971D76A368FDFCF9D2F0A23739851A3A6D2E02D65D -54DEE69ED5D81315D3EA5E356F94EF256DD267FD1E1A9EDC9CD63E743F299BCC4A4506233B8DD765 -2CA067F741603F93250C087D368F9E9CC4CC1A6DED567487C05BAA992B0056A77F630A72008E3946 -15A9DB24FE56A956650EC9DE90A6C2259189440247970541CA198748928215C0E132A81AA13208D8 -63C1FE817F70CA573B54577D10B73100AF8EA088208A44FB92ACA314AE5879706180788C17BB1D0B -81B6B95A1C4E0F9EA66F9B39BFE12444A6446691A7BDB03E0F03D9F07A10A7598F2166F108529F34 -CD90E601FFED3479ABCFCBDE8F051C348E48C61D95B00C59EA1287423F05666C3D36288844067E83 -E14F6B5210842C742B89F13ACD126B9FC50ABE2CA7D7ED513D43B6AC7F41EEDA416BFFFCC5C844AB -2D23D4DC09B2D510504CE98D02E72020D9E669DDAA344C63A1B75632F912A1C0DA3885DA4AF7E243 -E4A4C6493D6595BB6D56B0359106957259E59E336BAAF35BD1CEC5CDE735272EBCCAE8D4904AEBD2 -B32610C6FEA2B69941D6542ECB44D71092A3CF067708A3D087AE99FF29671AB7DD8758759B971A08 -AE1BAD78270D2FBEE37AA2DCB119D72F6C7B0C8509018A70D0B0BE2C6830EF8E0B24B1CE1141EF87 -3A4D7DCC501F808BFD94E4DC0F2915AA023076BCC8006490A43685EA25AAFC187302EBDE7FE1965A -04A5A398985D29F08E085127B56B057334D88EB638A4DDE64AFD204974C3939536B1B66A54B4DB81 -151853915718F70813F096CC1B0EA25E363B49264C2AD17158A4489F91453FBEDBDE15D7B74D7F98 -E81DF23251785D58295BA297F295AA6248A912CDD4F1111E6B628EECBB5139709E76EA4AB743CEC8 -26621D08E6BC64691CC90B3C3C1778931A28D3D5B1E20E96C643316613FC487C9B604C43463FA453 -3BCA1236286E6F5A6EEB2F1D9C34BDDE4595495A365F88055D9268541CF1654ACF478D384A5496A8 -772EA1402751A093582A6625A0A44816B5FDBE166835D598644296249B92CC90AA3FD6445C9A19BF -27F59CB0616C7306070F33C7DF4E1DE64AC8C5BB2FFAC1EF2B1B30E5A0275E6004CF64BBE2C6710E -DCFC3AA4ADD60106334708862FFA6652825BC84842736E47AE6917180365C75B27505EED3C6108E9 -898A780E20C3F606A860229AC46D0471ACA0187D6D539A1B8820F620F72B41AD1D3BF3834BF48CA2 -AFEA8BF535AF74C4562DEADCB63D2F5C7585722B77C989342D190FF926C8A5263B4F25286F99CF6F -C62EE6E2AD61C82B29D82468AC10FD27764278E5558CE8B41BA111CB2F040914451A480C93084237 -CAC8F66BB7C6689F340B8ABF0150E06D5B1177278A4C08742FE22F42C28680F190900344ADFA486D -59718C25D37275BCE4DF981AAC35D2C7E85C72A0188B8953CFA516FD545AEE0BF4B8BA301CFDE214 -4241FBDF3D204E3D2823301572E23F204C97305A82401660E12926EE7BA6EA1A81FF5C007933AFC7 -3266FAC4C134ED818A48E7DA01C71A46335C845F9DA5E960B25339D551582B375814148D94CFB781 -FC56093827B78578A73D4FF67B6B87F40CFA5E3F4325D9108CDB64BD06427B88C84105187316FA29 -90B4E3E8EDB6C78ABF164F4A9717D523794B2FE772A04DABBE688CCA977090979B5F47CEB90A1DBC -167D305EAB231C9F4260C4AD10889CB785169902FC0BED78DA15B8417453BB65856EA0BEA5245BA0 -573F623D215F6C0CF801851C305B355D26B52B0B343645FE25C78A3526841EDA480919A1BBE5F56F -C10ABEAA3E1FCCA7C43EE560F067F1AA2AFD642F769D1ACE8E2AAAF38850F0D757CD808C921D716E -96FBC07DA7860DFA70CEAE2888C0ED3CBF9586443532B68DAED9A926655C157A416C383A53D8F283 -2A4E67468112A09ADC837ED8EC95F70852921F50D4417239FC42EE3624CA97F682745CC5E76CC7C6 -7BD99F2180F8C0B7FB49539C8CC474C25C0DDE491671FF329E51BCFA779346D4686835A3AD6633FC -B5E0F67E0CA9CED8F215BEF4D240453EB2EDD6ADB22278AA5B985FA140C9834D38753DF2014F8C0E -E6DAD19E8FC54C03C1F6CB0F858986691D99592562CAD95FA0A5B2ABE4A8B54B457D42E8C33A2D19 -51C0419A72FB94FDA78ECD92BD2A1416459E9DECA9469F35E4C47DB531726DEE8F203D7042EDB32F -025DF3D582547BB1D45F7A5B70D317DF4EBB16E36B0D798E0932FD2A85B04FD67143E4B287A50416 -2C1F5A037CCD780088C5476385AF8168E12D97D44B0630621759173C8F1E3006B5B1C6D7138B7EEF -C3CC5F54E24B2C3CA7B41AACFD25E554880AAF406EA4C3C6E21D3B550B040FB1952598A7E8E6488F -E38288B2AEB6C4718338598A2BFE4D2B9D14C65732DA304C16FF3E1F8F03046EF095B65FD609DA87 -EC24A69278BFE65C905CD0329F6A486B8525B7EEA4F7AE56C2633CD83543269E8ACD6D71F500D82F -DFBDE7F7F7B1AEE67328549232E26CA55085B6E84D9E2E7F74068F93A90C4654F2F396E57C5F76F7 -E61CBBE523DBFBA6E76638BBA3064DA025A79E3A294FE7F1CC28A3B4C57DD6FDC48E541A85534B25 -E1BC11B4F78019457239EAEFD4BE9007D205F1D985F389DB22400B279C10948551A6B4A17FBDA0FF -C9428B18B43DC76EFB15FC2182216F1B60B4E344A03AD6C00F141EF99F89F24C819C3E32877A927D -84C2D006940F39CA8B71E5951673EA9BFD1749923219DE38929ECAA9CE43B06CFA7DA1BBEDFDA56C -61FF6C24F40E59B13870D5FDEB82D981154FAE5D6D5152DE69339359461A41A9713B6BBE47E868C9 -33CD74C75DB71D13BAE4DEC85E02FAA14EAD6C0A253B16C79514657B15E68CCFF9EE6AA385CFF9E2 -C53D9AE40F85C793E4E8FF50B2B7420F4FE69807BC5F37C3E300E6B3C3549D1D3246A2E70F091054 -1135BDF805E0A698E236B6496702D061241687B7B8D1A0E517DF0476DA09D89667A7AB375FD2672D -CBAB8124E511502DDBD08BA04D941DF1CEBDCCF7ED48405CBCC33774A68C5212FC6F132641FF413C -984F8B43BDFD7B1A2A3435F15AF07EF4970D3E4A0BB947C181E9CA27CC14A35BD1BD096875B45873 -8CA244F88C28728B74E25CB8C4FC1095A56CA75E4569AD3082EF194ADD11350DB3B74B96761D4538 -596FF7243B1E1B724716A144106E080D42036444FD472998460CE9ABBD05B42AF9389AC452BDBBA3 -A13A96890025789F16B9D92251FD3B3BEB2C61EDDB370A20456E3BFE5F4039E2557C451C524F8087 -015BAF3FF05F51869FB97512968BDB2B49589C1C7AF1E085250A47657465F480B7023E24C76731AC -0EAB6704123D77977D3A2C4C56B691346EBE589C619C04515D34F81FC6A17527D5D8319013C5D4FF -27CC3925E24C99231AC7FB9EAF0BBA482D3B75807AC85D03CD09DE5D9AE0B07B7A813F0449786500 -0AE8A7E00080300F0AB8C399057EDDBA273DD2E1B2A0DCEFAD3B332E6D4AC1FFAD846167DFD70E03 -46DAF84AF292D4F424256ED5AC4E104F80697050D50844A708EAC9E7F7784FD01646F3BD0C595CA5 -1EE6BD607D254E78ADDC5E15C3B6AC4940EC865A5C23105B6BE09EA09F2C05D6D76960A843B81EE4 -33977FAAC3CBDA85CDD2F4DB7C28293A77825635992AF8F3B38B4480D9A139B1662345A8ABE1634A -77496C3F57597D2985E9E54717AB2E99CA35789441BCDDEDE9A9E2106B401D9684ADBEFE40D607F0 -75C179E9CC03E59E65430DB70B441D43DF03F2AA6FF06F224B6E455B01C64FB89EEC9103E48453A9 -749B4D602808C7E408A8903091D85E06AAF635D0D529C3CDD1B8479AC0F4208C284BB678A547F2BD -77BB17C86D4560434F7AD1937760A6AA55B614CFA9FF8C9C96561AE6C8F2121C4E20237428BC51DF -2099B6C49E3EFA18E6D439E6E6981E746EBB1DC461259D8EA0F8099C47CCA27B2D982B72C9A07CF2 -1B3C05D6E26E6E286E348B8944078E24809F9C5F3D014B4CBA02533F5621BFBA1F0EDB776C634746 -703C9F73BA89B1960A496420C68F54E5B901A6D733D7ACC79F275FFFB253F389AA480084468BB34D -A1E797E43B7F6E8CAF5E8C93069A3A2730E57EC39B677BB73E3F07C2055599F7062E53B37A5F0099 -907D2ED87FF7A82C95FBAEB888033BDFD67BA3A6031A4CDC56CB1E4CF5B06B46E16D988BECCEFACB -9E1C037023D7BF5CCF5D65AA66A17AB361BE7981F132A578F3ABFB97960A6034F052D9D5AFDC0679 -782EC90F240F943A5F9A3D969ED7399254FF67D89DF668F7C56FCEA1FFDCF20481474AC8495D3AF4 -B6D7EE093E369C057F0B70858220693B398ACF8E8143558132E4391405E30A73937C53402E459F4A -A3539CF7A99A3F51C0307D045DF8B77757E92EA2F51BF0BB4F77D3904DD355665870C2B59F1ED7F8 -4FC71FDD7F0B6C5D3182DB77827CA6A2060D2B8C83C4EA4A432EF43A4D0A952CC6CBBE52A9F0CD66 -1A538973DE41FFE9C5CF55F2506B9EFEE51FBAE5E63BDCF5528499A47C031163C88D3022606784DE -2F46A9C9235AEE3D4F71D4959B0CFDC5B7E78C8C0A8F9DC99440C2263DBACB343C5C648577F5610B -50EAB1CF7FD02419EF3941C7CA0B0E64EBAD4B2CB05A0793DBC38F1946D44767BD287F5E9779C611 -CA0DAAA1E7393DBE0683C8D3455CDFEBC0E64B54B737E298DDA605227C0C4BBA87AA3EC7FA6EBAEC -39E6EF2537D5974391D31739D9FC42983D81AEE44711C823F35F8E2321AC74943871739D2DBE9748 -FE68592263E7713F27E0D49B9B5CB7A4E55DE54E6B800D15856450FFD3AE5F287B12AE4F438B20AE -9E27E6CAA00F3EAEADBE08432684FDF9931E925544A680182602A3C1997DE5D0630BD5A010535E66 -E1C123013D23966B3545C7431C39B97295BFA4099D14461004C42C85095EEACB9B47C593BC6DB863 -533A8619BAE09095DE8ECA432D4DDD49AA600D277E75DC3F5C6631E2A05382CB007825FADB77438D -CFA78E252D79B6A196D5164C2FEB85D75ECA25FF80B1D97FE10E87960CA0FC47C41D3A213BF141B4 -8BC3AAA93FA86245064668394665BFD52D12C3BE4CE39EFD8111754398A944C3FD1AFA98EC337BAA -AF899D35E804CF416AD7FE45FFF13FC6354007501043F98FE8428DE8013901BA6A28711A2CA85A27 -0BB135B72F1D5026E8217581860729E94F2F1878A0E96C59E9F62714FB5F8F25003DFC7347E99007 -8A9A331CB3A6A535BC61866F02513DEB982C4A13ADBFBAC3FF70A7335F40D5489E48E5EDEDEF1619 -1973D932479C62183B0E25EE8C4F76D4F1AE45DAEA4A12AEDD9EF81D248E8D19F8C8A5BECDD1EA1E -98783EB7A38149170851B1942C96C53DE06DEF80913BFC04E539EC67C110498D15B78268853E5C72 -F485F8A27B768569E54241F6115875E2973292CF48FF91D45EBED627AE9F0766D22201B20AFDD40E -5B17CF337F2999E0BD15B86E46EB3C18FC12B7DCADCF9DD50C6C7E3F37E615A892DB3F57E250A072 -A49F7277DD6A2C8042698233D35A699B17ECA5DBDA6D250ED4A16FCC893BF0DC2E33FB1EBD7DEDEA -3C1C39603C8B7E1A5A833A8FCDD5570BD088749BB232615366687962C7E56ED089CD7B092505CAFA -5A80F503C4CF337F07ADF0D106937E25670839D491F7BFF7A523DB609D126328C16113ECBCBF9C40 -04904427A108618AE5D4ED809F8CCAF72251104C94EC5BEE21F91B179D31DBA79CEEE5EC7FF698EB -84AB1D2D1A624F58B3622A78844CE51498B2CEF38EAFE259D22C7BA61104651A862008BC1DDDA58C -C45F663EB26428DAA85E7785363A69D2790996EF5D9621D53042F42F794962FEA46E46F37B8AD1FB -76FC8D5CF2146843F8CC625139C75FB42DDA71A752BAC48F294E4C0C8289FC46DA5EFD9C91BDA6D0 -27518B7E81E8B21F755A9615627D5812ACA674D1527A1185EED4E3C628196E7D0759B1CAE6B9B7E9 -01E9599A65230F1EE469CD33B9BD9C104C44E3C1AB966C9678BD0AD78111A4E0F2D07A01A038CEDE -7036D0534D684A1562A17AD64A00F279200C0371B1CBA61747671D2A21D3F9646CA290F6B82418A9 -6FA177C6278277504B7FBA936325F5FA124AB018A15DC18D2C5E8F93CDEEA52BEEDB78A57828D81A -3E6C38B9FAF3DC4EB7273ECE3EA4482A1C6242A335862C2C3717F9C9ED95F77B140C4E1569B2192F -C7DCF702D0BC9A50428EC406F8BD0CAF886B4D979320D3E429816D88F7C7146D960AC12E70F2CB7A -9F4E3E366665AB3F1B4B6440F55EEA26DC9EE0096BB7763731740A537766490C8C174723BF0EB40C -53701AAD12B21D436ADCE22203C1053A9DC4E9F17AE617888C4B4E6F3A720E4E6366BA628221A387 -D8AB15E04AD69387C310D3528BD2FAA5B22BFF3FA494F5FBFAC4F771C9C7402B95580C5AC4BB3AF6 -92A70CB2C851FA5CF1173EEC3EC29B5A05A0B728BBBB51D3B7AD8B0AF17A1563E82FAFD93F8B7118 -1FB7AFE352874F4EC6D334AB6747519AB8E847B7BCED33EB5458A828E074E74BA621BDCD03FEA604 -7F7B6ABDA01FC7514BA1AFF0D4D0C0CB8F4E42D5A87E395D9ACDD02CCC220C157153422018725846 -009A3ACD8C8CDDB66BC6836B4026FD9F526AA275D06C813179E5924F26A25094E7BDA8BD26AFC4CE -B41D8964D4FC4AF1DFB0595BC5D6714C32F15DC7194E9A3A73013C45D8FA55CC0550A12D9AAE8E9F -F199FA28EFC2426D8D1DEFB93A65717AF3EA8E2D5B4AA8EF0EF38E9600F7D4E7D9F1D67A2E63ECE4 -789FA74B159BFE2F91C19B0378BA52E93DF12830D99553B6618645E26126842AB70262D96E35E5E7 -50ECA0CE3458B3E51BEE2F21191136DFDBCA39BDC07939E521E4F492F392DEBD029C1EA237BD89AF -76BC89F618D530160AB16269FA6B693CF14BDC4EC7C630025703C5337F61458FA09104EB15C7CB20 -AA4C9BDB7CEF3A09F25BC7F3149951A7CD75372993B80CD2112F7674CEFD6AFA764AA3486730D2C1 -897A264D82A91709FEC4A21E30D812F558451804EE6F3DEE2C4C437846BCBDA07C5B6CBA1D94AF02 -9163B7383CAC6E088AB1DC14ED3743EE77E26EA7AD3119A76C0B5F925C4DE305CD7BB3A09A453947 -5B9BD79BE28FC462D8718CE05F9D94CAF3387BA55E6E447BF81A9EDDD3A34E17BE66BC52B0C0BB6F -86F6F008829173816D205182ED2ECED319864A796AB65D4E3950288BADA94FA32B6F453AFDFC6C39 -A4FCFE60353A64627E2057D4B379D3240012B3BB0ED0C7876CB83C1BA5EFB6E2A03F340C2B576731 -F848F762A7E1CCAF267EE06D621BC33FC245D0E1547ADC12CC0EB58B26BABDB8EAE9CBFBAB93836F -FF22BDA1831DD01B7346AD377AA298D84628BF1C07433284B0A90FC89F5AEB2651BA2CEA405D4F52 -DDC0E74B871D43F71EB4ACE0D2B401F9348EAC3A2EF0AD295036BF6CF6F870D58E00B619D50EA7DD -77BC28DEF91D805CD527DCBCFDC16C042BF9B874E3B1567EBA4C1E70744B9E7E5BD1FDA6A5FF6E10 -1613FBE58DC46CFAC1A65ADAF65E49757E9304E2AC9A91E0588600C709A61D4231730073A36D473F -518A145E141D0A5A494441B9EA99AC23F60F54F8127B477E1CE698BB4129B4B1DFEEDF10D9E665C2 -47A62F112F5CA30B0AE5DBF3E495FF06EB28EB438CE8AAAD84D5F50FB56A3AF002C23BCF66ABC270 -7AC233FC0F2723DB99D2CFE7D3B3667732A531F5DC315CE74EDB9050BF75D29E6430F57CB6778B2A -CBD57DFCEF896E6766C8FC5C9F9FBD701CD62CACF33EE0FC95E78DADD205B5F42CC63024624BAA0A -B4DD447832B4E1DBA77BDFADD223989F8E958C8D759AAA37930664C6EFEC708116248A2A7AF3D656 -DDEAFD009B7F5333854608E67E5E588A857167ADF9225CF6C641F5E19C3E08678A281199EDDAC831 -B57223B1BEEADFDCBC8F6F25D32FCA2336C808162E8F381656E847FB6CB13969572425AA05AC830C -33DE6E030F86A3A85D2A66A77F103C7042C97205526DC882EA9A00EB8BD5519847EB424C15F808A9 -1652A6CC89B66A5731126DEBADE123C63D88A2E550FACDEB3886FF98646000C64B3A91078012CA30 -904B71737CEF6BECABD43DD702880538F5A70085E6CC6015D2163681067C3D513A8C66032C34A0FE -17A58AD4BC97CA69BF41F11D5E910FDFE9729652D3EA21F8DD8CC19160A8FC77573B1E9CEF4E790A -79D8AD6723B6804E9616466C935303E063DEE29CAA6C3BAEBF278B818C2EC2F13ED645AB452397BF -00DB8B26E115026E256746CD0C78A959364FDE6DEDDCD0F441A61A1EBA32C7BC172BB09512148D1E -BAC9E791B7D51B71CAD2DC9B83B2F99B3726607D9CBE58B499A13753CE87FCDCE21C0AD0528ED0EF -B9B2C927F57C78C626248AA2B835A0791244C5896686A66173EC9F802C4C633A42B086334D2A4878 -0E53D00809247BE64E529F96AD2F8B3922A6097D414DDE1EC76F9552F9B8D58B8E34F359AD792B2B -E50C26DB05035E7497162E7C49C38D3CD9B98D620AA67492BE5AFCA3A81A7080185C7F0B5105223F -1FA77805502A2E8C5FEEA27699858D84A95842C5F2FB68686D59FE24091FCDDE139B6463BC6C7B1E -0E90D20A83651AF00C85797BB9F53ECEC1675C7EE636D0D9E77DBD8F89670F855EE4D4800FF3F695 -0EFF09BBF8A0DAF6B8242840CFA5BA73BEB95115F4A78BCC02D85ECCE0C0F2EF6F328AD1DD6CC049 -5A3315B414A4D61DA50DA46D7ACCEFF6EE56451805D26B0359AF193531F95F6589CEAD6FA041AF15 -3067F88A0A2FECD135C56682DB2B45A71D1FA737C064EE9A4F404BB72A70B3AF0330359393247EC7 -81512482579865240A23CD8479F21C2C44A119EBC4E81B308DD8AA86E60C3DD8ADA50E0DFE8308EB -1A7F201EDE8DCFDA405AEFB47E0E6CA7DDB376DCB21D37F7ACC4D3E9F26B03A8DE0E8940CA3A9E75 -963A389DF8038D2C486072F61C0CEAF500753C7A6352B1CD0338D9212B42A4D3DA23D5BDF44C27C9 -4B88A415A3242FFE2E1B332477A21D2B9CE075EE479C6E657A4D8874A8C53964229310E01ED4F3C6 -86FEF5258EDF3B464DD6FFD7F1CAF473BBE722D60FB14AB4918E93878A8AE4773930B8CEE110F476 -7F42A52D9304C55BE12846C911A10AB9B2E036BF9DFD597F5348D42233315FA80D0F563C388BC253 -2103F05E90DBF1923F229F980A2F4585C7A373511372D07DCBACA583099EA972C03E5AA67E663882 -6DB134564DB993CEEB6E7A6659C7C5C05C310267D5F8A24EEC2D5CC3E3F3C808E6D6068D1A57646B -37FABD98ECB7BAF99E7D9AC4414A491A73CA34C52F394352F6B5A15F0FC4D88622DAC694699C2464 -84ADAC3B1D366AFEDE2A2CD2042C90516A666A19A91C80248B11224BEDDF1A320E230739E755D098 -B6A67315535F4C187CFA67ED817A035056353FC859BF286317996FFFB478A2248B908FF12ABDE705 -402224A3EE5F463DD3D243875C84E02DB968ECA1CC52C75171EA50D6A88CA91327A7AA5795019F36 -C0A19C093A1C9D3723C7568F9D41F2E4FFB712FD47F897703D7A620B586B81936C84AAED61D84332 -B3BEBC4F95B796B93EF7A1F565C494F8A65EDB21E2EE18DC025522EF8E599887CA2836069CDDD889 -88E5862977B7472584303198CCE97EF9F9E1446D1F1F5ED1CFC666A8A0C3A03E1792EFB60A9B4065 -49E0DEDF6ACCDBD98742568B4735A747D8E5DE21E630125AE0C691D054E42199C15B1F80CAFA6E7B -B2005F374A9A5F9900ABB7409CCD50C3AFCCAB1214E6A856F7C7EBA89BC3291801E1343DA9DAD2C6 -ED075C8ECA1423B43E587AEC67E6145272814B3F191B3C285639F9E2D6E148A02DC2CBC0E054D629 -5CD05DBAC1950400A9189316F0265B86A732D302C5BEE8ED233768F237C62600CBAAFF3A110D5EFB -6CC7CA3B92D965CA7C5E8D3E64ECF239FE2507FC797FDBE54C1112B28D4DA44C60AB09D994C5BA78 -D663A2591934CC052BC70CD1DCA3325C66C9CB982E2039F5DB70C848D3DCEF655B1C2CD0CEC8865F -E8E1C0A267BE4F707ECE6F5A3DFCA3CC1EDF92C760439F51AA69A4C1801E96CA4D6EA4AD980258F3 -D15C893913ABCE09101984C61B91D603053E49A97CB82FBA707DAE8AF1D579FD69C8481CB7B712CB -CDDB4D287BE995E32C02B399602A08B9DD849039B5673F1930BEC7BF366EB082D2CA5DB2385C8CC4 -5BE3FC0E31820191A814EBA7C4F23B1938E6C4D800732787CD2CB97F762DFC85D4B798809B5F2254 -D826CA42B32695428D120298B44CF38494E56240B75DF1E41E46E53C44DC505452256DFEC819408D -605FF14D6C1F3F152F2FEA96EA0AB3B472D8704E06BE9F8C3E8395CAADD06D6DA033E81ADE5DC3B8 -3DAFF743C6E9E48716003D358DF63CD7FD3E2F727D1F2D0C29962F76D5C95ED44B6F08D052025A66 -5785F264A3D5F5593677B630E628B5EA81FB37CFFD7A30B7FAD226B6FDC82B0878AF4C0EC4F4243A -807B9839EA62BCBDF7C2E9B30A623876E632E084EBF4A21EDA04FC88A1C07021D0C72EC3E969D449 -FEB08E5826EC20E55B21EA71EA59F6E3B0710B0DDAB3261B4A2029ECAB68C19ADD5174E55D5E984A -4E5F38F592A302FEE6ECE732DDE841A28672C620CC5D687455A5C06FA9FE688394A04F96312ED025 -B7AA6FBCE2925F3AE559CC1886BEECDB70822E2E5CA3F732A87404B1536AAC469989E9610CFA440A -CE43875A70CA51F36CB6F629D9424C1E35A88F92D5DA3CD8CBAE6E8425A36968E21F4F30349749E0 -205BFF8D552837D6FC39532525370BBAC833F75F1854C93FC533A4AA53ADF7008173A70D94A4EBF5 -38EA9E62BCDA7C20E0A073BEE2EFAC34D2EF1D03BABD5147659E50B557045B2EB89DB303749B04D3 -F54B43FED612FCC68206E001A7AFE90230D9C12F74A32C7EDB5D0241DC3A5D51481FD7C8FAE08FEE -263FBCED7C7D911B3A303C835AF5FADFD218F61A9D6DE80485ABCA88200047B094441F7767B97A24 -E8C612590FA2407BAB1E8B56C71914EEF2355DD97CFAFCC192BC06FCE063D3D9D1A629AADC75E3BF -207234C208E7E30663EDD691043065C9CBC473D97C6D4DD3DFF59D6A9ABCDD4412C3128F603160AA -D8F81C6E7A4DCAF35F3A99B4EA10A34375B477C2BF846521A7EABD4D28078E9340452A198F3F5ACC -3DB7E3908939FF6E3709C6A3FD9889439A4AE3E10B618CC92E14B68429A3AD2C80940A1079452EC2 -66F254657BE7D79A2A24084AF73F6DF71FBCD32BF6913A3FAB25F977787F7BB0C3A3E8BAB38D7A2D -B0B4826950643DD1E03BD7DD1FB149A33862A89226B7CB454DAF613128C2075470E42E70A9444A8E -6ECA526345AB48E6F5160BA23B5BDDFDA6049EC44ED1461C7E0DD514B16E2FB285F72039DE3C7982 -EFD40D7F6C8E8F4CF35AC71B467BFC578002E8D2239A2FD2C4BCCDD8AF3D7DB1F4AE7F2D2E0811DF -9D0155BA6EDE50B5F052F14F6AB884FFF244D8806C07EBCB49ED22D85DF696995991A954AA97A1EC -D86ACD76E061B7541E87997FEF0657A826BD88EF3A4A5920462C6595E7A156F453291CA044CED810 -860C3B0149BCE73BECA713040664AD0591304106129600AF71317B0D2907839CEAC99515D357E980 -B1937B6E1200AACADA205421001F1B2F91753E80D2263C56AA164A74701A8D5FD28E46480B0DD963 -A683A1F355D7FB4463C7347C94EA5E2CA40B60B56297CB22D972C5BB10E56715A955605256C1541D -9F3BC5768A6F355CD3B863F0FA1A781EDB49368F51B29481CBB41D4AEB07AF9DBE8F52C5D0FF75F7 -FB6431D37D6AED84D78C778871CB0F715B4F07580F23B586C969C81B471FF6A6C7276F7E141E02A8 -584D4B9AB00E7BD643D2C3FAAA299B1F1E25048461952EA42D4882768A70DE46B213A287F8D31AC4 -6D5436F22A796C05D1FE50A9BC2A928066627A0D87DD57A3AD91DB446404B41557D1457873482005 -EA20916BBE46C613F456C849D46BA79D20627B446B2F49E3FA309AE14F8C420CFD94922CBC0FB9D3 -5A0F7DBEF577F1849A1A80E0011DA8AC082A8C6F61658E65AD177ABDF23EE17C8CF0D26B9FA3A6E9 -4837EB9E930336889767A8D7EA3CE980A8EA95528B004957BE6067CD9BD8E02A0F23CC1762CCA656 -D33412FF45E917FD4A03EB6E8C1F43FDB0A8965A33B4FD26BC24A20B304CA817E88495BA9B361A3E -933717FFB0271F7F70C5D3CBA1E86D0F51BF3ABA194DAF32C35C796627D00C7B2271ACE2463E37E9 -7B3C826CF3DB60028F240F9452CBE08F7EBCC5FDB1BCBB3C327A9F450B9E5671916101D6E3E5E458 -CA31F04D12F592F83BADA2C3683D3886AA3B403963AB5DBE220FEC00037A745839F67A3635DFD3BF -F08F367482962DED88ECF6322852D643A54D5D303EB04BFDDEE9BBA1EBCCBA7C653B3A613A8E719A -DEBE3CE1BD7E754E5F4977E863E3C2D388A65227B451D4F3A4F94E06513CBA4AC1F2F511613FF035 -611684CCC461599000E546E4D972CA6960E095A526E4735A23421A4C9B597ECE08AFA2753592BD16 -DED93255A1E33DEECE3C5EB77B94670E8137F2A4A4B98AC193258E7DEA5DB8408A806188F2D1DDC4 -40CCF0E9A6E2F0C78FDBD7B68DD4939D2458C1965BF8BED4564B32462FFF3EC892C03B11D3EA813F -AB4CFBE8D3016329C5B7E3DFED0F08284D44AA0B7A2F6BC96EA4503E8EF52A64C22BED6B452581AE -8FF8917D53976471941A9116A2D878FB2541B561767ABD4E31CCD8A590CA03494C62AFFD64EA0A1B -C779173DAD84999C7A8D844EB1259DE7BB5B25CD023537A474A524EBE4660B22568949E624D8FEA0 -AD37F4CE1EC75955EEFA49C6BF1803BE87E9C9865FF3F6B8525B8C15FE8835CA153D27E6C0FF0CA5 -1029A7A9185D25F0F14D86FC797DCC1F99EE97E2054B9C2A2E06FDBEB8DEF6CDD368BF23A858D9F8 -C1DEFDCEAF1B4A8DE5EAFC604CECCF0D285BE00AA912EAB66EFF4D37AD2EFE34853BBFD87CE09B18 -749B489943EECAE7887B006FB827D10191DAD18466CD1F86505879310A8B171F902EA0C26A388E13 -B53C700272CEE2BFB47ACB58247C13449C6BB9D01232C32517358F1A3DE064D43C18F8827D53789C -CF3CE2EBE78949A6ABFA1A6B8414CE360A5E22AFB7D1DCE6F5A06182C3B984B4F9BB1A905A9D5A14 -83750A1DE0A857CD5C06945EB7D4A2A6BF1237F32A154FDC06D51A703D44FE052FD3C53E9E8F417B -35D1C851F9203A8997521529F21AD8498F96930AA77EBAF82EE02A57BC77C792D9F220294B45F48E -A8FD94E01CD25645D36D168923562F3FDC93CB79DD4760DA0C103C2675722D7A1B79FCB4245ED12F -A0DB52492C9CCE58B333CFEE822812F7DCA68E802C451B5CFAEBAC608B950386B6C58239D1C62D62 -4DD5D15782FC552222CCA06DDF387B373E32C3C2864C63C768350C37283760F3515A5B0AFD66C48A -B522EB3E808C061F5CD6BD96CD18C9839D30508E7D4EDB88E8F11E31E10919B16B7971F06D7877A0 -58D8A4944C84FC6CAEDF3341B48B6E0D3C7B85D710E0C35F5B5053CF4B4798B3778CC28B2DC7AE0D -F3A49F9F3BCD8E95D746C35C3F47D68B8AA35D97AA08E711B5FBE70D1A623C82541EBDC51A827D0A -69E6C049087AD26F256EB7577F58CCFFBCCBA5A95D093DC29464C9A38DE95BC6B1853963B2DEB0B5 -7AD1248D6F1625E115EEB9510B5772AAE4E3C866657DB0B3BF0E0AC345E116F8D4976B770876FFE3 -748C36165522991F46A36F193DD1A1C94713673C7E4C81582391B636C72DE94CE6254374F99B623E -5686C13D8A8322E83E11BB0B0A896C6A8C2C4F756C5385CD7017F26D23F7C3EE97372C868C8C9155 -81723BB6B76B4C3CE8998E4FA6CA40B633DFDAA59BA902A4952DA90EC4FC3CF0F2676ACFA7F76F78 -236FA2DE10FD3545357215246BB7E527F277C28B353CC6D79DCEF21BCC8F77603CDD58A2CCDDBE3A -9802F941CED8E035313875319548C41992A2BE939A17CC109426E33825AE59BCD17CB19F50D972FF -CBE7D9B4B0BB095303D9DC9D406696C2508D6CE99E11CF00F6461147E97449ED5F486D480A86D3A7 -ACECB7E9A945984724EFC21C5079B1FD03ED803C2DEAFCE3327D2D7827715FD65D9506216C88B0FA -26935E95C64114A51919D419038B1A7E9C1E829FBFB53275093752DF19891A97F3CBF7719C1FD6CB -17019A6D2D25360ECA804C4B35172662CC4769D2B785C6C87E5A4ECCE31704E59F71263B7C3CAEC8 -ACB4C7426EC25F11A0042323EE6C3EEB04284DBAE2C770BC419DCE79BD4560AEA41571C3B595F525 -60191DC7A8FBF63D413A77A0905E517441B16C2B501EA2F9E99CC38D052679F288FDF1894542E3A6 -6989A0090185EB2E75134BFA3D9147C3DB8A621D9D35E37786853779E157B47F71626D6B3E633005 -9159C17596C1B87FE2B4FF47ED9D78FA4C2160077276C8B58CEF5DC030B4A5D83CF257096C047FE6 -4DE307C598B815058E72D5F57DF5C369E664E137DE29349E2F9DCD8C9F4EBA6E765B6327D7A20DFC -B20711273FD8091CBA605C4C494248076F7E03DF65A6A50164980BBBB708741E5BF6056E6F996DC0 -7FFF408C5B8EAB8DCEC315E92873228C805D4440A6470E3EE3983758DD211C9CECDBFAA4C9300CBA -00608A4B2404A3C7AF017A3B7E67F39F0B51ACF950D3E75CC7BC2B8D3480202FA958E8EE0B240501 -5232EE0D264C7CA02C18CA45CB3C2DE322D3EB7F00F9455DB6C5B1F4E59C3E95520EC36D7D903CBB -625D70B54BF6F8255E412604BBB29FEE026CC660577F91DB1DB4A613EEEFB20CF7AE3CD89D565AC8 -38416B01B5DE4FFA5550D17FB51FBBEBE21CF1D56038863EE931B90DEC2E211ED42BA92EC244D4CE -2C4EC5CA87A026992772DC2AF754FC982B94F36EA7B7BF75E0ECE90CBB2A6AA1A012E8898BD679C2 -3CB3827C35D5D02F0569C7AA82615D4AA67518ECF668D3B57D6EF1A8013424AC2268BA0D9A74D588 -79EDCF6382A89D397864940303EAEC45A38304BA8B1CB198967AE23EB81054BE74B16909A405E8A7 -799CEE3C270FE2A6DC50BD7370B6B2C8FDB9A87D88D5D40348D3984E39C693B6F4486D994778607A -80A3122872DD65E40492107C71C3CF708A9717E9EEFAFBDDC239C53AA9645B711038E59C8B861B37 -411AB2039BEDF9CFD00F08D9C5D76154427FF5DD39878CECC5D7BFB3F1F035087185C0981F3C2139 -BE84872FFAD3408531C4EA9387B89F5E3EC779E8850D50992DFDCF9132BC551E985943B07618AC10 -D1150451F0844C0DC41D6E17EB508DC8689EC726400D5A7F6FEB3CC7BCE05F09228B7CB2C5393664 -D8DD9A4B96B1020EF25D70AA2D91CAE93AFB5F2BF0AA18CA5C599FA1A708EF35BF8F7FFEC9AFC1F2 -42870D028B2B1459063B493943EF1283829783E1010242E5CF4DA39D93D506F3892936E7D6CF1124 -70A521D397438733D053944CFF12D6FFAE8246F20618684F263715AA98E15D72A526383E05C23214 -B78338E5B476F0981D90056E6E5D0DB66B1DF2298E597B2ABE1D817E18BEB056E65EDB4234342D96 -00470B1420C9210419D834E431B82F58608C87AC361A02D0F1FE4B470A3D71E0D21BB87E1023D428 -E23D596CB9E1A2184403A16E36E644BCCF9BBDE27290485057E62827283E7380AF786BF395B3961B -A5EA469C315763FA59E0F176EF81985F38B882DE56A74D128E256D1B89939728E55A92ABA21A6B78 -44FAC1BA7BBDD8B34A18194A2984B000380FE9F672E83EFDBF276FE797A325815B0F25CC95C97A9D -ACF56D583486305D7C9E51A7E337D14E3B900333EB38FD93A99587DA2341B10C059C71CE080FE753 -3C0F059FA40E560AF9C4A41A4BE6FB45846FF8F78165E10B4AD40F264BCF5596A1E8EF8CB6EA4B1A -3A5C69059AB1563843679ECB2511A90E8898F54295649CB73D277760D8D04ABACC7BCC6E777A0530 -E2067CCBC08673F9C8C178F9D672AC8A15E5367F0C5651B53E75E0CFA57C931746AE1A679C246D7C -9417F1CD89DDDBD1173C2F880B7B3847CBCCEBF99F7122E832D7C9BAFE2B54CBAA1ED48158DE3F36 -238B76B0E67644A28AEA996DDC006F6AC0242E4B667639E7523CBC90A0561193C1AF34481C2EF402 -EE43A82E1EBF4E3D601BB36B2D95CD93550D61CEE7A94E72F6D30C32C8F91A61E964B1F66ACFC398 -7F95D4028F116E9A9A8474AA29C1C1A984BE0E393BDC41DCEF6A6F1018DB60D52024899D8EB5D55D -324D73F39BFA47377B9E15B3B06A7585589FCF52A54684173E5183367E7B0952DC4BC2767C4C6247 -B1D6103E52BC7B7EA6298F454C5D97AC575F19C10ACDFF4E10C7D3755CFAB4200CAC545269FF1D8D -B0D607C7AD47F40DDF257AB4E7D0750577003C13E4941960C3DD7B0774DDAC18E8ABAF8F53E03CBE -F6D57B44F24CF821014C064278FD51B3427593D17694B4ABCE81F49CBB984C5878CDF0C38D1ED7FD -99B0B9A3BD8D8FF6219588B3B8FA59D0CDD1D9B2F65122AB45E48F1757467B9204926140E3C350C5 -A927A2E700173053EC35D3F1DA2D7258714C97FAA857F0898917BD94625C6D1E2D77138EFCAAAF51 -7B17FE187A2212C24A881A2C6A647DEF6376ED80AE4175C5EE80921F001995B44E49F0D33DD9075A -CF33BB03671C0BCC34AD5784AD1CDFED3A6D9BA103B3DDC1CC2DE74DBB576A0277715275218CD19C -A8899209125266D8BF1286F881DCC2C383749D1E768D670F4099F7DE959EDFE852583183C9111601 -2881A56A24AAF020EA45CD5F39660DEBCE30AC1C7B8CFC60387B1B0C3E361BE612FDFA9F01B7E4B4 -A18839A2C7E0E393EBC5AD9A8A4EBC316A740C1C295D9EF5F4DFFA0667F9582C0BB837B142C4CFC6 -B1798E9476D0631111033B8BA75A10FDC800E2AB1E0E829632F869CFE4737BE9E2800759EE0831DC -7D1195EAF80555771981DD6DC6606812D92CB8EF86447F5F6C6F626D0E265C67E52A6319189EE349 -D48E49DFE6A9E98F76C414A1E3217AE0A215A17E54AA498F4ECDC50242ACC7E2322F63BB2FF2189D -057E7354E32A3ED1803116176B9B9D0129930F919E2FEC280B2C8924E49E7BB75768A2EE1DA8ADBE -D4E3589906DF1B923AEF84C1BD327438B731012E69BB0D43A1842CB88BB54EA4516477F704CFEB28 -6E3EA483445AD4D74586FCF32E96D366901084365F693A53C5FB532FBFE7BC0CADC404C4985042D6 -8DBB90A6DCDA3531EE324D558A214F935CD9FCC9A0CEBE9B5FB0323F4B3820529599EF48EE068B5A -CE85004FEA2984F0A86F5AC9D56163BBFE1142B774148F1EB0A4DC89C3349052533A7DE66729DB24 -41B82F8F7360111DACF69293C9B281A0534F3E9E9224A75C49A832F28B2E497262475507B6DDFA9F -01CA0A6696E3F5AC7EA68595EBA0C2EB8A47813FF936D84AC1B23ECA7AA2862B793CCBB0DF9FDD49 -31BEF354CEC12FBF478559FEC29F81ADF4452E83963E56541D31F3691C93A50F0BBA5E9552C4F2A2 -3A6E53060729854A3DD71CC4308B91957DB19E66AAA18FA67055A950F1C2CFF78A03BC1A588CF624 -696068068719AFB1001C4581EE072113882D9052B21E355D401ED8CD24D067B99E616BDA5A0A5A93 -36FC499632B79FF2FD0DEFB096EF46B75E2D4E0F48DAEA239719FEC4D9A29818F5875FC5041A9EDB -D26CAF0ACE14CC80BA49BBA59E918EB3D8F1E541AA16026585A2F72DF7D83541816DE46981FB3EFD -0C30E458CFAD04C79421AB7C4925E23AEA07F9F018431C790002596D26BD9663B51B699DF53E4882 -CBC34EDE88EB55045B889B6062E35FD1E018BCE785157B85EC3B9CA6C85D4B16238275385B8285DB -012D8FB7C9F5B946A41D7A0FB878FF72C39683144D8A007CFF631B43748F2D5FC690300F9BC0C837 -006B92ECEBE0605E8C3A4A400E18AE8997D1B45FEE10068E247C647CF82C6DFBE5E881D511FFA687 -B7AEB78546BFD07D5F7EC242DCEF4930D8AAAD8C6152B6642AAC325963FD147F236BB850A9966573 -9D06CDBD7CA79A527DCF461E33F22BC9C5DB00DA2BD3DDDD8C99D99793BC98282AA8872FF96C3942 -85D82D9419EB78B6AE37A5F519397700F75D624A09BD255B576E955A323E784E8FC31131F003B0E3 -024A4F58FEF2A6C043796201FC425482E1155E229D1B2D43EF7B0D22322B22EF5C9A1BE026A1C3D3 -75EDAFF99597E1E5477952A4E8D2ACF5D014BC00DC2A272FA62B6983E27D228881E2EF2B8B95A681 -CBE90C5FDE16331C85222FE2A16F0A3C3000A63E2E21666C0C119F8AF89A543D37977069A5ACF155 -6324F05204CE8CAD50FF4FB630D9CBBFC324DEDA584AA56A99D3A76FF55BDC2C2EA3A021361CCD4A -83C7A5E2768D210FA6DE889FD48A39D679C94EC3C99A8D33FF11377DA7F6F1B71A2A05B302ECDE95 -4F26773F39AC881542F0D0969C3995C3519A8EF70B4220D86BF01BEECC6462855E7B686E1AFF1CA9 -1FB8FD8B4A69E10EE0C2AD94ADD44449506F9B6EF43641F2026EFF6E605C670560C2B74706FB949A -A7E8CC6A2D0D6207E457E7FD87EC1B9092DC68B9143947CC8ED14AFDDCBF8FDDA228A76847F96802 -E561F67CEEFDE45AE587673983FC04C96744DBAA83F2DC838D633943C75DCB9E6410474EB27B348F -26E505F0AB90878940E846C5E9F3C5FE8C3558C3236B1B88C405716949B8506841CABE1717474BB7 -C30DB91CDEE33B0F844811762FAEC535BDCF84C1C747CEF9B1FA61D2AFB5A81335BC42C06A94D7D5 -9B7EDE55BCF6F9867AEE107555CDD084B7684C2C87087475A39A9DA6347BE281CE5635A4D07865BA -98CE26C1465B1AB0343F49FF37B4D0CA9F3BB693D78DC3B21925CB996A038DCC172527FE57C07460 -EF39C07D4396E7FA970D9F22ABD21A9C794B64AD96762C7428F59A8757C36D6C4FFB23216195A04C -2A2C2E7B10EF7193931544D782FEE4B91E01119C5553BBC6252270A8D8C56DD62D448F5AD8DC69CC -B45E1F17F0AA1E445129DD00F000005B23D38DE93A3BE55A4C041947F36B4E4536E307D0180553F9 -2E46B743881CB5D5386C48C7D5F84C2BCD06B9C501F78C7EE61FA23516791FCF4DB278AF688A2E60 -10A56692AD92008497487EDFE4BD5FA083FA544138B20D6940020887E35D46E093B71F7A04A67460 -DC8116B4D4839625D7CA6959D6831CD93F81AC4EA2709036DD738364FDE71113BF22EBF13DFE1642 -E564701E6F0FFE7511EDF03FE448C2B28C64FB7D54B94CA576E481FA56B2B18AF10C71F699B6BFD4 -7459CDE1869D0FD306BF489A6F42E5B2F05CCF55BB6B9526973D19CB134CA7F13F1DB3716F8CC217 -73A832568C16250B5CDB16DF24BF81D49F5B37018BD310262EA7078107868AB0216CEC83CEFCAB1E -9F2C665A31585CA04DC01879CAA79AAA5AB201B516F7052B01B16BEE5606098393B0E5D9F9E5E3F4 -EB20F63C958E796DF41CF28839F5C62A0431648745D7837B519F3AA36BC6C08EF040CCF53D9B6D8C -0C7D1A84D707EC57A3C6AC9A62AB37251A01A5ED40FDEC6F5BE6E34C6A91D058319439778A2EE5D0 -363E2E1F33463C33327D05FFC0CBF08D5BC457C7230448972FB9B4D0D782BA7DBF10D3FFEF8BF523 -6EC16D4DD6D0D870D9D5EB5C64C9A46A4F583D4F831FEE74B0E5B33A09ABFD4444929BD8F638CD72 -EAB99CF2E9551DF427683964A592E49D186F285258C5D5F62196A98532421D73E3495F82695FEEC6 -E1952C562D546B28618FFAEEBEFF03A57F4D855021F85B0C7BC37FCC6DA9AECA099B646B99D41896 -09D3FF2D56422F8C37E97640293EC7C90E3380887836F4938FBF495CAC14FBA5648D89282D8D49D9 -1AF73ED36581139D8BD42551E263E830EA3C6EB381D85C42D74C50DB0CCAEC03F535ADE92128A016 -0E811C34748309AF7604919B66CD43EB5CA975302DCB6076FEB6BDD6FF55976FE990FB0CE9ABB11B -195403FB26E3D6C6A0DE1C5BE79E171A61E21F79EE8DBE7A832519813EF6B33EA098C2C32ADEA219 -AB2AAC8B093F40000995539D1276D5F2EF84CCD099B71FE4269BDBDB6A8D59C86F7D2E3FBCCF8773 -D0FAE97640BC1AD43CB4B992BFADFB09DBD0CAAEB8CD9DA264187C4F97300E9A6C9DEED5525479E6 -05C65AE336CBBDF4E5D7F79AD098F977285E065579B748FEAA97F2A753E1F962FCAB68D72BAA8EE4 -FF6691C23E31BC0F3E981A96FB440404856AE1AB32A7205B17D411D8F21C8C93B704D07EC594422A -BC368CDA2B1610CE6A973F4474E12B78B532666797F5755D269772C9F5400B3BFC6C58395D38527E -2CCCF29B56123F7DCEF3BDE5DC1DFC5B0293BB125085B1D2D929BC3EE84F4FAD571A4991C3DEE03F -2DB3A3097E52B1A7D5C73CCB6148EAC62E8E36DE9A71C57638C6E4D5D9DED18174E8C390E50B4A5B -913C074EEAEBE390B214B3A68F02862B9A296DB4B409769649E51D738CBBDFB7702E15C73C2AFC6B -C37CE15171F4E822CF20EFE55D9F061AA43E648989628FF79E65932390CBB15D8E621333B18B11C3 -BDF96F841D7434E01AD501FEA964A75B248A35CD9DF9A37E48A1E5A09C624B93CE44F0042FA00D7F -9EE89B9F7AB785E9C718CF6E7228F743271C2C9BBA17E5208B920E44E765D99D86650EB454B0FAAA -112753AA1BD3A24239E9C5FC47EEB1547AC9D23731B8DC48B9707830DAEC60C8D3790BBA1120F776 -4EFAC542CFFBCD5C05F9510B27B2534B704ECD36C8B041FD49A96881302FFF5B0163A2DD09C751D6 -D6AFEA9170A4F4C4AB8D46E62F763FE1BDA51DD1CE4A27E772F3A2869155F762FF26B7AA6FCFA4F1 -292E56F03AAB6322BF867E7710C34D43B5D85B45AA68014AD7879EED051B1933E491496E3E26D9AA -8B80A07BF2B94F1077E84A9726F08199887D66DE7A307BF33C30DD9CF3DA188088C03B2BAD09A217 -6B110DB2C868B53DA9A66C85737BA66C93C58A259860E294AD0191E3A72C73F40B0BD98699AA08DA -F03587B78F391F3A4313C58D9F29B53C70785637BD0C58310109C54091AB0A34CBB0C478613A7AC0 -FB8F0A8B4645AC966395D8BA775262CD291136AFFDDF01C1D83DD4EB3B59CCAD18057FE7D92A8CD4 -A58F22508D9FD7CF356571F701BBB23E749BDDCBF8A317FDA0AEFD952BB18545610FFAD3AC143D35 -1B8DB3F66293375E0E50235F0D0466932181D377EDD32A5F0FFA4E22B5A0CB4F343D9A7E4A342E9D -09DFF6C697630CD3971802C277A5590B8CA94BDE6B38446C794D072BBCCB724D5BC208EEF1B018D7 -39373BB910D668882CAA779C2D686081DE6A2606417B54D7C20E0E7F722648D893E4EDBAE8F00D6A -6DA3712F91AE860C756D1127D133AB828E9D80023B50B162C5A1C5CDF70CCB3FDD7EA060ED20838B -E1E50C4094C9E79E1A0187CDF780CAF45A725964F004253E034C5BE46BBF89D94631F1A33BAA35B8 -4FA2A9D08481C6674126CD96ED05DCE48BDA069D902D6836D5DFBA701DC0F98A863E64F0E312145D -8DC0B77F25B43AEC729A1243B45B08CA228DD6101CAA2AC5ADCC8EFF84A4CA3F254176C2CC711EE6 -C273835D0FD3528ECA2A976B88E51FE347FDB60F32370B66D338931D6581630ED586F349C638960C -31AE4204E89521A96E1219E696B913DEB2AAB7A3B022D06F34FDFCB810A04E60A4FEBE284C2F063E -0AE9EDF87704921CCFA193BDC912B747E13570066223A49F1F6E2AF0D4D65DA04CA876FF7A462FFC -9C0BA2CC545C3BD36DBE762F32B2D6BE5867C59F479195C92440DC165098B74EA5C3AD93CDF2D410 -B04C16BC7801E7956F4E5107450787AA592493171C3628E6B8F49D4F8429EB98DC52EF025F001387 -BC1A7093F7A99F10B5D2D7DD8BBB393BF6E56F08F4F7FA1A343F220D5A1EAE7168C74D41BE1DC1A8 -3BD65B72B982F4F7B34F24F97F9EC9A91011064031FACFF2A14921A32024385F4E061CD07D152E74 -1BF97156D951A342488FA7F5EF934CCAD13E2753A0AB7A1F565C2F7F6B349DF03BBC25BBD972A9AD -F809BB5C5048A8CCEF9297B2ED3324D18867F293CC66E88B3A39D107B610DFE79A3B4E83A96D3D52 -A17FE8A62C9FDD271130148366942C9CE57558D023DA5F7501319EBFA33DE9E6D1E76D7C20DB8A09 -B657839DA99F3D8143F1EE6253A3295C9651FA4366547893C2DC7ABCBF4BB7609DE5D001E0A36D9F -FBE01F7D0903B3208AE8547E2E5F14EC1AF4C2535CA8F4EA37E3F3CE172C7A1E8308995B1CC23E6E -81190246BCAB6E755BF868D449BB02A2AA87C44C9CC0F571ADC72547CEECBE104BB274B8AC16DCB7 -5D5F458D356466B921ACDEEAE384E2EB1DF6EF393B41B9747F0A4FAEB4AF1928D9AD6FB7E06FDC62 -1E4C6FC98CFB43F88584BD55D9B97CC9549093EDE586912161931162B1B1D52D0443260DABA02AF2 -B4432100D5506546013DA703573FA8013685CC798CE501960093DED713FFCCF89CA2B9106390198C -29A00864108CDCC1984A8BAB53919028C01B26ECC7925E38CBE6CCA8978EE21C2B06E7B3E48FBA97 -8E2A7D186E563C088F84AA23178B60E4729EE87D67B1091F3B6973676C1CBFE6530EB773C62E2C24 -97014AB0E8B71A1F4E86A378AA26591511BEE3CF3D64C94848582E1354E1605B6457823F2C5E640A -D3802946BB2E7E8E594E8C04B430C2385DD40746CE8534F50842E74D7115F3DB0C72D1C9C607C657 -3B094AEB73B7A79876CFFC3E2F8C9FEAAA07D3BFCE05B61F7749A8793BE90CCCECA2D7077F25E899 -D3331FE161A7E86C842495D584C6E4A0880B2951D8A13B88C4672080A0B1BE36BF47C3ACE7288CFE -41A8C1BAA6F0814A947FBD6B3AA72B6C73A8C578CA51CCC96F2352316C467BB960E981F2B6485BFB -44B577E71EFDA16E7405954BC7C9F0759F5A9F1EBCD2FA9CC9648D5831A68887F41B15081A204C24 -B4B992A231DEF9E698D4C3A25B6F5474F5BE6A601F2D337A58A0D21FF37FD91EB86D1D738893A03A -69F0CD743F611CDFFE69DB2C6ED0E4611D56F803BB0DC06E7FE85A303839612707647B1BE9FAF8D6 -84122CA9E5CB8BDE2936D3F4FF254D31529D7538BBD4D35539489F9E7316F24214B996BCDCF1818E -749A71CF0E8845AA1E2A58AA62A48E02BA4564625D20AA220EE719608521D7D7A7FCA0BD8904A401 -9819D371F3F59D46C1354E5FC1A6E5F79B20CF4ACA2BF0F2DE73DA193A6F9ACBFE0B4731C4BCEBE6 -D96FE822965DE965232282A3A130361F188B3AABDA95A8A2790D9240BE008B6A6DE4BBFCADA05B67 -86B9BB8E0DFA0C30043A3B07ED46277E07B9808422C8ED16758B9C396F4EA929D769785B2C9568E5 -70A83B989B25CE200F1727D41E2B702E7F88F1784F4C83FA60A74EB26B2DA95126E508ED519A61CC -151DB6804F61826C5F86D8FA89D06E526FED97A0DB88EDB432FF32C1ACC9B622EEDF601081AF7B96 -3C9CFC1D13E4A9C74FEA0A1C8E3D8653CD92A944D4CA6B0D306619AFD503506D77732D6514F604BE -4610C2560931BDE0B40939BC1D126B0E97F72AE1B4A9252123B54F7A27E0CFA4425B4546526FD741 -CA77952B10D13E0AC2E32006A903808FF0CD013F936238C74CC75FD915244C56A8412F37F0134840 -347699508D6F3D7F3203A25B7C70100719582CD588590EE34B3AB13E255B613A6D00386A0104CC5E -D2C646F09A88888D3751651D5646C5227A3C80E8DA1B0A331121DD2429F1F4775D30564DFF47D01B -BE2C6C72CE4D1FD9A2077C04D2B0274B8916F6A9D1A4A6964A534F47CF241D5A8E34B23F85BE9ACF -FC2FEA961F277539F215F8728D6788F67BEAF45502839BCF23D8763C3949352F00C579A9A4FC408E -C625E310DAE61512DFE6844E82D36A2F81709E1F05B38AE9C222ED62C961EE63593CED7AAF73CE2E -D3667740C77B309B93EEFE1B4BA65D48575A66BE86743DC9E5D3C2FF418D11F7F211B86E827EE1DF -C3613E7498030F07050524536D1F8A94DDB6698BE7B963C55CB3F74B676CD815A7B3DF4B1A0EA2BE -1B0B9A11FFBFD5B1FA49668AEE14629316AF436A0821C20BEEF7B3480847934A99F6D85B68F4DDF8 -859A754E009428AF89A90D1852C220A607FF0806E8080726EDC94D691D214B4521C147C4273AEBDD -BB4A697EF16448CD9B2FC95293305858DECFD406B89B9F3FDAE2AC579E80CF321EBAE5701FB2F7CA -D8ED04B4A63115886D45D6120F69AEF1A21D80AD3C2D35D2899F1902242B96CD349E0AAADA40F7A1 -1282B6B52BDD97708E58DC5E2D22D1153E5FA3F3B300BCDFAF98DEC2F4E3C82A1C85F985735F3987 -4F557579F422664E07CBE19DA680EFB0FC82C323EC5C4644C51709AC8D674608A8043C91E6C7988D -430F10BA6CE1FC7FC0604FCD8F723895250AEC36CC35B3FA14FE2A0D24095DCC30B2093F2298F5F0 -A97676A0BE66C3DC9ADACFE2FC0F721A20E945AFC1096A619075D5E9A264C796EC6C90EF1AEEA8DC -089B44FFC13D27CB2370070A52D4416C53F364393E46EDD7EDE00799960CE6E0D57E4909E88ADD64 -BDD2B0EBE2D73FA6ACF8B40280DAA0637E705C65AABD523B8815F22F23E9FF81E7829C7E4BC980C9 -143AEBE1A04DC0D253396BBB7268BD5AEEA356B610D5DCEE03135E00AE34388251F31714A1C40E18 -2652C48CDA2211A22CB6F02490E69A44CECB169754C53B16028D352E0119F5D5FAE0BD7EA1CDA647 -12A6147374B64244E21E9EC9F0D1381AD22D5B6212B26C3F9AA5F6045F25DD9F5EB4489EA39B1945 -331AC70510C5752557DE21D0A6CFC1EB10A98FA867B76DA6E4249469F591FD154D39E89364A43DB0 -07AA0D7A911CFAE6CE2B557997FBC44F55A27F622BD7B8B10EC9F5D10F2649A646FD964AE1B111B3 -5B46A252C4DEE44E7426EB5739F24E8A390694597DB3A1FE7800C97E59558322F0E49A0CCE2AD94B -1E2D1026AFA771723E3F523916F55ED866C9FB4A2F759651C613A2CFF362028CDF9D38F05D4C7C60 -24C533E930B64B099FB1AF04B01F5FB9CA6867E6EFF55A772C5391831059987E10CBF987E3F378E0 -1329F73D54DC0484177D3C3C06F67397955FF1CA4EF8AD1606B70455255D631A7D6EB92BFDBA14A0 -FF28B2ACE7E81AD666EA9B3A0F5A6BA3B5DFE35044FA4B3D8ED956009C60E98CC132F2E84967F4A9 -8A67B336D5EE7CAF7DD1F74D1FA08619941361FA7312CF225D89CEF97E864C8369EAFAB94D97F056 -5505D825972B754F6729596EEA91210B75DD8F645382ACE36DE60819A02B3B48DD00F5485F9264F9 -FA926D732E2C267B0BE8CA98526F124F97EFDB86132C5EF16B103908172FC51F286FFE45FF253512 -E0033F037FF182BA536A9EB2DF2D1DB257D9C86C46E1B002FB32AC70CA9462E6EB48994752CEBCE3 -9F08ABD4F4B0889283E55500702185A841E328 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%EndResource -/NimbusMonL-Regu-iso1252 /NimbusMonL-Regu ISO1252Encoding psp_definefont -/Times-Roman-iso1252 /Times-Roman ISO1252Encoding psp_definefont -294 310 moveto -0 0 0 setrgbcolor -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<4558504F52545F505953435249505453202B3D20534D4553485F6669786174696F6E5F68657861 -2E70792C20534D4553485F666C696768745F736B696E2E7079> -show -294 398 moveto -<69666571202840574954484E455447454E402C79657329> -show -294 442 moveto -<20204558504F52545F505953435249505453202B3D20534D4553485F626F785F74657472612E70 -792C20534D4553485F626F78325F74657472612E70792C205C202020> -show -294 486 moveto -<20202020202020202020202020202020202020202020534D4553485F626F78335F74657472612E -70792C20534D4553485F6669786174696F6E5F74657472612E70792C205C> -show -294 530 moveto -<20202020202020202020202020202020202020202020534D4553485F506172746974696F6E315F -74657472612E7079> -show -294 574 moveto -<656E646966> -show -295 691 moveto -/Symbol findfont 50 -50 matrix scale makefont setfont - -show -370 691 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<46696E616C656D656E74> -show -595 691 moveto -<20> -show -607 691 moveto -<3A> -show -294 797 moveto -/NimbusMonL-Regu-iso1252 findfont 42 -42 matrix scale makefont setfont -<2E2F6275696C645F636F6E666967757265> -show -294 841 moveto -<636420534D4553485F4255494C44> -show -294 885 moveto -<726D20636F6E6669672E2A> -show -294 929 moveto -<53414C4F4D45325F524F4F542F534D4553485F5352432F636F6E6669677572652096776974682D -6E657467656E3D6E657467656E5F696E7374616C6C6174696F6E5F70617468205C> -show -294 973 moveto -<967072656669783D736D6573685F696E7374616C6C5F70617468> -show -294 1016 moveto -<6D616B65> -show -220 1128 moveto -/Times-Roman-iso1252 findfont 50 -50 matrix scale makefont setfont -<6FF920736D6573685F696E7374616C6C5F7061746820657374206C61206469726563746F727920 -6427696E7374616C6C6174696F6E206475206D6F64756C6520534D4553482E> -show -280 277 1 308 rectfill -2125 277 1 308 rectfill -280 277 1846 1 rectfill -280 584 1846 1 rectfill -280 763 1 264 rectfill -2125 763 1 264 rectfill -280 763 1846 1 rectfill -280 1026 1846 1 rectfill -showpage -grestore grestore -%%PageTrailer - -%%Trailer -%%Pages: 7 -%%EOF diff --git a/doc/salome/tui/extra/AddNetgenInSalome2.sxw b/doc/salome/tui/extra/AddNetgenInSalome2.sxw deleted file mode 100644 index 15381905d..000000000 Binary files a/doc/salome/tui/extra/AddNetgenInSalome2.sxw and /dev/null differ diff --git a/doc/salome/tui/extra/PluginMeshers.html b/doc/salome/tui/extra/PluginMeshers.html deleted file mode 100755 index 64c368819..000000000 --- a/doc/salome/tui/extra/PluginMeshers.html +++ /dev/null @@ -1,344 +0,0 @@ - - - - - - - - Main Page - - - - -   -
                    - - - - - - - - -
                    -

                    -

                    -
                    - -
                    -
                    - -
                    -

                    How to add your own mesher

                    -
                    - -
                    -

                    (as a set of hypotheses and algorithms)

                    -
                    - -
                    -

                    to the application.

                    -
                    - -

                    Table of contents

                    - - - -

                    1. Introduction

                    - All hypotheses and algorithms are available in SMESH module via plugin mechanism. -Such approach allows easily to introduce new hypotheses and algorithms types -to the application. Also, it makes possible the customization of available -hypotheses and algorithms list for different users without recompilation -of sources.
                    -The goal of this document is to describe the process of creation external -mesher plugins. -

                    Back to the contents

                    -

                    2. Implementation steps

                    - -

                    -

                    2.1. Mesher plugin package

                    - -Create your mesher plugin package which will contain the sources files, e.g. - MyMesherPlugin.
                    -
                    -Back -to the contents
                    -

                    2.2. List of available hypotheses and algorithms

                    -Create XML file to describe all algorithms and hypotheses, provided by your -plugin package (see SMESH_SRC/resources/SMESH_Meshers.xml for example).
                    -
                    <meshers-group name="MyName"
                    -               resources="MyResourceKey"
                    -               -server-lib="libMyServerLib.so"
                    -               gui-lib="libMyClientLib.so">
                    -     <hypotheses>
                    -          <hypothesis type="MyHypType1"
                    -                  -    label-id="My beautiful hypothesis name"
                    -                   -   icon-id="my_hypo_1_icon.png"/>
                    -          </hypotheses>
                    -     <algorithms>
                    -          <algorithm type="MyAlgType1"
                    -                -     label-id="My beautiful algorithm name"
                    -                 -    icon-id="my_algo_1_icon.png"/>
                    -          </algorithms>
                    -</meshers-group>
                    -

                    - -
                      -
                    • Attributes of <meshers-group> tag:
                    • -
                    -
                    -
                      -
                    • value of <name> attribute is used to collect hypotheses/algoritms -in groups; you can also use this attribute for short description of your -mesher plugin.
                    • -
                    • value of <resources> attribute (MyResourceKey) is used to -access resources (messages and icons) from GUI (see paragraphs 2.4.2 and 2.5); in the current implementation -it should coincide with the name of plugin package; this limitation will -be eliminated in the further development.
                    • -
                    • value of <server-lib> attribute describes the name of your -mesher's server plugin library (See paragraph 2.3)
                    • -
                    • value of <gui-lib> attribute describes the name of your mesher's -client plugin library (See paragraph 2.4)
                    • -
                    -
                    -
                      -
                    • Attributes of <hypothesis/algorithm> tag:
                    • -
                    -
                    -
                      -
                    • value of <type> attribute is an unique name of the hypothesis/algorithm
                    • -
                    -
                      -
                        -
                      • It is a value of _name field of your hypothesis class (see paragraph - 2.3, implementation of constructor of StdMeshers_LocalLength -class: _name = "LocalLength")
                      • -
                      • It is a key to each certain hypothesis class (see paragraph 2.3, implementation of "GetHypothesisCreator()" method in -StdMeshers_i.cxx)
                      • -
                      • It is a key to each certain hypothesis GUI (see paragraph 2.4, implementation of "StdMeshersGUI_HypothesisCreator::CreateHypothesis()" -and "StdMeshersGUI_HypothesisCreator::EditHypothesis()" methods in StdMeshersGUI.cxx)
                      • -
                      • It is a key to each certain hypothesis icon in Object Browser -(see paragraph 2.4.2.1)
                      • -
                      -
                    -
                    -
                    -
                      -
                    • value of <label-id> attribute is displayed in the GUI in -the list of available hypotheses/algorithms ("Create Hypothesis/Algorithm" -dialog)
                    • -
                    • value of <icon-id> attribute is a name of icon file, which -is displayed in GUI in the list of available hypotheses/algorithms ("Create -Hypothesis/Algorithm" dialog)
                    • -
                    -
                    -Note: All attributes values are accessible in your GUI via HypothesisData -class (see paragraph 2.4.1)
                    -
                    -Note: The environment variable SMESH_MeshersList contains the list of plugins -names, separated by colon (":") symbol, e.g.:
                    -
                    -     setenv SMESH_MeshersList StdMeshers:NETGENPlugin
                    -
                    -Please, pay attention that StdMeshers should also be included into this environment -variable, if you want to use standard hypotheses/algorithms, provided with -SMESH module.
                    -
                    -The SALOME automatically locates XML files, searching them in the following -directories:
                    -
                    -    ${<PLUGINNAME>_ROOT_DIR}/share/salome/resources/<pluginname>
                    -    ${SALOME_<PluginName>Resources}
                    -    ${HOME}/.salome/resources
                    -    ${KERNEL_ROOT_DIR}/share/salome/resources/kernel

                    -
                    -where <PluginName> is a name of each mesher plugin package
                    -
                    -Back to the contents -

                    2.3. Build server plugin library <libMyServerLib.so>.

                    - -

                    2.3.1. Define interface to your hypotheses and algorithms.

                    - -
                    Example: SMESH_SRC/idl/SMESH_BasicHypothesis.idl
                    -         NETGENPLUGIN_SRC/src/NETGENPlugin_Algorithm.idl
                    -
                    - -

                    2.3.2. Implement functionality of your hypotheses -and algorithms.

                    - -
                    Inherit corresponding classes from SMESH. -

                    Example: SMESH_SRC/src/StdMeshers/StdMeshers_*
                    -         NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D
                    -

                    -
                    - -

                    2.3.3.Implement interface to your hypotheses and -algorithms.

                    - -
                    Inherit corresponding classes from SMESH_I. -

                    Example: SMESH_SRC/src/StdMeshers_I/SMESH_*_i
                    -         NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D_i
                    -

                    -
                    - -

                    2.3.4. Implement being exported method.

                    - -
                    GenericHypothesisCreator_i* GetHypothesisCreator (const char* -aHypType) -

                    <aHypType> is a value of <type> attribute in the XML-description -file

                    -
                    - -
                    Example: SMESH_SRC/src/StdMeshers_I/StdMeshers_i.cxx
                    -         NETGENPLUGIN_SRC/src/NETGENPlugin_i.cxx
                    -
                    - Back to the contents -

                    2.4. Build client (GUI) plugin library <libMyClientLib.so>.

                    - -
                    This step is required only if your hypotheses/algorithms need -specific GUI for their construction.
                    - -

                    2.4.1. Implement the required GUI (e.g. construction -dialog boxes).

                    - -
                    Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI_*Dlg -

                    Note: all data from XML-description files is accessible in your GUI -via HypothesisData class  (mySMESHGUI->GetHypothesisData (aHypType), -see SMESHGUI_Hypotheses.h for HypothesisData definition)

                    -
                    - -

                    2.4.2. Provide icons and messages for your GUI.

                    - -
                    2.4.2.1. Implement resource files
                    - -
                    MyResourceKey_icons.po and MyResourceKey_msg_en.po -

                    Example: SMESH_SRC/src/StdMeshersGUI/StdMeshers_*.po
                    -         NETGENPLUGIN_SRC/src/NETGENPlugin_icons.po
                    -

                    -Note: ICON_SMESH_TREE_HYPO_MyHypType1 is ID of icon for Object Browser for -hypothesis with type="MyHypType1"; ICON_SMESH_TREE_ALGO_MyAlgType1 is ID -of icon for Object Browser for algorithm with type="MyAlgType1".
                    -See paragraph 2 for definition of MyResourceKey, MyHypType1, MyAlgType1.
                    -

                    -
                    - -
                    2.4.2.2. Define environment variable SALOME_<MyResourceKey>Resources
                    -
                    It should point to the directory where resources are situated.
                    - -
                    Example: setenv SALOME_StdMeshersResources ${SMESH_ROOT_DIR}/share/salome/resources/smesh
                    - -

                    2.4.3. Implement your Hypothesis Creator and being -exported method

                    - -
                    SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator -
                    -   (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI) -

                    <aHypType> is to pass a value of <type> attribute in XML-description -file;
                    -<aServerLibName> is to pass a value of <server-lib> attribute -in XML-description file.

                    -

                    Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI.cxx

                    -
                    - Back to the contents -

                    2.5. Provide icons for object browser.

                    - -
                    If your hypotheses/algorithms do not need specific GUI, but you -want to provide icons for object browser, see 2.4.2 paragrath.
                    -
                    - - -

                    2.6. Setup your SALOME environment.

                    - -

                    2.6.1.  Add your plugin to the LD_LIBRARY_PATH, -PYTHONPATH (and maybe PATH) environment variables.
                    -

                    -
                    setenv PATH <path-to-my-plugin>/bin/salome:${PATH}
                    -setenv LD_LIBRARY_PATH <path-to-my-plugin>/lib/salome:${LD_LIBRARY_PATH}
                    -Setenv PYTHONPATH <path-to-my-plugin>/lib/python2.2/site-packages/salome:${PYTHONPATH}
                    -
                      
                    -
                    -

                    2.6.2.  Set mesher plugin resources environment -variable

                    -
                     This enviroment variable is used to set meshers plugins -which should be loaded by SMESH module (see 2.4.2.2 -paragraph). Add your plugin to this variable. All plugins are separated by -colon (":") symbol.
                    -
                    -Note: If you use runSalome.py script from KERNEL package to launch SALOME, -you may not to set environment variables, because this script sets them itself. -All what you should do is to add <plugin> section to your ${HOME}/.salome/salome.launch -file for SMESH module section:
                    -
                    -...
                    -<modules-list>
                    -    ...
                    -    <module name="SMESH">
                    -        <plugin name="MyMesher"/>
                    -    </module>
                    -    ...
                    -</modules-list>
                    -...

                    -
                    -Back to the contents

                    - - diff --git a/doc/salome/tui/extra/PluginMeshers.txt b/doc/salome/tui/extra/PluginMeshers.txt deleted file mode 100644 index 71e58b2e7..000000000 --- a/doc/salome/tui/extra/PluginMeshers.txt +++ /dev/null @@ -1,188 +0,0 @@ -####################################################################################### -# File : PluginMeshers.txt -# Author : Julia DOROVSKIKH -# Module : SMESH -# $Header$ -####################################################################################### -# -# How to add your own mesher (as a set of hypotheses and algorithms) to the application -# -####################################################################################### - -1. Create mesher plugin package, e.g. MyMesher. - -2. Create XML file to describe all algorithms and hypotheses, provided by plugin package - (see SMESH_SRC/resources/SMESH_Meshers.xml for example). - - - - - - - - - - - Attributes of tag: - - - value of attribute is used to collect hypotheses/algoritms in groups; - you can also use this attribute for short description of your mesher plugin - - - value of attribute (MyResourceKey) is used to access resources - (messages and icons) from GUI (see paragraphs 4.2 and 5); - currently it should coincide with the name of plugin package; this limitation - will be eliminated in the further development. - - - value of attribute describes the name of your mesher's - server plugin library (See paragraph 3) - - - value of attribute describes the name of your mesher's - client plugin library (See paragraph 4) - - Attributes of tag: - - - value of attribute is an unique name of the hypothesis/algorithm - - * It is a value of _name field of your hypothesis class - (see paragraph 3, implementation of constructor of - StdMeshers_LocalLength class: _name = "LocalLength") - - * It is a key to each certain hypothesis class - (see paragraph 3, implementation of "GetHypothesisCreator()" method in StdMeshers_i.cxx) - - * It is a key to each certain hypothesis GUI - (see paragraph 4, implementation of "StdMeshersGUI_HypothesisCreator::CreateHypothesis()" - and "StdMeshersGUI_HypothesisCreator::EditHypothesis()" methods in StdMeshersGUI.cxx) - - * It is a key to each certain hypothesis icon in Object Browser - (see paragraph 4.2.1) - - - value of attribute is displayed in the GUI in the list - of available hypotheses/algorithms ("Create Hypothesis/Algorithm" dialog) - - - value of attribute is a name of icon file, which is displayed in GUI - in the list of available hypotheses/algorithms ("Create Hypothesis/Algorithm" dialog) - - Note: All attributes values are accessible in your GUI via HypothesisData class - (see paragraph 4.1) - - Note: The environment variable SMESH_MeshersList contains the list of plugins names, - separated by colon (":") symbol, e.g.: - - setenv SMESH_MeshersList StdMeshers:NETGENPlugin - - Please, pay attention that StdMeshers should also be included into this environment variable, - if you want to use standard hypotheses/algorithms, provided with SMESH module. - - The SALOME automatically locates XML files, searching them in the following directories: - - ${_ROOT_DIR}/share/salome/resources/ - ${SALOME_Resources} - ${HOME}/.salome/resources - ${KERNEL_ROOT_DIR}/share/salome/resources/kernel - - where is a name of each mesher plugin package - -3. Build server plugin library . - - 3.1. Define interface to your hypotheses and algorithms. - - Example: SMESH_SRC/idl/SMESH_BasicHypothesis.idl - NETGENPLUGIN_SRC/src/NETGENPlugin_Algorithm.idl - - 3.2. Implement functionality of your hypotheses and algorithms. - Inherit corresponding classes from SMESH. - - Example: SMESH_SRC/src/StdMeshers/StdMeshers_* - NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D - - 3.3. Implement interface to your hypotheses and algorithms. - Inherit corresponding classes from SMESH_I. - - Example: SMESH_SRC/src/StdMeshers_I/SMESH_*_i - NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D_i - - 3.4. Implement being exported method. - - GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypType) - - is a value of attribute in the XML-description file - - Example: SMESH_SRC/src/StdMeshers_I/StdMeshers_i.cxx - NETGENPLUGIN_SRC/src/NETGENPlugin_i.cxx - -4. Build client (GUI) plugin library . - This step is required only if your hypotheses/algorithms need specific GUI for their construction. - - 4.1. Implement the required GUI (e.g. construction dialog boxes). - - Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI_*Dlg - - Note: all data from XML-description files is accessible in your GUI via HypothesisData class - (mySMESHGUI->GetHypothesisData (aHypType), - see SMESHGUI_Hypotheses.h for HypothesisData definition) - - 4.2. Provide icons and messages for your GUI. - - 4.2.1. Implement resource files - MyResourceKey_icons.po and MyResourceKey_msg_en.po - - Example: SMESH_SRC/src/StdMeshersGUI/StdMeshers_*.po - NETGENPLUGIN_SRC/src/NETGENPlugin_icons.po - - Note: ICON_SMESH_TREE_HYPO_MyHypType1 is ID of icon for Object Browser - for hypothesis with type="MyHypType1". - - ICON_SMESH_TREE_ALGO_MyAlgType1 is ID of icon for Object Browser - for algorithm with type="MyAlgType1". - - See paragraph 2 for definition of MyResourceKey, MyHypType1, MyAlgType1. - - 4.2.2. Define environment variable SALOME_Resources to point to the - directory where resources are situated. - - Example: setenv SALOME_StdMeshersResources ${SMESH_ROOT_DIR}/share/salome/resources/smesh - - 4.3. Implement your Hypothesis Creator and being exported method - - SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator - (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI) - - is to pass a value of attribute in XML-description file; - is to pass a value of attribute in XML-description file. - - Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI.cxx - -5. If your hypotheses/algorithms do not need specific GUI, - but you want to provide icons for object browser, see 4.2 paragrath - -6. Setup your SALOME environment. - - 6.1. Add your plugin to the LD_LIBRARY_PATH, PYTHONPATH (and maybe PATH) environment variables, e.g.: - - setenv PATH /bin/salome:${PATH} - setenv LD_LIBRARY_PATH /lib/salome:${LD_LIBRARY_PATH} - setenv PYTHONPATH /lib/python2.2/site-packages/salome:${PYTHONPATH} - - 6.2. Set mesher plugin resources environment variable (see 4.2.2 paragraph) - -Note: If you use runSalome.py script from KERNEL package to launch SALOME, you may not to set - environment variables, because this script sets them itself. All what you should do is - to add section to your ${HOME}/.salome/salome.launch file for SMESH module section: - - ... - - ... - - - - ... - - ... diff --git a/doc/salome/tui/images/head.png b/doc/salome/tui/images/head.png new file mode 100755 index 000000000..307d9ef9a Binary files /dev/null and b/doc/salome/tui/images/head.png differ diff --git a/doc/salome/tui/images/smeshscreen.png b/doc/salome/tui/images/smeshscreen.png new file mode 100755 index 000000000..638870e5f Binary files /dev/null and b/doc/salome/tui/images/smeshscreen.png differ diff --git a/doc/salome/tui/input/index.doc b/doc/salome/tui/input/index.doc new file mode 100644 index 000000000..d0ef8933b --- /dev/null +++ b/doc/salome/tui/input/index.doc @@ -0,0 +1,13 @@ +/*! \mainpage + +\image html smeshscreen.png + +To browse the \b SALOME Mesh module Developer Documentation, follow the links below or use navigation menu at the top of the page: +
                      +
                    • Modules - documentation of TUI functionality.
                    • +
                    • Name Spaces - list of TUI packages and scripts.
                    • +
                    • Data Structures - list of all data structures and classes with brief descriptions.
                    • +
                    • Files - list of all files with brief descriptions.
                    • +
                    + +*/ \ No newline at end of file diff --git a/doc/salome/tui/static/doxygen.css b/doc/salome/tui/static/doxygen.css index 389449d87..7a2dcbde8 100755 --- a/doc/salome/tui/static/doxygen.css +++ b/doc/salome/tui/static/doxygen.css @@ -1,160 +1,836 @@ -H1 { - text-align: center; +/* The standard CSS for doxygen */ + +body, table, div, p, dl { + font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size: 12px; +} + +/* @group Heading Levels */ + +h1 { + font-size: 150%; +} + +h2 { + font-size: 120%; +} + +h3 { + font-size: 100%; } -CAPTION { - font-weight: bold +dt { + font-weight: bold; } -/* Link in the top navbar */ -A.qindex {} +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} -A.qindexRef {} +p.enddd { + margin-bottom: 4px; +} -/* Link to any cross-referenced Doxygen element */ -A.el { - text-decoration: none; - font-weight: bold +p.endtd { + margin-bottom: 2px; } -A.elRef { - font-weight: bold +/* @end */ + +caption { + font-weight: bold; } -/* Link to any cross-referenced Doxygen element inside a code section - (ex: header) +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + padding: 2px; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code { + color: #4665A2; +} + +a.codeRef { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +.fragment { + font-family: monospace, fixed; + font-size: 105%; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.version { + border:1px solid #0000FF; + color: #CCCCCC; + font-family: Arial, Helvetica, sans-serif; + font-size: 9pt; + text-align: center; + width:100px; + -moz-border-radius: 8px; + margin: 5px; +} + +div.footer1 { + background-color: #DFE5F1; + border: 1px solid #AAAAAA; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + padding: 10px; + margin-top: 15px; +} + + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 10px; + margin-right: 10px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} */ -A.code { - text-decoration: none; - font-weight: normal; - color: #4444ee + +td.tiny { + font-size: 75%; } -A.codeRef { - font-weight: normal; - color: #4444ee +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; } -A:hover { - text-decoration: none; - background-color: lightblue +th.dirtab { + background: #EBEFF6; + font-weight: bold; } -DL.el { - margin-left: -1cm +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; } -/* A code fragment (ex: header) */ -DIV.fragment { - width: 100%; - border: none; - background-color: #CCCCCC +hr.footer { + height: 1px; } -/* In the alpha list (coumpound index), style of an alphabetical index letter */ -DIV.ah { - background-color: #CCCCCC; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; } -/* Method name (+ type) */ -TD.md { - background-color: lightblue; - font-weight: bold; +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; } -/* Method parameter (some of them) */ -TD.mdname1 { - background-color: lightblue; - font-weight: bold; color: #602020; +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; } -/* Method parameter (some of them) */ -TD.mdname { - background-color: lightblue; - font-weight: bold; - color: #602020; - width: 600px; +.memItemLeft, .memItemRight, .memTemplParams { + border-top: 1px solid #C4CFE5; } -/* Separator between methods group (usually empty, seems not supported by IE) */ -DIV.groupHeader { - margin-left: 16px; - margin-top: 12px; - margin-bottom: 6px; - font-weight: bold +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; } -DIV.groupText { - margin-left: 16px; - font-style: italic; - font-size: smaller +.memTemplParams { + color: #4665A2; + white-space: nowrap; } -BODY { - background: #FFFFFF; +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; } -/*div.div-page { - background-color: #FFFFFF; - margin-left: 1em; - margin-right: 1em; - margin-top: 1em; - margin-bottom: 0.1em; +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} - padding-left: 1em; - padding-right: 1em; - padding-top: 0.5em; - padding-bottom: 0.5em; +.memitem { + padding: 0; + margin-bottom: 10px; +} + +.memname { + white-space: nowrap; + font-weight: bold; + margin-left: 6px; +} + +.memproto { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 8px; + border-top-left-radius: 8px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 8px; + -moz-border-radius-topleft: 8px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 8px; + -webkit-border-top-left-radius: 8px; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + +} + +.memdoc { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 2px 5px; + background-color: #FBFCFD; + border-top-width: 0; + /* opera specific markup */ + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} + +.params, .retval, .exception, .tparams { + border-spacing: 6px 2px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + + + + +/* @end */ + +/* @group Directory (tree) */ + +/* for the tree view */ + +.ftvtree { + font-family: sans-serif; + margin: 0px; +} + +/* these are for tree view when used as main index */ + +.directory { + font-size: 9pt; + font-weight: bold; + margin: 5px; +} + +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +/* +The following two styles can be used to replace the root node title +with an image of your choice. Simply uncomment the next two styles, +specify the name of your image and be sure to set 'height' to the +proper pixel height of your image. +*/ + +/* +.directory h3.swap { + height: 61px; + background-repeat: no-repeat; + background-image: url("yourimage.gif"); +} +.directory h3.swap span { + display: none; +} +*/ + +.directory > h3 { + margin-top: 0; +} + +.directory p { + margin: 0px; + white-space: nowrap; +} + +.directory div { + display: none; + margin: 0px; +} + +.directory img { + vertical-align: -30%; +} + +/* these are for tree view when not used as main index */ + +.directory-alt { + font-size: 100%; + font-weight: bold; +} + +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +.directory-alt > h3 { + margin-top: 0; +} + +.directory-alt p { + margin: 0px; + white-space: nowrap; +} + +.directory-alt div { + display: none; + margin: 0px; +} + +.directory-alt img { + vertical-align: -30%; +} + +/* @end */ - border: 2px solid #0D299A; - border-width: 2px; - border-color: #0D299A; -}*/ +div.dynheader { + margin-top: 8px; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; +} + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + padding-left: 5px; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.title { + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +dl +{ + padding: 0 0 0 10px; +} + +dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug +{ + border-left:4px solid; + padding: 0 0 0 6px; +} + +dl.note +{ + border-color: #D0D000; +} + +dl.warning, dl.attention +{ + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + border-color: #00D000; +} + +dl.deprecated +{ + border-color: #505050; +} + +dl.todo +{ + border-color: #00C0E0; +} + +dl.test +{ + border-color: #3030E0; +} + +dl.bug +{ + border-color: #C08050; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + background-color: #175783; + border: 1px solid; + height: 80px; + background-repeat: no-repeat; +/* font: 300% arial,sans-serif;*/ + margin: 0px; + padding: 0px; +} + +#projectbrief +{ + font: 120% arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% arial,sans-serif; + margin: 0px; + padding: 0px; +} -DIV.div-footer { - margin-left: 1em; - margin-right: 1em; - margin-bottom: 0.2em; - text-align: right; - font-size: 9pt; +#titlearea +{ + background: url("head.png"); + background-color: #175783; + border: 1px solid; + height: 80px; + background-repeat: no-repeat; + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; } -/* In File List, Coumpound List, etc, 1st column of the index */ -TD.indexkey { - background-color: #CCCCCC; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} - -/* In File List, Coumpound List, etc, 2nd column of the index */ -TD.indexvalue { - background-color: #CCCCCC; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} - -span.keyword { color: #008000 } -span.keywordtype { color: #604020 } -span.keywordflow { color: #e08000 } -span.comment { color: #800000 } -span.preprocessor { color: #806020 } -span.stringliteral { color: #002080 } -span.charliteral { color: #008080 } diff --git a/doc/salome/tui/static/footer.html b/doc/salome/tui/static/footer.html index cb55f397a..5b030c021 100755 --- a/doc/salome/tui/static/footer.html +++ b/doc/salome/tui/static/footer.html @@ -1,5 +1,14 @@ - - - - + + + + + +
                    + +
                    +Copyright © 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
                    +Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
                    +
                    +
                    + + diff --git a/doc/salome/tui/static/header.html.in b/doc/salome/tui/static/header.html.in new file mode 100755 index 000000000..4571b4363 --- /dev/null +++ b/doc/salome/tui/static/header.html.in @@ -0,0 +1,20 @@ + + + + + +$title + +$treeview +$search +$mathjax + + + + +
                    +
                    Version: @VERSION@
                    + +
                    diff --git a/doc/salome/tui/static/myheader.html b/doc/salome/tui/static/myheader.html deleted file mode 100755 index d2efb75fa..000000000 --- a/doc/salome/tui/static/myheader.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Main Page - - - - -  - - diff --git a/idl/Makefile.am b/idl/Makefile.am index a1d468cb5..c43e554d3 100644 --- a/idl/Makefile.am +++ b/idl/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # This Makefile is responsible of generating the client and server # implementation of IDL interfaces for both C++ and python usage. # The building process of the C++ files is in charge of each source @@ -34,7 +32,10 @@ BASEIDL_FILES = \ SMESH_Filter.idl \ SMESH_Group.idl \ SMESH_Pattern.idl \ - SMESH_MeshEditor.idl + SMESH_MeshEditor.idl \ + SMESH_Measurements.idl + +BASEIDL_FILES_PY=$(BASEIDL_FILES:%.idl=%_idl.py) # This variable defines the files to be installed dist_salomeidl_DATA = $(BASEIDL_FILES) @@ -51,13 +52,16 @@ nodist_libSalomeIDLSMESH_la_SOURCES = \ SMESH_FilterSK.cc \ SMESH_GroupSK.cc \ SMESH_PatternSK.cc \ - SMESH_MeshEditorSK.cc + SMESH_MeshEditorSK.cc \ + SMESH_MeasurementsSK.cc + +# to be done at first, to avoid parallel compilation problems +BUILT_SOURCES = $(nodist_libSalomeIDLSMESH_la_SOURCES) # header files must be exported: other modules have to use this library nodist_salomeinclude_HEADERS = $(BASEIDL_FILES:%.idl=%.hh) libSalomeIDLSMESH_la_CPPFLAGS = \ - -I$(top_builddir)/salome_adm/unix \ -I$(top_builddir)/idl \ $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) \ $(KERNEL_CXXFLAGS) $(MED_CXXFLAGS) \ @@ -85,8 +89,7 @@ IDLCXXFLAGS = \ -I$(top_builddir)/idl/salome \ -I$(KERNEL_ROOT_DIR)/idl/salome \ -I$(MED_ROOT_DIR)/idl/salome \ - -I$(GEOM_ROOT_DIR)/idl/salome \ - -I$(top_builddir)/salome_adm/unix + -I$(GEOM_ROOT_DIR)/idl/salome IDLPYFLAGS = \ @IDLPYFLAGS@ \ @@ -107,9 +110,15 @@ install-exec-local: $(BASEIDL_FILES:%=$(top_srcdir)/idl/%) $(OMNIORB_IDL) $(IDLPYFLAGS) -C$(DESTDIR)$(salomepythondir) $$file ; \ done -# uninstall-local removes too much, but it works in distcheck +# we want to remove only staff generated for IDL files and nothing more uninstall-local: - rm -rf $(DESTDIR)$(salomepythondir)/* + @for modulen in SMESH StdMeshers ; do \ + test -d $(DESTDIR)$(salomepythondir)/$${modulen} && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen} ; \ + test -d $(DESTDIR)$(salomepythondir)/$${modulen}__POA && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}__POA" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen}__POA ; \ + done ; \ + for filen in $(BASEIDL_FILES_PY) ; do \ + echo "Removing $(DESTDIR)$(salomepythondir)/$${filen}" && rm -f $(DESTDIR)$(salomepythondir)/$${filen}* ; \ + done mostlyclean-local: -rm -f *.hh *.cc .depidl diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index 9c428ba14..5ec9ebbf0 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_BasicHypothesis.idl // Author : Paul RASCLE, EDF // @@ -29,7 +30,6 @@ #include "SMESH_Hypothesis.idl" #include "SMESH_Mesh.idl" - /*! * StdMeshers: interfaces to standard hypotheses and algorithms */ @@ -209,6 +209,26 @@ module StdMeshers */ long ConversionMode() raises (SALOME::SALOME_Exception); + + /*! + * Set list of edges to reverse + */ + void SetReversedEdges( in SMESH::long_array list ); + + /*! + * Returns list of edges to reverse + */ + SMESH::long_array GetReversedEdges(); + + /*! + * Set entry of the main object + */ + void SetObjectEntry( in string entry ); + + /*! + * Get the entry of the main object + */ + string GetObjectEntry(); }; /*! @@ -218,14 +238,48 @@ module StdMeshers { /*! * Sets or parameter value + * * OBSOLETE *. Avoid such a way of interface design + * * It is recommended to dedicate a method to each parameter. */ void SetLength(in double length, in boolean isStartLength) raises (SALOME::SALOME_Exception); + /*! + * Sets parameter value + */ + void SetStartLength(in double length) + raises (SALOME::SALOME_Exception); + + /*! + * Sets parameter value + */ + void SetEndLength(in double length) + raises (SALOME::SALOME_Exception); + /*! * Returns or parameter value */ double GetLength(in boolean isStartLength); + + /*! + * Set list of edges to reverse + */ + void SetReversedEdges( in SMESH::long_array list ); + + /*! + * Returns list of edges to reverse + */ + SMESH::long_array GetReversedEdges(); + + /*! + * Set entry of the main object + */ + void SetObjectEntry( in string entry ); + + /*! + * Get the entry of the main object + */ + string GetObjectEntry(); }; /*! @@ -269,14 +323,48 @@ module StdMeshers { /*! * Sets or parameter value + * * OBSOLETE *. Avoid such a way of interface design. + * * It is recommended to dedicate a method to each parameter. */ void SetLength(in double length, in boolean isStartLength) raises (SALOME::SALOME_Exception); + /*! + * Sets parameter value + */ + void SetStartLength(in double length) + raises (SALOME::SALOME_Exception); + + /*! + * Sets parameter value + */ + void SetEndLength(in double length) + raises (SALOME::SALOME_Exception); + /*! * Returns or parameter value */ double GetLength(in boolean isStartLength); + + /*! + * Set list of edges to reverse + */ + void SetReversedEdges( in SMESH::long_array list ); + + /*! + * Returns list of edges to reverse + */ + SMESH::long_array GetReversedEdges(); + + /*! + * Set entry of the main object + */ + void SetObjectEntry( in string entry ); + + /*! + * Get the entry of the main object + */ + string GetObjectEntry(); }; @@ -298,6 +386,54 @@ module StdMeshers }; + /*! + * StdMeshers_FixedPoints1D: interface of "Fixed points 1D" hypothesis + */ + interface StdMeshers_FixedPoints1D : SMESH::SMESH_Hypothesis + { + /*! + * Sets some points on edge using parameter on curve from 0 to 1 + * (additionally it is neecessary to check orientation of edges and + * create list of reversed edges if it is needed) and sets numbers + * of segments between given points (default values are equals 1) + */ + void SetPoints(in SMESH::double_array listParams) + raises (SALOME::SALOME_Exception); + void SetNbSegments(in SMESH::long_array listNbSeg) + raises (SALOME::SALOME_Exception); + + /*! + * Returns list of point's parameters + */ + SMESH::double_array GetPoints(); + + /*! + * Returns list of numbers of segments + */ + SMESH::long_array GetNbSegments(); + + /*! + * Set list of edges to reverse + */ + void SetReversedEdges( in SMESH::long_array list ); + + /*! + * Returns list of edges to reverse + */ + SMESH::long_array GetReversedEdges(); + + /*! + * Set entry of the main object + */ + void SetObjectEntry( in string entry ); + + /*! + * Get the entry of the main object + */ + string GetObjectEntry(); + }; + + /*! * StdMeshers_MaxElementVolume: interface of "Max. Hexahedron or Tetrahedron Volume" hypothesis */ @@ -344,16 +480,6 @@ module StdMeshers { }; - /*! - * StdMeshers_TrianglePreference: interface of "TrianglePreference" hypothesis. - * This hypothesis is used by StdMeshers_Quadrangle_2D algorithm. - * Presence of this hypothesis forces construction of triangles in the refinement - * area if the number of nodes on opposite edges is not the same. - */ - interface StdMeshers_TrianglePreference : SMESH::SMESH_Hypothesis - { - }; - /*! * StdMeshers_QuadraticMesh: interface of "QuadraticMesh" hypothesis. * This is an auxiliary 1D hypothesis whose presence forces construction @@ -411,6 +537,26 @@ module StdMeshers }; + /*! + * StdMeshers_NumberOfLayers2D: interface of "Nb. Layers" hypothesis. + * This hypothesis is used by "Radial quadrangle" algorithm. + * It specifies number of segments between the internal + * and the external surfaces. + */ + interface StdMeshers_NumberOfLayers2D : StdMeshers_NumberOfLayers + { + }; + + /*! + * StdMeshers_LayerDistribution2D: interface of "Distribution of Layers" hypothesis. + * This hypothesis is used by "Radial quadrangle" algorithm. + * It specifies 1D hypothesis defining distribution of segments between the internal + * and the external surfaces. + */ + interface StdMeshers_LayerDistribution2D : StdMeshers_LayerDistribution + { + }; + /*! * interface of "ProjectionSource1D" hypothesis. * This hypothesis specifies a meshed edge to take a mesh pattern from @@ -594,6 +740,189 @@ module StdMeshers double GetLength(); }; + /*! + * StdMeshers_QuadrangleParams: interface of "Quadrangle Params" hypothesis + */ + enum QuadType + { + QUAD_STANDARD, + QUAD_TRIANGLE_PREF, + QUAD_QUADRANGLE_PREF, + QUAD_QUADRANGLE_PREF_REVERSED, + QUAD_REDUCED, + QUAD_NB_TYPES /* this is not a type of quadrangulation */ + }; + + interface StdMeshers_QuadrangleParams : SMESH::SMESH_Hypothesis + { + /*! + * Set base vertex for triangles + */ + void SetTriaVertex( in long vertID ); + + /*! + * Returns base vertex for triangles + */ + long GetTriaVertex(); + + /*! + * Set entry of the main object + */ + void SetObjectEntry( in string entry ); + + /*! + * Get the entry of the main object + */ + string GetObjectEntry(); + + /*! + * Set the type of quadrangulation + */ + void SetQuadType( in QuadType type ); + + /*! + * Get the type of quadrangulation + */ + QuadType GetQuadType(); + }; + + /*! + * interface of "Source edges" hypothesis. + * This hypothesis specifies groups of edges of other mesh to be imported + * in this mesh + */ + interface StdMeshers_ImportSource1D : SMESH::SMESH_Hypothesis + { + /*! + * Set edges to import from other mesh + */ + void SetSourceEdges(in SMESH::ListOfGroups groups); + SMESH::string_array GetSourceEdges(); + + /*! + * Set to import the whole other mesh or not, and if yes, to + * copy groups of not. By default the mesh is not copied. + */ + void SetCopySourceMesh(in boolean toCopyMesh, in boolean toCopyGroups); + void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups); + }; + + /*! + * interface of "Source faces" hypothesis. + * This hypothesis specifies groups of faces of other mesh to be imported + * in this mesh + */ + interface StdMeshers_ImportSource2D : SMESH::SMESH_Hypothesis + { + /*! + * Set faces to import from other mesh + */ + void SetSourceFaces(in SMESH::ListOfGroups groups); + SMESH::string_array GetSourceFaces(); + + /*! + * Set to import the whole other mesh or not, and if yes, to + * copy groups of not. By default the mesh is not copied. + */ + void SetCopySourceMesh(in boolean toCopyMesh,in boolean toCopyGroups); + void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups); + }; + + /*! + * interface of "Viscous Layers" hypothesis. + * This hypothesis specifies parameters of layers of prisms to build + * near mesh boundary. This hypothesis can be used by several 3D algorithms: + * NETGEN 3D, GHS3D, Hexahedron(i,j,k) + */ + interface StdMeshers_ViscousLayers : SMESH::SMESH_Hypothesis + { + /*! + * Set faces to exclude from treatment + */ + void SetIgnoreFaces(in SMESH::long_array faceIDs) raises (SALOME::SALOME_Exception); + SMESH::long_array GetIgnoreFaces(); + + /*! + * Set total thickness of layers of prisms + */ + void SetTotalThickness(in double thickness) raises (SALOME::SALOME_Exception); + double GetTotalThickness(); + + /*! + * Set number of layers of prisms + */ + void SetNumberLayers(in short nb) raises (SALOME::SALOME_Exception); + short GetNumberLayers(); + + /*! + * Set factor (>1.0) of growth of layer thickness towards inside of mesh + */ + void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception); + double GetStretchFactor(); + }; + + /*! + * interface of "Body fitting Parameters" hypothesis. + * This hypothesis specifies + * - Definition of the Cartesian grid + * - Size threshold + */ + interface StdMeshers_CartesianParameters3D : SMESH::SMESH_Hypothesis + { + /*! + * Set size threshold. A polyhedral cell got by cutting an initial + * hexahedron by geometry boundary is considered small and is removed if + * it's size is \athreshold times less than the size of the initial hexahedron. + * threshold must be > 1.0 + */ + void SetSizeThreshold(in double threshold) raises (SALOME::SALOME_Exception); + double GetSizeThreshold(); + + /*! + * \brief Return true if the grid is defined by spacing functions and + * not by node coordinates in given direction (X==0,...) + */ + boolean IsGridBySpacing(in short axis); + + /*! + * Set coordinates of nodes along an axis (counterd from zero) + */ + void SetGrid(in SMESH::double_array coords, + in short axis) raises (SALOME::SALOME_Exception); + SMESH::double_array GetGrid(in short axis) raises (SALOME::SALOME_Exception); + + /*! + * \brief Set grid spacing along an axis + * \param spaceFunctions - functions defining spacing values at given point on axis + * \param internalPoints - points dividing a grid into parts along an axis + * \param axis - index of an axis counterd from zero, i.e. 0==X, 1==Y, 2==Z + * + * Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of + * the shape to mesh or withing an interval defined by internal points + */ + void SetGridSpacing(in SMESH::string_array spaceFunctions, + in SMESH::double_array internalPoints, + in short axis) raises (SALOME::SALOME_Exception); + + void GetGridSpacing(out SMESH::string_array spaceFunctions, + out SMESH::double_array internalPoints, + in short axis) raises (SALOME::SALOME_Exception); + + /*! + * \brief Computes node coordinates by spacing functions + * \param x0 - lower coordinate + * \param x1 - upper coordinate + * \param spaceFuns - space functions + * \param points - internal points + * \param coords - the computed coordinates + */ + SMESH::double_array ComputeCoordinates(in double x0, + in double x1, + in SMESH::string_array spaceFuns, + in SMESH::double_array points, + in string axisName ) raises (SALOME::SALOME_Exception); + }; + /*! * StdMeshers_SegmentAroundVertex_0D: interface of "SegmentAroundVertex" algorithm */ @@ -664,6 +993,13 @@ module StdMeshers { }; + /*! + * StdMeshers_Projection_1D2D: interface of "Projection 1D-2D" algorithm + */ + interface StdMeshers_Projection_1D2D : SMESH::SMESH_2D_Algo + { + }; + /*! * StdMeshers_Projection_1D: interface of "Projection 1D" algorithm */ @@ -687,6 +1023,32 @@ module StdMeshers { }; + /*! + * StdMeshers_RadialQuadrangle_1D2D: interface of "Radial quadrangle" algorithm + */ + interface StdMeshers_RadialQuadrangle_1D2D : SMESH::SMESH_2D_Algo + { + }; + + /*! + * StdMeshers_Import_1D2D: interface of "Use existing 2D elements" algorithm + */ + interface StdMeshers_Import_1D2D : SMESH::SMESH_2D_Algo + { + }; + /*! + * StdMeshers_Import_1D: interface of "Use existing 1D elements" algorithm + */ + interface StdMeshers_Import_1D : SMESH::SMESH_1D_Algo + { + }; + /*! + * StdMeshers_Cartesian_3D: interface of "Body fitting" algorithm + */ + interface StdMeshers_Cartesian_3D : SMESH::SMESH_3D_Algo + { + }; + }; #endif diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl index 83c1d43d2..8cc7bc864 100644 --- a/idl/SMESH_Filter.idl +++ b/idl/SMESH_Filter.idl @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Filter.idl // Author : Alexey Petrov, OCC // @@ -46,10 +47,16 @@ module SMESH FT_Skew, FT_Area, FT_Volume3D, + FT_MaxElementLength2D, + FT_MaxElementLength3D, FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces, + FT_EqualNodes, // IMPORTANT: when a new item is added, please + FT_EqualEdges, // 1) update getFunctNames() in SMESH_Filter_i.cxx: line 3910 + FT_EqualFaces, // 2) update fixFunctorType() in SMESH_2smeshpy.cxx: line 234 + FT_EqualVolumes, FT_MultiConnection, FT_MultiConnection2D, FT_Length, @@ -61,9 +68,15 @@ module SMESH FT_LyingOnGeom, FT_RangeOfIds, FT_BadOrientedVolume, + FT_BareBorderVolume, + FT_BareBorderFace, + FT_OverConstrainedVolume, + FT_OverConstrainedFace, FT_LinearOrQuadratic, FT_GroupColor, FT_ElemGeomType, + FT_CoplanarFaces, + FT_BallDiameter, FT_LessThan, FT_MoreThan, FT_EqualTo, @@ -73,6 +86,18 @@ module SMESH FT_Undefined }; + /*! + * Parameters of a reclangle of histogram + */ + struct HistogramRectangle + { + long nbEvents; + double min; + double max; + }; + typedef sequence Histogram; + + /*! * Base interface for all functors ( i.e. numerical functors and predicates ) */ @@ -83,8 +108,6 @@ module SMESH ElementType GetElementType(); }; - - /*! * Numerical functors are intended for calculating value by Id of mesh entity */ @@ -92,6 +115,8 @@ module SMESH { double GetValue( in long theElementId ); + Histogram GetHistogram( in short nbIntervals ); + /*! * Set precision for calculation. It is a position after point which is * used to functor value after calculation. @@ -107,6 +132,8 @@ module SMESH interface Skew : NumericalFunctor{}; interface Area : NumericalFunctor{}; interface Volume3D : NumericalFunctor{}; + interface MaxElementLength2D : NumericalFunctor{}; + interface MaxElementLength3D : NumericalFunctor{}; interface Length : NumericalFunctor{}; interface Length2D : NumericalFunctor { @@ -130,7 +157,9 @@ module SMESH typedef sequence Values; Values GetValues(); }; + interface BallDiameter : NumericalFunctor{}; + /*! * Predicates are intended for verification of criteria, * must return bool value by mesh id @@ -147,6 +176,54 @@ module SMESH */ interface BadOrientedVolume: Predicate {}; + /*! + * Logical functor (predicate) "Volumes with bare border". + * Verify whether a mesh volume has a free facet without a mesh face on it + */ + interface BareBorderVolume: Predicate {}; + /*! + * Logical functor (predicate) "Faces with bare border". + * Verify whether a mesh face has a side not shared with another face + * and without a mesh edge on it + */ + interface BareBorderFace: Predicate {}; + + /*! + * Logical functor (predicate) "Over-constrained Volume" + * Verify whether a mesh volume has only one facet shared with other volumes + */ + interface OverConstrainedVolume: Predicate {}; + /*! + * Logical functor (predicate) "Over-constrained Face". + * Verify whether a mesh face has only one border shared with other faces + */ + interface OverConstrainedFace: Predicate {}; + + /*! + * Logical functor (predicate) "Equal Nodes". + * Verify whether there is another mesh node with same coordinates + */ + interface EqualNodes: Predicate + { + void SetTolerance( in double theToler ); + double GetTolerance(); + }; + /*! + * Logical functor (predicate) "Equal Edges". + * Verify whether there is another mesh edge basing on the same nodes + */ + interface EqualEdges: Predicate {}; + /*! + * Logical functor (predicate) "Equal Faces". + * Verify whether there is another mesh face basing on the same nodes + */ + interface EqualFaces: Predicate {}; + /*! + * Logical functor (predicate) "Equal Volumes". + * Verify whether there is another mesh volumes basing on the same nodes + */ + interface EqualVolumes: Predicate {}; + /*! * Logical functor (predicate) "Belong To Geometry". * Verify whether mesh element or node belong to pointed Geom Object @@ -345,6 +422,16 @@ module SMESH void SetGeometryType( in GeometryType theType ); }; + /*! + * Functor "Coplanar faces" + * Returns true if a mesh face is a coplanar neighbour to a given one. It checks + * if normal of a face has angle with the threshold face less than a tolerance. + */ + interface CoplanarFaces : Predicate{ + void SetFace ( in long theFaceID ); + void SetTolerance( in double theToler ); + }; + /*! * Filter */ @@ -359,13 +446,13 @@ module SMESH * BinaryOp - binary logical operation FT_LogicalAND, FT_LogicalOR or * (FT_Undefined must be for the last criterion) * ThresholdStr - Threshold value defined as string. Used for: - * 1. Diaposon of identifiers. Example: "1,2,3,5-10,12,27-29" + * 1. Diapason of identifiers. Example: "1,2,3,5-10,12,27-29" * 2. BelongToGeom predicate for storing name of shape * 3. GroupColor predicate for storing group color "0.2;0;0.5" * ThresholdID - One more threshold value defined as string. Used for: * 1. BelongToGeom predicate for storing id of shape * Tolerance - Tolerance is used for comparators (EqualTo comparision) and for - * "Belong to plane" and "Belong to cylinder" predicates + * "Belong to plane", "Belong to cylinder" etc predicates * TypeOfElement - type of element SMESH::NODE, SMESH::FACE (used by BelongToGeom predicate only) * Precision - Precision of numerical functors */ @@ -449,10 +536,13 @@ module SMESH Skew CreateSkew(); Area CreateArea(); Volume3D CreateVolume3D(); + MaxElementLength2D CreateMaxElementLength2D(); + MaxElementLength3D CreateMaxElementLength3D(); Length CreateLength(); Length2D CreateLength2D(); MultiConnection CreateMultiConnection(); MultiConnection2D CreateMultiConnection2D(); + BallDiameter CreateBallDiameter(); /*! * Create logical functors ( predicates ) @@ -469,13 +559,23 @@ module SMESH FreeNodes CreateFreeNodes(); FreeFaces CreateFreeFaces(); + EqualNodes CreateEqualNodes(); + EqualEdges CreateEqualEdges(); + EqualFaces CreateEqualFaces(); + EqualVolumes CreateEqualVolumes(); + RangeOfIds CreateRangeOfIds(); BadOrientedVolume CreateBadOrientedVolume(); + BareBorderVolume CreateBareBorderVolume(); + BareBorderFace CreateBareBorderFace(); + OverConstrainedVolume CreateOverConstrainedVolume(); + OverConstrainedFace CreateOverConstrainedFace(); LinearOrQuadratic CreateLinearOrQuadratic(); GroupColor CreateGroupColor(); ElemGeomType CreateElemGeomType(); + CoplanarFaces CreateCoplanarFaces(); /*! * Create comparators ( predicates ) diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 7cc93177b..f6e9f89ad 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -1,23 +1,23 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File : SMESH_Gen.idl // Author : Paul RASCLE, EDF @@ -41,6 +41,7 @@ module SMESH interface FilterManager; interface SMESH_Pattern; + interface Measurements; /*! * Tags definition @@ -69,12 +70,14 @@ module SMESH const long Tag_EdgeGroups = 12; const long Tag_FaceGroups = 13; const long Tag_VolumeGroups = 14; - const long Tag_LastGroup = 14; + const long Tag_0DElementsGroups = 15; + const long Tag_BallElementsGroups = 16; + const long Tag_LastGroup = 16; /*! * Hypothesis definintion error */ - struct AlgoStateError + struct AlgoStateError { Hypothesis_Status state; string algoName; @@ -96,20 +99,22 @@ module SMESH COMPERR_EXCEPTION , // other exception raised COMPERR_MEMORY_PB , // memory allocation problem COMPERR_ALGO_FAILED , // computation failed - COMPERR_BAD_SHAPE // bad geometry + COMPERR_BAD_SHAPE , // bad geometry + COMPERR_WARNING , // algo reports error but sub-mesh is computed anyway + COMPERR_CANCELED // compute canceled }; 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 + short subShapeID; // id of sub-shape of a shape to mesh boolean hasBadMesh; // there are elements preventing computation available for visualization }; typedef sequence compute_error_array; - interface SMESH_Gen : Engines::Component, SALOMEDS::Driver + interface SMESH_Gen : Engines::EngineComponent, SALOMEDS::Driver { //GEOM::GEOM_Gen SetGeomEngine( in string containerLoc ); void SetGeomEngine( in GEOM::GEOM_Gen geomcompo ); @@ -118,6 +123,8 @@ module SMESH SMESH_Pattern GetPattern(); + Measurements CreateMeasurements(); + /*! Set the current mode */ @@ -146,7 +153,7 @@ module SMESH * Algorithms are 1D, 2D or 3D. */ SMESH_Hypothesis CreateHypothesis( in string theHypName, - in string theLibName ) + in string theLibName ) raises ( SALOME::SALOME_Exception ); /*! @@ -177,7 +184,7 @@ module SMESH * Set the object name */ void SetName( in string theObjectIOR, - in string theObjectName ) + in string theObjectName ) raises ( SALOME::SALOME_Exception ); /*! @@ -189,13 +196,13 @@ module SMESH */ SMESH_Mesh CreateMesh( in GEOM::GEOM_Object theObject ) raises ( SALOME::SALOME_Exception ); - + /*! * Create an empty mesh object */ SMESH_Mesh CreateEmptyMesh() raises ( SALOME::SALOME_Exception ); - + /*! * Create Mesh object importing data from given UNV file * (UNV supported version is I-DEAS 10) @@ -207,7 +214,14 @@ module SMESH * Create Mesh object(s) importing data from given MED file */ mesh_array CreateMeshesFromMED( in string theFileName, - out SMESH::DriverMED_ReadStatus theStatus ) + out SMESH::DriverMED_ReadStatus theStatus ) + raises ( SALOME::SALOME_Exception ); + + /*! + * Create Mesh object(s) importing data from given MED file + */ + mesh_array CreateMeshesFromSAUV( in string theFileName, + out SMESH::DriverMED_ReadStatus theStatus ) raises ( SALOME::SALOME_Exception ); /*! @@ -217,43 +231,98 @@ module SMESH raises ( SALOME::SALOME_Exception ); /*! - * Create a Mesh object, without a geometry shape reference + * Create Mesh object(s) importing data from given CGNS file + */ + mesh_array CreateMeshesFromCGNS( in string theFileName, + out SMESH::DriverMED_ReadStatus theStatus ) + raises ( SALOME::SALOME_Exception ); + + /*! + * Create a mesh by copying a part of another mesh + * \param meshPart - a part of mesh to copy + * \param meshName - a name of the new mesh + * \param toCopyGroups - to create in the new mesh groups + * the copied elements belongs to + * \param toKeepIDs - to preserve IDs of the copied elements or not + */ + SMESH_Mesh CopyMesh(in SMESH_IDSource meshPart, + in string meshName, + in boolean toCopyGroups, + in boolean toKeepIDs) + raises ( SALOME::SALOME_Exception ); + + /*! + * Concatenate the given meshes into one mesh. + * Union groups with the same name and type if + * theUniteIdenticalGroups flag is true. + * Merge coincident nodes and elements if + * theMergeNodesAndElements flag is true. + */ + SMESH_Mesh Concatenate(in mesh_array theMeshesArray, + in boolean theUniteIdenticalGroups, + in boolean theMergeNodesAndElements, + in double theMergeTolerance) + raises ( SALOME::SALOME_Exception ); + + /*! + * Concatenate the given meshes into one mesh. + * Union groups with the same name and type if + * theUniteIdenticalGroups flag is true. + * Merge coincident nodes and elements if + * theMergeNodesAndElements flag is true. + * Create the groups of all elements from initial meshes. */ -// SMESH_Mesh NewEmpty() -// raises ( SALOME::SALOME_Exception ); + SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray, + in boolean theUniteIdenticalGroups, + in boolean theMergeNodesAndElements, + in double theMergeTolerance) + raises ( SALOME::SALOME_Exception ); /*! - * Mesh a subShape. - * First, verify list of hypothesis associated with the subShape, + * Mesh a subShape. + * First, verify list of hypothesis associated with the Sub-shape, * return NOK if hypothesis are not sufficient */ - boolean Compute( in SMESH_Mesh theMesh, - in GEOM::GEOM_Object theSubObject ) + boolean Compute( in SMESH_Mesh theMesh, + in GEOM::GEOM_Object theSubObject ) raises ( SALOME::SALOME_Exception ); + /*! + * Cancel a computation. + */ + void CancelCompute( in SMESH_Mesh theMesh, + in GEOM::GEOM_Object theSubObject ); + /*! * Return true if hypotheses are defined well */ - boolean IsReadyToCompute( in SMESH_Mesh theMesh, - in GEOM::GEOM_Object theSubObject ) + boolean IsReadyToCompute( in SMESH_Mesh theMesh, + in GEOM::GEOM_Object theSubObject ) + raises ( SALOME::SALOME_Exception ); + + /*! + * Evaluates size of prospective mesh on a shape + */ + long_array Evaluate(in SMESH_Mesh theMesh, + in GEOM::GEOM_Object theSubObject) raises ( SALOME::SALOME_Exception ); /*! * Calculate Mesh as preview till indicated dimension - * First, verify list of hypothesis associated with the subShape. + * First, verify list of hypothesis associated with the Sub-shape. * Return mesh preview structure */ - MeshPreviewStruct Precompute( in SMESH_Mesh theMesh, - in GEOM::GEOM_Object theSubObject, - in Dimension theDimension, - inout long_array theShapesId ) + MeshPreviewStruct Precompute( in SMESH_Mesh theMesh, + in GEOM::GEOM_Object theSubObject, + in Dimension theDimension, + inout long_array theShapesId ) raises ( SALOME::SALOME_Exception ); /*! * Return errors of hypotheses definintion * algo_error_array is empty if everything is OK */ - algo_error_array GetAlgoState( in SMESH_Mesh theMesh, + algo_error_array GetAlgoState( in SMESH_Mesh theMesh, in GEOM::GEOM_Object theSubObject ) raises ( SALOME::SALOME_Exception ); @@ -261,19 +330,19 @@ module SMESH * Return errors of mesh computation * compute_error_array is empty if everything is OK */ - compute_error_array GetComputeErrors( in SMESH_Mesh theMesh, + compute_error_array GetComputeErrors( in SMESH_Mesh theMesh, in GEOM::GEOM_Object theSubObject ) raises ( SALOME::SALOME_Exception ); /*! - * Return mesh elements preventing computation of a subshape + * Return mesh elements preventing computation of a sub-shape */ MeshPreviewStruct GetBadInputElements( in SMESH_Mesh theMesh, in short theSubShapeID ) raises ( SALOME::SALOME_Exception ); /*! - * Return indeces of faces, edges and vertices of given subshapes + * Return indeces of faces, edges and vertices of given sub-shapes * within theMainObject */ long_array GetSubShapesId( in GEOM::GEOM_Object theMainObject, @@ -282,7 +351,7 @@ module SMESH /*! * Return geometrical object the given element is built on. - * The returned geometrical object, if not nil, is either found in the + * The returned geometrical object, if not nil, is either found in the * study or is published by this method with the given name */ GEOM::GEOM_Object GetGeometryByMeshElement( in SMESH_Mesh theMesh, @@ -295,42 +364,25 @@ module SMESH * The returned geometrical object not published in study by this method. */ GEOM::GEOM_Object FindGeometryByMeshElement( in SMESH_Mesh theMesh, - in long theElementID) + 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. + * \brief Return id of object, registered in current study context + * + * Can be used to check if the object was created in the same container, as this engine. */ - SMESH_Mesh Concatenate(in mesh_array theMeshesArray, - in boolean theUniteIdenticalGroups, - in boolean theMergeNodesAndElements, - in double theMergeTolerance) - raises ( SALOME::SALOME_Exception ); + long GetObjectId(in Object theObject); /*! - * Concatenate the given meshes into one mesh. - * Union groups with the same name and type if - * theUniteIdenticalGroups flag is true. - * Merge coincident nodes and elements if - * theMergeNodesAndElements flag is true. - * Create the groups of all elements from initial meshes. + * \brief Get MED version of the file by its name. */ - SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray, - in boolean theUniteIdenticalGroups, - in boolean theMergeNodesAndElements, - in double theMergeTolerance) - raises ( SALOME::SALOME_Exception ); + boolean GetMEDVersion(in string theFileName, out MED_VERSION theVersion); /*! - * \brief Return id of object, registered in current study context - * - * Can be used to check if the object was created in the same container, as this engine. + * \brief Get names of meshes defined in file with the specified name. */ - long GetObjectId(in Object theObject); + string_array GetMeshNames(in string theFileName); }; }; diff --git a/idl/SMESH_Group.idl b/idl/SMESH_Group.idl index aa9cee125..d00fe0e9d 100644 --- a/idl/SMESH_Group.idl +++ b/idl/SMESH_Group.idl @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Group.idl // Author : Sergey ANIKIN, OCC // $Header$ @@ -35,6 +36,7 @@ module SMESH { interface Predicate; + interface Filter; /*! * SMESH_Group: base interface of group object @@ -82,9 +84,21 @@ module SMESH long_array GetListOfID(); /*! - * Returns the mesh object this group belongs to + * Get the number of nodes of cells included to the group + * For a nodal group returns the same value as Size() function + */ + long GetNumberOfNodes(); + + /*! + * Get IDs of nodes of cells included to the group + * For a nodal group returns result of GetListOfID() function + */ + long_array GetNodeIDs(); + + /*! + * Return true if GetNumberOfNodes() won't take a long time for computation */ - SMESH_Mesh GetMesh(); + boolean IsNodeInfoAvailable(); /*! * Sets group color @@ -110,7 +124,7 @@ module SMESH }; /*! - * SMESH_Group: interface of group object + * SMESH_Group: interface of a standalone group object */ interface SMESH_Group : SMESH_GroupBase { @@ -120,26 +134,46 @@ module SMESH void Clear(); /*! - * Adds elements to the group + * Adds elements or nodes with specified identifiers to the group */ long Add( in long_array elem_ids ); + /*! + * Adds elements or nodes that match specified predicate to the group + */ long AddByPredicate( in Predicate thePredicate ); + /*! + * Add all elements or nodes from the specified source to the group + */ + long AddFrom( in SMESH_IDSource theSource ); /*! - * Removes elements from the group + * Removes elements or nodes with specified identifiers from the group */ long Remove( in long_array elem_ids ); + /*! + * Removes elements or nodes that match specified predicate from the group + */ long RemoveByPredicate( in Predicate thePredicate ); }; + /*! - * SMESH_Group: interface of group object linked to geometry + * SMESH_GroupOnGeom: interface of a group object linked to geometry */ interface SMESH_GroupOnGeom : SMESH_GroupBase { GEOM::GEOM_Object GetShape(); }; + /*! + * SMESH_GroupOnFilter: interface of a group object defined by filter + */ + interface SMESH_GroupOnFilter : SMESH_GroupBase + { + void SetFilter( in Filter theFilter); + Filter GetFilter(); + }; + }; diff --git a/idl/SMESH_Hypothesis.idl b/idl/SMESH_Hypothesis.idl index 56ae48b0c..8d18789ba 100644 --- a/idl/SMESH_Hypothesis.idl +++ b/idl/SMESH_Hypothesis.idl @@ -1,27 +1,27 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Hypothesis.idl // Author : Paul RASCLE, EDF -// $Header$ // #ifndef _SMESH_HYPOTHESIS_IDL_ #define _SMESH_HYPOTHESIS_IDL_ @@ -59,6 +59,22 @@ module SMESH */ long GetId(); + /*! + * Set the variable parameter + * \param parameter is a string containing the notebook variable + * used for Hypothesis creation + * \param method is a name of Hypothesis method setting this parameter + * + * This method must be called before calling method() + */ + void SetVarParameter (in string parameter, in string method); + + /*! + * Return the variable parameter used for Hypothesis creation by name of method + * setting this parameter + */ + string GetVarParameter (in string methodName); + /*! * Set list of parameters * \param theParameters is a string containing the notebook variables separated by ":" symbol, diff --git a/idl/SMESH_Measurements.idl b/idl/SMESH_Measurements.idl new file mode 100644 index 000000000..6d8d7f545 --- /dev/null +++ b/idl/SMESH_Measurements.idl @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_Measurements.idl +// Author : Pavel Telkov, OCC +// +#ifndef _SMESH_MEASUREMENTS_IDL_ +#define _SMESH_MEASUREMENTS_IDL_ + +#include "SALOME_GenericObj.idl" +#include "SMESH_Mesh.idl" + +module SMESH +{ + + /* + * Measure component + */ + struct Measure { + double minX, minY, minZ; + double maxX, maxY, maxZ; + long node1, node2; + long elem1, elem2; + double value; + }; + + interface Measurements: SALOME::GenericObj + { + /*! + * minimal distance between two entities + */ + Measure MinDistance(in SMESH_IDSource source1, + in SMESH_IDSource source2); + + /*! + * common bounding box of entities + */ + Measure BoundingBox(in ListOfIDSources sources); + }; +}; + +#endif diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index fa5180a24..409bb4e6e 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Mesh.idl // Author : Paul RASCLE, EDF // - #ifndef _SMESH_MESH_IDL_ #define _SMESH_MESH_IDL_ @@ -37,6 +37,8 @@ module SMESH typedef sequence ListOfHypothesis; interface SMESH_GroupBase; typedef sequence ListOfGroups; + interface SMESH_IDSource; + typedef sequence ListOfIDSources; typedef sequence double_array ; typedef sequence long_array ; @@ -68,7 +70,12 @@ module SMESH ADD_QUADTETRAHEDRON, ADD_QUADPYRAMID, ADD_QUADPENTAHEDRON, - ADD_QUADHEXAHEDRON + ADD_QUADHEXAHEDRON, + ADD_ELEM0D, + ADD_BIQUAD_QUADRANGLE, + ADD_TRIQUAD_HEXA, + ADD_HEXAGONAL_PRISM, + ADD_BALL }; struct log_block @@ -112,8 +119,11 @@ module SMESH NODE, EDGE, FACE, - VOLUME + VOLUME, + ELEM0D, + BALL }; + typedef sequence array_of_ElementType ; /*! * Enumeration for element geometry type, like in SMDS @@ -123,13 +133,15 @@ module SMESH Geom_POINT, Geom_EDGE, Geom_TRIANGLE, - Geom_QUADRANGLE, - Geom_POLYGON, + Geom_QUADRANGLE, // when a new GeometryType is added, please + Geom_POLYGON, // update a corresponding list in SMESH_2smeshpy.cxx, ln 665 Geom_TETRA, Geom_PYRAMID, Geom_HEXA, Geom_PENTA, - Geom_POLYHEDRA + Geom_HEXAGONAL_PRISM, + Geom_POLYHEDRA, + Geom_BALL }; /*! @@ -141,6 +153,41 @@ module SMESH ORDER_QUADRATIC /*! entities of 2nd order */ }; + + /*! + * Enumeration of entity type used in mesh info array, + * it should be synchronised with enum SMDSAbs_EntityType + */ + enum EntityType + { + Entity_Node, + Entity_0D, + Entity_Edge, + Entity_Quad_Edge, + Entity_Triangle, + Entity_Quad_Triangle, + Entity_Quadrangle, + Entity_Quad_Quadrangle, + Entity_BiQuad_Quadrangle, + Entity_Polygon, + Entity_Quad_Polygon, + Entity_Tetra, + Entity_Quad_Tetra, + Entity_Pyramid, + Entity_Quad_Pyramid, + Entity_Hexa, + Entity_Quad_Hexa, + Entity_TriQuad_Hexa, + Entity_Penta, + Entity_Quad_Penta, + Entity_Hexagonal_Prism, + Entity_Polyhedra, + Entity_Quad_Polyhedra, + Entity_Ball, + Entity_Last + }; + + /*! * Enumeration for hypothesis status (used by AddHypothesis() and RemoveHypothesis() methods) */ @@ -158,7 +205,7 @@ module SMESH HYP_NOTCONFORM, // not conform mesh is produced appling a hypothesis HYP_ALREADY_EXIST,// such hypothesis already exist HYP_BAD_DIM, // bad dimension - HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its subshape, nor a group + HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group HYP_BAD_GEOMETRY, // geometry mismatches algorithm's expectation HYP_NEED_SHAPE // algorithm can work on shape only }; @@ -212,18 +259,49 @@ module SMESH long_array elementConnectivities; types_array elementTypes; }; + interface SMESH_Mesh; + interface SMESH_IDSource { /*! * Returns a sequence of all element IDs */ long_array GetIDs(); + + /*! + * Returns statistic of mesh elements + * @return array of number enityties by index of EntityType + */ + long_array GetMeshInfo(); + + /*! + * Returns types of elements it contains. + * It's empty if the SMESH_IDSource contains no IDs + */ + array_of_ElementType GetTypes(); + + /*! + * Returns the mesh + */ + SMESH_Mesh GetMesh(); + + /*! + * Returns false if GetMeshInfo() returns incorrect information that may + * happen if mesh data is not yet fully loaded from the file of study. + */ + boolean IsMeshInfoCorrect(); }; interface SMESH_Group; interface SMESH_GroupOnGeom; + interface Filter; + interface SMESH_GroupOnFilter; interface SMESH_subMesh; interface SMESH_MeshEditor; + + typedef sequence submesh_array; + typedef sequence submesh_array_array; + interface SMESH_Mesh : SALOME::GenericObj, SMESH_IDSource { /*! @@ -239,12 +317,30 @@ module SMESH GEOM::GEOM_Object GetShapeToMesh() raises (SALOME::SALOME_Exception); + /*! + * Return false if the mesh is not yet fully loaded from the study file + */ + boolean IsLoaded() + raises (SALOME::SALOME_Exception); + + /*! + * Load full mesh data from the study file + */ + void Load() + raises (SALOME::SALOME_Exception); + /*! * Remove all nodes and elements */ void Clear() raises (SALOME::SALOME_Exception); + /*! + * Get the list of sub-meshes existing in the mesh + */ + submesh_array GetSubMeshes() + raises (SALOME::SALOME_Exception); + /*! * Remove all nodes and elements of submesh */ @@ -252,9 +348,9 @@ module SMESH raises (SALOME::SALOME_Exception); /*! - * Get the subMesh object associated to a subShape. The subMesh object + * Get the subMesh object associated to a Sub-shape. The subMesh object * gives access to nodes and elements IDs. - * SubMesh will be used instead of SubShape in a next idl version to + * SubMesh will be used instead of Sub-shape in a next idl version to * adress a specific subMesh... */ SMESH_subMesh GetSubMesh(in GEOM::GEOM_Object aSubObject, in string name) @@ -271,15 +367,23 @@ module SMESH * Create a group */ SMESH_Group CreateGroup( in ElementType elem_type, - in string name ) + in string name ) + raises (SALOME::SALOME_Exception); + + /*! + * Create a group from geometry + */ + SMESH_GroupOnGeom CreateGroupFromGEOM( in ElementType elemType, + in string name, + in GEOM::GEOM_Object geomObject ) raises (SALOME::SALOME_Exception); /*! - * Create a group from geometry group + * Create a group from filter */ - SMESH_GroupOnGeom CreateGroupFromGEOM( in ElementType elem_type, - in string name, - in GEOM::GEOM_Object theGeomObject ) + SMESH_GroupOnFilter CreateGroupFromFilter( in ElementType elemType, + in string name, + in SMESH::Filter filter ) raises (SALOME::SALOME_Exception); /*! @@ -376,26 +480,26 @@ module SMESH raises (SALOME::SALOME_Exception); /*! - * Convert group on geometry into standalone group + * Convert group on geometry or on filter into standalone group */ - SMESH_Group ConvertToStandalone( in SMESH_GroupOnGeom theGeomGroup ) + SMESH_Group ConvertToStandalone( in SMESH_GroupBase theGroupOn ) raises (SALOME::SALOME_Exception); /*! - * Add hypothesis to the mesh, under a particular subShape + * Add hypothesis to the mesh, under a particular Sub-shape * (or the main shape itself) * The Add method is only used to prepare the build of the mesh and store * the algorithms and associated parameters. * Actual job of mesh the shape is done by MESH_Gen. * @params - * - aSubShape : subShape obtained by a shape explode in GEOM + * - aSubShape : sub-shape obtained by a shape explode in GEOM * (or main shape) * - anHyp : hypothesis object * @return - * - OK if the hypothesis is compatible with the subShape - * (and all previous hypothesis on the subShape) - * - NOK if the hypothesis is not compatible with the subShape - * (or one previous hypothesis on the subShape) + * - OK if the hypothesis is compatible with the sub-shape + * (and all previous hypothesis on the sub-shape) + * - NOK if the hypothesis is not compatible with the sub-shape + * (or one previous hypothesis on the sub-shape) * raises exception if hypothesis has not been created */ Hypothesis_Status AddHypothesis(in GEOM::GEOM_Object aSubObject, @@ -415,7 +519,7 @@ module SMESH // raises (SALOME::SALOME_Exception); /*! - * Get the list of hypothesis added on a subShape + * Get the list of hypothesis added on a sub-shape */ ListOfHypothesis GetHypothesisList(in GEOM::GEOM_Object aSubObject) raises (SALOME::SALOME_Exception); @@ -477,6 +581,13 @@ module SMESH SMESH_MeshEditor GetMeshEditPreviewer() raises (SALOME::SALOME_Exception); + /*! + * Return true if the mesh has been edited since a total re-compute + * and those modifications may prevent successful partial re-compute + */ + boolean HasModificationsToDiscard() + raises (SALOME::SALOME_Exception); + /*! Check group names for duplications. * Consider maximum group name length stored in MED file. */ @@ -485,22 +596,56 @@ module SMESH /*! * Export Mesh to different MED Formats * @params + * - file : name of the MED file * - auto_groups : boolean parameter for creating/not creating * the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; * the typical use is auto_groups=false. - * - theVersion : define the version of format of MED file, that will be created + * - version : define the version of format of MED file, that will be created + * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists + */ + void ExportToMEDX( in string file, + in boolean auto_groups, + in MED_VERSION version, + in boolean overwrite ) raises (SALOME::SALOME_Exception); + + /*! + * Export a part of Mesh into a MED file + * @params + * - meshPart : a part of mesh to store + * - file : name of the MED file + * - version : define the version of format of MED file, that will be created + * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists + */ + void ExportPartToMED( in SMESH_IDSource meshPart, + in string file, + in boolean auto_groups, + in MED_VERSION version, + in boolean overwrite ) raises (SALOME::SALOME_Exception); + + /*! + * Export Mesh to different MED Formats + * Works, just the same as ExportToMEDX, with overwrite parameter equal to true. + * The method is kept in order to support old functionality */ void ExportToMED( in string file, in boolean auto_groups, in MED_VERSION theVersion ) raises (SALOME::SALOME_Exception); /*! * Export Mesh to MED_V2_1 MED format - * Works, just the same as ExportToMED, with MED_VERSION parameter equal to MED_V2_1. + * Works, just the same as ExportToMEDX with MED_VERSION parameter equal to MED_V2_1 + * and overwrite parameter equal to true * The method is kept in order to support old functionality */ void ExportMED( in string file, in boolean auto_groups ) raises (SALOME::SALOME_Exception); + /*! + * Export Mesh to SAUV formatted file + * Write a temporary med file and use med2sauv + */ + void ExportSAUV( in string file, in boolean auto_groups ) + raises (SALOME::SALOME_Exception); + /*! * Return string representation of a MED file version comprising nbDigits */ @@ -510,12 +655,20 @@ module SMESH * Export Mesh to DAT, UNV and STL Formats * (UNV supported version is I-DEAS 10) */ - void ExportDAT( in string file ) - raises (SALOME::SALOME_Exception); - void ExportUNV( in string file ) - raises (SALOME::SALOME_Exception); - void ExportSTL( in string file, in boolean isascii ) - raises (SALOME::SALOME_Exception); + void ExportDAT( in string file ) raises (SALOME::SALOME_Exception); + void ExportUNV( in string file ) raises (SALOME::SALOME_Exception); + void ExportSTL( in string file, + in boolean isascii ) raises (SALOME::SALOME_Exception); + void ExportCGNS( in SMESH_IDSource meshPart, + in string file, + in boolean overwrite ) raises (SALOME::SALOME_Exception); + void ExportPartToDAT( in SMESH_IDSource meshPart, + in string file ) raises (SALOME::SALOME_Exception); + void ExportPartToUNV( in SMESH_IDSource meshPart, + in string file ) raises (SALOME::SALOME_Exception); + void ExportPartToSTL( in SMESH_IDSource meshPart, + in string file, + in boolean isascii ) raises (SALOME::SALOME_Exception); /*! * Get MED Mesh @@ -532,6 +685,12 @@ module SMESH long NbElements() raises (SALOME::SALOME_Exception); + long Nb0DElements() + raises (SALOME::SALOME_Exception); + + long NbBalls() + raises (SALOME::SALOME_Exception); + long NbEdges() raises (SALOME::SALOME_Exception); @@ -556,6 +715,9 @@ module SMESH long NbQuadranglesOfOrder(in ElementOrder order) raises (SALOME::SALOME_Exception); + long NbBiQuadQuadrangles() + raises (SALOME::SALOME_Exception); + long NbPolygons() raises (SALOME::SALOME_Exception); @@ -577,6 +739,9 @@ module SMESH long NbHexasOfOrder(in ElementOrder order) raises (SALOME::SALOME_Exception); + long NbTriQuadraticHexas() + raises (SALOME::SALOME_Exception); + long NbPyramids() raises (SALOME::SALOME_Exception); @@ -589,6 +754,9 @@ module SMESH long NbPrismsOfOrder(in ElementOrder order) raises (SALOME::SALOME_Exception); + long NbHexagonalPrisms() + raises (SALOME::SALOME_Exception); + long NbPolyhedrons() raises (SALOME::SALOME_Exception); @@ -610,6 +778,9 @@ module SMESH ElementType GetElementType( in long id, in boolean iselem ) raises (SALOME::SALOME_Exception); + EntityType GetElementGeomType( in long id ) + raises (SALOME::SALOME_Exception); + long_array GetSubMeshElementsId(in long ShapeID) raises (SALOME::SALOME_Exception); @@ -619,6 +790,22 @@ module SMESH ElementType GetSubMeshElementType(in long ShapeID) raises (SALOME::SALOME_Exception); + + /*! + * Methods to set meshing order of submeshes + */ + + /*! + * \brief Return submesh objects list in meshing order + */ + submesh_array_array GetMeshOrder(); + + /*! + * \brief Set submesh object order + */ + boolean SetMeshOrder(in submesh_array_array theSubMeshArray); + + /*! * Get mesh description */ @@ -699,6 +886,16 @@ module SMESH */ long ElemNbFaces(in long id); + /*! + * Returns nodes of given face (counted from zero) for given volumic element. + */ + long_array GetElemFaceNodes(in long elemId, in short faceIndex); + + /*! + * Returns an element based on all given nodes. + */ + long FindElementByNodes(in long_array nodes); + /*! * Returns true if given element is polygon */ @@ -709,6 +906,11 @@ module SMESH */ boolean IsQuadratic(in long id); + /*! + * Returns diameter of a ball discrete element or zero in case of an invalid \a id + */ + double GetBallDiameter(in long id); + /*! * Returns XYZ coordinates of bary center for given element * as list of double diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index 0a4b5b7cd..561c5b884 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -1,26 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File : SMESH_MeshEditor.idl -// #ifndef _SMESH_MESHEDITOR_IDL_ #define _SMESH_MESHEDITOR_IDL_ @@ -29,21 +28,65 @@ module SMESH { + enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D }; + /*! * This interface makes modifications on the Mesh - removing elements and nodes etc. */ interface NumericalFunctor; interface SMESH_MeshEditor { + /*! + * \brief Wrap a sequence of ids in a SMESH_IDSource + * \param IDsOfElements list of mesh elements identifiers + * \return new ID source object + */ + SMESH_IDSource MakeIDSource(in long_array IDsOfElements, in ElementType type); + + /*! + * \brief Remove mesh elements specified by their identifiers. + * \param IDsOfElements list of mesh elements identifiers + * \return \c true if elements are correctly removed or \c false otherwise + */ boolean RemoveElements(in long_array IDsOfElements); + /*! + * \brief Remove mesh nodes specified by their identifiers. + * \param IDsOfNodes list of mesh nodes identifiers + * \return \c true if nodes are correctly removed or \c false otherwise + */ boolean RemoveNodes(in long_array IDsOfNodes); + /*! + * \brief Remove all orphan nodes. + * \return number of removed nodes + */ + long RemoveOrphanNodes(); + + /*! + * \brief Add a new node. + * \param x X coordinate of new node + * \param y Y coordinate of new node + * \param z Z coordinate of new node + * \return integer identifier of new node + */ long AddNode(in double x, in double y, in double z); /*! - * Create edge, either linear and quadratic (this is determed - * by number of given nodes). + * Create a 0D element on the given node. + * \param IdOfNode Node IDs for creation of element. + */ + long Add0DElement(in long IDOfNode); + + /*! + * Create a ball element on the given node. + * \param IdOfNode Node IDs for creation of element. + */ + long AddBall(in long IDOfNode, in double diameter); + + /*! + * Create an edge, either linear and quadratic (this is determed + * by number of given nodes, two or three). * \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: @@ -139,6 +182,19 @@ module SMESH boolean Reorient(in long_array IDsOfElements); boolean ReorientObject(in SMESH_IDSource theObject); + /*! + * \brief Reorient faces contained in \a the2Dgroup. + * \param the2Dgroup - the mesh or its part to reorient + * \param theDirection - desired direction of normal of \a theFace + * \param theFace - ID of face whose orientation is checked. + * It can be < 1 then \a thePoint is used to find a face. + * \param thePoint - is used to find a face if \a theFace < 1. + * \return number of reoriented elements. + */ + long Reorient2D(in SMESH_IDSource the2Dgroup, + in DirStruct theDirection, + in long theFace, + in PointStruct thePoint) raises (SALOME::SALOME_Exception); /*! * \brief Fuse neighbour triangles into quadrangles. @@ -149,8 +205,8 @@ module SMESH * \return TRUE in case of success, FALSE otherwise. */ boolean TriToQuad (in long_array IDsOfElements, - in NumericalFunctor Criterion, - in double MaxAngle); + in NumericalFunctor Criterion, + in double MaxAngle); /*! * \brief Fuse neighbour triangles into quadrangles. @@ -158,8 +214,8 @@ module SMESH * Behaves like the above method, taking list of elements from \a theObject */ boolean TriToQuadObject (in SMESH_IDSource theObject, - in NumericalFunctor Criterion, - in double MaxAngle); + in NumericalFunctor Criterion, + in double MaxAngle); /*! * \brief Split quadrangles into triangles. @@ -168,7 +224,7 @@ module SMESH * \return TRUE in case of success, FALSE otherwise. */ boolean QuadToTri (in long_array IDsOfElements, - in NumericalFunctor Criterion); + in NumericalFunctor Criterion); /*! * \brief Split quadrangles into triangles. @@ -176,7 +232,7 @@ module SMESH * Behaves like the above method, taking list of elements from \a theObject */ boolean QuadToTriObject (in SMESH_IDSource theObject, - in NumericalFunctor Criterion); + in NumericalFunctor Criterion); /*! * \brief Split quadrangles into triangles. @@ -185,7 +241,7 @@ module SMESH * \return TRUE in case of success, FALSE otherwise. */ boolean SplitQuad (in long_array IDsOfElements, - in boolean Diag13); + in boolean Diag13); /*! * \brief Split quadrangles into triangles. @@ -193,7 +249,7 @@ module SMESH * Behaves like the above method, taking list of elements from \a theObject */ boolean SplitQuadObject (in SMESH_IDSource theObject, - in boolean Diag13); + in boolean Diag13); /*! * Find better splitting of the given quadrangle. @@ -203,7 +259,19 @@ module SMESH * diagonal is better, 0 if error occurs. */ long BestSplit (in long IDOfQuad, - in NumericalFunctor Criterion); + in NumericalFunctor Criterion); + + /*! + * \brief Split volumic elements into tetrahedrons + * \param elems - elements to split + * \param methodFlags - flags passing splitting method: + * 1 - split the hexahedron into 5 tetrahedrons + * 2 - split the hexahedron into 6 tetrahedrons + * 3 - split the hexahedron into 24 tetrahedrons + */ + void SplitVolumesIntoTetra(in SMESH_IDSource elems, in short methodFlags) + raises (SALOME::SALOME_Exception); + enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH }; @@ -214,10 +282,10 @@ module SMESH in Smooth_Method Method); boolean SmoothObject(in SMESH_IDSource theObject, - in long_array IDsOfFixedNodes, - in long MaxNbOfIterations, - in double MaxAspectRatio, - in Smooth_Method Method); + in long_array IDsOfFixedNodes, + in long MaxNbOfIterations, + in double MaxAspectRatio, + in Smooth_Method Method); boolean SmoothParametric(in long_array IDsOfElements, in long_array IDsOfFixedNodes, @@ -235,6 +303,13 @@ module SMESH boolean ConvertFromQuadratic(); + void ConvertToQuadraticObject(in boolean theForce3d, + in SMESH_IDSource theObject) + raises (SALOME::SALOME_Exception); + + void ConvertFromQuadraticObject(in SMESH_IDSource theObject) + raises (SALOME::SALOME_Exception); + void RenumberNodes(); void RenumberElements(); @@ -268,10 +343,10 @@ module SMESH * \param NbOfSteps - number of elements to generate from one element */ void RotationSweepObject(in SMESH_IDSource theObject, - in AxisStruct Axix, - in double AngleInRadians, - in long NbOfSteps, - in double Tolerance); + in AxisStruct Axix, + in double AngleInRadians, + in long NbOfSteps, + in double Tolerance); /*! * \brief Same as previous but additionally create groups of elements * generated from elements belonging to preexisting groups @@ -289,19 +364,19 @@ module SMESH * \param NbOfSteps - number of elements to generate from one element */ void RotationSweepObject1D(in SMESH_IDSource theObject, - in AxisStruct Axix, - in double AngleInRadians, - in long NbOfSteps, - in double Tolerance); + in AxisStruct Axix, + in double AngleInRadians, + in long NbOfSteps, + in double Tolerance); /*! * \brief Same as previous but additionally create groups of elements * generated from elements belonging to preexisting groups */ ListOfGroups RotationSweepObject1DMakeGroups(in SMESH_IDSource theObject, - in AxisStruct Axix, - in double AngleInRadians, - in long NbOfSteps, - in double Tolerance); + in AxisStruct Axix, + in double AngleInRadians, + in long NbOfSteps, + in double Tolerance); /*! * \brief Genarate dim+1 elements by rotation of the object around axis * \param theObject - object containing elements to ratate @@ -310,19 +385,19 @@ module SMESH * \param NbOfSteps - number of elements to generate from one element */ void RotationSweepObject2D(in SMESH_IDSource theObject, - in AxisStruct Axix, - in double AngleInRadians, - in long NbOfSteps, - in double Tolerance); + in AxisStruct Axix, + in double AngleInRadians, + in long NbOfSteps, + in double Tolerance); /*! * \brief Same as previous but additionally create groups of elements * generated from elements belonging to preexisting groups */ ListOfGroups RotationSweepObject2DMakeGroups(in SMESH_IDSource theObject, - in AxisStruct Axix, - in double AngleInRadians, - in long NbOfSteps, - in double Tolerance); + in AxisStruct Axix, + in double AngleInRadians, + in long NbOfSteps, + in double Tolerance); /*! * \brief Genarate dim+1 elements by extrusion of elements along vector * \param IDsOfElements - elements to sweep @@ -332,6 +407,15 @@ module SMESH void ExtrusionSweep(in long_array IDsOfElements, in DirStruct StepVector, in long NbOfSteps); + /*! + * \brief Genarate dim+1 elements by extrusion of elements along vector + * \param IDsOfElements - elements to sweep + * \param StepVector - vector giving direction and distance of an extrusion step + * \param NbOfSteps - number of elements to generate from one element + */ + void ExtrusionSweep0D(in long_array IDsOfElements, + in DirStruct StepVector, + in long NbOfSteps); /*! * \brief Same as previous but additionally create groups of elements * generated from elements belonging to preexisting groups @@ -340,7 +424,13 @@ module SMESH in DirStruct StepVector, in long NbOfSteps); /*! - * Generate new elements by extrusion of theElements + * \brief Same as previous but elements are nodes + */ + ListOfGroups ExtrusionSweepMakeGroups0D(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 @@ -349,8 +439,8 @@ module SMESH void AdvancedExtrusion(in long_array IDsOfElements, in DirStruct StepVector, in long NbOfSteps, - in long ExtrFlags, - in double SewTolerance); + in long ExtrFlags, + in double SewTolerance); /*! * \brief Same as previous but additionally create groups of elements * generated from elements belonging to preexisting groups @@ -362,22 +452,29 @@ module SMESH in double SewTolerance); void ExtrusionSweepObject(in SMESH_IDSource theObject, - in DirStruct StepVector, - in long NbOfSteps); + in DirStruct StepVector, + in long NbOfSteps); ListOfGroups ExtrusionSweepObjectMakeGroups(in SMESH_IDSource theObject, in DirStruct StepVector, in long NbOfSteps); + void ExtrusionSweepObject0D(in SMESH_IDSource theObject, + in DirStruct StepVector, + in long NbOfSteps); + ListOfGroups ExtrusionSweepObject0DMakeGroups(in SMESH_IDSource theObject, + in DirStruct StepVector, + in long NbOfSteps); + void ExtrusionSweepObject1D(in SMESH_IDSource theObject, - in DirStruct StepVector, - in long NbOfSteps); + in DirStruct StepVector, + in long NbOfSteps); ListOfGroups ExtrusionSweepObject1DMakeGroups(in SMESH_IDSource theObject, in DirStruct StepVector, in long NbOfSteps); void ExtrusionSweepObject2D(in SMESH_IDSource theObject, - in DirStruct StepVector, - in long NbOfSteps); + in DirStruct StepVector, + in long NbOfSteps); ListOfGroups ExtrusionSweepObject2DMakeGroups(in SMESH_IDSource theObject, in DirStruct StepVector, in long NbOfSteps); @@ -392,14 +489,38 @@ module SMESH EXTR_CANT_GET_TANGENT }; + ListOfGroups ExtrusionAlongPathX(in long_array IDsOfElements, + in SMESH_IDSource Path, + in long NodeStart, + in boolean HasAngles, + in double_array Angles, + in boolean LinearVariation, + in boolean HasRefPoint, + in PointStruct RefPoint, + in boolean MakeGroups, + in ElementType ElemType, + out Extrusion_Error Error); + + ListOfGroups ExtrusionAlongPathObjX(in SMESH_IDSource theObject, + in SMESH_IDSource Path, + in long NodeStart, + in boolean HasAngles, + in double_array Angles, + in boolean LinearVariation, + in boolean HasRefPoint, + in PointStruct RefPoint, + in boolean MakeGroups, + in ElementType ElemType, + out Extrusion_Error Error); + 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); + 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); ListOfGroups ExtrusionAlongPathMakeGroups(in long_array IDsOfElements, in SMESH_Mesh PathMesh, in GEOM::GEOM_Object PathShape, @@ -411,13 +532,13 @@ module SMESH out Extrusion_Error Error); 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); + 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); ListOfGroups ExtrusionAlongPathObjectMakeGroups(in SMESH_IDSource theObject, in SMESH_Mesh PathMesh, in GEOM::GEOM_Object PathShape, @@ -429,47 +550,47 @@ module SMESH out Extrusion_Error Error); Extrusion_Error ExtrusionAlongPathObject1D(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); + 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); ListOfGroups ExtrusionAlongPathObject1DMakeGroups(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, - out Extrusion_Error Error); + 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, + out Extrusion_Error Error); Extrusion_Error ExtrusionAlongPathObject2D(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); + 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); ListOfGroups ExtrusionAlongPathObject2DMakeGroups(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, - out Extrusion_Error Error); + 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, + out Extrusion_Error Error); /*! * 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 + * 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 + * 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, @@ -492,9 +613,9 @@ module SMESH in string MeshName); void MirrorObject (in SMESH_IDSource theObject, - in AxisStruct Mirror, - in MirrorType Type, - in boolean Copy); + in AxisStruct Mirror, + in MirrorType Type, + in boolean Copy); ListOfGroups MirrorObjectMakeGroups (in SMESH_IDSource theObject, in AxisStruct Mirror, in MirrorType Type); @@ -515,8 +636,8 @@ module SMESH in string MeshName); void TranslateObject (in SMESH_IDSource theObject, - in DirStruct Vector, - in boolean Copy); + in DirStruct Vector, + in boolean Copy); ListOfGroups TranslateObjectMakeGroups (in SMESH_IDSource theObject, in DirStruct Vector); SMESH_Mesh TranslateObjectMakeMesh (in SMESH_IDSource theObject, @@ -524,6 +645,19 @@ module SMESH in boolean CopyGroups, in string MeshName); + void Scale (in SMESH_IDSource theObject, + in PointStruct thePoint, + in double_array theScaleFact, + in boolean Copy); + ListOfGroups ScaleMakeGroups (in SMESH_IDSource theObject, + in PointStruct thePoint, + in double_array theScaleFact); + SMESH_Mesh ScaleMakeMesh (in SMESH_IDSource theObject, + in PointStruct thePoint, + in double_array theScaleFact, + in boolean CopyGroups, + in string MeshName); + void Rotate (in long_array IDsOfElements, in AxisStruct Axis, in double AngleInRadians, @@ -538,9 +672,9 @@ module SMESH in string MeshName); void RotateObject (in SMESH_IDSource theObject, - in AxisStruct Axis, - in double AngleInRadians, - in boolean Copy); + in AxisStruct Axis, + in double AngleInRadians, + in boolean Copy); ListOfGroups RotateObjectMakeGroups (in SMESH_IDSource theObject, in AxisStruct Axis, in double AngleInRadians); @@ -554,8 +688,13 @@ module SMESH out array_of_long_array GroupsOfNodes); void FindCoincidentNodesOnPart (in SMESH_IDSource SubMeshOrGroup, - in double Tolerance, - out array_of_long_array GroupsOfNodes); + in double Tolerance, + out array_of_long_array GroupsOfNodes); + + void FindCoincidentNodesOnPartBut (in SMESH_IDSource SubMeshOrGroup, + in double Tolerance, + out array_of_long_array GroupsOfNodes, + in ListOfIDSources ExceptSubMeshOrGroups); void MergeNodes (in array_of_long_array GroupsOfNodes); @@ -565,7 +704,7 @@ module SMESH * \return List of groups of equal elements. */ void FindEqualElements (in SMESH_IDSource MeshOrSubMeshOrGroup, - out array_of_long_array GroupsOfElementsID); + out array_of_long_array GroupsOfElementsID); /*! * \brief Merge elements in each given group. @@ -577,13 +716,41 @@ module SMESH * \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); + /*! + * Return ID of node closest to a given point + */ + long FindNodeClosestTo(in double x, in double y, in double z); + + /*! + * Return elements of given type where the given point is IN or ON. + * + * 'ALL' type means elements of any type excluding nodes and 0D elements + */ + long_array FindElementsByPoint(in double x, in double y, in double z, in ElementType type); + + /*! + * Searching among the given elements, return elements of given type + * where the given point is IN or ON. + * + * 'ALL' type means elements of any type excluding nodes and 0D elements + */ + long_array FindAmongElementsByPoint(in SMESH_IDSource elements, + in double x, in double y, in double z, + in ElementType type); + + /*! + * Return point state in a closed 2D mesh in terms of TopAbs_State enumeration. + * TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. + */ + short GetPointState(in double x, in double y, in double z); + enum Sew_Error { SEW_OK, SEW_BORDER1_NOT_FOUND, @@ -604,8 +771,8 @@ module SMESH in long FirstNodeID2, in long SecondNodeID2, in long LastNodeID2, - in boolean CreatePolygons, - in boolean CreatePolyedrs); + in boolean CreatePolygons, + in boolean CreatePolyedrs); Sew_Error SewConformFreeBorders (in long FirstNodeID1, in long SecondNodeID1, @@ -618,8 +785,8 @@ module SMESH in long LastNodeIDOnFreeBorder, in long FirstNodeIDOnSide, in long LastNodeIDOnSide, - in boolean CreatePolygons, - in boolean CreatePolyedrs); + in boolean CreatePolygons, + in boolean CreatePolyedrs); Sew_Error SewSideElements (in long_array IDsOfSide1Elements, in long_array IDsOfSide2Elements, @@ -636,7 +803,7 @@ module SMESH boolean ChangeElemNodes(in long ide, in long_array newIDs); /*! - * Return data of mesh edition preview which is computed provided + * Return data of mesh edition preview which is computed provided * that the editor was obtained trough SMESH_Mesh::GetMeshEditPreviewer() */ MeshPreviewStruct GetPreviewData(); @@ -654,50 +821,302 @@ module SMESH * not creared - returns empty list */ long_array GetLastCreatedElems(); - + /*! * \brief Creates a hole in a mesh by doubling the nodes of some particular elements * \param theNodes - identifiers of nodes to be doubled - * \param theModifiedElems - identifiers of elements to be updated by the new (doubled) - * nodes. If list of element identifiers is empty then nodes are doubled but + * \param theModifiedElems - identifiers of elements to be updated by the new (doubled) + * nodes. If list of element identifiers is empty then nodes are doubled but * they not assigned to elements * \return TRUE if operation has been completed successfully, FALSE otherwise * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups() - */ - boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems ); + */ + boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems ); /*! - * \brief Creates a hole in a mesh by doubling the nodes of some particular elements - * This method provided for convenience works as DoubleNodes() described above. - * \param theNodeId - identifier of node to be doubled. - * \param theModifiedElems - identifiers of elements to be updated. - * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups() - */ - boolean DoubleNode( in long theNodeId, in long_array theModifiedElems ); + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theNodeId - identifier of node to be doubled. + * \param theModifiedElems - identifiers of elements to be updated. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups() + */ + boolean DoubleNode( in long theNodeId, in long_array theModifiedElems ); /*! - * \brief Creates a hole in a mesh by doubling the nodes of some particular elements - * This method provided for convenience works as DoubleNodes() described above. - * \param theNodes - group of nodes to be doubled. - * \param theModifiedElems - group of elements to be updated. - * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups() - */ - boolean DoubleNodeGroup( in SMESH_GroupBase theNodes, + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups(), DoubleNodeGroupNew() + */ + boolean DoubleNodeGroup( in SMESH_GroupBase theNodes, in SMESH_GroupBase theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup() described above, but returns a new group with + * newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ + SMESH_Group DoubleNodeGroupNew( in SMESH_GroupBase theNodes, + in SMESH_GroupBase theModifiedElems ); /*! - \brief Creates a hole in a mesh by doubling the nodes of some particular elements - This method provided for convenience works as DoubleNodes() described above. - \param theNodes - list of groups of nodes to be doubled - \param theModifiedElems - list of groups of elements to be updated. - \return TRUE if operation has been completed successfully, FALSE otherwise - \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes() - */ - boolean DoubleNodeGroups( in ListOfGroups theNodes, + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theNodes - list of groups of nodes to be doubled + * \param theModifiedElems - list of groups of elements to be updated. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes() + */ + boolean DoubleNodeGroups( in ListOfGroups theNodes, in ListOfGroups theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeGroups() described above, but returns a new group with + * newly created nodes. + * \param theNodes - list of groups of nodes to be doubled + * \param theModifiedElems - list of groups of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroups() + */ + SMESH_Group DoubleNodeGroupsNew( in ListOfGroups theNodes, + in ListOfGroups theModifiedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theAffectedElems - the list of elements (cells and edges) to which the + * replicated nodes should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodeGroups() + */ + boolean DoubleNodeElem( in long_array theElems, + in long_array theNodesNot, + in long_array theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion() + */ + boolean DoubleNodeElemInRegion( in long_array theElems, + in long_array theNodesNot, + in GEOM::GEOM_Object theShape ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodes(), DoubleNodeGroups(), DoubleNodeElemGroupNew() + */ + boolean DoubleNodeElemGroup( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in SMESH_GroupBase theAffectedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeElemGroup() described above, but returns a new group with + * newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ + SMESH_Group DoubleNodeElemGroupNew( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in SMESH_GroupBase theAffectedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeElemGroup() described above, but returns two new groups: + * a group of newly created elements and a group of newly created nodes + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \param theElemGroupNeeded - to create group of new elements or not + * \param theNodeGroupNeeded - to create group of new nodes or not + * \return two new groups of newly created elements (1st) and nodes (2nd) + * \sa DoubleNodeElemGroup() + */ + ListOfGroups DoubleNodeElemGroup2New( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in SMESH_GroupBase theAffectedElems, + in boolean theElemGroupNeeded, + in boolean theNodeGroupNeeded); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - group of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion() + */ + boolean DoubleNodeElemGroupInRegion( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in GEOM::GEOM_Object theShape ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew() + */ + boolean DoubleNodeElemGroups( in ListOfGroups theElems, + in ListOfGroups theNodesNot, + in ListOfGroups theAffectedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeElemGroups() described above, but returns a new group with + * newly created elements. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroups() + */ + SMESH_Group DoubleNodeElemGroupsNew( in ListOfGroups theElems, + in ListOfGroups theNodesNot, + in ListOfGroups theAffectedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeElemGroups() described above, but returns two new groups: + * a group of newly created elements and a group of newly created nodes. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \param theElemGroupNeeded - to create group of new elements or not + * \param theNodeGroupNeeded - to create group of new nodes or not + * \return two new groups of newly created elements (1st) and nodes (2nd) + * \sa DoubleNodeElemGroups() + */ + ListOfGroups DoubleNodeElemGroups2New( in ListOfGroups theElems, + in ListOfGroups theNodesNot, + in ListOfGroups theAffectedElems, + in boolean theElemGroupNeeded, + in boolean theNodeGroupNeeded ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion() + */ + boolean DoubleNodeElemGroupsInRegion( in ListOfGroups theElems, + in ListOfGroups theNodesNot, + in GEOM::GEOM_Object theShape ); + + /*! + * \brief Generates skin mesh (containing 2D cells) from 3D mesh + * The created 2D mesh elements based on nodes of free faces of boundary volumes + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ + boolean Make2DMeshFrom3D(); + + /*! + * \brief Creates missing boundary elements + * \param elements - elements whose boundary is to be checked + * \param dimension - defines type of boundary elements to create + * BND_1DFROM3D creates mesh edges on all borders of free facets of 3D elements. + * \param groupName - a name of group to store created boundary elements in, + * "" means not to create the group + * \param meshName - a name of new mesh to store created boundary elements in, + * "" means not to create the new mesh + * \param toCopyElements - if true, the checked elements will be copied into the new mesh + * else only boundary elements will be copied into the new mesh + * \param toCopyExistingBondary - if true, not only new but also pre-existing + * boundary elements will be copied into the new mesh + * \param group - returns the create group, if any + * \retval SMESH::SMESH_Mesh - the mesh where elements were added to + */ + SMESH_Mesh MakeBoundaryMesh(in SMESH_IDSource elements, + in Bnd_Dimension dimension, + in string groupName, + in string meshName, + in boolean toCopyElements, + in boolean toCopyExistingBondary, + out SMESH_Group group); + /*! + * \brief Creates missing boundary elements around either the whole mesh or + * groups of 2D elements + * \param dimension - defines type of boundary elements to create + * \param groupName - a name of group to store all boundary elements in, + * "" means not to create the group + * \param meshName - a name of a new mesh, which is a copy of the initial + * mesh + created boundary elements; "" means not to create the new mesh + * \param toCopyAll - if true, the whole initial mesh will be copied into + * the new mesh else only boundary elements will be copied into the new mesh + * \param groups - optional groups of 2D elements to make boundary around + * \param mesh - returns the mesh where elements were added to + * \param group - returns the created group, if any + * \retval long - number of added boundary elements + */ + long MakeBoundaryElements(in Bnd_Dimension dimension, + in string groupName, + in string meshName, + in boolean toCopyAll, + in ListOfIDSources groups, + out SMESH_Mesh mesh, + out SMESH_Group group) raises (SALOME::SALOME_Exception); + + /*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * Flat elements are mainly used by some types of mechanic calculations. + * + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * \param theDomains - list of groups of volumes + * \param createJointElems - if TRUE, create the elements + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ + boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains, + in boolean createJointElems ) + raises (SALOME::SALOME_Exception); + + /*! + * \brief Double nodes on some external faces and create flat elements. + * Flat elements are mainly used by some types of mechanic calculations. + * + * Each group of the list must be constituted of faces. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * \param theGroupsOfFaces - list of groups of faces + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ + boolean CreateFlatElementsOnFacesGroups( in ListOfGroups theGroupsOfFaces ); }; }; diff --git a/idl/SMESH_Pattern.idl b/idl/SMESH_Pattern.idl index 4f0bcfaa6..85b842f83 100644 --- a/idl/SMESH_Pattern.idl +++ b/idl/SMESH_Pattern.idl @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Pattern.idl // Created : Mon Aug 2 10:48:36 2004 // Author : Edward AGAPOV (eap) diff --git a/resources/Makefile.am b/resources/Makefile.am index 2ebd83edf..dcbb70ebc 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 28/06/2001 @@ -38,6 +36,7 @@ dist_salomeres_DATA = \ mesh_area.png \ mesh_aspect.png \ mesh_aspect_3d.png \ + mesh_biquad_quadrangle.png \ mesh_clear.png \ mesh_compute.png \ mesh_diagonal.png \ @@ -51,18 +50,27 @@ dist_salomeres_DATA = \ mesh_info.png \ advanced_mesh_info.png \ standard_mesh_info.png \ + mesh_elem_info.png \ + mesh_equal_edge.png \ + mesh_equal_face.png \ + mesh_equal_node.png \ + mesh_equal_volume.png \ mesh_whatis.png \ mesh_init.png \ mesh_length.png \ mesh_length_2d.png \ + mesh_find_elem_by_point.png \ mesh_free_edges.png \ mesh_free_edges_2d.png \ mesh_free_nodes.png \ + mesh_max_element_length_2d.png \ + mesh_max_element_length_3d.png \ mesh_multi_edges.png \ mesh_multi_edges_2d.png \ mesh_line_n.png \ mesh_line.png \ mesh_move_node.png \ + mesh_octahedron.png \ mesh_orientation.png \ mesh.png \ mesh_polygon.png \ @@ -71,8 +79,14 @@ dist_salomeres_DATA = \ mesh_pyramid.png \ mesh_quad_n.png \ mesh_quad.png \ + mesh_quadrangle_quadpref.png \ + mesh_quadrangle_quadpref_reversed.png \ + mesh_quadrangle_reduced.png \ + mesh_quadrangle_standard.png \ + mesh_quadrangle_triapref.png \ mesh_rem_element.png \ mesh_rem_node.png \ + mesh_rem_orphan_nodes.png \ mesh_shading.png \ mesh_shrink.png \ mesh_skew.png \ @@ -81,6 +95,7 @@ dist_salomeres_DATA = \ mesh_tree_algo_hexa.png \ mesh_tree_algo_mefisto.png \ mesh_tree_algo.png \ + mesh_tree_algo_0D.png \ mesh_tree_algo_quad.png \ mesh_tree_algo_regular.png \ mesh_tree_algo_tetra.png \ @@ -93,16 +108,22 @@ dist_salomeres_DATA = \ mesh_tree_importedmesh.png \ mesh_tree_mesh_warn.png \ mesh_triangle_n.png \ + mesh_triquad_hexahedron.png \ mesh_triangle.png \ mesh_update.png \ mesh_vertex_n.png \ mesh_vertex.png \ mesh_volume_3d.png \ + bare_border_volume.png \ + bare_border_face.png \ + over_constrained_volume.png \ + over_constrained_face.png \ mesh_wireframe.png \ mesh_points.png \ mesh_wrap.png \ mesh_group.png \ mesh_tree_group.png \ + mesh_tree_group_on_filter.png \ mesh_edit_group.png \ mesh_make_group.png \ mesh_groups_from_gemetry.png \ @@ -134,8 +155,8 @@ dist_salomeres_DATA = \ mesh_merge_elements.png \ select1.png \ StdMeshers.xml \ - SalomeApp.xml \ mesh_pattern.png \ + mesh_pentahedron.png \ pattern_sample_2d.png \ pattern_sample_3D.png \ mesh_add.png \ @@ -150,6 +171,9 @@ dist_salomeres_DATA = \ mesh_conv_to_quad.png \ mesh_tree_hypo_layers_distribution.png \ mesh_tree_algo_radial_prism.png \ + mesh_tree_algo_radial_quadrangle_1D2D.png \ + mesh_tree_algo_existing_2D.png \ + mesh_tree_algo_prism.png \ mesh_tree_algo_projection_2d.png \ mesh_hypo_source_edge.png \ mesh_hypo_source_3d.png \ @@ -161,11 +185,25 @@ dist_salomeres_DATA = \ mesh_tree_hypo_projection_3d.png \ mesh_tree_hypo_projection_2d.png \ mesh_build_compound.png \ + copy_mesh.png \ mesh_node_to_point.png \ mesh_tree_mesh_partial.png \ mesh_extractGroup.png \ mesh_precompute.png \ - mesh_free_faces.png + mesh_2d_from_3d.png \ + mesh_free_faces.png \ + scale.png \ + scale_along_axes.png \ + split_into_tetra.png \ + mesh_duplicate_nodes.png \ + mesh_duplicate_nodes_with_elem.png \ + mesh_bounding_box.png \ + mesh_hypo_viscous_layers.png \ + mesh_tree_hypo_viscous_layers.png \ + mesh_min_dist.png \ + reorient_faces_point.png \ + reorient_faces_face.png \ + mesh_ball.png # VSR: little trick to avoid putting if SMESHCatalog.xml to the distribution archive -nodist_salomeres_SCRIPTS = SMESHCatalog.xml +nodist_salomeres_SCRIPTS = SMESHCatalog.xml SalomeApp.xml diff --git a/resources/SMESHCatalog.xml.in b/resources/SMESHCatalog.xml.in index 200d23297..f65821917 100644 --- a/resources/SMESHCatalog.xml.in +++ b/resources/SMESHCatalog.xml.in @@ -1,6 +1,6 @@ - -
                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                    -
                    - - - - - - - - - - - - -
                    -
                    diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in new file mode 100644 index 000000000..0dbcc2e88 --- /dev/null +++ b/resources/SalomeApp.xml.in @@ -0,0 +1,109 @@ + + +
                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                    +
                    + + + +
                    +
                    + + + +
                    +
                    diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml index 4adf93e83..0d519fc57 100644 --- a/resources/StdMeshers.xml +++ b/resources/StdMeshers.xml @@ -1,7 +1,7 @@ Branche V6_main + +Problemes en cours +================== +- a faire ++ en cours, OK mais perfectible +* OK + ++ visualisation de groupe (type d'element): on voit tout le maillage, mais le groupe est OK + creation d'une structure vtkUnstructuredGrid locale : iteration un peu lourde, et pas de partage avec la structure du maillage (pas evident) +- inversion d'un volume (tetra): exception +- script de creation de noeuds et d'elements: OK, mais pas compatible avec version precedente (numerotation noeuds differente) ++ affichage numeros noeuds: numeros en trop sur (O,0,0) pas systematique, trouver la condition (enlever dans vtkUnstructuredGrid ?) + ==> purge systematique noeuds et cellules en trop dans compactage grid. ++ gestion du mode embedded mal faite lors d'un script python : journal commandes intempestif +- affichage des noeuds apres changement lineaire <--> quadratique à l'IHM : pas pris en compte, alors que maillage OK, + mais script OK + ==> cassé apres mode embedded ou elimination noeuds en trop ? +- extrusion elements 2D along a path : affichage apres calcul pas toujours OK (filaire) +- branche git a ouvrir pour merge avec V5_1_4_BR tag V5_1_4rc1 + +A tester, non pris en compte +============================ +- engine standalone +- polyedres (attendre vtk) + + +=============================== Hypothese de refonte de l'API de SMDS + +n'utiliser que vtkUnstructuredGrid, ne pas avor d'objets SMDS_MeshElement mais seulement des index de vtkUnstructuredGrid. +2987 usages de SMDS_MeshNodes +810 SMDS_MeshElement +... +==> en dernier ressort, lourd +================================================================================ + +Essai a API SMDS a peu pres constante +===================================== + +SMDS_Mesh + static vector _meshList; --> retrouver un SMDS_Mesh + vtkUnstructuredGrid* myGrid; + + vector myNodes; --> meme index que dans le pointSet de myGrid + vector myCells; --> index = ID client, pas le meme index que dans le cellTypes de myGrid (ID vtk) + + + +SMDS_MeshElement + int myID; --> index dans la structure geree par SMDS_Mesh + int myMeshId; --> pour retrouver SMDS_Mesh* dans _meshList + int myShapeId; --> pour retrouver la subShape + + +SMDS_MeshNode: SMDS_MeshElement + SMDS_PositionPtr myPosition; --> A REVOIR : objet position dans la shape geom + ##vector myInverseElements; --> SUPPRIME : pour retrouver les elements, vtkCellLinks + + +SMDS_MeshCell: SMDS_MeshElement --> generique pour tous les elements (cells) + int myVtkID --> A SUPPRIMER + +SMDS_MeshVolume: SMDS_MeshCell + +SMDS_VolumeOfNodes: SMDS_MeshVolume --> Garder temporairement, utilisation dans StdMesher et SMDS_VolumeTool + const SMDS_MeshNode **myNodes; --> Couteux + int myNbNodes; --> "" + +SMDS_VolumeVtkNodes: SMDS_MeshVolume --> Utiliser systematiquement dans SMDS, + --> IMPLEMENTER. + + +SMDS_MeshElementIDFactory: SMDS_MeshNodeIDFactory + vector myIDElements; // index = ID client, value = ID vtk --> A SUPPRIMER, ne sert que dans SMDS_MeshElementIDFactory + vector myVtkIndex; // index = ID vtk, value = ID client --> A REPORTER dans SMDS_Mesh + + + + +========= TODO ============ + +enlever vtkId de SMDS_MeshCell, utiliser SMDS_MeshElementIDFactory. + +ajouter ID dans SMDS_Mesh::createTriangle +verifier ID dans SMDS_Mesh::Find*OrCreate + +=================================================== +occupation memoire cube 100*100*100 sans affichage +NOTES: +- sur Debian Sarge 64 bits, les mesures malloc_stat() semblent coherentes + avec une mesure externe globale(recherche du passage en swap du process). +- sur Ubuntu 9.10 64 bits, les mesures malloc_stat() donnent des resultats bizarres (surestimation ?), + mais la mesure avec l'outil KDE de surveillance systeme est OK avec la recherche du swap. + + +Reference : V513 Debian Sarge 64 bits: --> 463 - 33 = 430 Mo +------------------------------------- +Total (incl. mmap): +system bytes = 43757568 +in use bytes = 32909584 = 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 464670720 +in use bytes = 463105120 = 463M +max mmap regions = 47 +max mmap bytes = 28188672 + +Debian Sarge 64 bits, vtkUnstructuredGrid nodes et hexa, 4 janvier 2010 --> 512 - 41 = 471M +----------------------------------- + +Total (incl. mmap): +system bytes = 52133888 +in use bytes = 41340320 : 41M +max mmap regions = 72 +max mmap bytes = 24625152 +---- +Total (incl. mmap): +system bytes = 520560640 +in use bytes = 518735584 : 512M +max mmap regions = 88 +max mmap bytes = 198385664 + +idem avec pool SMDS_MeshNodes --> 483 -33 = 450M +----------------------------- +Total (incl. mmap): +system bytes = 43696128 +in use bytes = 32915184 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 484806656 +in use bytes = 482980992 : 483M +max mmap regions = 58 +max mmap bytes = 184557568 + +idem ci-dessus + pool SMDS_VolumeVtkNodes --> 475 -33 = 442M (git: add ObjectPool.hxx) +----------------------------------------- + +Total (incl. mmap): +system bytes = 43200512 +in use bytes = 32908576 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 478068736 +in use bytes = 475144400 : 475M +max mmap regions = 59 +max mmap bytes = 184692736 + +remplacement SMDS_PositionPtr: (boost::shared_ptr --> SMDS_Position*) --> 436 - 35 = 401M (git SMDS_Position) +------------------------------------------------------------------------------------ +Total (incl. mmap): +system bytes = 45408256 +in use bytes = 35097680 : 35M +max mmap regions = 47 +max mmap bytes = 18116608 +---- +Total (incl. mmap): +system bytes = 438935552 +in use bytes = 436116560 : 436M +max mmap regions = 65 +max mmap bytes = 186437632 + +simplification SMDS_SpacePosition (pas de double[3]) --> 418 -33 = 385M (git SMDS_SpacePosition) +---------------------------------------------------- +Total (incl. mmap): +system bytes = 42582016 +in use bytes = 32883552 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 421728256 +in use bytes = 418378000 : 418M +max mmap regions = 58 +max mmap bytes = 183640064 + +sizeof(SMDS_MeshElement) 16 +sizeof(SMDS_MeshNode) 24 +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +impact d'un int en plus dans SMDS_MeshElement --> 426 - 33 = 393M +--------------------------------------------- + +sizeof(SMDS_MeshElement) 24 +sizeof(SMDS_MeshNode) 32 --> on retrouve bien les 8M +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +Total (incl. mmap): +system bytes = 43192320 +in use bytes = 32681088 : 33M +max mmap regions = 41 +max mmap bytes = 16371712 +---- +Total (incl. mmap): +system bytes = 429334528 +in use bytes = 426424576 : 426M +max mmap regions = 59 +max mmap bytes = 184692736 + +remplacement std::set par std::vector dans SMESHDS_SubMesh --> 347 - 35 = 312M +---------------------------------------------------------- +sizeof(SMDS_MeshElement) 24 +sizeof(SMDS_MeshNode) 32 +sizeof(SMDS_MeshCell) 24 +sizeof(SMDS_VolumeVtkNodes) 24 +sizeof(SMDS_Position) 16 +sizeof(SMDS_SpacePosition) 16 + +Total (incl. mmap): +system bytes = 45404160 +in use bytes = 35132160 --> 35M +max mmap regions = 49 +max mmap bytes = 17723392 +---- +Total (incl. mmap): +system bytes = 349831168 +in use bytes = 346885424 --> 347M +max mmap regions = 73 +max mmap bytes = 204148736 + +Ce resultat est coherent avec une recherche de swap sur une machine a 8Go de memoire: +Cube a 270**3 mailles (~20M mailles) --> 6.2 Go (idem Debian Sarge et Ubuntu 9.10, 64 bits) +Le meme avec V5.1.3 --> 14 Go (swap) + diff --git a/src/SMDS/ObjectPool.hxx b/src/SMDS/ObjectPool.hxx new file mode 100644 index 000000000..1ee371055 --- /dev/null +++ b/src/SMDS/ObjectPool.hxx @@ -0,0 +1,134 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _OBJECTPOOL_HXX_ +#define _OBJECTPOOL_HXX_ + +#include +#include +#include + +template class ObjectPool +{ + +private: + std::vector _chunkList; + std::vector _freeList; + int _nextFree; + int _maxAvail; + int _chunkSize; + + int getNextFree() + { + for (int i = _nextFree; i < _maxAvail; i++) + if (_freeList[i] == true) + { + return i; + break; + } + return _maxAvail; + } + + void checkDelete(int chunkId) + { + int i0 = _chunkSize * chunkId; + int i1 = _chunkSize * (chunkId + 1); + for (int i = i0; i < i1; i++) + if (_freeList[i] == false) + return; + std::cerr << "a chunk to delete" << std::endl; + // compactage des vecteurs un peu lourd, pas necessaire + //X* chunk = _chunkList[chunkId]; + //delete [] chunk; + } + +public: + ObjectPool(int nblk) + { + _chunkSize = nblk; + _nextFree = 0; + _maxAvail = 0; + _chunkList.clear(); + _freeList.clear(); + } + + virtual ~ObjectPool() + { + for (int i = 0; i < _chunkList.size(); i++) + delete[] _chunkList[i]; + } + + X* getNew() + { + X *obj = 0; + _nextFree = getNextFree(); + if (_nextFree == _maxAvail) + { + X* newChunk = new X[_chunkSize]; + _chunkList.push_back(newChunk); + _freeList.insert(_freeList.end(), _chunkSize, true); + _maxAvail += _chunkSize; + _freeList[_nextFree] = false; + obj = newChunk; // &newChunk[0]; + } + else + { + int chunkId = _nextFree / _chunkSize; + int rank = _nextFree - chunkId * _chunkSize; + _freeList[_nextFree] = false; + obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank]; + } + //obj->init(); + return obj; + } + + void destroy(X* obj) + { + long adrobj = (long) (obj); + for (int i = 0; i < _chunkList.size(); i++) + { + X* chunk = _chunkList[i]; + long adrmin = (long) (chunk); + if (adrobj < adrmin) + continue; + long adrmax = (long) (chunk + _chunkSize); + if (adrobj >= adrmax) + continue; + int rank = (adrobj - adrmin) / sizeof(X); + int toFree = i * _chunkSize + rank; + _freeList[toFree] = true; + if (toFree < _nextFree) + _nextFree = toFree; + //obj->clean(); + //checkDelete(i); compactage non fait + break; + } + } + + // void destroy(int toFree) + // { + // // no control 0<= toFree < _freeList.size() + // _freeList[toFree] = true; + // if (toFree < _nextFree) + // _nextFree = toFree; + // } + +}; + +#endif diff --git a/src/SMDS/SMDSAbs_ElementType.hxx b/src/SMDS/SMDSAbs_ElementType.hxx index a76772e3f..e66bbff09 100644 --- a/src/SMDS/SMDSAbs_ElementType.hxx +++ b/src/SMDS/SMDSAbs_ElementType.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDSAbs_ElementType.hxx // Module : SMESH @@ -30,33 +31,40 @@ /// Type (node, edge, face or volume) of elements /////////////////////////////////////////////////////////////////////////////// enum SMDSAbs_ElementType -{ - SMDSAbs_All, - SMDSAbs_Node, - SMDSAbs_Edge, - SMDSAbs_Face, - SMDSAbs_Volume, - SMDSAbs_NbElementTypes -}; + { + SMDSAbs_All, + SMDSAbs_Node, + SMDSAbs_Edge, + SMDSAbs_Face, + SMDSAbs_Volume, + SMDSAbs_0DElement, + SMDSAbs_Ball, + SMDSAbs_NbElementTypes + }; /*! enumeration for element geometry type */ enum SMDSAbs_GeometryType -{ - // 0D element - SMDSGeom_POINT, - // 1D element - SMDSGeom_EDGE, - // 2D element - SMDSGeom_TRIANGLE, - SMDSGeom_QUADRANGLE, - SMDSGeom_POLYGON, - // 3D element - SMDSGeom_TETRA, - SMDSGeom_PYRAMID, - SMDSGeom_PENTA, - SMDSGeom_HEXA, - SMDSGeom_POLYHEDRA, -}; + { + // 0D element + SMDSGeom_POINT, + // 1D element + SMDSGeom_EDGE, + // 2D element + SMDSGeom_TRIANGLE, + SMDSGeom_QUADRANGLE, + SMDSGeom_POLYGON, + // 3D element + SMDSGeom_TETRA, + SMDSGeom_PYRAMID, + SMDSGeom_HEXA, + SMDSGeom_PENTA, + SMDSGeom_HEXAGONAL_PRISM, + SMDSGeom_POLYHEDRA, + // Discrete elements + SMDSGeom_BALL, + // + SMDSGeom_NONE + }; enum SMDSAbs_ElementOrder { @@ -65,4 +73,36 @@ enum SMDSAbs_ElementOrder { ORDER_QUADRATIC /*! entities of 2nd order */ }; +/*! + * Enumeration of entity type uses in mesh info array, + * and should be synchronised with enum in SMDS + */ +enum SMDSAbs_EntityType { + SMDSEntity_Node, + SMDSEntity_0D, + SMDSEntity_Edge, + SMDSEntity_Quad_Edge, + SMDSEntity_Triangle, + SMDSEntity_Quad_Triangle, + SMDSEntity_Quadrangle, + SMDSEntity_Quad_Quadrangle, + SMDSEntity_BiQuad_Quadrangle, + SMDSEntity_Polygon, + SMDSEntity_Quad_Polygon, + SMDSEntity_Tetra, + SMDSEntity_Quad_Tetra, + SMDSEntity_Pyramid, + SMDSEntity_Quad_Pyramid, + SMDSEntity_Hexa, + SMDSEntity_Quad_Hexa, + SMDSEntity_TriQuad_Hexa, + SMDSEntity_Penta, + SMDSEntity_Quad_Penta, + SMDSEntity_Hexagonal_Prism, + SMDSEntity_Polyhedra, + SMDSEntity_Quad_Polyhedra, + SMDSEntity_Ball, + SMDSEntity_Last +}; + #endif diff --git a/src/SMDS/SMDS_BallElement.cxx b/src/SMDS/SMDS_BallElement.cxx new file mode 100644 index 000000000..9595e9889 --- /dev/null +++ b/src/SMDS/SMDS_BallElement.cxx @@ -0,0 +1,102 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMDS : implementaion of Salome mesh data structure +// Module : SMESH +// File : SMDS_BallElement.cxx +// Author : Edward AGAPOV (eap) + +#include "SMDS_BallElement.hxx" + +#include "SMDS_ElemIterator.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_VtkCellIterator.hxx" + +SMDS_BallElement::SMDS_BallElement() +{ + SMDS_MeshCell::init(); +} + +SMDS_BallElement::SMDS_BallElement (const SMDS_MeshNode * node, double diameter) +{ + init( node->getVtkId(), diameter, SMDS_Mesh::_meshList[ node->getMeshId() ] ); +} + +SMDS_BallElement::SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh) +{ + init( nodeId, diameter, mesh ); +} + +void SMDS_BallElement::init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh) +{ + SMDS_MeshCell::init(); + SMDS_UnstructuredGrid* grid = mesh->getGrid(); + myVtkID = grid->InsertNextLinkedCell( GetVtkType(), 1, &nodeId ); + myMeshId = mesh->getMeshId(); + grid->SetBallDiameter( myVtkID, diameter ); + mesh->setMyModified(); +} + +double SMDS_BallElement::GetDiameter() const +{ + return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetBallDiameter( myVtkID ); +} + +void SMDS_BallElement::SetDiameter(double diameter) +{ + SMDS_Mesh::_meshList[myMeshId]->getGrid()->SetBallDiameter( myVtkID, diameter ); +} + +bool SMDS_BallElement::ChangeNode (const SMDS_MeshNode * node) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + pts[0] = node->getVtkId(); + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +void SMDS_BallElement::Print (std::ostream & OS) const +{ + OS << "ball<" << GetID() << "> : "; +} + +const SMDS_MeshNode* SMDS_BallElement::GetNode (const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts, *pts; + grid->GetCellPoints( myVtkID, npts, pts ); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ 0 ]); +} + +SMDS_ElemIteratorPtr SMDS_BallElement::elementsIterator (SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + diff --git a/src/SMDS/SMDS_BallElement.hxx b/src/SMDS/SMDS_BallElement.hxx new file mode 100644 index 000000000..c8ead2a7a --- /dev/null +++ b/src/SMDS/SMDS_BallElement.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_BallElement.hxx +// Module : SMESH +// +#ifndef _SMDS_BallElement_HeaderFile +#define _SMDS_BallElement_HeaderFile + +#include "SMESH_SMDS.hxx" +#include "SMDS_MeshCell.hxx" + +#include + +class SMDS_EXPORT SMDS_BallElement: public SMDS_MeshCell +{ + public: + SMDS_BallElement(); + SMDS_BallElement (const SMDS_MeshNode * node, double diameter); + SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh); + void init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh); + double GetDiameter() const; + void SetDiameter(double diameter); + bool ChangeNode (const SMDS_MeshNode * node); + + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes) { return ChangeNode( nodes[0] ); } + virtual void Print (std::ostream & OS) const; + + virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Ball; } + virtual vtkIdType GetVtkType() const { return VTK_POLY_VERTEX; } + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Ball; } + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_BALL; } + virtual int NbNodes() const { return 1; } + virtual int NbEdges() const { return 0; } + virtual int NbFaces() const { return 0; } + virtual const SMDS_MeshNode* GetNode (const int ind) const; + + protected: + SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; +}; + +#endif diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx new file mode 100644 index 000000000..67ff05ffc --- /dev/null +++ b/src/SMDS/SMDS_Downward.cxx @@ -0,0 +1,2235 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: SMDS_Downward.cxx +// Created: Jun 3, 2010 +// Author: prascle + +#include "SMDS_Downward.hxx" +#include "SMDS_Mesh.hxx" +#include "utilities.h" + +#include +#include + +#include + +using namespace std; + +// --------------------------------------------------------------------------- + +vector SMDS_Downward::_cellDimension; + +/*! get the dimension of a cell (1,2,3 for 1D, 2D 3D) given the vtk cell type + * + * @param cellType vtk cell type @see vtkCellType.h + * @return 1,2 or 3 + */ +int SMDS_Downward::getCellDimension(unsigned char cellType) +{ + if (_cellDimension.empty()) + { + _cellDimension.resize(VTK_MAXTYPE + 1, 0); + _cellDimension[VTK_LINE] = 1; + _cellDimension[VTK_QUADRATIC_EDGE] = 1; + _cellDimension[VTK_TRIANGLE] = 2; + _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2; + _cellDimension[VTK_QUAD] = 2; + _cellDimension[VTK_QUADRATIC_QUAD] = 2; + _cellDimension[VTK_BIQUADRATIC_QUAD] = 2; + _cellDimension[VTK_TETRA] = 3; + _cellDimension[VTK_QUADRATIC_TETRA] = 3; + _cellDimension[VTK_HEXAHEDRON] = 3; + _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3; + _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3; + _cellDimension[VTK_WEDGE] = 3; + _cellDimension[VTK_QUADRATIC_WEDGE] = 3; + _cellDimension[VTK_PYRAMID] = 3; + _cellDimension[VTK_QUADRATIC_PYRAMID] = 3; + _cellDimension[VTK_HEXAGONAL_PRISM] = 3; + } + return _cellDimension[cellType]; +} + +// --------------------------------------------------------------------------- + +/*! Generic constructor for all the downward connectivity structures (one per vtk cell type). + * The static structure for cell dimension is set only once. + * @param grid unstructured grid associated to the mesh. + * @param nbDownCells number of downward entities associated to this vtk type of cell. + * @return + */ +SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) : + _grid(grid), _nbDownCells(nbDownCells) +{ + this->_maxId = 0; + this->_cellIds.clear(); + this->_cellTypes.clear(); + if (_cellDimension.empty()) + getCellDimension( VTK_LINE ); +} + +SMDS_Downward::~SMDS_Downward() +{ +} + +/*! Give or create an entry for downward connectivity structure relative to a cell. + * If the entry already exists, just return its id, otherwise, create it. + * The internal storage memory is allocated if needed. + * The SMDS_UnstructuredGrid::_cellIdToDownId vector is completed for vtkUnstructuredGrid cells. + * @param vtkId for a vtkUnstructuredGrid cell or -1 (default) for a created downward cell. + * @return the rank in downward[vtkType] structure. + */ +int SMDS_Downward::addCell(int vtkId) +{ + int localId = -1; + if (vtkId >= 0) + localId = _grid->CellIdToDownId(vtkId); + if (localId >= 0) + return localId; + + localId = this->_maxId; + this->_maxId++; + this->allocate(_maxId); + if (vtkId >= 0) + { + this->_vtkCellIds[localId] = vtkId; + _grid->setCellIdToDownId(vtkId, localId); + } + this->initCell(localId); + return localId; +} + +/*! generic method do nothing. see derived methods + * + * @param cellId + */ +void SMDS_Downward::initCell(int cellId) +{ +} + +/*! Get the number of downward entities associated to a cell (always the same for a given vtk type of cell) + * + * @param cellId not used here. + * @return + */ +int SMDS_Downward::getNumberOfDownCells(int cellId) +{ + return _nbDownCells; +} + +/*! get a pointer on the downward entities id's associated to a cell. + * @see SMDS_Downward::getNumberOfDownCells for the number of downward entities. + * @see SMDS_Downward::getDownTypes for the vtk cell types associated to the downward entities. + * @param cellId index of the cell in the downward structure relative to a given vtk cell type. + * @return table of downward entities id's. + */ +const int* SMDS_Downward::getDownCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_cellIds[_nbDownCells * cellId]; +} + +/*! get a list of vtk cell types associated to downward entities of a given cell, in the same order + * than the downward entities id's list (@see SMDS_Downward::getDownCells). + * + * @param cellId index of the cell in the downward structure relative to a vtk cell type. + * @return table of downward entities types. + */ +const unsigned char* SMDS_Downward::getDownTypes(int cellId) +{ + return &_cellTypes[0]; +} + +/*! add a downward entity of dimension n-1 (cell or node) to a given cell. + * Actual implementation is done in derived methods. + * @param cellId index of the parent cell (dimension n) in the downward structure relative to a vtk cell type. + * @param lowCellId index of the children cell to add (dimension n-1) + * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add). + */ +void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + ASSERT(0); // must be re-implemented in derived class +} + +/*! add a downward entity of dimension n+1 to a given cell. + * Actual implementation is done in derived methods. + * @param cellId index of the children cell (dimension n) in the downward structure relative to a vtk cell type. + * @param upCellId index of the parent cell to add (dimension n+1) + * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add). + */ +void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType) +{ + ASSERT(0); // must be re-implemented in derived class +} + +int SMDS_Downward::getNodeSet(int cellId, int* nodeSet) +{ + return 0; +} + +// --------------------------------------------------------------------------- + +SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) : + SMDS_Downward(grid, nbDownCells) +{ + _upCellIdsVector.clear(); + _upCellTypesVector.clear(); + _upCellIds.clear(); + _upCellTypes.clear(); + _upCellIndex.clear(); +} + +SMDS_Down1D::~SMDS_Down1D() +{ +} + +/*! clear vectors used to reference 2D cells containing the edge + * + * @param cellId + */ +void SMDS_Down1D::initCell(int cellId) +{ + _upCellIdsVector[cellId].clear(); + _upCellTypesVector[cellId].clear(); +} + +/*! Resize the downward connectivity storage vector if needed. + * + * @param nbElems total number of elements of the same type required + */ +void SMDS_Down1D::allocate(int nbElems) +{ + if (nbElems >= _vtkCellIds.size()) + { + _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); + _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); + _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize); + _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize); + } +} + +void SMDS_Down1D::compactStorage() +{ + _cellIds.resize(_nbDownCells * _maxId); + _vtkCellIds.resize(_maxId); + + int sizeUpCells = 0; + for (int i = 0; i < _maxId; i++) + sizeUpCells += _upCellIdsVector[i].size(); + _upCellIds.resize(sizeUpCells, -1); + _upCellTypes.resize(sizeUpCells); + _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [ + int current = 0; + for (int i = 0; i < _maxId; i++) + { + _upCellIndex[i] = current; + for (int j = 0; j < _upCellIdsVector[i].size(); j++) + { + _upCellIds[current] = _upCellIdsVector[i][j]; + _upCellTypes[current] = _upCellTypesVector[i][j]; + current++; + } + } + _upCellIndex[_maxId] = current; + + _upCellIdsVector.clear(); + _upCellTypesVector.clear(); +} + +void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int nbFaces = _upCellIdsVector[cellId].size(); + for (int i = 0; i < nbFaces; i++) + { + if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType)) + { + return; // already done + } + } + _upCellIdsVector[cellId].push_back(upCellId); + _upCellTypesVector[cellId].push_back(aType); +} + +int SMDS_Down1D::getNumberOfUpCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return _upCellIndex[cellId + 1] - _upCellIndex[cellId]; +} + +const int* SMDS_Down1D::getUpCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellIds[_upCellIndex[cellId]]; +} + +const unsigned char* SMDS_Down1D::getUpTypes(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellTypes[_upCellIndex[cellId]]; +} + +void SMDS_Down1D::getNodeIds(int cellId, std::set& nodeSet) +{ + for (int i = 0; i < _nbDownCells; i++) + nodeSet.insert(_cellIds[_nbDownCells * cellId + i]); +} + +int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet) +{ + for (int i = 0; i < _nbDownCells; i++) + nodeSet[i] = _cellIds[_nbDownCells * cellId + i]; + return _nbDownCells; +} + +void SMDS_Down1D::setNodes(int cellId, int vtkId) +{ + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + _grid->GetCellPoints(vtkId, npts, pts); + // MESSAGE(vtkId << " " << npts << " " << _nbDownCells); + //ASSERT(npts == _nbDownCells); + for (int i = 0; i < npts; i++) + { + _cellIds[_nbDownCells * cellId + i] = pts[i]; + } +} + +void SMDS_Down1D::setNodes(int cellId, const int* nodeIds) +{ + //ASSERT(nodeIds.size() == _nbDownCells); + for (int i = 0; i < _nbDownCells; i++) + { + _cellIds[_nbDownCells * cellId + i] = nodeIds[i]; + } +} + +/*! Build the list of vtkUnstructuredGrid cells containing the edge. + * We keep in the list the cells that contains all the nodes, we keep only volumes and faces. + * @param cellId id of the edge in the downward structure + * @param vtkIds vector of vtk id's + * @return number of vtk cells (size of vector) + */ +int SMDS_Down1D::computeVtkCells(int cellId, std::vector& vtkIds) +{ + vtkIds.clear(); + + // --- find all the cells the points belong to, and how many of the points belong to a given cell + + int *pts = &_cellIds[_nbDownCells * cellId]; + int ncells = this->computeVtkCells(pts, vtkIds); + return ncells; +} + +/*! Build the list of vtkUnstructuredGrid cells containing the edge. + * + * @param pts list of points id's defining an edge + * @param vtkIds vector of vtk id's + * @return number of vtk cells (size of vector) + */ +int SMDS_Down1D::computeVtkCells(int *pts, std::vector& vtkIds) +{ + + // --- find all the cells the points belong to, and how many of the points belong to a given cell + + int cellIds[1000]; + int cellCnt[1000]; + int cnt = 0; + for (int i = 0; i < _nbDownCells; i++) + { + vtkIdType point = pts[i]; + int numCells = _grid->GetLinks()->GetNcells(point); + vtkIdType *cells = _grid->GetLinks()->GetCells(point); + for (int j = 0; j < numCells; j++) + { + int vtkCellId = cells[j]; + bool found = false; + for (int k = 0; k < cnt; k++) + { + if (cellIds[k] == vtkCellId) + { + cellCnt[k] += 1; + found = true; + break; + } + } + if (!found) + { + cellIds[cnt] = vtkCellId; + cellCnt[cnt] = 1; + // TODO ASSERT(cnt<1000); + cnt++; + } + } + } + + // --- find the face and volume cells: they contains all the points and are of type volume or face + + int ncells = 0; + for (int i = 0; i < cnt; i++) + { + if (cellCnt[i] == _nbDownCells) + { + int vtkElemId = cellIds[i]; + int vtkType = _grid->GetCellType(vtkElemId); + if (SMDS_Downward::getCellDimension(vtkType) > 1) + { + vtkIds.push_back(vtkElemId); + ncells++; + } + } + } + + return ncells; +} + +/*! Build the list of downward faces from a list of vtk cells. + * + * @param cellId id of the edge in the downward structure + * @param vtkIds vector of vtk id's + * @param downFaces vector of face id's in downward structures + * @param downTypes vector of face types + * @return number of downward faces + */ +int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes) +{ + int *pts = &_cellIds[_nbDownCells * cellId]; + int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes); + return nbFaces; +} + +/*! Build the list of downward faces from a list of vtk cells. + * + * @param pts list of points id's defining an edge + * @param vtkIds vector of vtk id's + * @param downFaces vector of face id's in downward structures + * @param downTypes vector of face types + * @return number of downward faces + */ +int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes) +{ + int cnt = 0; + for (int i = 0; i < nbcells; i++) + { + int vtkId = vtkIds[i]; + int vtkType = _grid->GetCellType(vtkId); + if (SMDS_Downward::getCellDimension(vtkType) == 2) + { + int faceId = _grid->CellIdToDownId(vtkId); + downFaces[cnt] = faceId; + downTypes[cnt] = vtkType; + cnt++; + } + else if (SMDS_Downward::getCellDimension(vtkType) == 3) + { + int volId = _grid->CellIdToDownId(vtkId); + SMDS_Downward * downvol = _grid->getDownArray(vtkType); + //const int *downIds = downvol->getDownCells(volId); + const unsigned char* downTypesVol = downvol->getDownTypes(volId); + int nbFaces = downvol->getNumberOfDownCells(volId); + const int* faceIds = downvol->getDownCells(volId); + for (int n = 0; n < nbFaces; n++) + { + SMDS_Down2D *downFace = static_cast (_grid->getDownArray(downTypesVol[n])); + bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells); + if (isInFace) + { + bool alreadySet = false; + for (int k = 0; k < cnt; k++) + if (faceIds[n] == downFaces[k]) + { + alreadySet = true; + break; + } + if (!alreadySet) + { + downFaces[cnt] = faceIds[n]; + downTypes[cnt] = downTypesVol[n]; + cnt++; + } + } + } + } + } + return cnt; +} + +// --------------------------------------------------------------------------- + +SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) : + SMDS_Downward(grid, nbDownCells) +{ + _upCellIds.clear(); + _upCellTypes.clear(); + _tempNodes.clear(); + _nbNodes = 0; +} + +SMDS_Down2D::~SMDS_Down2D() +{ +} + +int SMDS_Down2D::getNumberOfUpCells(int cellId) +{ + int nbup = 0; + if (_upCellIds[2 * cellId] >= 0) + nbup++; + if (_upCellIds[2 * cellId + 1] >= 0) + nbup++; + return nbup; +} + +const int* SMDS_Down2D::getUpCells(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellIds[2 * cellId]; +} + +const unsigned char* SMDS_Down2D::getUpTypes(int cellId) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + return &_upCellTypes[2 * cellId]; +} + +void SMDS_Down2D::getNodeIds(int cellId, std::set& nodeSet) +{ + for (int i = 0; i < _nbDownCells; i++) + { + int downCellId = _cellIds[_nbDownCells * cellId + i]; + unsigned char cellType = _cellTypes[i]; + this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet); + } +} + +/*! Find in vtkUnstructuredGrid the volumes containing a face already stored in vtkUnstructuredGrid. + * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses + * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. + * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. + * @param cellId the face cell id in vkUnstructuredGrid + * @param ids a couple of vtkId, initialized at -1 (no parent volume) + * @return number of volumes (0, 1 or 2) + */ +int SMDS_Down2D::computeVolumeIds(int cellId, int* ids) +{ + // --- find point id's of the face + + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + _grid->GetCellPoints(cellId, npts, pts); + vector nodes; + for (int i = 0; i < npts; i++) + nodes.push_back(pts[i]); + int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids); + return nvol; +} + +/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes + * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses + * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. + * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. + * @param faceByNodes + * @param ids a couple of vtkId, initialized at -1 (no parent volume) + * @return number of volumes (0, 1 or 2) + */ +int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids) +{ + int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids); + return nvol; +} + +/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes + * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses + * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes. + * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid. + * @param pts array of vtk node id's + * @param npts number of nodes + * @param ids + * @return number of volumes (0, 1 or 2) + */ +int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids) +{ + + // --- find all the cells the points belong to, and how many of the points belong to a given cell + + int cellIds[1000]; + int cellCnt[1000]; + int cnt = 0; + for (int i = 0; i < npts; i++) + { + vtkIdType point = pts[i]; + int numCells = _grid->GetLinks()->GetNcells(point); + //MESSAGE("cells pour " << i << " " << numCells); + vtkIdType *cells = _grid->GetLinks()->GetCells(point); + for (int j = 0; j < numCells; j++) + { + int vtkCellId = cells[j]; + bool found = false; + for (int k = 0; k < cnt; k++) + { + if (cellIds[k] == vtkCellId) + { + cellCnt[k] += 1; + found = true; + break; + } + } + if (!found) + { + cellIds[cnt] = vtkCellId; + cellCnt[cnt] = 1; + // TODO ASSERT(cnt<1000); + cnt++; + } + } + } + + // --- find the volume cells: they contains all the points and are of type volume + + int nvol = 0; + for (int i = 0; i < cnt; i++) + { + //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]); + if (cellCnt[i] == npts) + { + int vtkElemId = cellIds[i]; + int vtkType = _grid->GetCellType(vtkElemId); + if (SMDS_Downward::getCellDimension(vtkType) == 3) + { + ids[nvol] = vtkElemId; // store the volume id in given vector + nvol++; + } + } + if (nvol == 2) + break; + } + + return nvol; +} + +void SMDS_Down2D::setTempNodes(int cellId, int vtkId) +{ + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + _grid->GetCellPoints(vtkId, npts, pts); + // MESSAGE(vtkId << " " << npts << " " << _nbNodes); + //ASSERT(npts == _nbNodes); + for (int i = 0; i < npts; i++) + { + _tempNodes[_nbNodes * cellId + i] = pts[i]; + } +} + +void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes) +{ + for (int i = 0; i < faceByNodes.nbNodes; i++) + _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i]; +} + +/*! Find if all the nodes belongs to the face. + * + * @param cellId the face cell Id + * @param nodeSet set of node id's to be found in the face list of nodes + * @return + */ +bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts) +{ + int nbFound = 0; + int *nodes = &_tempNodes[_nbNodes * cellId]; + for (int j = 0; j < npts; j++) + { + int point = pts[j]; + for (int i = 0; i < _nbNodes; i++) + { + if (nodes[i] == point) + { + nbFound++; + break; + } + } + } + return (nbFound == npts); +} + +/*! Resize the downward connectivity storage vector if needed. + * + * @param nbElems total number of elements of the same type required + */ +void SMDS_Down2D::allocate(int nbElems) +{ + if (nbElems >= _vtkCellIds.size()) + { + _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); + _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); + _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1); + _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1); + _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1); + } +} + +void SMDS_Down2D::compactStorage() +{ + _cellIds.resize(_nbDownCells * _maxId); + _upCellIds.resize(2 * _maxId); + _upCellTypes.resize(2 * _maxId); + _vtkCellIds.resize(_maxId); + _tempNodes.clear(); +} + +void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + int *vols = &_upCellIds[2 * cellId]; + unsigned char *types = &_upCellTypes[2 * cellId]; + for (int i = 0; i < 2; i++) + { + if (vols[i] < 0) + { + vols[i] = upCellId; // use non affected volume + types[i] = aType; + return; + } + if ((vols[i] == upCellId) && (types[i] == aType)) // already done + return; + } + ASSERT(0); +} + +int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet) +{ + for (int i = 0; i < _nbNodes; i++) + nodeSet[i] = _tempNodes[_nbNodes * cellId + i]; + return _nbNodes; +} + +int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes) +{ + int *edges = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i])) + { + int nodeSet[3]; + int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet); + bool found = false; + for (int j = 0; j < npts; j++) + { + int point = edgeByNodes.nodeIds[j]; + found = false; + for (int k = 0; k < npts; k++) + { + if (nodeSet[k] == point) + { + found = true; + break; + } + } + if (!found) + break; + } + if (found) + return edges[i]; + } + } + return -1; +} + +// --------------------------------------------------------------------------- + +SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) : + SMDS_Downward(grid, nbDownCells) +{ +} + +SMDS_Down3D::~SMDS_Down3D() +{ +} + +void SMDS_Down3D::allocate(int nbElems) +{ + if (nbElems >= _vtkCellIds.size()) + { + _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1); + _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1); + } +} + +void SMDS_Down3D::compactStorage() +{ + // nothing to do, size was known before +} + +int SMDS_Down3D::getNumberOfUpCells(int cellId) +{ + return 0; +} + +const int* SMDS_Down3D::getUpCells(int cellId) +{ + return 0; +} + +const unsigned char* SMDS_Down3D::getUpTypes(int cellId) +{ + return 0; +} + +void SMDS_Down3D::getNodeIds(int cellId, std::set& nodeSet) +{ + int vtkId = this->_vtkCellIds[cellId]; + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(vtkId, npts, nodes); + for (int i = 0; i < npts; i++) + nodeSet.insert(nodes[i]); +} + +int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes) +{ + int *faces = &_cellIds[_nbDownCells * cellId]; + int npoints = 0; + + for (int i = 0; i < _nbDownCells; i++) + { + if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i])) + { + if (npoints == 0) + npoints = faceByNodes.nbNodes; + + int nodeSet[10]; + int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet); + if (npts != npoints) + continue; // skip this face + bool found = false; + for (int j = 0; j < npts; j++) + { + int point = faceByNodes.nodeIds[j]; + found = false; + for (int k = 0; k < npts; k++) + { + if (nodeSet[k] == point) + { + found = true; + break; // point j is in the 2 faces, skip remaining k values + } + } + if (!found) + break; // point j is not in the 2 faces, skip the remaining tests + } + if (found) + return faces[i]; + } + } + return -1; +} + +// --------------------------------------------------------------------------- + +SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) : + SMDS_Down1D(grid, 2) +{ + _cellTypes.push_back(VTK_VERTEX); + _cellTypes.push_back(VTK_VERTEX); +} + +SMDS_DownEdge::~SMDS_DownEdge() +{ +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) : + SMDS_Down1D(grid, 3) +{ + _cellTypes.push_back(VTK_VERTEX); + _cellTypes.push_back(VTK_VERTEX); + _cellTypes.push_back(VTK_VERTEX); +} + +SMDS_DownQuadEdge::~SMDS_DownQuadEdge() +{ +} + +// --------------------------------------------------------------------------- + +SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 3) +{ + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _nbNodes = 3; +} + +SMDS_DownTriangle::~SMDS_DownTriangle() +{ +} + +void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 3; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nbNodes = 2; + edgesWithNodes.elems[0].vtkType = VTK_LINE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nbNodes = 2; + edgesWithNodes.elems[1].vtkType = VTK_LINE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[2].nbNodes = 2; + edgesWithNodes.elems[2].vtkType = VTK_LINE; +} + +void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_LINE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 3) +{ + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _nbNodes = 6; +} + +SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle() +{ +} + +void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 3; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nodeIds[2] = nodes[3]; + edgesWithNodes.elems[0].nbNodes = 3; + edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nodeIds[2] = nodes[4]; + edgesWithNodes.elems[1].nbNodes = 3; + edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[2].nodeIds[2] = nodes[5]; + edgesWithNodes.elems[2].nbNodes = 3; + edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE; +} + +void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_QUADRATIC_EDGE); + int *edges = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (edges[i] < 0) + { + edges[i] = lowCellId; + return; + } + if (edges[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 4) +{ + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _cellTypes.push_back(VTK_LINE); + _nbNodes = 4; +} + +SMDS_DownQuadrangle::~SMDS_DownQuadrangle() +{ +} + +void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 4; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nbNodes = 2; + edgesWithNodes.elems[0].vtkType = VTK_LINE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nbNodes = 2; + edgesWithNodes.elems[1].vtkType = VTK_LINE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[3]; + edgesWithNodes.elems[2].nbNodes = 2; + edgesWithNodes.elems[2].vtkType = VTK_LINE; + + edgesWithNodes.elems[3].nodeIds[0] = nodes[3]; + edgesWithNodes.elems[3].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[3].nbNodes = 2; + edgesWithNodes.elems[3].vtkType = VTK_LINE; +} + +void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_LINE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) : + SMDS_Down2D(grid, 4) +{ + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _cellTypes.push_back(VTK_QUADRATIC_EDGE); + _nbNodes = 8; +} + +SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle() +{ +} + +void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes) +{ + int *nodes = &_tempNodes[_nbNodes * cellId]; + edgesWithNodes.nbElems = 4; + + edgesWithNodes.elems[0].nodeIds[0] = nodes[0]; + edgesWithNodes.elems[0].nodeIds[1] = nodes[1]; + edgesWithNodes.elems[0].nodeIds[2] = nodes[4]; + edgesWithNodes.elems[0].nbNodes = 3; + edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[1].nodeIds[0] = nodes[1]; + edgesWithNodes.elems[1].nodeIds[1] = nodes[2]; + edgesWithNodes.elems[1].nodeIds[2] = nodes[5]; + edgesWithNodes.elems[1].nbNodes = 3; + edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[2].nodeIds[0] = nodes[2]; + edgesWithNodes.elems[2].nodeIds[1] = nodes[3]; + edgesWithNodes.elems[2].nodeIds[2] = nodes[6]; + edgesWithNodes.elems[2].nbNodes = 3; + edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE; + + edgesWithNodes.elems[3].nodeIds[0] = nodes[3]; + edgesWithNodes.elems[3].nodeIds[1] = nodes[0]; + edgesWithNodes.elems[3].nodeIds[2] = nodes[7]; + edgesWithNodes.elems[3].nbNodes = 3; + edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE; +} + +void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_QUADRATIC_EDGE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +// --------------------------------------------------------------------------- + +SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 4) +{ + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); +} + +SMDS_DownTetra::~SMDS_DownTetra() +{ +} + +void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; + int ids[12] = { 0, 1, 2, 0, 3, 1, 2, 3, 0, 1, 3, 2 }; +//int ids[12] = { 2, 1, 0, 1, 3, 0, 0, 3, 2, 2, 3, 1 }; + for (int k = 0; k < 4; k++) + { + tofind.clear(); + for (int i = 0; i < 3; i++) + tofind.insert(nodes[ids[3 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 3; i++) + orderedNodes[i] = nodes[ids[3 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_TRIANGLE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The linear tetrahedron is defined by four points. + * @see vtkTetra.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 4; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nbNodes = 3; + facesWithNodes.elems[0].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[3]; + facesWithNodes.elems[1].nbNodes = 3; + facesWithNodes.elems[1].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[3]; + facesWithNodes.elems[2].nbNodes = 3; + facesWithNodes.elems[2].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[3]; + facesWithNodes.elems[3].nbNodes = 3; + facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 4) +{ + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); +} + +SMDS_DownQuadTetra::~SMDS_DownQuadTetra() +{ +} + +void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; + int ids[24] = { 0, 1, 2, 4, 5, 6, 0, 3, 1, 7, 8, 4, 2, 3, 0, 9, 7, 6, 1, 3, 2, 8, 9, 5 }; +//int ids[24] = { 2, 1, 0, 5, 4, 6, 1, 3, 0, 8, 7, 4, 0, 3, 2, 7, 9, 6, 2, 3, 1, 9, 8, 5 }; + for (int k = 0; k < 4; k++) + { + tofind.clear(); + for (int i = 0; i < 6; i++) + tofind.insert(nodes[ids[6 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 6; i++) + orderedNodes[i] = nodes[ids[6 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The ordering of the ten points defining the quadratic tetrahedron cell is point id's (0-3,4-9) + * where id's 0-3 are the four tetrahedron vertices; + * and point id's 4-9 are the mid-edge nodes between (0,1), (1,2), (2,0), (0,3), (1,3), and (2,3). + * @see vtkQuadraticTetra.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 4; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[4]; + facesWithNodes.elems[0].nodeIds[4] = nodes[5]; + facesWithNodes.elems[0].nodeIds[5] = nodes[6]; + facesWithNodes.elems[0].nbNodes = 6; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[3]; + facesWithNodes.elems[1].nodeIds[3] = nodes[4]; + facesWithNodes.elems[1].nodeIds[4] = nodes[8]; + facesWithNodes.elems[1].nodeIds[5] = nodes[7]; + facesWithNodes.elems[1].nbNodes = 6; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[3]; + facesWithNodes.elems[2].nodeIds[3] = nodes[6]; + facesWithNodes.elems[2].nodeIds[4] = nodes[9]; + facesWithNodes.elems[2].nodeIds[5] = nodes[7]; + facesWithNodes.elems[2].nbNodes = 6; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[3]; + facesWithNodes.elems[3].nodeIds[3] = nodes[5]; + facesWithNodes.elems[3].nodeIds[4] = nodes[9]; + facesWithNodes.elems[3].nodeIds[5] = nodes[8]; + facesWithNodes.elems[3].nbNodes = 6; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); +} + +SMDS_DownPyramid::~SMDS_DownPyramid() +{ +} + +void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; + int ids[16] = { 0, 1, 2, 3, 0, 3, 4, 3, 2, 4, 2, 1, 4, 1, 0, 4 }; + + tofind.clear(); + for (int i = 0; i < 4; i++) + tofind.insert(nodes[ids[i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 4; i++) + orderedNodes[i] = nodes[ids[i]]; + return; + } + for (int k = 0; k < 4; k++) + { + tofind.clear(); + for (int i = 0; i < 3; i++) + tofind.insert(nodes[ids[4 + 3 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 3; i++) + orderedNodes[i] = nodes[ids[4 + 3 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUAD) + { + if (faces[0] < 0) + { + faces[0] = lowCellId; + return; + } + if (faces[0] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_TRIANGLE); + for (int i = 1; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The pyramid is defined by the five points (0-4) where (0,1,2,3) is the base of the pyramid which, + * using the right hand rule, forms a quadrilateral whose normal points in the direction of the + * pyramid apex at vertex #4. + * @see vtkPyramid.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nbNodes = 4; + facesWithNodes.elems[0].vtkType = VTK_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[4]; + facesWithNodes.elems[1].nbNodes = 3; + facesWithNodes.elems[1].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[1]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nbNodes = 3; + facesWithNodes.elems[2].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[2]; + facesWithNodes.elems[3].nodeIds[1] = nodes[3]; + facesWithNodes.elems[3].nodeIds[2] = nodes[4]; + facesWithNodes.elems[3].nbNodes = 3; + facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[0]; + facesWithNodes.elems[4].nodeIds[2] = nodes[4]; + facesWithNodes.elems[4].nbNodes = 3; + facesWithNodes.elems[4].vtkType = VTK_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); +} + +SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid() +{ +} + +void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; + int ids[32] = { 0, 1, 2, 3, 5, 6, 7, 8, + 0, 3, 4, 8, 12, 9, 3, 2, 4, 7 , 11, 12, 2, 1, 4, 6, 10, 11, 1, 0, 4, 5, 9, 10 }; + + tofind.clear(); + for (int i = 0; i < 4; i++) + tofind.insert(nodes[ids[i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 8; i++) + orderedNodes[i] = nodes[ids[i]]; + return; + } + for (int k = 0; k < 4; k++) + { + tofind.clear(); + for (int i = 0; i < 6; i++) + tofind.insert(nodes[ids[8 + 6 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 6; i++) + orderedNodes[i] = nodes[ids[8 + 6 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUADRATIC_QUAD) + { + if (faces[0] < 0) + { + faces[0] = lowCellId; + return; + } + if (faces[0] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); + for (int i = 1; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The ordering of the thirteen points defining the quadratic pyramid cell is point id's (0-4,5-12) + * where point id's 0-4 are the five corner vertices of the pyramid; followed + * by eight mid-edge nodes (5-12). Note that these mid-edge nodes lie on the edges defined by + * 5(0,1), 6(1,2), 7(2,3), 8(3,0), 9(0,4), 10(1,4), 11(2,4), 12(3,4). + * @see vtkQuadraticPyramid.h in Filtering. + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nodeIds[4] = nodes[5]; + facesWithNodes.elems[0].nodeIds[5] = nodes[6]; + facesWithNodes.elems[0].nodeIds[6] = nodes[7]; + facesWithNodes.elems[0].nodeIds[7] = nodes[8]; + facesWithNodes.elems[0].nbNodes = 8; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[0]; + facesWithNodes.elems[1].nodeIds[1] = nodes[1]; + facesWithNodes.elems[1].nodeIds[2] = nodes[4]; + facesWithNodes.elems[1].nodeIds[3] = nodes[5]; + facesWithNodes.elems[1].nodeIds[4] = nodes[10]; + facesWithNodes.elems[1].nodeIds[5] = nodes[9]; + facesWithNodes.elems[1].nbNodes = 6; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[2].nodeIds[0] = nodes[1]; + facesWithNodes.elems[2].nodeIds[1] = nodes[2]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nodeIds[3] = nodes[6]; + facesWithNodes.elems[2].nodeIds[4] = nodes[11]; + facesWithNodes.elems[2].nodeIds[5] = nodes[10]; + facesWithNodes.elems[2].nbNodes = 6; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[3].nodeIds[0] = nodes[2]; + facesWithNodes.elems[3].nodeIds[1] = nodes[3]; + facesWithNodes.elems[3].nodeIds[2] = nodes[4]; + facesWithNodes.elems[3].nodeIds[3] = nodes[7]; + facesWithNodes.elems[3].nodeIds[4] = nodes[12]; + facesWithNodes.elems[3].nodeIds[5] = nodes[11]; + facesWithNodes.elems[3].nbNodes = 6; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[0]; + facesWithNodes.elems[4].nodeIds[2] = nodes[4]; + facesWithNodes.elems[4].nodeIds[3] = nodes[8]; + facesWithNodes.elems[4].nodeIds[4] = nodes[9]; + facesWithNodes.elems[4].nodeIds[5] = nodes[12]; + facesWithNodes.elems[4].nbNodes = 6; + facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_TRIANGLE); + _cellTypes.push_back(VTK_TRIANGLE); +} + +SMDS_DownPenta::~SMDS_DownPenta() +{ +} + +void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; +//int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 }; + int ids[18] = { 0, 1, 2, 3, 5, 4, 0, 3, 4, 1, 1, 4, 5, 2, 2, 5, 3, 0 }; + + for (int k = 0; k < 2; k++) + { + tofind.clear(); + for (int i = 0; i < 3; i++) + tofind.insert(nodes[ids[3 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 3; i++) + orderedNodes[i] = nodes[ids[3 * k + i]]; + return; + } + } + for (int k = 0; k < 3; k++) + { + tofind.clear(); + for (int i = 0; i < 4; i++) + tofind.insert(nodes[ids[6 + 4 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 4; i++) + orderedNodes[i] = nodes[ids[6 + 4 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUAD) + for (int i = 0; i < 3; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_TRIANGLE); + for (int i = 3; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's. + * A wedge or pentahedron consists of two triangular and three quadrilateral faces + * and is defined by the six points (0-5) where (0,1,2) is the base of the wedge which, + * using the right hand rule, forms a triangle whose normal points outward + * (away from the triangular face (3,4,5)). + * @see vtkWedge.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[2]; + facesWithNodes.elems[0].nodeIds[2] = nodes[5]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nbNodes = 4; + facesWithNodes.elems[0].vtkType = VTK_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[1]; + facesWithNodes.elems[1].nodeIds[1] = nodes[2]; + facesWithNodes.elems[1].nodeIds[2] = nodes[5]; + facesWithNodes.elems[1].nodeIds[3] = nodes[4]; + facesWithNodes.elems[1].nbNodes = 4; + facesWithNodes.elems[1].vtkType = VTK_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nodeIds[3] = nodes[3]; + facesWithNodes.elems[2].nbNodes = 4; + facesWithNodes.elems[2].vtkType = VTK_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[0]; + facesWithNodes.elems[3].nodeIds[1] = nodes[1]; + facesWithNodes.elems[3].nodeIds[2] = nodes[2]; + facesWithNodes.elems[3].nbNodes = 3; + facesWithNodes.elems[3].vtkType = VTK_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[4]; + facesWithNodes.elems[4].nodeIds[2] = nodes[5]; + facesWithNodes.elems[4].nbNodes = 3; + facesWithNodes.elems[4].vtkType = VTK_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 5) +{ + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); + _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE); +} + +SMDS_DownQuadPenta::~SMDS_DownQuadPenta() +{ +} + +void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; +//int ids[18] = { 0, 2, 1, 3, 4, 5, 0, 1, 4, 3, 1, 2, 5, 4, 2, 0, 3, 5 }; + int ids[36] = { 0, 1, 2, 6, 7, 8, 3, 5, 4, 11, 10, 9, + 0, 3, 4, 1, 12, 9, 13, 6, 1, 4, 5, 2, 13, 10, 14, 7, 2, 5, 3, 0, 14, 11, 12, 8 }; + + for (int k = 0; k < 2; k++) + { + tofind.clear(); + for (int i = 0; i < 6; i++) + tofind.insert(nodes[ids[6 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 6; i++) + orderedNodes[i] = nodes[ids[6 * k + i]]; + return; + } + } + for (int k = 0; k < 3; k++) + { + tofind.clear(); + for (int i = 0; i < 8; i++) + tofind.insert(nodes[ids[12 + 8 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 8; i++) + orderedNodes[i] = nodes[ids[12 + 8 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0) && (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + if (aType == VTK_QUADRATIC_QUAD) + for (int i = 0; i < 3; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + else + { + //ASSERT(aType == VTK_QUADRATIC_TRIANGLE); + for (int i = 3; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The quadratic wedge (or pentahedron) is defined by fifteen points. + * The ordering of the fifteen points defining the cell is point id's (0-5,6-14) + * where point id's 0-5 are the six corner vertices of the wedge, followed by + * nine mid-edge nodes (6-14). Note that these mid-edge nodes lie on the edges defined by + * (0,1), (1,2), (2,0), (3,4), (4,5), (5,3), (0,3), (1,4), (2,5). + * @see vtkQuadraticWedge.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 5; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[2]; + facesWithNodes.elems[0].nodeIds[2] = nodes[5]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nodeIds[4] = nodes[8]; + facesWithNodes.elems[0].nodeIds[5] = nodes[14]; + facesWithNodes.elems[0].nodeIds[6] = nodes[11]; + facesWithNodes.elems[0].nodeIds[7] = nodes[12]; + facesWithNodes.elems[0].nbNodes = 8; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[1]; + facesWithNodes.elems[1].nodeIds[1] = nodes[2]; + facesWithNodes.elems[1].nodeIds[2] = nodes[5]; + facesWithNodes.elems[1].nodeIds[3] = nodes[4]; + facesWithNodes.elems[1].nodeIds[4] = nodes[7]; + facesWithNodes.elems[1].nodeIds[5] = nodes[14]; + facesWithNodes.elems[1].nodeIds[6] = nodes[10]; + facesWithNodes.elems[1].nodeIds[7] = nodes[13]; + facesWithNodes.elems[1].nbNodes = 8; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[4]; + facesWithNodes.elems[2].nodeIds[3] = nodes[3]; + facesWithNodes.elems[2].nodeIds[4] = nodes[6]; + facesWithNodes.elems[2].nodeIds[5] = nodes[13]; + facesWithNodes.elems[2].nodeIds[6] = nodes[9]; + facesWithNodes.elems[2].nodeIds[7] = nodes[12]; + facesWithNodes.elems[2].nbNodes = 8; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[0]; + facesWithNodes.elems[3].nodeIds[1] = nodes[1]; + facesWithNodes.elems[3].nodeIds[2] = nodes[2]; + facesWithNodes.elems[3].nodeIds[3] = nodes[6]; + facesWithNodes.elems[3].nodeIds[4] = nodes[7]; + facesWithNodes.elems[3].nodeIds[5] = nodes[8]; + facesWithNodes.elems[3].nbNodes = 6; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE; + + facesWithNodes.elems[4].nodeIds[0] = nodes[3]; + facesWithNodes.elems[4].nodeIds[1] = nodes[4]; + facesWithNodes.elems[4].nodeIds[2] = nodes[5]; + facesWithNodes.elems[4].nodeIds[3] = nodes[9]; + facesWithNodes.elems[4].nodeIds[4] = nodes[10]; + facesWithNodes.elems[4].nodeIds[5] = nodes[11]; + facesWithNodes.elems[4].nbNodes = 6; + facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE; +} + +// --------------------------------------------------------------------------- + +SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 6) +{ + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); + _cellTypes.push_back(VTK_QUAD); +} + +SMDS_DownHexa::~SMDS_DownHexa() +{ +} + +void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; +//int ids[24] = { 0, 1, 2, 3, 7, 6, 5, 4, 4, 0, 3, 7, 5, 1, 0, 4, 6, 2, 1, 5, 7, 3, 2, 6}; + int ids[24] = { 3, 2, 1, 0, 4, 5, 6, 7, 7, 3, 0, 4, 4, 0, 1, 5, 5, 1, 2, 6, 6, 2, 3, 7}; + for (int k = 0; k < 6; k++) // loop on the 6 faces + { + tofind.clear(); + for (int i = 0; i < 4; i++) + tofind.insert(nodes[ids[4 * k + i]]); // node ids of the face i + if (setNodes == tofind) + { + for (int i = 0; i < 4; i++) + orderedNodes[i] = nodes[ids[4 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); + MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]); +} + +void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); + // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The hexahedron is defined by the eight points (0-7), where (0,1,2,3) is the base + * of the hexahedron which, using the right hand rule, forms a quadrilateral whose normal + * points in the direction of the opposite face (4,5,6,7). + * @see vtkHexahedron.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 6; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nbNodes = 4; + facesWithNodes.elems[0].vtkType = VTK_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[4]; + facesWithNodes.elems[1].nodeIds[1] = nodes[5]; + facesWithNodes.elems[1].nodeIds[2] = nodes[6]; + facesWithNodes.elems[1].nodeIds[3] = nodes[7]; + facesWithNodes.elems[1].nbNodes = 4; + facesWithNodes.elems[1].vtkType = VTK_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[5]; + facesWithNodes.elems[2].nodeIds[3] = nodes[4]; + facesWithNodes.elems[2].nbNodes = 4; + facesWithNodes.elems[2].vtkType = VTK_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[6]; + facesWithNodes.elems[3].nodeIds[3] = nodes[5]; + facesWithNodes.elems[3].nbNodes = 4; + facesWithNodes.elems[3].vtkType = VTK_QUAD; + + facesWithNodes.elems[4].nodeIds[0] = nodes[2]; + facesWithNodes.elems[4].nodeIds[1] = nodes[6]; + facesWithNodes.elems[4].nodeIds[2] = nodes[7]; + facesWithNodes.elems[4].nodeIds[3] = nodes[3]; + facesWithNodes.elems[4].nbNodes = 4; + facesWithNodes.elems[4].vtkType = VTK_QUAD; + + facesWithNodes.elems[5].nodeIds[0] = nodes[3]; + facesWithNodes.elems[5].nodeIds[1] = nodes[7]; + facesWithNodes.elems[5].nodeIds[2] = nodes[4]; + facesWithNodes.elems[5].nodeIds[3] = nodes[0]; + facesWithNodes.elems[5].nbNodes = 4; + facesWithNodes.elems[5].vtkType = VTK_QUAD; +} + +// --------------------------------------------------------------------------- + +SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) : + SMDS_Down3D(grid, 6) +{ + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); + _cellTypes.push_back(VTK_QUADRATIC_QUAD); +} + +SMDS_DownQuadHexa::~SMDS_DownQuadHexa() +{ +} + +void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) +{ + set setNodes; + setNodes.clear(); + for (int i = 0; i < orderedNodes.size(); i++) + setNodes.insert(orderedNodes[i]); + //MESSAGE("cellId = " << cellId); + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes); + + set tofind; + //int ids[24] = { 3, 2, 1, 0, 4, 5, 6, 7, 7, 3, 0, 4, 4, 0, 1, 5, 5, 1, 2, 6, 6, 2, 3, 7}; + int ids[48] = { 3, 2, 1, 0,10, 9, 8,11, 4, 5, 6, 7,12,13,14,15, 7, 3, 0, 4,19,11,16,15, + 4, 0, 1, 5,16, 8,17,12, 5, 1, 2, 6,17, 9,18,13, 6, 2, 3, 7,18,10,19,14}; + for (int k = 0; k < 6; k++) + { + tofind.clear(); + for (int i = 0; i < 8; i++) + tofind.insert(nodes[ids[8 * k + i]]); + if (setNodes == tofind) + { + for (int i = 0; i < 8; i++) + orderedNodes[i] = nodes[ids[8 * k + i]]; + return; + } + } + MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId])); + MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]); + MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]); +} + +void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType) +{ + //ASSERT((cellId >=0)&& (cellId < _maxId)); + int *faces = &_cellIds[_nbDownCells * cellId]; + for (int i = 0; i < _nbDownCells; i++) + { + if (faces[i] < 0) + { + faces[i] = lowCellId; + return; + } + if (faces[i] == lowCellId) + return; + } + ASSERT(0); +} + +/*! Create a list of faces described by a vtk Type and an ordered set of Node Id's + * The ordering of the twenty points defining the quadratic hexahedron cell is point id's (0-7,8-19) + * where point id's 0-7 are the eight corner vertices of the cube, followed by twelve mid-edge nodes (8-19). + * Note that these mid-edge nodes lie on the edges defined by + * (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7). + * @see vtkQuadraticHexahedron.h in Filtering + * @param cellId volumeId in vtkUnstructuredGrid + * @param facesWithNodes vector of face descriptors to be filled + */ +void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) +{ + // --- find point id's of the volume + + vtkIdType npts = 0; + vtkIdType *nodes; // will refer to the point id's of the volume + _grid->GetCellPoints(cellId, npts, nodes); + + // --- create all the ordered list of node id's for each face + + facesWithNodes.nbElems = 6; + + facesWithNodes.elems[0].nodeIds[0] = nodes[0]; + facesWithNodes.elems[0].nodeIds[1] = nodes[1]; + facesWithNodes.elems[0].nodeIds[2] = nodes[2]; + facesWithNodes.elems[0].nodeIds[3] = nodes[3]; + facesWithNodes.elems[0].nodeIds[4] = nodes[8]; + facesWithNodes.elems[0].nodeIds[5] = nodes[9]; + facesWithNodes.elems[0].nodeIds[6] = nodes[10]; + facesWithNodes.elems[0].nodeIds[7] = nodes[11]; + facesWithNodes.elems[0].nbNodes = 8; + facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[1].nodeIds[0] = nodes[4]; + facesWithNodes.elems[1].nodeIds[1] = nodes[5]; + facesWithNodes.elems[1].nodeIds[2] = nodes[6]; + facesWithNodes.elems[1].nodeIds[3] = nodes[7]; + facesWithNodes.elems[1].nodeIds[4] = nodes[12]; + facesWithNodes.elems[1].nodeIds[5] = nodes[13]; + facesWithNodes.elems[1].nodeIds[6] = nodes[14]; + facesWithNodes.elems[1].nodeIds[7] = nodes[15]; + facesWithNodes.elems[1].nbNodes = 8; + facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[2].nodeIds[0] = nodes[0]; + facesWithNodes.elems[2].nodeIds[1] = nodes[1]; + facesWithNodes.elems[2].nodeIds[2] = nodes[5]; + facesWithNodes.elems[2].nodeIds[3] = nodes[4]; + facesWithNodes.elems[2].nodeIds[4] = nodes[8]; + facesWithNodes.elems[2].nodeIds[5] = nodes[17]; + facesWithNodes.elems[2].nodeIds[6] = nodes[12]; + facesWithNodes.elems[2].nodeIds[7] = nodes[16]; + facesWithNodes.elems[2].nbNodes = 8; + facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[3].nodeIds[0] = nodes[1]; + facesWithNodes.elems[3].nodeIds[1] = nodes[2]; + facesWithNodes.elems[3].nodeIds[2] = nodes[6]; + facesWithNodes.elems[3].nodeIds[3] = nodes[5]; + facesWithNodes.elems[3].nodeIds[4] = nodes[9]; + facesWithNodes.elems[3].nodeIds[5] = nodes[18]; + facesWithNodes.elems[3].nodeIds[6] = nodes[13]; + facesWithNodes.elems[3].nodeIds[7] = nodes[17]; + facesWithNodes.elems[3].nbNodes = 8; + facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[4].nodeIds[0] = nodes[2]; + facesWithNodes.elems[4].nodeIds[1] = nodes[6]; + facesWithNodes.elems[4].nodeIds[2] = nodes[7]; + facesWithNodes.elems[4].nodeIds[3] = nodes[3]; + facesWithNodes.elems[4].nodeIds[4] = nodes[18]; + facesWithNodes.elems[4].nodeIds[5] = nodes[14]; + facesWithNodes.elems[4].nodeIds[6] = nodes[19]; + facesWithNodes.elems[4].nodeIds[7] = nodes[10]; + facesWithNodes.elems[4].nbNodes = 8; + facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD; + + facesWithNodes.elems[5].nodeIds[0] = nodes[3]; + facesWithNodes.elems[5].nodeIds[1] = nodes[7]; + facesWithNodes.elems[5].nodeIds[2] = nodes[4]; + facesWithNodes.elems[5].nodeIds[3] = nodes[0]; + facesWithNodes.elems[5].nodeIds[4] = nodes[19]; + facesWithNodes.elems[5].nodeIds[5] = nodes[15]; + facesWithNodes.elems[5].nodeIds[6] = nodes[16]; + facesWithNodes.elems[5].nodeIds[7] = nodes[11]; + facesWithNodes.elems[5].nbNodes = 8; + facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD; +} + +// --------------------------------------------------------------------------- + diff --git a/src/SMDS/SMDS_Downward.hxx b/src/SMDS/SMDS_Downward.hxx new file mode 100644 index 000000000..56854fd1d --- /dev/null +++ b/src/SMDS/SMDS_Downward.hxx @@ -0,0 +1,381 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: SMDS_Downward.hxx +// Created: Jun 3, 2010 +// Author: prascle + +#ifndef SMDS_DOWNWARD_HXX_ +#define SMDS_DOWNWARD_HXX_ + +#include "SMDS_UnstructuredGrid.hxx" + +#include +#include + +typedef struct +{ + int nodeIds[8]; //!< max number of nodes in a face or edge: quad quad = 8 + int nbNodes; + unsigned char vtkType; +} ElemByNodesType; // TODO resize for polyhedrons + +typedef struct +{ + ElemByNodesType elems[6]; //!< max number of faces in a volume or edges in a face : hexahedron = 6 + int nbElems; +} ListElemByNodesType; // TODO resize for polyhedrons + +class DownIdType +{ +public: + DownIdType(int a, unsigned char b) : + cellId(a), cellType(b) + { + } + int cellId; + unsigned char cellType; +}; + +struct DownIdCompare +{ + bool operator ()(const DownIdType e1, const DownIdType e2) const + { + if (e1.cellId == e2.cellId) + return (e1.cellType < e2.cellType); + else + return (e1.cellId < e2.cellId); + } +}; + +class SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; + friend class SMDS_Down2D; + friend class SMDS_Down3D; +public: + virtual int getNumberOfDownCells(int cellId); + virtual const int* getDownCells(int cellId); + virtual const unsigned char* getDownTypes(int cellId); + virtual int getNumberOfUpCells(int cellId) = 0; + virtual const int* getUpCells(int cellId) = 0; + virtual const unsigned char* getUpTypes(int cellId) = 0; + virtual void getNodeIds(int cellId, std::set& nodeSet) = 0; + virtual int getNodes(int cellId, int* nodevec) {return 0; } + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes) {}; + int getVtkCellId(int cellId) + { + return _vtkCellIds[cellId]; + } + int getMaxId() + { + return _maxId; + } + static int getCellDimension(unsigned char cellType); +protected: + SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Downward(); + int addCell(int vtkId = -1); + virtual void initCell(int cellId); + virtual void allocate(int nbElems) = 0; + virtual void compactStorage() = 0; + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual int getNodeSet(int cellId, int* nodeSet); + + SMDS_UnstructuredGrid* _grid; + int _maxId; + int _nbDownCells; //!< the same number for all cells of a derived class + std::vector _cellIds; //!< growing size: all the down cell id's, size = _maxId * _nbDownCells + std::vector _vtkCellIds; //!< growing size: size = _maxId, either vtkId or -1 + std::vector _cellTypes; //!< fixed size: the same vector for all cells of a derived class + + static std::vector _cellDimension; //!< conversion table: type --> dimension +}; + +class SMDS_Down1D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); + virtual void getNodeIds(int cellId, std::set& nodeSet); + virtual int getNodes(int cellId, int* nodevec) { return getNodeSet(cellId, nodevec); } +protected: + SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down1D(); + virtual void initCell(int cellId); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's + virtual int getNodeSet(int cellId, int* nodeSet); + void setNodes(int cellId, int vtkId); + void setNodes(int cellId, const int* nodeIds); + int computeVtkCells(int cellId, std::vector& vtkIds); + int computeVtkCells(int* pts, std::vector& vtkIds); + int computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes); + int computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes); + + std::vector > _upCellIdsVector; //!< the number of faces sharing an edge is not known + std::vector > _upCellTypesVector; //!< the number of faces sharing an edge is not known + std::vector _upCellIds; //!< compacted storage after connectivity calculation + std::vector _upCellTypes; //!< compacted storage after connectivity calculation + std::vector _upCellIndex; //!< compacted storage after connectivity calculation +}; + +class SMDS_Down2D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; + friend class SMDS_Down1D; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); + virtual void getNodeIds(int cellId, std::set& nodeSet); +protected: + SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down2D(); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void addUpCell(int cellId, int upCellId, unsigned char aType); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0; + virtual int getNodeSet(int cellId, int* nodeSet); + int computeVolumeIds(int cellId, int* ids); + int computeVolumeIds(ElemByNodesType& faceByNodes, int* ids); + int computeVolumeIdsFromNodesFace(int* nodes, int nbNodes, int* ids); + void setTempNodes(int cellId, int vtkId); + void setTempNodes(int cellId, ElemByNodesType& faceByNodes); + bool isInFace(int cellId, int *pts, int npts); + int FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes); + + std::vector _upCellIds; //!< 2 volumes max. per face + std::vector _upCellTypes; //!< 2 volume types per face + std::vector _tempNodes; //!< temporary storage of nodes, until downward connectivity completion + int _nbNodes; //!< number of nodes in a face +}; + +class SMDS_Down3D: public SMDS_Downward +{ + friend class SMDS_UnstructuredGrid; +public: + virtual int getNumberOfUpCells(int cellId); + virtual const int* getUpCells(int cellId); + virtual const unsigned char* getUpTypes(int cellId); + virtual void getNodeIds(int cellId, std::set& nodeSet); +protected: + SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells); + ~SMDS_Down3D(); + virtual void allocate(int nbElems); + virtual void compactStorage(); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0; + int FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes); +}; + +class SMDS_DownEdge: public SMDS_Down1D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownEdge(SMDS_UnstructuredGrid *grid); + ~SMDS_DownEdge(); +}; + +class SMDS_DownQuadEdge: public SMDS_Down1D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadEdge(); +}; + +class SMDS_DownTriangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownTriangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownTriangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadTriangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadTriangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadrangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadrangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +class SMDS_DownQuadQuadrangle: public SMDS_Down2D +{ + friend class SMDS_UnstructuredGrid; +public: +protected: + SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadQuadrangle(); + virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's +}; + +//class SMDS_DownPolygon: public SMDS_Down2D +//{ +//public: +// SMDS_DownPolygon(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownPolygon(); +//protected: +//}; + +//class SMDS_DownQuadPolygon: public SMDS_Down2D +//{ +//public: +// SMDS_DownQuadPolygon(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownQuadPolygon(); +//protected: +//}; + +class SMDS_DownTetra: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownTetra(SMDS_UnstructuredGrid *grid); + ~SMDS_DownTetra(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadTetra: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadTetra(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownPyramid: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownPyramid(SMDS_UnstructuredGrid *grid); + ~SMDS_DownPyramid(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadPyramid: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadPyramid(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownPenta: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownPenta(SMDS_UnstructuredGrid *grid); + ~SMDS_DownPenta(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadPenta: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadPenta(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownHexa: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownHexa(SMDS_UnstructuredGrid *grid); + ~SMDS_DownHexa(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +class SMDS_DownQuadHexa: public SMDS_Down3D +{ + friend class SMDS_UnstructuredGrid; +public: + virtual void getOrderedNodesOfFace(int cellId, std::vector& orderedNodes); +protected: + SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid); + ~SMDS_DownQuadHexa(); + virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); + virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes); +}; + +//class SMDS_DownPolyhedra: public SMDS_Down3D +//{ +//public: +// SMDS_DownPolyhedra(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownPolyhedra(); +//protected: +//}; + +//class SMDS_DownQuadPolyhedra: public SMDS_Down3D +//{ +//public: +// SMDS_DownQuadPolyhedra(SMDS_UnstructuredGrid *grid); +// ~SMDS_DownQuadPolyhedra(); +//protected: +//}; + +#endif /* SMDS_DOWNWARD_HXX_ */ diff --git a/src/SMDS/SMDS_EdgePosition.cxx b/src/SMDS/SMDS_EdgePosition.cxx index 1317d2b75..dcc47f72a 100644 --- a/src/SMDS/SMDS_EdgePosition.cxx +++ b/src/SMDS/SMDS_EdgePosition.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_EdgePosition.cxx // Author : Jean-Michel BOULCOURT @@ -35,33 +36,23 @@ using namespace std; //purpose : //======================================================================= -SMDS_EdgePosition::SMDS_EdgePosition(const int aEdgeId, - const double aUParam):SMDS_Position(aEdgeId), myUParameter(aUParam) -{ -} - -//======================================================================= -//function : Coords -//purpose : -//======================================================================= - -const double *SMDS_EdgePosition::Coords() const +SMDS_EdgePosition::SMDS_EdgePosition(const double aUParam): myUParameter(aUParam) { - static double origin[]={0,0,0}; - MESSAGE("SMDS_EdgePosition::Coords not implemented"); - return origin; + //MESSAGE("********************************* SMDS_EdgePosition " << myUParameter); } /** */ SMDS_TypeOfPosition SMDS_EdgePosition::GetTypeOfPosition() const { - return SMDS_TOP_EDGE; + //MESSAGE("###################################### SMDS_EdgePosition::GetTypeOfPosition"); + return SMDS_TOP_EDGE; } void SMDS_EdgePosition::SetUParameter(double aUparam) { - myUParameter = aUparam; + //MESSAGE("############################### SMDS_EdgePosition::SetUParameter " << aUparam); + myUParameter = aUparam; } //======================================================================= @@ -71,5 +62,6 @@ void SMDS_EdgePosition::SetUParameter(double aUparam) double SMDS_EdgePosition::GetUParameter() const { - return myUParameter; + //MESSAGE("########################## SMDS_EdgePosition::GetUParameter " << myUParameter); + return myUParameter; } diff --git a/src/SMDS/SMDS_EdgePosition.hxx b/src/SMDS/SMDS_EdgePosition.hxx index f6005e947..ced2e9403 100644 --- a/src/SMDS/SMDS_EdgePosition.hxx +++ b/src/SMDS/SMDS_EdgePosition.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_EdgePosition.hxx // Module : SMESH @@ -34,15 +35,14 @@ class SMDS_EXPORT SMDS_EdgePosition:public SMDS_Position { public: - SMDS_EdgePosition(const int aEdgeId=0, const double aUParam=0); - const virtual double * Coords() const; - SMDS_TypeOfPosition GetTypeOfPosition() const; - void SetUParameter(double aUparam); - double GetUParameter() const; + SMDS_EdgePosition(const double aUParam=0); + SMDS_TypeOfPosition GetTypeOfPosition() const; + void SetUParameter(double aUparam); + double GetUParameter() const; private: - double myUParameter; + double myUParameter; }; diff --git a/src/SMDS/SMDS_ElemIterator.hxx b/src/SMDS/SMDS_ElemIterator.hxx index 511426e5d..129d8f6c4 100755 --- a/src/SMDS/SMDS_ElemIterator.hxx +++ b/src/SMDS/SMDS_ElemIterator.hxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshElement.hxx // Module : SMESH -// Created: 12.01.05 18:02:52 -// Author: Michael Sazonov +// Created: 12.01.05 18:02:52 +// Author: Michael Sazonov // #ifndef SMDS_ElemIterator_HeaderFile #define SMDS_ElemIterator_HeaderFile @@ -33,6 +34,7 @@ class SMDS_MeshElement; class SMDS_MeshNode; +class SMDS_Mesh0DElement; class SMDS_MeshEdge; class SMDS_MeshFace; class SMDS_MeshVolume; @@ -43,6 +45,9 @@ typedef boost::shared_ptr > SMDS_ElemIte typedef SMDS_Iterator SMDS_NodeIterator; typedef boost::shared_ptr > SMDS_NodeIteratorPtr; +typedef SMDS_Iterator SMDS_0DElementIterator; +typedef boost::shared_ptr > SMDS_0DElementIteratorPtr; + typedef SMDS_Iterator SMDS_EdgeIterator; typedef boost::shared_ptr > SMDS_EdgeIteratorPtr; diff --git a/src/SMDS/SMDS_FaceOfEdges.cxx b/src/SMDS/SMDS_FaceOfEdges.cxx index 5b5483022..a03bc0bf7 100644 --- a/src/SMDS/SMDS_FaceOfEdges.cxx +++ b/src/SMDS/SMDS_FaceOfEdges.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifdef _MSC_VER @@ -28,6 +29,7 @@ #include "SMDS_FaceOfEdges.hxx" #include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" +#include "utilities.h" using namespace std; @@ -38,12 +40,12 @@ using namespace std; int SMDS_FaceOfEdges::NbEdges() const { - return myNbEdges; + return myNbEdges; } int SMDS_FaceOfEdges::NbFaces() const { - return 1; + return 1; } //======================================================================= //function : Print @@ -52,15 +54,15 @@ int SMDS_FaceOfEdges::NbFaces() const void SMDS_FaceOfEdges::Print(ostream & OS) const { - OS << "face <" << GetID() << " > : "; - int i; - for (i = 0; i < NbEdges() - 1; i++) OS << myEdges[i] << ","; - OS << myEdges[i] << ") " << endl; + OS << "face <" << GetID() << " > : "; + int i; + for (i = 0; i < NbEdges() - 1; i++) OS << myEdges[i] << ","; + OS << myEdges[i] << ") " << endl; } SMDSAbs_ElementType SMDS_FaceOfEdges::GetType() const { - return SMDSAbs_Face; + return SMDSAbs_Face; } //======================================================================= @@ -86,7 +88,7 @@ class SMDS_FaceOfEdges_MyIterator:public SMDS_ElemIterator { index++; return mySet[index-1]; - } + } }; SMDS_ElemIteratorPtr SMDS_FaceOfEdges::elementsIterator @@ -110,11 +112,12 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, const SMDS_MeshEdge* edge2, const SMDS_MeshEdge* edge3) { - myNbEdges = 3; - myEdges[0]=edge1; - myEdges[1]=edge2; - myEdges[2]=edge3; - myEdges[3]=0; + //MESSAGE("****************************************************** SMDS_FaceOfEdges"); + myNbEdges = 3; + myEdges[0]=edge1; + myEdges[1]=edge2; + myEdges[2]=edge3; + myEdges[3]=0; } SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, @@ -122,38 +125,39 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, const SMDS_MeshEdge* edge3, const SMDS_MeshEdge* edge4) { - myNbEdges = 4; - myEdges[0]=edge1; - myEdges[1]=edge2; - myEdges[2]=edge3; - myEdges[3]=edge4; + //MESSAGE("****************************************************** SMDS_FaceOfEdges"); + myNbEdges = 4; + myEdges[0]=edge1; + myEdges[1]=edge2; + myEdges[2]=edge3; + myEdges[3]=edge4; } /*bool operator<(const SMDS_FaceOfEdges& f1, const SMDS_FaceOfEdges& f2) { - set set1,set2; - SMDS_ElemIteratorPtr it; - const SMDS_MeshNode * n; - - it=f1.nodesIterator(); - - while(it->more()) - { - n=static_cast(it->next()); - set1.insert(*n); - } - - delete it; - it=f2.nodesIterator(); - - while(it->more()) - { - n=static_cast(it->next()); - set2.insert(*n); - } - - delete it; - return set1 set1,set2; + SMDS_ElemIteratorPtr it; + const SMDS_MeshNode * n; + + it=f1.nodesIterator(); + + while(it->more()) + { + n=static_cast(it->next()); + set1.insert(*n); + } + + delete it; + it=f2.nodesIterator(); + + while(it->more()) + { + n=static_cast(it->next()); + set2.insert(*n); + } + + delete it; + return set1= myEdges[ i ]->NbNodes() ) index -= myEdges[ i ]->NbNodes(); @@ -183,3 +185,12 @@ const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const return 0; } +SMDSAbs_EntityType SMDS_FaceOfEdges::GetEntityType() const +{ + return myNbEdges == 3 ? SMDSEntity_Triangle : SMDSEntity_Quadrangle; +} + +SMDSAbs_GeometryType SMDS_FaceOfEdges::GetGeomType() const +{ + return myNbEdges == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE; +} diff --git a/src/SMDS/SMDS_FaceOfEdges.hxx b/src/SMDS/SMDS_FaceOfEdges.hxx index 23659b85c..9eb81b1f0 100644 --- a/src/SMDS/SMDS_FaceOfEdges.hxx +++ b/src/SMDS/SMDS_FaceOfEdges.hxx @@ -1,25 +1,26 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMDS : implementaion of Salome mesh data structure + +// SMESH SMDS : implementation of Salome mesh data structure // #ifndef _SMDS_FaceOfEdges_HeaderFile #define _SMDS_FaceOfEdges_HeaderFile @@ -36,37 +37,30 @@ class SMDS_EXPORT SMDS_FaceOfEdges:public SMDS_MeshFace { public: - void Print(std::ostream & OS) const; - SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, + void Print(std::ostream & OS) const; + SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, const SMDS_MeshEdge* edge2, const SMDS_MeshEdge* edge3); - SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, + SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1, const SMDS_MeshEdge* edge2, const SMDS_MeshEdge* edge3, const SMDS_MeshEdge* edge4); - - SMDSAbs_ElementType GetType() const; - int NbNodes() const; - int NbEdges() const; - int NbFaces() const; -// friend bool operator<(const SMDS_FaceOfEdges& e1, const SMDS_FaceOfEdges& e2); - - - /*! - * \brief Return node by its index - * \param ind - node index - * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range - */ - virtual const SMDS_MeshNode* GetNode(const int ind) const; + + virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes) {return false;} + virtual int NbNodes() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; protected: - SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; private: - const SMDS_MeshEdge* myEdges[4]; + const SMDS_MeshEdge* myEdges[4]; int myNbEdges; }; diff --git a/src/SMDS/SMDS_FaceOfNodes.cxx b/src/SMDS/SMDS_FaceOfNodes.cxx index 645e934dd..9d05d4505 100644 --- a/src/SMDS/SMDS_FaceOfNodes.cxx +++ b/src/SMDS/SMDS_FaceOfNodes.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifdef _MSC_VER @@ -42,17 +43,17 @@ using namespace std; int SMDS_FaceOfNodes::NbEdges() const { - return NbNodes(); + return NbNodes(); } int SMDS_FaceOfNodes::NbFaces() const { - return 1; + return 1; } int SMDS_FaceOfNodes::NbNodes() const { - return myNbNodes; + return myNbNodes; } //======================================================================= @@ -62,10 +63,10 @@ int SMDS_FaceOfNodes::NbNodes() const void SMDS_FaceOfNodes::Print(ostream & OS) const { - OS << "face <" << GetID() << " > : "; - int i; - for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ","; - OS << myNodes[i] << ") " << endl; + OS << "face <" << GetID() << " > : "; + int i; + for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ","; + OS << myNodes[i] << ") " << endl; } //======================================================================= @@ -95,7 +96,7 @@ public: 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 )); + SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNodeWrap( i + 1 )); if ( edge ) myElems.push_back( edge ); } @@ -132,11 +133,12 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, const SMDS_MeshNode* node2, const SMDS_MeshNode* node3) { - myNbNodes = 3; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=0; + //MESSAGE("******************************************************* SMDS_FaceOfNodes"); + myNbNodes = 3; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=0; } SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, @@ -144,11 +146,12 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1, const SMDS_MeshNode* node3, const SMDS_MeshNode* node4) { - myNbNodes = 4; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; + //MESSAGE("******************************************************* SMDS_FaceOfNodes"); + myNbNodes = 4; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; } bool SMDS_FaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) @@ -169,39 +172,17 @@ bool SMDS_FaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[], * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ const SMDS_MeshNode* SMDS_FaceOfNodes::GetNode(const int ind) const { - return myNodes[ WrappedIndex( ind )]; + return myNodes[ ind ]; } -/*bool operator<(const SMDS_FaceOfNodes& f1, const SMDS_FaceOfNodes& f2) +SMDSAbs_EntityType SMDS_FaceOfNodes::GetEntityType() const { - set set1,set2; - SMDS_ElemIteratorPtr it; - const SMDS_MeshNode * n; - - it=f1.nodesIterator(); - - while(it->more()) - { - n=static_cast(it->next()); - set1.insert(*n); - } - - delete it; - it=f2.nodesIterator(); - - while(it->more()) - { - n=static_cast(it->next()); - set2.insert(*n); - } - - delete it; - return set1 class SMDS_Iterator { public: - /// Return true if and only if there are other object in this iterator - virtual bool more()=0; - - /// Return the current object and step to the next one - virtual VALUE next()=0; - - /// Delete the current element and step to the next one - virtual void remove(){} - - /// Provide virtual destructor just for case if some derived iterator + /// Return true if and only if there are other object in this iterator + virtual bool more()=0; + + /// Return the current object and step to the next one + virtual VALUE next()=0; + + /// Delete the current element and step to the next one + virtual void remove(){} + + /// Provide virtual destructor just for case if some derived iterator /// must have a destructor - virtual ~SMDS_Iterator(){} + virtual ~SMDS_Iterator(){} }; #endif diff --git a/src/SMDS/SMDS_IteratorOfElements.cxx b/src/SMDS/SMDS_IteratorOfElements.cxx index 220e67ac9..761fa55e9 100644 --- a/src/SMDS/SMDS_IteratorOfElements.cxx +++ b/src/SMDS/SMDS_IteratorOfElements.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifdef _MSC_VER @@ -29,24 +30,24 @@ bool SMDS_IteratorOfElements::subMore() { - if((t2Iterator.get()==NULL)||(!t2Iterator->more())) - { - if(t1Iterator->more()) - { - t2Iterator=t1Iterator->next()->elementsIterator(myType); - return subMore(); - } - else return false; - } - else return true; + if((t2Iterator.get()==NULL)||(!t2Iterator->more())) + { + if(t1Iterator->more()) + { + t2Iterator=t1Iterator->next()->elementsIterator(myType); + return subMore(); + } + else return false; + } + else return true; } const SMDS_MeshElement * SMDS_IteratorOfElements::subNext() { - if((t2Iterator.get()==NULL)||(!t2Iterator->more())) - if(t1Iterator->more()) - t2Iterator=t1Iterator->next()->elementsIterator(myType); - return t2Iterator->next(); + if((t2Iterator.get()==NULL)||(!t2Iterator->more())) + if(t1Iterator->more()) + t2Iterator=t1Iterator->next()->elementsIterator(myType); + return t2Iterator->next(); } ///////////////////////////////////////////////////////////////////////////// @@ -61,48 +62,48 @@ SMDS_IteratorOfElements::SMDS_IteratorOfElements(const SMDS_MeshElement * elemen myType(type), myElement(element), myProxyElement(NULL) { - while(subMore()) - alreadyReturnedElements.insert(subNext()); - itAlreadyReturned= alreadyReturnedElements.begin(); - switch(myElement->GetType()) - { - case SMDSAbs_Node: - case SMDSAbs_Edge: myReverseIteration=true; break; - case SMDSAbs_Face: myReverseIteration=(type==SMDSAbs_Volume); break; - default: myReverseIteration=false; - } + while(subMore()) + alreadyReturnedElements.insert(subNext()); + itAlreadyReturned= alreadyReturnedElements.begin(); + switch(myElement->GetType()) + { + case SMDSAbs_Node: + case SMDSAbs_Edge: myReverseIteration=true; break; + case SMDSAbs_Face: myReverseIteration=(type==SMDSAbs_Volume); break; + default: myReverseIteration=false; + } } bool SMDS_IteratorOfElements::more() { - if(myProxyElement==NULL) - { - while(itAlreadyReturned!=alreadyReturnedElements.end()) - { - myProxyElement=*itAlreadyReturned; - itAlreadyReturned++; + if(myProxyElement==NULL) + { + while(itAlreadyReturned!=alreadyReturnedElements.end()) + { + myProxyElement=*itAlreadyReturned; + itAlreadyReturned++; - if(myReverseIteration) - { - SMDS_ElemIteratorPtr it= - myProxyElement->elementsIterator(myElement->GetType()); - while(it->more()) - { - if(it->next()==myElement) return true; - } - } - else return true; - } - myProxyElement=NULL; - return false; - } - else return true; + if(myReverseIteration) + { + SMDS_ElemIteratorPtr it= + myProxyElement->elementsIterator(myElement->GetType()); + while(it->more()) + { + if(it->next()==myElement) return true; + } + } + else return true; + } + myProxyElement=NULL; + return false; + } + else return true; } const SMDS_MeshElement * SMDS_IteratorOfElements::next() { - more(); - const SMDS_MeshElement *e=myProxyElement; - myProxyElement=NULL; - return e; + more(); + const SMDS_MeshElement *e=myProxyElement; + myProxyElement=NULL; + return e; } diff --git a/src/SMDS/SMDS_IteratorOfElements.hxx b/src/SMDS/SMDS_IteratorOfElements.hxx index 381ff647a..239cb9fb0 100644 --- a/src/SMDS/SMDS_IteratorOfElements.hxx +++ b/src/SMDS/SMDS_IteratorOfElements.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #include "SMESH_SMDS.hxx" @@ -35,22 +36,22 @@ class SMDS_EXPORT SMDS_IteratorOfElements:public SMDS_ElemIterator /// Create an iterator which look for elements of type type which are linked /// to the element element. it is the iterator to get connectivity of element ////////////////////////////////////////////////////////////////////////////// - SMDS_IteratorOfElements(const SMDS_MeshElement * element, + SMDS_IteratorOfElements(const SMDS_MeshElement * element, SMDSAbs_ElementType type, const SMDS_ElemIteratorPtr& it); - bool more(); - const SMDS_MeshElement * next(); + bool more(); + const SMDS_MeshElement * next(); private: - SMDS_ElemIteratorPtr t2Iterator; - SMDS_ElemIteratorPtr t1Iterator; - SMDSAbs_ElementType myType; - const SMDS_MeshElement * myProxyElement; - const SMDS_MeshElement * myElement; - bool myReverseIteration; + SMDS_ElemIteratorPtr t2Iterator; + SMDS_ElemIteratorPtr t1Iterator; + SMDSAbs_ElementType myType; + const SMDS_MeshElement * myProxyElement; + const SMDS_MeshElement * myElement; + bool myReverseIteration; - std::set alreadyReturnedElements; - std::set::iterator itAlreadyReturned; - bool subMore(); - const SMDS_MeshElement * subNext(); + std::set alreadyReturnedElements; + std::set::iterator itAlreadyReturned; + bool subMore(); + const SMDS_MeshElement * subNext(); }; diff --git a/src/SMDS/SMDS_IteratorOnIterators.hxx b/src/SMDS/SMDS_IteratorOnIterators.hxx new file mode 100644 index 000000000..105edfdc1 --- /dev/null +++ b/src/SMDS/SMDS_IteratorOnIterators.hxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_IteratorOnIterators.hxx +// Author : Edward AGAPOV (eap) +// +#ifndef SMDS_IteratorOnIterators_HeaderFile +#define SMDS_IteratorOnIterators_HeaderFile + +#include "SMDS_Iterator.hxx" + +/////////////////////////////////////////////////////////////////////////////// +/// SMDS_Iterator iterating over all elements provided by other iterators +/// +/// Other iterators must implement SMDS_Iterator iterface and +/// must be provided within a stl-like container +/// BE CAREFUL: iterator pointed value is static_cast'ed to VALUE +/////////////////////////////////////////////////////////////////////////////// + +template +class SMDS_IteratorOnIterators : public SMDS_Iterator +{ +protected: + CONTAINER_OF_ITERATORS _iterators; + typename CONTAINER_OF_ITERATORS::iterator _beg, _end; +public: + SMDS_IteratorOnIterators(const CONTAINER_OF_ITERATORS& iterators): + _iterators( iterators ), _beg( _iterators.begin()), _end(_iterators.end() ) + { + while ( _beg != _end && !(*_beg)->more()) ++_beg; + } + + /// Return true iff there are other object in this iterator + virtual bool more() { return _beg != _end && (*_beg)->more(); } + + /// Return the current object and step to the next one + virtual VALUE next() + { + VALUE __v = (VALUE)(*_beg)->next(); + while ( _beg != _end && !(*_beg)->more()) + ++_beg; + return __v; + } +}; + +#endif diff --git a/src/SMDS/SMDS_LinearEdge.cxx b/src/SMDS/SMDS_LinearEdge.cxx new file mode 100644 index 000000000..fd2ba30d6 --- /dev/null +++ b/src/SMDS/SMDS_LinearEdge.cxx @@ -0,0 +1,162 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMDS_LinearEdge.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_LinearEdge.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_LinearEdge +//purpose : +//======================================================================= + +SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + //MESSAGE("SMDS_LinearEdge " << GetID()); + myNodes[0] = node1; + myNodes[1] = node2; +} + +//======================================================================= +//function : Print +//purpose : +//======================================================================= + +void SMDS_LinearEdge::Print(ostream & OS) const +{ + OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] + << ") " << endl; +} + +int SMDS_LinearEdge::NbNodes() const +{ + return 2; +} + +int SMDS_LinearEdge::NbEdges() const +{ + return 1; +} + +class SMDS_LinearEdge_MyNodeIterator: public SMDS_ElemIterator +{ + const SMDS_MeshNode * const * myNodes; + int myIndex; +public: + SMDS_LinearEdge_MyNodeIterator(const SMDS_MeshNode * const * nodes) : + myNodes(nodes), myIndex(0) + { + } + + bool more() + { + return myIndex < 2; + } + + const SMDS_MeshElement* next() + { + myIndex++; + return myNodes[myIndex - 1]; + } +}; + +SMDS_ElemIteratorPtr SMDS_LinearEdge::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Edge: + return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes)); + default: + return SMDS_ElemIteratorPtr( + new SMDS_IteratorOfElements( + this, + type, + SMDS_ElemIteratorPtr( + new SMDS_LinearEdge_MyNodeIterator( + myNodes)))); + } +} + +bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2) +{ + int id11 = e1.myNodes[0]->getVtkId(); + int id21 = e2.myNodes[0]->getVtkId(); + int id12 = e1.myNodes[1]->getVtkId(); + int id22 = e2.myNodes[1]->getVtkId(); + int tmp; + + if (id11 >= id12) + { + tmp = id11; + id11 = id12; + id12 = tmp; + } + if (id21 >= id22) + { + tmp = id21; + id21 = id22; + id22 = tmp; + } + + if (id11 < id21) + return true; + else if (id11 == id21) + return (id21 < id22); + else + return false; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const +{ + return myNodes[ind]; +} + +//======================================================================= +//function : ChangeNodes +//purpose : +//======================================================================= + +bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2) +{ + myNodes[0] = node1; + myNodes[1] = node2; + return true; +} diff --git a/src/SMDS/SMDS_LinearEdge.hxx b/src/SMDS/SMDS_LinearEdge.hxx new file mode 100644 index 000000000..34ca147ee --- /dev/null +++ b/src/SMDS/SMDS_LinearEdge.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMDS_LinearEdge.hxx +// Module : SMESH +// +#ifndef _SMDS_LinearEdge_HeaderFile +#define _SMDS_LinearEdge_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshEdge.hxx" +#include + +class SMDS_EXPORT SMDS_LinearEdge: public SMDS_MeshEdge +{ + +public: + SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + void Print(std::ostream & OS) const; + + virtual SMDSAbs_EntityType GetEntityType() const + { + return SMDSEntity_Edge; + } + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) + { + return false; + } + int NbNodes() const; + int NbEdges() const; + friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2); + + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + +protected: + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + +protected: + const SMDS_MeshNode* myNodes[3]; + +}; +#endif diff --git a/src/SMDS/SMDS_MemoryLimit.cxx b/src/SMDS/SMDS_MemoryLimit.cxx index 4de22248e..8df52064a 100644 --- a/src/SMDS/SMDS_MemoryLimit.cxx +++ b/src/SMDS/SMDS_MemoryLimit.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMDS_MemoryLimit.cxx // Created : Fri Sep 21 17:16:42 2007 // Author : Edward AGAPOV (eap) diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index e8d8af697..fe6f186e4 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1,52 +1,70 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMDS : implementaion of Salome mesh data structure + +// SMESH SMDS : implementation of Salome mesh data structure // #ifdef _MSC_VER #pragma warning(disable:4786) #endif -#include "utilities.h" -#include "SMDS_Mesh.hxx" -#include "SMDS_VolumeOfNodes.hxx" -#include "SMDS_VolumeOfFaces.hxx" -#include "SMDS_FaceOfNodes.hxx" #include "SMDS_FaceOfEdges.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_FaceOfNodes.hxx" +#include "SMDS_Mesh.hxx" #include "SMDS_PolygonalFaceOfNodes.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_QuadraticEdge.hxx" #include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_QuadraticVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_SpacePosition.hxx" +#include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_VolumeOfFaces.hxx" +#include "SMDS_VolumeOfNodes.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include #include #include +#include +#include using namespace std; #ifndef WIN32 #include #endif -// number of added entitis to check memory after -#define CHECKMEMORY_INTERVAL 1000 +// number of added entities to check memory after +#define CHECKMEMORY_INTERVAL 100000 + +vector SMDS_Mesh::_meshList = vector(); +int SMDS_Mesh::chunkSize = 1024; + //================================================================================ /*! @@ -64,35 +82,38 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) if ( err ) return -1; + const unsigned long Mbyte = 1024 * 1024; + static int limit = -1; if ( limit < 0 ) { int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM if (status >= 0 ) { limit = WEXITSTATUS(status); } + else { + double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2; + limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte ); + } if ( limit < 20 ) limit = 20; else - limit = int( limit * 1.5 ); -#ifdef _DEBUG_ + limit = int ( limit * 1.5 ); MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" ); -#endif } - const unsigned long Mbyte = 1024 * 1024; // compute separately to avoid overflow int freeMb = ( si.freeram * si.mem_unit ) / Mbyte + ( si.freeswap * si.mem_unit ) / Mbyte; + //cout << "freeMb = " << freeMb << " limit = " << limit << endl; if ( freeMb > limit ) return freeMb - limit; if ( doNotRaise ) return 0; -#ifdef _DEBUG_ + MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" ); -#endif throw std::bad_alloc(); #else return -1; @@ -103,12 +124,50 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) /// Create a new mesh object /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::SMDS_Mesh() - :myParent(NULL), - myNodeIDFactory(new SMDS_MeshElementIDFactory()), - myElementIDFactory(new SMDS_MeshElementIDFactory()), - myHasConstructionEdges(false), myHasConstructionFaces(false), - myHasInverseElements(true) -{ + :myParent(NULL), + myNodeIDFactory(new SMDS_MeshNodeIDFactory()), + myElementIDFactory(new SMDS_MeshElementIDFactory()), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true), + myNodeMin(0), myNodeMax(0), + myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),myBallPool(0), + myModified(false), myModifTime(0), myCompactTime(0), + xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0) +{ + myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector + MESSAGE("myMeshId=" << myMeshId); + MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) ); + MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) ); + MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) ); + MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) ); + MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) ); + MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) ); + myNodeIDFactory->SetMesh(this); + myElementIDFactory->SetMesh(this); + _meshList.push_back(this); + myNodePool = new ObjectPool(SMDS_Mesh::chunkSize); + myEdgePool = new ObjectPool(SMDS_Mesh::chunkSize); + myFacePool = new ObjectPool(SMDS_Mesh::chunkSize); + myVolumePool = new ObjectPool(SMDS_Mesh::chunkSize); + myBallPool = new ObjectPool(SMDS_Mesh::chunkSize); + + myNodes.clear(); + myCells.clear(); + //myCellIdSmdsToVtk.clear(); + myCellIdVtkToSmds.clear(); + myGrid = SMDS_UnstructuredGrid::New(); + myGrid->setSMDS_mesh(this); + myGrid->Initialize(); + myGrid->Allocate(); + vtkPoints* points = vtkPoints::New(); + // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion" + // using double type for storing coordinates of nodes instead float. + points->SetDataType(VTK_DOUBLE); + points->SetNumberOfPoints(SMDS_Mesh::chunkSize); + myGrid->SetPoints( points ); + points->Delete(); + myGrid->BuildLinks(); + this->Modified(); } /////////////////////////////////////////////////////////////////////////////// @@ -117,10 +176,15 @@ SMDS_Mesh::SMDS_Mesh() /// (2003-09-08) of SMESH /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent) - :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory), - myElementIDFactory(parent->myElementIDFactory), - myHasConstructionEdges(false), myHasConstructionFaces(false), - myHasInverseElements(true) + :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory), + myElementIDFactory(parent->myElementIDFactory), + myHasConstructionEdges(false), myHasConstructionFaces(false), + myHasInverseElements(true), + myNodePool(parent->myNodePool), + myEdgePool(parent->myEdgePool), + myFacePool(parent->myFacePool), + myVolumePool(parent->myVolumePool), + myBallPool(parent->myBallPool) { } @@ -130,9 +194,9 @@ SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent) SMDS_Mesh *SMDS_Mesh::AddSubMesh() { - SMDS_Mesh *submesh = new SMDS_Mesh(this); - myChildren.insert(myChildren.end(), submesh); - return submesh; + SMDS_Mesh *submesh = new SMDS_Mesh(this); + myChildren.insert(myChildren.end(), submesh); + return submesh; } /////////////////////////////////////////////////////////////////////////////// @@ -156,22 +220,131 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) // find the MeshNode corresponding to ID const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); if(!node){ - if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); - myNodes.Add(node); + if (ID < 1) + { + MESSAGE("=============> Bad Node Id: " << ID); + ID = myNodeIDFactory->GetFreeID(); + } + myNodeIDFactory->adjustMaxId(ID); + SMDS_MeshNode * node = myNodePool->getNew(); + node->init(ID, myMeshId, 0, x, y, z); + + if (ID >= myNodes.size()) + { + myNodes.resize(ID+SMDS_Mesh::chunkSize, 0); +// MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize); + } + myNodes[ID] = node; myNodeIDFactory->BindID(ID,node); myInfo.myNbNodes++; + myModified = true; + this->adjustBoundingBox(x, y, z); return node; }else return NULL; } +/////////////////////////////////////////////////////////////////////////////// +/// create a Mesh0DElement and add it to the current Mesh +/// @return : The created Mesh0DElement +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID) +{ + SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode); + if (!node) return NULL; + return SMDS_Mesh::Add0DElementWithID(node, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Mesh0DElement and add it to the current Mesh +/// @return : The created Mesh0DElement +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node) +{ + return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new Mesh0DElement and at it to the mesh +/// @param idnode ID of the node +/// @param ID ID of the 0D element to create +/// @return The created 0D element or NULL if an element with this +/// ID already exists or if input node is not found. +/////////////////////////////////////////////////////////////////////////////// +SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID) +{ + if (!n) return 0; + + if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); + //MESSAGE("Add0DElementWithID" << ID) + SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n); + if (myElementIDFactory->BindID(ID, el0d)) { + //SMDS_MeshNode *node = const_cast(n); + //node->AddInverseElement(el0d);// --- fait avec BindID + adjustmyCellsCapacity(ID); + myCells[ID] = el0d; + myInfo.myNb0DElements++; + return el0d; + } + + delete el0d; + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Ball and add it to the current Mesh +/// @return : The created Ball +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID) +{ + SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode); + if (!node) return NULL; + return SMDS_Mesh::AddBallWithID(node, diameter, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Ball and add it to the current Mesh +/// @return : The created Ball +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter) +{ + return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new Ball and at it to the mesh +/// @param idnode ID of the node +// @param diameter ball diameter +/// @param ID ID of the 0D element to create +/// @return The created 0D element or NULL if an element with this +/// ID already exists or if input node is not found. +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID) +{ + if (!n) return 0; + + if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); + + SMDS_BallElement *ball = myBallPool->getNew(); + ball->init(n->getVtkId(), diameter, this); + if (!this->registerElement(ID,ball)) + { + this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL); + myBallPool->destroy(ball); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = ball; + myInfo.myNbBalls++; + return ball; +} + /////////////////////////////////////////////////////////////////////////////// /// create a MeshEdge and add it to the current Mesh /// @return : The created MeshEdge /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) { SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -185,7 +358,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) /////////////////////////////////////////////////////////////////////////////// SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID()); } @@ -200,28 +373,37 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - int ID) + const SMDS_MeshNode * n2, + int ID) { if ( !n1 || !n2 ) return 0; + SMDS_MeshEdge * edge = 0; - if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + // --- retreive nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); - SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2); - if(myElementIDFactory->BindID(ID, edge)) { - SMDS_MeshNode *node1,*node2; - node1=const_cast(n1); - node2=const_cast(n2); - node1->AddInverseElement(edge); - node2->AddInverseElement(edge); - myEdges.Add(edge); - myInfo.myNbEdges++; - return edge; - } - else { - delete edge; - return NULL; - } + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(nodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + edge = edgevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = edge; + myInfo.myNbEdges++; + +// if (edge && !registerElement(ID, edge)) +// { +// RemoveElement(edge, false); +// edge = NULL; +// } + return edge; } /////////////////////////////////////////////////////////////////////////////// @@ -230,8 +412,8 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) { return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID()); } @@ -246,7 +428,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, i SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); if(!node1 || !node2 || !node3) return NULL; - return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID); + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -258,12 +440,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n3, int ID) { - SMDS_MeshFace * face=createTriangle(n1, n2, n3); + //MESSAGE("AddFaceWithID " << ID) + SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID); - if (face && !registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } +// if (face && !registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } return face; } @@ -273,9 +456,9 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID()); } @@ -284,11 +467,11 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, /// Add a quadrangle defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int ID) +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) { SMDS_MeshNode *node1, *node2, *node3, *node4; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); @@ -296,7 +479,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); if(!node1 || !node2 || !node3 || !node4) return NULL; - return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID); + return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -309,12 +492,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { - SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4); + //MESSAGE("AddFaceWithID " << ID); + SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID); - if (face && !registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } +// if (face && !registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } return face; } @@ -329,7 +513,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; - return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); + //MESSAGE("AddFaceWithID"); + return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -345,15 +530,18 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, return NULL; if ( !e1 || !e2 || !e3 ) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + MESSAGE("AddFaceWithID" << ID); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbTriangles++; if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + registerElement(myElementIDFactory->GetFreeID(), face); + //RemoveElement(face, false); + //face = NULL; } return face; } @@ -370,7 +558,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; - return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); + //MESSAGE("AddFaceWithID" ); + return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// @@ -385,49 +574,54 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; + MESSAGE("AddFaceWithID" << ID); if ( !e1 || !e2 || !e3 || !e4 ) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadrangles++; if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + registerElement(myElementIDFactory->GetFreeID(), face); + //RemoveElement(face, false); + //face = NULL; } return face; } /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron and add it to the mesh. -///@return The created tetrahedron +///Create a new tetrahedron and add it to the mesh. +///@return The created tetrahedron /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { int ID = myElementIDFactory->GetFreeID(); + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; } /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron and add it to the mesh. +///Create a new tetrahedron and add it to the mesh. ///@param ID The ID of the new volume ///@return The created tetrahedron or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int ID) { + //MESSAGE("AddVolumeWithID" << ID); SMDS_MeshNode *node1, *node2, *node3, *node4; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -436,11 +630,11 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, if(!node1 || !node2 || !node3 || !node4) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID); } - + /////////////////////////////////////////////////////////////////////////////// -///Create a new tetrahedron and add it to the mesh. +///Create a new tetrahedron and add it to the mesh. ///@param ID The ID of the new volume -///@return The created tetrahedron +///@return The created tetrahedron /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, @@ -449,16 +643,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4); SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbTetras++; } else if(hasConstructionEdges()) { @@ -466,51 +662,70 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbTetras++; } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } return volume; } /////////////////////////////////////////////////////////////////////////////// -///Create a new pyramid and add it to the mesh. +///Create a new pyramid and add it to the mesh. ///Nodes 1,2,3 and 4 define the base of the pyramid -///@return The created pyramid +///@return The created pyramid /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5) { int ID = myElementIDFactory->GetFreeID(); + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; } /////////////////////////////////////////////////////////////////////////////// -///Create a new pyramid and add it to the mesh. +///Create a new pyramid and add it to the mesh. ///Nodes 1,2,3 and 4 define the base of the pyramid ///@param ID The ID of the new volume ///@return The created pyramid or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int idnode5, - int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshNode *node1, *node2, *node3, *node4, *node5; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -520,7 +735,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID); } - + /////////////////////////////////////////////////////////////////////////////// ///Create a new pyramid and add it to the mesh. ///Nodes 1,2,3 and 4 define the base of the pyramid @@ -535,16 +750,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5); SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPyramids++; } else if(hasConstructionEdges()) { @@ -552,53 +769,73 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPyramids++; } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } return volume; } /////////////////////////////////////////////////////////////////////////////// -///Create a new prism and add it to the mesh. +///Create a new prism and add it to the mesh. ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. -///@return The created prism +///@return The created prism /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6) { int ID = myElementIDFactory->GetFreeID(); + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; } /////////////////////////////////////////////////////////////////////////////// -///Create a new prism and add it to the mesh. +///Create a new prism and add it to the mesh. ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. ///@param ID The ID of the new volume ///@return The created prism or NULL if an element with this ID already exists ///or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int idnode5, - int idnode6, - int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -609,7 +846,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL; return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID); } - + /////////////////////////////////////////////////////////////////////////////// ///Create a new prism and add it to the mesh. ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle. @@ -625,9 +862,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); @@ -635,7 +873,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3); SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPrisms++; } else if(hasConstructionEdges()) { @@ -643,57 +882,208 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPrisms++; } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexagonal prism and add it to the mesh. +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, + n7, n8, n9, n10, n11, n12, + ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexagonal prism and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism or NULL if an element with this ID already exists +///or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int idnode7, + int idnode8, + int idnode9, + int idnode10, + int idnode11, + int idnode12, + int ID) +{ + SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); + SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); + SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9); + SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10); + SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11); + SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12); + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, + node7, node8, node9, node10, node11, node12, + ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexagonal prism and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, + int ID) +{ + SMDS_MeshVolume* volume = 0; + if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || + !n7 || !n8 || !n9 || !n10 || !n11 || !n12 ) + return volume; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if(hasConstructionFaces()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n11->getVtkId()); + nodeIds.push_back(n10->getVtkId()); + nodeIds.push_back(n9->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbHexPrism++; } + return volume; } /////////////////////////////////////////////////////////////////////////////// -///Create a new hexahedron and add it to the mesh. +///Create a new hexahedron and add it to the mesh. ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. -///@return The created hexahedron +///@return The created hexahedron /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8) { int ID = myElementIDFactory->GetFreeID(); - SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; } /////////////////////////////////////////////////////////////////////////////// -///Create a new hexahedron and add it to the mesh. +///Create a new hexahedron and add it to the mesh. ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. ///@param ID The ID of the new volume ///@return The created hexahedron or NULL if an element with this ID already ///exists or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, - int idnode2, - int idnode3, - int idnode4, - int idnode5, - int idnode6, - int idnode7, - int idnode8, - int ID) +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int idnode7, + int idnode8, + int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8; node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); @@ -708,7 +1098,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7, node8, ID); } - + /////////////////////////////////////////////////////////////////////////////// ///Create a new hexahedron and add it to the mesh. ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. @@ -727,9 +1117,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n8, int ID) { + //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); @@ -738,7 +1129,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6); SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbHexas++; } else if(hasConstructionEdges()) { @@ -746,16 +1138,36 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return NULL; } else { -// volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); - volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbHexas++; } - - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } + +// if (!registerElement(ID, volume)) { +// RemoveElement(volume, false); +// volume = NULL; +// } return volume; } @@ -769,6 +1181,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, const SMDS_MeshFace * f3, const SMDS_MeshFace * f4) { + //MESSAGE("AddVolumeWithID"); if (!hasConstructionFaces()) return NULL; return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID()); @@ -777,7 +1190,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, /////////////////////////////////////////////////////////////////////////////// ///Create a new tetrahedron defined by its faces and add it to the mesh. ///@param ID The ID of the new volume -///@return The created tetrahedron +///@return The created tetrahedron /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, @@ -786,17 +1199,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, const SMDS_MeshFace * f4, int ID) { + MESSAGE("AddVolumeWithID" << ID); if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4) return 0; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbTetras++; if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; } return volume; } @@ -812,7 +1228,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, const SMDS_MeshFace * f4, const SMDS_MeshFace * f5) { - if (!hasConstructionFaces()) + //MESSAGE("AddVolumeWithID"); + if (!hasConstructionFaces()) return NULL; return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID()); } @@ -820,7 +1237,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, /////////////////////////////////////////////////////////////////////////////// ///Create a new pyramid defined by its faces and add it to the mesh. ///@param ID The ID of the new volume -///@return The created pyramid +///@return The created pyramid /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, @@ -830,17 +1247,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, const SMDS_MeshFace * f5, int ID) { + MESSAGE("AddVolumeWithID" << ID); if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPyramids++; if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; } return volume; } @@ -857,7 +1277,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, const SMDS_MeshFace * f5, const SMDS_MeshFace * f6) { - if (!hasConstructionFaces()) + //MESSAGE("AddVolumeWithID" ); + if (!hasConstructionFaces()) return NULL; return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID()); } @@ -865,7 +1286,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1, /////////////////////////////////////////////////////////////////////////////// ///Create a new prism defined by its faces and add it to the mesh. ///@param ID The ID of the new volume -///@return The created prism +///@return The created prism /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, @@ -876,17 +1297,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, const SMDS_MeshFace * f6, int ID) { + MESSAGE("AddVolumeWithID" << ID); if (!hasConstructionFaces()) return NULL; if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.Add(volume); + adjustmyCellsCapacity(ID); + myCells[ID] = volume; myInfo.myNbPrisms++; if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; + registerElement(myElementIDFactory->GetFreeID(), volume); + //RemoveElement(volume, false); + //volume = NULL; } return volume; } @@ -895,16 +1319,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, /// Add a polygon defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, - const int ID) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector & nodes_ids, + const int ID) { int nbNodes = nodes_ids.size(); - std::vector nodes (nbNodes); + vector nodes (nbNodes); for (int i = 0; i < nbNodes; i++) { nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); if (!nodes[i]) return NULL; } - return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); } /////////////////////////////////////////////////////////////////////////////// @@ -912,31 +1336,56 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID - (std::vector nodes, - const int ID) + (const vector & nodes, + const int ID) { SMDS_MeshFace * face; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if (hasConstructionEdges()) - { - MESSAGE("Error : Not implemented"); - return NULL; - } + { + MESSAGE("Error : Not implemented"); + return NULL; + } else - { - for ( int i = 0; i < nodes.size(); ++i ) - if ( !nodes[ i ] ) return 0; - face = new SMDS_PolygonalFaceOfNodes(nodes); - myFaces.Add(face); - myInfo.myNbPolygons++; - } + { +//#ifdef VTK_HAVE_POLYHEDRON + //MESSAGE("AddPolygonalFaceWithID vtk " << ID); + vector nodeIds; + nodeIds.clear(); + vector::const_iterator it = nodes.begin(); + for ( ; it != nodes.end(); ++it) + nodeIds.push_back((*it)->getVtkId()); + + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->initPoly(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; +//#else +// MESSAGE("AddPolygonalFaceWithID smds " << ID); +// for ( int i = 0; i < nodes.size(); ++i ) +// if ( !nodes[ i ] ) return 0; +// face = new SMDS_PolygonalFaceOfNodes(nodes); +//#endif + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbPolygons++; + } - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; - } - return face; +//#ifndef VTK_HAVE_POLYHEDRON +// if (!registerElement(ID, face)) +// { +// registerElement(myElementIDFactory->GetFreeID(), face); +// //RemoveElement(face, false); +// //face = NULL; +// } +//#endif + return face; } /////////////////////////////////////////////////////////////////////////////// @@ -944,25 +1393,25 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID /// An ID is automatically affected to the created face. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector nodes) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector & nodes) { return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); } /////////////////////////////////////////////////////////////////////////////// -/// Create a new polyhedral volume and add it to the mesh. +/// Create a new polyhedral volume and add it to the mesh. /// @param ID The ID of the new volume /// @return The created volume or NULL if an element with this ID already exists /// or if input nodes are not found. /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID - (std::vector nodes_ids, - std::vector quantities, - const int ID) + (const vector & nodes_ids, + const vector & quantities, + const int ID) { int nbNodes = nodes_ids.size(); - std::vector nodes (nbNodes); + vector nodes (nbNodes); for (int i = 0; i < nbNodes; i++) { nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); if (!nodes[i]) return NULL; @@ -971,47 +1420,79 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID } /////////////////////////////////////////////////////////////////////////////// -/// Create a new polyhedral volume and add it to the mesh. +/// Create a new polyhedral volume and add it to the mesh. /// @param ID The ID of the new volume /// @return The created volume /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID - (std::vector nodes, - std::vector quantities, - const int ID) + (const vector& nodes, + const vector & quantities, + const int ID) { - SMDS_MeshVolume* volume; - if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - if (hasConstructionFaces()) { - MESSAGE("Error : Not implemented"); - return NULL; - } else if (hasConstructionEdges()) { - MESSAGE("Error : Not implemented"); + SMDS_MeshVolume* volume = 0; + if ( nodes.empty() || quantities.empty() ) return NULL; - } else { - for ( int i = 0; i < nodes.size(); ++i ) - if ( !nodes[ i ] ) return 0; - volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); - myVolumes.Add(volume); - myInfo.myNbPolyhedrons++; - } + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if (hasConstructionFaces()) + { + MESSAGE("Error : Not implemented"); + return NULL; + } + else if (hasConstructionEdges()) + { + MESSAGE("Error : Not implemented"); + return NULL; + } + else + { +//#ifdef VTK_HAVE_POLYHEDRON + //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID); + vector nodeIds; + nodeIds.clear(); + vector::const_iterator it = nodes.begin(); + for (; it != nodes.end(); ++it) + nodeIds.push_back((*it)->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->initPoly(nodeIds, quantities, this); + if (!this->registerElement(ID, volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; +//#else +// MESSAGE("AddPolyhedralVolumeWithID smds " << ID); +// for ( int i = 0; i < nodes.size(); ++i ) +// if ( !nodes[ i ] ) return 0; +// volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); +//#endif + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbPolyhedrons++; + } - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } +//#ifndef VTK_HAVE_POLYHEDRON +// if (!registerElement(ID, volume)) +// { +// registerElement(myElementIDFactory->GetFreeID(), volume); +// //RemoveElement(volume, false); +// //volume = NULL; +// } +//#endif return volume; } /////////////////////////////////////////////////////////////////////////////// -/// Create a new polyhedral volume and add it to the mesh. +/// Create a new polyhedral volume and add it to the mesh. /// @return The created volume /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume - (std::vector nodes, - std::vector quantities) + (const vector & nodes, + const vector & quantities) { int ID = myElementIDFactory->GetFreeID(); SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); @@ -1019,41 +1500,186 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume return v; } +SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector& vtkNodeIds) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID); + if (v == NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector& vtkNodeIds, const int ID) +{ + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(vtkNodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + vtkIdType aVtkType = volvtk->GetVtkType(); + switch (aVtkType) + { + case VTK_TETRA: + myInfo.myNbTetras++; + break; + case VTK_PYRAMID: + myInfo.myNbPyramids++; + break; + case VTK_WEDGE: + myInfo.myNbPrisms++; + break; + case VTK_HEXAHEDRON: + myInfo.myNbHexas++; + break; + case VTK_QUADRATIC_TETRA: + myInfo.myNbQuadTetras++; + break; + case VTK_QUADRATIC_PYRAMID: + myInfo.myNbQuadPyramids++; + break; + case VTK_QUADRATIC_WEDGE: + myInfo.myNbQuadPrisms++; + break; + case VTK_QUADRATIC_HEXAHEDRON: + myInfo.myNbQuadHexas++; + break; +//#ifdef VTK_HAVE_POLYHEDRON + case VTK_POLYHEDRON: + myInfo.myNbPolyhedrons++; + break; +//#endif + default: + myInfo.myNbPolyhedrons++; + break; + } + return volvtk; +} + +SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector& vtkNodeIds) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID); + if (f == NULL) myElementIDFactory->ReleaseID(ID); + return f; +} + +SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector& vtkNodeIds, const int ID) +{ + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(vtkNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = facevtk; + vtkIdType aVtkType = facevtk->GetVtkType(); + switch (aVtkType) + { + case VTK_TRIANGLE: + myInfo.myNbTriangles++; + break; + case VTK_QUAD: + myInfo.myNbQuadrangles++; + break; + case VTK_QUADRATIC_TRIANGLE: + myInfo.myNbQuadTriangles++; + break; + case VTK_QUADRATIC_QUAD: + myInfo.myNbQuadQuadrangles++; + break; + case VTK_BIQUADRATIC_QUAD: + myInfo.myNbBiQuadQuadrangles++; + break; + case VTK_POLYGON: + myInfo.myNbPolygons++; + break; + default: + myInfo.myNbPolygons++; + } + return facevtk; +} + /////////////////////////////////////////////////////////////////////////////// /// Registers element with the given ID, maintains inverse connections /////////////////////////////////////////////////////////////////////////////// -bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element) +bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element) { - if (myElementIDFactory->BindID(ID, element)) { - SMDS_ElemIteratorPtr it = element->nodesIterator(); - while (it->more()) { - SMDS_MeshNode *node = static_cast - (const_cast(it->next())); - node->AddInverseElement(element); - } - return true; + //MESSAGE("registerElement " << ID); + if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound + { + MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId()); + return false; } - return false; + + element->myID = ID; + element->myMeshId = myMeshId; + + SMDS_MeshCell *cell = dynamic_cast(element); + MYASSERT(cell); + int vtkId = cell->getVtkId(); + if (vtkId == -1) + vtkId = myElementIDFactory->SetInVtkGrid(element); + + if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector + { +// MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize); + myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1); + } + myCellIdVtkToSmds[vtkId] = ID; + + myElementIDFactory->updateMinMax(ID); + return true; } /////////////////////////////////////////////////////////////////////////////// -/// Return the node whose ID is 'ID'. +/// Return the node whose SMDS ID is 'ID'. /////////////////////////////////////////////////////////////////////////////// const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const { - return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID); + if (ID < 1 || ID >= myNodes.size()) + { +// MESSAGE("------------------------------------------------------------------------- "); +// MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size()); +// MESSAGE("------------------------------------------------------------------------- "); + return 0; + } + return (const SMDS_MeshNode *)myNodes[ID]; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the node whose VTK ID is 'vtkId'. +/////////////////////////////////////////////////////////////////////////////// +const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const +{ + // TODO if needed use mesh->nodeIdFromVtkToSmds + if (vtkId < 0 || vtkId >= (myNodes.size() -1)) + { + MESSAGE("------------------------------------------------------------------------- "); + MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size()); + MESSAGE("------------------------------------------------------------------------- "); + return 0; + } + return (const SMDS_MeshNode *)myNodes[vtkId+1]; } /////////////////////////////////////////////////////////////////////////////// -///Create a triangle and add it to the current mesh. This methode do not bind a +///Create a triangle and add it to the current mesh. This method do not bind an ///ID to the create triangle. /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3) + const SMDS_MeshNode * node3, + int ID) { if ( !node1 || !node2 || !node3) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionEdges()) { SMDS_MeshEdge *edge1, *edge2, *edge3; @@ -1061,15 +1687,35 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, edge2=FindEdgeOrCreate(node2,node3); edge3=FindEdgeOrCreate(node3,node1); + //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbTriangles++; return face; } else { - SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3); - myFaces.Add(face); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(node1->getVtkId()); + nodeIds.push_back(node2->getVtkId()); + nodeIds.push_back(node3->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + //MESSAGE("createTriangle " << ID << " " << face); myInfo.myNbTriangles++; return face; } @@ -1080,14 +1726,16 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, ///a ID to the create triangle. /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4) + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + int ID) { if ( !node1 || !node2 || !node3 || !node4 ) return 0; - if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionEdges()) { + //MESSAGE("createQuadrangle hasConstructionEdges "<< ID); SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; edge1=FindEdgeOrCreate(node1,node2); edge2=FindEdgeOrCreate(node2,node3); @@ -1095,14 +1743,33 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, edge4=FindEdgeOrCreate(node4,node1); SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); - myFaces.Add(face); + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadrangles++; return face; } else { - SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4); - myFaces.Add(face); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(node1->getVtkId()); + nodeIds.push_back(node2->getVtkId()); + nodeIds.push_back(node3->getVtkId()); + nodeIds.push_back(node4->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; myInfo.myNbQuadrangles++; return face; } @@ -1114,7 +1781,18 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) { - RemoveElement(node, true); + MESSAGE("RemoveNode"); + RemoveElement(node, true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Remove an edge and all the elements which own this edge +/////////////////////////////////////////////////////////////////////////////// + +void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d) +{ + MESSAGE("Remove0DElement"); + RemoveElement(elem0d,true); } /////////////////////////////////////////////////////////////////////////////// @@ -1123,7 +1801,8 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node) void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge) { - RemoveElement(edge,true); + MESSAGE("RemoveEdge"); + RemoveElement(edge,true); } /////////////////////////////////////////////////////////////////////////////// @@ -1132,7 +1811,8 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge) void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face) { - RemoveElement(face, true); + MESSAGE("RemoveFace"); + RemoveElement(face, true); } /////////////////////////////////////////////////////////////////////////////// @@ -1141,7 +1821,8 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face) void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume) { - RemoveElement(volume, true); + MESSAGE("RemoveVolume"); + RemoveElement(volume, true); } //======================================================================= @@ -1151,8 +1832,8 @@ void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume) bool SMDS_Mesh::RemoveFromParent() { - if (myParent==NULL) return false; - else return (myParent->RemoveSubMesh(this)); + if (myParent==NULL) return false; + else return (myParent->RemoveSubMesh(this)); } //======================================================================= @@ -1162,89 +1843,54 @@ bool SMDS_Mesh::RemoveFromParent() bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) { - bool found = false; + bool found = false; - list::iterator itmsh=myChildren.begin(); - for (; itmsh!=myChildren.end() && !found; itmsh++) - { - SMDS_Mesh * submesh = *itmsh; - if (submesh == aMesh) - { - found = true; - myChildren.erase(itmsh); - } - } + list::iterator itmsh=myChildren.begin(); + for (; itmsh!=myChildren.end() && !found; itmsh++) + { + SMDS_Mesh * submesh = *itmsh; + if (submesh == aMesh) + { + found = true; + myChildren.erase(itmsh); + } + } - return found; + return found; } //======================================================================= //function : ChangeElementNodes -//purpose : +//purpose : //======================================================================= bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, const SMDS_MeshNode * nodes[], const int nbnodes) { + MESSAGE("SMDS_Mesh::ChangeElementNodes"); // keep current nodes of elem - set oldNodes; - SMDS_ElemIteratorPtr itn = element->nodesIterator(); - while(itn->more()) - oldNodes.insert( itn->next() ); - - if ( !element->IsPoly() ) - myInfo.remove( element ); // element may change type + set oldNodes( element->begin_nodes(), element->end_nodes() ); // change nodes bool Ok = false; - SMDS_MeshElement* elem = const_cast(element); - switch ( elem->GetType() ) - { - case SMDSAbs_Edge: { - if ( nbnodes == 2 ) { - if ( SMDS_MeshEdge* edge = dynamic_cast( elem )) - Ok = edge->ChangeNodes( nodes[0], nodes[1] ); - } - else if ( nbnodes == 3 ) { - if ( SMDS_QuadraticEdge* edge = dynamic_cast( elem )) - Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] ); + SMDS_MeshCell* cell = dynamic_cast((SMDS_MeshElement*) element); + if (cell) + { + Ok = cell->vtkOrder(nodes, nbnodes); + Ok = cell->ChangeNodes(nodes, nbnodes); } - break; - } - case SMDSAbs_Face: { - if ( SMDS_FaceOfNodes* face = dynamic_cast( elem )) - Ok = face->ChangeNodes( nodes, nbnodes ); - else - if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast( elem )) - Ok = QF->ChangeNodes( nodes, nbnodes ); - else - if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem)) - Ok = face->ChangeNodes(nodes, nbnodes); - break; - } - case SMDSAbs_Volume: { - if ( SMDS_VolumeOfNodes* vol = dynamic_cast( elem )) - Ok = vol->ChangeNodes( nodes, nbnodes ); - else - if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem )) - Ok = QV->ChangeNodes( nodes, nbnodes ); - break; - } - default: - MESSAGE ( "WRONG ELEM TYPE"); - } if ( Ok ) { // update InverseElements - set::iterator it; + set::iterator it; // AddInverseElement to new nodes for ( int i = 0; i < nbnodes; i++ ) { it = oldNodes.find( nodes[i] ); if ( it == oldNodes.end() ) // new node - const_cast( nodes[i] )->AddInverseElement( elem ); + const_cast( nodes[i] )->AddInverseElement( cell ); else // remove from oldNodes a node that remains in elem oldNodes.erase( it ); @@ -1252,15 +1898,11 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, // RemoveInverseElement from the nodes removed from elem for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) { - SMDS_MeshNode * n = static_cast - (const_cast( *it )); - n->RemoveInverseElement( elem ); + SMDS_MeshNode * n = const_cast( *it ); + n->RemoveInverseElement( cell ); } } - if ( !element->IsPoly() ) - myInfo.add( element ); // element may change type - return Ok; } @@ -1277,7 +1919,7 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, return false; } - const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast(elem); + const SMDS_VtkVolume* vol = dynamic_cast(elem); if (!vol) { return false; } @@ -1290,7 +1932,9 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, } // change nodes - bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); + // TODO remove this function + //bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); + bool Ok = false; if (!Ok) { return false; } @@ -1322,6 +1966,75 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, } +//======================================================================= +//function : Find0DElement +//purpose : +//======================================================================= +const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const +{ + const SMDS_MeshNode * node = FindNode(idnode); + if(node == NULL) return NULL; + return Find0DElement(node); +} + +const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) +{ + if (!node) return 0; + const SMDS_Mesh0DElement* toReturn = NULL; + SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement); + while (it1->more() && (toReturn == NULL)) { + const SMDS_MeshElement* e = it1->next(); + if (e->NbNodes() == 1) { + toReturn = static_cast(e); + } + } + return toReturn; +} + +//======================================================================= +//function : FindBall +//purpose : +//======================================================================= + +const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const +{ + const SMDS_MeshNode * node = FindNode(idnode); + if(node == NULL) return NULL; + return FindBall(node); +} + +const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node) +{ + if (!node) return 0; + const SMDS_BallElement* toReturn = NULL; + SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball); + while (it1->more() && (toReturn == NULL)) { + const SMDS_MeshElement* e = it1->next(); + if (e->GetGeomType() == SMDSGeom_BALL) + toReturn = static_cast(e); + } + return toReturn; +} + +//======================================================================= +//function : Find0DElementOrCreate +//purpose : +//======================================================================= +//SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node) +//{ +// if (!node) return 0; +// SMDS_Mesh0DElement * toReturn = NULL; +// toReturn = const_cast(Find0DElement(node)); +// if (toReturn == NULL) { +// //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); +// toReturn = new SMDS_Mesh0DElement(node); +// my0DElements.Add(toReturn); +// myInfo.myNb0DElements++; +// } +// return toReturn; +//} + + //======================================================================= //function : FindEdge //purpose : @@ -1364,15 +2077,30 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, //======================================================================= SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) { if ( !node1 || !node2) return 0; SMDS_MeshEdge * toReturn=NULL; toReturn=const_cast(FindEdge(node1,node2)); if(toReturn==NULL) { - if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); - toReturn=new SMDS_MeshEdge(node1,node2); - myEdges.Add(toReturn); + if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element + adjustmyCellsCapacity(ID); + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(node1->getVtkId()); + nodeIds.push_back(node2->getVtkId()); + + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(nodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + toReturn = edgevtk; + myCells[ID] = toReturn; myInfo.myNbEdges++; } return toReturn; @@ -1427,7 +2155,7 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, //======================================================================= const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, - int idnode3) const + int idnode3) const { const SMDS_MeshNode * node1=FindNode(idnode1); const SMDS_MeshNode * node2=FindNode(idnode2); @@ -1469,7 +2197,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, SMDS_MeshFace * toReturn=NULL; toReturn = const_cast(FindFace(node1,node2,node3)); if(toReturn==NULL) { - toReturn = createTriangle(node1,node2,node3); + int ID = myElementIDFactory->GetFreeID(); + toReturn = createTriangle(node1,node2,node3, ID); } return toReturn; } @@ -1527,7 +2256,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, SMDS_MeshFace * toReturn=NULL; toReturn=const_cast(FindFace(node1,node2,node3,node4)); if(toReturn==NULL) { - toReturn=createQuadrangle(node1,node2,node3,node4); + int ID = myElementIDFactory->GetFreeID(); + toReturn=createQuadrangle(node1,node2,node3,node4,ID); } return toReturn; } @@ -1651,7 +2381,16 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { - return myElementIDFactory->MeshElement(IDelem); + if ((IDelem <= 0) || IDelem >= myCells.size()) + { + MESSAGE("--------------------------------------------------------------------------------- "); + MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size()); + MESSAGE("--------------------------------------------------------------------------------- "); + // TODO raise an exception + //assert(0); + return 0; + } + return myCells[IDelem]; } //======================================================================= @@ -1659,33 +2398,55 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const //purpose : find polygon //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes_ids) const +const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector& nodes_ids) const { int nbnodes = nodes_ids.size(); - std::vector poly_nodes (nbnodes); + vector poly_nodes (nbnodes); for (int inode = 0; inode < nbnodes; inode++) { const SMDS_MeshNode * node = FindNode(nodes_ids[inode]); if (node == NULL) return NULL; + poly_nodes[inode] = node; } return FindFace(poly_nodes); } -const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes) +const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector& nodes) { - if ( nodes.size() > 2 && nodes[0] ) { - SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face); - while (itF->more()) { - 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; - } + return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face ); +} + + +//================================================================================ +/*! + * \brief Return element based on all given nodes + * \param nodes - node of element + * \param type - type of element + * \param noMedium - true if medium nodes of quadratic element are not included in + * \retval const SMDS_MeshElement* - found element or NULL + */ +//================================================================================ + +const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector& nodes, + const SMDSAbs_ElementType type, + const bool noMedium) +{ + if ( nodes.size() > 0 && nodes[0] ) + { + SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type); + while (itF->more()) + { + const SMDS_MeshElement* e = itF->next(); + int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes(); + if ( nbNodesToCheck == nodes.size() ) + { + for ( int i = 1; e && i < nodes.size(); ++ i ) + { + int nodeIndex = e->GetNodeIndex( nodes[ i ]); + if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck ) + e = 0; } - if ( f ) - return static_cast (f); + if ( e ) + return static_cast (e); } } } @@ -1694,100 +2455,111 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nod //======================================================================= //function : DumpNodes -//purpose : +//purpose : //======================================================================= void SMDS_Mesh::DumpNodes() const { - MESSAGE("dump nodes of mesh : "); - SMDS_NodeIteratorPtr itnode=nodesIterator(); - while(itnode->more()) MESSAGE(itnode->next()); + MESSAGE("dump nodes of mesh : "); + SMDS_NodeIteratorPtr itnode=nodesIterator(); + while(itnode->more()) ; //MESSAGE(itnode->next()); +} + +//======================================================================= +//function : Dump0DElements +//purpose : +//======================================================================= +void SMDS_Mesh::Dump0DElements() const +{ + MESSAGE("dump 0D elements of mesh : "); + SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement); + while(it0d->more()) ; //MESSAGE(it0d->next()); } //======================================================================= //function : DumpEdges -//purpose : +//purpose : //======================================================================= void SMDS_Mesh::DumpEdges() const { - MESSAGE("dump edges of mesh : "); - SMDS_EdgeIteratorPtr itedge=edgesIterator(); - while(itedge->more()) MESSAGE(itedge->next()); + MESSAGE("dump edges of mesh : "); + SMDS_EdgeIteratorPtr itedge=edgesIterator(); + while(itedge->more()) ; //MESSAGE(itedge->next()); } //======================================================================= //function : DumpFaces -//purpose : +//purpose : //======================================================================= void SMDS_Mesh::DumpFaces() const { - MESSAGE("dump faces of mesh : "); - SMDS_FaceIteratorPtr itface=facesIterator(); - while(itface->more()) MESSAGE(itface->next()); + MESSAGE("dump faces of mesh : "); + SMDS_FaceIteratorPtr itface=facesIterator(); + while(itface->more()) ; //MESSAGE(itface->next()); } //======================================================================= //function : DumpVolumes -//purpose : +//purpose : //======================================================================= void SMDS_Mesh::DumpVolumes() const { - MESSAGE("dump volumes of mesh : "); - SMDS_VolumeIteratorPtr itvol=volumesIterator(); - while(itvol->more()) MESSAGE(itvol->next()); + MESSAGE("dump volumes of mesh : "); + SMDS_VolumeIteratorPtr itvol=volumesIterator(); + while(itvol->more()) ; //MESSAGE(itvol->next()); } //======================================================================= //function : DebugStats -//purpose : +//purpose : //======================================================================= void SMDS_Mesh::DebugStats() const { - MESSAGE("Debug stats of mesh : "); + MESSAGE("Debug stats of mesh : "); - MESSAGE("===== NODES ====="<more()) - { - const SMDS_MeshNode *node = itnode->next(); + SMDS_NodeIteratorPtr itnode=nodesIterator(); + int sizeofnodes = 0; + int sizeoffaces = 0; - sizeofnodes += sizeof(*node); - - SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); - while(it->more()) - { - const SMDS_MeshElement *me = it->next(); - sizeofnodes += sizeof(me); - } + while(itnode->more()) + { + const SMDS_MeshNode *node = itnode->next(); + + sizeofnodes += sizeof(*node); - } + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while(it->more()) + { + const SMDS_MeshElement *me = it->next(); + sizeofnodes += sizeof(me); + } + } - SMDS_FaceIteratorPtr itface=facesIterator(); - while(itface->more()) - { - const SMDS_MeshElement *face = itface->next(); - sizeoffaces += sizeof(*face); + SMDS_FaceIteratorPtr itface=facesIterator(); + while(itface->more()) + { + const SMDS_MeshElement *face = itface->next(); + sizeoffaces += sizeof(*face); + } - } - MESSAGE("total size of node elements = " << sizeofnodes);; - MESSAGE("total size of face elements = " << sizeoffaces);; + MESSAGE("total size of node elements = " << sizeofnodes);; + MESSAGE("total size of face elements = " << sizeoffaces);; - //#endif + //#endif } /////////////////////////////////////////////////////////////////////////////// @@ -1795,7 +2567,26 @@ void SMDS_Mesh::DebugStats() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbNodes() const { - return myNodes.Size(); + //MESSAGE(myGrid->GetNumberOfPoints()); + //MESSAGE(myInfo.NbNodes()); + //MESSAGE(myNodeMax); + return myInfo.NbNodes(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of 0D elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::Nb0DElements() const +{ + return myInfo.Nb0DElements(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of 0D elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbBalls() const +{ + return myInfo.NbBalls(); } /////////////////////////////////////////////////////////////////////////////// @@ -1803,7 +2594,7 @@ int SMDS_Mesh::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbEdges() const { - return myEdges.Size(); + return myInfo.NbEdges(); } /////////////////////////////////////////////////////////////////////////////// @@ -1811,7 +2602,7 @@ int SMDS_Mesh::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbFaces() const { - return myFaces.Size(); + return myInfo.NbFaces(); } /////////////////////////////////////////////////////////////////////////////// @@ -1819,17 +2610,16 @@ int SMDS_Mesh::NbFaces() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbVolumes() const { - return myVolumes.Size(); + return myInfo.NbVolumes(); } /////////////////////////////////////////////////////////////////////////////// /// Return the number of child mesh of this mesh. -/// Note that the tree structure of SMDS_Mesh seems to be unused in this version -/// (2003-09-08) of SMESH +/// Note that the tree structure of SMDS_Mesh is unused in SMESH /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbSubMesh() const { - return myChildren.size(); + return myChildren.size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1854,36 +2644,18 @@ SMDS_Mesh::~SMDS_Mesh() { SMDS_ElemIteratorPtr eIt = elementsIterator(); while ( eIt->more() ) - myElementIDFactory->ReleaseID(eIt->next()->GetID()); + { + const SMDS_MeshElement *elem = eIt->next(); + myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); + } SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - myNodeIDFactory->ReleaseID(itn->next()->GetID()); - } - SetOfNodes::Iterator itn(myNodes); - for (; itn.More(); itn.Next()) - delete itn.Value(); - - SetOfEdges::Iterator ite(myEdges); - for (; ite.More(); ite.Next()) - { - SMDS_MeshElement* elem = ite.Value(); - delete elem; - } - - SetOfFaces::Iterator itf(myFaces); - for (; itf.More(); itf.Next()) - { - SMDS_MeshElement* elem = itf.Value(); - delete elem; - } - - SetOfVolumes::Iterator itv(myVolumes); - for (; itv.More(); itv.Next()) - { - SMDS_MeshElement* elem = itv.Value(); - delete elem; + { + const SMDS_MeshNode *node = itn->next(); + ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition()); + myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); + } } - } //================================================================================ @@ -1894,43 +2666,88 @@ SMDS_Mesh::~SMDS_Mesh() void SMDS_Mesh::Clear() { - if (myParent!=NULL) { + MESSAGE("SMDS_Mesh::Clear"); + if (myParent!=NULL) + { SMDS_ElemIteratorPtr eIt = elementsIterator(); while ( eIt->more() ) - myElementIDFactory->ReleaseID(eIt->next()->GetID()); + { + const SMDS_MeshElement *elem = eIt->next(); + myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); + } SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - myNodeIDFactory->ReleaseID(itn->next()->GetID()); - } - else { + { + const SMDS_MeshNode *node = itn->next(); + myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); + } + } + else + { myNodeIDFactory->Clear(); myElementIDFactory->Clear(); - } - SMDS_VolumeIteratorPtr itv = volumesIterator(); + } + + SMDS_ElemIteratorPtr itv = elementsIterator(); while (itv->more()) - delete itv->next(); - myVolumes.Clear(); - - SMDS_FaceIteratorPtr itf = facesIterator(); - while (itf->more()) - delete itf->next(); - myFaces.Clear(); - - SMDS_EdgeIteratorPtr ite = edgesIterator(); - while (ite->more()) - delete ite->next(); - myEdges.Clear(); + { + SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next()); + SMDSAbs_ElementType aType = elem->GetType(); + switch (aType) + { + case SMDSAbs_0DElement: + delete elem; + break; + case SMDSAbs_Edge: + myEdgePool->destroy(static_cast(elem)); + break; + case SMDSAbs_Face: + myFacePool->destroy(static_cast(elem)); + break; + case SMDSAbs_Volume: + myVolumePool->destroy(static_cast(elem)); + break; + case SMDSAbs_Ball: + myBallPool->destroy(static_cast(elem)); + break; + default: + break; + } + } + myCells.clear(); + myCellIdVtkToSmds.clear(); + //myCellIdSmdsToVtk.clear(); SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - delete itn->next(); - myNodes.Clear(); + { + SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next()); + node->SetPosition(SMDS_SpacePosition::originSpacePosition()); + myNodePool->destroy(node); + } + myNodes.clear(); list::iterator itc=myChildren.begin(); while(itc!=myChildren.end()) (*itc)->Clear(); + myModified = false; + xmin = 0; xmax = 0; + ymin = 0; ymax = 0; + zmin = 0; zmax = 0; + myInfo.Clear(); + + myGrid->Initialize(); + myGrid->Allocate(); + vtkPoints* points = vtkPoints::New(); + // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion" + // using double type for storing coordinates of nodes instead float. + points->SetDataType(VTK_DOUBLE); + points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/); + myGrid->SetPoints( points ); + points->Delete(); + myGrid->BuildLinks(); } /////////////////////////////////////////////////////////////////////////////// @@ -1940,7 +2757,7 @@ void SMDS_Mesh::Clear() /////////////////////////////////////////////////////////////////////////////// bool SMDS_Mesh::hasConstructionEdges() { - return myHasConstructionEdges; + return myHasConstructionEdges; } /////////////////////////////////////////////////////////////////////////////// @@ -1952,7 +2769,7 @@ bool SMDS_Mesh::hasConstructionEdges() /////////////////////////////////////////////////////////////////////////////// bool SMDS_Mesh::hasConstructionFaces() { - return myHasConstructionFaces; + return myHasConstructionFaces; } /////////////////////////////////////////////////////////////////////////////// @@ -1961,7 +2778,7 @@ bool SMDS_Mesh::hasConstructionFaces() /////////////////////////////////////////////////////////////////////////////// bool SMDS_Mesh::hasInverseElements() { - return myHasInverseElements; + return myHasInverseElements; } /////////////////////////////////////////////////////////////////////////////// @@ -1970,7 +2787,7 @@ bool SMDS_Mesh::hasInverseElements() /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::setConstructionEdges(bool b) { - myHasConstructionEdges=b; + myHasConstructionEdges=b; } /////////////////////////////////////////////////////////////////////////////// @@ -1979,7 +2796,7 @@ void SMDS_Mesh::setConstructionEdges(bool b) /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::setConstructionFaces(bool b) { - myHasConstructionFaces=b; + myHasConstructionFaces=b; } /////////////////////////////////////////////////////////////////////////////// @@ -1988,283 +2805,339 @@ void SMDS_Mesh::setConstructionFaces(bool b) /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::setInverseElements(bool b) { - if(!b) MESSAGE("Error : inverseElement=false not implemented"); - myHasInverseElements=b; + if(!b) MESSAGE("Error : inverseElement=false not implemented"); + myHasInverseElements=b; +} + +namespace { + + //================================================================================ + /*! + * \brief Iterator on elements in id increasing order + */ + //================================================================================ + + template + class IdSortedIterator : public SMDS_Iterator + { + SMDS_MeshElementIDFactory& myIDFact; + int myID, myMaxID, myNbFound, myTotalNb; + SMDSAbs_ElementType myType; + ELEM myElem; + + public: + IdSortedIterator(const SMDS_MeshElementIDFactory& fact, + const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!! + const int totalNb) + :myIDFact( fact ), + myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ), + myType( type ), + myElem(0) + { + next(); + } + bool more() + { + return myElem; + } + ELEM next() + { + ELEM current = myElem; + + for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID ) + if ((myElem = (ELEM) myIDFact.MeshElement( myID )) + && myElem->GetType() != myType ) + myElem = 0; + + myNbFound += bool(myElem); + + return current; + } + }; + + //================================================================================ + /*! + * \brief Iterator on vector of elements, possibly being resized while iteration + */ + //================================================================================ + + template > + class ElemVecIterator: public SMDS_Iterator + { + const std::vector& _vector; + size_t _index; + bool _more; + VALUE_FILTER _filter; + public: + ElemVecIterator(const std::vector& vec, + const VALUE_FILTER& filter=VALUE_FILTER() ) + :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter ) + { + if ( _more && !_filter( _vector[ _index ])) + next(); + } + virtual bool more() + { + return _more; + } + virtual RETURN_VALUE next() + { + if ( !_more ) return NULL; + VECTOR_VALUE current = _vector[ _index ]; + _more = 0; + while ( !_more && ++_index < _vector.size() ) + _more = _filter( _vector[ _index ]); + return (RETURN_VALUE) current; + } + }; } /////////////////////////////////////////////////////////////////////////////// /// Return an iterator on nodes of the current mesh factory /////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator -{ - SMDS_ElemIteratorPtr myIterator; - public: - SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it) - {} - bool more() - { - return myIterator->more(); - } +SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const +{ + // naturally always sorted by ID + typedef ElemVecIterator TIterator; + return SMDS_NodeIteratorPtr( new TIterator(myNodes)); +} - const SMDS_MeshNode* next() - { - return static_cast(myIterator->next()); - } -}; +SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const +{ + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator; + return SMDS_ElemIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type ))); +} -SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const +SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const { - return SMDS_NodeIteratorPtr - (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator())); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator; + return SMDS_ElemIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type ))); } /////////////////////////////////////////////////////////////////////////////// /// Return an iterator on elements of the current mesh factory /////////////////////////////////////////////////////////////////////////////// -SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const +SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const { - return myElementIDFactory->elementsIterator(); + // naturally always sorted by ID + switch ( type ) { + + case SMDSAbs_All: + return SMDS_ElemIteratorPtr (new ElemVecIterator(myCells)); + + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr + ( new ElemVecIterator( myNodes )); + + default: + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type ))); + } + return SMDS_ElemIteratorPtr(); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on edges of the current mesh. /////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator -{ - typedef SMDS_Mesh::SetOfEdges SetOfEdges; - SetOfEdges::Iterator myIterator; - public: - SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s) - {} - bool more() - { - while(myIterator.More()) - { - if(myIterator.Value()->GetID()!=-1) - return true; - myIterator.Next(); - } - return false; - } - - const SMDS_MeshEdge* next() - { - const SMDS_MeshEdge* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; - -SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const +SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const { - return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges)); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_EdgeIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ))); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on faces of the current mesh. /////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator -{ - typedef SMDS_Mesh::SetOfFaces SetOfFaces; - SetOfFaces::Iterator myIterator; - public: - SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s) - {} - - bool more() - { - while(myIterator.More()) - { - if(myIterator.Value()->GetID()!=-1) - return true; - myIterator.Next(); - } - return false; - } - const SMDS_MeshFace* next() - { - const SMDS_MeshFace* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; - -SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const +SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const { - return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces)); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_FaceIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face ))); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on volumes of the current mesh. /////////////////////////////////////////////////////////////////////////////// -class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator -{ - typedef SMDS_Mesh::SetOfVolumes SetOfVolumes; - SetOfVolumes::Iterator myIterator; - public: - SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s) - {} - - bool more() - { - return myIterator.More() != Standard_False; - } - - const SMDS_MeshVolume* next() - { - const SMDS_MeshVolume* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; -SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const +SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const { - return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes)); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_VolumeIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ))); } /////////////////////////////////////////////////////////////////////////////// /// Do intersection of sets (more than 2) /////////////////////////////////////////////////////////////////////////////// static set * intersectionOfSets( - set vs[], int numberOfSets) + set vs[], int numberOfSets) { - set* rsetA=new set(vs[0]); - set* rsetB; + set* rsetA=new set(vs[0]); + set* rsetB; - for(int i=0; i(); - set_intersection( - rsetA->begin(), rsetA->end(), - vs[i+1].begin(), vs[i+1].end(), - inserter(*rsetB, rsetB->begin())); - delete rsetA; - rsetA=rsetB; - } - return rsetA; + for(int i=0; i(); + set_intersection( + rsetA->begin(), rsetA->end(), + vs[i+1].begin(), vs[i+1].end(), + inserter(*rsetB, rsetB->begin())); + delete rsetA; + rsetA=rsetB; + } + return rsetA; } /////////////////////////////////////////////////////////////////////////////// -/// Return the list of finit elements owning the given element +/// Return the list of finite elements owning the given element: elements +/// containing all the nodes of the given element, for instance faces and +/// volumes containing a given edge. /////////////////////////////////////////////////////////////////////////////// static set * getFinitElements(const SMDS_MeshElement * element) { - int numberOfSets=element->NbNodes(); - set *initSet = new set[numberOfSets]; + int numberOfSets=element->NbNodes(); + set *initSet = new set[numberOfSets]; - SMDS_ElemIteratorPtr itNodes=element->nodesIterator(); + SMDS_ElemIteratorPtr itNodes=element->nodesIterator(); - int i=0; - while(itNodes->more()) - { - const SMDS_MeshNode * n=static_cast(itNodes->next()); - SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + int i=0; + while(itNodes->more()) + { + const SMDS_MeshElement* node = itNodes->next(); + MYASSERT(node); + const SMDS_MeshNode * n=static_cast(node); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + + //initSet[i]=set(); + while(itFe->more()) + { + const SMDS_MeshElement* elem = itFe->next(); + MYASSERT(elem); + initSet[i].insert(elem); - //initSet[i]=set(); - while(itFe->more()) - initSet[i].insert(itFe->next()); + } - i++; - } - set *retSet=intersectionOfSets(initSet, numberOfSets); + i++; + } + set *retSet=intersectionOfSets(initSet, numberOfSets); +// MESSAGE("nb elems " << i << " intersection " << retSet->size()); delete [] initSet; - return retSet; + return retSet; } /////////////////////////////////////////////////////////////////////////////// /// Return the list of nodes used only by the given elements /////////////////////////////////////////////////////////////////////////////// static set * getExclusiveNodes( - set& elements) -{ - set * toReturn=new set(); - set::iterator itElements=elements.begin(); - - while(itElements!=elements.end()) - { - SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator(); - itElements++; - - while(itNodes->more()) - { - const SMDS_MeshNode * n=static_cast(itNodes->next()); - SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); - set s; - while(itFe->more()) + set& elements) +{ + set * toReturn=new set(); + set::iterator itElements=elements.begin(); + + while(itElements!=elements.end()) + { + SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator(); + itElements++; + + while(itNodes->more()) + { + const SMDS_MeshNode * n=static_cast(itNodes->next()); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + set s; + while(itFe->more()) s.insert(itFe->next()); - if(s==elements) toReturn->insert(n); - } - } - return toReturn; + if(s==elements) toReturn->insert(n); + } + } + return toReturn; } /////////////////////////////////////////////////////////////////////////////// -///Find the children of an element that are made of given nodes +///Find the children of an element that are made of given nodes ///@param setOfChildren The set in which matching children will be inserted ///@param element The element were to search matching children ///@param nodes The nodes that the children must have to be selected /////////////////////////////////////////////////////////////////////////////// -void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren, - const SMDS_MeshElement * element, set& nodes) -{ - - switch(element->GetType()) - { - case SMDSAbs_Node: - MESSAGE("Internal Error: This should not append"); - break; - case SMDSAbs_Edge: - { - SMDS_ElemIteratorPtr itn=element->nodesIterator(); - while(itn->more()) - { - const SMDS_MeshElement * e=itn->next(); - if(nodes.find(e)!=nodes.end()) +void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren, + const SMDS_MeshElement * element, + set& nodes) +{ + switch(element->GetType()) + { + case SMDSAbs_Node: + MESSAGE("Internal Error: This should not happen"); + break; + case SMDSAbs_0DElement: + { + } + break; + case SMDSAbs_Edge: + { + SMDS_ElemIteratorPtr itn=element->nodesIterator(); + while(itn->more()) + { + const SMDS_MeshElement * e=itn->next(); + if(nodes.find(e)!=nodes.end()) { setOfChildren.insert(element); break; } - } - } break; - case SMDSAbs_Face: - { - SMDS_ElemIteratorPtr itn=element->nodesIterator(); - while(itn->more()) - { - const SMDS_MeshElement * e=itn->next(); - if(nodes.find(e)!=nodes.end()) + } + } break; + case SMDSAbs_Face: + { + SMDS_ElemIteratorPtr itn=element->nodesIterator(); + while(itn->more()) + { + const SMDS_MeshElement * e=itn->next(); + if(nodes.find(e)!=nodes.end()) { setOfChildren.insert(element); break; } - } - if(hasConstructionEdges()) - { - SMDS_ElemIteratorPtr ite=element->edgesIterator(); - while(ite->more()) - addChildrenWithNodes(setOfChildren, ite->next(), nodes); - } - } break; - case SMDSAbs_Volume: - { - if(hasConstructionFaces()) - { - SMDS_ElemIteratorPtr ite=element->facesIterator(); - while(ite->more()) - addChildrenWithNodes(setOfChildren, ite->next(), nodes); - } - else if(hasConstructionEdges()) - { - SMDS_ElemIteratorPtr ite=element->edgesIterator(); - while(ite->more()) - addChildrenWithNodes(setOfChildren, ite->next(), nodes); - } - } - } + } + if(hasConstructionEdges()) + { + SMDS_ElemIteratorPtr ite=element->edgesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + } break; + case SMDSAbs_Volume: + { + if(hasConstructionFaces()) + { + SMDS_ElemIteratorPtr ite=element->facesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + else if(hasConstructionEdges()) + { + SMDS_ElemIteratorPtr ite=element->edgesIterator(); + while(ite->more()) + addChildrenWithNodes(setOfChildren, ite->next(), nodes); + } + } + } } /////////////////////////////////////////////////////////////////////////////// @@ -2272,17 +3145,17 @@ void SMDS_Mesh::addChildrenWithNodes(set& setOfChildren ///@param removenodes if true remaining nodes will be removed /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, - const bool removenodes) + const bool removenodes) { list removedElems; list removedNodes; RemoveElement( elem, removedElems, removedNodes, removenodes ); } - + /////////////////////////////////////////////////////////////////////////////// ///@param elem The element to delete -///@param removedElems contains all removed elements -///@param removedNodes contains all removed nodes +///@param removedElems to be filled with all removed elements +///@param removedNodes to be filled with all removed nodes ///@param removenodes if true remaining nodes will be removed /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, @@ -2290,125 +3163,195 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, list& removedNodes, bool removenodes) { + //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes); // get finite elements built on elem set * s1; - if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge || - !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face || - elem->GetType() == SMDSAbs_Volume) - { - s1 = new set(); - s1->insert(elem); - } + if ( (elem->GetType() == SMDSAbs_0DElement) + || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges()) + || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces()) + || (elem->GetType() == SMDSAbs_Volume) ) + { + s1 = new set (); + s1->insert(elem); + } else s1 = getFinitElements(elem); // get exclusive nodes (which would become free afterwards) set * s2; if (elem->GetType() == SMDSAbs_Node) // a node is removed - { - // do not remove nodes except elem - s2 = new set(); - s2->insert(elem); - removenodes = true; - } + { + // do not remove nodes except elem + s2 = new set (); + s2->insert(elem); + removenodes = true; + } else s2 = getExclusiveNodes(*s1); // form the set of finite and construction elements to remove set s3; - set::iterator it=s1->begin(); - while(it!=s1->end()) - { - addChildrenWithNodes(s3, *it ,*s2); - s3.insert(*it); - it++; - } - if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem); + set::iterator it = s1->begin(); + while (it != s1->end()) + { + addChildrenWithNodes(s3, *it, *s2); + s3.insert(*it); + it++; + } + if (elem->GetType() != SMDSAbs_Node) + s3.insert(elem); // remove finite and construction elements - it=s3.begin(); - while(it!=s3.end()) - { - // Remove element from of its nodes - SMDS_ElemIteratorPtr itn=(*it)->nodesIterator(); - while(itn->more()) + it = s3.begin(); + while (it != s3.end()) { - SMDS_MeshNode * n = static_cast - (const_cast(itn->next())); - n->RemoveInverseElement( (*it) ); + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn = (*it)->nodesIterator(); + while (itn->more()) + { + SMDS_MeshNode * n = static_cast (const_cast (itn->next())); + n->RemoveInverseElement((*it)); + } + int IdToRemove = (*it)->GetID(); + int vtkid = (*it)->getVtkId(); + //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid << + // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType()); + switch ((*it)->GetType()) + { + case SMDSAbs_Node: + MYASSERT("Internal Error: This should not happen") + ; + break; + case SMDSAbs_0DElement: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ? + myInfo.remove(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + delete (*it); + break; + case SMDSAbs_Edge: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveEdge(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkEdge* vtkElem = dynamic_cast(*it)) + myEdgePool->destroy((SMDS_VtkEdge*) vtkElem); + else + delete (*it); + break; + case SMDSAbs_Face: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveFace(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkFace* vtkElem = dynamic_cast(*it)) + myFacePool->destroy((SMDS_VtkFace*) vtkElem); + else + delete (*it); + break; + case SMDSAbs_Volume: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.RemoveVolume(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_VtkVolume* vtkElem = dynamic_cast(*it)) + myVolumePool->destroy((SMDS_VtkVolume*) vtkElem); + else + delete (*it); + break; + case SMDSAbs_Ball: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.remove(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_BallElement* vtkElem = dynamic_cast(*it)) + myBallPool->destroy(const_cast( vtkElem )); + else + delete (*it); + break; + } + if (vtkid >= 0) + { + //MESSAGE("VTK_EMPTY_CELL in " << vtkid); + this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL); + } + it++; } - switch((*it)->GetType()) - { - case SMDSAbs_Node: - MESSAGE("Internal Error: This should not happen"); - break; - case SMDSAbs_Edge: - myEdges.Remove(static_cast - (const_cast(*it))); - myInfo.RemoveEdge(*it); - break; - case SMDSAbs_Face: - myFaces.Remove(static_cast - (const_cast(*it))); - myInfo.RemoveFace(*it); - break; - case SMDSAbs_Volume: - myVolumes.Remove(static_cast - (const_cast(*it))); - myInfo.RemoveVolume(*it); - break; - } - //MESSAGE( "SMDS: RM elem " << (*it)->GetID() ); - removedElems.push_back( (*it) ); - myElementIDFactory->ReleaseID((*it)->GetID()); - delete (*it); - it++; - } - // remove exclusive (free) nodes - if(removenodes) - { - it=s2->begin(); - while(it!=s2->end()) + if (removenodes) { - //MESSAGE( "SMDS: RM node " << (*it)->GetID() ); - myNodes.Remove(static_cast - (const_cast(*it))); - myInfo.myNbNodes--; - myNodeIDFactory->ReleaseID((*it)->GetID()); - removedNodes.push_back( (*it) ); - delete *it; - it++; + it = s2->begin(); + while (it != s2->end()) + { + int IdToRemove = (*it)->GetID(); + //MESSAGE( "SMDS: RM node " << IdToRemove); + if (IdToRemove >= 0) + { + myNodes[IdToRemove] = 0; + myInfo.myNbNodes--; + } + myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId()); + removedNodes.push_back((*it)); + if (const SMDS_MeshNode* vtkElem = dynamic_cast(*it)) + { + ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition()); + myNodePool->destroy((SMDS_MeshNode*) vtkElem); + } + else + delete (*it); + it++; + } } - } delete s2; delete s1; } - + /////////////////////////////////////////////////////////////////////////////// ///@param elem The element to delete /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) { + int elemId = elem->GetID(); + int vtkId = elem->getVtkId(); + //MESSAGE("RemoveFreeElement " << elemId); SMDSAbs_ElementType aType = elem->GetType(); + SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem); if (aType == SMDSAbs_Node) { + //MESSAGE("Remove free node " << elemId); // only free node can be removed by this method - const SMDS_MeshNode* n = static_cast(elem); + const SMDS_MeshNode* n = static_cast(todest); SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); if (!itFe->more()) { // free node - myNodes.Remove(const_cast(n)); + myNodes[elemId] = 0; myInfo.myNbNodes--; - myNodeIDFactory->ReleaseID(elem->GetID()); - delete elem; + ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition()); + myNodePool->destroy(static_cast(todest)); + myNodeIDFactory->ReleaseID(elemId, vtkId); } } else { if (hasConstructionEdges() || hasConstructionFaces()) // this methods is only for meshes without descendants return; + //MESSAGE("Remove free element " << elemId); // Remove element from of its nodes SMDS_ElemIteratorPtr itn = elem->nodesIterator(); while (itn->more()) { @@ -2418,27 +3361,39 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) } // in meshes without descendants elements are always free - switch (aType) { + switch (aType) { + case SMDSAbs_0DElement: + myCells[elemId] = 0; + myInfo.remove(elem); + delete elem; + break; case SMDSAbs_Edge: - myEdges.Remove(static_cast - (const_cast(elem))); + myCells[elemId] = 0; myInfo.RemoveEdge(elem); + myEdgePool->destroy(static_cast(todest)); break; case SMDSAbs_Face: - myFaces.Remove(static_cast - (const_cast(elem))); + myCells[elemId] = 0; myInfo.RemoveFace(elem); + myFacePool->destroy(static_cast(todest)); break; case SMDSAbs_Volume: - myVolumes.Remove(static_cast - (const_cast(elem))); + myCells[elemId] = 0; myInfo.RemoveVolume(elem); + myVolumePool->destroy(static_cast(todest)); + break; + case SMDSAbs_Ball: + myCells[elemId] = 0; + myInfo.remove(elem); + myBallPool->destroy(static_cast(todest)); break; default: break; } - myElementIDFactory->ReleaseID(elem->GetID()); - delete elem; + myElementIDFactory->ReleaseID(elemId, vtkId); + + this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL); + // --- to do: keep vtkid in a list of reusable cells } } @@ -2454,44 +3409,36 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const while (itn->more()) if (elem == itn->next()) return true; - SMDS_EdgeIteratorPtr ite = edgesIterator(); + SMDS_ElemIteratorPtr ite = elementsIterator(); while (ite->more()) if (elem == ite->next()) return true; - SMDS_FaceIteratorPtr itf = facesIterator(); - while (itf->more()) - if (elem == itf->next()) - return true; - SMDS_VolumeIteratorPtr itv = volumesIterator(); - while (itv->more()) - if (elem == itv->next()) - return true; return false; } //======================================================================= //function : MaxNodeID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MaxNodeID() const { - return myNodeIDFactory->GetMaxID(); + return myNodeMax; } //======================================================================= //function : MinNodeID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MinNodeID() const { - return myNodeIDFactory->GetMinID(); + return myNodeMin; } //======================================================================= //function : MaxElementID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MaxElementID() const @@ -2501,7 +3448,7 @@ int SMDS_Mesh::MaxElementID() const //======================================================================= //function : MinElementID -//purpose : +//purpose : //======================================================================= int SMDS_Mesh::MinElementID() const @@ -2516,10 +3463,11 @@ int SMDS_Mesh::MinElementID() const void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) { + MESSAGE("Renumber"); if ( deltaID == 0 ) return; - SMDS_MeshElementIDFactory * idFactory = + SMDS_MeshNodeIDFactory * idFactory = isNodes ? myNodeIDFactory : myElementIDFactory; // get existing elements in the order of ID increasing @@ -2582,9 +3530,9 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) //======================================================================= //function : AddEdgeWithID -//purpose : +//purpose : //======================================================================= -SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) { return SMDS_Mesh::AddEdgeWithID ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1), @@ -2595,10 +3543,10 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) //======================================================================= //function : AddEdge -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, + const SMDS_MeshNode* n2, const SMDS_MeshNode* n12) { return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID()); @@ -2606,41 +3554,52 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, //======================================================================= //function : AddEdgeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n12, - int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) { if ( !n1 || !n2 || !n12 ) return 0; - SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12); - if(myElementIDFactory->BindID(ID, edge)) { - SMDS_MeshNode *node1,*node2, *node12; - node1 = const_cast(n1); - node2 = const_cast(n2); - node12 = const_cast(n12); - node1->AddInverseElement(edge); - node2->AddInverseElement(edge); - node12->AddInverseElement(edge); - myEdges.Add(edge); - myInfo.myNbQuadEdges++; - return edge; - } - else { - delete edge; - return NULL; - } + + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + SMDS_MeshEdge * edge = 0; + SMDS_VtkEdge *edgevtk = myEdgePool->getNew(); + edgevtk->init(nodeIds, this); + if (!this->registerElement(ID,edgevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL); + myEdgePool->destroy(edgevtk); + return 0; + } + edge = edgevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = edge; + myInfo.myNbQuadEdges++; + +// if (!registerElement(ID, edge)) { +// RemoveElement(edge, false); +// edge = NULL; +// } + return edge; + } //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31) @@ -2651,7 +3610,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n12,int n23,int n31, int ID) @@ -2668,14 +3627,14 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, int ID) { if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0; @@ -2683,27 +3642,49 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, // creation quadratic edges - not implemented return 0; } - SMDS_QuadraticFaceOfNodes* face = - new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31); - myFaces.Add(face); - myInfo.myNbQuadTriangles++; - - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; + else + { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n31->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbQuadTriangles++; + +// if (!registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; } - return face; } //======================================================================= //function : AddFace -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, @@ -2715,7 +3696,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n34,int n41, int ID) @@ -2734,7 +3715,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, //======================================================================= //function : AddFaceWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -2742,39 +3723,159 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, int ID) { if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0; if(hasConstructionEdges()) { // creation quadratic edges - not implemented + return 0; + } + else + { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n41->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbQuadQuadrangles++; + +// if (!registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; } - SMDS_QuadraticFaceOfNodes* face = - new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41); - myFaces.Add(face); - myInfo.myNbQuadQuadrangles++; +} - if (!registerElement(ID, face)) { - RemoveElement(face, false); - face = NULL; +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter, + myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int nCenter, int ID) +{ + return SMDS_Mesh::AddFaceWithID + ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter), + ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0; + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + return 0; + } + else + { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(nCenter->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbBiQuadQuadrangles++; + +// if (!registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; } - return face; } //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34) { @@ -2787,7 +3888,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n31, @@ -2818,7 +3919,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34, int ID) @@ -2829,33 +3930,56 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, // creation quadratic faces - not implemented return 0; } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + + nodeIds.push_back(n31->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n14->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n24->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadTetras++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; } //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45) @@ -2870,7 +3994,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n12,int n23,int n34,int n41, @@ -2901,12 +4025,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, + const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, const SMDS_MeshNode * n45, @@ -2919,36 +4043,61 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, // creation quadratic faces - not implemented return 0; } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23, - n34,n41,n15,n25,n35,n45); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n15->getVtkId()); + nodeIds.push_back(n45->getVtkId()); + nodeIds.push_back(n35->getVtkId()); + nodeIds.push_back(n25->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadPyramids++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; } //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36) @@ -2963,7 +4112,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, @@ -2998,14 +4147,14 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36, @@ -3018,40 +4167,69 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, // creation quadratic faces - not implemented return 0; } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31, - n45,n56,n64,n14,n25,n36); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n31->getVtkId()); + + nodeIds.push_back(n45->getVtkId()); + nodeIds.push_back(n56->getVtkId()); + nodeIds.push_back(n64->getVtkId()); + + nodeIds.push_back(n14->getVtkId()); + nodeIds.push_back(n25->getVtkId()); + nodeIds.push_back(n36->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadPrisms++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; - } - return volume; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; } //======================================================================= //function : AddVolume -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, @@ -3067,7 +4245,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolumeWithID -//purpose : +//purpose : //======================================================================= SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, @@ -3107,18 +4285,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n3, const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, @@ -3132,15 +4310,391 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return 0; // creation quadratic faces - not implemented } - SMDS_QuadraticVolumeOfNodes * volume = - new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, - n56,n67,n78,n85,n15,n26,n37,n48); - myVolumes.Add(volume); + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n85->getVtkId()); + nodeIds.push_back(n78->getVtkId()); + nodeIds.push_back(n67->getVtkId()); + nodeIds.push_back(n56->getVtkId()); + + nodeIds.push_back(n15->getVtkId()); + nodeIds.push_back(n48->getVtkId()); + nodeIds.push_back(n37->getVtkId()); + nodeIds.push_back(n26->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; myInfo.myNbQuadHexas++; - if (!registerElement(ID, volume)) { - RemoveElement(volume, false); - volume = NULL; +// if (!registerElement(ID, volvtk)) { +// RemoveElement(volvtk, false); +// volvtk = NULL; +// } + return volvtk; +} + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, + n56, n67, n78, n85, n15, n26, n37, n48, + n1234, n1256, n2367, n3478, n1458, n5678, nCenter, + ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter, int ID) +{ + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 20 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter, + int ID) +{ + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 || + !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 || + !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter ) + return 0; + if(hasConstructionFaces()) { + return 0; + // creation quadratic faces - not implemented } - return volume; + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n85->getVtkId()); + nodeIds.push_back(n78->getVtkId()); + nodeIds.push_back(n67->getVtkId()); + nodeIds.push_back(n56->getVtkId()); + + nodeIds.push_back(n15->getVtkId()); + nodeIds.push_back(n48->getVtkId()); + nodeIds.push_back(n37->getVtkId()); + nodeIds.push_back(n26->getVtkId()); + + nodeIds.push_back(n1256->getVtkId()); + nodeIds.push_back(n3478->getVtkId()); + nodeIds.push_back(n1458->getVtkId()); + nodeIds.push_back(n2367->getVtkId()); + nodeIds.push_back(n1234->getVtkId()); + nodeIds.push_back(n5678->getVtkId()); + nodeIds.push_back(nCenter->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbTriQuadHexas++; + + return volvtk; +} + + +void SMDS_Mesh::updateNodeMinMax() +{ + myNodeMin = 0; + if (myNodes.size() == 0) + { + myNodeMax=0; + return; + } + while (!myNodes[myNodeMin] && (myNodeMin=0)) + myNodeMin--; +} + +void SMDS_Mesh::incrementNodesCapacity(int nbNodes) +{ +// int val = myCellIdSmdsToVtk.size(); +// MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes); +// myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1 + int val = myNodes.size(); + MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes); + myNodes.resize(val +nbNodes, 0); +} + +void SMDS_Mesh::incrementCellsCapacity(int nbCells) +{ + int val = myCellIdVtkToSmds.size(); + MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells); + myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1 + val = myCells.size(); + MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells); + myNodes.resize(val +nbCells, 0); +} + +void SMDS_Mesh::adjustStructure() +{ + myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()); +} + +void SMDS_Mesh::dumpGrid(string ficdump) +{ + MESSAGE("SMDS_Mesh::dumpGrid " << ficdump); +// vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); +// aWriter->SetFileName(ficdump.c_str()); +// aWriter->SetInput(myGrid); +// if(myGrid->GetNumberOfCells()) +// { +// aWriter->Write(); +// } +// aWriter->Delete(); + ficdump = ficdump + "_connectivity"; + ofstream ficcon(ficdump.c_str(), ios::out); + int nbPoints = myGrid->GetNumberOfPoints(); + ficcon << "-------------------------------- points " << nbPoints << endl; + for (int i=0; iGetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl; + } + int nbCells = myGrid->GetNumberOfCells(); + ficcon << "-------------------------------- cells " << nbCells << endl; + for (int i=0; iGetCell(i)); +// MESSAGE(" " << myGrid->GetCell(i)->GetCellType()); + ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -"; + int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints(); + vtkIdList *listid = myGrid->GetCell(i)->GetPointIds(); + for (int j=0; jGetId(j); + } + ficcon << endl; + } + ficcon << "-------------------------------- connectivity " << nbPoints << endl; + vtkCellLinks *links = myGrid->GetCellLinks(); + for (int i=0; iGetNcells(i); + vtkIdType *cells = links->GetCells(i); + ficcon << i << " - " << ncells << " -"; + for (int j=0; j= 0 && vtkid < myCellIdVtkToSmds.size()) + return myCellIdVtkToSmds[vtkid]; + throw SALOME_Exception(LOCALIZED ("vtk id out of bounds")); +} + +void SMDS_Mesh::updateBoundingBox() +{ + xmin = 0; xmax = 0; + ymin = 0; ymax = 0; + zmin = 0; zmax = 0; + vtkPoints *points = myGrid->GetPoints(); + int myNodesSize = this->myNodes.size(); + for (int i = 0; i < myNodesSize; i++) + { + if (SMDS_MeshNode *n = myNodes[i]) + { + double coords[3]; + points->GetPoint(n->myVtkID, coords); + if (coords[0] < xmin) xmin = coords[0]; + else if (coords[0] > xmax) xmax = coords[0]; + if (coords[1] < ymin) ymin = coords[1]; + else if (coords[1] > ymax) ymax = coords[1]; + if (coords[2] < zmin) zmin = coords[2]; + else if (coords[2] > zmax) zmax = coords[2]; + } + } +} + +double SMDS_Mesh::getMaxDim() +{ + double dmax = 1.e-3; + if ((xmax - xmin) > dmax) dmax = xmax -xmin; + if ((ymax - ymin) > dmax) dmax = ymax -ymin; + if ((zmax - zmin) > dmax) dmax = zmax -zmin; + MESSAGE("getMaxDim " << dmax); + return dmax; +} + +//! modification that needs compact structure and redraw +void SMDS_Mesh::Modified() +{ + if (this->myModified) + { + this->myModifTime++; + MESSAGE("modified"); + myModified = false; + } +} + +//! get last modification timeStamp +unsigned long SMDS_Mesh::GetMTime() const +{ + return this->myModifTime; +} + +bool SMDS_Mesh::isCompacted() +{ + if (this->myModifTime > this->myCompactTime) + { + MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime); + this->myCompactTime = this->myModifTime; + return false; + } + return true; } diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index a0def42ba..7e0361286 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_Mesh.hxx // Module : SMESH @@ -29,73 +30,113 @@ #include "SMESH_SMDS.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_MeshCell.hxx" +#include "SMDS_Mesh0DElement.hxx" #include "SMDS_MeshEdge.hxx" #include "SMDS_MeshFace.hxx" #include "SMDS_MeshVolume.hxx" +#include "SMDS_MeshNodeIDFactory.hxx" #include "SMDS_MeshElementIDFactory.hxx" #include "SMDS_MeshInfo.hxx" #include "SMDS_ElemIterator.hxx" -#include +#include "SMDS_VolumeOfNodes.hxx" +#include "SMDS_VtkEdge.hxx" +#include "SMDS_VtkFace.hxx" +#include "SMDS_VtkVolume.hxx" +#include "ObjectPool.hxx" +#include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_BallElement.hxx" #include #include #include +#include +#include +#include + +#include "Utils_SALOME_Exception.hxx" -class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject{ +#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified")); + +class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject +{ public: - + friend class SMDS_MeshIDFactory; + friend class SMDS_MeshNodeIDFactory; + friend class SMDS_MeshElementIDFactory; + friend class SMDS_MeshVolumeVtkNodes; + friend class SMDS_MeshNode; + SMDS_Mesh(); - SMDS_NodeIteratorPtr nodesIterator() const; - SMDS_EdgeIteratorPtr edgesIterator() const; - SMDS_FaceIteratorPtr facesIterator() const; - SMDS_VolumeIteratorPtr volumesIterator() const; - SMDS_ElemIteratorPtr elementsIterator() const; - + //! to retreive this SMDS_Mesh instance from its elements (index stored in SMDS_Elements) + static std::vector _meshList; + + //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid + inline SMDS_UnstructuredGrid* getGrid() {return myGrid; } + inline int getMeshId() {return myMeshId; } + + virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; + virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const; + virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const; + virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; + virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const; + virtual SMDS_ElemIteratorPtr elementEntityIterator(SMDSAbs_EntityType type) const; + SMDSAbs_ElementType GetElementType( const int id, const bool iselem ) const; SMDS_Mesh *AddSubMesh(); - + virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID); - virtual SMDS_MeshNode* AddNode(double x, double y, double z); - + virtual SMDS_MeshNode* AddNode (double x, double y, double z); + + virtual SMDS_Mesh0DElement* Add0DElementWithID(int n, int ID); + virtual SMDS_Mesh0DElement* Add0DElementWithID(const SMDS_MeshNode * n, int ID); + virtual SMDS_Mesh0DElement* Add0DElement (const SMDS_MeshNode * n); + + virtual SMDS_BallElement* AddBallWithID(int n, double diameter, int ID); + virtual SMDS_BallElement* AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID); + virtual SMDS_BallElement* AddBall (const SMDS_MeshNode * n, double diameter); + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID); virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - int ID); + const SMDS_MeshNode * n2, + int ID); virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2); - + const SMDS_MeshNode * n2); + // 2d order edge with 3 nodes: n12 - node between n1 and n2 virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID); virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n12, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID); virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n12); virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3); + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1, const SMDS_MeshEdge * e2, const SMDS_MeshEdge * e3, int ID); @@ -116,100 +157,122 @@ public: virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n12,int n23,int n31, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31); + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); // 2d order quadrangle virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n34,int n41, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41); + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41); + + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int nCenter, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter); virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5); + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6); + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1, const SMDS_MeshFace * f2, @@ -244,29 +307,59 @@ public: const SMDS_MeshFace * f5, const SMDS_MeshFace * f6); + // hexagonal prism + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, + int n7, int n8, int n9, int n10, int n11, int n12, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12); + // 2d order tetrahedron of 10 nodes virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n31, int n14,int n24,int n34, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, - const SMDS_MeshNode * n24, - const SMDS_MeshNode * n34, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, + const SMDS_MeshNode * n14, const SMDS_MeshNode * n24, const SMDS_MeshNode * n34); @@ -276,28 +369,28 @@ public: int n15,int n25,int n35,int n45, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, - const SMDS_MeshNode * n25, - const SMDS_MeshNode * n35, - const SMDS_MeshNode * n45, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n15, const SMDS_MeshNode * n25, const SMDS_MeshNode * n35, @@ -311,33 +404,33 @@ public: int n14,int n25,int n36, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - const SMDS_MeshNode * n45, - const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, - const SMDS_MeshNode * n14, - const SMDS_MeshNode * n25, - const SMDS_MeshNode * n36, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, + const SMDS_MeshNode * n31, const SMDS_MeshNode * n45, const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, + const SMDS_MeshNode * n64, const SMDS_MeshNode * n14, const SMDS_MeshNode * n25, const SMDS_MeshNode * n36); @@ -350,68 +443,143 @@ public: int n15,int n26,int n37,int n48, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - const SMDS_MeshNode * n56, - const SMDS_MeshNode * n67, - const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, - const SMDS_MeshNode * n15, - const SMDS_MeshNode * n26, - const SMDS_MeshNode * n37, - const SMDS_MeshNode * n48, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, + const SMDS_MeshNode * n41, const SMDS_MeshNode * n56, const SMDS_MeshNode * n67, const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, + const SMDS_MeshNode * n85, const SMDS_MeshNode * n15, const SMDS_MeshNode * n26, const SMDS_MeshNode * n37, const SMDS_MeshNode * n48); - virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, - const int ID); + // 2d oreder Hexahedrons with 27 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter); + + virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector & nodes_ids, + const int ID); - virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes, - const int ID); + virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector & nodes, + const int ID); - virtual SMDS_MeshFace* AddPolygonalFace (std::vector nodes); + virtual SMDS_MeshFace* AddPolygonalFace (const std::vector & nodes); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (std::vector nodes_ids, - std::vector quantities, - const int ID); + (const std::vector & nodes_ids, + const std::vector & quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (std::vector nodes, - std::vector quantities, - const int ID); + (const std::vector & nodes, + const std::vector & quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolume - (std::vector nodes, - std::vector quantities); + (const std::vector & nodes, + const std::vector & quantities); + + virtual SMDS_MeshVolume* AddVolumeFromVtkIds(const std::vector& vtkNodeIds); + + virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector& vtkNodeIds, + const int ID); + + virtual SMDS_MeshFace* AddFaceFromVtkIds(const std::vector& vtkNodeIds); + + virtual SMDS_MeshFace* AddFaceFromVtkIdsWithID(const std::vector& vtkNodeIds, + const int ID); virtual void RemoveElement(const SMDS_MeshElement * elem, std::list& removedElems, @@ -419,6 +587,7 @@ public: const bool removenodes = false); virtual void RemoveElement(const SMDS_MeshElement * elem, bool removenodes = false); virtual void RemoveNode(const SMDS_MeshNode * node); + virtual void Remove0DElement(const SMDS_Mesh0DElement * elem0d); virtual void RemoveEdge(const SMDS_MeshEdge * edge); virtual void RemoveFace(const SMDS_MeshFace * face); virtual void RemoveVolume(const SMDS_MeshVolume * volume); @@ -430,7 +599,7 @@ public: virtual void RemoveFreeElement(const SMDS_MeshElement * elem); virtual void Clear(); - + virtual bool RemoveFromParent(); virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh); @@ -443,8 +612,12 @@ public: virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); // Renumber all nodes or elements. + virtual void compactMesh(); const SMDS_MeshNode *FindNode(int idnode) const; + const SMDS_MeshNode *FindNodeVtk(int idnode) const; + const SMDS_Mesh0DElement* Find0DElement(int idnode) const; + const SMDS_BallElement* FindBall(int idnode) const; const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const; const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const; const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const; @@ -454,6 +627,8 @@ public: const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4, int idnode5, int idnode6, int idnode7, int idnode8) const; const SMDS_MeshElement *FindElement(int IDelem) const; + static const SMDS_Mesh0DElement* Find0DElement(const SMDS_MeshNode * n); + static const SMDS_BallElement* FindBall(const SMDS_MeshNode * n); static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2); static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1, @@ -481,8 +656,11 @@ public: const SMDS_MeshNode *n7, const SMDS_MeshNode *n8); - const SMDS_MeshFace *FindFace(std::vector nodes_ids) const; - static const SMDS_MeshFace* FindFace(std::vector nodes); + const SMDS_MeshFace *FindFace(const std::vector& nodes_ids) const; + static const SMDS_MeshFace* FindFace(const std::vector& nodes); + static const SMDS_MeshElement* FindElement(const std::vector& nodes, + const SMDSAbs_ElementType type=SMDSAbs_All, + const bool noMedium=true); /*! * \brief Raise an exception if free memory (ram+swap) too low @@ -498,19 +676,23 @@ public: const SMDS_MeshInfo& GetMeshInfo() const { return myInfo; } - int NbNodes() const; - int NbEdges() const; - int NbFaces() const; - int NbVolumes() const; - int NbSubMesh() const; + virtual int NbNodes() const; + virtual int Nb0DElements() const; + virtual int NbBalls() const; + virtual int NbEdges() const; + virtual int NbFaces() const; + virtual int NbVolumes() const; + virtual int NbSubMesh() const; + void DumpNodes() const; + void Dump0DElements() const; void DumpEdges() const; void DumpFaces() const; void DumpVolumes() const; void DebugStats() const; - SMDS_Mesh *boundaryFaces(); - SMDS_Mesh *boundaryEdges(); + virtual ~SMDS_Mesh(); + bool hasConstructionEdges(); bool hasConstructionFaces(); bool hasInverseElements(); @@ -526,52 +708,127 @@ public: */ bool Contains (const SMDS_MeshElement* elem) const; - typedef NCollection_Map SetOfNodes; - typedef NCollection_Map SetOfEdges; - typedef NCollection_Map SetOfFaces; - typedef NCollection_Map SetOfVolumes; + typedef std::vector SetOfNodes; + typedef std::vector SetOfCells; + + void updateNodeMinMax(); + void updateBoundingBox(); + double getMaxDim(); + int fromVtkToSmds(int vtkid); + + void incrementNodesCapacity(int nbNodes); + void incrementCellsCapacity(int nbCells); + void adjustStructure(); + void dumpGrid(string ficdump="dumpGrid"); + static int chunkSize; -private: + //! low level modification: add, change or remove node or element + inline void setMyModified() { this->myModified = true; } + + void Modified(); + unsigned long GetMTime() const; + bool isCompacted(); + +protected: SMDS_Mesh(SMDS_Mesh * parent); - SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3); + SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + int ID); SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4); + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + int ID); SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2); + const SMDS_MeshNode * n2); SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, - const SMDS_MeshNode *n2, - const SMDS_MeshNode *n3); + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3); SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1, - const SMDS_MeshNode *n2, - const SMDS_MeshNode *n3, - const SMDS_MeshNode *n4); + const SMDS_MeshNode *n2, + const SMDS_MeshNode *n3, + const SMDS_MeshNode *n4); bool registerElement(int ID, SMDS_MeshElement * element); - void addChildrenWithNodes(std::set& setOfChildren, - const SMDS_MeshElement * element, - std::set& nodes); + void addChildrenWithNodes(std::set& setOfChildren, + const SMDS_MeshElement * element, + std::set& nodes); + + inline void adjustmyCellsCapacity(int ID) + { + assert(ID >= 0); + myElementIDFactory->adjustMaxId(ID); + if (ID >= myCells.size()) + myCells.resize(ID+SMDS_Mesh::chunkSize,0); + } + + inline void adjustBoundingBox(double x, double y, double z) + { + if (x > xmax) xmax = x; + else if (x < xmin) xmin = x; + if (y > ymax) ymax = y; + else if (y < ymin) ymin = y; + if (z > zmax) zmax = z; + else if (z < zmin) zmin = z; + } // Fields PRIVATE - + + //! index of this SMDS_mesh in the static vector _meshList + int myMeshId; + + //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid + SMDS_UnstructuredGrid* myGrid; + + //! Small objects like SMDS_MeshNode are allocated by chunks to limit memory costs of new + ObjectPool* myNodePool; + + //! Small objects like SMDS_VtkVolume are allocated by chunks to limit memory costs of new + ObjectPool* myVolumePool; + ObjectPool* myFacePool; + ObjectPool* myEdgePool; + ObjectPool* myBallPool; + + //! SMDS_MeshNodes refer to vtk nodes (vtk id = index in myNodes),store reference to this mesh, and sub-shape SetOfNodes myNodes; - SetOfEdges myEdges; - SetOfFaces myFaces; - SetOfVolumes myVolumes; + + //! SMDS_MeshCells refer to vtk cells (vtk id != index in myCells),store reference to this mesh, and sub-shape + SetOfCells myCells; + + //! for cells only: index = ID for SMDS users, value = ID in vtkUnstructuredGrid + //std::vector myCellIdSmdsToVtk; + + //! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users + std::vector myCellIdVtkToSmds; + SMDS_Mesh * myParent; std::list myChildren; - SMDS_MeshElementIDFactory *myNodeIDFactory; + SMDS_MeshNodeIDFactory *myNodeIDFactory; SMDS_MeshElementIDFactory *myElementIDFactory; SMDS_MeshInfo myInfo; + //! use a counter to keep track of modifications + unsigned long myModifTime, myCompactTime; + + int myNodeMin; + int myNodeMax; + bool myHasConstructionEdges; bool myHasConstructionFaces; bool myHasInverseElements; + + //! any add, remove or change of node or cell + bool myModified; + + double xmin; + double xmax; + double ymin; + double ymax; + double zmin; + double zmax; }; diff --git a/src/SMDS/SMDS_Mesh0DElement.cxx b/src/SMDS/SMDS_Mesh0DElement.cxx new file mode 100644 index 000000000..a1a244c6d --- /dev/null +++ b/src/SMDS/SMDS_Mesh0DElement.cxx @@ -0,0 +1,147 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_Mesh0DElement.cxx +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_Mesh0DElement.hxx" +#include "SMDS_IteratorOfElements.hxx" +#include "SMDS_MeshNode.hxx" +#include "utilities.h" + +using namespace std; + +//======================================================================= +//function : SMDS_Mesh0DElement +//purpose : +//======================================================================= +SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node) +{ + MESSAGE("SMDS_Mesh0DElement " << GetID()); + myNode = node; +} + +//======================================================================= +//function : Print +//purpose : +//======================================================================= +void SMDS_Mesh0DElement::Print (ostream & OS) const +{ + OS << "0D Element <" << GetID() << "> : (" << myNode << ") " << endl; +} + +//======================================================================= +//function : NbNodes +//purpose : +//======================================================================= +int SMDS_Mesh0DElement::NbNodes() const +{ + return 1; +} + +//======================================================================= +//function : NbEdges +//purpose : +//======================================================================= +int SMDS_Mesh0DElement::NbEdges() const +{ + return 0; +} + +//======================================================================= +//function : GetType +//purpose : +//======================================================================= +SMDSAbs_ElementType SMDS_Mesh0DElement::GetType() const +{ + return SMDSAbs_0DElement; +} + +vtkIdType SMDS_Mesh0DElement::GetVtkType() const +{ + return VTK_VERTEX; +} + +//======================================================================= +//function : elementsIterator +//purpose : +//======================================================================= +class SMDS_Mesh0DElement_MyNodeIterator: public SMDS_ElemIterator +{ + const SMDS_MeshNode * myNode; + int myIndex; + public: + SMDS_Mesh0DElement_MyNodeIterator(const SMDS_MeshNode * node): + myNode(node),myIndex(0) {} + + bool more() + { + return myIndex < 1; + } + + const SMDS_MeshElement* next() + { + myIndex++; + if (myIndex == 1) + return myNode; + return NULL; + } +}; + +SMDS_ElemIteratorPtr SMDS_Mesh0DElement::elementsIterator (SMDSAbs_ElementType type) const +{ + switch(type) + { + case SMDSAbs_0DElement: + return SMDS_MeshElement::elementsIterator(SMDSAbs_0DElement); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_Mesh0DElement_MyNodeIterator(myNode)); + default: + return SMDS_ElemIteratorPtr + (new SMDS_IteratorOfElements + (this,type, SMDS_ElemIteratorPtr(new SMDS_Mesh0DElement_MyNodeIterator(myNode)))); + } +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_Mesh0DElement::GetNode(const int ind) const +{ + if (ind == 0) + return myNode; + return NULL; +} + +//======================================================================= +//function : ChangeNode +//purpose : +//======================================================================= +bool SMDS_Mesh0DElement::ChangeNode (const SMDS_MeshNode * node) +{ + myNode = node; + return true; +} diff --git a/src/SMDS/SMDS_Mesh0DElement.hxx b/src/SMDS/SMDS_Mesh0DElement.hxx new file mode 100644 index 000000000..81578a816 --- /dev/null +++ b/src/SMDS/SMDS_Mesh0DElement.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_Mesh0DElement.hxx +// Module : SMESH +// +#ifndef _SMDS_Mesh0DElement_HeaderFile +#define _SMDS_Mesh0DElement_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshCell.hxx" + +#include + +class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshCell +{ + public: + SMDS_Mesh0DElement (const SMDS_MeshNode * node); + bool ChangeNode (const SMDS_MeshNode * node); + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;}; + virtual void Print (std::ostream & OS) const; + + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const {return SMDSEntity_0D;} + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_POINT; } + virtual const SMDS_MeshNode* GetNode (const int ind) const; + virtual int NbNodes() const; + virtual int NbEdges() const; + + protected: + virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const; + + protected: + const SMDS_MeshNode* myNode; +}; + +#endif diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx new file mode 100644 index 000000000..521c976ff --- /dev/null +++ b/src/SMDS/SMDS_MeshCell.cxx @@ -0,0 +1,428 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMDS_MeshCell.hxx" +#include "utilities.h" + +int SMDS_MeshCell::nbCells = 0; + +SMDS_MeshCell::SMDS_MeshCell() : + SMDS_MeshElement(-1) +{ + nbCells++; + myVtkID = -1; +} + +SMDS_MeshCell::~SMDS_MeshCell() +{ + nbCells--; +} +//================================================================================ +/*! + * \brief Return VTKCellType corresponding to SMDSAbs_EntityType + */ +//================================================================================ + +VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType) +{ + static std::vector< VTKCellType > vtkTypes; + if ( vtkTypes.empty() ) + { + vtkTypes.resize( SMDSEntity_Last+1, VTK_EMPTY_CELL ); + vtkTypes[ SMDSEntity_Node ] = VTK_VERTEX; + vtkTypes[ SMDSEntity_0D ] = VTK_VERTEX; + vtkTypes[ SMDSEntity_Edge ] = VTK_LINE; + vtkTypes[ SMDSEntity_Quad_Edge ] = VTK_QUADRATIC_EDGE; + vtkTypes[ SMDSEntity_Triangle ] = VTK_TRIANGLE; + vtkTypes[ SMDSEntity_Quad_Triangle ] = VTK_QUADRATIC_TRIANGLE; + vtkTypes[ SMDSEntity_Quadrangle ] = VTK_QUAD; + vtkTypes[ SMDSEntity_Quad_Quadrangle ] = VTK_QUADRATIC_QUAD; + vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD; + vtkTypes[ SMDSEntity_Polygon ] = VTK_POLYGON; + //vtkTypes[ SMDSEntity_Quad_Polygon ] = ; + vtkTypes[ SMDSEntity_Tetra ] = VTK_TETRA; + vtkTypes[ SMDSEntity_Quad_Tetra ] = VTK_QUADRATIC_TETRA; + vtkTypes[ SMDSEntity_Pyramid ] = VTK_PYRAMID; + vtkTypes[ SMDSEntity_Quad_Pyramid ] = VTK_QUADRATIC_PYRAMID; + vtkTypes[ SMDSEntity_Hexa ] = VTK_HEXAHEDRON; + vtkTypes[ SMDSEntity_Quad_Hexa ] = VTK_QUADRATIC_HEXAHEDRON; + vtkTypes[ SMDSEntity_TriQuad_Hexa ] = VTK_TRIQUADRATIC_HEXAHEDRON; + vtkTypes[ SMDSEntity_Penta ] = VTK_WEDGE; + vtkTypes[ SMDSEntity_Quad_Penta ] = VTK_QUADRATIC_WEDGE; + vtkTypes[ SMDSEntity_Hexagonal_Prism ] = VTK_HEXAGONAL_PRISM; + vtkTypes[ SMDSEntity_Polyhedra ] = VTK_POLYHEDRON; + //vtkTypes[ SMDSEntity_Quad_Polyhedra ] = ; + vtkTypes[ SMDSEntity_Ball ] = VTK_POLY_VERTEX; + } + return vtkTypes[ smdsType ]; +} + +//================================================================================ +/*! + * \brief Return indices to transform cell connectivity from SMDS to VTK + * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]] + */ +//================================================================================ + +const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType) +{ + static std::vector< std::vector< int > > toVtkInterlaces; + if ( toVtkInterlaces.empty() ) + { + toVtkInterlaces.resize( SMDSEntity_Last+1 ); + // { + // const int ids[] = {0}; + // toVtkInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 ); + // toVtkInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 ); + // } + // { + // const int ids[] = {0,1}; + // toVtkInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 ); + // } + // { + // const int ids[] = {0,1,2}; + // toVtkInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 ); + // } + // { + // const int ids[] = {0,1,2}; + // toVtkInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 ); + // } + // { + // const int ids[] = {0,1,2,3,4,5}; + // toVtkInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 ); + // } + // { + // const int ids[] = {0,1,2,3}; + // toVtkInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 ); + // } + // { + // const int ids[] = {0,1,2,3,4,5,6,7}; + // toVtkInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 ); + // } + // { + // const int ids[] = {0,1,2,3,4,5,6,7,8}; + // toVtkInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 ); + // } + { + const int ids[] = {0,2,1,3}; + toVtkInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 ); + } + { + const int ids[] = {0,2,1,3,6,5,4,7,9,8}; + toVtkInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 ); + } + { + const int ids[] = {0,3,2,1,4}; + toVtkInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 ); + } + { + const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + toVtkInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 ); + } + { + const int ids[] = {0,3,2,1,4,7,6,5}; + toVtkInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 ); + } + { + const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; + toVtkInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 ); + } + { + const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17, 21,23,24,22,20,25,26}; + toVtkInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 ); + } + { + const int ids[] = {0,1,2,3,4,5}; + toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 ); + } + { + const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; + toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 ); + } + { + const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7}; + toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 ); + } + } + return toVtkInterlaces[smdsType]; +} + +//================================================================================ +/*! + * \brief Return indices to reverse an SMDS cell of given type + * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]] + */ +//================================================================================ + +const std::vector& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType) +{ + static std::vector< std::vector< int > > reverseInterlaces; + if ( reverseInterlaces.empty() ) + { + reverseInterlaces.resize( SMDSEntity_Last+1 ); + { + const int ids[] = {0}; + reverseInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 ); + reverseInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 ); + reverseInterlaces[SMDSEntity_Ball].assign( &ids[0], &ids[0]+1 ); + } + { + const int ids[] = {1,0}; + reverseInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 ); + } + { + const int ids[] = {1,0,2}; + reverseInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 ); + } + { + const int ids[] = {0,2,1}; + reverseInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 ); + } + { + const int ids[] = {0,2,1,5,4,3}; + reverseInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 ); + } + { + const int ids[] = {0,3,2,1}; + reverseInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 ); + } + { + const int ids[] = {0,3,2,1,7,6,5,4}; + reverseInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 ); + } + { + const int ids[] = {0,3,2,1,7,6,5,4,8}; + reverseInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 ); + } + { + const int ids[] = {0,2,1,3}; + reverseInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 ); + } + { + const int ids[] = {0,2,1,3,6,5,4,7,9,8}; + reverseInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 ); + } + { + const int ids[] = {0,3,2,1,4}; + reverseInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 ); + } + { + const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + reverseInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 ); + } + { + const int ids[] = {0,3,2,1,4,7,6,5}; + reverseInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 ); + } + { + const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; + reverseInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 ); + } + { + const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17, 20,24,23,22,21,25,26}; + reverseInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 ); + } + { + const int ids[] = {0,2,1,3,5,4}; + reverseInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 ); + } + { + const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13}; + reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 ); + } + { + const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7}; + reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 ); + } + } + return reverseInterlaces[smdsType]; +} + +//================================================================================ +/*! + * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order + * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]] + */ +//================================================================================ + +const std::vector& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType) +{ + static std::vector< std::vector< int > > interlace; + if ( interlace.empty() ) + { + interlace.resize( SMDSEntity_Last+1 ); + { + const int ids[] = {0,2,1}; + interlace[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 ); + } + { + const int ids[] = {0,3,1,4,2,5}; + interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 ); + } + { + const int ids[] = {0,4,1,5,2,6,3,7,8}; + interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 ); + interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 ); + } + } + return interlace[smdsType]; +} + +//================================================================================ +/*! + * \brief Return SMDSAbs_EntityType corresponding to VTKCellType + */ +//================================================================================ + +SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType) +{ + static std::vector< SMDSAbs_EntityType > smdsTypes; + if ( smdsTypes.empty() ) + { + smdsTypes.resize( VTK_NUMBER_OF_CELL_TYPES, SMDSEntity_Last ); + for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS ) + smdsTypes[ toVtkType( SMDSAbs_EntityType( iSMDS ))] = SMDSAbs_EntityType( iSMDS ); + } + return smdsTypes[ vtkType ]; +} + +//================================================================================ +/*! + * \brief Return SMDSAbs_ElementType by SMDSAbs_GeometryType + */ +//================================================================================ + +SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_GeometryType geomType) +{ + switch ( geomType ) { + case SMDSGeom_POINT: return SMDSAbs_0DElement; + + case SMDSGeom_EDGE: return SMDSAbs_Edge; + + case SMDSGeom_TRIANGLE: + case SMDSGeom_QUADRANGLE: + case SMDSGeom_POLYGON: return SMDSAbs_Face; + + case SMDSGeom_TETRA: + case SMDSGeom_PYRAMID: + case SMDSGeom_HEXA: + case SMDSGeom_PENTA: + case SMDSGeom_HEXAGONAL_PRISM: + case SMDSGeom_POLYHEDRA: return SMDSAbs_Volume; + + case SMDSGeom_BALL: return SMDSAbs_Ball; + + case SMDSGeom_NONE: ; + } + return SMDSAbs_All; +} + +//================================================================================ +/*! + * \brief Return SMDSAbs_ElementType by SMDSAbs_EntityType + */ +//================================================================================ + +SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType) +{ + switch ( entityType ) { + case SMDSEntity_Node: return SMDSAbs_Node; + + case SMDSEntity_0D: return SMDSAbs_0DElement; + + case SMDSEntity_Edge: + case SMDSEntity_Quad_Edge: return SMDSAbs_Edge; + + case SMDSEntity_Triangle: + case SMDSEntity_Quad_Triangle: + case SMDSEntity_Quadrangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: return SMDSAbs_Face; + + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + case SMDSEntity_Hexagonal_Prism: + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume; + + case SMDSEntity_Ball: return SMDSAbs_Ball; + + case SMDSEntity_Last:; + } + return SMDSAbs_All; +} + + +//================================================================================ +/*! + * \brief Return indices to transform cell connectivity from VTK to SMDS + * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]] + */ +//================================================================================ + +const std::vector& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType) +{ + static std::vector< std::vector > fromVtkInterlaces; + if ( fromVtkInterlaces.empty() ) + { + fromVtkInterlaces.resize( SMDSEntity_Last+1 ); + for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS ) + { + const std::vector & toVtk = toVtkOrder( SMDSAbs_EntityType( iSMDS )); + std::vector & toSmds = fromVtkInterlaces[ iSMDS ]; + toSmds.resize( toVtk.size() ); + for ( size_t i = 0; i < toVtk.size(); ++i ) + toSmds[ toVtk[i] ] = i; + } + } + return fromVtkInterlaces[ smdsType ]; +} + +//================================================================================ +/*! + * \brief Return indices to transform cell connectivity from SMDS to VTK + * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]] + */ +//================================================================================ + +const std::vector& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType) +{ + return toVtkOrder( toSmdsType( vtkType )); +} + +//================================================================================ +/*! + * \brief Return indices to transform cell connectivity from VTK to SMDS + * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]] + */ +//================================================================================ + +const std::vector& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType) +{ + return fromVtkOrder( toSmdsType( vtkType )); +} diff --git a/src/SMDS/SMDS_MeshCell.hxx b/src/SMDS/SMDS_MeshCell.hxx new file mode 100644 index 000000000..ca006b5ff --- /dev/null +++ b/src/SMDS/SMDS_MeshCell.hxx @@ -0,0 +1,72 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _SMDS_MESHCELL_HXX_ +#define _SMDS_MESHCELL_HXX_ + +#include "SMDS_MeshElement.hxx" + +/*! + * \brief Base class for all cells + */ + +class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement +{ +public: + SMDS_MeshCell(); + virtual ~SMDS_MeshCell(); + + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)= 0; + virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) {return true; } + + static VTKCellType toVtkType (SMDSAbs_EntityType vtkType); + static SMDSAbs_EntityType toSmdsType(VTKCellType vtkType); + static SMDSAbs_ElementType toSmdsType(SMDSAbs_GeometryType geomType); + static SMDSAbs_ElementType toSmdsType(SMDSAbs_EntityType entityType); + + static const std::vector& toVtkOrder(VTKCellType vtkType); + static const std::vector& toVtkOrder(SMDSAbs_EntityType smdsType); + static const std::vector& fromVtkOrder(VTKCellType vtkType); + static const std::vector& fromVtkOrder(SMDSAbs_EntityType smdsType); + + static const std::vector& reverseSmdsOrder(SMDSAbs_EntityType smdsType); + static const std::vector& interlacedSmdsOrder(SMDSAbs_EntityType smdsType); + + template< class VECT > + static void applyInterlace( const std::vector& interlace, VECT & data) + { + if ( interlace.empty() ) return; + VECT tmpData( data.size() ); + for ( size_t i = 0; i < data.size(); ++i ) + tmpData[i] = data[ interlace[i] ]; + data.swap( tmpData ); + } + + static int nbCells; + +protected: + inline void exchange(const SMDS_MeshNode* nodes[],int a, int b) + { + const SMDS_MeshNode* noda = nodes[a]; + nodes[a] = nodes[b]; + nodes[b] = noda; + } +}; + +#endif diff --git a/src/SMDS/SMDS_MeshEdge.cxx b/src/SMDS/SMDS_MeshEdge.cxx index 9d17cd439..859061842 100644 --- a/src/SMDS/SMDS_MeshEdge.cxx +++ b/src/SMDS/SMDS_MeshEdge.cxx @@ -1,161 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMDS : implementaion of Salome mesh data structure -// File : SMDS_MeshEdge.cxx -// Author : Jean-Michel BOULCOURT -// Module : SMESH -// -#ifdef _MSC_VER -#pragma warning(disable:4786) -#endif #include "SMDS_MeshEdge.hxx" -#include "SMDS_IteratorOfElements.hxx" -#include "SMDS_MeshNode.hxx" - -using namespace std; - -//======================================================================= -//function : SMDS_MeshEdge -//purpose : -//======================================================================= - -SMDS_MeshEdge::SMDS_MeshEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) -{ - myNodes[0]=node1; - myNodes[1]=node2; -} - -//======================================================================= -//function : Print -//purpose : -//======================================================================= - -void SMDS_MeshEdge::Print(ostream & OS) const -{ - OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] << - ") " << endl; -} - -int SMDS_MeshEdge::NbNodes() const -{ - return 2; -} - -int SMDS_MeshEdge::NbEdges() const -{ - return 1; -} SMDSAbs_ElementType SMDS_MeshEdge::GetType() const { - return SMDSAbs_Edge; + return SMDSAbs_Edge; } -class SMDS_MeshEdge_MyNodeIterator:public SMDS_ElemIterator +vtkIdType SMDS_MeshEdge::GetVtkType() const { - const SMDS_MeshNode *const* myNodes; - int myIndex; - public: - SMDS_MeshEdge_MyNodeIterator(const SMDS_MeshNode * const* nodes): - myNodes(nodes),myIndex(0) {} - - bool more() - { - return myIndex<2; - } - - const SMDS_MeshElement* next() - { - myIndex++; - return myNodes[myIndex-1]; - } -}; - -SMDS_ElemIteratorPtr SMDS_MeshEdge:: - elementsIterator(SMDSAbs_ElementType type) const -{ - switch(type) - { - case SMDSAbs_Edge: - return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); - case SMDSAbs_Node: - return SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes)); - default: - return SMDS_ElemIteratorPtr - (new SMDS_IteratorOfElements - (this,type, SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes)))); - } -} - -bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2) -{ - int id11=e1.myNodes[0]->GetID(); - int id21=e2.myNodes[0]->GetID(); - int id12=e1.myNodes[1]->GetID(); - int id22=e2.myNodes[1]->GetID(); - int tmp; - - if(id11>=id12) - { - tmp=id11; - id11=id12; - id12=tmp; - } - if(id21>=id22) - { - tmp=id21; - id21=id22; - id22=tmp; - } - - if(id11 +#include "SMDS_MeshCell.hxx" -class SMDS_EXPORT SMDS_MeshEdge:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshEdge: public SMDS_MeshCell { - - public: - SMDS_MeshEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2); - bool ChangeNodes(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2); - void Print(std::ostream & OS) const; - - SMDSAbs_ElementType GetType() const; - int NbNodes() const; - int NbEdges() const; - friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2); - - /*! - * \brief Return node by its index - * \param ind - node index - * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range - */ - virtual const SMDS_MeshNode* GetNode(const int ind) const; - - protected: - SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; - - protected: - const SMDS_MeshNode* myNodes[3]; - + + public: + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_EDGE; } }; #endif diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 646f92d10..1f422d382 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifdef _MSC_VER @@ -34,19 +35,33 @@ using namespace std; -SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID) +SMDS_MeshElement::SMDS_MeshElement(int ID) +{ + init(ID); +} + +SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, LongType shapeId) +{ + init(id, meshId, shapeId); +} + +void SMDS_MeshElement::init(int id, ShortType meshId, LongType shapeId ) { + myID = id; + myMeshId = meshId; + myShapeId = shapeId; + myIdInShape = -1; } void SMDS_MeshElement::Print(ostream & OS) const { - OS << "dump of mesh element" << endl; + OS << "dump of mesh element" << endl; } ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME) { - ME->Print(OS); - return OS; + ME->Print(OS); + return OS; } /////////////////////////////////////////////////////////////////////////////// @@ -55,7 +70,7 @@ ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME) /////////////////////////////////////////////////////////////////////////////// SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const { - return elementsIterator(SMDSAbs_Node); + return elementsIterator(SMDSAbs_Node); } /////////////////////////////////////////////////////////////////////////////// @@ -64,7 +79,7 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const /////////////////////////////////////////////////////////////////////////////// SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const { - return elementsIterator(SMDSAbs_Edge); + return elementsIterator(SMDSAbs_Edge); } /////////////////////////////////////////////////////////////////////////////// @@ -73,7 +88,7 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const /////////////////////////////////////////////////////////////////////////////// SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const { - return elementsIterator(SMDSAbs_Face); + return elementsIterator(SMDSAbs_Face); } /////////////////////////////////////////////////////////////////////////////// @@ -81,14 +96,14 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const /////////////////////////////////////////////////////////////////////////////// int SMDS_MeshElement::NbNodes() const { - int nbnodes=0; - SMDS_ElemIteratorPtr it=nodesIterator(); - while(it->more()) - { - it->next(); - nbnodes++; - } - return nbnodes; + int nbnodes=0; + SMDS_ElemIteratorPtr it=nodesIterator(); + while(it->more()) + { + it->next(); + nbnodes++; + } + return nbnodes; } /////////////////////////////////////////////////////////////////////////////// @@ -96,14 +111,14 @@ int SMDS_MeshElement::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_MeshElement::NbEdges() const { - int nbedges=0; - SMDS_ElemIteratorPtr it=edgesIterator(); - while(it->more()) - { - it->next(); - nbedges++; - } - return nbedges; + int nbedges=0; + SMDS_ElemIteratorPtr it=edgesIterator(); + while(it->more()) + { + it->next(); + nbedges++; + } + return nbedges; } /////////////////////////////////////////////////////////////////////////////// @@ -111,14 +126,14 @@ int SMDS_MeshElement::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_MeshElement::NbFaces() const { - int nbfaces=0; - SMDS_ElemIteratorPtr it=facesIterator(); - while(it->more()) - { - it->next(); - nbfaces++; - } - return nbfaces; + int nbfaces=0; + SMDS_ElemIteratorPtr it=facesIterator(); + while(it->more()) + { + it->next(); + nbfaces++; + } + return nbfaces; } /////////////////////////////////////////////////////////////////////////////// @@ -142,56 +157,63 @@ class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator const SMDS_MeshElement* next() { myMore=false; - return myElement; - } + return myElement; + } }; + SMDS_ElemIteratorPtr SMDS_MeshElement:: - elementsIterator(SMDSAbs_ElementType type) const + elementsIterator(SMDSAbs_ElementType type) const { - /** @todo Check that iterator in the child classes return elements - in the same order for each different implementation (i.e: SMDS_VolumeOfNodes - and SMDS_VolumeOfFaces */ - - if(type==GetType()) + /** @todo Check that iterator in the child classes return elements + in the same order for each different implementation (i.e: SMDS_VolumeOfNodes + and SMDS_VolumeOfFaces */ + + if(type==GetType()) return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this)); - else - { + else + { MESSAGE("Iterator not implemented"); return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL); - } + } } -/////////////////////////////////////////////////////////////////////////////// -///Return the ID of the element -/////////////////////////////////////////////////////////////////////////////// -int SMDS_MeshElement::GetID() const +//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes +SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIteratorToUNV() const { - return myID; + MESSAGE("Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); +} + +//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes +SMDS_ElemIteratorPtr SMDS_MeshElement::interlacedNodesElemIterator() const +{ + MESSAGE("Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); } bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2) { - if(e1.GetType()!=e2.GetType()) return false; - switch(e1.GetType()) - { - case SMDSAbs_Node: - return static_cast(e1) < - static_cast(e2); + if(e1.GetType()!=e2.GetType()) return false; + switch(e1.GetType()) + { + case SMDSAbs_Node: + return static_cast(e1) < + static_cast(e2); - case SMDSAbs_Edge: - return static_cast(e1) < - static_cast(e2); + case SMDSAbs_Edge: + return static_cast(e1) < + static_cast(e2); - case SMDSAbs_Face: - return static_cast(e1) < - static_cast(e2); + case SMDSAbs_Face: + return static_cast(e1) < + static_cast(e2); - case SMDSAbs_Volume: - return static_cast(e1) < - static_cast(e2); + case SMDSAbs_Volume: + return static_cast(e1) < + static_cast(e2); - default : MESSAGE("Internal Error"); - } + default : MESSAGE("Internal Error"); + } return false; } @@ -202,12 +224,13 @@ bool SMDS_MeshElement::IsValidIndex(const int ind) const const SMDS_MeshNode* SMDS_MeshElement::GetNode(const int ind) const { - SMDS_ElemIteratorPtr it = nodesIterator(); - int i = 0, index = WrappedIndex( ind ); - while ( index != i++ ) - it->next(); - if ( it->more() ) - return static_cast (it->next()); + if ( ind >= 0 ) { + SMDS_ElemIteratorPtr it = nodesIterator(); + for ( int i = 0; i < ind; ++i ) + it->next(); + if ( it->more() ) + return static_cast (it->next()); + } return 0; } @@ -221,6 +244,17 @@ bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const return false; } +//================================================================================ +/*! + * \brief Return number of nodes excluding medium ones + */ +//================================================================================ + +int SMDS_MeshElement::NbCornerNodes() const +{ + return IsQuadratic() ? NbNodes() - NbEdges() : NbNodes(); +} + //================================================================================ /*! * \brief Check if a node belongs to the element diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 2716456d3..918ebb668 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshElement.hxx // Module : SMESH @@ -27,22 +28,35 @@ #define _SMDS_MeshElement_HeaderFile #include "SMESH_SMDS.hxx" - + #include "SMDSAbs_ElementType.hxx" #include "SMDS_MeshObject.hxx" #include "SMDS_ElemIterator.hxx" #include "SMDS_MeshElementIDFactory.hxx" +#include "SMDS_StdIterator.hxx" #include #include +#include +#include + +//typedef unsigned short UShortType; +typedef short ShortType; +typedef int LongType; + class SMDS_MeshNode; class SMDS_MeshEdge; -class SMDS_MeshFace; +class SMDS_MeshFace; +class SMDS_Mesh; + +// ============================================================ +/*! + * \brief Base class for elements + */ +// ============================================================ + -/////////////////////////////////////////////////////////////////////////////// -/// Base class for elements -/////////////////////////////////////////////////////////////////////////////// class SMDS_EXPORT SMDS_MeshElement:public SMDS_MeshObject { public: @@ -51,25 +65,47 @@ public: SMDS_ElemIteratorPtr edgesIterator() const; SMDS_ElemIteratorPtr facesIterator() const; virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; + + // std-like iteration on nodes + typedef SMDS_StdIterator< const SMDS_MeshNode*, SMDS_ElemIteratorPtr > iterator; + iterator begin_nodes() const { return iterator( nodesIterator() ); } + iterator end_nodes() const { return iterator(); } virtual int NbNodes() const; virtual int NbEdges() const; virtual int NbFaces() const; - int GetID() const; + inline int GetID() const { return myID; }; ///Return the type of the current element virtual SMDSAbs_ElementType GetType() const = 0; - virtual bool IsPoly() const { return false; }; + virtual SMDSAbs_EntityType GetEntityType() const = 0; + virtual SMDSAbs_GeometryType GetGeomType() const = 0; + virtual vtkIdType GetVtkType() const = 0; + virtual bool IsPoly() const { return false; } virtual bool IsQuadratic() const; virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + virtual int NbCornerNodes() const; friend SMDS_EXPORT std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *); - friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem); + friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement* elem); + friend class SMDS_Mesh; + friend class SMESHDS_Mesh; + friend class SMESHDS_SubMesh; + friend class SMDS_MeshElementIDFactory; // =========================== // Access to nodes by index // =========================== + /*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ + virtual const SMDS_MeshNode* GetNode(const int ind) const; + /*! * \brief Return node by its index * \param ind - node index @@ -77,7 +113,7 @@ public: * * Index is wrapped if it is out of a valid range */ - virtual const SMDS_MeshNode* GetNode(const int ind) const; + const SMDS_MeshNode* GetNodeWrap(const int ind) const { return GetNode( WrappedIndex( ind )); } /*! * \brief Return true if index of node is valid (0 <= ind < NbNodes()) @@ -104,12 +140,65 @@ public: */ int GetNodeIndex( const SMDS_MeshNode* node ) const; + inline ShortType getMeshId() const { return myMeshId; } + inline LongType getshapeId() const { return myShapeId; } + inline int getIdInShape() const { return myIdInShape; } + inline int getVtkId() const { return myVtkID; } + + /*! + * \brief Filters of elements, to be used with SMDS_SetIterator + */ + struct TypeFilter + { + SMDSAbs_ElementType _type; + TypeFilter( SMDSAbs_ElementType t = SMDSAbs_NbElementTypes ):_type(t) {} + bool operator()(const SMDS_MeshElement* e) const { return e && e->GetType() == _type; } + }; + struct EntityFilter + { + SMDSAbs_EntityType _type; + EntityFilter( SMDSAbs_EntityType t = SMDSEntity_Last ):_type(t) {} + bool operator()(const SMDS_MeshElement* e) const { return e && e->GetEntityType() == _type; } + }; + struct GeomFilter + { + SMDSAbs_GeometryType _type; + GeomFilter( SMDSAbs_GeometryType t = SMDSGeom_NONE ):_type(t) {} + bool operator()(const SMDS_MeshElement* e) const { return e && e->GetGeomType() == _type; } + }; + protected: + inline void setId(int id) {myID = id; } + inline void setShapeId(LongType shapeId) {myShapeId = shapeId; } + inline void setIdInShape(int id) { myIdInShape = id; } + inline void setVtkId(int vtkId) { myVtkID = vtkId; } SMDS_MeshElement(int ID=-1); + SMDS_MeshElement(int id, ShortType meshId, LongType shapeId = 0); + virtual void init(int id = -1, ShortType meshId = -1, LongType shapeId = 0); virtual void Print(std::ostream & OS) const; -private: + //! Element index in vector SMDS_Mesh::myNodes or SMDS_Mesh::myCells int myID; + //! index in vtkUnstructuredGrid + int myVtkID; + //! SMDS_Mesh identification in SMESH + ShortType myMeshId; + //! SubShape and SubMesh identification in SMESHDS + LongType myShapeId; + //! Element index in SMESHDS_SubMesh vector + int myIdInShape; +}; + + +// ============================================================ +/*! + * \brief Comparator of elements by ID for usage in std containers + */ +// ============================================================ + +struct TIDCompare { + bool operator () (const SMDS_MeshElement* e1, const SMDS_MeshElement* e2) const + { return e1->GetID() < e2->GetID(); } }; #endif diff --git a/src/SMDS/SMDS_MeshElementIDFactory.cxx b/src/SMDS/SMDS_MeshElementIDFactory.cxx index 7ecfba5b0..204d7215d 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.cxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshElementIDFactory.cxx // Author : Jean-Michel BOULCOURT @@ -30,6 +31,14 @@ #include "SMDS_MeshElementIDFactory.hxx" #include "SMDS_MeshElement.hxx" +#include "SMDS_Mesh.hxx" + +#include "utilities.h" + +#include "SMDS_UnstructuredGrid.hxx" +#include + +#include using namespace std; @@ -38,23 +47,46 @@ using namespace std; //purpose : //======================================================================= SMDS_MeshElementIDFactory::SMDS_MeshElementIDFactory(): - SMDS_MeshIDFactory(), - myMin(0), myMax(0) + SMDS_MeshNodeIDFactory() +{ +} + +int SMDS_MeshElementIDFactory::SetInVtkGrid(SMDS_MeshElement * elem) { + // --- retrieve nodes ID + + SMDS_MeshCell *cell = dynamic_cast(elem); + assert(cell); + vector nodeIds; + SMDS_ElemIteratorPtr it = elem->nodesIterator(); + while(it->more()) + { + int nodeId = (static_cast(it->next()))->getVtkId(); + MESSAGE(" node in cell " << cell->getVtkId() << " : " << nodeId) + nodeIds.push_back(nodeId); + } + + // --- insert cell in vtkUnstructuredGrid + + vtkUnstructuredGrid * grid = myMesh->getGrid(); + //int locType = elem->GetType(); + int typ = VTK_VERTEX;//GetVtkCellType(locType); + int cellId = grid->InsertNextLinkedCell(typ, nodeIds.size(), &nodeIds[0]); + cell->setVtkId(cellId); + //MESSAGE("SMDS_MeshElementIDFactory::SetInVtkGrid " << cellId); + return cellId; } //======================================================================= //function : BindID //purpose : //======================================================================= + bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem) { - if (myIDElements.IsBound(ID)) - return false; - myIDElements.Bind(ID,elem); - elem->myID=ID; - updateMinMax (ID); - return true; + MESSAGE("SMDS_MeshElementIDFactory::BindID " << ID); + SetInVtkGrid(elem); + return myMesh->registerElement(ID, elem); } //======================================================================= @@ -63,22 +95,23 @@ bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem) //======================================================================= SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID) { - if (!myIDElements.IsBound(ID)) + if ((ID<1) || (ID>=myMesh->myCells.size())) return NULL; - return myIDElements.Find(ID); + const SMDS_MeshElement* elem = GetMesh()->FindElement(ID); + return (SMDS_MeshElement*)(elem); } - //======================================================================= //function : GetFreeID //purpose : //======================================================================= + int SMDS_MeshElementIDFactory::GetFreeID() { int ID; do { ID = SMDS_MeshIDFactory::GetFreeID(); - } while (myIDElements.IsBound(ID)); + } while ( MeshElement( ID )); return ID; } @@ -86,38 +119,25 @@ int SMDS_MeshElementIDFactory::GetFreeID() //function : ReleaseID //purpose : //======================================================================= -void SMDS_MeshElementIDFactory::ReleaseID(const int ID) +void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId) { - myIDElements.UnBind(ID); + if (ID < 1) // TODO check case ID == O + { + MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID ID = " << ID); + return; + } + //MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID smdsId vtkId " << ID << " " << vtkId); + if (vtkId >= 0) + { + assert(vtkId < myMesh->myCellIdVtkToSmds.size()); + myMesh->myCellIdVtkToSmds[vtkId] = -1; + myMesh->setMyModified(); + } SMDS_MeshIDFactory::ReleaseID(ID); if (ID == myMax) myMax = 0; if (ID == myMin) - myMin = 0; -} - -//======================================================================= -//function : GetMaxID -//purpose : -//======================================================================= - -int SMDS_MeshElementIDFactory::GetMaxID() const -{ - if (myMax == 0) - updateMinMax(); - return myMax; -} - -//======================================================================= -//function : GetMinID -//purpose : -//======================================================================= - -int SMDS_MeshElementIDFactory::GetMinID() const -{ - if (myMin == 0) - updateMinMax(); - return myMin; + myMax = 0; } //======================================================================= @@ -127,12 +147,20 @@ int SMDS_MeshElementIDFactory::GetMinID() const void SMDS_MeshElementIDFactory::updateMinMax() const { - myMin = IntegerLast(); + myMin = INT_MAX; myMax = 0; - SMDS_IdElementMap::Iterator it(myIDElements); - for (; it.More(); it.Next()) - updateMinMax (it.Key()); - if (myMin == IntegerLast()) + for (int i = 0; i < myMesh->myCells.size(); i++) + { + if (myMesh->myCells[i]) + { + int id = myMesh->myCells[i]->GetID(); + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + } + if (myMin == INT_MAX) myMin = 0; } @@ -141,35 +169,15 @@ void SMDS_MeshElementIDFactory::updateMinMax() const //purpose : Return an iterator on elements of the factory //======================================================================= -class SMDS_Fact_MyElemIterator:public SMDS_ElemIterator -{ - SMDS_IdElementMap::Iterator myIterator; - public: - SMDS_Fact_MyElemIterator(const SMDS_IdElementMap& s):myIterator(s) - {} - - bool more() - { - return myIterator.More() != Standard_False; - } - - const SMDS_MeshElement* next() - { - const SMDS_MeshElement* current = myIterator.Value(); - myIterator.Next(); - return current; - } -}; - SMDS_ElemIteratorPtr SMDS_MeshElementIDFactory::elementsIterator() const { - return SMDS_ElemIteratorPtr - (new SMDS_Fact_MyElemIterator(myIDElements)); + return myMesh->elementsIterator(SMDSAbs_All); } void SMDS_MeshElementIDFactory::Clear() { - myIDElements.Clear(); + //myMesh->myCellIdSmdsToVtk.clear(); + myMesh->myCellIdVtkToSmds.clear(); myMin = myMax = 0; SMDS_MeshIDFactory::Clear(); } diff --git a/src/SMDS/SMDS_MeshElementIDFactory.hxx b/src/SMDS/SMDS_MeshElementIDFactory.hxx index a574def92..793ff0b32 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.hxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshElementIDFactory.hxx // Module : SMESH @@ -28,28 +29,28 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshIDFactory.hxx" -#include "SMDS_ElemIterator.hxx" +#include "SMDS_MeshNodeIDFactory.hxx" -#include +#include class SMDS_MeshElement; +class SMDS_Mesh; -typedef NCollection_DataMap SMDS_IdElementMap; - -class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshIDFactory +class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshNodeIDFactory { public: + friend class SMDS_Mesh; + SMDS_MeshElementIDFactory(); bool BindID(int ID, SMDS_MeshElement * elem); + int SetInVtkGrid(SMDS_MeshElement * elem); SMDS_MeshElement * MeshElement(int ID); virtual int GetFreeID(); - virtual void ReleaseID(int ID); - int GetMaxID() const; - int GetMinID() const; + virtual void ReleaseID(int ID, int vtkId = -1); SMDS_ElemIteratorPtr elementsIterator() const; virtual void Clear(); -private: + +protected: void updateMinMax() const; void updateMinMax(int id) const { @@ -57,9 +58,6 @@ private: if (id < myMin) myMin = id; } - SMDS_IdElementMap myIDElements; - mutable int myMin, myMax; - }; #endif diff --git a/src/SMDS/SMDS_MeshFace.cxx b/src/SMDS/SMDS_MeshFace.cxx index a4a19f03f..a3e4cf521 100644 --- a/src/SMDS/SMDS_MeshFace.cxx +++ b/src/SMDS/SMDS_MeshFace.cxx @@ -1,29 +1,35 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #include "SMDS_MeshFace.hxx" SMDSAbs_ElementType SMDS_MeshFace::GetType() const { - return SMDSAbs_Face; + return SMDSAbs_Face; +} + +vtkIdType SMDS_MeshFace::GetVtkType() const +{ + return VTK_POLY_LINE; // --- must be reimplemented in derived classes } diff --git a/src/SMDS/SMDS_MeshFace.hxx b/src/SMDS/SMDS_MeshFace.hxx index a633e4ecf..15e06572a 100644 --- a/src/SMDS/SMDS_MeshFace.hxx +++ b/src/SMDS/SMDS_MeshFace.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshFace.hxx // Module : SMESH @@ -28,12 +29,13 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshCell.hxx" -class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshCell { public: - SMDSAbs_ElementType GetType() const; + SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; }; #endif diff --git a/src/SMDS/SMDS_MeshGroup.cxx b/src/SMDS/SMDS_MeshGroup.cxx index 67c1df426..b81ffe55a 100644 --- a/src/SMDS/SMDS_MeshGroup.cxx +++ b/src/SMDS/SMDS_MeshGroup.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshGroup.cxx // Author : Jean-Michel BOULCOURT @@ -40,7 +41,7 @@ using namespace std; SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh, const SMDSAbs_ElementType theType) - :myMesh(theMesh),myType(theType), myParent(NULL) + :myMesh(theMesh),myType(theType), myParent(NULL), myTic(0) { } @@ -51,7 +52,7 @@ SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh, SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * theParent, const SMDSAbs_ElementType theType) - :myMesh(theParent->myMesh),myType(theType), myParent(theParent) + :myMesh(theParent->myMesh),myType(theType), myParent(theParent) { } @@ -63,9 +64,9 @@ SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * theParent, const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup (const SMDSAbs_ElementType theType) { - const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this,theType); - myChildren.insert(myChildren.end(),subgroup); - return subgroup; + const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this,theType); + myChildren.insert(myChildren.end(),subgroup); + return subgroup; } //======================================================================= @@ -75,19 +76,19 @@ const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * theGroup) { - bool found = false; - list::iterator itgroup; - for(itgroup=myChildren.begin(); itgroup!=myChildren.end(); itgroup++) - { - const SMDS_MeshGroup* subgroup=*itgroup; - if (subgroup == theGroup) - { - found = true; - myChildren.erase(itgroup); - } - } - - return found; + bool found = false; + list::iterator itgroup; + for(itgroup=myChildren.begin(); itgroup!=myChildren.end(); itgroup++) + { + const SMDS_MeshGroup* subgroup=*itgroup; + if (subgroup == theGroup) + { + found = true; + myChildren.erase(itgroup); + } + } + + return found; } //======================================================================= @@ -97,12 +98,12 @@ bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * theGroup) bool SMDS_MeshGroup::RemoveFromParent() { - - if (myParent==NULL) return false; - else - { - return (myParent->RemoveSubGroup(this)); - } + + if (myParent==NULL) return false; + else + { + return (myParent->RemoveSubGroup(this)); + } } //======================================================================= //function : Clear @@ -111,8 +112,9 @@ bool SMDS_MeshGroup::RemoveFromParent() void SMDS_MeshGroup::Clear() { - myElements.clear(); - myType = SMDSAbs_All; + myElements.clear(); + myType = SMDSAbs_All; + ++myTic; } //======================================================================= @@ -122,14 +124,15 @@ void SMDS_MeshGroup::Clear() void SMDS_MeshGroup::Add(const SMDS_MeshElement * theElem) { - // the type of the group is determined by the first element added - if (myElements.empty()) myType = theElem->GetType(); - else if (theElem->GetType() != myType) { - MESSAGE("SMDS_MeshGroup::Add : Type Mismatch "<GetType()<<"!="<GetType(); + else if (theElem->GetType() != myType) { + MESSAGE("SMDS_MeshGroup::Add : Type Mismatch "<GetType()<<"!="<::iterator found - = myElements.find(theElem); + set::iterator found = myElements.find(theElem); if ( found != myElements.end() ) { myElements.erase(found); if (myElements.empty()) myType = SMDSAbs_All; + ++myTic; return true; } return false; @@ -156,7 +159,7 @@ bool SMDS_MeshGroup::Remove(const SMDS_MeshElement * theElem) bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * theElem) const { - return myElements.find(theElem)!=myElements.end(); + return myElements.find(theElem)!=myElements.end(); } //======================================================================= diff --git a/src/SMDS/SMDS_MeshGroup.hxx b/src/SMDS/SMDS_MeshGroup.hxx index 788aaa79a..c46184ea9 100644 --- a/src/SMDS/SMDS_MeshGroup.hxx +++ b/src/SMDS/SMDS_MeshGroup.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshGroup.hxx // Module : SMESH @@ -34,27 +35,28 @@ class SMDS_EXPORT SMDS_MeshGroup:public SMDS_MeshObject { public: - SMDS_MeshGroup(const SMDS_Mesh * theMesh, + SMDS_MeshGroup(const SMDS_Mesh * theMesh, const SMDSAbs_ElementType theType = SMDSAbs_All); - const SMDS_MeshGroup * AddSubGroup + const SMDS_MeshGroup * AddSubGroup (const SMDSAbs_ElementType theType = SMDSAbs_All); - virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup); - virtual bool RemoveFromParent(); + virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup); + virtual bool RemoveFromParent(); const SMDS_Mesh* GetMesh() const { return myMesh; } void SetType (const SMDSAbs_ElementType theType); void Clear(); - void Add(const SMDS_MeshElement * theElem); - bool Remove(const SMDS_MeshElement * theElem); - bool IsEmpty() const { return myElements.empty(); } - int Extent() const { return myElements.size(); } + void Add(const SMDS_MeshElement * theElem); + bool Remove(const SMDS_MeshElement * theElem); + bool IsEmpty() const { return myElements.empty(); } + int Extent() const { return myElements.size(); } + int Tic() const { return myTic; } - int SubGroupsNb() const { return myChildren.size(); } + int SubGroupsNb() const { return myChildren.size(); } SMDSAbs_ElementType GetType() const { return myType; } - bool Contains(const SMDS_MeshElement * theElem) const; + bool Contains(const SMDS_MeshElement * theElem) const; void InitIterator() const { const_cast(myIterator) = myElements.begin(); } @@ -73,18 +75,19 @@ class SMDS_EXPORT SMDS_MeshGroup:public SMDS_MeshObject { return *(const_cast(myGroupIterator))++; } private: - SMDS_MeshGroup(SMDS_MeshGroup* theParent, + SMDS_MeshGroup(SMDS_MeshGroup* theParent, const SMDSAbs_ElementType theType = SMDSAbs_All); typedef std::set::const_iterator TIterator; typedef std::list::const_iterator TGroupIterator; - const SMDS_Mesh * myMesh; - SMDSAbs_ElementType myType; - std::set myElements; - SMDS_MeshGroup * myParent; - std::list myChildren; + const SMDS_Mesh * myMesh; + SMDSAbs_ElementType myType; + std::set myElements; /* - not sorted by ID because it */ + SMDS_MeshGroup * myParent; /* can contain deleted elements */ + std::list myChildren; TIterator myIterator; TGroupIterator myGroupIterator; + int myTic; // to track changes }; #endif diff --git a/src/SMDS/SMDS_MeshIDFactory.cxx b/src/SMDS/SMDS_MeshIDFactory.cxx index 88b9ce38d..ce8f45d2f 100644 --- a/src/SMDS/SMDS_MeshIDFactory.cxx +++ b/src/SMDS/SMDS_MeshIDFactory.cxx @@ -1,30 +1,33 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshIDFactory.cxx // Author : Jean-Michel BOULCOURT // Module : SMESH // #include "SMDS_MeshIDFactory.hxx" +#include "SMDS_Mesh.hxx" +#include "utilities.h" using namespace std; @@ -33,27 +36,33 @@ using namespace std; //purpose : //======================================================================= -SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0) +SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0), myMesh(0) { } int SMDS_MeshIDFactory::GetFreeID() { - if (myPoolOfID.empty()) return ++myMaxID; - else - { + int newid; + if (myPoolOfID.empty()) + { + newid = ++myMaxID; + //MESSAGE("GetFreeID new " << newid); + } + else + { set::iterator i = myPoolOfID.begin(); - int ID = *i;//myPoolOfID.top(); - myPoolOfID.erase( i );//myPoolOfID.pop(); - return ID; - } + newid = *i;//myPoolOfID.top(); + myPoolOfID.erase( i );//myPoolOfID.pop(); + //MESSAGE("GetFreeID pool " << newid); + } + return newid; } //======================================================================= //function : ReleaseID //purpose : //======================================================================= -void SMDS_MeshIDFactory::ReleaseID(const int ID) +void SMDS_MeshIDFactory::ReleaseID(int ID, int vtkId) { if ( ID > 0 ) { @@ -82,6 +91,24 @@ void SMDS_MeshIDFactory::ReleaseID(const int ID) void SMDS_MeshIDFactory::Clear() { - myMaxID = 0; - myPoolOfID.clear(); + myMaxID = 0; + myPoolOfID.clear(); +} + +void SMDS_MeshIDFactory::SetMesh(SMDS_Mesh *mesh) +{ + myMesh = mesh; } + +SMDS_Mesh* SMDS_MeshIDFactory::GetMesh() +{ + return myMesh; +} + +void SMDS_MeshIDFactory::emptyPool(int maxId) +{ + MESSAGE("SMDS_MeshIDFactory::emptyPool " << myMaxID << " --> " << maxId); + myMaxID = maxId; + myPoolOfID.clear(); +} + diff --git a/src/SMDS/SMDS_MeshIDFactory.hxx b/src/SMDS/SMDS_MeshIDFactory.hxx index e81b41890..c79e17aaa 100644 --- a/src/SMDS/SMDS_MeshIDFactory.hxx +++ b/src/SMDS/SMDS_MeshIDFactory.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshIDFactory.hxx // Module : SMESH @@ -31,18 +32,25 @@ #include "SMDS_MeshObject.hxx" #include +class SMDS_Mesh; class SMDS_EXPORT SMDS_MeshIDFactory:public SMDS_MeshObject { public: - virtual int GetFreeID(); - virtual void ReleaseID(int ID); + int GetFreeID(); + virtual void ReleaseID(int ID, int vtkId = -1); virtual void Clear(); - protected: - SMDS_MeshIDFactory(); - int myMaxID; - std::set myPoolOfID; + void SetMesh(SMDS_Mesh *mesh); + SMDS_Mesh* GetMesh(); + inline bool isPoolIdEmpty() { return myPoolOfID.empty(); }; + virtual void emptyPool(int maxId); + inline void adjustMaxId(int ID) { if (ID > myMaxID) myMaxID = ID;}; +protected: + SMDS_MeshIDFactory(); + int myMaxID; + std::set myPoolOfID; + SMDS_Mesh *myMesh; }; #endif diff --git a/src/SMDS/SMDS_MeshInfo.hxx b/src/SMDS/SMDS_MeshInfo.hxx index 6b00427d9..026590a2e 100644 --- a/src/SMDS/SMDS_MeshInfo.hxx +++ b/src/SMDS/SMDS_MeshInfo.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMDS_MeshInfo.hxx // Created : Mon Sep 24 18:32:41 2007 // Author : Edward AGAPOV (eap) @@ -26,6 +24,7 @@ #ifndef SMDS_MeshInfo_HeaderFile #define SMDS_MeshInfo_HeaderFile +#include using namespace std; #include "SMESH_SMDS.hxx" @@ -37,14 +36,21 @@ class SMDS_EXPORT SMDS_MeshInfo public: inline SMDS_MeshInfo(); + inline SMDS_MeshInfo& operator=(const SMDS_MeshInfo& other); inline void Clear(); - int NbNodes() const { return myNbNodes; } + inline int NbElements(SMDSAbs_ElementType type=SMDSAbs_All) const; + inline int NbEntities(SMDSAbs_EntityType type) const; + int NbNodes() const { return myNbNodes; } + int Nb0DElements() const { return myNb0DElements; } + int NbBalls() const { return myNbBalls; } inline int NbEdges (SMDSAbs_ElementOrder order = ORDER_ANY) const; + inline int NbFaces (SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbTriangles (SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const; + int NbBiQuadQuadrangles() const { return myNbBiQuadQuadrangles; } int NbPolygons() const { return myNbPolygons; } inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const; @@ -52,15 +58,21 @@ public: inline int NbHexas (SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const; inline int NbPrisms (SMDSAbs_ElementOrder order = ORDER_ANY) const; + inline int NbHexPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const; + int NbTriQuadHexas() const { return myNbTriQuadHexas; } int NbPolyhedrons() const { return myNbPolyhedrons; } +protected: + inline void addWithPoly(const SMDS_MeshElement* el); + inline void setNb(const SMDSAbs_EntityType geomType, const int nb); + private: friend class SMDS_Mesh; // methods to count NOT POLY elements inline void remove(const SMDS_MeshElement* el); inline void add (const SMDS_MeshElement* el); - inline int index(SMDSAbs_ElementType type, int nbNodes); + inline int index(SMDSAbs_ElementType type, int nbNodes) const; // methods to remove elements of ANY kind inline void RemoveEdge(const SMDS_MeshElement* el); inline void RemoveFace(const SMDS_MeshElement* el); @@ -68,15 +80,18 @@ private: int myNbNodes; + int myNb0DElements; + int myNbBalls; int myNbEdges , myNbQuadEdges ; int myNbTriangles , myNbQuadTriangles ; - int myNbQuadrangles, myNbQuadQuadrangles; + int myNbQuadrangles, myNbQuadQuadrangles, myNbBiQuadQuadrangles; int myNbPolygons; int myNbTetras , myNbQuadTetras ; - int myNbHexas , myNbQuadHexas ; + int myNbHexas , myNbQuadHexas, myNbTriQuadHexas; int myNbPyramids, myNbQuadPyramids; int myNbPrisms , myNbQuadPrisms ; + int myNbHexPrism; int myNbPolyhedrons; std::vector myNb; // pointers to myNb... fields @@ -84,51 +99,69 @@ private: }; inline SMDS_MeshInfo::SMDS_MeshInfo(): - myNbNodes(0), + myNbNodes (0), + myNb0DElements (0), + myNbBalls (0), myNbEdges (0), myNbQuadEdges (0), myNbTriangles (0), myNbQuadTriangles (0), - myNbQuadrangles(0), myNbQuadQuadrangles(0), - myNbPolygons(0), - myNbTetras (0), myNbQuadTetras (0), - myNbHexas (0), myNbQuadHexas (0), - myNbPyramids(0), myNbQuadPyramids(0), - myNbPrisms (0), myNbQuadPrisms (0), + myNbQuadrangles(0), myNbQuadQuadrangles(0), myNbBiQuadQuadrangles(0), + myNbPolygons (0), + myNbTetras (0), myNbQuadTetras (0), + myNbHexas (0), myNbQuadHexas (0), myNbTriQuadHexas(0), + myNbPyramids (0), myNbQuadPyramids(0), + myNbPrisms (0), myNbQuadPrisms (0), + myNbHexPrism (0), myNbPolyhedrons(0) { - // Number of nodes in standard element types - // n v f e - // o o a d - // d l c g - // e e e - // ----------- - // 1 - // 2 * - // 3 * - // 4 * * * - // 5 * - // 6 * * - // 7 - // 8 * * - // 9 - // 10 * - // 11 - // 12 - // 13 * - // 14 - // 15 * - // 16 - // 17 - // 18 - // 19 + // Number of nodes in standard element types (. - actual nb, * - after the shift) + // n v f e 0 n b + // o o a d d o a + // d l c g d l + // e e e e l + // s + // ==================== + // 0 ------------------ - DON't USE 0!!! + // 1 . * . + // 2 . * + // 3 . * + // 4 * . . + // 5 * + // 6 * . + // 7 * + // 8 * . + // 9 . * + // 10 * + // 11 + // 12 * + // 13 * + // 14 + // 15 * + // 16 * + // 17 * + // 18 + // 19 * // 20 * + // 21 * + // 22 * + // 23 + // 24 + // 25 + // 26 + // 27 * // // So to have a unique index for each type basing on nb of nodes, we use a shift: - myShift.resize(SMDSAbs_Volume + 1, 0); - myShift[ SMDSAbs_Face ] = +8; // 3->11, 4->12, 6->14, 8->16 - myShift[ SMDSAbs_Edge ] = -2; // 2->0, 4->2 + myShift.resize(SMDSAbs_NbElementTypes, 0); + + myShift[ SMDSAbs_Face ] = +13;// 3->16, 4->17, 6->19, 8->21, 9->22 + myShift[ SMDSAbs_Edge ] = +5; // 2->7, 4->9 + myShift[ SMDSAbs_0DElement ] = +2; // 1->3 + myShift[ SMDSAbs_Ball ] = +1; // 1->2 + + myNb.resize( index( SMDSAbs_Volume,27 ) + 1, NULL); - myNb.resize( index( SMDSAbs_Volume,20 ) + 1, NULL); myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes; + myNb[ index( SMDSAbs_0DElement,1 )] = & myNb0DElements; + myNb[ index( SMDSAbs_Ball,1 )] = & myNbBalls; myNb[ index( SMDSAbs_Edge,2 )] = & myNbEdges; myNb[ index( SMDSAbs_Edge,4 )] = & myNbQuadEdges; @@ -137,22 +170,36 @@ inline SMDS_MeshInfo::SMDS_MeshInfo(): myNb[ index( SMDSAbs_Face,4 )] = & myNbQuadrangles; myNb[ index( SMDSAbs_Face,6 )] = & myNbQuadTriangles; myNb[ index( SMDSAbs_Face,8 )] = & myNbQuadQuadrangles; + myNb[ index( SMDSAbs_Face,9 )] = & myNbBiQuadQuadrangles; myNb[ index( SMDSAbs_Volume, 4)] = & myNbTetras; myNb[ index( SMDSAbs_Volume, 5)] = & myNbPyramids; myNb[ index( SMDSAbs_Volume, 6)] = & myNbPrisms; myNb[ index( SMDSAbs_Volume, 8)] = & myNbHexas; myNb[ index( SMDSAbs_Volume, 10)] = & myNbQuadTetras; + myNb[ index( SMDSAbs_Volume, 12)] = & myNbHexPrism; myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids; myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms; myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas; + myNb[ index( SMDSAbs_Volume, 27)] = & myNbTriQuadHexas; +} + +inline SMDS_MeshInfo& // operator= +SMDS_MeshInfo::operator=(const SMDS_MeshInfo& other) +{ for ( int i=0; iGetType(), el->NbNodes()) ]); } +inline void // addWithPoly +SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el) +{ + if ( el->IsPoly() ) + ++( el->GetType()==SMDSAbs_Face ? myNbPolygons : myNbPolyhedrons ); + else + add(el); +} inline void // RemoveEdge SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el) { if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; } @@ -189,11 +244,11 @@ SMDS_MeshInfo::NbTriangles (SMDSAbs_ElementOrder order) const inline int // NbQuadrangles SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const -{ return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles; } +{ return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles+myNbBiQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles+myNbBiQuadQuadrangles; } inline int // NbVolumes SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const -{ return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); } +{ return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + NbHexPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); } inline int // NbTetras SMDS_MeshInfo::NbTetras (SMDSAbs_ElementOrder order) const @@ -201,7 +256,7 @@ SMDS_MeshInfo::NbTetras (SMDSAbs_ElementOrder order) const inline int // NbHexas SMDS_MeshInfo::NbHexas (SMDSAbs_ElementOrder order) const -{ return order == ORDER_ANY ? myNbHexas+myNbQuadHexas : order == ORDER_LINEAR ? myNbHexas : myNbQuadHexas; } +{ return order == ORDER_ANY ? myNbHexas+myNbQuadHexas+myNbTriQuadHexas : order == ORDER_LINEAR ? myNbHexas : myNbQuadHexas+myNbTriQuadHexas; } inline int // NbPyramids SMDS_MeshInfo::NbPyramids(SMDSAbs_ElementOrder order) const @@ -211,4 +266,108 @@ inline int // NbPrisms SMDS_MeshInfo::NbPrisms (SMDSAbs_ElementOrder order) const { return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; } +inline int // NbHexPrisms +SMDS_MeshInfo::NbHexPrisms (SMDSAbs_ElementOrder order) const +{ return order == ORDER_ANY ? myNbHexPrism : order == ORDER_LINEAR ? myNbHexPrism : 0; } + +inline int // NbElements +SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const +{ + int nb = 0; + switch (type) { + case SMDSAbs_All: + for ( int i=1+index( SMDSAbs_Node,1 ); i + +#include "utilities.h" +#include "Utils_SALOME_Exception.hxx" +#include using namespace std; +int SMDS_MeshNode::nbNodes =0; + //======================================================================= //function : SMDS_MeshNode //purpose : //======================================================================= +SMDS_MeshNode::SMDS_MeshNode() : + SMDS_MeshElement(-1, -1, 0), + myPosition(SMDS_SpacePosition::originSpacePosition()) +{ + nbNodes++; +} + +SMDS_MeshNode::SMDS_MeshNode(int id, int meshId, int shapeId, double x, double y, double z): + SMDS_MeshElement(id, meshId, shapeId), + myPosition(SMDS_SpacePosition::originSpacePosition()) +{ + nbNodes++; + init(id, meshId, shapeId, x, y ,z); +} + +void SMDS_MeshNode::init(int id, int meshId, int shapeId, double x, double y, double z) +{ + SMDS_MeshElement::init(id, meshId, shapeId); + myVtkID = id -1; + assert(myVtkID >= 0); + //MESSAGE("Node " << myID << " " << myVtkID << " (" << x << ", " << y << ", " << z << ")"); + SMDS_Mesh* mesh = SMDS_Mesh::_meshList[myMeshId]; + SMDS_UnstructuredGrid * grid = mesh->getGrid(); + vtkPoints *points = grid->GetPoints(); + points->InsertPoint(myVtkID, x, y, z); + SMDS_CellLinks *cellLinks = dynamic_cast(grid->GetCellLinks()); + assert(cellLinks); + if (myVtkID >= cellLinks->GetLinksSize()) + cellLinks->ResizeL(myVtkID+SMDS_Mesh::chunkSize); +} -SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z): - myX(x), myY(y), myZ(z), - myPosition(SMDS_SpacePosition::originSpacePosition()) +SMDS_MeshNode::~SMDS_MeshNode() { + nbNodes--; + if ( myPosition && myPosition != SMDS_SpacePosition::originSpacePosition() ) + delete myPosition, myPosition = 0; } //======================================================================= @@ -49,14 +89,10 @@ SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z): void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent) { - NCollection_List::Iterator it(myInverseElements); - while (it.More()) { - const SMDS_MeshElement* elem = it.Value(); - if (elem == parent) - myInverseElements.Remove(it); - else - it.Next(); - } + //MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID()); + const SMDS_MeshCell* cell = dynamic_cast(parent); + MYASSERT(cell); + SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId()); } //======================================================================= @@ -66,8 +102,8 @@ void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent) void SMDS_MeshNode::Print(ostream & OS) const { - OS << "Node <" << GetID() << "> : X = " << myX << " Y = " - << myY << " Z = " << myZ << endl; + OS << "Node <" << myID << "> : X = " << X() << " Y = " + << Y() << " Z = " << Z() << endl; } //======================================================================= @@ -77,7 +113,11 @@ void SMDS_MeshNode::Print(ostream & OS) const void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos) { - myPosition = aPos; + if ( myPosition && + myPosition != SMDS_SpacePosition::originSpacePosition() && + myPosition != aPos ) + delete myPosition; + myPosition = aPos; } //======================================================================= @@ -87,7 +127,7 @@ void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos) const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const { - return myPosition; + return myPosition; } //======================================================================= @@ -96,121 +136,186 @@ const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const */ //======================================================================= -class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator +class SMDS_MeshNode_MyInvIterator: public SMDS_ElemIterator { - NCollection_List::Iterator myIterator; - SMDSAbs_ElementType myType; - public: - SMDS_MeshNode_MyInvIterator(const NCollection_List& s, - SMDSAbs_ElementType type): - myIterator(s), myType(type) - {} +private: + SMDS_Mesh* myMesh; + vtkIdType* myCells; + int myNcells; + SMDSAbs_ElementType myType; + int iter; + vector cellList; + +public: + SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) : + myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) + { + //MESSAGE("SMDS_MeshNode_MyInvIterator : ncells " << myNcells); + cellList.clear(); + if (type == SMDSAbs_All) + for (int i = 0; i < ncells; i++) + cellList.push_back(cells[i]); + else for (int i = 0; i < ncells; i++) + { + int vtkId = cells[i]; + int smdsId = myMesh->fromVtkToSmds(vtkId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (elem->GetType() == type) + { + //MESSAGE("Add element vtkId " << vtkId << " " << elem->GetType()) + cellList.push_back(vtkId); + } + } + myCells = &cellList[0]; + myNcells = cellList.size(); + //MESSAGE("myNcells="<GetType() != myType) - myIterator.Next(); - } - return myIterator.More() != Standard_False; + //MESSAGE("iter " << iter << " ncells " << myNcells); + return (iter < myNcells); } const SMDS_MeshElement* next() { - const SMDS_MeshElement* current=myIterator.Value(); - myIterator.Next(); - return current; - } + int vtkId = myCells[iter]; + int smdsId = myMesh->fromVtkToSmds(vtkId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (!elem) + { + MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element"); + throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element"); + } + //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType()); + iter++; + return elem; + } }; SMDS_ElemIteratorPtr SMDS_MeshNode:: - GetInverseElementIterator(SMDSAbs_ElementType type) const + GetInverseElementIterator(SMDSAbs_ElementType type) const { - return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements,type)); + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + //MESSAGE("myID " << myID << " ncells " << l.ncells); + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); } // Same as GetInverseElementIterator but the create iterator only return // wanted type elements. class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator { - NCollection_List mySet; - NCollection_List::Iterator myIterator; +private: + SMDS_Mesh* myMesh; + vtkIdType* myCells; + int myNcells; + SMDSAbs_ElementType myType; + int iter; + vector myFiltCells; + public: - SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type, - const NCollection_List& s) + SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh, + vtkIdType* cells, + int ncells, + SMDSAbs_ElementType type): + myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) { - const SMDS_MeshElement * e; - bool toInsert; - NCollection_List::Iterator it(s); - for(; it.More(); it.Next()) - { - e=it.Value(); - switch(type) - { - case SMDSAbs_Edge: toInsert=true; break; - case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break; - case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break; - } - if(toInsert) mySet.Append(e); - } - myIterator.Init(mySet); + //MESSAGE("myNcells " << myNcells); + for (; iterfromVtkToSmds(vtkId); + //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (elem->GetType() == type) + myFiltCells.push_back((SMDS_MeshElement*)elem); + } + myNcells = myFiltCells.size(); + //MESSAGE("myNcells " << myNcells); + iter = 0; + //MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells); } bool more() { - return myIterator.More() != Standard_False; + return (iter< myNcells); } const SMDS_MeshElement* next() { - const SMDS_MeshElement* current=myIterator.Value(); - myIterator.Next(); - return current; + const SMDS_MeshElement* elem = myFiltCells[iter]; + iter++; + return elem; } }; SMDS_ElemIteratorPtr SMDS_MeshNode:: - elementsIterator(SMDSAbs_ElementType type) const + elementsIterator(SMDSAbs_ElementType type) const { if(type==SMDSAbs_Node) return SMDS_MeshElement::elementsIterator(SMDSAbs_Node); else - return SMDS_ElemIteratorPtr - (new SMDS_IteratorOfElements - (this,type, - SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(type, myInverseElements)))); + { + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); + } } int SMDS_MeshNode::NbNodes() const { - return 1; + return 1; +} + +double* SMDS_MeshNode::getCoord() const +{ + return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID); } double SMDS_MeshNode::X() const { - return myX; + double *coord = getCoord(); + return coord[0]; } double SMDS_MeshNode::Y() const { - return myY; + double *coord = getCoord(); + return coord[1]; } double SMDS_MeshNode::Z() const { - return myZ; + double *coord = getCoord(); + return coord[2]; } +//================================================================================ +/*! + * \brief thread safe getting coords + */ +void SMDS_MeshNode::GetXYZ(double xyz[3]) const +{ + return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID,xyz); +} + +//* resize the vtkPoints structure every SMDS_Mesh::chunkSize points void SMDS_MeshNode::setXYZ(double x, double y, double z) { - myX=x; - myY=y; - myZ=z; + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkPoints *points = mesh->getGrid()->GetPoints(); + points->InsertPoint(myVtkID, x, y, z); + mesh->adjustBoundingBox(x, y, z); + mesh->setMyModified(); } SMDSAbs_ElementType SMDS_MeshNode::GetType() const { - return SMDSAbs_Node; + return SMDSAbs_Node; +} + +vtkIdType SMDS_MeshNode::GetVtkType() const +{ + return VTK_VERTEX; } //======================================================================= @@ -219,13 +324,12 @@ SMDSAbs_ElementType SMDS_MeshNode::GetType() const //======================================================================= void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) { - NCollection_List::Iterator it(myInverseElements); - for (; it.More(); it.Next()) { - const SMDS_MeshElement* elem = it.Value(); - if (elem == ME) - return; - } - myInverseElements.Append(ME); + const SMDS_MeshCell *cell = dynamic_cast (ME); + assert(cell); + SMDS_UnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkCellLinks *Links = grid->GetCellLinks(); + Links->ResizeCellList(myVtkID, 1); + Links->AddCellReference(cell->getVtkId(), myVtkID); } //======================================================================= @@ -234,12 +338,13 @@ void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) //======================================================================= void SMDS_MeshNode::ClearInverseElements() { - myInverseElements.Clear(); + SMDS_Mesh::_meshList[myMeshId]->getGrid()->ResizeCellList(myVtkID, 0); } bool SMDS_MeshNode::emptyInverseElements() { - return myInverseElements.IsEmpty() != Standard_False; + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + return (l.ncells == 0); } //================================================================================ @@ -250,13 +355,19 @@ bool SMDS_MeshNode::emptyInverseElements() int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const { + vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); + if ( type == SMDSAbs_All ) - return myInverseElements.Extent(); + return l.ncells; + int nb = 0; - NCollection_List::Iterator it( myInverseElements ); - for ( ; it.More(); it.Next() ) - if ( it.Value()->GetType() == type ) - nb++; + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + for (int i=0; iFindElement(mesh->fromVtkToSmds(l.cells[i])); + if (elem->GetType() == type) + nb++; + } return nb; } @@ -265,14 +376,14 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const /////////////////////////////////////////////////////////////////////////////// bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2) { - return e1.GetID() +#include "ObjectPool.hxx" -class SMDS_EXPORT SMDS_MeshNode:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshNode: public SMDS_MeshElement { +public: + friend class SMESHDS_Mesh; + friend class SMDS_Mesh; + friend class ObjectPool; + friend class SMDS_VtkFace; + + void Print(std::ostream & OS) const; + double X() const; // ! NOT thread safe methods ! + double Y() const; + double Z() const; + void GetXYZ(double xyx[3]) const; // thread safe getting coords + SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; + int NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) const; + const SMDS_PositionPtr& GetPosition() const; + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Node;} + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_NONE; } + virtual int NbNodes() const; + + void SetPosition(const SMDS_PositionPtr& aPos); + void setXYZ(double x, double y, double z); - public: - SMDS_MeshNode(double x, double y, double z); - void Print(std::ostream & OS) const; - double X() const; - double Y() const; - double Z() const; - void AddInverseElement(const SMDS_MeshElement * ME); - void RemoveInverseElement(const SMDS_MeshElement * parent); - void ClearInverseElements(); - bool emptyInverseElements(); - SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; - int NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) const; - void SetPosition(const SMDS_PositionPtr& aPos); - const SMDS_PositionPtr& GetPosition() const; - SMDSAbs_ElementType GetType() const; - int NbNodes() const; - void setXYZ(double x, double y, double z); - friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2); + static int nbNodes; - /*! - * \brief Return node by its index - * \param ind - node index - * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range - */ - virtual const SMDS_MeshNode* GetNode(const int) const { return this; } +protected: + SMDS_MeshNode(); + SMDS_MeshNode(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0); + virtual ~SMDS_MeshNode(); + void init(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0); + inline void setVtkId(int vtkId) { myVtkID = vtkId; }; + double* getCoord() const; + void AddInverseElement(const SMDS_MeshElement * ME); + void RemoveInverseElement(const SMDS_MeshElement * parent); + void ClearInverseElements(); + bool emptyInverseElements(); - protected: - SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; - private: - double myX, myY, myZ; - SMDS_PositionPtr myPosition; - NCollection_List myInverseElements; +private: + SMDS_PositionPtr myPosition; }; #endif diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.cxx b/src/SMDS/SMDS_MeshNodeIDFactory.cxx new file mode 100644 index 000000000..0884a5b98 --- /dev/null +++ b/src/SMDS/SMDS_MeshNodeIDFactory.cxx @@ -0,0 +1,149 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMDS_MeshNodeIDFactory.cxx +// Author : Jean-Michel BOULCOURT +// Module : SMESH +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + +#include "SMDS_MeshNodeIDFactory.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_Mesh.hxx" + +#include +#include + +using namespace std; + +//======================================================================= +//function : SMDS_MeshNodeIDFactory +//purpose : +//======================================================================= +SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory() : + SMDS_MeshIDFactory(), myMin(0), myMax(0) +{ +} + +//======================================================================= +//function : BindID +//purpose : +//======================================================================= +bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem) +{ + updateMinMax(ID); + return true; +} + +//======================================================================= +//function : MeshElement +//purpose : +//======================================================================= +SMDS_MeshElement* SMDS_MeshNodeIDFactory::MeshElement(int ID) +{ + // commented since myMax can be 0 after ReleaseID() +// if ((ID < 1) || (ID > myMax)) +// return NULL; + const SMDS_MeshElement* elem = GetMesh()->FindNode(ID); + return (SMDS_MeshElement*) (elem); +} + +//======================================================================= +//function : GetFreeID +//purpose : +//======================================================================= +int SMDS_MeshNodeIDFactory::GetFreeID() +{ + int ID; + do { + ID = SMDS_MeshIDFactory::GetFreeID(); + } while ( MeshElement( ID )); + return ID; +} + +//======================================================================= +//function : ReleaseID +//purpose : +//======================================================================= +void SMDS_MeshNodeIDFactory::ReleaseID(const int ID, int vtkId) +{ + SMDS_MeshIDFactory::ReleaseID(ID); + myMesh->setMyModified(); + if (ID == myMax) + myMax = 0; // --- force updateMinMax + if (ID == myMin) + myMax = 0; // --- force updateMinMax +} + +//======================================================================= +//function : GetMaxID +//purpose : +//======================================================================= + +int SMDS_MeshNodeIDFactory::GetMaxID() const +{ + if (myMax == 0) + updateMinMax(); + return myMax; +} + +//======================================================================= +//function : GetMinID +//purpose : +//======================================================================= + +int SMDS_MeshNodeIDFactory::GetMinID() const +{ + if (myMax == 0) + updateMinMax(); + return myMin; +} + +//======================================================================= +//function : updateMinMax +//purpose : +//======================================================================= + +void SMDS_MeshNodeIDFactory::updateMinMax() const +{ + myMesh->updateNodeMinMax(); + myMin = myMesh->MinNodeID(); + myMax = myMesh->MaxNodeID(); +} + +SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const +{ + return myMesh->elementsIterator(SMDSAbs_Node); +} + +void SMDS_MeshNodeIDFactory::Clear() +{ + myMin = myMax = 0; + SMDS_MeshIDFactory::Clear(); +} + +void SMDS_MeshNodeIDFactory::emptyPool(int maxId) +{ + SMDS_MeshIDFactory::emptyPool(maxId); + myMax = maxId; +} diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.hxx b/src/SMDS/SMDS_MeshNodeIDFactory.hxx new file mode 100644 index 000000000..07c0341e1 --- /dev/null +++ b/src/SMDS/SMDS_MeshNodeIDFactory.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMDS_MeshElementIDFactory.hxx +// Module : SMESH +// +#ifndef _SMDS_MeshNodeIDFactory_HeaderFile +#define _SMDS_MeshNodeIDFactory_HeaderFile + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshIDFactory.hxx" +#include "SMDS_ElemIterator.hxx" + +#include + +class SMDS_MeshElement; + +class SMDS_EXPORT SMDS_MeshNodeIDFactory: public SMDS_MeshIDFactory +{ +public: + SMDS_MeshNodeIDFactory(); + bool BindID(int ID, SMDS_MeshElement * elem); + SMDS_MeshElement * MeshElement(int ID); + virtual int GetFreeID(); + virtual void ReleaseID(int ID, int vtkId = -1); + int GetMaxID() const; + int GetMinID() const; + SMDS_ElemIteratorPtr elementsIterator() const; + virtual void Clear(); + virtual void emptyPool(int maxId); + +protected: + void updateMinMax() const; + void updateMinMax(int id) const + { + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + + mutable int myMin, myMax; + +}; + +#endif diff --git a/src/SMDS/SMDS_MeshObject.cxx b/src/SMDS/SMDS_MeshObject.cxx index b023c73e9..f880cff6c 100644 --- a/src/SMDS/SMDS_MeshObject.cxx +++ b/src/SMDS/SMDS_MeshObject.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshObject.cxx // Author : Jean-Michel BOULCOURT diff --git a/src/SMDS/SMDS_MeshObject.hxx b/src/SMDS/SMDS_MeshObject.hxx index 8004fcbf9..c3bd07de6 100644 --- a/src/SMDS/SMDS_MeshObject.hxx +++ b/src/SMDS/SMDS_MeshObject.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshObject.hxx // Module : SMESH diff --git a/src/SMDS/SMDS_MeshVolume.cxx b/src/SMDS/SMDS_MeshVolume.cxx index 574b5b0ff..7cf865a32 100644 --- a/src/SMDS/SMDS_MeshVolume.cxx +++ b/src/SMDS/SMDS_MeshVolume.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshVolume.cxx // Author : Jean-Michel BOULCOURT @@ -32,6 +33,10 @@ SMDSAbs_ElementType SMDS_MeshVolume::GetType() const { - return SMDSAbs_Volume; + return SMDSAbs_Volume; } +vtkIdType SMDS_MeshVolume::GetVtkType() const +{ + return VTK_CONVEX_POINT_SET; // --- must be reimplemented in derived classes +} diff --git a/src/SMDS/SMDS_MeshVolume.hxx b/src/SMDS/SMDS_MeshVolume.hxx index aa3498eac..1f928c610 100644 --- a/src/SMDS/SMDS_MeshVolume.hxx +++ b/src/SMDS/SMDS_MeshVolume.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshVolume.hxx // Module : SMESH @@ -28,12 +29,13 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshCell.hxx" -class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshElement +class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshCell { - + public: - SMDSAbs_ElementType GetType() const; + SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; }; #endif diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx index 282256c7f..4738a0220 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifdef _MSC_VER @@ -42,6 +43,7 @@ using namespace std; SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes (std::vector nodes) { + //MESSAGE("******************************************** SMDS_PolygonalFaceOfNodes"); myNodes = nodes; } @@ -154,7 +156,7 @@ public: 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 )); + SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNodeWrap( i + 1 )); if ( edge ) myElems.push_back( edge ); } @@ -191,11 +193,8 @@ SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ const SMDS_MeshNode* SMDS_PolygonalFaceOfNodes::GetNode(const int ind) const { return myNodes[ WrappedIndex( ind )]; } - diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx index 3c9f9a508..1586f2514 100644 --- a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx +++ b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifndef _SMDS_PolygonalFaceOfNodes_HeaderFile @@ -40,6 +41,7 @@ class SMDS_EXPORT SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace SMDS_PolygonalFaceOfNodes (std::vector nodes); virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Polygon; } virtual bool IsPoly() const { return true; }; bool ChangeNodes (std::vector nodes); @@ -58,8 +60,6 @@ class SMDS_EXPORT SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ virtual const SMDS_MeshNode* GetNode(const int ind) const; diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx index 4b20720f6..b030440ec 100644 --- a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx +++ b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifdef _MSC_VER @@ -44,6 +45,7 @@ SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes vector quantities) : SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL) { + //MESSAGE("****************************************** SMDS_PolyhedralVolumeOfNodes"); ChangeNodes(nodes, quantities); } @@ -259,5 +261,5 @@ SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::uniqueNodesIterator() const const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetNode(const int ind) const { - return myNodesByFaces[ WrappedIndex( ind )]; + return myNodesByFaces[ ind ]; } diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx index 9cddb1f02..237c92571 100644 --- a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx +++ b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_PolyhedralVolumeOfNodes.hxx // Module : SMESH @@ -38,7 +39,8 @@ class SMDS_EXPORT SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes //virtual ~SMDS_PolyhedralVolumeOfNodes(); - virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Polyhedra; } virtual bool IsPoly() const { return true; }; bool ChangeNodes (const std::vector & nodes, diff --git a/src/SMDS/SMDS_Position.cxx b/src/SMDS/SMDS_Position.cxx index 46b63e1f8..939b50fe9 100644 --- a/src/SMDS/SMDS_Position.cxx +++ b/src/SMDS/SMDS_Position.cxx @@ -1,58 +1,41 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_Position.cxx // Author : Jean-Michel BOULCOURT // Module : SMESH // #include "SMDS_Position.hxx" +#include "utilities.h" //======================================================================= //function : SMDS_Position //purpose : //======================================================================= -SMDS_Position::SMDS_Position(int aShapeId) :myShapeId(aShapeId) -{ -} - -//======================================================================= -//function : SetShapeId -//purpose : -//======================================================================= - -void SMDS_Position::SetShapeId(int aShapeId) -{ - myShapeId = aShapeId; -} - -//======================================================================= -//function : GetShapeId -//purpose : -//======================================================================= - -int SMDS_Position::GetShapeId() const +SMDS_Position::SMDS_Position() { - return myShapeId; + //MESSAGE("########################## SMDS_Position "); } //======================================================================= diff --git a/src/SMDS/SMDS_Position.hxx b/src/SMDS/SMDS_Position.hxx index 687bc098e..3b4530e1d 100644 --- a/src/SMDS/SMDS_Position.hxx +++ b/src/SMDS/SMDS_Position.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_Position.hxx // Module : SMESH @@ -32,24 +33,19 @@ #include class SMDS_Position; -typedef boost::shared_ptr SMDS_PositionPtr; +//typedef boost::shared_ptr SMDS_PositionPtr; +typedef SMDS_Position* SMDS_PositionPtr; class SMDS_EXPORT SMDS_Position { public: - const virtual double * Coords() const = 0; - virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0; - virtual int GetDim() const; - void SetShapeId(int aShapeId); - int GetShapeId() const; - virtual ~SMDS_Position() {} + virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0; + virtual int GetDim() const; + virtual ~SMDS_Position() {} protected: - SMDS_Position(int aShapeId); - - private: - int myShapeId; + SMDS_Position(); }; diff --git a/src/SMDS/SMDS_QuadraticEdge.cxx b/src/SMDS/SMDS_QuadraticEdge.cxx index d314cf281..78a3bc1f0 100644 --- a/src/SMDS/SMDS_QuadraticEdge.cxx +++ b/src/SMDS/SMDS_QuadraticEdge.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File: SMDS_QuadraticEdge.cxx // Created: 16.01.06 16:25:42 @@ -29,6 +30,7 @@ #include "SMDS_SetIterator.hxx" #include "SMDS_IteratorOfElements.hxx" #include "SMDS_MeshNode.hxx" +#include "utilities.h" using namespace std; @@ -40,8 +42,9 @@ using namespace std; SMDS_QuadraticEdge::SMDS_QuadraticEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, const SMDS_MeshNode * node12) - :SMDS_MeshEdge(node1,node2) -{ + :SMDS_LinearEdge(node1,node2) +{ + //MESSAGE("******************************************************* SMDS_QuadraticEdge"); myNodes[2]=node12; } @@ -182,4 +185,3 @@ SMDS_ElemIteratorPtr SMDS_QuadraticEdge::elementsIterator(SMDSAbs_ElementType ty (this,type, SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes)))); } } - diff --git a/src/SMDS/SMDS_QuadraticEdge.hxx b/src/SMDS/SMDS_QuadraticEdge.hxx index 83877d6a1..2a0d0bc40 100644 --- a/src/SMDS/SMDS_QuadraticEdge.hxx +++ b/src/SMDS/SMDS_QuadraticEdge.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_QuadraticEdge.hxx // Module : SMESH @@ -28,10 +29,10 @@ #include "SMESH_SMDS.hxx" -#include "SMDS_MeshEdge.hxx" +#include "SMDS_LinearEdge.hxx" #include -class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_MeshEdge +class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_LinearEdge { public: @@ -47,6 +48,8 @@ public: int NbNodes() const; + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Quad_Edge; } + virtual bool IsQuadratic() const { return true; } virtual bool IsMediumNode(const SMDS_MeshNode* node) const; diff --git a/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx index b981bd92f..6a70243c0 100644 --- a/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx +++ b/src/SMDS/SMDS_QuadraticFaceOfNodes.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File: SMDS_QuadraticFaceOfNodes.cxx // Created: 16.01.06 17:12:58 @@ -48,6 +49,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31) { + //MESSAGE("********************************************** SMDS_QuadraticFaceOfNodes 1"); myNodes.resize( 6 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -72,6 +74,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1, const SMDS_MeshNode * n34, const SMDS_MeshNode * n41) { + //MESSAGE("********************************************* SMDS_QuadraticFaceOfNodes 2"); myNodes.resize( 8 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -255,7 +258,7 @@ public: _MyEdgeIterator(const SMDS_QuadraticFaceOfNodes* face):myIndex(0) { myElems.reserve( face->NbNodes() ); SMDS_ElemIteratorPtr nIt = face->interlacedNodesElemIterator(); - const SMDS_MeshNode* n0 = face->GetNode( -1 ); + const SMDS_MeshNode* n0 = face->GetNodeWrap( -1 ); while ( nIt->more() ) { const SMDS_MeshNode* n1 = static_cast( nIt->next() ); const SMDS_MeshElement* edge = SMDS_Mesh::FindEdge( n0, n1 ); @@ -300,11 +303,13 @@ SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::elementsIterator * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ const SMDS_MeshNode* SMDS_QuadraticFaceOfNodes::GetNode(const int ind) const { - return myNodes[ WrappedIndex( ind )]; + return myNodes[ ind ]; } +SMDSAbs_EntityType SMDS_QuadraticFaceOfNodes::GetEntityType() const +{ + return NbNodes() == 6 ? SMDSEntity_Quad_Triangle : SMDSEntity_Quad_Quadrangle; +} diff --git a/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx b/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx index f4284918a..21c2a7e6b 100644 --- a/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx +++ b/src/SMDS/SMDS_QuadraticFaceOfNodes.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_QuadraticVolumeOfNodes.hxx // Module : SMESH @@ -49,6 +50,7 @@ public: const SMDS_MeshNode * n34, const SMDS_MeshNode * n41); + virtual SMDSAbs_EntityType GetEntityType() const; virtual bool IsQuadratic() const { return true; } virtual bool IsMediumNode(const SMDS_MeshNode* node) const; @@ -70,8 +72,6 @@ public: * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ virtual const SMDS_MeshNode* GetNode(const int ind) const; diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx index 4a0ae2e7e..579b3e420 100644 --- a/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File: SMDS_QuadraticVolumeOfNodes.cxx // Created: 17.01.06 09:46:11 @@ -53,6 +54,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n24, const SMDS_MeshNode * n34) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 10 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -87,6 +89,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n35, const SMDS_MeshNode * n45) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 13 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -126,6 +129,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n25, const SMDS_MeshNode * n36) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 15 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -172,6 +176,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes const SMDS_MeshNode * n37, const SMDS_MeshNode * n48) { + //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes"); myNodes.resize( 20 ); myNodes[ 0 ] = n1; myNodes[ 1 ] = n2; @@ -362,11 +367,22 @@ SMDS_ElemIteratorPtr SMDS_QuadraticVolumeOfNodes::elementsIterator * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ const SMDS_MeshNode* SMDS_QuadraticVolumeOfNodes::GetNode(const int ind) const { - return myNodes[ WrappedIndex( ind )]; + return myNodes[ ind ]; } +SMDSAbs_EntityType SMDS_QuadraticVolumeOfNodes::GetEntityType() const +{ + SMDSAbs_EntityType aType = SMDSEntity_Quad_Tetra; + switch(NbNodes()) + { + case 10: aType = SMDSEntity_Quad_Tetra; break; + case 13: aType = SMDSEntity_Quad_Pyramid; break; + case 15: aType = SMDSEntity_Quad_Penta; break; + case 20: + default: aType = SMDSEntity_Quad_Hexa; break; + } + return aType; +} diff --git a/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx b/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx index 34ce542a6..80312496c 100644 --- a/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx +++ b/src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_QuadraticVolumeOfNodes.hxx // Module : SMESH @@ -99,6 +100,7 @@ public: const SMDS_MeshNode * n37, const SMDS_MeshNode * n48); + virtual SMDSAbs_EntityType GetEntityType() const; virtual bool IsQuadratic() const { return true; } virtual bool IsMediumNode(const SMDS_MeshNode* node) const; @@ -116,8 +118,6 @@ public: * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ virtual const SMDS_MeshNode* GetNode(const int ind) const; diff --git a/src/SMDS/SMDS_SetIterator.hxx b/src/SMDS/SMDS_SetIterator.hxx index e76ea8ce5..a200bdd9f 100644 --- a/src/SMDS/SMDS_SetIterator.hxx +++ b/src/SMDS/SMDS_SetIterator.hxx @@ -1,27 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_SetIterator.hxx -// Created : Mon Feb 27 16:57:43 2006 +// Created : Feb 27 2006 // Author : Edward AGAPOV (eap) // #ifndef SMDS_SetIterator_HeaderFile @@ -29,12 +30,12 @@ #include "SMDS_Iterator.hxx" -/////////////////////////////////////////////////////////////////////////////// -/// Accessors to value pointed by iterator -/////////////////////////////////////////////////////////////////////////////// - namespace SMDS { + /////////////////////////////////////////////////////////////////////////////// + /// Accessors to value pointed by iterator + /////////////////////////////////////////////////////////////////////////////// + template struct SimpleAccessor { static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) *it; } @@ -49,6 +50,22 @@ namespace SMDS { struct ValueAccessor { static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) it->second; } }; + + /////////////////////////////////////////////////////////////////////////////// + /// Filters of value pointed by iterator + /////////////////////////////////////////////////////////////////////////////// + + template + struct PassAllValueFilter + { + bool operator()(const VALUE& t ) { return true; } + }; + + template + struct NonNullFilter + { + bool operator()(const VALUE& t ) { return bool( t ); } + }; } /////////////////////////////////////////////////////////////////////////////// @@ -60,26 +77,43 @@ namespace SMDS { template > + typename ACCESOR=SMDS::SimpleAccessor, + typename VALUE_FILTER=SMDS::PassAllValueFilter > class SMDS_SetIterator : public SMDS_Iterator { protected: VALUE_SET_ITERATOR _beg, _end; + VALUE_FILTER _filter; public: SMDS_SetIterator(const VALUE_SET_ITERATOR & begin, - const VALUE_SET_ITERATOR & end) - { init ( begin, end ); } + const VALUE_SET_ITERATOR & end, + const VALUE_FILTER& filter=VALUE_FILTER()) + { init ( begin, end, filter ); } /// Initialization virtual void init(const VALUE_SET_ITERATOR & begin, - const VALUE_SET_ITERATOR & end) - { _beg = begin; _end = end; } - - /// Return true if and only if there are other object in this iterator - virtual bool more() { return _beg != _end; } - + const VALUE_SET_ITERATOR & end, + const VALUE_FILTER& filter=VALUE_FILTER()) + { + _beg = begin; + _end = end; + _filter = filter; + if ( more() && !_filter( ACCESOR::value( _beg ))) + next(); + } + /// Return true iff there are other object in this iterator + virtual bool more() + { + return _beg != _end; + } /// Return the current object and step to the next one - virtual VALUE next() { return ACCESOR::value( _beg++ ); } + virtual VALUE next() + { + VALUE ret = ACCESOR::value( _beg++ ); + while ( more() && !_filter( ACCESOR::value( _beg ))) + ++_beg; + return ret; + } }; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/SMDS/SMDS_SpacePosition.cxx b/src/SMDS/SMDS_SpacePosition.cxx index 09532f347..422de6a3f 100644 --- a/src/SMDS/SMDS_SpacePosition.cxx +++ b/src/SMDS/SMDS_SpacePosition.cxx @@ -1,58 +1,45 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_SpacePosition.cxx // Author : Jean-Michel BOULCOURT // Module : SMESH // + #include "SMDS_SpacePosition.hxx" -//======================================================================= -//function : SMDS_SpacePosition -//purpose : -//======================================================================= +SMDS_SpacePosition* SMDS_SpacePosition::_originPosition = new SMDS_SpacePosition(); -SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z): - SMDS_Position(0) +SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z) { - myCoords[0]=x; - myCoords[1]=y; - myCoords[2]=z; } -/** -*/ SMDS_TypeOfPosition SMDS_SpacePosition::GetTypeOfPosition() const { - return SMDS_TOP_3DSPACE; -} - -const double * SMDS_SpacePosition::Coords() const -{ - return myCoords; + return SMDS_TOP_3DSPACE; } SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition() { - static SMDS_PositionPtr staticpos (new SMDS_SpacePosition()); - return staticpos; + return _originPosition; } diff --git a/src/SMDS/SMDS_SpacePosition.hxx b/src/SMDS/SMDS_SpacePosition.hxx index f80f3210a..1313ed5cc 100644 --- a/src/SMDS/SMDS_SpacePosition.hxx +++ b/src/SMDS/SMDS_SpacePosition.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_SpacePosition.hxx // Module : SMESH @@ -33,14 +34,12 @@ class SMDS_EXPORT SMDS_SpacePosition:public SMDS_Position { - public: - SMDS_SpacePosition(double x=0, double y=0, double z=0); - const virtual double * Coords() const; - virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const; - inline void SetCoords(const double x, const double y, const double z); - static SMDS_PositionPtr originSpacePosition(); - private: - double myCoords[3]; +public: + SMDS_SpacePosition(double x=0, double y=0, double z=0); + virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const; + static SMDS_PositionPtr originSpacePosition(); +private: + static SMDS_SpacePosition* _originPosition; }; #endif diff --git a/src/SMDS/SMDS_StdIterator.hxx b/src/SMDS/SMDS_StdIterator.hxx new file mode 100644 index 000000000..f09647f1f --- /dev/null +++ b/src/SMDS/SMDS_StdIterator.hxx @@ -0,0 +1,80 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_StdIterator.hxx +// Created : Fri Feb 5 11:03:46 2010 +// Author : Edward AGAPOV (eap) +// +#ifndef __SMDS_StdIterator_HXX__ +#define __SMDS_StdIterator_HXX__ + + +/////////////////////////////////////////////////////////////////////////////// +/*! + * \brief Wrapper over pointer to SMDS_Iterator, like SMDS_ElemIteratorPtr, enabling + * its usage in std-like way: provide operators ++, *, etc. + */ +/////////////////////////////////////////////////////////////////////////////// + +template > +class SMDS_StdIterator : public std::iterator< std::input_iterator_tag, VALUE > +{ + VALUE _value; + PtrSMDSIterator _piterator; + EqualVALUE _EqualVALUE; + +public: + typedef SMDS_StdIterator _Self; + + // constructor to use as return from begin() + SMDS_StdIterator( PtrSMDSIterator pItr ) + : _value( pItr->more() ? (VALUE)(pItr->next()) : 0 ), _piterator(pItr) + {} + // constructor to use as return from end() + SMDS_StdIterator(): _value( 0 ) + {} + + /// Return the current object + VALUE operator*() const + { return _value; } + + // Step to the next one + _Self& + operator++() + { _value = _piterator->more() ? VALUE( _piterator->next()) : 0; return *this; } + + // Step to the next one + _Self + operator++(int) + { _Self res = *this; _value = _piterator->more() ? VALUE( _piterator->next()) : 0; return res; } + + // Test of end + bool + operator!=(const _Self& __x) const + { return !_EqualVALUE( _value, __x._value); } + + // Test of equality + bool + operator==(const _Self& __x) const + { return _EqualVALUE( _value, __x._value); } + +}; + +#endif diff --git a/src/SMDS/SMDS_TypeOfPosition.hxx b/src/SMDS/SMDS_TypeOfPosition.hxx index da5b39c48..c1c7249b4 100644 --- a/src/SMDS/SMDS_TypeOfPosition.hxx +++ b/src/SMDS/SMDS_TypeOfPosition.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_TypeOfPosition.hxx // Module : SMESH @@ -28,11 +29,11 @@ enum SMDS_TypeOfPosition // Value is equal to shape dimention { - SMDS_TOP_UNSPEC = -1, - SMDS_TOP_VERTEX = 0, - SMDS_TOP_EDGE = 1, - SMDS_TOP_FACE = 2, - SMDS_TOP_3DSPACE = 3 + SMDS_TOP_UNSPEC = -1, + SMDS_TOP_VERTEX = 0, + SMDS_TOP_EDGE = 1, + SMDS_TOP_FACE = 2, + SMDS_TOP_3DSPACE = 3 }; #endif diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx new file mode 100644 index 000000000..0d9b1e6c3 --- /dev/null +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -0,0 +1,1145 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#define CHRONODEF +#include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_MeshInfo.hxx" +#include "SMDS_Downward.hxx" +#include "SMDS_MeshVolume.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace std; + +SMDS_CellLinks* SMDS_CellLinks::New() +{ + MESSAGE("SMDS_CellLinks::New"); + return new SMDS_CellLinks(); +} + +vtkCellLinks::Link* SMDS_CellLinks::ResizeL(vtkIdType sz) +{ + return vtkCellLinks::Resize(sz); +} + +vtkIdType SMDS_CellLinks::GetLinksSize() +{ + return this->Size; +} + +SMDS_CellLinks::SMDS_CellLinks() : + vtkCellLinks() +{ +} + +SMDS_CellLinks::~SMDS_CellLinks() +{ +} + +SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New() +{ + MESSAGE("SMDS_UnstructuredGrid::New"); + return new SMDS_UnstructuredGrid(); +} + +SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() : + vtkUnstructuredGrid() +{ + _cellIdToDownId.clear(); + _downTypes.clear(); + _downArray.clear(); + _mesh = 0; +} + +SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid() +{ +} + +unsigned long SMDS_UnstructuredGrid::GetMTime() +{ + unsigned long mtime = vtkUnstructuredGrid::GetMTime(); + MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime); + return mtime; +} + +void SMDS_UnstructuredGrid::Update() +{ + MESSAGE("SMDS_UnstructuredGrid::Update"); + return vtkUnstructuredGrid::Update(); +} + +void SMDS_UnstructuredGrid::UpdateInformation() +{ + MESSAGE("SMDS_UnstructuredGrid::UpdateInformation"); + return vtkUnstructuredGrid::UpdateInformation(); +} + +vtkPoints* SMDS_UnstructuredGrid::GetPoints() +{ + // TODO erreur incomprehensible de la macro vtk GetPoints apparue avec la version paraview de fin aout 2010 + //MESSAGE("*********************** SMDS_UnstructuredGrid::GetPoints " << this->Points << " " << vtkUnstructuredGrid::GetPoints()); + return this->Points; +} + +//#ifdef VTK_HAVE_POLYHEDRON +int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *pts) +{ + if (type != VTK_POLYHEDRON) + return vtkUnstructuredGrid::InsertNextLinkedCell(type, npts, pts); + + // --- type = VTK_POLYHEDRON + //MESSAGE("InsertNextLinkedCell VTK_POLYHEDRON"); + int cellid = this->InsertNextCell(type, npts, pts); + + set setOfNodes; + setOfNodes.clear(); + int nbfaces = npts; + int i = 0; + for (int nf = 0; nf < nbfaces; nf++) + { + int nbnodes = pts[i]; + i++; + for (int k = 0; k < nbnodes; k++) + { + //MESSAGE(" cell " << cellid << " face " << nf << " node " << pts[i]); + setOfNodes.insert(pts[i]); + i++; + } + } + + set::iterator it = setOfNodes.begin(); + for (; it != setOfNodes.end(); ++it) + { + //MESSAGE("reverse link for node " << *it << " cell " << cellid); + this->Links->ResizeCellList(*it, 1); + this->Links->AddCellReference(cellid, *it); + } + + return cellid; +} +//#endif + +void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) +{ + _mesh = mesh; +} + +void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int newNodeSize, + std::vector& idCellsOldToNew, int newCellSize) +{ + MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);CHRONO(1); + int alreadyCopied = 0; + + // --- if newNodeSize, create a new compacted vtkPoints + + vtkPoints *newPoints = vtkPoints::New(); + newPoints->SetDataType(VTK_DOUBLE); + newPoints->SetNumberOfPoints(newNodeSize); + if (newNodeSize) + { + MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize); + // rnv: to fix bug "21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion" + // using double type for storing coordinates of nodes instead float. + int oldNodeSize = idNodesOldToNew.size(); + + int i = 0; + while ( i < oldNodeSize ) + { + // skip a hole if any + while ( i < oldNodeSize && idNodesOldToNew[i] < 0 ) + ++i; + int startBloc = i; + // look for a block end + while ( i < oldNodeSize && idNodesOldToNew[i] >= 0 ) + ++i; + int endBloc = i; + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); + } + newPoints->Squeeze(); + } + + // --- create new compacted Connectivity, Locations and Types + + int oldCellSize = this->Types->GetNumberOfTuples(); + + vtkCellArray *newConnectivity = vtkCellArray::New(); + newConnectivity->Initialize(); + int oldCellDataSize = this->Connectivity->GetData()->GetSize(); + newConnectivity->Allocate(oldCellDataSize); + MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize); + + vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New(); + newTypes->Initialize(); + newTypes->SetNumberOfValues(newCellSize); + + vtkIdTypeArray *newLocations = vtkIdTypeArray::New(); + newLocations->Initialize(); + newLocations->SetNumberOfValues(newCellSize); + + // TODO some polyhedron may be huge (only in some tests) + vtkIdType tmpid[NBMAXNODESINCELL]; + vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell + + alreadyCopied = 0; + int i = 0; + while ( i < oldCellSize ) + { + // skip a hole if any + while ( i < oldCellSize && this->Types->GetValue(i) == VTK_EMPTY_CELL ) + ++i; + int startBloc = i; + // look for a block end + while ( i < oldCellSize && this->Types->GetValue(i) != VTK_EMPTY_CELL ) + ++i; + int endBloc = i; + if ( endBloc > startBloc ) + copyBloc(newTypes, + idCellsOldToNew, idNodesOldToNew, + newConnectivity, newLocations, + pointsCell, alreadyCopied, + startBloc, endBloc); + } + newConnectivity->Squeeze(); + + if (1/*newNodeSize*/) + { + MESSAGE("------- newNodeSize, setPoints"); + this->SetPoints(newPoints); + MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints()); + } + + if (vtkDoubleArray* diameters = + vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )) // Balls + { + for (int oldCellID = 0; oldCellID < oldCellSize; oldCellID++) + { + if (this->Types->GetValue(oldCellID) == VTK_EMPTY_CELL) + continue; + int newCellId = idCellsOldToNew[ oldCellID ]; + if (newTypes->GetValue(newCellId) == VTK_POLY_VERTEX) + diameters->SetValue( newCellId, diameters->GetValue( oldCellID )); + } + } + + if (this->FaceLocations) + { + vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New(); + newFaceLocations->Initialize(); + newFaceLocations->Allocate(newTypes->GetSize()); + vtkIdTypeArray *newFaces = vtkIdTypeArray::New(); + newFaces->Initialize(); + newFaces->Allocate(this->Faces->GetSize()); + for (int i = 0; i < oldCellSize; i++) + { + if (this->Types->GetValue(i) == VTK_EMPTY_CELL) + continue; + int newCellId = idCellsOldToNew[i]; + if (newTypes->GetValue(newCellId) == VTK_POLYHEDRON) + { + newFaceLocations->InsertNextValue(newFaces->GetMaxId()+1); + int oldFaceLoc = this->FaceLocations->GetValue(i); + int nCellFaces = this->Faces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(nCellFaces); + for (int n=0; nFaces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(nptsInFace); + for (int k=0; kFaces->GetValue(oldFaceLoc++); + newFaces->InsertNextValue(idNodesOldToNew[oldpt]); + } + } + } + else + { + newFaceLocations->InsertNextValue(-1); + } + } + newFaceLocations->Squeeze(); + newFaces->Squeeze(); + newFaceLocations->Register(this); + newFaces->Register(this); + this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces); + newFaceLocations->Delete(); + newFaces->Delete(); + } + else + { + this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces); + } + + newPoints->Delete(); + newTypes->Delete(); + newLocations->Delete(); + newConnectivity->Delete(); + this->BuildLinks(); +} + +void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector& idNodesOldToNew, int& alreadyCopied, + int start, int end) +{ + MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); + void *target = newPoints->GetVoidPointer(3 * alreadyCopied); + void *source = this->Points->GetVoidPointer(3 * start); + int nbPoints = end - start; + if (nbPoints > 0) + { + memcpy(target, source, 3 * sizeof(double) * nbPoints); + for (int j = start; j < end; j++) + idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId + } +} + +void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, + std::vector& idCellsOldToNew, + std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, + vtkIdTypeArray* newLocations, + vtkIdType* pointsCell, + int& alreadyCopied, + int start, + int end) +{ + MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); + for (int j = start; j < end; j++) + { + newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); + idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId + vtkIdType oldLoc = this->Locations->GetValue(j); + vtkIdType nbpts; + vtkIdType *oldPtsCell = 0; + this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); + assert(nbpts < NBMAXNODESINCELL); + //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts ); + for (int l = 0; l < nbpts; l++) + { + int oldval = oldPtsCell[l]; + pointsCell[l] = idNodesOldToNew[oldval]; + //MESSAGE(" " << oldval << " " << pointsCell[l]); + } + /*int newcnt = */newConnectivity->InsertNextCell(nbpts, pointsCell); + int newLoc = newConnectivity->GetInsertLocation(nbpts); + //MESSAGE(newcnt << " " << newLoc); + newLocations->SetValue(alreadyCopied, newLoc); + alreadyCopied++; + } +} + +int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId) +{ + if((vtkCellId < 0) || (vtkCellId >= _cellIdToDownId.size())) + { + //MESSAGE("SMDS_UnstructuredGrid::CellIdToDownId structure not up to date: vtkCellId=" + // << vtkCellId << " max="<< _cellIdToDownId.size()); + return -1; + } + return _cellIdToDownId[vtkCellId]; +} + +void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId) +{ + // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size())); + _cellIdToDownId[vtkCellId] = downId; +} + +void SMDS_UnstructuredGrid::CleanDownwardConnectivity() +{ + for (int i = 0; i < _downArray.size(); i++) + { + if (_downArray[i]) + delete _downArray[i]; + _downArray[i] = 0; + } + _cellIdToDownId.clear(); +} + +/*! Build downward connectivity: to do only when needed because heavy memory load. + * Downward connectivity is no more valid if vtkUnstructuredGrid is modified. + * + */ +void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges) +{ + MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2); + // TODO calcul partiel sans edges + + // --- erase previous data if any + + this->CleanDownwardConnectivity(); + + // --- create SMDS_Downward structures (in _downArray vector[vtkCellType]) + + _downArray.resize(VTK_MAXTYPE + 1, 0); + + _downArray[VTK_LINE] = new SMDS_DownEdge(this); + _downArray[VTK_QUADRATIC_EDGE] = new SMDS_DownQuadEdge(this); + _downArray[VTK_TRIANGLE] = new SMDS_DownTriangle(this); + _downArray[VTK_QUADRATIC_TRIANGLE] = new SMDS_DownQuadTriangle(this); + _downArray[VTK_QUAD] = new SMDS_DownQuadrangle(this); + _downArray[VTK_QUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this); + _downArray[VTK_BIQUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this); + _downArray[VTK_TETRA] = new SMDS_DownTetra(this); + _downArray[VTK_QUADRATIC_TETRA] = new SMDS_DownQuadTetra(this); + _downArray[VTK_PYRAMID] = new SMDS_DownPyramid(this); + _downArray[VTK_QUADRATIC_PYRAMID] = new SMDS_DownQuadPyramid(this); + _downArray[VTK_WEDGE] = new SMDS_DownPenta(this); + _downArray[VTK_QUADRATIC_WEDGE] = new SMDS_DownQuadPenta(this); + _downArray[VTK_HEXAHEDRON] = new SMDS_DownHexa(this); + _downArray[VTK_QUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this); + _downArray[VTK_TRIQUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this); + _downArray[VTK_HEXAGONAL_PRISM] = new SMDS_DownPenta(this); + + // --- get detailed info of number of cells of each type, allocate SMDS_downward structures + + const SMDS_MeshInfo &meshInfo = _mesh->GetMeshInfo(); + + int nbLinTetra = meshInfo.NbTetras (ORDER_LINEAR); + int nbQuadTetra = meshInfo.NbTetras (ORDER_QUADRATIC); + int nbLinPyra = meshInfo.NbPyramids(ORDER_LINEAR); + int nbQuadPyra = meshInfo.NbPyramids(ORDER_QUADRATIC); + int nbLinPrism = meshInfo.NbPrisms (ORDER_LINEAR); + int nbQuadPrism = meshInfo.NbPrisms (ORDER_QUADRATIC); + int nbLinHexa = meshInfo.NbHexas (ORDER_LINEAR); + int nbQuadHexa = meshInfo.NbHexas (ORDER_QUADRATIC); + int nbHexPrism = meshInfo.NbHexPrisms(); + + int nbLineGuess = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa); + int nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa); + int nbLinTriaGuess = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra; + int nbQuadTriaGuess = 2 * nbQuadTetra + nbQuadPrism + 2 * nbQuadPyra; + int nbLinQuadGuess = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa); + int nbQuadQuadGuess = int((2.0 / 3.0) * nbQuadPrism + (1.0 / 2.0) * nbQuadPyra + 3 * nbQuadHexa); + + int GuessSize[VTK_MAXTYPE]; + GuessSize[VTK_LINE] = nbLineGuess; + GuessSize[VTK_QUADRATIC_EDGE] = nbQuadEdgeGuess; + GuessSize[VTK_TRIANGLE] = nbLinTriaGuess; + GuessSize[VTK_QUADRATIC_TRIANGLE] = nbQuadTriaGuess; + GuessSize[VTK_QUAD] = nbLinQuadGuess; + GuessSize[VTK_QUADRATIC_QUAD] = nbQuadQuadGuess; + GuessSize[VTK_BIQUADRATIC_QUAD] = nbQuadQuadGuess; + GuessSize[VTK_TETRA] = nbLinTetra; + GuessSize[VTK_QUADRATIC_TETRA] = nbQuadTetra; + GuessSize[VTK_PYRAMID] = nbLinPyra; + GuessSize[VTK_QUADRATIC_PYRAMID] = nbQuadPyra; + GuessSize[VTK_WEDGE] = nbLinPrism; + GuessSize[VTK_QUADRATIC_WEDGE] = nbQuadPrism; + GuessSize[VTK_HEXAHEDRON] = nbLinHexa; + GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa; + GuessSize[VTK_TRIQUADRATIC_HEXAHEDRON] = nbQuadHexa; + GuessSize[VTK_HEXAGONAL_PRISM] = nbHexPrism; + + _downArray[VTK_LINE] ->allocate(nbLineGuess); + _downArray[VTK_QUADRATIC_EDGE] ->allocate(nbQuadEdgeGuess); + _downArray[VTK_TRIANGLE] ->allocate(nbLinTriaGuess); + _downArray[VTK_QUADRATIC_TRIANGLE] ->allocate(nbQuadTriaGuess); + _downArray[VTK_QUAD] ->allocate(nbLinQuadGuess); + _downArray[VTK_QUADRATIC_QUAD] ->allocate(nbQuadQuadGuess); + _downArray[VTK_BIQUADRATIC_QUAD] ->allocate(nbQuadQuadGuess); + _downArray[VTK_TETRA] ->allocate(nbLinTetra); + _downArray[VTK_QUADRATIC_TETRA] ->allocate(nbQuadTetra); + _downArray[VTK_PYRAMID] ->allocate(nbLinPyra); + _downArray[VTK_QUADRATIC_PYRAMID] ->allocate(nbQuadPyra); + _downArray[VTK_WEDGE] ->allocate(nbLinPrism); + _downArray[VTK_QUADRATIC_WEDGE] ->allocate(nbQuadPrism); + _downArray[VTK_HEXAHEDRON] ->allocate(nbLinHexa); + _downArray[VTK_QUADRATIC_HEXAHEDRON] ->allocate(nbQuadHexa); + _downArray[VTK_TRIQUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa); + _downArray[VTK_HEXAGONAL_PRISM] ->allocate(nbHexPrism); + + // --- iteration on vtkUnstructuredGrid cells, only faces + // for each vtk face: + // create a downward face entry with its downward id. + // compute vtk volumes, create downward volumes entry. + // mark face in downward volumes + // mark volumes in downward face + + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only faces");CHRONO(20); + int cellSize = this->Types->GetNumberOfTuples(); + _cellIdToDownId.resize(cellSize, -1); + + for (int i = 0; i < cellSize; i++) + { + int vtkFaceType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkFaceType) == 2) + { + int vtkFaceId = i; + //ASSERT(_downArray[vtkFaceType]); + int connFaceId = _downArray[vtkFaceType]->addCell(vtkFaceId); + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + downFace->setTempNodes(connFaceId, vtkFaceId); + int vols[2] = { -1, -1 }; + int nbVolumes = downFace->computeVolumeIds(vtkFaceId, vols); + //MESSAGE("nbVolumes="<< nbVolumes); + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId); + //ASSERT(_downArray[vtkVolType]); + int connVolId = _downArray[vtkVolType]->addCell(vtkVolId); + _downArray[vtkVolType]->addDownCell(connVolId, connFaceId, vtkFaceType); + _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId, vtkVolType); + // MESSAGE("Face " << vtkFaceId << " belongs to volume " << vtkVolId); + } + } + } + + // --- iteration on vtkUnstructuredGrid cells, only volumes + // for each vtk volume: + // create downward volumes entry if not already done + // build a temporary list of faces described with their nodes + // for each face + // compute the vtk volumes containing this face + // check if the face is already listed in the volumes (comparison of ordered list of nodes) + // if not, create a downward face entry (resizing of structure required) + // (the downward faces store a temporary list of nodes to ease the comparison) + // create downward volumes entry if not already done + // mark volumes in downward face + // mark face in downward volumes + + CHRONOSTOP(20); + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only volumes");CHRONO(21); + + for (int i = 0; i < cellSize; i++) + { + int vtkType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkType) == 3) + { + //CHRONO(31); + int vtkVolId = i; + // MESSAGE("vtk volume " << vtkVolId); + //ASSERT(_downArray[vtkType]); + /*int connVolId = */_downArray[vtkType]->addCell(vtkVolId); + + // --- find all the faces of the volume, describe the faces by their nodes + + SMDS_Down3D* downVol = static_cast (_downArray[vtkType]); + ListElemByNodesType facesWithNodes; + downVol->computeFacesWithNodes(vtkVolId, facesWithNodes); + // MESSAGE("vtk volume " << vtkVolId << " contains " << facesWithNodes.nbElems << " faces"); + //CHRONOSTOP(31); + for (int iface = 0; iface < facesWithNodes.nbElems; iface++) + { + // --- find the volumes containing the face + + //CHRONO(32); + int vtkFaceType = facesWithNodes.elems[iface].vtkType; + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + int vols[2] = { -1, -1 }; + int *nodes = &facesWithNodes.elems[iface].nodeIds[0]; + int lg = facesWithNodes.elems[iface].nbNodes; + int nbVolumes = downFace->computeVolumeIdsFromNodesFace(nodes, lg, vols); + // MESSAGE("vtk volume " << vtkVolId << " face " << iface << " belongs to " << nbVolumes << " volumes"); + + // --- check if face is registered in the volumes + //CHRONOSTOP(32); + + //CHRONO(33); + int connFaceId = -1; + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId2 = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId2); + //ASSERT(_downArray[vtkVolType]); + int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2); + SMDS_Down3D* downVol2 = static_cast (_downArray[vtkVolType]); + connFaceId = downVol2->FindFaceByNodes(connVolId2, facesWithNodes.elems[iface]); + if (connFaceId >= 0) + break; // --- face already created + }//CHRONOSTOP(33); + + // --- if face is not registered in the volumes, create face + + //CHRONO(34); + if (connFaceId < 0) + { + connFaceId = _downArray[vtkFaceType]->addCell(); + downFace->setTempNodes(connFaceId, facesWithNodes.elems[iface]); + }//CHRONOSTOP(34); + + // --- mark volumes in downward face and mark face in downward volumes + + //CHRONO(35); + for (int ivol = 0; ivol < nbVolumes; ivol++) + { + int vtkVolId2 = vols[ivol]; + int vtkVolType = this->GetCellType(vtkVolId2); + //ASSERT(_downArray[vtkVolType]); + int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2); + _downArray[vtkVolType]->addDownCell(connVolId2, connFaceId, vtkFaceType); + _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId2, vtkVolType); + // MESSAGE(" From volume " << vtkVolId << " face " << connFaceId << " belongs to volume " << vtkVolId2); + }//CHRONOSTOP(35); + } + } + } + + // --- iteration on vtkUnstructuredGrid cells, only edges + // for each vtk edge: + // create downward edge entry + // store the nodes id's in downward edge (redundant with vtkUnstructuredGrid) + // find downward faces + // (from vtk faces or volumes, get downward faces, they have a temporary list of nodes) + // mark edge in downward faces + // mark faces in downward edge + + CHRONOSTOP(21); + MESSAGE("--- iteration on vtkUnstructuredGrid cells, only edges");CHRONO(22); + + for (int i = 0; i < cellSize; i++) + { + int vtkEdgeType = this->GetCellType(i); + if (SMDS_Downward::getCellDimension(vtkEdgeType) == 1) + { + int vtkEdgeId = i; + //ASSERT(_downArray[vtkEdgeType]); + int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId); + SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); + downEdge->setNodes(connEdgeId, vtkEdgeId); + vector vtkIds; + int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds); + int downFaces[1000]; + unsigned char downTypes[1000]; + int nbDownFaces = downEdge->computeFaces(connEdgeId, &vtkIds[0], nbVtkCells, downFaces, downTypes); + for (int n = 0; n < nbDownFaces; n++) + { + _downArray[downTypes[n]]->addDownCell(downFaces[n], connEdgeId, vtkEdgeType); + _downArray[vtkEdgeType]->addUpCell(connEdgeId, downFaces[n], downTypes[n]); + } + } + } + + // --- iteration on downward faces (they are all listed now) + // for each downward face: + // build a temporary list of edges with their ordered list of nodes + // for each edge: + // find all the vtk cells containing this edge + // then identify all the downward faces containing the edge, from the vtk cells + // check if the edge is already listed in the faces (comparison of ordered list of nodes) + // if not, create a downward edge entry with the node id's + // mark edge in downward faces + // mark downward faces in edge (size of list unknown, to be allocated) + + CHRONOSTOP(22);CHRONO(23); + + for (int vtkFaceType = 0; vtkFaceType < VTK_QUADRATIC_PYRAMID; vtkFaceType++) + { + if (SMDS_Downward::getCellDimension(vtkFaceType) != 2) + continue; + + // --- find all the edges of the face, describe the edges by their nodes + + SMDS_Down2D* downFace = static_cast (_downArray[vtkFaceType]); + int maxId = downFace->getMaxId(); + for (int faceId = 0; faceId < maxId; faceId++) + { + //CHRONO(40); + ListElemByNodesType edgesWithNodes; + downFace->computeEdgesWithNodes(faceId, edgesWithNodes); + // MESSAGE("downward face type " << vtkFaceType << " num " << faceId << " contains " << edgesWithNodes.nbElems << " edges"); + + //CHRONOSTOP(40); + for (int iedge = 0; iedge < edgesWithNodes.nbElems; iedge++) + { + + // --- check if the edge is already registered by exploration of the faces + + //CHRONO(41); + vector vtkIds; + unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType; + int *pts = &edgesWithNodes.elems[iedge].nodeIds[0]; + SMDS_Down1D* downEdge = static_cast (_downArray[vtkEdgeType]); + int nbVtkCells = downEdge->computeVtkCells(pts, vtkIds); + //CHRONOSTOP(41);CHRONO(42); + int downFaces[1000]; + unsigned char downTypes[1000]; + int nbDownFaces = downEdge->computeFaces(pts, &vtkIds[0], nbVtkCells, downFaces, downTypes); + //CHRONOSTOP(42); + + //CHRONO(43); + int connEdgeId = -1; + for (int idf = 0; idf < nbDownFaces; idf++) + { + int faceId2 = downFaces[idf]; + int faceType = downTypes[idf]; + //ASSERT(_downArray[faceType]); + SMDS_Down2D* downFace2 = static_cast (_downArray[faceType]); + connEdgeId = downFace2->FindEdgeByNodes(faceId2, edgesWithNodes.elems[iedge]); + if (connEdgeId >= 0) + break; // --- edge already created + }//CHRONOSTOP(43); + + // --- if edge is not registered in the faces, create edge + + if (connEdgeId < 0) + { + //CHRONO(44); + connEdgeId = _downArray[vtkEdgeType]->addCell(); + downEdge->setNodes(connEdgeId, edgesWithNodes.elems[iedge].nodeIds); + //CHRONOSTOP(44); + } + + // --- mark faces in downward edge and mark edge in downward faces + + //CHRONO(45); + for (int idf = 0; idf < nbDownFaces; idf++) + { + int faceId2 = downFaces[idf]; + int faceType = downTypes[idf]; + //ASSERT(_downArray[faceType]); + //SMDS_Down2D* downFace2 = static_cast (_downArray[faceType]); + _downArray[vtkEdgeType]->addUpCell(connEdgeId, faceId2, faceType); + _downArray[faceType]->addDownCell(faceId2, connEdgeId, vtkEdgeType); + // MESSAGE(" From face t:" << vtkFaceType << " " << faceId << + // " edge " << connEdgeId << " belongs to face t:" << faceType << " " << faceId2); + }//CHRONOSTOP(45); + } + } + } + + CHRONOSTOP(23);CHRONO(24); + + // compact downward connectivity structure: adjust downward arrays size, replace vector> by a single vector + // 3D first then 2D and last 1D to release memory before edge upCells reorganization, (temporary memory use) + + for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--) + { + if (SMDS_Downward *down = _downArray[vtkType]) + { + down->compactStorage(); + } + } + + // --- Statistics + + for (int vtkType = 0; vtkType <= VTK_QUADRATIC_PYRAMID; vtkType++) + { + if (SMDS_Downward *down = _downArray[vtkType]) + { + if (down->getMaxId()) + { + MESSAGE("Cells of Type " << vtkType << " : number of entities, est: " + << GuessSize[vtkType] << " real: " << down->getMaxId()); + } + } + }CHRONOSTOP(24);CHRONOSTOP(2); + counters::stats(); +} + +/*! Get the neighbors of a cell. + * Only the neighbors having the dimension of the cell are taken into account + * (neighbors of a volume are the volumes sharing a face with this volume, + * neighbors of a face are the faces sharing an edge with this face...). + * @param neighborsVtkIds vector of neighbors vtk id's to fill (reserve enough space). + * @param downIds downward id's of cells of dimension n-1, to fill (reserve enough space). + * @param downTypes vtk types of cells of dimension n-1, to fill (reserve enough space). + * @param vtkId the vtk id of the cell + * @return number of neighbors + */ +int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId) +{ + int vtkType = this->GetCellType(vtkId); + int cellDim = SMDS_Downward::getCellDimension(vtkType); + if (cellDim <2) + return 0; // TODO voisins des edges = edges connectees + int cellId = this->_cellIdToDownId[vtkId]; + + int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId); + const int *downCells = _downArray[vtkType]->getDownCells(cellId); + const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(cellId); + + // --- iteration on faces of the 3D cell (or edges on the 2D cell). + + int nb = 0; + for (int i = 0; i < nbCells; i++) + { + int downId = downCells[i]; + int cellType = downTyp[i]; + int nbUp = _downArray[cellType]->getNumberOfUpCells(downId); + const int *upCells = _downArray[cellType]->getUpCells(downId); + const unsigned char* upTypes = _downArray[cellType]->getUpTypes(downId); + + // ---for a volume, max 2 upCells, one is this cell, the other is a neighbor + // for a face, number of neighbors (connected faces) not known + + for (int j = 0; j < nbUp; j++) + { + if ((upCells[j] == cellId) && (upTypes[j] == vtkType)) + continue; + int vtkNeighbor = _downArray[upTypes[j]]->getVtkCellId(upCells[j]); + neighborsVtkIds[nb] = vtkNeighbor; + downIds[nb] = downId; + downTypes[nb] = cellType; + nb++; + } + if (nb >= NBMAXNEIGHBORS) + assert(0); + } + return nb; +} + +/*! get the volumes containing a face or an edge of the grid + * The edge or face belongs to the vtkUnstructuredGrid + * @param volVtkIds vector of parent volume ids to fill (reserve enough space!) + * @param vtkId vtk id of the face or edge + */ +int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int vtkId) +{ + int vtkType = this->GetCellType(vtkId); + int dim = SMDS_Downward::getCellDimension(vtkType); + int nbFaces = 0; + unsigned char cellTypes[1000]; + int downCellId[1000]; + if (dim == 1) + { + int downId = this->CellIdToDownId(vtkId); + if (downId < 0) + { + MESSAGE("Downward structure not up to date: new edge not taken into account"); + return 0; + } + nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId); + const int *upCells = _downArray[vtkType]->getUpCells(downId); + const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId); + for (int i=0; i< nbFaces; i++) + { + cellTypes[i] = upTypes[i]; + downCellId[i] = upCells[i]; + } + } + else if (dim == 2) + { + nbFaces = 1; + cellTypes[0] = this->GetCellType(vtkId); + int downId = this->CellIdToDownId(vtkId); + if (downId < 0) + { + MESSAGE("Downward structure not up to date: new face not taken into account"); + return 0; + } + downCellId[0] = downId; + } + + int nbvol =0; + for (int i=0; igetNumberOfUpCells(downId); + const int *upCells = _downArray[vtkTypeFace]->getUpCells(downId); + const unsigned char* upTypes = _downArray[vtkTypeFace]->getUpTypes(downId); + for (int j=0; jgetVtkCellId(upCells[j]); + if (vtkVolId >= 0) + volVtkIds[nbvol++] = vtkVolId; + } + } + return nbvol; +} + +/*! get the volumes containing a face or an edge of the downward structure + * The edge or face does not necessary belong to the vtkUnstructuredGrid + * @param volVtkIds vector of parent volume ids to fill (reserve enough space!) + * @param downId id in the downward structure + * @param downType type of cell + */ +int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int downId, unsigned char downType) +{ + int vtkType = downType; + int dim = SMDS_Downward::getCellDimension(vtkType); + int nbFaces = 0; + unsigned char cellTypes[1000]; + int downCellId[1000]; + if (dim == 1) + { + nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId); + const int *upCells = _downArray[vtkType]->getUpCells(downId); + const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId); + for (int i=0; i< nbFaces; i++) + { + cellTypes[i] = upTypes[i]; + downCellId[i] = upCells[i]; + } + } + else if (dim == 2) + { + nbFaces = 1; + cellTypes[0] = vtkType; + downCellId[0] = downId; + } + + int nbvol =0; + for (int i=0; igetNumberOfUpCells(downId); + const int *upCells = _downArray[vtkTypeFace]->getUpCells(downId); + const unsigned char* upTypes = _downArray[vtkTypeFace]->getUpTypes(downId); + for (int j=0; jgetVtkCellId(upCells[j]); + if (vtkVolId >= 0) + volVtkIds[nbvol++] = vtkVolId; + } + } + return nbvol; +} + +/*! get the node id's of a cell. + * The cell is defined by it's downward connectivity id and type. + * @param nodeSet set of of vtk node id's to fill. + * @param downId downward connectivity id of the cell. + * @param downType type of cell. + */ +void SMDS_UnstructuredGrid::GetNodeIds(std::set& nodeSet, int downId, unsigned char downType) +{ + _downArray[downType]->getNodeIds(downId, nodeSet); +} + +/*! change some nodes in cell without modifying type or internal connectivity. + * Nodes inverse connectivity is maintained up to date. + * @param vtkVolId vtk id of the cell + * @param localClonedNodeIds map old node id to new node id. + */ +void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds) +{ + vtkIdType npts = 0; + vtkIdType *pts; // will refer to the point id's of the face + this->GetCellPoints(vtkVolId, npts, pts); + for (int i = 0; i < npts; i++) + { + if (localClonedNodeIds.count(pts[i])) + { + vtkIdType oldpt = pts[i]; + pts[i] = localClonedNodeIds[oldpt]; + //MESSAGE(oldpt << " --> " << pts[i]); + //this->RemoveReferenceToCell(oldpt, vtkVolId); + //this->AddReferenceToCell(pts[i], vtkVolId); + } + } +} + +/*! reorder the nodes of a face + * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face. + * @param orderedNodes list of nodes to reorder (in out) + * @return size of the list + */ +int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector& orderedNodes) +{ + int vtkType = this->GetCellType(vtkVolId); + dim = SMDS_Downward::getCellDimension(vtkType); + if (dim == 3) + { + SMDS_Down3D *downvol = static_cast (_downArray[vtkType]); + int downVolId = this->_cellIdToDownId[vtkVolId]; + downvol->getOrderedNodesOfFace(downVolId, orderedNodes); + } + // else nothing to do; + return orderedNodes.size(); +} + +void SMDS_UnstructuredGrid::BuildLinks() +{ + // Remove the old links if they are already built + if (this->Links) + { + this->Links->UnRegister(this); + } + + this->Links = SMDS_CellLinks::New(); + this->Links->Allocate(this->GetNumberOfPoints()); + this->Links->Register(this); + this->Links->BuildLinks(this, this->Connectivity); + this->Links->Delete(); +} + +/*! Create a volume (prism or hexahedron) by duplication of a face. + * Designed for use in creation of flat elements separating volume domains. + * A face separating two domains is shared by two volume cells. + * All the nodes are already created (for the two faces). + * Each original Node is associated to corresponding nodes in the domains. + * Some nodes may be duplicated for more than two domains, when domain separations intersect. + * In that case, even some of the nodes to use for the original face may be changed. + * @param vtkVolId: vtk id of a volume containing the face, to get an orientation for the face. + * @param domain1: domain of the original face + * @param domain2: domain of the duplicated face + * @param originalNodes: the vtk node ids of the original face + * @param nodeDomains: map(original id --> map(domain --> duplicated node id)) + * @return ok if success. + */ +SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, + int domain1, + int domain2, + std::set& originalNodes, + std::map >& nodeDomains, + std::map >& nodeQuadDomains) +{ + //MESSAGE("extrudeVolumeFromFace " << vtkVolId); + vector orderedOriginals; + orderedOriginals.clear(); + set::const_iterator it = originalNodes.begin(); + for (; it != originalNodes.end(); ++it) + orderedOriginals.push_back(*it); + + int dim = 0; + int nbNodes = this->getOrderedNodesOfFace(vtkVolId, dim, orderedOriginals); + vector orderedNodes; + + bool isQuadratic = false; + switch (orderedOriginals.size()) + { + case 3: + if (dim == 2) + isQuadratic = true; + break; + case 6: + case 8: + isQuadratic = true; + break; + default: + isQuadratic = false; + break; + } + + if (isQuadratic) + { + long dom1 = domain1; + long dom2 = domain2; + long dom1_2; // for nodeQuadDomains + if (domain1 < domain2) + dom1_2 = dom1 + INT_MAX * dom2; + else + dom1_2 = dom2 + INT_MAX * dom1; + //cerr << "dom1=" << dom1 << " dom2=" << dom2 << " dom1_2=" << dom1_2 << endl; + int ima = orderedOriginals.size(); + int mid = orderedOriginals.size() / 2; + //cerr << "ima=" << ima << " mid=" << mid << endl; + for (int i = 0; i < mid; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + for (int i = 0; i < mid; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + for (int i = mid; i < ima; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + for (int i = mid; i < ima; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + for (int i = 0; i < mid; i++) + { + int oldId = orderedOriginals[i]; + int newId; + if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2)) + newId = nodeQuadDomains[oldId][dom1_2]; + else + { + double *coords = this->GetPoint(oldId); + SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); + newId = newNode->getVtkId(); + std::map emptyMap; + nodeQuadDomains[oldId] = emptyMap; + nodeQuadDomains[oldId][dom1_2] = newId; + } + orderedNodes.push_back(newId); + } + } + else + { + for (int i = 0; i < nbNodes; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); + if (dim == 3) + for (int i = 0; i < nbNodes; i++) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + else + for (int i = nbNodes-1; i >= 0; i--) + orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); + + } + + if (dim == 3) + { + SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes); + return vol; + } + else if (dim == 2) + { + SMDS_MeshFace *face = _mesh->AddFaceFromVtkIds(orderedNodes); + return face; + } + + // TODO update sub-shape list of elements and nodes + return 0; +} + +//================================================================================ +/*! + * \brief Allocates data array for ball diameters + * \param MaxVtkID - max ID of a ball element + */ +//================================================================================ + +void SMDS_UnstructuredGrid::AllocateDiameters( vtkIdType MaxVtkID ) +{ + SetBallDiameter( MaxVtkID, 0 ); +} + +//================================================================================ +/*! + * \brief Sets diameter of a ball element + * \param vtkID - vtk id of the ball element + * \param diameter - diameter of the ball element + */ +//================================================================================ + +void SMDS_UnstructuredGrid::SetBallDiameter( vtkIdType vtkID, double diameter ) +{ + vtkDoubleArray* array = vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() ); + if ( !array ) + { + array = vtkDoubleArray::New(); + array->SetNumberOfComponents(1); + vtkDataSet::CellData->SetScalars( array ); + } + array->InsertValue( vtkID, diameter ); +} + +//================================================================================ +/*! + * \brief Returns diameter of a ball element + * \param vtkID - vtk id of the ball element + */ +//================================================================================ + +double SMDS_UnstructuredGrid::GetBallDiameter( vtkIdType vtkID ) const +{ + if ( vtkDataSet::CellData ) + return vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )->GetValue( vtkID ); + return 0; +} + diff --git a/src/SMDS/SMDS_UnstructuredGrid.hxx b/src/SMDS/SMDS_UnstructuredGrid.hxx new file mode 100644 index 000000000..4c1cc7b80 --- /dev/null +++ b/src/SMDS/SMDS_UnstructuredGrid.hxx @@ -0,0 +1,125 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File: SMDS_UnstructuredGrid.hxx +// Author: prascle +// Created: September 16, 2009, 10:28 PM + +#ifndef _SMDS_UNSTRUCTUREDGRID_HXX +#define _SMDS_UNSTRUCTUREDGRID_HXX + +#include "SMESH_SMDS.hxx" + +#include +#include +#include "chrono.hxx" + +#include +#include +#include + +//#define VTK_HAVE_POLYHEDRON +//#ifdef VTK_HAVE_POLYHEDRON +#define VTK_MAXTYPE VTK_POLYHEDRON +//#else +// #define VTK_MAXTYPE VTK_QUADRATIC_PYRAMID +//#endif + +#define NBMAXNEIGHBORS 100 + +// allow very huge polyhedrons in tests +#define NBMAXNODESINCELL 5000 + +class SMDS_Downward; +class SMDS_Mesh; +class SMDS_MeshCell; +class SMDS_MeshVolume; + +class SMDS_EXPORT SMDS_CellLinks: public vtkCellLinks +{ +public: + vtkCellLinks::Link* ResizeL(vtkIdType sz); + vtkIdType GetLinksSize(); + static SMDS_CellLinks* New(); +protected: + SMDS_CellLinks(); + ~SMDS_CellLinks(); +}; + +class SMDS_EXPORT SMDS_UnstructuredGrid: public vtkUnstructuredGrid +{ +public: + void setSMDS_mesh(SMDS_Mesh *mesh); + void compactGrid(std::vector& idNodesOldToNew, + int newNodeSize, + std::vector& idCellsOldToNew, + int newCellSize); + virtual unsigned long GetMTime(); + virtual void Update(); + virtual void UpdateInformation(); + virtual vtkPoints *GetPoints(); + + //#ifdef VTK_HAVE_POLYHEDRON + int InsertNextLinkedCell(int type, int npts, vtkIdType *pts); + //#endif + + int CellIdToDownId(int vtkCellId); + void setCellIdToDownId(int vtkCellId, int downId); + void CleanDownwardConnectivity(); + void BuildDownwardConnectivity(bool withEdges); + int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId); + int GetParentVolumes(int* volVtkIds, int vtkId); + int GetParentVolumes(int* volVtkIds, int downId, unsigned char downType); + void GetNodeIds(std::set& nodeSet, int downId, unsigned char downType); + void ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds); + int getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector& orderedNodes); + void BuildLinks(); + SMDS_MeshCell* extrudeVolumeFromFace(int vtkVolId, int domain1, int domain2, + std::set& originalNodes, + std::map >& nodeDomains, + std::map >& nodeQuadDomains); + vtkCellLinks* GetLinks() + { + return Links; + } + SMDS_Downward* getDownArray(unsigned char vtkType) + { + return _downArray[vtkType]; + } + void AllocateDiameters( vtkIdType maxVtkID ); + void SetBallDiameter( vtkIdType vtkID, double diameter ); + double GetBallDiameter( vtkIdType vtkID ) const; + + static SMDS_UnstructuredGrid* New(); + SMDS_Mesh *_mesh; +protected: + SMDS_UnstructuredGrid(); + ~SMDS_UnstructuredGrid(); + void copyNodes(vtkPoints *newPoints, std::vector& idNodesOldToNew, int& alreadyCopied, int start, int end); + void copyBloc(vtkUnsignedCharArray *newTypes, std::vector& idCellsOldToNew, std::vector& idNodesOldToNew, + vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied, + int start, int end); + + std::vector _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1 + std::vector _downTypes; + std::vector _downArray; +}; + +#endif /* _SMDS_UNSTRUCTUREDGRID_HXX */ + diff --git a/src/SMDS/SMDS_VertexPosition.cxx b/src/SMDS/SMDS_VertexPosition.cxx index c3311b5a5..20584970c 100644 --- a/src/SMDS/SMDS_VertexPosition.cxx +++ b/src/SMDS/SMDS_VertexPosition.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_VertexPosition.cxx // Author : Jean-Michel BOULCOURT @@ -35,25 +36,13 @@ using namespace std; //purpose : //======================================================================= -SMDS_VertexPosition:: SMDS_VertexPosition(const int aVertexId) - :SMDS_Position(aVertexId) +SMDS_VertexPosition:: SMDS_VertexPosition() { + //MESSAGE("*********************************************** SMDS_VertexPosition " << aVertexId); } -//======================================================================= -//function : Coords -//purpose : -//======================================================================= - -const double *SMDS_VertexPosition::Coords() const -{ - const static double origin[]={0,0,0}; - MESSAGE("SMDS_VertexPosition::Coords not implemented"); - return origin; -} - - SMDS_TypeOfPosition SMDS_VertexPosition::GetTypeOfPosition() const { - return SMDS_TOP_VERTEX; + //MESSAGE("################################################# GetTypeOfPosition"); + return SMDS_TOP_VERTEX; } diff --git a/src/SMDS/SMDS_VertexPosition.hxx b/src/SMDS/SMDS_VertexPosition.hxx index dad7b5a13..6b574cd11 100644 --- a/src/SMDS/SMDS_VertexPosition.hxx +++ b/src/SMDS/SMDS_VertexPosition.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_VertexPosition.hxx // Module : SMESH @@ -33,10 +34,9 @@ class SMDS_EXPORT SMDS_VertexPosition:public SMDS_Position { - public: - SMDS_TypeOfPosition GetTypeOfPosition() const; - SMDS_VertexPosition(int aVertexId=0); - const double *Coords() const; + public: + SMDS_TypeOfPosition GetTypeOfPosition() const; + SMDS_VertexPosition(); }; #endif diff --git a/src/SMDS/SMDS_VolumeOfFaces.cxx b/src/SMDS/SMDS_VolumeOfFaces.cxx index c993dcc66..e5aa46096 100644 --- a/src/SMDS/SMDS_VolumeOfFaces.cxx +++ b/src/SMDS/SMDS_VolumeOfFaces.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_VolumeOfFaces.cxx // Author : Jean-Michel BOULCOURT @@ -30,6 +31,7 @@ #include "SMDS_VolumeOfFaces.hxx" #include "SMDS_IteratorOfElements.hxx" +#include "utilities.h" using namespace std; @@ -40,16 +42,16 @@ using namespace std; void SMDS_VolumeOfFaces::Print(ostream & OS) const { - OS << "volume <" << GetID() << "> : "; - int i; - for (i = 0; i < NbFaces()-1; ++i) OS << myFaces[i] << ","; - OS << myFaces[i]<< ") " << endl; + OS << "volume <" << GetID() << "> : "; + int i; + for (i = 0; i < NbFaces()-1; ++i) OS << myFaces[i] << ","; + OS << myFaces[i]<< ") " << endl; } int SMDS_VolumeOfFaces::NbFaces() const { - return myNbFaces; + return myNbFaces; } class SMDS_VolumeOfFaces_MyIterator:public SMDS_ElemIterator @@ -74,7 +76,7 @@ class SMDS_VolumeOfFaces_MyIterator:public SMDS_ElemIterator }; SMDS_ElemIteratorPtr SMDS_VolumeOfFaces:: - elementsIterator(SMDSAbs_ElementType type) const + elementsIterator(SMDSAbs_ElementType type) const { switch(type) { @@ -95,13 +97,14 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face3, const SMDS_MeshFace * face4) { - myNbFaces = 4; - myFaces[0]=face1; - myFaces[1]=face2; - myFaces[2]=face3; - myFaces[3]=face4; - myFaces[4]=0; - myFaces[5]=0; + //MESSAGE("****************************************************** SMDS_VolumeOfFaces"); + myNbFaces = 4; + myFaces[0]=face1; + myFaces[1]=face2; + myFaces[2]=face3; + myFaces[3]=face4; + myFaces[4]=0; + myFaces[5]=0; } SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, @@ -110,13 +113,14 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face4, const SMDS_MeshFace * face5) { - myNbFaces = 5; - myFaces[0]=face1; - myFaces[1]=face2; - myFaces[2]=face3; - myFaces[3]=face4; - myFaces[4]=face5; - myFaces[5]=0; + //MESSAGE("****************************************************** SMDS_VolumeOfFaces"); + myNbFaces = 5; + myFaces[0]=face1; + myFaces[1]=face2; + myFaces[2]=face3; + myFaces[3]=face4; + myFaces[4]=face5; + myFaces[5]=0; } SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, @@ -126,12 +130,40 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face5, const SMDS_MeshFace * face6) { - myNbFaces = 6; - myFaces[0]=face1; - myFaces[1]=face2; - myFaces[2]=face3; - myFaces[3]=face4; - myFaces[4]=face5; - myFaces[5]=face6; + //MESSAGE("****************************************************** SMDS_VolumeOfFaces"); + myNbFaces = 6; + myFaces[0]=face1; + myFaces[1]=face2; + myFaces[2]=face3; + myFaces[3]=face4; + myFaces[4]=face5; + myFaces[5]=face6; +} + +SMDSAbs_EntityType SMDS_VolumeOfFaces::GetEntityType() const +{ + SMDSAbs_EntityType aType = SMDSEntity_Tetra; + switch(myNbFaces) + { + case 4: aType = SMDSEntity_Tetra; break; + case 5: aType = SMDSEntity_Pyramid; break; + case 6: aType = SMDSEntity_Penta; break; + case 8: + default: aType = SMDSEntity_Hexa; break; + } + return aType; } +SMDSAbs_GeometryType SMDS_VolumeOfFaces::GetGeomType() const +{ + SMDSAbs_GeometryType aType = SMDSGeom_NONE; + switch(myNbFaces) + { + case 4: aType = SMDSGeom_TETRA; break; + case 5: aType = SMDSGeom_PYRAMID; break; + case 6: aType = SMDSGeom_PENTA; break; + case 8: + default: aType = SMDSGeom_HEXA; break; + } + return aType; +} diff --git a/src/SMDS/SMDS_VolumeOfFaces.hxx b/src/SMDS/SMDS_VolumeOfFaces.hxx index 074fbec23..a64d53ab5 100644 --- a/src/SMDS/SMDS_VolumeOfFaces.hxx +++ b/src/SMDS/SMDS_VolumeOfFaces.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_VolumeOfFaces.hxx // Module : SMESH @@ -36,32 +37,35 @@ class SMDS_EXPORT SMDS_VolumeOfFaces:public SMDS_MeshVolume { - + public: - SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, + SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face2, const SMDS_MeshFace * face3, const SMDS_MeshFace * face4); - SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, + SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face2, const SMDS_MeshFace * face3, const SMDS_MeshFace * face4, const SMDS_MeshFace * face5); - SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, + SMDS_VolumeOfFaces(const SMDS_MeshFace * face1, const SMDS_MeshFace * face2, const SMDS_MeshFace * face3, const SMDS_MeshFace * face4, const SMDS_MeshFace * face5, const SMDS_MeshFace * face6); - void Print(std::ostream & OS) const; - - int NbFaces() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], + const int nbNodes) {return false;} + virtual void Print(std::ostream & OS) const; + + virtual int NbFaces() const; protected: - SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; - const SMDS_MeshFace * myFaces[6]; - int myNbFaces; + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + const SMDS_MeshFace * myFaces[6]; + int myNbFaces; }; #endif diff --git a/src/SMDS/SMDS_VolumeOfNodes.cxx b/src/SMDS/SMDS_VolumeOfNodes.cxx index ff46fc318..cb4cdfa34 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.cxx +++ b/src/SMDS/SMDS_VolumeOfNodes.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // #ifdef _MSC_VER @@ -29,10 +30,9 @@ #include "SMDS_MeshNode.hxx" #include "SMDS_SetIterator.hxx" #include "SMDS_VolumeTool.hxx" +#include "SMDS_Mesh.hxx" #include "utilities.h" -#include - using namespace std; /////////////////////////////////////////////////////////////////////////////// @@ -40,73 +40,77 @@ using namespace std; /// 5,1 and 7,3 are an edges. /////////////////////////////////////////////////////////////////////////////// SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6, - const SMDS_MeshNode * node7, - const SMDS_MeshNode * node8) -{ - myNbNodes = 8; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; - myNodes[4]=node5; - myNodes[5]=node6; - myNodes[6]=node7; - myNodes[7]=node8; + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6, + const SMDS_MeshNode * node7, + const SMDS_MeshNode * node8) +{ + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 8; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; + myNodes[4]=node5; + myNodes[5]=node6; + myNodes[6]=node7; + myNodes[7]=node8; } SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4) -{ - myNbNodes = 4; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4) +{ + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 4; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; } SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5) -{ - myNbNodes = 5; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; - myNodes[4]=node5; + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5) +{ + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 5; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; + myNodes[4]=node5; } SMDS_VolumeOfNodes::SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6) -{ - myNbNodes = 6; - myNodes = new const SMDS_MeshNode* [myNbNodes]; - myNodes[0]=node1; - myNodes[1]=node2; - myNodes[2]=node3; - myNodes[3]=node4; - myNodes[4]=node5; - myNodes[5]=node6; + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6) +{ + //MESSAGE("***************************************************** SMDS_VolumeOfNodes"); + myNbNodes = 6; + myNodes = new const SMDS_MeshNode* [myNbNodes]; + myNodes[0]=node1; + myNodes[1]=node2; + myNodes[2]=node3; + myNodes[3]=node4; + myNodes[4]=node5; + myNodes[5]=node6; } bool SMDS_VolumeOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[], @@ -132,56 +136,48 @@ SMDS_VolumeOfNodes::~SMDS_VolumeOfNodes() } } -//======================================================================= -//function : Print -//purpose : -//======================================================================= - void SMDS_VolumeOfNodes::Print(ostream & OS) const { - OS << "volume <" << GetID() << "> : "; - int i; - for (i = 0; i < NbNodes(); ++i) OS << myNodes[i] << ","; - OS << myNodes[NbNodes()-1]<< ") " << endl; + OS << "volume <" << GetID() << "> : "; + int i; + for (i = 0; i < NbNodes()-1; ++i) OS << myNodes[i] << ","; + OS << myNodes[NbNodes()-1]<< ") " << endl; } int SMDS_VolumeOfNodes::NbFaces() const { - switch(NbNodes()) - { - case 4: return 4; - case 5: return 5; - case 6: return 5; - case 8: return 6; - default: MESSAGE("invalid number of nodes"); - } + switch(NbNodes()) + { + case 4: return 4; + case 5: return 5; + case 6: return 5; + case 8: return 6; + default: MESSAGE("invalid number of nodes"); + } return 0; } int SMDS_VolumeOfNodes::NbNodes() const { - return myNbNodes; + return myNbNodes; } int SMDS_VolumeOfNodes::NbEdges() const { - switch(NbNodes()) - { - case 4: return 6; - case 5: return 8; - case 6: return 9; - case 8: return 12; - default: MESSAGE("invalid number of nodes"); - } + switch(NbNodes()) + { + case 4: return 6; + case 5: return 8; + case 6: return 9; + case 8: return 12; + default: MESSAGE("invalid number of nodes"); + } return 0; } -/// =================================================================== /*! * \brief Iterator on node of volume */ -/// =================================================================== - class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator { public: @@ -189,12 +185,9 @@ class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator SMDS_NodeArrayElemIterator( s, & s[ l ]) {} }; -/// =================================================================== /*! * \brief Iterator on faces or edges of volume */ -/// =================================================================== - class _MySubIterator : public SMDS_ElemIterator { vector< const SMDS_MeshElement* > myElems; @@ -234,17 +227,45 @@ SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::elementsIterator(SMDSAbs_ElementType ty SMDSAbs_ElementType SMDS_VolumeOfNodes::GetType() const { - return SMDSAbs_Volume; + return SMDSAbs_Volume; } /*! * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ const SMDS_MeshNode* SMDS_VolumeOfNodes::GetNode(const int ind) const { - return myNodes[ WrappedIndex( ind )]; + return myNodes[ ind ]; +} + +SMDSAbs_EntityType SMDS_VolumeOfNodes::GetEntityType() const +{ + SMDSAbs_EntityType aType = SMDSEntity_Tetra; + switch(myNbNodes) + { + case 4: aType = SMDSEntity_Tetra; break; + case 5: aType = SMDSEntity_Pyramid; break; + case 6: aType = SMDSEntity_Penta; break; + case 8: + default: aType = SMDSEntity_Hexa; break; + } + return aType; +} + +SMDSAbs_GeometryType SMDS_VolumeOfNodes::GetGeomType() const +{ + SMDSAbs_GeometryType aType = SMDSGeom_NONE; + switch(myNbNodes) + { + case 4: aType = SMDSGeom_TETRA; break; + case 5: aType = SMDSGeom_PYRAMID; break; + case 6: aType = SMDSGeom_PENTA; break; + case 12: aType = SMDSGeom_HEXAGONAL_PRISM; break; + case 8: + default: aType = SMDSGeom_HEXA; break; + } + return aType; } + diff --git a/src/SMDS/SMDS_VolumeOfNodes.hxx b/src/SMDS/SMDS_VolumeOfNodes.hxx index ee773285b..86e22b622 100644 --- a/src/SMDS/SMDS_VolumeOfNodes.hxx +++ b/src/SMDS/SMDS_VolumeOfNodes.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_MeshVolume.hxx // Module : SMESH @@ -32,58 +33,60 @@ class SMDS_EXPORT SMDS_VolumeOfNodes:public SMDS_MeshVolume { - + public: - SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4); - SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5); - SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6); - SMDS_VolumeOfNodes( - const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2, - const SMDS_MeshNode * node3, - const SMDS_MeshNode * node4, - const SMDS_MeshNode * node5, - const SMDS_MeshNode * node6, - const SMDS_MeshNode * node7, - const SMDS_MeshNode * node8); + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4); + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5); + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6); + SMDS_VolumeOfNodes( + const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3, + const SMDS_MeshNode * node4, + const SMDS_MeshNode * node5, + const SMDS_MeshNode * node6, + const SMDS_MeshNode * node7, + const SMDS_MeshNode * node8); bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); ~SMDS_VolumeOfNodes(); - void Print(std::ostream & OS) const; - int NbFaces() const; - int NbNodes() const; - int NbEdges() const; - SMDSAbs_ElementType GetType() const; + void Print(std::ostream & OS) const; + int NbFaces() const; + int NbNodes() const; + int NbEdges() const; + virtual SMDSAbs_ElementType GetType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; /*! * \brief Return node by its index * \param ind - node index * \retval const SMDS_MeshNode* - the node - * - * Index is wrapped if it is out of a valid range */ virtual const SMDS_MeshNode* GetNode(const int ind) const; protected: - SMDS_ElemIteratorPtr - elementsIterator(SMDSAbs_ElementType type) const; - const SMDS_MeshNode** myNodes; - int myNbNodes; + SMDS_ElemIteratorPtr + elementsIterator(SMDSAbs_ElementType type) const; + const SMDS_MeshNode** myNodes; + int myNbNodes; + }; + #endif diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 0984cb505..841d23540 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMDS_VolumeTool.cxx // Created : Tue Jul 13 12:22:13 2004 // Author : Edward AGAPOV (eap) @@ -31,14 +32,14 @@ #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_VtkVolume.hxx" #include "SMDS_Mesh.hxx" #include "utilities.h" #include -#include -#include +#include +#include using namespace std; @@ -46,6 +47,10 @@ using namespace std; // Node indices in faces depending on volume orientation // making most faces normals external // ====================================================== +// For all elements, 0-th face is bottom based on the first nodes. +// For prismatic elements (tetra,hexa,prisms), 1-th face is a top one. +// For all elements, side faces follow order of bottom nodes +// ====================================================== /* // N3 @@ -66,11 +71,6 @@ static int Tetra_F [4][4] = { // FORWARD == EXTERNAL { 0, 3, 1, 0 }, { 1, 3, 2, 1 }, { 0, 2, 3, 0 }}; -static int Tetra_R [4][4] = { // REVERSED - { 0, 1, 2, 0 }, // All faces but a bottom have external normals - { 0, 1, 3, 0 }, - { 1, 2, 3, 1 }, - { 0, 3, 2, 0 }}; static int Tetra_RE [4][4] = { // REVERSED -> FORWARD (EXTERNAL) { 0, 2, 1, 0 }, // All faces have external normals { 0, 1, 3, 0 }, @@ -86,13 +86,8 @@ static int Pyramid_F [5][5] = { // FORWARD == EXTERNAL { 0, 4, 1, 0, 4 }, { 1, 4, 2, 1, 4 }, { 2, 4, 3, 2, 4 }, - { 3, 4, 0, 3, 4 }}; -static int Pyramid_R [5][5] = { // REVERSED - { 0, 1, 2, 3, 0 }, // All faces but a bottom have external normals - { 0, 1, 4, 0, 4 }, - { 1, 2, 4, 1, 4 }, - { 2, 3, 4, 2, 4 }, - { 3, 0, 4, 3, 4 }}; + { 3, 4, 0, 3, 4 } +}; static int Pyramid_RE [5][5] = { // REVERSED -> FORWARD (EXTERNAL) { 0, 3, 2, 1, 0 }, // All faces but a bottom have external normals { 0, 1, 4, 0, 4 }, @@ -117,29 +112,17 @@ static int Pyramid_nbN [] = { 4, 3, 3, 3, 3 }; // N0 +---------+ N2 */ static int Penta_F [5][5] = { // FORWARD - { 0, 1, 2, 0, 0 }, // Top face has an internal normal, other - external - { 3, 4, 5, 3, 3 }, // 0 is bottom, 1 is top face - { 0, 2, 5, 3, 0 }, - { 1, 4, 5, 2, 1 }, - { 0, 3, 4, 1, 0 }}; -static int Penta_R [5][5] = { // REVERSED - { 0, 1, 2, 0, 0 }, // Bottom face has an internal normal, other - external - { 3, 4, 5, 3, 3 }, // 0 is bottom, 1 is top face - { 0, 3, 5, 2, 0 }, - { 1, 2, 5, 4, 1 }, - { 0, 1, 4, 3, 0 }}; -static int Penta_FE [5][5] = { // FORWARD -> EXTERNAL - { 0, 1, 2, 0, 0 }, - { 3, 5, 4, 3, 3 }, - { 0, 2, 5, 3, 0 }, + { 0, 1, 2, 0, 0 }, // All faces have external normals + { 3, 5, 4, 3, 3 }, // 0 is bottom, 1 is top face + { 0, 3, 4, 1, 0 }, { 1, 4, 5, 2, 1 }, - { 0, 3, 4, 1, 0 }}; + { 0, 2, 5, 3, 0 }}; static int Penta_RE [5][5] = { // REVERSED -> EXTERNAL { 0, 2, 1, 0, 0 }, { 3, 4, 5, 3, 3 }, - { 0, 3, 5, 2, 0 }, + { 0, 1, 4, 3, 0 }, { 1, 2, 5, 4, 1 }, - { 0, 1, 4, 3, 0 }}; + { 0, 3, 5, 2, 0 }}; static int Penta_nbN [] = { 3, 3, 4, 4, 4 }; /* @@ -158,35 +141,58 @@ static int Penta_nbN [] = { 3, 3, 4, 4, 4 }; // N0+----------+N3 */ static int Hexa_F [6][5] = { // FORWARD - { 0, 1, 2, 3, 0 }, // opposite faces are neighbouring, - { 4, 5, 6, 7, 4 }, // odd face(1,3,5) normal is internal, even(0,2,4) - external - { 1, 0, 4, 5, 1 }, // same index nodes of opposite faces are linked - { 2, 3, 7, 6, 2 }, - { 0, 3, 7, 4, 0 }, - { 1, 2, 6, 5, 1 }}; -// static int Hexa_R [6][5] = { // REVERSED -// { 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, -// { 4, 7, 6, 5, 4 }, // odd face(1,3,5) normal is external, even(0,2,4) - internal -// { 1, 5, 4, 0, 1 }, // same index nodes of opposite faces are linked -// { 2, 6, 7, 3, 2 }, -// { 0, 4, 7, 3, 0 }, -// { 1, 5, 6, 2, 1 }}; -static int Hexa_FE [6][5] = { // FORWARD -> EXTERNAL - { 0, 1, 2, 3, 0 } , // opposite faces are neighbouring, - { 4, 7, 6, 5, 4 }, // all face normals are external, - { 0, 4, 5, 1, 0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 0, 1, 2, 3, 0 }, + { 4, 7, 6, 5, 4 }, // all face normals are external + { 0, 4, 5, 1, 0 }, + { 1, 5, 6, 2, 1 }, { 3, 2, 6, 7, 3 }, - { 0, 3, 7, 4, 0 }, - { 1, 5, 6, 2, 1 }}; + { 0, 3, 7, 4, 0 }}; static int Hexa_RE [6][5] = { // REVERSED -> EXTERNAL - { 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, - { 4, 5, 6, 7, 4 }, // all face normals are external, - { 0, 1, 5, 4, 0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 0, 3, 2, 1, 0 }, + { 4, 5, 6, 7, 4 }, // all face normals are external + { 0, 1, 5, 4, 0 }, + { 1, 2, 6, 5, 1 }, { 3, 7, 6, 2, 3 }, - { 0, 4, 7, 3, 0 }, - { 1, 2, 6, 5, 1 }}; + { 0, 4, 7, 3, 0 }}; static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 }; +/* +// N8 +------+ N9 +// / \ +// / \ +// N7 + + N10 +// \ / +// \ / +// N6 +------+ N11 +// HEXAGONAL PRISM +// N2 +------+ N3 +// / \ +// / \ +// N1 + + N4 +// \ / +// \ / +// N0 +------+ N5 +*/ +static int HexPrism_F [8][7] = { // FORWARD + { 0, 1, 2, 3, 4, 5, 0 }, + { 6,11,10, 9, 8, 7, 6 }, + { 0, 6, 7, 1, 0, 0, 0 }, + { 1, 7, 8, 2, 1, 1, 1 }, + { 2, 8, 9, 3, 2, 2, 2 }, + { 3, 9,10, 4, 3, 3, 3 }, + { 4,10,11, 5, 4, 4, 4 }, + { 5,11, 6, 0, 5, 5, 5 }}; +static int HexPrism_RE [8][7] = { // REVERSED -> EXTERNAL + { 0, 5, 4, 3, 2, 1, 0 }, + { 6,11,10, 9, 8, 7, 6 }, + { 0, 6, 7, 1, 0, 0, 0 }, + { 1, 7, 8, 2, 1, 1, 1 }, + { 2, 8, 9, 3, 2, 2, 2 }, + { 3, 9,10, 4, 3, 3, 3 }, + { 4,10,11, 5, 4, 4, 4 }, + { 5,11, 6, 0, 5, 5, 5 }}; +static int HexPrism_nbN [] = { 6, 6, 4, 4, 4, 4, 4, 4 }; + /* // N3 @@ -202,18 +208,13 @@ static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 }; // + // N2 */ -static int QuadTetra_F [4][7] = { // FORWARD == EXTERNAL +static int QuadTetra_F [4][7] = { // FORWARD { 0, 4, 1, 5, 2, 6, 0 }, // All faces have external normals { 0, 7, 3, 8, 1, 4, 0 }, { 1, 8, 3, 9, 2, 5, 1 }, { 0, 6, 2, 9, 3, 7, 0 }}; -static int QuadTetra_R [4][7] = { // REVERSED - { 0, 4, 1, 5, 2, 6, 0 }, // All faces but a bottom have external normals - { 0, 4, 1, 8, 3, 7, 0 }, - { 1, 5, 2, 9, 3, 8, 1 }, - { 0, 7, 3, 9, 2, 6, 0 }}; static int QuadTetra_RE [4][7] = { // REVERSED -> FORWARD (EXTERNAL) - { 0, 6, 2, 5, 1, 4, 0 }, // All faces have external normals + { 0, 6, 2, 5, 1, 4, 0 }, // All faces have external normals { 0, 4, 1, 8, 3, 7, 0 }, { 1, 5, 2, 9, 3, 8, 1 }, { 0, 7, 3, 9, 2, 6, 0 }}; @@ -240,18 +241,12 @@ static int QuadTetra_nbN [] = { 6, 6, 6, 6 }; // | | // 0+----+----+3 // 8 -static int QuadPyram_F [5][9] = { // FORWARD == EXTERNAL +static int QuadPyram_F [5][9] = { // FORWARD { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces have external normals { 0, 9, 4, 10,1, 5, 0, 4, 4 }, { 1, 10,4, 11,2, 6, 1, 4, 4 }, { 2, 11,4, 12,3, 7, 2, 4, 4 }, { 3, 12,4, 9, 0, 8, 3, 4, 4 }}; -static int QuadPyram_R [5][9] = { // REVERSED - { 0, 5, 1, 6, 2, 7, 3, 8, 0 }, // All faces but a bottom have external normals - { 0, 5, 1, 10,4, 9, 0, 4, 4 }, - { 1, 6, 2, 11,4, 10,1, 4, 4 }, - { 2, 7, 3, 12,4, 11,2, 4, 4 }, - { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL) { 0, 8, 3, 7, 2, 6, 1, 5, 0 }, // All faces but a bottom have external normals { 0, 5, 1, 10,4, 9, 0, 4, 4 }, @@ -271,9 +266,6 @@ static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 }; // | | | // | +13 | QUADRATIC // | | | PENTAHEDRON -// | | | -// | | | -// | | | // 12+ | +14 // | | | // | | | @@ -286,29 +278,17 @@ static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 }; // 8 */ static int QuadPenta_F [5][9] = { // FORWARD - { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Top face has an internal normal, other - external - { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face - { 0, 8, 2, 14,5, 11,3, 12,0 }, - { 1, 13,4, 10,5, 14,2, 7, 1 }, - { 0, 12,3, 9, 4, 13,1, 6, 0 }}; -static int QuadPenta_R [5][9] = { // REVERSED - { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, // Bottom face has an internal normal, other - external - { 3, 9, 4, 10,5, 11,3, 3, 3 }, // 0 is bottom, 1 is top face - { 0, 12,3, 11,5, 14,2, 8, 0 }, - { 1, 7, 2, 14,5, 10,4, 13,1 }, - { 0, 6, 1, 13,4, 9, 3, 12,0 }}; -static int QuadPenta_FE [5][9] = { // FORWARD -> EXTERNAL { 0, 6, 1, 7, 2, 8, 0, 0, 0 }, { 3,11, 5, 10,4, 9, 3, 3, 3 }, - { 0, 8, 2, 14,5, 11,3, 12,0 }, + { 0, 12,3, 9, 4, 13,1, 6, 0 }, { 1, 13,4, 10,5, 14,2, 7, 1 }, - { 0, 12,3, 9, 4, 13,1, 6, 0 }}; + { 0, 8, 2, 14,5, 11,3, 12,0 }}; static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL { 0, 8, 2, 7, 1, 6, 0, 0, 0 }, { 3, 9, 4, 10,5, 11,3, 3, 3 }, - { 0, 12,3, 11,5, 14,2, 8, 0 }, + { 0, 6, 1, 13,4, 9, 3, 12,0 }, { 1, 7, 2, 14,5, 10,4, 13,1 }, - { 0, 6, 1, 13,4, 9, 3, 12,0 }}; + { 0, 12,3, 11,5, 14,2, 8, 0 }}; static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 }; /* @@ -335,39 +315,43 @@ static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 }; // 11 */ static int QuadHexa_F [6][9] = { // FORWARD - { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, - { 4, 12,5, 13,6, 14,7, 15,4 }, // odd face(1,3,5) normal is internal, even(0,2,4) - external - { 1, 8, 0, 16,4, 12,5, 17,1 }, // same index nodes of opposite faces are linked - { 2, 10,3, 19,7, 14,6, 18,2 }, - { 0, 11,3, 19,7, 15,4, 16,0 }, - { 1, 9, 2, 18,6, 13,5, 17,1 }}; -// static int Hexa_R [6][5] = { // REVERSED -// { 0, 3, 2, 1, 0 }, // opposite faces are neighbouring, -// { 4, 7, 6, 5, 4 }, // odd face(1,3,5) normal is external, even(0,2,4) - internal -// { 1, 5, 4, 0, 1 }, // same index nodes of opposite faces are linked -// { 2, 6, 7, 3, 2 }, -// { 0, 4, 7, 3, 0 }, -// { 1, 5, 6, 2, 1 }}; -static int QuadHexa_FE [6][9] = { // FORWARD -> EXTERNAL - { 0, 8, 1, 9, 2, 10,3, 11,0 }, // opposite faces are neighbouring, - { 4, 15,7, 14,6, 13,5, 12,4 }, // all face normals are external, - { 0, 16,4, 12,5, 17,1, 8, 0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 0, 8, 1, 9, 2, 10,3, 11,0 }, // all face normals are external, + { 4, 15,7, 14,6, 13,5, 12,4 }, + { 0, 16,4, 12,5, 17,1, 8, 0 }, + { 1, 17,5, 13,6, 18,2, 9, 1 }, { 3, 10,2, 18,6, 14,7, 19,3 }, - { 0, 11,3, 19,7, 15,4, 16,0 }, - { 1, 17,5, 13,6, 18,2, 9, 1 }}; + { 0, 11,3, 19,7, 15,4, 16,0 }}; static int QuadHexa_RE [6][9] = { // REVERSED -> EXTERNAL - { 0, 11,3, 10,2, 9, 1, 8, 0 }, // opposite faces are neighbouring, - { 4, 12,5, 13,6, 14,7, 15,4 }, // all face normals are external, - { 0, 8, 1, 17,5, 12,4, 16,0 }, // links in opposite faces: 0-0, 1-3, 2-2, 3-1 + { 0, 11,3, 10,2, 9, 1, 8, 0 }, // all face normals are external + { 4, 12,5, 13,6, 14,7, 15,4 }, + { 0, 8, 1, 17,5, 12,4, 16,0 }, + { 1, 9, 2, 18,6, 13,5, 17,1 }, { 3, 19,7, 14,6, 18,2, 10,3 }, - { 0, 16,4, 15,7, 19,3, 11,0 }, - { 1, 9, 2, 18,6, 13,5, 17,1 }}; + { 0, 16,4, 15,7, 19,3, 11,0 }}; static int QuadHexa_nbN [] = { 8, 8, 8, 8, 8, 8 }; +static int TriQuadHexa_F [6][9] = { // FORWARD + { 0, 8, 1, 9, 2, 10,3, 11, 20 }, // all face normals are external + { 4, 15,7, 14,6, 13,5, 12, 25 }, + { 0, 16,4, 12,5, 17,1, 8, 21 }, + { 1, 17,5, 13,6, 18,2, 9, 22 }, + { 3, 10,2, 18,6, 14,7, 19, 23 }, + { 0, 11,3, 19,7, 15,4, 16, 24 }}; +static int TriQuadHexa_RE [6][9] = { // REVERSED -> EXTERNAL + { 0, 11,3, 10,2, 9, 1, 8, 20 }, // opposite faces are neighbouring, + { 4, 12,5, 13,6, 14,7, 15, 25 }, // all face normals are external + { 0, 8, 1, 17,5, 12,4, 16, 21 }, + { 1, 9, 2, 18,6, 13,5, 17, 22 }, + { 3, 19,7, 14,6, 18,2, 10, 23 }, + { 0, 16,4, 15,7, 19,3, 11, 24 }}; +static int TriQuadHexa_nbN [] = { 9, 9, 9, 9, 9, 9 }; + // ======================================================== // to perform some calculations without linkage to CASCADE // ======================================================== +namespace +{ struct XYZ { double x; double y; @@ -376,25 +360,56 @@ struct XYZ { XYZ( double X, double Y, double Z ) { x = X; y = Y; z = Z; } XYZ( const XYZ& other ) { x = other.x; y = other.y; z = other.z; } XYZ( const SMDS_MeshNode* n ) { x = n->X(); y = n->Y(); z = n->Z(); } - XYZ operator-( const XYZ& other ); - XYZ Crossed( const XYZ& other ); - double Dot( const XYZ& other ); - double Magnitude(); + inline XYZ operator-( const XYZ& other ); + inline XYZ operator+( const XYZ& other ); + inline XYZ Crossed( const XYZ& other ); + inline double Dot( const XYZ& other ); + inline double Magnitude(); + inline double SquareMagnitude(); }; -XYZ XYZ::operator-( const XYZ& Right ) { +inline XYZ XYZ::operator-( const XYZ& Right ) { return XYZ(x - Right.x, y - Right.y, z - Right.z); } -XYZ XYZ::Crossed( const XYZ& Right ) { +inline XYZ XYZ::operator+( const XYZ& Right ) { + return XYZ(x + Right.x, y + Right.y, z + Right.z); +} +inline XYZ XYZ::Crossed( const XYZ& Right ) { return XYZ (y * Right.z - z * Right.y, z * Right.x - x * Right.z, x * Right.y - y * Right.x); } -double XYZ::Dot( const XYZ& Other ) { +inline double XYZ::Dot( const XYZ& Other ) { return(x * Other.x + y * Other.y + z * Other.z); } -double XYZ::Magnitude() { +inline double XYZ::Magnitude() { return sqrt (x * x + y * y + z * z); } +inline double XYZ::SquareMagnitude() { + return (x * x + y * y + z * z); +} + + //================================================================================ + /*! + * \brief Return linear type corresponding to a quadratic one + */ + //================================================================================ + + SMDS_VolumeTool::VolumeType quadToLinear(SMDS_VolumeTool::VolumeType quadType) + { + SMDS_VolumeTool::VolumeType linType = SMDS_VolumeTool::VolumeType( int(quadType)-4 ); + const int nbCornersByQuad = SMDS_VolumeTool::NbCornerNodes( quadType ); + if ( SMDS_VolumeTool::NbCornerNodes( linType ) == nbCornersByQuad ) + return linType; + + int iLin = 0; + for ( ; iLin < SMDS_VolumeTool::NB_VOLUME_TYPES; ++iLin ) + if ( SMDS_VolumeTool::NbCornerNodes( SMDS_VolumeTool::VolumeType( iLin )) == nbCornersByQuad) + return SMDS_VolumeTool::VolumeType( iLin ); + + return SMDS_VolumeTool::UNKNOWN; + } + +} // namespace //======================================================================= //function : SMDS_VolumeTool @@ -402,18 +417,10 @@ double XYZ::Magnitude() { //======================================================================= SMDS_VolumeTool::SMDS_VolumeTool () - : myVolume( 0 ), - myPolyedre( 0 ), - myVolForward( true ), - myNbFaces( 0 ), - myVolumeNbNodes( 0 ), - myVolumeNodes( NULL ), - myExternalFaces( false ), - myFaceNbNodes( 0 ), - myCurFace( -1 ), - myFaceNodeIndices( NULL ), - myFaceNodes( NULL ) + : myVolumeNodes( NULL ), + myFaceNodes( NULL ) { + Set( 0 ); } //======================================================================= @@ -421,20 +428,12 @@ SMDS_VolumeTool::SMDS_VolumeTool () //purpose : //======================================================================= -SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume) - : myVolume( 0 ), - myPolyedre( 0 ), - myVolForward( true ), - myNbFaces( 0 ), - myVolumeNbNodes( 0 ), - myVolumeNodes( NULL ), - myExternalFaces( false ), - myFaceNbNodes( 0 ), - myCurFace( -1 ), - myFaceNodeIndices( NULL ), - myFaceNodes( NULL ) +SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume, + const bool ignoreCentralNodes) + : myVolumeNodes( NULL ), + myFaceNodes( NULL ) { - Set( theVolume ); + Set( theVolume, ignoreCentralNodes ); } //======================================================================= @@ -444,14 +443,11 @@ SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume) SMDS_VolumeTool::~SMDS_VolumeTool() { - if (myVolumeNodes != NULL) { - delete [] myVolumeNodes; - myVolumeNodes = NULL; - } - if (myFaceNodes != NULL) { - delete [] myFaceNodes; - myFaceNodes = NULL; - } + if ( myVolumeNodes != NULL ) delete [] myVolumeNodes; + if ( myFaceNodes != NULL ) delete [] myFaceNodes; + + myFaceNodeIndices = NULL; + myVolumeNodes = myFaceNodes = NULL; } //======================================================================= @@ -459,10 +455,13 @@ SMDS_VolumeTool::~SMDS_VolumeTool() //purpose : Set volume to iterate on //======================================================================= -bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume) +bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume, + const bool ignoreCentralNodes) { + // reset fields myVolume = 0; myPolyedre = 0; + myIgnoreCentralNodes = ignoreCentralNodes; myVolForward = true; myNbFaces = 0; @@ -471,66 +470,63 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume) delete [] myVolumeNodes; myVolumeNodes = NULL; } + myPolyIndices.clear(); myExternalFaces = false; - myFaceNbNodes = 0; + + myAllFacesNodeIndices_F = 0; + //myAllFacesNodeIndices_FE = 0; + myAllFacesNodeIndices_RE = 0; + myAllFacesNbNodes = 0; myCurFace = -1; + myFaceNbNodes = 0; myFaceNodeIndices = NULL; if (myFaceNodes != NULL) { delete [] myFaceNodes; myFaceNodes = NULL; } - if ( theVolume && theVolume->GetType() == SMDSAbs_Volume ) - { - myVolume = theVolume; + // set volume data + if ( !theVolume || theVolume->GetType() != SMDSAbs_Volume ) + return false; - myNbFaces = theVolume->NbFaces(); - myVolumeNbNodes = theVolume->NbNodes(); + myVolume = theVolume; + if (myVolume->IsPoly()) + myPolyedre = dynamic_cast( myVolume ); - // set volume nodes - int iNode = 0; - myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes]; - SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator(); - while ( nodeIt->more() ) { - myVolumeNodes[ iNode++ ] = static_cast( nodeIt->next() ); - } + myNbFaces = theVolume->NbFaces(); + myVolumeNbNodes = theVolume->NbNodes(); - if (myVolume->IsPoly()) { - myPolyedre = static_cast( myVolume ); - if (!myPolyedre) { - MESSAGE("Warning: bad volumic element"); - return false; - } - } - else { - switch ( myVolumeNbNodes ) { - case 4: - case 5: - case 6: - case 8: - case 10: - case 13: - case 15: - case 20: { - // define volume orientation - XYZ botNormal; - GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z ); - const SMDS_MeshNode* topNode = myVolumeNodes[ myVolumeNbNodes - 1 ]; - const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ]; - XYZ upDir (topNode->X() - botNode->X(), - topNode->Y() - botNode->Y(), - topNode->Z() - botNode->Z() ); - myVolForward = ( botNormal.Dot( upDir ) < 0 ); - break; - } - default: - break; - } - } + // set nodes + int iNode = 0; + myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes]; + SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator(); + while ( nodeIt->more() ) + myVolumeNodes[ iNode++ ] = static_cast( nodeIt->next() ); + + // check validity + if ( !setFace(0) ) + return ( myVolume = 0 ); + + if ( !myPolyedre ) + { + // define volume orientation + XYZ botNormal; + GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z ); + const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ]; + int topNodeIndex = myVolume->NbCornerNodes() - 1; + while ( !IsLinked( 0, topNodeIndex, /*ignoreMediumNodes=*/true )) --topNodeIndex; + const SMDS_MeshNode* topNode = myVolumeNodes[ topNodeIndex ]; + XYZ upDir (topNode->X() - botNode->X(), + topNode->Y() - botNode->Y(), + topNode->Z() - botNode->Z() ); + myVolForward = ( botNormal.Dot( upDir ) < 0 ); + + if ( !myVolForward ) + myCurFace = -1; // previous setFace(0) didn't take myVolForward into account } - return ( myVolume != 0 ); + return true; } //======================================================================= @@ -572,6 +568,12 @@ void SMDS_VolumeTool::Inverse () SWAP_NODES( myVolumeNodes, 1, 3 ); SWAP_NODES( myVolumeNodes, 5, 7 ); break; + case 12: + SWAP_NODES( myVolumeNodes, 1, 5 ); + SWAP_NODES( myVolumeNodes, 2, 4 ); + SWAP_NODES( myVolumeNodes, 7, 11 ); + SWAP_NODES( myVolumeNodes, 8, 10 ); + break; case 10: SWAP_NODES( myVolumeNodes, 1, 2 ); @@ -600,6 +602,17 @@ void SMDS_VolumeTool::Inverse () SWAP_NODES( myVolumeNodes, 13, 14 ); SWAP_NODES( myVolumeNodes, 17, 19 ); break; + case 27: + SWAP_NODES( myVolumeNodes, 1, 3 ); + SWAP_NODES( myVolumeNodes, 5, 7 ); + SWAP_NODES( myVolumeNodes, 8, 11 ); + SWAP_NODES( myVolumeNodes, 9, 10 ); + SWAP_NODES( myVolumeNodes, 12, 15 ); + SWAP_NODES( myVolumeNodes, 13, 14 ); + SWAP_NODES( myVolumeNodes, 17, 19 ); + SWAP_NODES( myVolumeNodes, 21, 24 ); + SWAP_NODES( myVolumeNodes, 22, 23 ); + break; default:; } } @@ -614,26 +627,18 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const if ( myPolyedre ) return POLYHEDA; - if ( myVolume ) { -// static const VolumeType types[] = { -// TETRA, // myVolumeNbNodes = 4 -// PYRAM, // myVolumeNbNodes = 5 -// PENTA, // myVolumeNbNodes = 6 -// UNKNOWN, // myVolumeNbNodes = 7 -// HEXA // myVolumeNbNodes = 8 -// }; -// return types[ myVolumeNbNodes - 4 ]; - switch(myVolumeNbNodes) { - case 4: return TETRA; break; - case 5: return PYRAM; break; - case 6: return PENTA; break; - case 8: return HEXA; break; - case 10: return QUAD_TETRA; break; - case 13: return QUAD_PYRAM; break; - case 15: return QUAD_PENTA; break; - case 20: return QUAD_HEXA; break; - default: break; - } + switch( myVolumeNbNodes ) { + case 4: return TETRA; + case 5: return PYRAM; + case 6: return PENTA; + case 8: return HEXA; + case 12: return HEX_PRISM; + case 10: return QUAD_TETRA; + case 13: return QUAD_PYRAM; + case 15: return QUAD_PENTA; + case 20: return QUAD_HEXA; + case 27: return QUAD_HEXA; + default: break; } return UNKNOWN; @@ -693,30 +698,29 @@ double SMDS_VolumeTool::GetSize() const // split a polyhedron into tetrahedrons + int saveCurFace = myCurFace; SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this ); - XYZ baryCenter; - me->GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z); - SMDS_MeshNode bcNode ( baryCenter.x, baryCenter.y, baryCenter.z ); - for ( int f = 0; f < NbFaces(); ++f ) { - bool externalFace = me->IsFaceExternal( f ); // it calls setFace() - for ( int n = 2; n < myFaceNbNodes; ++n ) + me->setFace( f ); + XYZ area (0,0,0), p1( myFaceNodes[0] ); + for ( int n = 0; n < myFaceNbNodes; ++n ) { - double Vn = getTetraVolume( myFaceNodes[ 0 ], - myFaceNodes[ n-1 ], - myFaceNodes[ n ], - & bcNode ); -/// cout <<"++++ " << Vn << " nodes " <GetID() << " " <GetID() << " " <GetID() << " < " << V << endl; - V += externalFace ? -Vn : Vn; + XYZ p2( myFaceNodes[ n+1 ]); + area = area + p1.Crossed( p2 ); + p1 = p2; } + V += p1.Dot( area ); } + V /= 6; + if ( saveCurFace > -1 && saveCurFace != myCurFace ) + me->setFace( myCurFace ); } else { const static int ind[] = { - 0, 1, 3, 6, 11, 19, 32, 46, 66}; - const static int vtab[][4] = { + 0, 1, 3, 6, 11, 23, 31, 44, 58, 78 }; + const static int vtab[][4] = { // decomposition into tetra in the order of enum VolumeType // tetrahedron { 0, 1, 2, 3 }, // pyramid @@ -732,6 +736,22 @@ double SMDS_VolumeTool::GetSize() const { 1, 3, 6, 2 }, { 4, 6, 3, 7 }, { 1, 4, 6, 3 }, + // hexagonal prism + { 0, 1, 2, 7 }, + { 0, 7, 8, 6 }, + { 2, 7, 8, 0 }, + + { 0, 3, 4, 9 }, + { 0, 9, 10, 6 }, + { 4, 9, 10, 0 }, + + { 0, 3, 4, 9 }, + { 0, 9, 10, 6 }, + { 4, 9, 10, 0 }, + + { 0, 4, 5, 10 }, + { 0, 10, 11, 6 }, + { 5, 10, 11, 0 }, // quadratic tetrahedron { 0, 4, 6, 7 }, @@ -837,6 +857,32 @@ bool SMDS_VolumeTool::GetBaryCenter(double & X, double & Y, double & Z) const return true; } +//================================================================================ +/*! + * \brief Classify a point + * \param tol - thickness of faces + */ +//================================================================================ + +bool SMDS_VolumeTool::IsOut(double X, double Y, double Z, double tol) const +{ + // LIMITATION: for convex volumes only + XYZ p( X,Y,Z ); + for ( int iF = 0; iF < myNbFaces; ++iF ) + { + XYZ faceNormal; + if ( !GetFaceNormal( iF, faceNormal.x, faceNormal.y, faceNormal.z )) + continue; + if ( !IsFaceExternal( iF )) + faceNormal = XYZ() - faceNormal; // reverse + + XYZ face2p( p - XYZ( myFaceNodes[0] )); + if ( face2p.Dot( faceNormal ) > tol ) + return true; + } + return false; +} + //======================================================================= //function : SetExternalNormal //purpose : Node order will be so that faces normals are external @@ -853,7 +899,7 @@ void SMDS_VolumeTool::SetExternalNormal () //purpose : Return number of nodes in the array of face nodes //======================================================================= -int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) +int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) const { if ( !setFace( faceIndex )) return 0; @@ -868,7 +914,7 @@ int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) // the last node == the first one. //======================================================================= -const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) +const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) const { if ( !setFace( faceIndex )) return 0; @@ -883,14 +929,19 @@ const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) // the last node index == the first one. //======================================================================= -const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) +const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) const { - if (myVolume->IsPoly()) { - MESSAGE("Warning: attempt to obtain FaceNodesIndices of polyhedral volume"); - return NULL; - } if ( !setFace( faceIndex )) return 0; + + if (myPolyedre) + { + SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this ); + me->myPolyIndices.resize( myFaceNbNodes + 1 ); + me->myFaceNodeIndices = & me->myPolyIndices[0]; + for ( int i = 0; i <= myFaceNbNodes; ++i ) + me->myFaceNodeIndices[i] = myVolume->GetNodeIndex( myFaceNodes[i] ); + } return myFaceNodeIndices; } @@ -900,25 +951,23 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) //======================================================================= bool SMDS_VolumeTool::GetFaceNodes (int faceIndex, - set& theFaceNodes ) + set& theFaceNodes ) const { if ( !setFace( faceIndex )) return false; theFaceNodes.clear(); - int iNode, nbNode = myFaceNbNodes; - for ( iNode = 0; iNode < nbNode; iNode++ ) - theFaceNodes.insert( myFaceNodes[ iNode ]); + theFaceNodes.insert( myFaceNodes, myFaceNodes + myFaceNbNodes ); return true; } //======================================================================= //function : IsFaceExternal -//purpose : Check normal orientation of a returned face +//purpose : Check normal orientation of a given face //======================================================================= -bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) +bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const { if ( myExternalFaces || !myVolume ) return true; @@ -933,26 +982,29 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) return true; } - switch ( myVolumeNbNodes ) { - case 4: - case 5: - case 10: - case 13: - // only the bottom of a reversed tetrahedron can be internal - return ( myVolForward || faceIndex != 0 ); - case 6: - case 15: - // in a forward pentahedron, the top is internal, in a reversed one - bottom - return ( myVolForward ? faceIndex != 1 : faceIndex != 0 ); - case 8: - case 20: { - // in a forward hexahedron, even face normal is external, odd - internal - bool odd = faceIndex % 2; - return ( myVolForward ? !odd : odd ); - } - default:; - } - return false; + // switch ( myVolumeNbNodes ) { + // case 4: + // case 5: + // case 10: + // case 13: + // // only the bottom of a reversed tetrahedron can be internal + // return ( myVolForward || faceIndex != 0 ); + // case 6: + // case 15: + // case 12: + // // in a forward prism, the top is internal, in a reversed one - bottom + // return ( myVolForward ? faceIndex != 1 : faceIndex != 0 ); + // case 8: + // case 20: + // case 27: { + // // in a forward hexahedron, even face normal is external, odd - internal + // bool odd = faceIndex % 2; + // return ( myVolForward ? !odd : odd ); + // } + // default:; + // } + // return false; + return true; } //======================================================================= @@ -960,30 +1012,28 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) //purpose : Return a normal to a face //======================================================================= -bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) +bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) const { if ( !setFace( faceIndex )) return false; - XYZ p1 ( myFaceNodes[0] ); - XYZ p2 ( myFaceNodes[1] ); - XYZ p3 ( myFaceNodes[2] ); + const int iQuad = ( myFaceNbNodes > 6 && !myPolyedre ) ? 2 : 1; + XYZ p1 ( myFaceNodes[0*iQuad] ); + XYZ p2 ( myFaceNodes[1*iQuad] ); + XYZ p3 ( myFaceNodes[2*iQuad] ); XYZ aVec12( p2 - p1 ); XYZ aVec13( p3 - p1 ); XYZ cross = aVec12.Crossed( aVec13 ); - //if ( myFaceNbNodes == 4 ) { - if ( myFaceNbNodes >3 ) { - XYZ p4 ( myFaceNodes[3] ); + if ( myFaceNbNodes >3*iQuad ) { + XYZ p4 ( myFaceNodes[3*iQuad] ); XYZ aVec14( p4 - p1 ); XYZ cross2 = aVec13.Crossed( aVec14 ); - cross.x += cross2.x; - cross.y += cross2.y; - cross.z += cross2.z; + cross = cross + cross2; } double size = cross.Magnitude(); - if ( size <= DBL_MIN ) + if ( size <= numeric_limits::min() ) return false; X = cross.x / size; @@ -993,12 +1043,33 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub return true; } +//================================================================================ +/*! + * \brief Return barycenter of a face + */ +//================================================================================ + +bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const +{ + if ( !setFace( faceIndex )) + return false; + + X = Y = Z = 0.0; + for ( int i = 0; i < myFaceNbNodes; ++i ) + { + X += myFaceNodes[i]->X() / myFaceNbNodes; + Y += myFaceNodes[i]->Y() / myFaceNbNodes; + Z += myFaceNodes[i]->Z() / myFaceNbNodes; + } + return true; +} + //======================================================================= //function : GetFaceArea //purpose : Return face area //======================================================================= -double SMDS_VolumeTool::GetFaceArea( int faceIndex ) +double SMDS_VolumeTool::GetFaceArea( int faceIndex ) const { if (myVolume->IsPoly()) { MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume"); @@ -1023,6 +1094,26 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex ) return area; } +//================================================================================ +/*! + * \brief Return index of the node located at face center of a quadratic element like HEX27 + */ +//================================================================================ + +int SMDS_VolumeTool::GetCenterNodeIndex( int faceIndex ) const +{ + if ( myAllFacesNbNodes && myVolumeNbNodes == 27 ) // classic element with 27 nodes + { + switch ( faceIndex ) { + case 0: return 20; + case 1: return 25; + default: + return faceIndex + 19; + } + } + return -1; +} + //======================================================================= //function : GetOppFaceIndex //purpose : Return index of the opposite face if it exists, else -1. @@ -1031,19 +1122,37 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex ) int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const { int ind = -1; - if (myVolume->IsPoly()) { + if (myPolyedre) { MESSAGE("Warning: attempt to obtain opposite face on polyhedral volume"); return ind; } + const int nbHoriFaces = 2; + if ( faceIndex >= 0 && faceIndex < NbFaces() ) { switch ( myVolumeNbNodes ) { case 6: + case 15: if ( faceIndex == 0 || faceIndex == 1 ) ind = 1 - faceIndex; break; case 8: - ind = faceIndex + ( faceIndex % 2 ? -1 : 1 ); + case 12: + if ( faceIndex <= 1 ) // top or bottom + ind = 1 - faceIndex; + else { + const int nbSideFaces = myAllFacesNbNodes[0]; + ind = ( faceIndex - nbHoriFaces + nbSideFaces/2 ) % nbSideFaces + nbHoriFaces; + } + break; + case 20: + case 27: + if ( faceIndex <= 1 ) // top or bottom + ind = 1 - faceIndex; + else { + const int nbSideFaces = myAllFacesNbNodes[0] / 2; + ind = ( faceIndex - nbHoriFaces + nbSideFaces/2 ) % nbSideFaces + nbHoriFaces; + } break; default:; } @@ -1054,10 +1163,12 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const //======================================================================= //function : IsLinked //purpose : return true if theNode1 is linked with theNode2 +// If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well //======================================================================= bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, - const SMDS_MeshNode* theNode2) const + const SMDS_MeshNode* theNode2, + const bool theIgnoreMediumNodes) const { if ( !myVolume ) return false; @@ -1090,12 +1201,13 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, } // find nodes indices - int i1 = -1, i2 = -1; - for ( int i = 0; i < myVolumeNbNodes; i++ ) { + int i1 = -1, i2 = -1, nbFound = 0; + for ( int i = 0; i < myVolumeNbNodes && nbFound < 2; i++ ) + { if ( myVolumeNodes[ i ] == theNode1 ) - i1 = i; + i1 = i, ++nbFound; else if ( myVolumeNodes[ i ] == theNode2 ) - i2 = i; + i2 = i, ++nbFound; } return IsLinked( i1, i2 ); } @@ -1104,10 +1216,12 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, //function : IsLinked //purpose : return true if the node with theNode1Index is linked // with the node with theNode2Index +// If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well //======================================================================= bool SMDS_VolumeTool::IsLinked (const int theNode1Index, - const int theNode2Index) const + const int theNode2Index, + bool theIgnoreMediumNodes) const { if ( myVolume->IsPoly() ) { return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]); @@ -1119,10 +1233,33 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, if ( minInd < 0 || maxInd > myVolumeNbNodes - 1 || maxInd == minInd ) return false; - switch ( myVolumeNbNodes ) { - case 4: + VolumeType type = GetVolumeType(); + if ( myVolume->IsQuadratic() ) + { + int firstMediumInd = myVolume->NbCornerNodes(); + if ( minInd >= firstMediumInd ) + return false; // both nodes are medium - not linked + if ( maxInd < firstMediumInd ) // both nodes are corners + { + if ( theIgnoreMediumNodes ) + type = quadToLinear(type); // to check linkage of corner nodes only + else + return false; // corner nodes are not linked directly in a quadratic cell + } + } + + switch ( type ) { + case TETRA: return true; - case 5: + case HEXA: + switch ( maxInd - minInd ) { + case 1: return minInd != 3; + case 3: return minInd == 0 || minInd == 4; + case 4: return true; + default:; + } + break; + case PYRAM: if ( maxInd == 4 ) return true; switch ( maxInd - minInd ) { @@ -1131,7 +1268,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, default:; } break; - case 6: + case PENTA: switch ( maxInd - minInd ) { case 1: return minInd != 2; case 2: return minInd == 0 || minInd == 3; @@ -1139,15 +1276,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, default:; } break; - case 8: - switch ( maxInd - minInd ) { - case 1: return minInd != 3; - case 3: return minInd == 0 || minInd == 4; - case 4: return true; - default:; - } - break; - case 10: + case QUAD_TETRA: { switch ( minInd ) { case 0: if( maxInd==4 || maxInd==6 || maxInd==7 ) return true; @@ -1158,7 +1287,22 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, } break; } - case 13: + case QUAD_HEXA: + { + switch ( minInd ) { + case 0: if( maxInd==8 || maxInd==11 || maxInd==16 ) return true; + case 1: if( maxInd==8 || maxInd==9 || maxInd==17 ) return true; + case 2: if( maxInd==9 || maxInd==10 || maxInd==18 ) return true; + case 3: if( maxInd==10 || maxInd==11 || maxInd==19 ) return true; + case 4: if( maxInd==12 || maxInd==15 || maxInd==16 ) return true; + case 5: if( maxInd==12 || maxInd==13 || maxInd==17 ) return true; + case 6: if( maxInd==13 || maxInd==14 || maxInd==18 ) return true; + case 7: if( maxInd==14 || maxInd==15 || maxInd==19 ) return true; + default:; + } + break; + } + case QUAD_PYRAM: { switch ( minInd ) { case 0: if( maxInd==5 || maxInd==8 || maxInd==9 ) return true; @@ -1170,7 +1314,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, } break; } - case 15: + case QUAD_PENTA: { switch ( minInd ) { case 0: if( maxInd==6 || maxInd==8 || maxInd==12 ) return true; @@ -1183,20 +1327,12 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, } break; } - case 20: + case HEX_PRISM: { - switch ( minInd ) { - case 0: if( maxInd==8 || maxInd==11 || maxInd==16 ) return true; - case 1: if( maxInd==8 || maxInd==9 || maxInd==17 ) return true; - case 2: if( maxInd==9 || maxInd==10 || maxInd==18 ) return true; - case 3: if( maxInd==10 || maxInd==11 || maxInd==19 ) return true; - case 4: if( maxInd==12 || maxInd==15 || maxInd==16 ) return true; - case 5: if( maxInd==12 || maxInd==13 || maxInd==17 ) return true; - case 6: if( maxInd==13 || maxInd==14 || maxInd==18 ) return true; - case 7: if( maxInd==14 || maxInd==15 || maxInd==19 ) return true; - default:; - } - break; + const int diff = maxInd-minInd; + if ( diff > 6 ) return false;// not linked top and bottom + if ( diff == 6 ) return true; // linked top and bottom + return diff == 1 || diff == 7; } default:; } @@ -1227,10 +1363,9 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const */ //================================================================================ -int SMDS_VolumeTool::GetAllExistingFaces(vector & faces) +int SMDS_VolumeTool::GetAllExistingFaces(vector & faces) const { faces.clear(); - faces.reserve( NbFaces() ); for ( int iF = 0; iF < NbFaces(); ++iF ) { const SMDS_MeshFace* face = 0; const SMDS_MeshNode** nodes = GetFaceNodes( iF ); @@ -1265,7 +1400,7 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector & edges { edges.clear(); edges.reserve( myVolumeNbNodes * 2 ); - for ( int i = 0; i < myVolumeNbNodes; ++i ) { + for ( int i = 0; i < myVolumeNbNodes-1; ++i ) { for ( int j = i + 1; j < myVolumeNbNodes; ++j ) { if ( IsLinked( i, j )) { const SMDS_MeshElement* edge = @@ -1278,47 +1413,83 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector & edges return edges.size(); } -//======================================================================= -//function : IsFreeFace -//purpose : check that only one volume is build on the face nodes -//======================================================================= +//================================================================================ +/*! + * \brief Return minimal square distance between connected corner nodes + */ +//================================================================================ -bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) +double SMDS_VolumeTool::MinLinearSize2() const { - const int free = true; + double minSize = 1e+100; + int iQ = myVolume->IsQuadratic() ? 2 : 1; + + // store current face data + int curFace = myCurFace, nbN = myFaceNbNodes; + int* ind = myFaceNodeIndices; + myFaceNodeIndices = NULL; + const SMDS_MeshNode** nodes = myFaceNodes; + myFaceNodes = NULL; + + // it seems that compute distance twice is faster than organization of a sole computing + myCurFace = -1; + for ( int iF = 0; iF < myNbFaces; ++iF ) + { + setFace( iF ); + for ( int iN = 0; iN < myFaceNbNodes; iN += iQ ) + { + XYZ n1( myFaceNodes[ iN ]); + XYZ n2( myFaceNodes[(iN + iQ) % myFaceNbNodes]); + minSize = std::min( minSize, (n1 - n2).SquareMagnitude()); + } + } + // restore current face data + myCurFace = curFace; + myFaceNbNodes = nbN; + myFaceNodeIndices = ind; + delete [] myFaceNodes; myFaceNodes = nodes; + + return minSize; +} + +//================================================================================ +/*! + * \brief check that only one volume is build on the face nodes + * + * If a face is shared by one of , it is considered free + */ +//================================================================================ + +bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) const +{ + const bool isFree = true; if (!setFace( faceIndex )) - return !free; + return !isFree; const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex ); - int nbFaceNodes = myFaceNbNodes; + const int nbFaceNodes = myFaceNbNodes; - // evaluate nb of face nodes shared by other volume + // evaluate nb of face nodes shared by other volumes int maxNbShared = -1; typedef map< const SMDS_MeshElement*, int > TElemIntMap; TElemIntMap volNbShared; TElemIntMap::iterator vNbIt; for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { const SMDS_MeshNode* n = nodes[ iNode ]; - SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(); + SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( SMDSAbs_Volume ); while ( eIt->more() ) { const SMDS_MeshElement* elem = eIt->next(); - if ( elem != myVolume && elem->GetType() == SMDSAbs_Volume ) { - int nbShared = 1; - vNbIt = volNbShared.find( elem ); - if ( vNbIt == volNbShared.end() ) { - volNbShared.insert ( TElemIntMap::value_type( elem, nbShared )); - } - else { - nbShared = ++(*vNbIt).second; - } - if ( nbShared > maxNbShared ) - maxNbShared = nbShared; + if ( elem != myVolume ) { + vNbIt = volNbShared.insert( make_pair( elem, 0 )).first; + (*vNbIt).second++; + if ( vNbIt->second > maxNbShared ) + maxNbShared = vNbIt->second; } } } if ( maxNbShared < 3 ) - return free; // is free + return isFree; // is free // find volumes laying on the opposite side of the face // and sharing all nodes @@ -1327,55 +1498,81 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) if ( IsFaceExternal( faceIndex )) intNormal = XYZ( -intNormal.x, -intNormal.y, -intNormal.z ); XYZ p0 ( nodes[0] ), baryCenter; - for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) { - int nbShared = (*vNbIt).second; + for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); ) { + const int& nbShared = (*vNbIt).second; if ( nbShared >= 3 ) { SMDS_VolumeTool volume( (*vNbIt).first ); volume.GetBaryCenter( baryCenter.x, baryCenter.y, baryCenter.z ); XYZ intNormal2( baryCenter - p0 ); - if ( intNormal.Dot( intNormal2 ) < 0 ) - continue; // opposite side + if ( intNormal.Dot( intNormal2 ) < 0 ) { + // opposite side + if ( nbShared >= nbFaceNodes ) + { + // a volume shares the whole facet + if ( otherVol ) *otherVol = vNbIt->first; + return !isFree; + } + ++vNbIt; + continue; + } } // remove a volume from volNbShared map - volNbShared.erase( vNbIt-- ); + volNbShared.erase( vNbIt++ ); } - // here volNbShared contains only volumes laying on the - // opposite side of the face - if ( volNbShared.empty() ) { - return free; // is free + // here volNbShared contains only volumes laying on the opposite side of + // the face and sharing 3 or more but not all face nodes with myVolume + if ( volNbShared.size() < 2 ) { + return isFree; // is free } // check if the whole area of a face is shared - bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle - for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) { - SMDS_VolumeTool volume( (*vNbIt).first ); - bool prevLinkShared = false; - int nbSharedLinks = 0; - for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { - bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] ); - if ( linkShared ) - nbSharedLinks++; - if ( linkShared && prevLinkShared && - volume.IsLinked( nodes[ iNode - 1 ], nodes[ iNode + 1] )) - isShared[ iNode ] = true; - prevLinkShared = linkShared; - } - if ( nbSharedLinks == nbFaceNodes ) - return !free; // is not free - if ( nbFaceNodes == 4 ) { - // check traingle parts 1 & 3 - if ( isShared[1] && isShared[3] ) - return !free; // is not free - // check triangle parts 0 & 2; - // 0 part could not be checked in the loop; check it here - if ( isShared[2] && prevLinkShared && - volume.IsLinked( nodes[ 0 ], nodes[ 1 ] ) && - volume.IsLinked( nodes[ 1 ], nodes[ 3 ] ) ) - return !free; // is not free - } + for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) + { + const SMDS_MeshNode* n = nodes[ iNode ]; + // check if n is shared by one of volumes of volNbShared + bool isShared = false; + SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( SMDSAbs_Volume ); + while ( eIt->more() && !isShared ) + isShared = volNbShared.count( eIt->next() ); + if ( !isShared ) + return isFree; } - return free; + if ( otherVol ) *otherVol = volNbShared.begin()->first; + return !isFree; + +// if ( !myVolume->IsPoly() ) +// { +// bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle +// for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) { +// SMDS_VolumeTool volume( (*vNbIt).first ); +// bool prevLinkShared = false; +// int nbSharedLinks = 0; +// for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) { +// bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] ); +// if ( linkShared ) +// nbSharedLinks++; +// if ( linkShared && prevLinkShared && +// volume.IsLinked( nodes[ iNode - 1 ], nodes[ iNode + 1] )) +// isShared[ iNode ] = true; +// prevLinkShared = linkShared; +// } +// if ( nbSharedLinks == nbFaceNodes ) +// return !free; // is not free +// if ( nbFaceNodes == 4 ) { +// // check traingle parts 1 & 3 +// if ( isShared[1] && isShared[3] ) +// return !free; // is not free +// // check triangle parts 0 & 2; +// // 0 part could not be checked in the loop; check it here +// if ( isShared[2] && prevLinkShared && +// volume.IsLinked( nodes[ 0 ], nodes[ 1 ] ) && +// volume.IsLinked( nodes[ 1 ], nodes[ 3 ] ) ) +// return !free; // is not free +// } +// } +// } +// return free; } //======================================================================= @@ -1383,7 +1580,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex ) //purpose : Return index of a face formed by theFaceNodes //======================================================================= -int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes ) +int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes ) const { for ( int iFace = 0; iFace < myNbFaces; iFace++ ) { const SMDS_MeshNode** nodes = GetFaceNodes( iFace ); @@ -1421,7 +1618,7 @@ int SMDS_VolumeTool::GetFaceIndex( const set& theFaceNodes //purpose : //======================================================================= -bool SMDS_VolumeTool::setFace( int faceIndex ) +bool SMDS_VolumeTool::setFace( int faceIndex ) const { if ( !myVolume ) return false; @@ -1439,93 +1636,120 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) myFaceNodes = NULL; } - if (myVolume->IsPoly()) { + if (myVolume->IsPoly()) + { if (!myPolyedre) { MESSAGE("Warning: bad volumic element"); return false; } - // check orientation - bool isGoodOri = true; - if (myExternalFaces) - isGoodOri = IsFaceExternal( faceIndex ); - // set face nodes int iNode; myFaceNbNodes = myPolyedre->NbFaceNodes(faceIndex + 1); myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1]; - if (isGoodOri) { - for ( iNode = 0; iNode < myFaceNbNodes; iNode++ ) - myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1); - } else { - for ( iNode = 0; iNode < myFaceNbNodes; iNode++ ) - myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, myFaceNbNodes - iNode); - } + for ( iNode = 0; iNode < myFaceNbNodes; iNode++ ) + myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1); myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first + // check orientation + if (myExternalFaces) + { + myCurFace = faceIndex; // avoid infinite recursion in IsFaceExternal() + myExternalFaces = false; // force normal computation by IsFaceExternal() + if ( !IsFaceExternal( faceIndex )) + for ( int i = 0, j = myFaceNbNodes; i < j; ++i, --j ) + std::swap( myFaceNodes[i], myFaceNodes[j] ); + myExternalFaces = true; + } } - else { - // choose face node indices - switch ( myVolumeNbNodes ) { - case 4: - myFaceNbNodes = Tetra_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ]; - else - myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ]; - break; - case 5: - myFaceNbNodes = Pyramid_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ]; - else - myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ]; - break; - case 6: - myFaceNbNodes = Penta_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ]; - else - myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ]; - break; - case 8: - myFaceNbNodes = Hexa_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ]; - else - myFaceNodeIndices = Hexa_F[ faceIndex ]; - break; - case 10: - myFaceNbNodes = QuadTetra_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_RE[ faceIndex ]; - else - myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_R[ faceIndex ]; - break; - case 13: - myFaceNbNodes = QuadPyram_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_RE[ faceIndex ]; - else - myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_R[ faceIndex ]; - break; - case 15: - myFaceNbNodes = QuadPenta_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? QuadPenta_FE[ faceIndex ] : QuadPenta_RE[ faceIndex ]; - else - myFaceNodeIndices = myVolForward ? QuadPenta_F[ faceIndex ] : QuadPenta_R[ faceIndex ]; - break; - case 20: - myFaceNbNodes = QuadHexa_nbN[ faceIndex ]; - if ( myExternalFaces ) - myFaceNodeIndices = myVolForward ? QuadHexa_FE[ faceIndex ] : QuadHexa_RE[ faceIndex ]; - else - myFaceNodeIndices = QuadHexa_F[ faceIndex ]; - break; - default: - return false; + else + { + if ( !myAllFacesNodeIndices_F ) + { + // choose data for an element type + switch ( myVolumeNbNodes ) { + case 4: + myAllFacesNodeIndices_F = &Tetra_F [0][0]; + //myAllFacesNodeIndices_FE = &Tetra_F [0][0]; + myAllFacesNodeIndices_RE = &Tetra_RE[0][0]; + myAllFacesNbNodes = Tetra_nbN; + myMaxFaceNbNodes = sizeof(Tetra_F[0])/sizeof(Tetra_F[0][0]); + break; + case 5: + myAllFacesNodeIndices_F = &Pyramid_F [0][0]; + //myAllFacesNodeIndices_FE = &Pyramid_F [0][0]; + myAllFacesNodeIndices_RE = &Pyramid_RE[0][0]; + myAllFacesNbNodes = Pyramid_nbN; + myMaxFaceNbNodes = sizeof(Pyramid_F[0])/sizeof(Pyramid_F[0][0]); + break; + case 6: + myAllFacesNodeIndices_F = &Penta_F [0][0]; + //myAllFacesNodeIndices_FE = &Penta_FE[0][0]; + myAllFacesNodeIndices_RE = &Penta_RE[0][0]; + myAllFacesNbNodes = Penta_nbN; + myMaxFaceNbNodes = sizeof(Penta_F[0])/sizeof(Penta_F[0][0]); + break; + case 8: + myAllFacesNodeIndices_F = &Hexa_F [0][0]; + ///myAllFacesNodeIndices_FE = &Hexa_FE[0][0]; + myAllFacesNodeIndices_RE = &Hexa_RE[0][0]; + myAllFacesNbNodes = Hexa_nbN; + myMaxFaceNbNodes = sizeof(Hexa_F[0])/sizeof(Hexa_F[0][0]); + break; + case 10: + myAllFacesNodeIndices_F = &QuadTetra_F [0][0]; + //myAllFacesNodeIndices_FE = &QuadTetra_F [0][0]; + myAllFacesNodeIndices_RE = &QuadTetra_RE[0][0]; + myAllFacesNbNodes = QuadTetra_nbN; + myMaxFaceNbNodes = sizeof(QuadTetra_F[0])/sizeof(QuadTetra_F[0][0]); + break; + case 13: + myAllFacesNodeIndices_F = &QuadPyram_F [0][0]; + //myAllFacesNodeIndices_FE = &QuadPyram_F [0][0]; + myAllFacesNodeIndices_RE = &QuadPyram_RE[0][0]; + myAllFacesNbNodes = QuadPyram_nbN; + myMaxFaceNbNodes = sizeof(QuadPyram_F[0])/sizeof(QuadPyram_F[0][0]); + break; + case 15: + myAllFacesNodeIndices_F = &QuadPenta_F [0][0]; + //myAllFacesNodeIndices_FE = &QuadPenta_FE[0][0]; + myAllFacesNodeIndices_RE = &QuadPenta_RE[0][0]; + myAllFacesNbNodes = QuadPenta_nbN; + myMaxFaceNbNodes = sizeof(QuadPenta_F[0])/sizeof(QuadPenta_F[0][0]); + break; + case 20: + case 27: + myAllFacesNodeIndices_F = &QuadHexa_F [0][0]; + //myAllFacesNodeIndices_FE = &QuadHexa_FE[0][0]; + myAllFacesNodeIndices_RE = &QuadHexa_RE[0][0]; + myAllFacesNbNodes = QuadHexa_nbN; + myMaxFaceNbNodes = sizeof(QuadHexa_F[0])/sizeof(QuadHexa_F[0][0]); + if ( !myIgnoreCentralNodes && myVolumeNbNodes == 27 ) + { + myAllFacesNodeIndices_F = &TriQuadHexa_F [0][0]; + //myAllFacesNodeIndices_FE = &TriQuadHexa_FE[0][0]; + myAllFacesNodeIndices_RE = &TriQuadHexa_RE[0][0]; + myAllFacesNbNodes = TriQuadHexa_nbN; + myMaxFaceNbNodes = sizeof(TriQuadHexa_F[0])/sizeof(TriQuadHexa_F[0][0]); + } + break; + case 12: + myAllFacesNodeIndices_F = &HexPrism_F [0][0]; + //myAllFacesNodeIndices_FE = &HexPrism_FE[0][0]; + myAllFacesNodeIndices_RE = &HexPrism_RE[0][0]; + myAllFacesNbNodes = HexPrism_nbN; + myMaxFaceNbNodes = sizeof(HexPrism_F[0])/sizeof(HexPrism_F[0][0]); + break; + default: + return false; + } } + myFaceNbNodes = myAllFacesNbNodes[ faceIndex ]; + // if ( myExternalFaces ) + // myFaceNodeIndices = (int*)( myVolForward ? myAllFacesNodeIndices_FE + faceIndex*myMaxFaceNbNodes : myAllFacesNodeIndices_RE + faceIndex*myMaxFaceNbNodes ); + // else + // myFaceNodeIndices = (int*)( myAllFacesNodeIndices_F + faceIndex*myMaxFaceNbNodes ); + myFaceNodeIndices = (int*)( myVolForward ? myAllFacesNodeIndices_F + faceIndex*myMaxFaceNbNodes : myAllFacesNodeIndices_RE + faceIndex*myMaxFaceNbNodes ); // set face nodes myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1]; @@ -1554,7 +1778,9 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes) case 10: return QUAD_TETRA; case 13: return QUAD_PYRAM; case 15: return QUAD_PENTA; - case 20: return QUAD_HEXA; + case 20: + case 27: return QUAD_HEXA; + case 12: return HEX_PRISM; default:return UNKNOWN; } } @@ -1575,7 +1801,8 @@ int SMDS_VolumeTool::NbFaces( VolumeType type ) case QUAD_PENTA: return 5; case HEXA : case QUAD_HEXA : return 6; - default: return 0; + case HEX_PRISM : return 8; + default: return 0; } } @@ -1598,7 +1825,8 @@ int SMDS_VolumeTool::NbCornerNodes(VolumeType type) case QUAD_PENTA: return 6; case HEXA : case QUAD_HEXA : return 8; - default: return 0; + case HEX_PRISM : return 12; + default: return 0; } return 0; } @@ -1619,12 +1847,14 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices(VolumeType type, switch ( type ) { case TETRA: return Tetra_F[ faceIndex ]; case PYRAM: return Pyramid_F[ faceIndex ]; - case PENTA: return external ? Penta_FE[ faceIndex ] : Penta_F[ faceIndex ]; - case HEXA: return external ? Hexa_FE[ faceIndex ] : Hexa_F[ faceIndex ]; + case PENTA: return external ? Penta_F[ faceIndex ] : Penta_F[ faceIndex ]; + case HEXA: return external ? Hexa_F[ faceIndex ] : Hexa_F[ faceIndex ]; case QUAD_TETRA: return QuadTetra_F[ faceIndex ]; case QUAD_PYRAM: return QuadPyram_F[ faceIndex ]; - case QUAD_PENTA: return external ? QuadPenta_FE[ faceIndex ] : QuadPenta_F[ faceIndex ]; - case QUAD_HEXA: return external ? QuadHexa_FE[ faceIndex ] : QuadHexa_F[ faceIndex ]; + case QUAD_PENTA: return external ? QuadPenta_F[ faceIndex ] : QuadPenta_F[ faceIndex ]; + // what about SMDSEntity_TriQuad_Hexa? + case QUAD_HEXA: return external ? QuadHexa_F[ faceIndex ] : QuadHexa_F[ faceIndex ]; + case HEX_PRISM: return external ? HexPrism_F[ faceIndex ] : HexPrism_F[ faceIndex ]; default:; } return 0; @@ -1646,18 +1876,20 @@ int SMDS_VolumeTool::NbFaceNodes(VolumeType type, case QUAD_TETRA: return QuadTetra_nbN[ faceIndex ]; case QUAD_PYRAM: return QuadPyram_nbN[ faceIndex ]; case QUAD_PENTA: return QuadPenta_nbN[ faceIndex ]; + // what about SMDSEntity_TriQuad_Hexa? case QUAD_HEXA: return QuadHexa_nbN[ faceIndex ]; + case HEX_PRISM: return HexPrism_nbN[ faceIndex ]; default:; } return 0; } //======================================================================= -//function : Get +//function : Element //purpose : return element //======================================================================= -const SMDS_MeshVolume* SMDS_VolumeTool::Get() const +const SMDS_MeshVolume* SMDS_VolumeTool::Element() const { return static_cast( myVolume ); } diff --git a/src/SMDS/SMDS_VolumeTool.hxx b/src/SMDS/SMDS_VolumeTool.hxx index b95bc8a62..5c22c3eda 100644 --- a/src/SMDS/SMDS_VolumeTool.hxx +++ b/src/SMDS/SMDS_VolumeTool.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMDS_VolumeTool.hxx // Module : SMESH @@ -32,7 +33,7 @@ class SMDS_MeshElement; class SMDS_MeshNode; -class SMDS_PolyhedralVolumeOfNodes; +class SMDS_VtkVolume; class SMDS_MeshVolume; #include @@ -50,18 +51,23 @@ class SMDS_EXPORT SMDS_VolumeTool { public: - enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, QUAD_TETRA, - QUAD_PYRAM, QUAD_PENTA, QUAD_HEXA, POLYHEDA }; + enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, + HEX_PRISM, QUAD_TETRA, QUAD_PYRAM, QUAD_PENTA, QUAD_HEXA, + POLYHEDA, NB_VOLUME_TYPES }; // to keep synchronised with GetSize()! SMDS_VolumeTool (); ~SMDS_VolumeTool (); - SMDS_VolumeTool (const SMDS_MeshElement* theVolume); + SMDS_VolumeTool (const SMDS_MeshElement* theVolume, + const bool ignoreCentralNodes=true); - bool Set (const SMDS_MeshElement* theVolume); + bool Set (const SMDS_MeshElement* theVolume, + const bool ignoreCentralNodes=true); // Set volume. - // Return false if theVolume is not of type SMDSAbs_Volume + // Return false if theVolume is not of type SMDSAbs_Volume. + // ignoreCentralNodes makes skip nodes at face centers when returning + // nodes of faces of SMDSEntity_TriQuad_Hexa - const SMDS_MeshVolume* Get() const; + const SMDS_MeshVolume* Element() const; // return element int ID() const; @@ -93,19 +99,25 @@ class SMDS_EXPORT SMDS_VolumeTool bool GetBaryCenter (double & X, double & Y, double & Z) const; + bool IsOut(double X, double Y, double Z, double tol) const; + // Classify a point // ----------------------- // info on node connection // ----------------------- bool IsLinked (const SMDS_MeshNode* theNode1, - const SMDS_MeshNode* theNode2) const; + const SMDS_MeshNode* theNode2, + const bool theIgnoreMediumNodes=false) const; // Return true if theNode1 is linked with theNode2. + // If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well bool IsLinked (const int theNode1Index, - const int theNode2Index) const; + const int theNode2Index, + bool theIgnoreMediumNodes=false) const; // Return true if the node with theNode1Index is linked // with the node with theNode2Index + // If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well int GetNodeIndex(const SMDS_MeshNode* theNode) const; // Return an index of theNode @@ -113,9 +125,15 @@ class SMDS_EXPORT SMDS_VolumeTool int GetAllExistingEdges(std::vector & edges) const; // Fill vector with boundary edges existing in the mesh + double MinLinearSize2() const; + // Return minimal square distance between connected corner nodes + // ------------- // info on faces // ------------- + // For all elements, 0-th face is bottom based on the first nodes. + // For prismatic elements (tetra,hexa,prisms), 1-th face is a top one. + // For all elements, side faces follow order of bottom nodes void SetExternalNormal (); // Node order in faces will be so that faces normals are external. @@ -124,44 +142,57 @@ class SMDS_EXPORT SMDS_VolumeTool // Return number of faces of the volume. In the following // methods 0 <= faceIndex < NbFaces() - int NbFaceNodes( int faceIndex ); + int NbFaceNodes( int faceIndex ) const; // Return number of nodes in the array of face nodes - const int* GetFaceNodesIndices( int faceIndex ); + const int* GetFaceNodesIndices( int faceIndex ) const; // Return the array of face nodes indices // To comfort link iteration, the array // length == NbFaceNodes( faceIndex ) + 1 and - // the last node index == the first one. + // the last node index == the first one, except for + // SMDSEntity_TriQuad_Hexa at ignoreCentralNodes==false. + // NOTE: for the quadratic volume, node indices are in the order the nodes encounter + // in face boundary and not the order they are in the mesh face - const SMDS_MeshNode** GetFaceNodes( int faceIndex ); + const SMDS_MeshNode** GetFaceNodes( int faceIndex ) const; // Return the array of face nodes. // To comfort link iteration, the array // length == NbFaceNodes( faceIndex ) + 1 and - // the last node == the first one. + // the last node == the first one, except for + // SMDSEntity_TriQuad_Hexa at ignoreCentralNodes==false. + // NOTE: for the quadratic volume, nodes are in the order they encounter in face boundary + // and not the order they are in the mesh face // WARNING: do not modify the array, some methods // work basing on its contents bool GetFaceNodes (int faceIndex, - std::set& theFaceNodes ); + std::set& theFaceNodes ) const; // Return a set of face nodes. - bool IsFaceExternal( int faceIndex ); + bool IsFaceExternal( int faceIndex ) const; // Check normal orientation of a face. // SetExternalNormal() is taken into account. - bool IsFreeFace( int faceIndex ); + bool IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol=0 ) const; // Check that all volumes built on the face nodes lays on one side + // otherVol returns another volume sharing the given facet - bool GetFaceNormal (int faceIndex, double & X, double & Y, double & Z); + bool GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) const; // Return a normal to a face - double GetFaceArea( int faceIndex ); + bool GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const; + // Return barycenter of a face + + double GetFaceArea( int faceIndex ) const; // Return face area int GetOppFaceIndex( int faceIndex ) const; // Return index of the opposite face if it exists, else -1. - int GetFaceIndex( const std::set& theFaceNodes ); + int GetCenterNodeIndex( int faceIndex ) const; + // Return index of the node located at face center of a quadratic element like HEX27 + + int GetFaceIndex( const std::set& theFaceNodes ) const; // Return index of a face formed by theFaceNodes. // Return -1 if a face not found @@ -169,7 +200,7 @@ class SMDS_EXPORT SMDS_VolumeTool // Return index of a face formed by theFaceNodesIndices // Return -1 if a face not found - int GetAllExistingFaces(std::vector & faces); + int GetAllExistingFaces(std::vector & faces) const; // Fill vector with boundary faces existing in the mesh // ------------------------ @@ -189,32 +220,40 @@ class SMDS_EXPORT SMDS_VolumeTool // To comfort link iteration, the array // length == NbFaceNodes( faceIndex ) + 1 and // the last node index == the first one. + // Nodes at face centers of SMDSEntity_TriQuad_Hexa are ignored - static int NbFaceNodes(VolumeType type, - int faceIndex ); + static int NbFaceNodes(VolumeType type, int faceIndex ); // Return number of nodes in the array of face nodes + // Nodes at face centers of SMDSEntity_TriQuad_Hexa are ignored static int NbCornerNodes(VolumeType type); // Useful to know nb of corner nodes of a quadratic volume private: - bool setFace( int faceIndex ); + bool setFace( int faceIndex ) const; const SMDS_MeshElement* myVolume; - const SMDS_PolyhedralVolumeOfNodes* myPolyedre; + const SMDS_VtkVolume* myPolyedre; + bool myIgnoreCentralNodes; bool myVolForward; int myNbFaces; int myVolumeNbNodes; const SMDS_MeshNode** myVolumeNodes; + std::vector< int > myPolyIndices; + + mutable bool myExternalFaces; - bool myExternalFaces; + mutable const int* myAllFacesNodeIndices_F; + mutable const int* myAllFacesNodeIndices_RE; + mutable const int* myAllFacesNbNodes; + mutable int myMaxFaceNbNodes; - int myCurFace; - int myFaceNbNodes; - int* myFaceNodeIndices; - const SMDS_MeshNode** myFaceNodes; + mutable int myCurFace; + mutable int myFaceNbNodes; + mutable int* myFaceNodeIndices; + mutable const SMDS_MeshNode** myFaceNodes; }; #endif diff --git a/src/SMDS/SMDS_VtkCellIterator.cxx b/src/SMDS/SMDS_VtkCellIterator.cxx new file mode 100644 index 000000000..80b421c5d --- /dev/null +++ b/src/SMDS/SMDS_VtkCellIterator.cxx @@ -0,0 +1,205 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMDS_VtkCellIterator.hxx" +#include "utilities.h" + +SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + _mesh(mesh), _cellId(vtkCellId), _index(0), _type(aType) +{ + vtkUnstructuredGrid* grid = _mesh->getGrid(); + _vtkIdList = vtkIdList::New(); + const std::vector& interlace = SMDS_MeshCell::fromVtkOrder( aType ); + if ( interlace.empty() ) + { + grid->GetCellPoints(_cellId, _vtkIdList); + _nbNodes = _vtkIdList->GetNumberOfIds(); + } + else + { + vtkIdType npts, *pts; + grid->GetCellPoints( _cellId, npts, pts ); + _vtkIdList->SetNumberOfIds( _nbNodes = npts ); + for (int i = 0; i < _nbNodes; i++) + _vtkIdList->SetId(i, pts[interlace[i]]); + } +} + +SMDS_VtkCellIterator::~SMDS_VtkCellIterator() +{ + _vtkIdList->Delete(); +} + +bool SMDS_VtkCellIterator::more() +{ + return (_index < _nbNodes); +} + +const SMDS_MeshElement* SMDS_VtkCellIterator::next() +{ + vtkIdType id = _vtkIdList->GetId(_index++); + return _mesh->FindNodeVtk(id); +} + +SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + SMDS_VtkCellIterator() +{ + _mesh = mesh; + _cellId = vtkCellId; + _index = 0; + _type = aType; + //MESSAGE("SMDS_VtkCellInterlacedIterator (UNV)" << _type); + + _vtkIdList = vtkIdList::New(); + vtkIdType* pts; + vtkUnstructuredGrid* grid = _mesh->getGrid(); + grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts); + _vtkIdList->SetNumberOfIds(_nbNodes); + int *ids = 0; + switch (_type) + { + case SMDSEntity_Quad_Edge: + { + static int id[] = { 0, 2, 1 }; + ids = id; + break; + } + case SMDSEntity_Quad_Triangle: + { + static int id[] = { 0, 3, 1, 4, 2, 5 }; + ids = id; + break; + } + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + { + static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + ids = id; + _nbNodes = 8; + break; + } + case SMDSEntity_Quad_Tetra: + { + static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 }; + ids = id; + break; + } + case SMDSEntity_Quad_Pyramid: + { + static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 }; + ids = id; + break; + } + case SMDSEntity_Penta: + { + static int id[] = { 0, 2, 1, 3, 5, 4 }; + ids = id; + break; + } + case SMDSEntity_Quad_Penta: + { + static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 }; + ids = id; + break; + } + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + { + static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 }; + ids = id; + _nbNodes = 20; + break; + } + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: + default: + { + // static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + // 25, 26, 27, 28, 29 }; + // ids = id; + // break; + } + } + if ( ids ) + for (int i = 0; i < _nbNodes; i++) + _vtkIdList->SetId(i, pts[ids[i]]); + else + for (int i = 0; i < _nbNodes; i++) + _vtkIdList->SetId(i, pts[i]); +} + +SMDS_VtkCellIteratorToUNV::~SMDS_VtkCellIteratorToUNV() +{ +} + +SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) : + SMDS_VtkCellIterator() +{ + _mesh = mesh; + _cellId = vtkCellId; + _index = 0; + _type = aType; + //MESSAGE("SMDS_VtkCellIteratorPolyH " << _type); + _vtkIdList = vtkIdList::New(); + vtkUnstructuredGrid* grid = _mesh->getGrid(); + grid->GetCellPoints(_cellId, _vtkIdList); + _nbNodes = _vtkIdList->GetNumberOfIds(); + switch (_type) + { + case SMDSEntity_Polyhedra: + { + //MESSAGE("SMDS_VtkCellIterator Polyhedra"); + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(_cellId, nFaces, ptIds); + int id = 0; + _nbNodesInFaces = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + _nbNodesInFaces += nodesInFace; + id += (nodesInFace + 1); + } + _vtkIdList->SetNumberOfIds(_nbNodesInFaces); + id = 0; + int n = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + for (int k = 1; k <= nodesInFace; k++) + _vtkIdList->SetId(n++, ptIds[id + k]); + id += (nodesInFace + 1); + } + break; + } + default: + assert(0); + } +} + +SMDS_VtkCellIteratorPolyH::~SMDS_VtkCellIteratorPolyH() +{ +} + +bool SMDS_VtkCellIteratorPolyH::more() +{ + return (_index < _nbNodesInFaces); +} diff --git a/src/SMDS/SMDS_VtkCellIterator.hxx b/src/SMDS/SMDS_VtkCellIterator.hxx new file mode 100644 index 000000000..ce151099d --- /dev/null +++ b/src/SMDS/SMDS_VtkCellIterator.hxx @@ -0,0 +1,72 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _SMDS_VTKCELLITERATOR_HXX_ +#define _SMDS_VTKCELLITERATOR_HXX_ + +#include "SMDS_ElemIterator.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDSAbs_ElementType.hxx" + +#include +#include + +class SMDS_VtkCellIterator: public SMDS_ElemIterator +{ +public: + SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIterator(); + virtual bool more(); + virtual const SMDS_MeshElement* next(); + inline void exchange(vtkIdType a, vtkIdType b) + { + vtkIdType t = _vtkIdList->GetId(a); + _vtkIdList->SetId(a, _vtkIdList->GetId(b)); + _vtkIdList->SetId(b, t); + } + +protected: + SMDS_VtkCellIterator() {}; + + SMDS_Mesh* _mesh; + int _cellId; + int _index; + int _nbNodes; + SMDSAbs_EntityType _type; + vtkIdList* _vtkIdList; +}; + +class SMDS_VtkCellIteratorToUNV: public SMDS_VtkCellIterator +{ +public: + SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIteratorToUNV(); +}; + +class SMDS_VtkCellIteratorPolyH: public SMDS_VtkCellIterator +{ +public: + SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType); + virtual ~SMDS_VtkCellIteratorPolyH(); + virtual bool more(); +protected: + int _nbNodesInFaces; +}; + +#endif diff --git a/src/SMDS/SMDS_VtkEdge.cxx b/src/SMDS/SMDS_VtkEdge.cxx new file mode 100644 index 000000000..cb324014e --- /dev/null +++ b/src/SMDS/SMDS_VtkEdge.cxx @@ -0,0 +1,172 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMDS_VtkEdge.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include +#include + +using namespace std; + +SMDS_VtkEdge::SMDS_VtkEdge() +{ +} + +SMDS_VtkEdge::SMDS_VtkEdge(std::vector nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} + +SMDS_VtkEdge::~SMDS_VtkEdge() +{ +} + +void SMDS_VtkEdge::init(std::vector nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshEdge::init(); + vtkUnstructuredGrid* grid = mesh->getGrid(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_LINE; + if (nodeIds.size() == 3) + aType = VTK_QUADRATIC_EDGE; + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + mesh->setMyModified(); + //MESSAGE("SMDS_VtkEdge::init myVtkID " << myVtkID); +} + +bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) +{ + const SMDS_MeshNode* nodes[] = { node1, node2 }; + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return ChangeNodes(nodes, 2); +} + +bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +bool SMDS_VtkEdge::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + //MESSAGE("IsMediumNode " << npts << " " << (node->getVtkId() == pts[npts-1])); + return ((npts == 3) && (node->getVtkId() == pts[2])); +} + +void SMDS_VtkEdge::Print(std::ostream & OS) const +{ + OS << "edge <" << GetID() << "> : "; +} + +int SMDS_VtkEdge::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + assert(nbPoints >= 2); + return nbPoints; +} + +int SMDS_VtkEdge::NbEdges() const +{ + return 1; +} + +SMDSAbs_EntityType SMDS_VtkEdge::GetEntityType() const +{ + if (NbNodes() == 2) + return SMDSEntity_Edge; + else + return SMDSEntity_Quad_Edge; +} + +vtkIdType SMDS_VtkEdge::GetVtkType() const +{ + if (NbNodes() == 2) + return VTK_LINE; + else + return VTK_QUADRATIC_EDGE; + +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* +SMDS_VtkEdge::GetNode(const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]); +} + +bool SMDS_VtkEdge::IsQuadratic() const +{ + if (this->NbNodes() > 2) + return true; + else + return false; +} + +SMDS_ElemIteratorPtr SMDS_VtkEdge::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_ElemIteratorPtr SMDS_VtkEdge::nodesIteratorToUNV() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_ElemIteratorPtr SMDS_VtkEdge::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} diff --git a/src/SMDS/SMDS_VtkEdge.hxx b/src/SMDS/SMDS_VtkEdge.hxx new file mode 100644 index 000000000..c5f04300b --- /dev/null +++ b/src/SMDS/SMDS_VtkEdge.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMDS : implementaion of Salome mesh data structure +// File : SMDS_VtkEdge.hxx +// Module : SMESH + +#ifndef _SMDS_VTKEDGE_HXX_ +#define _SMDS_VTKEDGE_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshEdge.hxx" +#include +#include + +class SMDS_EXPORT SMDS_VtkEdge: public SMDS_MeshEdge +{ + +public: + SMDS_VtkEdge(); + SMDS_VtkEdge(std::vector nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkEdge(); + void init(std::vector nodeIds, SMDS_Mesh* mesh); + bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2); + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + + virtual void Print(std::ostream & OS) const; + virtual int NbNodes() const; + virtual int NbEdges() const; + + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual bool IsQuadratic() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; +protected: +}; +#endif diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx new file mode 100644 index 000000000..80644c7e2 --- /dev/null +++ b/src/SMDS/SMDS_VtkFace.cxx @@ -0,0 +1,301 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMDS_VtkFace.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include + +using namespace std; + +SMDS_VtkFace::SMDS_VtkFace() +{ +} + +SMDS_VtkFace::SMDS_VtkFace(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} + +SMDS_VtkFace::~SMDS_VtkFace() +{ +} + +void SMDS_VtkFace::init(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshFace::init(); + vtkUnstructuredGrid* grid = mesh->getGrid(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_TRIANGLE; + switch (nodeIds.size()) + { + case 3: + aType = VTK_TRIANGLE; + break; + case 4: + aType = VTK_QUAD; + break; + case 6: + aType = VTK_QUADRATIC_TRIANGLE; + break; + case 8: + aType = VTK_QUADRATIC_QUAD; + break; + case 9: + aType = VTK_BIQUADRATIC_QUAD; + break; + default: + aType = VTK_POLYGON; + break; + } + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + mesh->setMyModified(); + //MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID); +} + +void SMDS_VtkFace::initPoly(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshFace::init(); + vtkUnstructuredGrid* grid = mesh->getGrid(); + myMeshId = mesh->getMeshId(); + myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + mesh->setMyModified(); +} + +bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +void SMDS_VtkFace::Print(std::ostream & OS) const +{ + OS << "face <" << GetID() << "> : "; +} + +int SMDS_VtkFace::NbEdges() const +{ + // TODO quadratic polygons ? + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbEdges = 3; + switch (aVtkType) + { + case VTK_TRIANGLE: + case VTK_QUADRATIC_TRIANGLE: + nbEdges = 3; + break; + case VTK_QUAD: + case VTK_QUADRATIC_QUAD: + case VTK_BIQUADRATIC_QUAD: + nbEdges = 4; + break; + case VTK_POLYGON: + default: + nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints(); + break; + } + return nbEdges; +} + +int SMDS_VtkFace::NbFaces() const +{ + return 1; +} + +int SMDS_VtkFace::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + return nbPoints; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* +SMDS_VtkFace::GetNode(const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]); +} + +bool SMDS_VtkFace::IsQuadratic() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + // TODO quadratic polygons ? + switch (aVtkType) + { + case VTK_QUADRATIC_TRIANGLE: + case VTK_QUADRATIC_QUAD: + case VTK_BIQUADRATIC_QUAD: + return true; + break; + default: + return false; + } +} + +bool SMDS_VtkFace::IsPoly() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return (aVtkType == VTK_POLYGON); +} + +bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int rankFirstMedium = 0; + switch (aVtkType) + { + case VTK_QUADRATIC_TRIANGLE: + rankFirstMedium = 3; // medium nodes are of rank 3,4,5 + break; + case VTK_QUADRATIC_QUAD: + case VTK_BIQUADRATIC_QUAD: + rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7 + break; + default: + //MESSAGE("wrong element type " << aVtkType); + return false; + } + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + vtkIdType nodeId = node->getVtkId(); + for (int rank = 0; rank < npts; rank++) + { + if (pts[rank] == nodeId) + { + //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium)); + if (rank < rankFirstMedium) + return false; + else + return true; + } + } + //throw SALOME_Exception(LOCALIZED("node does not belong to this element")); + MESSAGE("======================================================"); + MESSAGE("= IsMediumNode: node does not belong to this element ="); + MESSAGE("======================================================"); + return false; +} + +int SMDS_VtkFace::NbCornerNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + vtkIdType aVtkType = grid->GetCellType(myVtkID); + if ( aVtkType != VTK_POLYGON ) + return nbPoints <= 4 ? nbPoints : nbPoints / 2; + return nbPoints; +} + +SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return SMDS_MeshCell::toSmdsType( VTKCellType( aVtkType )); +} + +SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + switch ( aVtkType ) { + case VTK_TRIANGLE: + case VTK_QUADRATIC_TRIANGLE: + return SMDSGeom_TRIANGLE; + case VTK_QUAD: + case VTK_QUADRATIC_QUAD: + case VTK_BIQUADRATIC_QUAD: + return SMDSGeom_QUADRANGLE; + case VTK_POLYGON: + return SMDSGeom_POLYGON; + default:; + } + return SMDSGeom_NONE; +} + +vtkIdType SMDS_VtkFace::GetVtkType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return aVtkType; +} + +SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); + default: + MESSAGE("ERROR : Iterator not implemented") + ; + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_ElemIteratorPtr SMDS_VtkFace::nodesIteratorToUNV() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_ElemIteratorPtr SMDS_VtkFace::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +//! change only the first node, used for temporary triangles in quadrangle to triangle adaptor +void SMDS_VtkFace::ChangeApex(SMDS_MeshNode* node) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + grid->RemoveReferenceToCell(pts[0], myVtkID); + pts[0] = node->getVtkId(); + node->AddInverseElement(this), + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); +} diff --git a/src/SMDS/SMDS_VtkFace.hxx b/src/SMDS/SMDS_VtkFace.hxx new file mode 100644 index 000000000..f84192f3f --- /dev/null +++ b/src/SMDS/SMDS_VtkFace.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _SMDS_VTKFACE_HXX_ +#define _SMDS_VTKFACE_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshFace.hxx" +#include +#include + +class SMDS_EXPORT SMDS_VtkFace: public SMDS_MeshFace +{ +public: + SMDS_VtkFace(); + SMDS_VtkFace(const std::vector& nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkFace(); + void init(const std::vector& nodeIds, SMDS_Mesh* mesh); + void initPoly(const std::vector& nodeIds, SMDS_Mesh* mesh); + + bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles + + virtual void Print(std::ostream & OS) const; + virtual int NbEdges() const; + virtual int NbFaces() const; + virtual int NbNodes() const; + + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + + virtual bool IsQuadratic() const; + virtual bool IsPoly() const; + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + virtual int NbCornerNodes() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; +protected: +}; + +#endif diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx new file mode 100644 index 000000000..de9174e0b --- /dev/null +++ b/src/SMDS/SMDS_VtkVolume.cxx @@ -0,0 +1,675 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMDS_VtkVolume.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_VtkCellIterator.hxx" + +#include "utilities.h" + +#include + +SMDS_VtkVolume::SMDS_VtkVolume() +{ +} + +SMDS_VtkVolume::SMDS_VtkVolume(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + init(nodeIds, mesh); +} +/*! + * typed used are vtk types (@see vtkCellType.h) + * see GetEntityType() for conversion in SMDS type (@see SMDSAbs_ElementType.hxx) + */ +void SMDS_VtkVolume::init(const std::vector& nodeIds, SMDS_Mesh* mesh) +{ + SMDS_MeshVolume::init(); + vtkUnstructuredGrid* grid = mesh->getGrid(); + myMeshId = mesh->getMeshId(); + vtkIdType aType = VTK_TETRA; + switch (nodeIds.size()) // cases are in order of usage frequency + { + case 4: + aType = VTK_TETRA; + break; + case 8: + aType = VTK_HEXAHEDRON; + break; + case 5: + aType = VTK_PYRAMID; + break; + case 6: + aType = VTK_WEDGE; + break; + case 10: + aType = VTK_QUADRATIC_TETRA; + break; + case 20: + aType = VTK_QUADRATIC_HEXAHEDRON; + break; + case 13: + aType = VTK_QUADRATIC_PYRAMID; + break; + case 15: + aType = VTK_QUADRATIC_WEDGE; + break; + case 12: + aType = VTK_HEXAGONAL_PRISM; + break; + case 27: + aType = VTK_TRIQUADRATIC_HEXAHEDRON; + break; + default: + aType = VTK_HEXAHEDRON; + break; + } + myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]); + mesh->setMyModified(); + //MESSAGE("SMDS_VtkVolume::init myVtkID " << myVtkID); +} + +//#ifdef VTK_HAVE_POLYHEDRON +void SMDS_VtkVolume::initPoly(const std::vector& nodeIds, + const std::vector& nbNodesPerFace, + SMDS_Mesh* mesh) +{ + SMDS_MeshVolume::init(); + //MESSAGE("SMDS_VtkVolume::initPoly"); + SMDS_UnstructuredGrid* grid = mesh->getGrid(); + //double center[3]; + //this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), ¢er[0]); + vector ptIds; + vtkIdType nbFaces = nbNodesPerFace.size(); + int k = 0; + for (int i = 0; i < nbFaces; i++) + { + int nf = nbNodesPerFace[i]; + ptIds.push_back(nf); + // EAP: a right approach is: + // - either the user should care of order of nodes or + // - the user should use a service method arranging nodes if he + // don't want or can't to do it by him-self + // The method below works OK only with planar faces and convex polyhedrones + // + // double a[3]; + // double b[3]; + // double c[3]; + // grid->GetPoints()->GetPoint(nodeIds[k], a); + // grid->GetPoints()->GetPoint(nodeIds[k + 1], b); + // grid->GetPoints()->GetPoint(nodeIds[k + 2], c); + // bool isFaceForward = this->isForward(a, b, c, center); + //MESSAGE("isFaceForward " << i << " " << isFaceForward); + const vtkIdType *facePts = &nodeIds[k]; + //if (isFaceForward) + for (int n = 0; n < nf; n++) + ptIds.push_back(facePts[n]); + // else + // for (int n = nf - 1; n >= 0; n--) + // ptIds.push_back(facePts[n]); + k += nf; + } + myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]); + mesh->setMyModified(); +} +//#endif + +bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + if (nbNodes != npts) + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } + for (int i = 0; i < nbNodes; i++) + { + pts[i] = nodes[i]->getVtkId(); + } + SMDS_Mesh::_meshList[myMeshId]->setMyModified(); + return true; +} + +/*! + * Reorder in VTK order a list of nodes given in SMDS order. + * To be used before ChangeNodes: lists are given or computed in SMDS order. + */ +bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) +{ + if (nbNodes != this->NbNodes()) + { + MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes()); + return false; + } + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + const std::vector& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType )); + if ( !interlace.empty() ) + { + ASSERT( interlace.size() == nbNodes ); + std::vector initNodes( nodes, nodes+nbNodes ); + for ( size_t i = 0; i < interlace.size(); ++i ) + nodes[i] = initNodes[ interlace[i] ]; + } + return true; +} + +SMDS_VtkVolume::~SMDS_VtkVolume() +{ +} + +void SMDS_VtkVolume::Print(ostream & OS) const +{ + OS << "volume <" << GetID() << "> : "; +} + +int SMDS_VtkVolume::NbFaces() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbFaces = 4; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + nbFaces = 4; + break; + case VTK_PYRAMID: + case VTK_WEDGE: + case VTK_QUADRATIC_PYRAMID: + case VTK_QUADRATIC_WEDGE: + nbFaces = 5; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + nbFaces = 6; + break; + case VTK_POLYHEDRON: + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + nbFaces = nFaces; + break; + } + case VTK_HEXAGONAL_PRISM: + nbFaces = 8; + break; + default: + MESSAGE("invalid volume type") + ; + nbFaces = 0; + break; + } + return nbFaces; +} + +int SMDS_VtkVolume::NbNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbPoints = 0; + if (aVtkType != VTK_POLYHEDRON) + { + nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints(); + } + else + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; + nbPoints += nodesInFace; + id += (nodesInFace + 1); + } + } + return nbPoints; +} + +int SMDS_VtkVolume::NbEdges() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbEdges = 6; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + nbEdges = 6; + break; + case VTK_PYRAMID: + case VTK_QUADRATIC_PYRAMID: + nbEdges = 8; + break; + case VTK_WEDGE: + case VTK_QUADRATIC_WEDGE: + nbEdges = 9; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + nbEdges = 12; + break; + case VTK_POLYHEDRON: + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + nbEdges = 0; + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int edgesInFace = ptIds[id]; + id += (edgesInFace + 1); + nbEdges += edgesInFace; + } + nbEdges = nbEdges / 2; + break; + } + case VTK_HEXAGONAL_PRISM: + nbEdges = 18; + break; + default: + MESSAGE("invalid volume type") + ; + nbEdges = 0; + break; + } + return nbEdges; +} + +/*! polyhedron only, + * 1 <= face_ind <= NbFaces() + */ +int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int nbNodes = 0; + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; + id += (nodesInFace + 1); + if (i == face_ind - 1) + { + nbNodes = nodesInFace; + break; + } + } + } + return nbNodes; +} + +/*! polyhedron only, + * 1 <= face_ind <= NbFaces() + * 1 <= node_ind <= NbFaceNodes() + */ +const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int node_ind) const +{ + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkUnstructuredGrid* grid = mesh->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + const SMDS_MeshNode* node = 0; + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + if (i == face_ind - 1) // first face is number 1 + { + if ((node_ind > 0) && (node_ind <= nodesInFace)) + node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node + break; + } + id += (nodesInFace + 1); + } + } + return node; +} + +/*! polyhedron only, + * return number of nodes for each face + */ +std::vector SMDS_VtkVolume::GetQuantities() const +{ + vector quantities; + quantities.clear(); + SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; + vtkUnstructuredGrid* grid = mesh->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) + { + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + quantities.push_back(nodesInFace); + id += (nodesInFace + 1); + } + } + return quantities; +} + +SMDS_ElemIteratorPtr SMDS_VtkVolume::elementsIterator(SMDSAbs_ElementType type) const +{ + switch (type) + { + case SMDSAbs_Node: + { + SMDSAbs_EntityType aType = this->GetEntityType(); + if (aType == SMDSEntity_Polyhedra) + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorPolyH(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType)); + else + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType)); + } + default: + MESSAGE("ERROR : Iterator not implemented"); + return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL); + } +} + +SMDS_ElemIteratorPtr SMDS_VtkVolume::nodesIteratorToUNV() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDS_ElemIteratorPtr SMDS_VtkVolume::interlacedNodesElemIterator() const +{ + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} + +SMDSAbs_ElementType SMDS_VtkVolume::GetType() const +{ + return SMDSAbs_Volume; +} + +/*! + * \brief Return node by its index + * \param ind - node index + * \retval const SMDS_MeshNode* - the node + */ +const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + vtkIdType npts, *pts; + grid->GetCellPoints( this->myVtkID, npts, pts ); + const std::vector& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( aVtkType )); + return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ind]] ); +} + +bool SMDS_VtkVolume::IsQuadratic() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + // TODO quadratic polyhedrons ? + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: + case VTK_QUADRATIC_PYRAMID: + case VTK_QUADRATIC_WEDGE: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + return true; + break; + default: + return false; + } +} + +bool SMDS_VtkVolume::IsPoly() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + return (aVtkType == VTK_POLYHEDRON); +} + +bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + int rankFirstMedium = 0; + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: + rankFirstMedium = 4; // medium nodes are of rank 4 to 9 + break; + case VTK_QUADRATIC_PYRAMID: + rankFirstMedium = 5; // medium nodes are of rank 5 to 12 + break; + case VTK_QUADRATIC_WEDGE: + rankFirstMedium = 6; // medium nodes are of rank 6 to 14 + break; + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + rankFirstMedium = 8; // medium nodes are of rank 8 to 19 + break; + default: + return false; + } + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(myVtkID, npts, pts); + vtkIdType nodeId = node->getVtkId(); + for (int rank = 0; rank < npts; rank++) + { + if (pts[rank] == nodeId) + { + if (rank < rankFirstMedium) + return false; + else + return true; + } + } + //throw SALOME_Exception(LOCALIZED("node does not belong to this element")); + MESSAGE("======================================================"); + MESSAGE("= IsMediumNode: node does not belong to this element ="); + MESSAGE("======================================================"); + return false; +} + +int SMDS_VtkVolume::NbCornerNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + int nbN = grid->GetCell(myVtkID)->GetNumberOfPoints(); + vtkIdType aVtkType = grid->GetCellType(myVtkID); + switch (aVtkType) + { + case VTK_QUADRATIC_TETRA: return 4; + case VTK_QUADRATIC_PYRAMID: return 5; + case VTK_QUADRATIC_WEDGE: return 6; + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: return 8; + default:; + } + return nbN; +} + +SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + + SMDSAbs_EntityType aType = SMDSEntity_Tetra; + switch (aVtkType) + { + case VTK_TETRA: + aType = SMDSEntity_Tetra; + break; + case VTK_PYRAMID: + aType = SMDSEntity_Pyramid; + break; + case VTK_WEDGE: + aType = SMDSEntity_Penta; + break; + case VTK_HEXAHEDRON: + aType = SMDSEntity_Hexa; + break; + case VTK_QUADRATIC_TETRA: + aType = SMDSEntity_Quad_Tetra; + break; + case VTK_QUADRATIC_PYRAMID: + aType = SMDSEntity_Quad_Pyramid; + break; + case VTK_QUADRATIC_WEDGE: + aType = SMDSEntity_Quad_Penta; + break; + case VTK_QUADRATIC_HEXAHEDRON: + aType = SMDSEntity_Quad_Hexa; + break; + case VTK_TRIQUADRATIC_HEXAHEDRON: + aType = SMDSEntity_TriQuad_Hexa; + break; + case VTK_HEXAGONAL_PRISM: + aType = SMDSEntity_Hexagonal_Prism; + break; +//#ifdef VTK_HAVE_POLYHEDRON + case VTK_POLYHEDRON: + aType = SMDSEntity_Polyhedra; + break; +//#endif + default: + aType = SMDSEntity_Polyhedra; + break; + } + return aType; +} + +SMDSAbs_GeometryType SMDS_VtkVolume::GetGeomType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aVtkType = grid->GetCellType(this->myVtkID); + + SMDSAbs_GeometryType aType = SMDSGeom_NONE; + switch (aVtkType) + { + case VTK_TETRA: + case VTK_QUADRATIC_TETRA: + aType = SMDSGeom_TETRA; + break; + case VTK_PYRAMID: + case VTK_QUADRATIC_PYRAMID: + aType = SMDSGeom_PYRAMID; + break; + case VTK_WEDGE: + case VTK_QUADRATIC_WEDGE: + aType = SMDSGeom_PENTA; + break; + case VTK_HEXAHEDRON: + case VTK_QUADRATIC_HEXAHEDRON: + case VTK_TRIQUADRATIC_HEXAHEDRON: + aType = SMDSGeom_HEXA; + break; + case VTK_HEXAGONAL_PRISM: + aType = SMDSGeom_HEXAGONAL_PRISM; + break; +//#ifdef VTK_HAVE_POLYHEDRON + case VTK_POLYHEDRON: + aType = SMDSGeom_POLYHEDRA; + break; +//#endif + default: + aType = SMDSGeom_POLYHEDRA; + break; + } + return aType; +} + +vtkIdType SMDS_VtkVolume::GetVtkType() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + vtkIdType aType = grid->GetCellType(myVtkID); + return aType; +} + +void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid, + const vtkIdType * nodeIds, + int nbNodes, + double* result) +{ + for (int j = 0; j < 3; j++) + result[j] = 0; + if (nbNodes <= 0) + return; + for (int i = 0; i < nbNodes; i++) + { + double *coords = grid->GetPoint(nodeIds[i]); + for (int j = 0; j < 3; j++) + result[j] += coords[j]; + } + for (int j = 0; j < 3; j++) + result[j] = result[j] / nbNodes; + //MESSAGE("center " << result[0] << " " << result[1] << " " << result[2]); + return; +} + +bool SMDS_VtkVolume::isForward(double* a, double* b, double* c, double* d) +{ + double u[3], v[3], w[3]; + for (int j = 0; j < 3; j++) + { + //MESSAGE("a,b,c,d " << a[j] << " " << b[j] << " " << c[j] << " " << d[j]); + u[j] = b[j] - a[j]; + v[j] = c[j] - a[j]; + w[j] = d[j] - a[j]; + //MESSAGE("u,v,w " << u[j] << " " << v[j] << " " << w[j]); + } + double prodmixte = (u[1]*v[2] - u[2]*v[1]) * w[0] + + (u[2]*v[0] - u[0]*v[2]) * w[1] + + (u[0]*v[1] - u[1]*v[0]) * w[2]; + return (prodmixte < 0); +} + +/*! For polyhedron only + * @return actual number of nodes (not the sum of nodes of all faces) + */ +int SMDS_VtkVolume::NbUniqueNodes() const +{ + vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); + return grid->GetCell(myVtkID)->GetNumberOfPoints(); +} + +/*! For polyhedron use only + * @return iterator on actual nodes (not through the faces) + */ +SMDS_ElemIteratorPtr SMDS_VtkVolume::uniqueNodesIterator() const +{ + MESSAGE("uniqueNodesIterator"); + return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); +} diff --git a/src/SMDS/SMDS_VtkVolume.hxx b/src/SMDS/SMDS_VtkVolume.hxx new file mode 100644 index 000000000..5f3f62b31 --- /dev/null +++ b/src/SMDS/SMDS_VtkVolume.hxx @@ -0,0 +1,79 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _SMDS_VTKVOLUME_HXX_ +#define _SMDS_VTKVOLUME_HXX_ + +#include "SMESH_SMDS.hxx" + +#include "SMDS_MeshVolume.hxx" +#include "SMDS_UnstructuredGrid.hxx" +#include + +class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume +{ +public: + SMDS_VtkVolume(); + SMDS_VtkVolume(const std::vector& nodeIds, SMDS_Mesh* mesh); + ~SMDS_VtkVolume(); + void init(const std::vector& nodeIds, SMDS_Mesh* mesh); +//#ifdef VTK_HAVE_POLYHEDRON + void initPoly(const std::vector& nodeIds, + const std::vector& nbNodesPerFace, SMDS_Mesh* mesh); +//#endif + virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes); + virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes); + + virtual void Print(std::ostream & OS) const; + virtual int NbFaces() const; + virtual int NbNodes() const; + virtual int NbEdges() const; + + // 1 <= face_ind <= NbFaces() + int NbFaceNodes (const int face_ind) const; + // 1 <= face_ind <= NbFaces() + // 1 <= node_ind <= NbFaceNodes() + const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; + + virtual SMDSAbs_ElementType GetType() const; + virtual vtkIdType GetVtkType() const; + virtual SMDSAbs_EntityType GetEntityType() const; + virtual SMDSAbs_GeometryType GetGeomType() const; + virtual const SMDS_MeshNode* GetNode(const int ind) const; + virtual bool IsQuadratic() const; + virtual bool IsPoly() const; + virtual bool IsMediumNode(const SMDS_MeshNode* node) const; + virtual int NbCornerNodes() const; + static void gravityCenter(SMDS_UnstructuredGrid* grid, + const vtkIdType *nodeIds, + int nbNodes, + double* result); + static bool isForward(double* a,double* b,double* c,double* d); + int NbUniqueNodes() const; + SMDS_ElemIteratorPtr uniqueNodesIterator() const; + std::vector GetQuantities() const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; + virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const; + virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const; + +protected: +}; + +#endif diff --git a/src/SMDS/SMESH_SMDS.hxx b/src/SMDS/SMESH_SMDS.hxx index 97a1b63ff..d99e401df 100755 --- a/src/SMDS/SMESH_SMDS.hxx +++ b/src/SMDS/SMESH_SMDS.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_SMDS.hxx // Author : Alexander A. BORODIN // Module : SMESH diff --git a/src/SMDS/chrono.cxx b/src/SMDS/chrono.cxx new file mode 100644 index 000000000..8956ce34a --- /dev/null +++ b/src/SMDS/chrono.cxx @@ -0,0 +1,86 @@ +// Copyright (C) 2006-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "chrono.hxx" +#include "utilities.h" + +using namespace std; + +cntStruct* counters::_ctrs = 0; +int counters::_nbChrono = 0; + +counters::counters(int nb) +{ + MESSAGE("counters::counters(int nb)"); + _nbChrono = nb; + _ctrs = new cntStruct[_nbChrono]; + + for (int i = 0; i < _nbChrono; i++) + { + _ctrs[i]._ctrNames = 0; + _ctrs[i]._ctrLines = 0; + _ctrs[i]._ctrOccur = 0; + _ctrs[i]._ctrCumul = 0; + } + + MESSAGE("counters::counters()"); +} + +counters::~counters() +{ + stats(); +} + +void counters::stats() +{ + MESSAGE("counters::stats()"); + for (int i = 0; i < _nbChrono; i++) + if (_ctrs[i]._ctrOccur) + { + MESSAGE("Compteur[" << i << "]: "<< _ctrs[i]._ctrNames << "[" << _ctrs[i]._ctrLines << "]"); + MESSAGE(" " << _ctrs[i]._ctrOccur); + MESSAGE(" " << _ctrs[i]._ctrCumul); + } +} + +chrono::chrono(int i) : + _ctr(i), _run(true) +{ + //MESSAGE("chrono::chrono " << _ctr << " " << _run); + _start = clock(); +} + +chrono::~chrono() +{ + if (_run) + stop(); +} + +void chrono::stop() +{ + //MESSAGE("chrono::stop " << _ctr << " " << _run); + if (_run) + { + _run = false; + _end = clock(); + double elapse = double(_end - _start) / double(CLOCKS_PER_SEC); + counters::_ctrs[_ctr]._ctrOccur++; + counters::_ctrs[_ctr]._ctrCumul += elapse; + } +} diff --git a/src/SMDS/chrono.hxx b/src/SMDS/chrono.hxx new file mode 100644 index 000000000..bee39b0b8 --- /dev/null +++ b/src/SMDS/chrono.hxx @@ -0,0 +1,75 @@ +// Copyright (C) 2006-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _CHRONO_HXX_ +#define _CHRONO_HXX_ + +#include "SMESH_SMDS.hxx" + +#include +#include +#include +#include + +typedef struct acnt +{ + char* _ctrNames; + int _ctrLines; + int _ctrOccur; + double _ctrCumul; +} cntStruct; + +class SMDS_EXPORT counters +{ +public: + static cntStruct *_ctrs; + counters(int nb); + ~counters(); + static void stats(); +protected: + static int _nbChrono; +}; + +class SMDS_EXPORT chrono +{ +public: + chrono(int i); + ~chrono(); + void stop(); +protected: + bool _run; + int _ctr; + clock_t _start, _end; +}; + +#ifdef CHRONODEF +#define CHRONO(i) counters::_ctrs[i]._ctrNames = (char *)__FILE__; \ + counters::_ctrs[i]._ctrLines = __LINE__; \ + chrono aChrono##i(i); + +#define CHRONOSTOP(i) aChrono##i.stop(); + +#else // CHRONODEF + +#define CHRONO(i) +#define CHRONOSTOP(i) + +#endif // CHRONODEF + +#endif // _CHRONO_HXX_ diff --git a/src/SMESH/Makefile.am b/src/SMESH/Makefile.am index 2905cc92b..3008e024f 100644 --- a/src/SMESH/Makefile.am +++ b/src/SMESH/Makefile.am @@ -1,31 +1,28 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESH : implementaion of SMESH idl descriptions # File : Makefile.in # Author : Paul RASCLE, EDF # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : SMESH -# $Header$ -# + include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files @@ -43,17 +40,9 @@ salomeinclude_HEADERS = \ SMESH_3D_Algo.hxx \ SMESH_Group.hxx \ SMESH_MeshEditor.hxx \ - SMESH_Block.hxx \ SMESH_Pattern.hxx \ - SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx \ - SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx \ - SMESH_SequenceOfElemPtr.hxx \ - SMESH_SequenceOfNode.hxx \ SMESH_MesherHelper.hxx \ - SMESH_Octree.hxx \ - SMESH_OctreeNode.hxx \ - SMESH_Comment.hxx \ - SMESH_ComputeError.hxx \ + SMESH_ProxyMesh.hxx \ SMESH_SMESH.hxx # Libraries targets @@ -61,6 +50,7 @@ salomeinclude_HEADERS = \ lib_LTLIBRARIES = libSMESHimpl.la dist_libSMESHimpl_la_SOURCES = \ + memoire.h \ SMESH_Gen.cxx \ SMESH_Mesh.cxx \ SMESH_subMesh.cxx \ @@ -72,12 +62,10 @@ dist_libSMESHimpl_la_SOURCES = \ SMESH_3D_Algo.cxx \ SMESH_Group.cxx \ SMESH_MeshEditor.cxx \ - SMESH_Block.cxx \ SMESH_Pattern.cxx \ SMESH_HypoFilter.cxx \ - SMESH_MesherHelper.cxx \ - SMESH_Octree.cxx \ - SMESH_OctreeNode.cxx + SMESH_ProxyMesh.cxx \ + SMESH_MesherHelper.cxx # additionnal information to compile and link file libSMESHimpl_la_CPPFLAGS = \ @@ -85,6 +73,7 @@ libSMESHimpl_la_CPPFLAGS = \ $(CAS_CPPFLAGS) \ $(MED_CXXFLAGS) \ $(GEOM_CXX_FLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ @HDF5_INCLUDES@ \ -I$(srcdir)/../Controls \ @@ -93,10 +82,14 @@ libSMESHimpl_la_CPPFLAGS = \ -I$(srcdir)/../DriverMED \ -I$(srcdir)/../DriverUNV \ -I$(srcdir)/../DriverSTL \ + -I$(srcdir)/../DriverCGNS \ -I$(srcdir)/../SMDS \ -I$(srcdir)/../SMESHDS \ - -I$(top_builddir)/salome_adm/unix + -I$(srcdir)/../SMESHUtils +if WITH_CGNS + DriverCGNS_LIB = ../DriverCGNS/libMeshDriverCGNS.la +endif libSMESHimpl_la_LDFLAGS = \ ../SMESHDS/libSMESHDS.la \ @@ -105,5 +98,8 @@ libSMESHimpl_la_LDFLAGS = \ ../DriverSTL/libMeshDriverSTL.la \ ../DriverMED/libMeshDriverMED.la \ ../DriverUNV/libMeshDriverUNV.la \ + $(DriverCGNS_LIB) \ + ../SMESHUtils/libSMESHUtils.la \ + $(BOOST_LIB_THREAD) \ $(GEOM_LDFLAGS) -lNMTTools \ - $(CAS_LDPATH) -lTKShHealing + $(CAS_LDPATH) -lTKShHealing -lTKPrim -lTKG2d diff --git a/src/SMESH/SMESH_0D_Algo.cxx b/src/SMESH/SMESH_0D_Algo.cxx index f20074cc3..bc3461d10 100644 --- a/src/SMESH/SMESH_0D_Algo.cxx +++ b/src/SMESH/SMESH_0D_Algo.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_0D_Algo.cxx // Module : SMESH diff --git a/src/SMESH/SMESH_0D_Algo.hxx b/src/SMESH/SMESH_0D_Algo.hxx index 71f7476e6..d7ba782d8 100644 --- a/src/SMESH/SMESH_0D_Algo.hxx +++ b/src/SMESH/SMESH_0D_Algo.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_0D_Algo.hxx // Module : SMESH diff --git a/src/SMESH/SMESH_1D_Algo.cxx b/src/SMESH/SMESH_1D_Algo.cxx index ff6b9f7ff..3027f82f4 100644 --- a/src/SMESH/SMESH_1D_Algo.cxx +++ b/src/SMESH/SMESH_1D_Algo.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_1D_Algo.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH/SMESH_1D_Algo.hxx b/src/SMESH/SMESH_1D_Algo.hxx index 9da4fd985..e10aa197d 100644 --- a/src/SMESH/SMESH_1D_Algo.hxx +++ b/src/SMESH/SMESH_1D_Algo.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_1D_Algo.hxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH/SMESH_2D_Algo.cxx b/src/SMESH/SMESH_2D_Algo.cxx index 00723cbd7..a4feece7b 100644 --- a/src/SMESH/SMESH_2D_Algo.cxx +++ b/src/SMESH/SMESH_2D_Algo.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_2D_Algo.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH/SMESH_2D_Algo.hxx b/src/SMESH/SMESH_2D_Algo.hxx index 41a8bc1af..0a2a127f3 100644 --- a/src/SMESH/SMESH_2D_Algo.hxx +++ b/src/SMESH/SMESH_2D_Algo.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_2D_Algo.hxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH/SMESH_3D_Algo.cxx b/src/SMESH/SMESH_3D_Algo.cxx index ee547368f..d7a0ed88d 100644 --- a/src/SMESH/SMESH_3D_Algo.cxx +++ b/src/SMESH/SMESH_3D_Algo.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_3D_Algo.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH/SMESH_3D_Algo.hxx b/src/SMESH/SMESH_3D_Algo.hxx index 9c4761408..2b64d9eb0 100644 --- a/src/SMESH/SMESH_3D_Algo.hxx +++ b/src/SMESH/SMESH_3D_Algo.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_3D_Algo.hxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 7398cf856..9768eb049 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -1,41 +1,46 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Algo.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// #include "SMESH_Algo.hxx" -#include "SMESH_Comment.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_HypoFilter.hxx" -#include "SMDS_FacePosition.hxx" + #include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMDS_VolumeTool.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESHDS_SubMesh.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_TypeDefs.hxx" + +#include #include #include @@ -61,6 +66,7 @@ #include "utilities.h" #include +#include using namespace std; @@ -75,8 +81,8 @@ SMESH_Algo::SMESH_Algo (int hypId, int studyId, SMESH_Gen * gen) { gen->_mapAlgo[hypId] = this; - _onlyUnaryInput = _requireDescretBoundary = _requireShape = true; - _quadraticMesh = false; + _onlyUnaryInput = _requireDiscreteBoundary = _requireShape = true; + _quadraticMesh = _supportSubmeshes = false; _error = COMPERR_OK; } @@ -170,11 +176,42 @@ double SMESH_Algo::EdgeLength(const TopoDS_Edge & E) return 0; TopLoc_Location L; Handle(Geom_Curve) C = BRep_Tool::Curve(E, L, UMin, UMax); - GeomAdaptor_Curve AdaptCurve(C); + GeomAdaptor_Curve AdaptCurve(C, UMin, UMax); //range is important for periodic curves double length = GCPnts_AbscissaPoint::Length(AdaptCurve, UMin, UMax); return length; } +//================================================================================ +/*! + * \brief Calculate normal of a mesh face + */ +//================================================================================ + +bool SMESH_Algo::FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool normalized) +{ + if ( !F || F->GetType() != SMDSAbs_Face ) + return false; + + normal.SetCoord(0,0,0); + int nbNodes = F->IsQuadratic() ? F->NbNodes()/2 : F->NbNodes(); + for ( int i = 0; i < nbNodes-2; ++i ) + { + gp_XYZ p[3]; + for ( int n = 0; n < 3; ++n ) + { + const SMDS_MeshNode* node = F->GetNode( i + n ); + p[n].SetCoord( node->X(), node->Y(), node->Z() ); + } + normal += ( p[2] - p[1] ) ^ ( p[0] - p[1] ); + } + double size2 = normal.SquareModulus(); + bool ok = ( size2 > numeric_limits::min() * numeric_limits::min()); + if ( normalized && ok ) + normal /= sqrt( size2 ); + + return ok; +} + //================================================================================ /*! * \brief Find out elements orientation on a geometrical face @@ -223,10 +260,10 @@ bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face& theFace, const SMDS_PositionPtr& pos = node->GetPosition(); if ( !pos ) continue; if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) { - fPos = dynamic_cast< const SMDS_FacePosition* >( pos.get() ); + fPos = dynamic_cast< const SMDS_FacePosition* >( pos ); } else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) { - vID = pos->GetShapeId(); + vID = node->getshapeId(); } } if ( fPos || ( !normalOK && vID )) { @@ -321,7 +358,7 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh, if ( !eSubMesh || !eSubMesh->GetElements()->more() ) return false; // edge is not meshed - int nbEdgeNodes = 0; + //int nbEdgeNodes = 0; set < double > paramSet; if ( eSubMesh ) { @@ -334,17 +371,19 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh, if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) return false; const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); - paramSet.insert( epos->GetUParameter() ); - ++nbEdgeNodes; + static_cast(node->GetPosition()); + if ( !paramSet.insert( epos->GetUParameter() ).second ) + return false; // equal parameters } } // add vertex nodes params - Standard_Real f, l; - BRep_Tool::Range(theEdge, f, l); - paramSet.insert( f ); - paramSet.insert( l ); - if ( paramSet.size() != nbEdgeNodes + 2 ) + TopoDS_Vertex V1,V2; + TopExp::Vertices( theEdge, V1, V2); + if ( VertexNode( V1, theMesh ) && + !paramSet.insert( BRep_Tool::Parameter(V1,theEdge) ).second ) + return false; // there are equal parameters + if ( VertexNode( V2, theMesh ) && + !paramSet.insert( BRep_Tool::Parameter(V2,theEdge) ).second ) return false; // there are equal parameters // fill the vector @@ -399,8 +438,9 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE ) return false; const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); - theNodes.insert( make_pair( epos->GetUParameter(), node )); + static_cast(node->GetPosition()); + theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node )); + //MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID()); ++nbNodes; } } @@ -409,6 +449,7 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh* theM TopExp::Vertices(theEdge, v1, v2); const SMDS_MeshNode* n1 = VertexNode( v1, (SMESHDS_Mesh*) theMesh ); const SMDS_MeshNode* n2 = VertexNode( v2, (SMESHDS_Mesh*) theMesh ); + //MESSAGE("Vertices ID " << n1->GetID() << " " << n2->GetID()); Standard_Real f, l; BRep_Tool::Range(theEdge, f, l); if ( v1.Orientation() != TopAbs_FORWARD ) @@ -455,20 +496,31 @@ bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter, */ //================================================================================ -GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge & E1, - const TopoDS_Edge & E2) +GeomAbs_Shape SMESH_Algo::Continuity(TopoDS_Edge E1, + 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; + //E1.Orientation(TopAbs_FORWARD), E2.Orientation(TopAbs_FORWARD); // avoid pb with internal edges + if (E1.Orientation() > TopAbs_REVERSED) // INTERNAL + E1.Orientation( TopAbs_FORWARD ); + if (E2.Orientation() > TopAbs_REVERSED) // INTERNAL + E2.Orientation( TopAbs_FORWARD ); + + TopoDS_Vertex V, VV1[2], VV2[2]; + TopExp::Vertices( E1, VV1[0], VV1[1], true ); + TopExp::Vertices( E2, VV2[0], VV2[1], true ); + if ( VV1[1].IsSame( VV2[0] )) { V = VV1[1]; } + else if ( VV1[0].IsSame( VV2[1] )) { V = VV1[0]; } + else if ( VV1[1].IsSame( VV2[1] )) { V = VV1[1]; E1.Reverse(); } + else if ( VV1[0].IsSame( VV2[0] )) { V = VV1[0]; E1.Reverse(); } + else { 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 ); Standard_Real tol = BRep_Tool::Tolerance( V ); Standard_Real angTol = 2e-3; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif return BRepLProp::Continuity(C1, C2, u1, u2, tol, angTol); @@ -488,7 +540,7 @@ GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge & E1, //================================================================================ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V, - SMESHDS_Mesh* meshDS) + const SMESHDS_Mesh* meshDS) { if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(V) ) { SMDS_NodeIteratorPtr nIt= sm->GetNodes(); @@ -498,6 +550,103 @@ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V, return 0; } +//======================================================================= +//function : GetCommonNodes +//purpose : Return nodes common to two elements +//======================================================================= + +vector< const SMDS_MeshNode*> SMESH_Algo::GetCommonNodes(const SMDS_MeshElement* e1, + const SMDS_MeshElement* e2) +{ + vector< const SMDS_MeshNode*> common; + for ( int i = 0 ; i < e1->NbNodes(); ++i ) + if ( e2->GetNodeIndex( e1->GetNode( i )) >= 0 ) + common.push_back( e1->GetNode( i )); + return common; +} + +//======================================================================= +//function : GetMeshError +//purpose : Finds topological errors of a sub-mesh +//WARNING : 1D check is NOT implemented so far +//======================================================================= + +SMESH_Algo::EMeshError SMESH_Algo::GetMeshError(SMESH_subMesh* subMesh) +{ + EMeshError err = MEr_OK; + + SMESHDS_SubMesh* smDS = subMesh->GetSubMeshDS(); + if ( !smDS ) + return MEr_EMPTY; + + switch ( subMesh->GetSubShape().ShapeType() ) + { + case TopAbs_FACE: { // ====================== 2D ===================== + + SMDS_ElemIteratorPtr fIt = smDS->GetElements(); + if ( !fIt->more() ) + return MEr_EMPTY; + + // We check that olny links on EDGEs encouter once, the rest links, twice + set< SMESH_TLink > links; + while ( fIt->more() ) + { + const SMDS_MeshElement* f = fIt->next(); + int nbNodes = f->NbCornerNodes(); // ignore medium nodes + for ( int i = 0; i < nbNodes; ++i ) + { + const SMDS_MeshNode* n1 = f->GetNode( i ); + const SMDS_MeshNode* n2 = f->GetNode(( i+1 ) % nbNodes); + std::pair< set< SMESH_TLink >::iterator, bool > it_added = + links.insert( SMESH_TLink( n1, n2 )); + if ( !it_added.second ) + // As we do NOT(!) check if mesh is manifold, we believe that a link can + // encounter once or twice only (not three times), we erase a link as soon + // as it encounters twice to speed up search in the map. + links.erase( it_added.first ); + } + } + // the links remaining in the should all be on EDGE + set< SMESH_TLink >::iterator linkIt = links.begin(); + for ( ; linkIt != links.end(); ++linkIt ) + { + const SMESH_TLink& link = *linkIt; + if ( link.node1()->GetPosition()->GetTypeOfPosition() > SMDS_TOP_EDGE || + link.node2()->GetPosition()->GetTypeOfPosition() > SMDS_TOP_EDGE ) + return MEr_HOLES; + } + // TODO: to check orientation + break; + } + case TopAbs_SOLID: { // ====================== 3D ===================== + + SMDS_ElemIteratorPtr vIt = smDS->GetElements(); + if ( !vIt->more() ) + return MEr_EMPTY; + + SMDS_VolumeTool vTool; + while ( !vIt->more() ) + { + if (!vTool.Set( vIt->next() )) + continue; // strange + + for ( int iF = 0; iF < vTool.NbFaces(); ++iF ) + if ( vTool.IsFreeFace( iF )) + { + int nbN = vTool.NbFaceNodes( iF ); + const SMDS_MeshNode** nodes = vTool.GetFaceNodes( iF ); + for ( int i = 0; i < nbN; ++i ) + if ( nodes[i]->GetPosition()->GetTypeOfPosition() > SMDS_TOP_FACE ) + return MEr_HOLES; + } + } + break; + } + default:; + } + return err; +} + //================================================================================ /*! * \brief Sets event listener to submeshes if necessary @@ -539,6 +688,18 @@ bool SMESH_Algo::Compute(SMESH_Mesh & /*aMesh*/, SMESH_MesherHelper* /*aHelper*/ return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected"); } +//======================================================================= +//function : CancelCompute +//purpose : Sets _computeCanceled to true. It's usage depends on +// * implementation of a particular mesher. +//======================================================================= + +void SMESH_Algo::CancelCompute() +{ + _computeCanceled = true; + _error = COMPERR_CANCELED; +} + //================================================================================ /*! * \brief store error and comment and then return ( error == COMPERR_OK ) @@ -599,6 +760,8 @@ void SMESH_Algo::InitComputeError() if ( (*elem)->GetID() < 1 ) delete *elem; _badInputElements.clear(); + + _computeCanceled = false; } //================================================================================ diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index 4b681dc0a..580445b48 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Algo.hxx // Author : Paul RASCLE, EDF // Module : SMESH // - #ifndef _SMESH_ALGO_HXX_ #define _SMESH_ALGO_HXX_ @@ -53,8 +53,20 @@ class SMESHDS_Mesh; class SMDS_MeshNode; class SMESH_subMesh; class SMESH_MesherHelper; - - +class gp_XYZ; + +typedef std::map< SMESH_subMesh*, std::vector > MapShapeNbElems; +typedef std::map< SMESH_subMesh*, std::vector >::iterator MapShapeNbElemsItr; + +/*! + * \brief Root of all algorithms + * + * Methods of the class are grouped into several parts: + * - main lifecycle methods, like Compute() + * - methods describing features of the algorithm, like NeedShape() + * - methods related to dependencies between sub-meshes imposed by the algorith + * - static utilities, like EdgeLength() + */ class SMESH_EXPORT SMESH_Algo:public SMESH_Hypothesis { public: @@ -74,14 +86,14 @@ public: /*! * \brief Saves nothing in a stream * \param save - the stream - * \retval virtual std::ostream & - the stream + * \retval std::ostream & - the stream */ virtual std::ostream & SaveTo(std::ostream & save); /*! * \brief Loads nothing from a stream * \param load - the stream - * \retval virtual std::ostream & - the stream + * \retval std::ostream & - the stream */ virtual std::istream & LoadFrom(std::istream & load); @@ -106,9 +118,9 @@ public: * \param aShape - the shape * \retval bool - is a success * - * Algorithms that !NeedDescretBoundary() || !OnlyUnaryInput() are + * Algorithms that !NeedDiscreteBoundary() || !OnlyUnaryInput() are * to set SMESH_ComputeError returned by SMESH_submesh::GetComputeError() - * to report problematic subshapes + * to report problematic sub-shapes */ virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) = 0; @@ -122,6 +134,22 @@ public: */ virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper); + /*! + * \brief Sets _computeCanceled to true. It's usage depends on + * implementation of a particular mesher. + */ + virtual void CancelCompute(); + + /*! + * \brief evaluates size of prospective mesh on a shape + * \param aMesh - the mesh + * \param aShape - the shape + * \param aNbElems - prospective number of elements by types + * \retval bool - is a success + */ + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap) = 0; + /*! * \brief Returns a list of compatible hypotheses used to mesh a shape * \param aMesh - the mesh @@ -193,14 +221,14 @@ public: // an input temporary shape that is neither MainShape nor // its child. - bool NeedDescretBoundary() const { return _requireDescretBoundary; } + bool NeedDiscreteBoundary() const { return _requireDiscreteBoundary; } // 3 - is a Dim-1 mesh prerequisite bool NeedShape() const { return _requireShape; } // 4 - is shape existance required bool SupportSubmeshes() const { return _supportSubmeshes; } - // 5 - whether supports submeshes if !NeedDescretBoundary() + // 5 - whether supports submeshes if !NeedDiscreteBoundary() public: @@ -214,7 +242,7 @@ public: * * This method is called when a submesh gets HYP_OK algo_state. * After being set, event listener is notified on each event of a submesh. - * By default non listener is set + * By default none listener is set */ virtual void SetEventListener(SMESH_subMesh* subMesh); @@ -268,13 +296,18 @@ public: */ static double EdgeLength(const TopoDS_Edge & E); + /*! + * \brief Calculate normal of a mesh face + */ + static bool FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool normalized=true); + /*! * \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); + static GeomAbs_Shape Continuity(TopoDS_Edge E1, TopoDS_Edge E2); /*! * \brief Return true if an edge can be considered as a continuation of another @@ -289,10 +322,22 @@ public: * \param meshDS - mesh * \retval const SMDS_MeshNode* - found node or NULL */ - static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, - SMESHDS_Mesh* meshDS); + static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, const SMESHDS_Mesh* meshDS); -protected: + /*! + * \brief Return nodes common to two elements + */ + static std::vector< const SMDS_MeshNode*> GetCommonNodes(const SMDS_MeshElement* e1, + const SMDS_MeshElement* e2); + + enum EMeshError { MEr_OK = 0, MEr_HOLES, MEr_BAD_ORI, MEr_EMPTY }; + + /*! + * \brief Finds topological errors of a sub-mesh + */ + static EMeshError GetMeshError(SMESH_subMesh* subMesh); + + protected: /*! * \brief store error and comment and then return ( error == COMPERR_OK ) @@ -322,11 +367,11 @@ protected: // Algo features influencing which Compute() and how is called: // in what turn and with what input shape. - // This fields must be redefined if necessary by each descendant at constructor. + // These fields must be redefined if necessary by each descendant at constructor. bool _onlyUnaryInput; // mesh one shape of GetDim() at once. Default TRUE - bool _requireDescretBoundary; // GetDim()-1 mesh must be present. Default TRUE + bool _requireDiscreteBoundary; // GetDim()-1 mesh must be present. Default TRUE bool _requireShape; // work with GetDim()-1 mesh bound to geom only. Default TRUE - bool _supportSubmeshes; // if !_requireDescretBoundary. Default FALSE + bool _supportSubmeshes; // if !_requireDiscreteBoundary. Default FALSE // quadratic mesh creation required, // is usually set trough SMESH_MesherHelper::IsQuadraticSubMesh() @@ -335,6 +380,8 @@ protected: int _error; //!< SMESH_ComputeErrorName or anything algo specific std::string _comment; //!< any text explaining what is wrong in Compute() std::list _badInputElements; //!< to explain COMPERR_BAD_INPUT_MESH + + volatile bool _computeCanceled; //!< is set to True while computing to stop it }; #endif diff --git a/src/SMESH/SMESH_Block.cxx b/src/SMESH/SMESH_Block.cxx deleted file mode 100644 index 0fd49966a..000000000 --- a/src/SMESH/SMESH_Block.cxx +++ /dev/null @@ -1,1710 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SMESH_Pattern.hxx -// Created : Mon Aug 2 10:30:00 2004 -// Author : Edward AGAPOV (eap) -// -#include "SMESH_Block.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "SMDS_MeshNode.hxx" -#include "SMDS_MeshVolume.hxx" -#include "SMDS_VolumeTool.hxx" -#include "utilities.h" - -#include - -using namespace std; - -//#define DEBUG_PARAM_COMPUTE - -//================================================================================ -/*! - * \brief Set edge data - * \param edgeID - block subshape ID - * \param curve - edge geometry - * \param isForward - is curve orientation coincides with edge orientation in the block - */ -//================================================================================ - -void SMESH_Block::TEdge::Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward ) -{ - myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID ); - if ( myC3d ) delete myC3d; - myC3d = curve; - myFirst = curve->FirstParameter(); - myLast = curve->LastParameter(); - if ( !isForward ) - std::swap( myFirst, myLast ); -} - -//================================================================================ -/*! - * \brief Set coordinates of nodes at edge ends to work with mesh block - * \param edgeID - block subshape ID - * \param node1 - coordinates of node with lower ID - * \param node2 - coordinates of node with upper ID - */ -//================================================================================ - -void SMESH_Block::TEdge::Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 ) -{ - myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID ); - myNodes[ 0 ] = node1; - myNodes[ 1 ] = node2; - - if ( myC3d ) delete myC3d; - myC3d = 0; -} - -//======================================================================= -//function : SMESH_Block::TEdge::GetU -//purpose : -//======================================================================= - -double SMESH_Block::TEdge::GetU( const gp_XYZ& theParams ) const -{ - double u = theParams.Coord( myCoordInd ); - if ( !myC3d ) // if mesh block - return u; - return ( 1 - u ) * myFirst + u * myLast; -} - -//======================================================================= -//function : SMESH_Block::TEdge::Point -//purpose : -//======================================================================= - -gp_XYZ SMESH_Block::TEdge::Point( const gp_XYZ& theParams ) const -{ - double u = GetU( theParams ); - if ( myC3d ) return myC3d->Value( u ).XYZ(); - // mesh block - return myNodes[0] * ( 1 - u ) + myNodes[1] * u; -} - -//================================================================================ -/*! - * \brief Destructor - */ -//================================================================================ - -SMESH_Block::TEdge::~TEdge() -{ - if ( myC3d ) delete myC3d; -} - -//================================================================================ -/*! - * \brief Set face data - * \param faceID - block subshape ID - * \param S - face surface geometry - * \param c2d - 4 pcurves in the order as returned by GetFaceEdgesIDs(faceID) - * \param isForward - orientation of pcurves comparing with block edge direction - */ -//================================================================================ - -void SMESH_Block::TFace::Set( const int faceID, - Adaptor3d_Surface* S, - Adaptor2d_Curve2d* c2D[4], - const bool isForward[4] ) -{ - if ( myS ) delete myS; - myS = S; - // pcurves - vector< int > edgeIdVec; - GetFaceEdgesIDs( faceID, edgeIdVec ); - for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges - { - myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] ); - if ( myC2d[ iE ]) delete myC2d[ iE ]; - myC2d[ iE ] = c2D[ iE ]; - myFirst[ iE ] = myC2d[ iE ]->FirstParameter(); - myLast [ iE ] = myC2d[ iE ]->LastParameter(); - if ( !isForward[ iE ]) - std::swap( myFirst[ iE ], myLast[ iE ] ); - } - // 2d corners - myCorner[ 0 ] = myC2d[ 0 ]->Value( myFirst[0] ).XY(); - myCorner[ 1 ] = myC2d[ 0 ]->Value( myLast[0] ).XY(); - myCorner[ 2 ] = myC2d[ 1 ]->Value( myLast[1] ).XY(); - myCorner[ 3 ] = myC2d[ 1 ]->Value( myFirst[1] ).XY(); -} - -//================================================================================ -/*! - * \brief Set face data to work with mesh block - * \param faceID - block subshape ID - * \param edgeU0 - filled data of edge u0 = GetFaceEdgesIDs(faceID)[ 0 ] - * \param edgeU1 - filled data of edge u1 = GetFaceEdgesIDs(faceID)[ 1 ] - */ -//================================================================================ - -void SMESH_Block::TFace::Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 ) -{ - vector< int > edgeIdVec; - GetFaceEdgesIDs( faceID, edgeIdVec ); - myNodes[ 0 ] = edgeU0.NodeXYZ( 1 ); - myNodes[ 1 ] = edgeU0.NodeXYZ( 0 ); - myNodes[ 2 ] = edgeU1.NodeXYZ( 0 ); - myNodes[ 3 ] = edgeU1.NodeXYZ( 1 ); - myCoordInd[ 0 ] = GetCoordIndOnEdge( edgeIdVec[ 0 ] ); - myCoordInd[ 1 ] = GetCoordIndOnEdge( edgeIdVec[ 1 ] ); - myCoordInd[ 2 ] = GetCoordIndOnEdge( edgeIdVec[ 2 ] ); - myCoordInd[ 3 ] = GetCoordIndOnEdge( edgeIdVec[ 3 ] ); - if ( myS ) delete myS; - myS = 0; -} - -//================================================================================ -/*! - * \brief Destructor - */ -//================================================================================ - -SMESH_Block::TFace::~TFace() -{ - if ( myS ) delete myS; - for ( int i = 0 ; i < 4; ++i ) - if ( myC2d[ i ]) delete myC2d[ i ]; -} - -//======================================================================= -//function : SMESH_Block::TFace::GetCoefs -//purpose : return coefficients for addition of [0-3]-th edge and vertex -//======================================================================= - -void SMESH_Block::TFace::GetCoefs(int iE, - const gp_XYZ& theParams, - double& Ecoef, - double& Vcoef ) const -{ - double dU = theParams.Coord( GetUInd() ); - double dV = theParams.Coord( GetVInd() ); - switch ( iE ) { - case 0: - Ecoef = ( 1 - dV ); // u0 - Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00 - case 1: - Ecoef = dV; // u1 - Vcoef = dU * ( 1 - dV ); break; // 10 - case 2: - Ecoef = ( 1 - dU ); // 0v - Vcoef = dU * dV ; break; // 11 - case 3: - Ecoef = dU ; // 1v - Vcoef = ( 1 - dU ) * dV ; break; // 01 - default: ASSERT(0); - } -} - -//======================================================================= -//function : SMESH_Block::TFace::GetUV -//purpose : -//======================================================================= - -gp_XY SMESH_Block::TFace::GetUV( const gp_XYZ& theParams ) const -{ - gp_XY uv(0.,0.); - for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges - { - double Ecoef = 0, Vcoef = 0; - GetCoefs( iE, theParams, Ecoef, Vcoef ); - // edge addition - double u = theParams.Coord( myCoordInd[ iE ] ); - u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ]; - uv += Ecoef * myC2d[ iE ]->Value( u ).XY(); - // corner addition - uv -= Vcoef * myCorner[ iE ]; - } - return uv; -} - -//======================================================================= -//function : SMESH_Block::TFace::Point -//purpose : -//======================================================================= - -gp_XYZ SMESH_Block::TFace::Point( const gp_XYZ& theParams ) const -{ - gp_XYZ p(0.,0.,0.); - if ( !myS ) // if mesh block - { - for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges - { - double Ecoef = 0, Vcoef = 0; - GetCoefs( iE, theParams, Ecoef, Vcoef ); - // edge addition - double u = theParams.Coord( myCoordInd[ iE ] ); - int i1 = 0, i2 = 1; - switch ( iE ) { - case 1: i1 = 3; i2 = 2; break; - case 2: i1 = 1; i2 = 2; break; - case 3: i1 = 0; i2 = 3; break; - } - p += Ecoef * ( myNodes[ i1 ] * ( 1 - u ) + myNodes[ i2 ] * u ); - // corner addition - p -= Vcoef * myNodes[ iE ]; - } - - } - else // shape block - { - gp_XY uv = GetUV( theParams ); - p = myS->Value( uv.X(), uv.Y() ).XYZ(); - } - return p; -} - -//======================================================================= -//function : GetShapeCoef -//purpose : -//======================================================================= - -double* SMESH_Block::GetShapeCoef (const int theShapeID) -{ - static double shapeCoef[][3] = { - // V000, V100, V010, V110 - { -1,-1,-1 }, { 1,-1,-1 }, { -1, 1,-1 }, { 1, 1,-1 }, - // V001, V101, V011, V111, - { -1,-1, 1 }, { 1,-1, 1 }, { -1, 1, 1 }, { 1, 1, 1 }, - // Ex00, Ex10, Ex01, Ex11, - { 0,-1,-1 }, { 0, 1,-1 }, { 0,-1, 1 }, { 0, 1, 1 }, - // E0y0, E1y0, E0y1, E1y1, - { -1, 0,-1 }, { 1, 0,-1 }, { -1, 0, 1 }, { 1, 0, 1 }, - // E00z, E10z, E01z, E11z, - { -1,-1, 0 }, { 1,-1, 0 }, { -1, 1, 0 }, { 1, 1, 0 }, - // Fxy0, Fxy1, Fx0z, Fx1z, F0yz, F1yz, - { 0, 0,-1 }, { 0, 0, 1 }, { 0,-1, 0 }, { 0, 1, 0 }, { -1, 0, 0 }, { 1, 0, 0 }, - // ID_Shell - { 0, 0, 0 } - }; - if ( theShapeID < ID_V000 || theShapeID > ID_F1yz ) - return shapeCoef[ ID_Shell - 1 ]; - - return shapeCoef[ theShapeID - 1 ]; -} - -//======================================================================= -//function : ShellPoint -//purpose : return coordinates of a point in shell -//======================================================================= - -bool SMESH_Block::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const -{ - thePoint.SetCoord( 0., 0., 0. ); - for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ ) - { - // coef - double* coefs = GetShapeCoef( shapeID ); - double k = 1; - for ( int iCoef = 0; iCoef < 3; iCoef++ ) { - if ( coefs[ iCoef ] != 0 ) { - if ( coefs[ iCoef ] < 0 ) - k *= ( 1. - theParams.Coord( iCoef + 1 )); - else - k *= theParams.Coord( iCoef + 1 ); - } - } - // add point on a shape - if ( fabs( k ) > DBL_MIN ) - { - gp_XYZ Ps; - if ( shapeID < ID_Ex00 ) // vertex - VertexPoint( shapeID, Ps ); - else if ( shapeID < ID_Fxy0 ) { // edge - EdgePoint( shapeID, theParams, Ps ); - k = -k; - } else // face - FacePoint( shapeID, theParams, Ps ); - - thePoint += k * Ps; - } - } - return true; -} - -//======================================================================= -//function : ShellPoint -//purpose : computes coordinates of a point in shell by points on sub-shapes; -// thePointOnShape[ subShapeID ] must be a point on a subShape -//======================================================================= - -bool SMESH_Block::ShellPoint(const gp_XYZ& theParams, - const vector& thePointOnShape, - gp_XYZ& thePoint ) -{ - if ( thePointOnShape.size() < ID_F1yz ) - return false; - - double x = theParams.X(), y = theParams.Y(), z = theParams.Z(); - double x1 = 1. - x, y1 = 1. - y, z1 = 1. - z; - const vector& p = thePointOnShape; - - thePoint = - x1 * p[ID_F0yz] + x * p[ID_F1yz] + - y1 * p[ID_Fx0z] + y * p[ID_Fx1z] + - z1 * p[ID_Fxy0] + z * p[ID_Fxy1] + - x1 * (y1 * (z1 * p[ID_V000] + z * p[ID_V001]) + - y * (z1 * p[ID_V010] + z * p[ID_V011])) + - x * (y1 * (z1 * p[ID_V100] + z * p[ID_V101]) + - y * (z1 * p[ID_V110] + z * p[ID_V111])); - thePoint -= - x1 * (y1 * p[ID_E00z] + y * p[ID_E01z]) + - x * (y1 * p[ID_E10z] + y * p[ID_E11z]) + - y1 * (z1 * p[ID_Ex00] + z * p[ID_Ex01]) + - y * (z1 * p[ID_Ex10] + z * p[ID_Ex11]) + - z1 * (x1 * p[ID_E0y0] + x * p[ID_E1y0]) + - z * (x1 * p[ID_E0y1] + x * p[ID_E1y1]); - - return true; -} - -//======================================================================= -//function : Constructor -//purpose : -//======================================================================= - -SMESH_Block::SMESH_Block(): - myNbIterations(0), - mySumDist(0.), - myTolerance(-1.) // to be re-initialized -{ -} - - -//======================================================================= -//function : NbVariables -//purpose : -//======================================================================= - -Standard_Integer SMESH_Block::NbVariables() const -{ - return 3; -} - -//======================================================================= -//function : NbEquations -//purpose : -//======================================================================= - -Standard_Integer SMESH_Block::NbEquations() const -{ - return 1; -} - -//======================================================================= -//function : Value -//purpose : -//======================================================================= - -Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theFxyz) -{ - gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) ); - if ( params.IsEqual( myParam, DBL_MIN )) { // same param - theFxyz( 1 ) = funcValue( myValues[ SQUARE_DIST ]); - } - else { - ShellPoint( params, P ); - gp_Vec dP( P - myPoint ); - theFxyz(1) = funcValue( dP.SquareMagnitude() ); - } - return true; -} - -//======================================================================= -//function : Derivatives -//purpose : -//======================================================================= - -Standard_Boolean SMESH_Block::Derivatives(const math_Vector& XYZ,math_Matrix& Df) -{ - math_Vector F(1,3); - return Values(XYZ,F,Df); -} - -//======================================================================= -//function : GetStateNumber -//purpose : -//======================================================================= - -Standard_Integer SMESH_Block::GetStateNumber () -{ - return 0; //myValues[0] < 1e-1; -} - -//======================================================================= -//function : Values -//purpose : -//======================================================================= - -Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ, - math_Vector& theFxyz, - math_Matrix& theDf) -{ - gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) ); - if ( params.IsEqual( myParam, DBL_MIN )) { // same param - theFxyz( 1 ) = funcValue( myValues[ SQUARE_DIST ] ); - theDf( 1, DRV_1 ) = myValues[ DRV_1 ]; - theDf( 1, DRV_2 ) = myValues[ DRV_2 ]; - theDf( 1, DRV_3 ) = myValues[ DRV_3 ]; - return true; - } -#ifdef DEBUG_PARAM_COMPUTE - MESSAGE ( "PARAM GUESS: " << params.X() << " "<< params.Y() << " "<< params.X() ); - myNbIterations++; // how many times call ShellPoint() -#endif - ShellPoint( params, P ); - - gp_Vec dP( myPoint, P ); - double sqDist = dP.SquareMagnitude(); - theFxyz(1) = funcValue( sqDist ); - - if ( sqDist < myTolerance * myTolerance ) { // a solution found - myParam = params; - myValues[ SQUARE_DIST ] = sqDist; - theFxyz(1) = theDf( 1,1 ) = theDf( 1,2 ) = theDf( 1,3 ) = 0; - return true; - } - - if ( sqDist < myValues[ SQUARE_DIST ] ) // a better guess - { - // 3 partial derivatives - gp_Vec drv[ 3 ]; // where we move with a small step in each direction - for ( int iP = 1; iP <= 3; iP++ ) { - if ( iP == myFaceIndex ) { - drv[ iP - 1 ] = gp_Vec(0,0,0); - continue; - } - gp_XYZ Pi; - bool onEdge = ( theXYZ( iP ) + 0.001 > 1. ); - if ( onEdge ) - params.SetCoord( iP, theXYZ( iP ) - 0.001 ); - else - params.SetCoord( iP, theXYZ( iP ) + 0.001 ); - ShellPoint( params, Pi ); - params.SetCoord( iP, theXYZ( iP ) ); // restore params - gp_Vec dPi ( P, Pi ); - if ( onEdge ) dPi *= -1.; - double mag = dPi.Magnitude(); - if ( mag > DBL_MIN ) - dPi /= mag; - drv[ iP - 1 ] = dPi; - } - for ( int iP = 0; iP < 3; iP++ ) { -#if 1 - theDf( 1, iP + 1 ) = dP * drv[iP]; -#else - // Distance from P to plane passing through myPoint and defined - // by the 2 other derivative directions: - // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P) - // where L is (P -> myPoint), P is defined by the 2 other derivative direction - int iPrev = ( iP ? iP - 1 : 2 ); - int iNext = ( iP == 2 ? 0 : iP + 1 ); - gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] ); - double Direc = plnNorm * drv[ iP ]; - if ( Abs(Direc) <= DBL_MIN ) - theDf( 1, iP + 1 ) = dP * drv[ iP ]; - else { - double Dis = plnNorm * P - plnNorm * myPoint; - theDf( 1, iP + 1 ) = Dis/Direc; - } -#endif - } -#ifdef DEBUG_PARAM_COMPUTE - MESSAGE ( "F = " << theFxyz(1) << " DRV: " << theDf(1,1) << " " << theDf(1,2) << " " << theDf(1,3) ); - myNbIterations +=3; // how many times call ShellPoint() -#endif - - // store better values - myParam = params; - myValues[SQUARE_DIST]= sqDist; - myValues[DRV_1] = theDf(1,DRV_1); - myValues[DRV_2] = theDf(1,DRV_2); - myValues[DRV_3] = theDf(1,DRV_3); - } - - return true; -} - -//============================================================================ -//function : computeParameters -//purpose : compute point parameters in the block using math_FunctionSetRoot -//============================================================================ - -bool SMESH_Block::computeParameters(const gp_Pnt& thePoint, - gp_XYZ& theParams, - const gp_XYZ& theParamsHint) -{ - myPoint = thePoint.XYZ(); - - myParam.SetCoord( -1,-1,-1 ); - myValues[ SQUARE_DIST ] = 1e100; - - math_Vector low ( 1, 3, 0.0 ); - math_Vector up ( 1, 3, 1.0 ); - math_Vector tol ( 1, 3, 1e-4 ); - math_Vector start( 1, 3, 0.0 ); - start( 1 ) = theParamsHint.X(); - start( 2 ) = theParamsHint.Y(); - start( 3 ) = theParamsHint.Z(); - - math_FunctionSetRoot paramSearch( *this, tol ); - - mySquareFunc = 0; // large approaching steps - //if ( hasHint ) mySquareFunc = 1; // small approaching steps - - double loopTol = 10 * myTolerance; - int nbLoops = 0; - while ( distance() > loopTol && nbLoops <= 3 ) - { - paramSearch.Perform ( *static_cast(this), - start, low, up ); - start( 1 ) = myParam.X(); - start( 2 ) = myParam.Y(); - start( 3 ) = myParam.Z(); - mySquareFunc = !mySquareFunc; - nbLoops++; - } -#ifdef DEBUG_PARAM_COMPUTE - mySumDist += distance(); - MESSAGE ( " ------ SOLUTION: ( "<< myParam.X() <<" "<< myParam.Y() <<" "<< myParam.Z() <<" )"< 0 ) - theParams.SetCoord( myFaceIndex, myFaceParam ); - - return true; -} - -//======================================================================= -//function : ComputeParameters -//purpose : compute point parameters in the block -//======================================================================= - -bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint, - gp_XYZ& theParams, - const int theShapeID, - const gp_XYZ& theParamsHint) -{ - if ( VertexParameters( theShapeID, theParams )) - return true; - - if ( IsEdgeID( theShapeID )) { - TEdge& e = myEdge[ theShapeID - ID_FirstE ]; - Adaptor3d_Curve* curve = e.GetCurve(); - Extrema_ExtPC anExtPC( thePoint, *curve, curve->FirstParameter(), curve->LastParameter() ); - int i, nb = anExtPC.IsDone() ? anExtPC.NbExt() : 0; - for ( i = 1; i <= nb; i++ ) { - if ( anExtPC.IsMin( i )) - return EdgeParameters( theShapeID, anExtPC.Point( i ).Parameter(), theParams ); - } - return false; - } - - const bool isOnFace = IsFaceID( theShapeID ); - double * coef = GetShapeCoef( theShapeID ); - - // Find the first guess paremeters - - gp_XYZ start(0, 0, 0); - - bool hasHint = ( 0 <= theParamsHint.X() && theParamsHint.X() <= 1 && - 0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 && - 0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 ); - if ( !hasHint && !myGridComputed ) - { - // define the first guess by thePoint projection on lines - // connecting vertices - bool needGrid = false; - gp_XYZ par000( 0, 0, 0 ), par111( 1, 1, 1 ); - double zero = DBL_MIN * DBL_MIN; - for ( int iEdge = 0, iParam = 1; iParam <= 3 && !needGrid; iParam++ ) - { - if ( isOnFace && coef[ iParam - 1 ] != 0 ) { - iEdge += 4; - continue; - } - double sumParam = 0; - for ( int iE = 0; iE < 4; iE++, iEdge++ ) { // loop on 4 parallel edges - gp_Pnt p0 = myEdge[ iEdge ].Point( par000 ); - gp_Pnt p1 = myEdge[ iEdge ].Point( par111 ); - gp_Vec v01( p0, p1 ), v0P( p0, thePoint ); - double len2 = v01.SquareMagnitude(); - double par = 0; - if ( len2 > zero ) { - par = v0P.Dot( v01 ) / len2; - if ( par < 0 || par > 1 ) { // projection falls out of line ends => needGrid - needGrid = true; - break; - } - } - sumParam += par; - } - start.SetCoord( iParam, sumParam / 4.); - } - if ( needGrid ) { - // compute nodes of 3 x 3 x 3 grid - int iNode = 0; - Bnd_Box box; - for ( double x = 0.25; x < 0.9; x += 0.25 ) - for ( double y = 0.25; y < 0.9; y += 0.25 ) - for ( double z = 0.25; z < 0.9; z += 0.25 ) { - TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ]; - prmPtn.first.SetCoord( x, y, z ); - ShellPoint( prmPtn.first, prmPtn.second ); - box.Add( gp_Pnt( prmPtn.second )); - } - myGridComputed = true; - myTolerance = sqrt( box.SquareExtent() ) * 1e-5; - } - } - - if ( hasHint ) - { - start = theParamsHint; - } - else if ( myGridComputed ) - { - double minDist = DBL_MAX; - gp_XYZ* bestParam = 0; - for ( int iNode = 0; iNode < 27; iNode++ ) { - TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ]; - double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus(); - if ( dist < minDist ) { - minDist = dist; - bestParam = & prmPtn.first; - } - } - start = *bestParam; - } - - myFaceIndex = -1; - myFaceParam = 0.; - if ( isOnFace ) { - // put a point on the face - for ( int iCoord = 0; iCoord < 3; iCoord++ ) - if ( coef[ iCoord ] ) { - myFaceIndex = iCoord + 1; - myFaceParam = ( coef[ iCoord ] < 0.5 ) ? 0.0 : 1.0; - start.SetCoord( myFaceIndex, myFaceParam ); - } - } - -#ifdef DEBUG_PARAM_COMPUTE - MESSAGE ( " #### POINT " < sqDistance ) { // solution get worse - if ( ++nbGetWorst > 2 ) - return computeParameters( thePoint, theParams, solution ); - } -#ifdef DEBUG_PARAM_COMPUTE - MESSAGE ( "PARAMS: ( " << params.X() <<" "<< params.Y() <<" "<< params.Z() <<" )" ); - MESSAGE ( "DIST: " << sqrt( sqDist ) ); -#endif - - if ( sqDist < sqDistance ) { // get better - sqDistance = sqDist; - solution = params; - nbGetWorst = 0; - if ( sqDistance < sqTolerance ) // a solution found - break; - } - - // look for a next better solution - for ( int iP = 1; iP <= 3; iP++ ) { - if ( iP == myFaceIndex ) - continue; - // see where we move with a small (=parDelta) step in this direction - gp_XYZ nearParams = params; - bool onEdge = ( params.Coord( iP ) + parDelta > 1. ); - if ( onEdge ) - nearParams.SetCoord( iP, params.Coord( iP ) - parDelta ); - else - nearParams.SetCoord( iP, params.Coord( iP ) + parDelta ); - ShellPoint( nearParams, Pi ); - gp_Vec dPi ( P, Pi ); - if ( onEdge ) dPi *= -1.; - // modify a parameter - double mag = dPi.Magnitude(); - if ( mag < DBL_MIN ) - continue; - gp_Vec dir = dPi / mag; // dir we move modifying the parameter - double dist = dir * dP; // where we should get to - double dPar = dist / mag * parDelta; // predict parameter change - double curPar = params.Coord( iP ); - double par = curPar - dPar; // new parameter value - while ( par > 1 || par < 0 ) { - dPar /= 2.; - par = curPar - dPar; - } - params.SetCoord( iP, par ); - } - - nbLoops++; - } -#ifdef DEBUG_PARAM_COMPUTE - myNbIterations += nbLoops*4; // how many times ShellPoint called - mySumDist += sqrt( sqDistance ); - MESSAGE ( " ------ SOLUTION: ( "< 0 ) - theParams.SetCoord( myFaceIndex, myFaceParam ); - - return true; -} - -//======================================================================= -//function : VertexParameters -//purpose : return parameters of a vertex given by TShapeID -//======================================================================= - -bool SMESH_Block::VertexParameters(const int theVertexID, gp_XYZ& theParams) -{ - switch ( theVertexID ) { - case ID_V000: theParams.SetCoord(0., 0., 0.); return true; - case ID_V100: theParams.SetCoord(1., 0., 0.); return true; - case ID_V110: theParams.SetCoord(1., 1., 0.); return true; - case ID_V010: theParams.SetCoord(0., 1., 0.); return true; - default:; - } - return false; -} - -//======================================================================= -//function : EdgeParameters -//purpose : return parameters of a point given by theU on edge -//======================================================================= - -bool SMESH_Block::EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams) -{ - if ( IsEdgeID( theEdgeID )) { - vector< int > vertexVec; - GetEdgeVertexIDs( theEdgeID, vertexVec ); - VertexParameters( vertexVec[0], theParams ); - TEdge& e = myEdge[ theEdgeID - ID_Ex00 ]; - double param = ( theU - e.EndParam(0) ) / ( e.EndParam(1) - e.EndParam(0) ); - theParams.SetCoord( e.CoordInd(), param ); - return true; - } - return false; -} - -//======================================================================= -//function : DumpShapeID -//purpose : debug an id of a block sub-shape -//======================================================================= - -#define CASEDUMP(id,strm) case id: strm << #id; break; - -ostream& SMESH_Block::DumpShapeID (const int id, ostream& stream) -{ - switch ( id ) { - CASEDUMP( ID_V000, stream ); - CASEDUMP( ID_V100, stream ); - CASEDUMP( ID_V010, stream ); - CASEDUMP( ID_V110, stream ); - CASEDUMP( ID_V001, stream ); - CASEDUMP( ID_V101, stream ); - CASEDUMP( ID_V011, stream ); - CASEDUMP( ID_V111, stream ); - CASEDUMP( ID_Ex00, stream ); - CASEDUMP( ID_Ex10, stream ); - CASEDUMP( ID_Ex01, stream ); - CASEDUMP( ID_Ex11, stream ); - CASEDUMP( ID_E0y0, stream ); - CASEDUMP( ID_E1y0, stream ); - CASEDUMP( ID_E0y1, stream ); - CASEDUMP( ID_E1y1, stream ); - CASEDUMP( ID_E00z, stream ); - CASEDUMP( ID_E10z, stream ); - CASEDUMP( ID_E01z, stream ); - CASEDUMP( ID_E11z, stream ); - CASEDUMP( ID_Fxy0, stream ); - CASEDUMP( ID_Fxy1, stream ); - CASEDUMP( ID_Fx0z, stream ); - CASEDUMP( ID_Fx1z, stream ); - CASEDUMP( ID_F0yz, stream ); - CASEDUMP( ID_F1yz, stream ); - CASEDUMP( ID_Shell, stream ); - default: stream << "ID_INVALID"; - } - return stream; -} - -//======================================================================= -//function : GetShapeIDByParams -//purpose : define an id of the block sub-shape by normlized point coord -//======================================================================= - -int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord ) -{ - // id ( 0 - 26 ) computation: - - // vertex ( 0 - 7 ) : id = 1*x + 2*y + 4*z - - // edge || X ( 8 - 11 ) : id = 8 + 1*y + 2*z - // edge || Y ( 12 - 15 ): id = 1*x + 12 + 2*z - // edge || Z ( 16 - 19 ): id = 1*x + 2*y + 16 - - // face || XY ( 20 - 21 ): id = 8 + 12 + 1*z - 0 - // face || XZ ( 22 - 23 ): id = 8 + 1*y + 16 - 2 - // face || YZ ( 24 - 25 ): id = 1*x + 12 + 16 - 4 - - static int iAddBnd[] = { 1, 2, 4 }; - static int iAddNotBnd[] = { 8, 12, 16 }; - static int iFaceSubst[] = { 0, 2, 4 }; - - int id = 0; - int iOnBoundary = 0; - for ( int iCoord = 0; iCoord < 3; iCoord++ ) - { - double val = theCoord.Coord( iCoord + 1 ); - if ( val == 0.0 ) - iOnBoundary++; - else if ( val == 1.0 ) - id += iAddBnd[ iOnBoundary++ ]; - else - id += iAddNotBnd[ iCoord ]; - } - if ( iOnBoundary == 1 ) // face - id -= iFaceSubst[ (id - 20) / 4 ]; - else if ( iOnBoundary == 0 ) // shell - id = 26; - - if ( id > 26 || id < 0 ) { - MESSAGE( "GetShapeIDByParams() = " << id - <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() ); - } - - return id + 1; // shape ids start at 1 -} - -//======================================================================= -//function : GetOrderedEdges -//purpose : return nb wires and a list of oredered edges -//======================================================================= - -int SMESH_Block::GetOrderedEdges (const TopoDS_Face& theFace, - TopoDS_Vertex theFirstVertex, - list< TopoDS_Edge >& theEdges, - list< int > & theNbVertexInWires) -{ - // put wires in a list, so that an outer wire comes first - list aWireList; - TopoDS_Wire anOuterWire = BRepTools::OuterWire( theFace ); - aWireList.push_back( anOuterWire ); - for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() ) - if ( !anOuterWire.IsSame( wIt.Value() )) - aWireList.push_back( TopoDS::Wire( wIt.Value() )); - - // loop on edges of wires - theNbVertexInWires.clear(); - list::iterator wlIt = aWireList.begin(); - for ( ; wlIt != aWireList.end(); wlIt++ ) - { - int iE; - BRepTools_WireExplorer wExp( *wlIt, theFace ); - for ( iE = 0; wExp.More(); wExp.Next(), iE++ ) - { - TopoDS_Edge edge = wExp.Current(); - edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() )); - theEdges.push_back( edge ); - } - theNbVertexInWires.push_back( iE ); - iE = 0; - if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire - // orient closed edges - list< TopoDS_Edge >::iterator eIt, eIt2; - for ( eIt = theEdges.begin(); eIt != theEdges.end(); eIt++ ) - { - TopoDS_Edge& edge = *eIt; - if ( TopExp::FirstVertex( edge ).IsSame( TopExp::LastVertex( edge ) )) - { - eIt2 = eIt; - bool isNext = ( eIt2 == theEdges.begin() ); - TopoDS_Edge edge2 = isNext ? *(++eIt2) : *(--eIt2); - double f1,l1,f2,l2; - Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( edge, theFace, f1,l1 ); - Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( edge2, theFace, f2,l2 ); - gp_Pnt2d pf = c1->Value( edge.Orientation() == TopAbs_FORWARD ? f1 : l1 ); - gp_Pnt2d pl = c1->Value( edge.Orientation() == TopAbs_FORWARD ? l1 : f1 ); - bool isFirst = ( edge2.Orientation() == TopAbs_FORWARD ? isNext : !isNext ); - gp_Pnt2d p2 = c2->Value( isFirst ? f2 : l2 ); - isFirst = ( p2.SquareDistance( pf ) < p2.SquareDistance( pl )); - if ( isNext ? isFirst : !isFirst ) - edge.Reverse(); - // to make a seam go first - if ( theFirstVertex.IsNull() ) - theFirstVertex = TopExp::FirstVertex( edge, true ); - } - } - // rotate theEdges until it begins from theFirstVertex - if ( ! theFirstVertex.IsNull() ) { - TopoDS_Vertex vv[2]; - TopExp::Vertices( theEdges.front(), vv[0], vv[1], true ); - // on closed face, make seam edge the first in the list - while ( !vv[0].IsSame( theFirstVertex ) || vv[0].IsSame( vv[1] )) - { - theEdges.splice(theEdges.end(), theEdges, - theEdges.begin(), ++theEdges.begin()); - TopExp::Vertices( theEdges.front(), vv[0], vv[1], true ); - if ( iE++ > theNbVertexInWires.back() ) { -#ifdef _DEBUG_ - gp_Pnt p = BRep_Tool::Pnt( theFirstVertex ); - MESSAGE ( " : Warning : vertex "<< theFirstVertex.TShape().operator->() - << " ( " << p.X() << " " << p.Y() << " " << p.Z() << " )" - << " not found in outer wire of face "<< theFace.TShape().operator->() - << " with vertices: " ); - wExp.Init( *wlIt, theFace ); - for ( int i = 0; wExp.More(); wExp.Next(), i++ ) - { - TopoDS_Edge edge = wExp.Current(); - edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() )); - TopoDS_Vertex v = TopExp::FirstVertex( edge, true ); - gp_Pnt p = BRep_Tool::Pnt( v ); - MESSAGE_ADD ( i << " " << v.TShape().operator->() << " " - << p.X() << " " << p.Y() << " " << p.Z() << " " << std::endl ); - } -#endif - break; // break infinite loop - } - } - } - } // end outer wire - } - - return aWireList.size(); -} -//================================================================================ -/*! - * \brief Call it after geometry initialisation - */ -//================================================================================ - -void SMESH_Block::init() -{ - myNbIterations = 0; - mySumDist = 0; - myGridComputed = false; -} - -//======================================================================= -//function : LoadMeshBlock -//purpose : prepare to work with theVolume -//======================================================================= - -#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z()) - -bool SMESH_Block::LoadMeshBlock(const SMDS_MeshVolume* theVolume, - const int theNode000Index, - const int theNode001Index, - vector& theOrderedNodes) -{ - MESSAGE(" ::LoadMeshBlock()"); - init(); - - SMDS_VolumeTool vTool; - if (!vTool.Set( theVolume ) || vTool.NbNodes() != 8 || - !vTool.IsLinked( theNode000Index, theNode001Index )) { - MESSAGE(" Bad arguments "); - return false; - } - vTool.SetExternalNormal(); - // In terms of indices used for access to nodes and faces in SMDS_VolumeTool: - int V000, V100, V010, V110, V001, V101, V011, V111; // 8 vertices - int Fxy0, Fxy1; // bottom and top faces - // vertices of faces - vector vFxy0, vFxy1; - - V000 = theNode000Index; - V001 = theNode001Index; - - // get faces sharing V000 and V001 - list fV000, fV001; - int i, iF, iE, iN; - for ( iF = 0; iF < vTool.NbFaces(); ++iF ) { - const int* nid = vTool.GetFaceNodesIndices( iF ); - for ( iN = 0; iN < 4; ++iN ) - if ( nid[ iN ] == V000 ) { - fV000.push_back( iF ); - } else if ( nid[ iN ] == V001 ) { - fV001.push_back( iF ); - } - } - - // find the bottom (Fxy0), the top (Fxy1) faces - list::iterator fIt1, fIt2, Fxy0Pos; - for ( fIt1 = fV000.begin(); fIt1 != fV000.end(); fIt1++) { - fIt2 = std::find( fV001.begin(), fV001.end(), *fIt1 ); - if ( fIt2 != fV001.end() ) { // *fIt1 is in the both lists - fV001.erase( fIt2 ); // erase Fx0z or F0yz from fV001 - } else { // *fIt1 is in fV000 only - Fxy0Pos = fIt1; // points to Fxy0 - } - } - Fxy0 = *Fxy0Pos; - Fxy1 = fV001.front(); - const SMDS_MeshNode** nn = vTool.GetNodes(); - - // find bottom veritices, their order is that a face normal is external - vFxy0.resize(4); - const int* nid = vTool.GetFaceNodesIndices( Fxy0 ); - for ( i = 0; i < 4; ++i ) - if ( nid[ i ] == V000 ) - break; - for ( iN = 0; iN < 4; ++iN, ++i ) { - if ( i == 4 ) i = 0; - vFxy0[ iN ] = nid[ i ]; - } - // find top veritices, their order is that a face normal is external - vFxy1.resize(4); - nid = vTool.GetFaceNodesIndices( Fxy1 ); - for ( i = 0; i < 4; ++i ) - if ( nid[ i ] == V001 ) - break; - for ( iN = 0; iN < 4; ++iN, ++i ) { - if ( i == 4 ) i = 0; - vFxy1[ iN ] = nid[ i ]; - } - // find indices of the rest veritices - V100 = vFxy0[3]; - V010 = vFxy0[1]; - V110 = vFxy0[2]; - V101 = vFxy1[1]; - V011 = vFxy1[3]; - V111 = vFxy1[2]; - - // set points coordinates - myPnt[ ID_V000 - 1 ] = gpXYZ( nn[ V000 ] ); - myPnt[ ID_V100 - 1 ] = gpXYZ( nn[ V100 ] ); - myPnt[ ID_V010 - 1 ] = gpXYZ( nn[ V010 ] ); - myPnt[ ID_V110 - 1 ] = gpXYZ( nn[ V110 ] ); - myPnt[ ID_V001 - 1 ] = gpXYZ( nn[ V001 ] ); - myPnt[ ID_V101 - 1 ] = gpXYZ( nn[ V101 ] ); - myPnt[ ID_V011 - 1 ] = gpXYZ( nn[ V011 ] ); - myPnt[ ID_V111 - 1 ] = gpXYZ( nn[ V111 ] ); - - // fill theOrderedNodes - theOrderedNodes.resize( 8 ); - theOrderedNodes[ 0 ] = nn[ V000 ]; - theOrderedNodes[ 1 ] = nn[ V100 ]; - theOrderedNodes[ 2 ] = nn[ V010 ]; - theOrderedNodes[ 3 ] = nn[ V110 ]; - theOrderedNodes[ 4 ] = nn[ V001 ]; - theOrderedNodes[ 5 ] = nn[ V101 ]; - theOrderedNodes[ 6 ] = nn[ V011 ]; - theOrderedNodes[ 7 ] = nn[ V111 ]; - - // fill edges - vector< int > vertexVec; - for ( iE = 0; iE < NbEdges(); ++iE ) { - GetEdgeVertexIDs(( iE + ID_FirstE ), vertexVec ); - myEdge[ iE ].Set(( iE + ID_FirstE ), - myPnt[ vertexVec[0] - 1 ], - myPnt[ vertexVec[1] - 1 ]); - } - - // fill faces' corners - for ( iF = ID_Fxy0; iF < ID_Shell; ++iF ) - { - TFace& tFace = myFace[ iF - ID_FirstF ]; - vector< int > edgeIdVec(4, -1); - GetFaceEdgesIDs( iF, edgeIdVec ); - tFace.Set( iF, myEdge[ edgeIdVec [ 0 ] - ID_Ex00], myEdge[ edgeIdVec [ 1 ] - ID_Ex00]); - } - - return true; -} - -//======================================================================= -//function : LoadBlockShapes -//purpose : Initialize block geometry with theShell, -// add sub-shapes of theBlock to theShapeIDMap so that they get -// IDs acoording to enum TShapeID -//======================================================================= - -bool SMESH_Block::LoadBlockShapes(const TopoDS_Shell& theShell, - const TopoDS_Vertex& theVertex000, - const TopoDS_Vertex& theVertex001, - TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) -{ - MESSAGE(" ::LoadBlockShapes()"); - return ( FindBlockShapes( theShell, theVertex000, theVertex001, theShapeIDMap ) && - LoadBlockShapes( theShapeIDMap )); -} - -//======================================================================= -//function : LoadBlockShapes -//purpose : add sub-shapes of theBlock to theShapeIDMap so that they get -// IDs acoording to enum TShapeID -//======================================================================= - -bool SMESH_Block::FindBlockShapes(const TopoDS_Shell& theShell, - const TopoDS_Vertex& theVertex000, - const TopoDS_Vertex& theVertex001, - TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) -{ - MESSAGE(" ::FindBlockShapes()"); - - // 8 vertices - TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111; - // 12 edges - TopoDS_Shape Ex00, Ex10, Ex01, Ex11; - TopoDS_Shape E0y0, E1y0, E0y1, E1y1; - TopoDS_Shape E00z, E10z, E01z, E11z; - // 6 faces - TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz; - - // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape - // filled by TopExp::MapShapesAndAncestors() - const int NB_FACES_BY_VERTEX = 6; - - TopTools_IndexedDataMapOfShapeListOfShape vfMap; - TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_FACE, vfMap ); - if ( vfMap.Extent() != 8 ) { - MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() ); - return false; - } - - V000 = theVertex000; - V001 = theVertex001; - - if ( V000.IsNull() ) { - // find vertex 000 - the one with smallest coordinates - double minVal = DBL_MAX, minX, val; - for ( int i = 1; i <= 8; i++ ) { - const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i )); - gp_Pnt P = BRep_Tool::Pnt( v ); - val = P.X() + P.Y() + P.Z(); - if ( val < minVal || ( val == minVal && P.X() < minX )) { - V000 = v; - minVal = val; - minX = P.X(); - } - } - // find vertex 001 - the one on the most vertical edge passing through V000 - TopTools_IndexedDataMapOfShapeListOfShape veMap; - TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_EDGE, veMap ); - gp_Vec dir001 = gp::DZ(); - gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 )); - double maxVal = -DBL_MAX; - TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 )); - for ( ; eIt.More(); eIt.Next() ) { - const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() ); - TopoDS_Vertex v = TopExp::FirstVertex( e ); - if ( v.IsSame( V000 )) - v = TopExp::LastVertex( e ); - val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized(); - if ( val > maxVal ) { - V001 = v; - maxVal = val; - } - } - } - - // find the bottom (Fxy0), Fx0z and F0yz faces - - const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 ); - const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 ); - if (f000List.Extent() != NB_FACES_BY_VERTEX || - f001List.Extent() != NB_FACES_BY_VERTEX ) { - MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent()); - return false; - } - TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List ); - int i, j, iFound1, iFound2; - for ( j = 0; f000It.More(); f000It.Next(), j++ ) - { - if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice - const TopoDS_Shape& F = f000It.Value(); - for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { - if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice - if ( F.IsSame( f001It.Value() )) - break; - } - if ( f001It.More() ) // Fx0z or F0yz found - if ( Fx0z.IsNull() ) { - Fx0z = F; - iFound1 = i; - } else { - F0yz = F; - iFound2 = i; - } - else // F is the bottom face - Fxy0 = F; - } - if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) { - MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() ); - return false; - } - - // choose the top face (Fxy1) - for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { - if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice - if ( i != iFound1 && i != iFound2 ) - break; - } - Fxy1 = f001It.Value(); - if ( Fxy1.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - - // find bottom edges and veritices - list< TopoDS_Edge > eList; - list< int > nbVertexInWires; - GetOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires ); - if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - list< TopoDS_Edge >::iterator elIt = eList.begin(); - for ( i = 0; elIt != eList.end(); elIt++, i++ ) - switch ( i ) { - case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break; - case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break; - case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break; - case 3: Ex00 = *elIt; break; - default:; - } - if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) { - MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); - return false; - } - - - // find top edges and veritices - eList.clear(); - GetOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires ); - if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ ) - switch ( i ) { - case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break; - case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break; - case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break; - case 3: E0y1 = *elIt; break; - default:; - } - if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) { - MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); - return false; - } - - // swap Fx0z and F0yz if necessary - TopExp_Explorer exp( Fx0z, TopAbs_VERTEX ); - for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100 - if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() )) - break; // V101 or V100 found - if ( !exp.More() ) { // not found - std::swap( Fx0z, F0yz); - } - - // find Fx1z and F1yz faces - const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 ); - const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 ); - if (f111List.Extent() != NB_FACES_BY_VERTEX || - f110List.Extent() != NB_FACES_BY_VERTEX ) { - MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent()); - return false; - } - TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List); - for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) { - if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice - const TopoDS_Shape& F = f110It.Value(); - for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) { - if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice - if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found - if ( Fx1z.IsNull() ) - Fx1z = F; - else - F1yz = F; - } - } - } - if ( Fx1z.IsNull() || F1yz.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - - // swap Fx1z and F1yz if necessary - for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() ) - if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() )) - break; - if ( !exp.More() ) { - std::swap( Fx1z, F1yz); - } - - // find vertical edges - for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) { - const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); - const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); - if ( vFirst.IsSame( V001 )) - E00z = edge; - else if ( vFirst.IsSame( V100 )) - E10z = edge; - } - if ( E00z.IsNull() || E10z.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) { - const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); - const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); - if ( vFirst.IsSame( V111 )) - E11z = edge; - else if ( vFirst.IsSame( V010 )) - E01z = edge; - } - if ( E01z.IsNull() || E11z.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - - // load shapes in theShapeIDMap - - theShapeIDMap.Clear(); - - theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD )); - - theShapeIDMap.Add(Ex00); - theShapeIDMap.Add(Ex10); - theShapeIDMap.Add(Ex01); - theShapeIDMap.Add(Ex11); - - theShapeIDMap.Add(E0y0); - theShapeIDMap.Add(E1y0); - theShapeIDMap.Add(E0y1); - theShapeIDMap.Add(E1y1); - - theShapeIDMap.Add(E00z); - theShapeIDMap.Add(E10z); - theShapeIDMap.Add(E01z); - theShapeIDMap.Add(E11z); - - theShapeIDMap.Add(Fxy0); - theShapeIDMap.Add(Fxy1); - theShapeIDMap.Add(Fx0z); - theShapeIDMap.Add(Fx1z); - theShapeIDMap.Add(F0yz); - theShapeIDMap.Add(F1yz); - - theShapeIDMap.Add(theShell); - - return true; -} - -//================================================================================ -/*! - * \brief Initialize block geometry with shapes from theShapeIDMap - * \param theShapeIDMap - map of block subshapes - * \retval bool - is a success - */ -//================================================================================ - -bool SMESH_Block::LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) -{ - init(); - - // store shapes geometry - for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ ) - { - const TopoDS_Shape& S = theShapeIDMap( shapeID ); - switch ( S.ShapeType() ) - { - case TopAbs_VERTEX: { - - if ( !IsVertexID( ID_V111 )) return false; - myPnt[ shapeID - ID_V000 ] = BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ(); - break; - } - case TopAbs_EDGE: { - - if ( !IsEdgeID( shapeID )) return false; - const TopoDS_Edge& edge = TopoDS::Edge( S ); - TEdge& tEdge = myEdge[ shapeID - ID_FirstE ]; - tEdge.Set( shapeID, - new BRepAdaptor_Curve( edge ), - IsForwardEdge( edge, theShapeIDMap )); - break; - } - case TopAbs_FACE: { - - if ( !LoadFace( TopoDS::Face( S ), shapeID, theShapeIDMap )) - return false; - break; - } - default: break; - } - } // loop on shapes in theShapeIDMap - - return true; -} - -//================================================================================ -/*! - * \brief Load face geometry - * \param theFace - face - * \param theFaceID - face in-block ID - * \param theShapeIDMap - map of block subshapes - * \retval bool - is a success - * - * It is enough to compute params or coordinates on the face. - * Face subshapes must be loaded into theShapeIDMap before - */ -//================================================================================ - -bool SMESH_Block::LoadFace(const TopoDS_Face& theFace, - const int theFaceID, - const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) -{ - if ( !IsFaceID( theFaceID ) ) return false; - // pcurves - Adaptor2d_Curve2d* c2d[4]; - bool isForward[4]; - vector< int > edgeIdVec; - GetFaceEdgesIDs( theFaceID, edgeIdVec ); - for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges - { - if ( edgeIdVec[ iE ] > theShapeIDMap.Extent() ) - return false; - const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ])); - c2d[ iE ] = new BRepAdaptor_Curve2d( edge, theFace ); - isForward[ iE ] = IsForwardEdge( edge, theShapeIDMap ); - } - TFace& tFace = myFace[ theFaceID - ID_FirstF ]; - tFace.Set( theFaceID, new BRepAdaptor_Surface( theFace ), c2d, isForward ); - return true; -} - -//================================================================================ -/*! - * \brief/ Insert theShape into theShapeIDMap with theShapeID - * \param theShape - shape to insert - * \param theShapeID - shape in-block ID - * \param theShapeIDMap - map of block subshapes - */ -//================================================================================ - -bool SMESH_Block::Insert(const TopoDS_Shape& theShape, - const int theShapeID, - TopTools_IndexedMapOfOrientedShape& theShapeIDMap) -{ - if ( !theShape.IsNull() && theShapeID > 0 ) - { - if ( theShapeIDMap.Contains( theShape )) - return ( theShapeIDMap.FindIndex( theShape ) == theShapeID ); - - if ( theShapeID <= theShapeIDMap.Extent() ) { - theShapeIDMap.Substitute( theShapeID, theShape ); - } - else { - while ( theShapeIDMap.Extent() < theShapeID - 1 ) { - TopoDS_Compound comp; - BRep_Builder().MakeCompound( comp ); - theShapeIDMap.Add( comp ); - } - theShapeIDMap.Add( theShape ); - } - return true; - } - return false; -} - -//======================================================================= -//function : GetFaceEdgesIDs -//purpose : return edges IDs in the order u0, u1, 0v, 1v -// u0 means "|| u, v == 0" -//======================================================================= - -void SMESH_Block::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec ) -{ - edgeVec.resize( 4 ); - switch ( faceID ) { - case ID_Fxy0: - edgeVec[ 0 ] = ID_Ex00; - edgeVec[ 1 ] = ID_Ex10; - edgeVec[ 2 ] = ID_E0y0; - edgeVec[ 3 ] = ID_E1y0; - break; - case ID_Fxy1: - edgeVec[ 0 ] = ID_Ex01; - edgeVec[ 1 ] = ID_Ex11; - edgeVec[ 2 ] = ID_E0y1; - edgeVec[ 3 ] = ID_E1y1; - break; - case ID_Fx0z: - edgeVec[ 0 ] = ID_Ex00; - edgeVec[ 1 ] = ID_Ex01; - edgeVec[ 2 ] = ID_E00z; - edgeVec[ 3 ] = ID_E10z; - break; - case ID_Fx1z: - edgeVec[ 0 ] = ID_Ex10; - edgeVec[ 1 ] = ID_Ex11; - edgeVec[ 2 ] = ID_E01z; - edgeVec[ 3 ] = ID_E11z; - break; - case ID_F0yz: - edgeVec[ 0 ] = ID_E0y0; - edgeVec[ 1 ] = ID_E0y1; - edgeVec[ 2 ] = ID_E00z; - edgeVec[ 3 ] = ID_E01z; - break; - case ID_F1yz: - edgeVec[ 0 ] = ID_E1y0; - edgeVec[ 1 ] = ID_E1y1; - edgeVec[ 2 ] = ID_E10z; - edgeVec[ 3 ] = ID_E11z; - break; - default: - MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID ); - } -} - -//======================================================================= -//function : GetEdgeVertexIDs -//purpose : return vertex IDs of an edge -//======================================================================= - -void SMESH_Block::GetEdgeVertexIDs (const int edgeID, vector< int >& vertexVec ) -{ - vertexVec.resize( 2 ); - switch ( edgeID ) { - - case ID_Ex00: - vertexVec[ 0 ] = ID_V000; - vertexVec[ 1 ] = ID_V100; - break; - case ID_Ex10: - vertexVec[ 0 ] = ID_V010; - vertexVec[ 1 ] = ID_V110; - break; - case ID_Ex01: - vertexVec[ 0 ] = ID_V001; - vertexVec[ 1 ] = ID_V101; - break; - case ID_Ex11: - vertexVec[ 0 ] = ID_V011; - vertexVec[ 1 ] = ID_V111; - break; - - case ID_E0y0: - vertexVec[ 0 ] = ID_V000; - vertexVec[ 1 ] = ID_V010; - break; - case ID_E1y0: - vertexVec[ 0 ] = ID_V100; - vertexVec[ 1 ] = ID_V110; - break; - case ID_E0y1: - vertexVec[ 0 ] = ID_V001; - vertexVec[ 1 ] = ID_V011; - break; - case ID_E1y1: - vertexVec[ 0 ] = ID_V101; - vertexVec[ 1 ] = ID_V111; - break; - - case ID_E00z: - vertexVec[ 0 ] = ID_V000; - vertexVec[ 1 ] = ID_V001; - break; - case ID_E10z: - vertexVec[ 0 ] = ID_V100; - vertexVec[ 1 ] = ID_V101; - break; - case ID_E01z: - vertexVec[ 0 ] = ID_V010; - vertexVec[ 1 ] = ID_V011; - break; - case ID_E11z: - vertexVec[ 0 ] = ID_V110; - vertexVec[ 1 ] = ID_V111; - break; - default: - vertexVec.resize(0); - MESSAGE(" GetEdgeVertexIDs(), wrong edge ID: " << edgeID ); - } -} diff --git a/src/SMESH/SMESH_Block.hxx b/src/SMESH/SMESH_Block.hxx deleted file mode 100644 index 20c18163b..000000000 --- a/src/SMESH/SMESH_Block.hxx +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : SMESH_Block.hxx -// Created : Tue Nov 30 12:42:18 2004 -// Author : Edward AGAPOV (eap) -// -#ifndef SMESH_Block_HeaderFile -#define SMESH_Block_HeaderFile - -#include "SMESH_SMESH.hxx" - -//#include -//#include -//#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -class SMDS_MeshVolume; -class SMDS_MeshNode; -class Adaptor3d_Surface; -class Adaptor2d_Curve2d; -class Adaptor3d_Curve; -class gp_Pnt; - -// ========================================================= -// class calculating coordinates of 3D points by normalized -// parameters inside the block and vice versa -// ========================================================= - -class SMESH_EXPORT SMESH_Block: public math_FunctionSetWithDerivatives -{ - public: - enum TShapeID { - // ---------------------------- - // Ids of the block sub-shapes - // ---------------------------- - ID_NONE = 0, - - ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111, - - ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11, - ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1, - ID_E00z, ID_E10z, ID_E01z, ID_E11z, - - ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz, - - ID_Shell - }; - enum { // to use TShapeID for indexing certain type subshapes - - ID_FirstV = ID_V000, ID_FirstE = ID_Ex00, ID_FirstF = ID_Fxy0 - - }; - - - public: - // ------------------------------------------------- - // Block topology in terms of block sub-shapes' ids - // ------------------------------------------------- - - static int NbVertices() { return 8; } - static int NbEdges() { return 12; } - static int NbFaces() { return 6; } - static int NbSubShapes() { return ID_Shell; } - // to avoid magic numbers when allocating memory for subshapes - - static inline bool IsVertexID( int theShapeID ) - { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); } - - static inline bool IsEdgeID( int theShapeID ) - { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); } - - static inline bool IsFaceID( int theShapeID ) - { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); } - - static int ShapeIndex( int theShapeID ) - { - if ( IsVertexID( theShapeID )) return theShapeID - ID_V000; - if ( IsEdgeID( theShapeID )) return theShapeID - ID_Ex00; - if ( IsFaceID( theShapeID )) return theShapeID - ID_Fxy0; - return 0; - } - // return index [0-...] for each type of sub-shapes, - // for example : - // ShapeIndex( ID_Ex00 ) == 0 - // ShapeIndex( ID_Ex10 ) == 1 - - static void GetFaceEdgesIDs (const int faceID, std::vector< int >& edgeVec ); - // return edges IDs of a face in the order u0, u1, 0v, 1v - - static void GetEdgeVertexIDs (const int edgeID, std::vector< int >& vertexVec ); - // return vertex IDs of an edge - - static int GetCoordIndOnEdge (const int theEdgeID) - { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; } - // return an index of a coordinate which varies along the edge - - static double* GetShapeCoef (const int theShapeID); - // for theShapeID( TShapeID ), returns 3 coefficients used - // to compute an addition of an on-theShape point to coordinates - // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz), - // then the addition of a point P is computed as P*kx*ky*kz and ki is - // defined by the returned coef like this: - // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi - - static int GetShapeIDByParams ( const gp_XYZ& theParams ); - // define an id of the block sub-shape by point parameters - - static std::ostream& DumpShapeID (const int theBlockShapeID, std::ostream& stream); - // DEBUG: dump an id of a block sub-shape - - - public: - // --------------- - // Initialization - // --------------- - - SMESH_Block(); - - bool LoadBlockShapes(const TopoDS_Shell& theShell, - const TopoDS_Vertex& theVertex000, - const TopoDS_Vertex& theVertex001, - TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); - // Initialize block geometry with theShell, - // add sub-shapes of theBlock to theShapeIDMap so that they get - // IDs acoording to enum TShapeID - - bool LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap); - // Initialize block geometry with shapes from theShapeIDMap - - bool LoadMeshBlock(const SMDS_MeshVolume* theVolume, - const int theNode000Index, - const int theNode001Index, - std::vector& theOrderedNodes); - // prepare to work with theVolume and - // return nodes in theVolume corners in the order of TShapeID enum - - bool LoadFace(const TopoDS_Face& theFace, - const int theFaceID, - const TopTools_IndexedMapOfOrientedShape& theShapeIDMap); - // Load face geometry. - // It is enough to compute params or coordinates on the face. - // Face subshapes must be loaded into theShapeIDMap before - - static bool Insert(const TopoDS_Shape& theShape, - const int theShapeID, - TopTools_IndexedMapOfOrientedShape& theShapeIDMap); - // Insert theShape into theShapeIDMap with theShapeID, - // Not yet set shapes preceding theShapeID are filled with compounds - // Return true if theShape was successfully bound to theShapeID - - static bool FindBlockShapes(const TopoDS_Shell& theShell, - const TopoDS_Vertex& theVertex000, - const TopoDS_Vertex& theVertex001, - TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); - // add sub-shapes of theBlock to theShapeIDMap so that they get - // IDs acoording to enum TShapeID - -public: - // --------------------------------- - // Define coordinates by parameters - // --------------------------------- - - bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const { - if ( !IsVertexID( theVertexID )) return false; - thePoint = myPnt[ theVertexID - ID_FirstV ]; return true; - } - // return vertex coordinates, parameters are defined by theVertexID - - bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { - if ( !IsEdgeID( theEdgeID )) return false; - thePoint = myEdge[ theEdgeID - ID_FirstE ].Point( theParams ); return true; - } - // return coordinates of a point on edge - - bool EdgeU( const int theEdgeID, const gp_XYZ& theParams, double& theU ) const { - if ( !IsEdgeID( theEdgeID )) return false; - theU = myEdge[ theEdgeID - ID_FirstE ].GetU( theParams ); return true; - } - // return parameter on edge by in-block parameters - - bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { - if ( !IsFaceID ( theFaceID )) return false; - thePoint = myFace[ theFaceID - ID_FirstF ].Point( theParams ); return true; - } - // return coordinates of a point on face - - bool FaceUV( const int theFaceID, const gp_XYZ& theParams, gp_XY& theUV ) const { - if ( !IsFaceID ( theFaceID )) return false; - theUV = myFace[ theFaceID - ID_FirstF ].GetUV( theParams ); return true; - } - // return UV coordinates on a face by in-block parameters - - bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const; - // return coordinates of a point in shell - - static bool ShellPoint(const gp_XYZ& theParams, - const std::vector& thePointOnShape, - gp_XYZ& thePoint ); - // computes coordinates of a point in shell by points on sub-shapes - // and point parameters. - // thePointOnShape[ subShapeID ] must be a point on a subShape; - // thePointOnShape.size() == ID_Shell, thePointOnShape[0] not used - - - public: - // --------------------------------- - // Define parameters by coordinates - // --------------------------------- - - bool ComputeParameters (const gp_Pnt& thePoint, - gp_XYZ& theParams, - const int theShapeID = ID_Shell, - const gp_XYZ& theParamsHint = gp_XYZ(-1,-1,-1)); - // compute point parameters in the block. - // Note: for edges, it is better to use EdgeParameters() - - bool VertexParameters(const int theVertexID, gp_XYZ& theParams); - // return parameters of a vertex given by TShapeID - - bool EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams); - // return parameters of a point given by theU on edge - - - public: - // --------------- - // Block geomerty - // --------------- - - - - public: - // --------- - // Services - // --------- - - static bool IsForwardEdge (const TopoDS_Edge & theEdge, - const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) { - int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD )); - int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD )); - return ( v1ID < v2ID ); - } - // Return true if an in-block parameter increases along theEdge curve - - static int GetOrderedEdges (const TopoDS_Face& theFace, - TopoDS_Vertex theFirstVertex, - std::list< TopoDS_Edge >& theEdges, - std::list< int > & theNbVertexInWires); - // Return nb wires and a list of oredered edges. - // It is used to assign indices to subshapes. - // theFirstVertex may be NULL. - // Always try to set a seam edge first - - public: - // ----------------------------------------------------------- - // Methods of math_FunctionSetWithDerivatives used internally - // to define parameters by coordinates - // ----------------------------------------------------------- - Standard_Integer NbVariables() const; - Standard_Integer NbEquations() const; - Standard_Boolean Value(const math_Vector& X,math_Vector& F) ; - Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ; - Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ; - Standard_Integer GetStateNumber (); - - protected: - - /*! - * \brief Call it after geometry initialisation - */ - void init(); - - // 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; - double myLast; - Adaptor3d_Curve* myC3d; - // if mesh volume - gp_XYZ myNodes[2]; - public: - void Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward ); - void Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 ); - Adaptor3d_Curve* GetCurve() const { return myC3d; } - double EndParam(int i) const { return i ? myLast : myFirst; } - int CoordInd() const { return myCoordInd; } - const gp_XYZ& NodeXYZ(int i) const { return i ? myNodes[1] : myNodes[0]; } - gp_XYZ Point( const gp_XYZ& theParams ) const; // Return coord by params - double GetU( const gp_XYZ& theParams ) const; // Return U by params - TEdge(): myC3d(0) {} - ~TEdge(); - }; - - class SMESH_EXPORT TFace { - // 4 edges in the order u0, u1, 0v, 1v - int myCoordInd[ 4 ]; - double myFirst [ 4 ]; - double myLast [ 4 ]; - Adaptor2d_Curve2d* myC2d [ 4 ]; - // 4 corner points in the order 00, 10, 11, 01 - gp_XY myCorner [ 4 ]; - // surface - Adaptor3d_Surface* myS; - // if mesh volume - gp_XYZ myNodes[4]; - public: - void Set( const int faceID, Adaptor3d_Surface* S, // must be in GetFaceEdgesIDs() order: - Adaptor2d_Curve2d* c2d[4], const bool isForward[4] ); - void Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 ); - gp_XY GetUV( const gp_XYZ& theParams ) const; - gp_XYZ Point( const gp_XYZ& theParams ) const; - int GetUInd() const { return myCoordInd[ 0 ]; } - int GetVInd() const { return myCoordInd[ 2 ]; } - void GetCoefs( int i, const gp_XYZ& theParams, double& eCoef, double& vCoef ) const; - TFace(): myS(0) { myC2d[0]=myC2d[1]=myC2d[2]=myC2d[3]=0; } - ~TFace(); - }; - - // geometry in the order as in TShapeID: - // 8 vertices - gp_XYZ myPnt[ 8 ]; - // 12 edges - TEdge myEdge[ 12 ]; - // 6 faces - TFace myFace[ 6 ]; - - // for param computation - - enum { SQUARE_DIST = 0, DRV_1, DRV_2, DRV_3 }; - double distance () const { return sqrt( myValues[ SQUARE_DIST ]); } - double funcValue(double sqDist) const { return mySquareFunc ? sqDist : sqrt(sqDist); } - bool computeParameters(const gp_Pnt& thePoint, gp_XYZ& theParams, const gp_XYZ& theParamsHint); - - int myFaceIndex; - double myFaceParam; - int myNbIterations; - double mySumDist; - double myTolerance; - bool mySquareFunc; - - gp_XYZ myPoint; // the given point - gp_XYZ myParam; // the best parameters guess - double myValues[ 4 ]; // values computed at myParam: square distance and 3 derivatives - - typedef std::pair TxyzPair; - TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess - bool myGridComputed; -}; - - -#endif diff --git a/src/SMESH/SMESH_Comment.hxx b/src/SMESH/SMESH_Comment.hxx deleted file mode 100644 index 14d42faf4..000000000 --- a/src/SMESH/SMESH_Comment.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH : implementaion of SMESH idl descriptions -// 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 -# include - -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 - SMESH_Comment( const T &anything ) { - _s << anything ; - this->string::operator=( _s.str() ); - } - - template - SMESH_Comment & operator<<( const T &anything ) { - _s << anything ; - this->string::operator=( _s.str() ); - return *this ; - } -}; - - -#endif diff --git a/src/SMESH/SMESH_ComputeError.hxx b/src/SMESH/SMESH_ComputeError.hxx deleted file mode 100644 index a764f0a3b..000000000 --- a/src/SMESH/SMESH_ComputeError.hxx +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH : implementaion of SMESH idl descriptions -// File : SMESH_Hypothesis.hxx -// Author : Edward AGAPOV (eap) -// Module : SMESH -// $Header: -// -#ifndef SMESH_ComputeError_HeaderFile -#define SMESH_ComputeError_HeaderFile - -#include -#include -#include - -class SMESH_Algo; -class SMDS_MeshElement; -struct SMESH_ComputeError; - -typedef boost::shared_ptr 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; - - std::list myBadElements; //!< to explain COMPERR_BAD_INPUT_MESH - - 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 diff --git a/src/SMESH/SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx b/src/SMESH/SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx deleted file mode 100644 index 0ac60ca29..000000000 --- a/src/SMESH/SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File: SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx -// Created: 26.09.05 17:41:10 -// Author: Sergey KUUL -// -#ifndef SMESH_DataMapOfElemPtrSequenceOfElemPtr_HeaderFile -#define SMESH_DataMapOfElemPtrSequenceOfElemPtr_HeaderFile - -#include "SMESH_SMESH.hxx" - -#include - -#include - -SMESH_EXPORT -inline Standard_Integer HashCode(SMDS_MeshElementPtr theElem, - const Standard_Integer theUpper) -{ - void* anElem = (void*) theElem; - return HashCode(anElem,theUpper); -} - -SMESH_EXPORT -inline Standard_Boolean IsEqual(SMDS_MeshElementPtr theOne, - SMDS_MeshElementPtr theTwo) -{ - return theOne == theTwo; -} - -DEFINE_BASECOLLECTION (SMESH_BaseCollectionSequenceOfElemPtr, SMESH_SequenceOfElemPtr) -DEFINE_DATAMAP (SMESH_DataMapOfElemPtrSequenceOfElemPtr, - SMESH_BaseCollectionSequenceOfElemPtr, - SMDS_MeshElementPtr, SMESH_SequenceOfElemPtr) -#endif diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 955e1335d..dae945eec 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -1,104 +1,89 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Gen.cxx // Author : Paul RASCLE, EDF // Module : SMESH +// + +//#define CHRONODEF #include "SMESH_Gen.hxx" -#include "SMESH_subMesh.hxx" -#include "SMESH_HypoFilter.hxx" -#include "SMESHDS_Document.hxx" + +#include "SMDS_Mesh.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMESHDS_Document.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" #include "utilities.h" #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" -#include -#include -#include -#include +#include + +#include "memoire.h" using namespace std; //============================================================================= /*! - * default constructor: + * Constructor */ //============================================================================= SMESH_Gen::SMESH_Gen() { - MESSAGE("SMESH_Gen::SMESH_Gen"); - _localId = 0; - _hypId = 0; - _segmentation = 10; + MESSAGE("SMESH_Gen::SMESH_Gen"); + _localId = 0; + _hypId = 0; + _segmentation = _nbSegments = 10; + SMDS_Mesh::_meshList.clear(); + MESSAGE(SMDS_Mesh::_meshList.size()); + _counters = new counters(100); +#ifdef WITH_SMESH_CANCEL_COMPUTE + _compute_canceled = false; + _sm_current = NULL; +#endif } //============================================================================= /*! - * + * Destructor */ //============================================================================= SMESH_Gen::~SMESH_Gen() { - MESSAGE("SMESH_Gen::~SMESH_Gen"); + MESSAGE("SMESH_Gen::~SMESH_Gen"); } //============================================================================= /*! - * - */ -//============================================================================= - -/*SMESH_Hypothesis *SMESH_Gen::CreateHypothesis(const char *anHyp, int studyId) - throw(SALOME_Exception) -{ - - MESSAGE("CreateHypothesis("<GetID(); - myStudyContext->mapHypothesis[hypId] = myHypothesis; - SCRUTE(studyId); - SCRUTE(hypId); - - // store hypothesis in SMESHDS document - - myStudyContext->myDocument->AddHypothesis(myHypothesis); - return myHypothesis; -}*/ - -//============================================================================= -/*! - * + * Creates a mesh in a study. + * if (theIsEmbeddedMode) { mesh modification commands are not logged } */ //============================================================================= @@ -113,11 +98,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode) // create a new SMESH_mesh object SMESH_Mesh *aMesh = new SMESH_Mesh(_localId++, - theStudyId, - this, - theIsEmbeddedMode, - aStudyContext->myDocument); - aStudyContext->mapMesh[_localId] = aMesh; + theStudyId, + this, + theIsEmbeddedMode, + aStudyContext->myDocument); + aStudyContext->mapMesh[_localId-1] = aMesh; return aMesh; } @@ -131,10 +116,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode) bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool anUpward, - const ::MeshDimension aDim, - TSetOfInt* aShapesId) + const ::MeshDimension aDim, + TSetOfInt* aShapesId) { MESSAGE("SMESH_Gen::Compute"); + MEMOSTAT; bool ret = true; @@ -142,13 +128,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const bool includeSelf = true; const bool complexShapeFirst = true; + const int globalAlgoDim = 100; SMESH_subMeshIteratorPtr smIt; if ( anUpward ) // is called from below code here { // ----------------------------------------------- - // mesh all the subshapes starting from vertices + // mesh all the sub-shapes starting from vertices // ----------------------------------------------- smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst); while ( smIt->more() ) @@ -166,28 +153,47 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // clear compute state to not show previous compute errors // if preview invoked less dimension less than previous smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - continue; + continue; } if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) + { +#ifdef WITH_SMESH_CANCEL_COMPUTE + if (_compute_canceled) + return false; + _sm_current = smToCompute; +#endif smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE ); +#ifdef WITH_SMESH_CANCEL_COMPUTE + _sm_current = NULL; +#endif + } // we check all the submeshes here and detect if any of them failed to compute if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) ret = false; else if ( aShapesId ) - aShapesId->insert( smToCompute->GetId() ); + aShapesId->insert( smToCompute->GetId() ); } + //aMesh.GetMeshDS()->Modified(); return ret; } else { // ----------------------------------------------------------------- - // apply algos that DO NOT require descretized boundaries and DO NOT + // apply algos that DO NOT require Discreteized boundaries and DO NOT // support submeshes, starting from the most complex shapes // and collect submeshes with algos that DO support submeshes // ----------------------------------------------------------------- list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes; + + // map to sort sm with same dim algos according to dim of + // the shape the algo assigned to (issue 0021217) + multimap< int, SMESH_subMesh* > shDim2sm; + multimap< int, SMESH_subMesh* >::reverse_iterator shDim2smIt; + TopoDS_Shape algoShape; + int prevShapeDim = -1; + smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst); while ( smIt->more() ) { @@ -196,40 +202,87 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, continue; const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); - const int aShapeDim = GetShapeDim( aSubShape ); + int aShapeDim = GetShapeDim( aSubShape ); if ( aShapeDim < 1 ) break; // check for preview dimension limitations if ( aShapesId && aShapeDim > (int)aDim ) - continue; + continue; - SMESH_Algo* algo = GetAlgo( aMesh, aSubShape ); - if ( algo && !algo->NeedDescretBoundary() ) + SMESH_Algo* algo = GetAlgo( aMesh, aSubShape, &algoShape ); + if ( algo && !algo->NeedDiscreteBoundary() ) { if ( algo->SupportSubmeshes() ) - smWithAlgoSupportingSubmeshes.push_back( smToCompute ); + { + // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes + // so that more local algos to go first + if ( prevShapeDim != aShapeDim ) + { + prevShapeDim = aShapeDim; + for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt ) + if ( shDim2smIt->first == globalAlgoDim ) + smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second ); + else + smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second ); + shDim2sm.clear(); + } + // add smToCompute to shDim2sm map + if ( algoShape.IsSame( aMesh.GetShapeToMesh() )) + { + aShapeDim = globalAlgoDim; // to compute last + } + else + { + aShapeDim = GetShapeDim( algoShape ); + if ( algoShape.ShapeType() == TopAbs_COMPOUND ) + { + TopoDS_Iterator it( algoShape ); + aShapeDim += GetShapeDim( it.Value() ); + } + } + shDim2sm.insert( make_pair( aShapeDim, smToCompute )); + } else - { + { +#ifdef WITH_SMESH_CANCEL_COMPUTE + if (_compute_canceled) + return false; + _sm_current = smToCompute; +#endif smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE ); - if ( aShapesId ) - aShapesId->insert( smToCompute->GetId() ); - } +#ifdef WITH_SMESH_CANCEL_COMPUTE + _sm_current = NULL; +#endif + if ( aShapesId ) + aShapesId->insert( smToCompute->GetId() ); + } } } + // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes + for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt ) + if ( shDim2smIt->first == globalAlgoDim ) + smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second ); + else + smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second ); + + // ------------------------------------------------------------ + // sort list of submeshes according to mesh order + // ------------------------------------------------------------ + aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes ); + // ------------------------------------------------------------ // compute submeshes under shapes with algos that DO NOT require - // descretized boundaries and DO support submeshes + // Discreteized boundaries and DO support submeshes // ------------------------------------------------------------ - list< SMESH_subMesh* >::reverse_iterator subIt, subEnd; - subIt = smWithAlgoSupportingSubmeshes.rbegin(); - subEnd = smWithAlgoSupportingSubmeshes.rend(); + list< SMESH_subMesh* >::iterator subIt, subEnd; + subIt = smWithAlgoSupportingSubmeshes.begin(); + subEnd = smWithAlgoSupportingSubmeshes.end(); // start from lower shapes for ( ; subIt != subEnd; ++subIt ) { sm = *subIt; // get a shape the algo is assigned to - TopoDS_Shape algoShape; if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape )) continue; // strange... @@ -240,18 +293,18 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, SMESH_subMesh* smToCompute = smIt->next(); const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); - const int aShapeDim = GetShapeDim( aSubShape ); + const int aShapeDim = GetShapeDim( aSubShape ); //if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue; - if ( aShapeDim < 1 ) continue; + if ( aShapeDim < 1 ) continue; - // check for preview dimension limitations - if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim ) - continue; - + // check for preview dimension limitations + if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim ) + continue; + SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); filter .And( SMESH_HypoFilter::IsApplicableTo( aSubShape )) - .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape )); + .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh )); if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) { SMESH_Hypothesis::Hypothesis_Status status; @@ -262,31 +315,239 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } } // ---------------------------------------------------------- - // apply the algos that do not require descretized boundaries + // apply the algos that do not require Discreteized boundaries // ---------------------------------------------------------- - for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt ) + for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt ) + { + sm = *subIt; if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { - const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType(); - // check for preview dimension limitations - if ( aShapesId && GetShapeDim( aShType ) > (int)aDim ) - continue; - + const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType(); + // check for preview dimension limitations + if ( aShapesId && GetShapeDim( aShType ) > (int)aDim ) + continue; + +#ifdef WITH_SMESH_CANCEL_COMPUTE + if (_compute_canceled) + return false; + _sm_current = sm; +#endif sm->ComputeStateEngine( SMESH_subMesh::COMPUTE ); - if ( aShapesId ) - aShapesId->insert( sm->GetId() ); +#ifdef WITH_SMESH_CANCEL_COMPUTE + _sm_current = NULL; +#endif + if ( aShapesId ) + aShapesId->insert( sm->GetId() ); } - + } // ----------------------------------------------- - // mesh the rest subshapes starting from vertices + // mesh the rest sub-shapes starting from vertices // ----------------------------------------------- ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId ); } MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret); + MEMOSTAT; + + SMESHDS_Mesh *myMesh = aMesh.GetMeshDS(); + myMesh->adjustStructure(); + MESSAGE("*** compactMesh after compute"); + myMesh->compactMesh(); + //myMesh->adjustStructure(); + list listind = myMesh->SubMeshIndices(); + list::iterator it = listind.begin(); + int total = 0; + for(; it != listind.end(); ++it) + { + ::SMESHDS_SubMesh *subMesh = myMesh->MeshElements(*it); + total += subMesh->getSize(); + } + MESSAGE("total elements and nodes in submesh sets:" << total); + MESSAGE("Number of node objects " << SMDS_MeshNode::nbNodes); + MESSAGE("Number of cell objects " << SMDS_MeshCell::nbCells); + //myMesh->dumpGrid(); + //aMesh.GetMeshDS()->Modified(); + + // fix quadratic mesh by bending iternal links near concave boundary + if ( aShape.IsSame( aMesh.GetShapeToMesh() ) && + !aShapesId ) // not preview + { + SMESH_MesherHelper aHelper( aMesh ); + if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR ) + aHelper.FixQuadraticElements(); + } + return ret; +} + + +#ifdef WITH_SMESH_CANCEL_COMPUTE +//============================================================================= +/*! + * Prepare Compute a mesh + */ +//============================================================================= +void SMESH_Gen::PrepareCompute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) +{ + _compute_canceled = false; + _sm_current = NULL; +} +//============================================================================= +/*! + * Cancel Compute a mesh + */ +//============================================================================= +void SMESH_Gen::CancelCompute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape) +{ + _compute_canceled = true; + if(_sm_current) + { + _sm_current->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED ); + } +} +#endif + +//============================================================================= +/*! + * Evaluate a mesh + */ +//============================================================================= + +bool SMESH_Gen::Evaluate(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap, + const bool anUpward, + TSetOfInt* aShapesId) +{ + MESSAGE("SMESH_Gen::Evaluate"); + + bool ret = true; + + SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); + + const bool includeSelf = true; + const bool complexShapeFirst = true; + SMESH_subMeshIteratorPtr smIt; + + if ( anUpward ) { // is called from below code here + // ----------------------------------------------- + // mesh all the sub-shapes starting from vertices + // ----------------------------------------------- + smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst); + while ( smIt->more() ) { + SMESH_subMesh* smToCompute = smIt->next(); + + // do not mesh vertices of a pseudo shape + const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType(); + //if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX ) + // continue; + if ( !aMesh.HasShapeToMesh() ) { + if( aShType == TopAbs_VERTEX || aShType == TopAbs_WIRE || + aShType == TopAbs_SHELL ) + continue; + } + + smToCompute->Evaluate(aResMap); + if( aShapesId ) + aShapesId->insert( smToCompute->GetId() ); + } + return ret; + } + else { + // ----------------------------------------------------------------- + // apply algos that DO NOT require Discreteized boundaries and DO NOT + // support submeshes, starting from the most complex shapes + // and collect submeshes with algos that DO support submeshes + // ----------------------------------------------------------------- + list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes; + smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst); + while ( smIt->more() ) { + SMESH_subMesh* smToCompute = smIt->next(); + const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); + const int aShapeDim = GetShapeDim( aSubShape ); + if ( aShapeDim < 1 ) break; + + SMESH_Algo* algo = GetAlgo( aMesh, aSubShape ); + if ( algo && !algo->NeedDiscreteBoundary() ) { + if ( algo->SupportSubmeshes() ) { + smWithAlgoSupportingSubmeshes.push_front( smToCompute ); + } + else { + smToCompute->Evaluate(aResMap); + if ( aShapesId ) + aShapesId->insert( smToCompute->GetId() ); + } + } + } + + // ------------------------------------------------------------ + // sort list of meshes according to mesh order + // ------------------------------------------------------------ + aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes ); + + // ------------------------------------------------------------ + // compute submeshes under shapes with algos that DO NOT require + // Discreteized boundaries and DO support submeshes + // ------------------------------------------------------------ + list< SMESH_subMesh* >::iterator subIt, subEnd; + subIt = smWithAlgoSupportingSubmeshes.begin(); + subEnd = smWithAlgoSupportingSubmeshes.end(); + // start from lower shapes + for ( ; subIt != subEnd; ++subIt ) { + sm = *subIt; + + // get a shape the algo is assigned to + TopoDS_Shape algoShape; + if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape )) + continue; // strange... + + // look for more local algos + smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst); + while ( smIt->more() ) { + SMESH_subMesh* smToCompute = smIt->next(); + + const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); + const int aShapeDim = GetShapeDim( aSubShape ); + if ( aShapeDim < 1 ) continue; + + //const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType(); + + SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); + filter + .And( SMESH_HypoFilter::IsApplicableTo( aSubShape )) + .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh )); + + if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) { + SMESH_Hypothesis::Hypothesis_Status status; + if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status )) + // mesh a lower smToCompute starting from vertices + Evaluate( aMesh, aSubShape, aResMap, /*anUpward=*/true, aShapesId ); + } + } + } + // ---------------------------------------------------------- + // apply the algos that do not require Discreteized boundaries + // ---------------------------------------------------------- + for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt ) + { + sm = *subIt; + sm->Evaluate(aResMap); + if ( aShapesId ) + aShapesId->insert( sm->GetId() ); + } + + // ----------------------------------------------- + // mesh the rest sub-shapes starting from vertices + // ----------------------------------------------- + ret = Evaluate( aMesh, aShape, aResMap, /*anUpward=*/true, aShapesId ); + } + + MESSAGE( "VSR - SMESH_Gen::Evaluate() finished, OK = " << ret); return ret; } + //======================================================================= //function : checkConformIgnoredAlgos //purpose : @@ -297,7 +558,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh, const SMESH_Algo* aGlobIgnoAlgo, const SMESH_Algo* aLocIgnoAlgo, bool & checkConform, - map& aCheckedMap, + set& aCheckedMap, list< SMESH_Gen::TAlgoStateError > & theErrors) { ASSERT( aSubMesh ); @@ -337,7 +598,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh, << " <" << algo->GetName() << "> is hidden by global <" << aGlobIgnoAlgo->GetName() << ">"); } - else if ( !algo->NeedDescretBoundary() && !isGlobal) + else if ( !algo->NeedDiscreteBoundary() && !isGlobal) { // local algo is not hidden and hides algos on sub-shapes if (checkConform && !aSubMesh->IsConform( algo )) @@ -352,19 +613,15 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh& aMesh, } // sub-algos will be hidden by a local - const map& smMap = aSubMesh->DependsOn(); - map::const_reverse_iterator revItSub; + SMESH_subMeshIteratorPtr revItSub = + aSubMesh->getDependsOnIterator( /*includeSelf=*/false, /*complexShapeFirst=*/true); bool checkConform2 = false; - for ( revItSub = smMap.rbegin(); revItSub != smMap.rend(); revItSub++) + while ( revItSub->more() ) { - checkConformIgnoredAlgos (aMesh, (*revItSub).second, aGlobIgnoAlgo, + SMESH_subMesh* sm = revItSub->next(); + checkConformIgnoredAlgos (aMesh, sm, aGlobIgnoAlgo, algo, checkConform2, aCheckedMap, theErrors); - int key = (*revItSub).first; - SMESH_subMesh* sm = (*revItSub).second; - if ( aCheckedMap.find( key ) == aCheckedMap.end() ) - { - aCheckedMap[ key ] = sm; - } + aCheckedMap.insert( sm ); } } } @@ -385,7 +642,7 @@ static bool checkMissing(SMESH_Gen* aGen, const int aTopAlgoDim, bool* globalChecked, const bool checkNoAlgo, - map& aCheckedMap, + set& aCheckedMap, list< SMESH_Gen::TAlgoStateError > & theErrors) { if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX) @@ -455,18 +712,16 @@ static bool checkMissing(SMESH_Gen* aGen, ASSERT (algo); bool isTopLocalAlgo = ( aTopAlgoDim <= algo->GetDim() && !aGen->IsGlobalHypothesis( algo, aMesh )); - if (!algo->NeedDescretBoundary() || isTopLocalAlgo) + if (!algo->NeedDiscreteBoundary() || isTopLocalAlgo) { - bool checkNoAlgo2 = ( algo->NeedDescretBoundary() ); - const map& subMeshes = aSubMesh->DependsOn(); - map::const_iterator itsub; - for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) + bool checkNoAlgo2 = ( algo->NeedDiscreteBoundary() ); + SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false, + /*complexShapeFirst=*/false); + while ( itsub->more() ) { // sub-meshes should not be checked further more - int key = (*itsub).first; - SMESH_subMesh* sm = (*itsub).second; - if ( aCheckedMap.find( key ) == aCheckedMap.end() ) - aCheckedMap[ key ] = sm; + SMESH_subMesh* sm = itsub->next(); + aCheckedMap.insert( sm ); if (isTopLocalAlgo) { @@ -542,7 +797,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh, // -------------------------------------------------------- // info on algos that will be ignored because of ones that - // don't NeedDescretBoundary() attached to super-shapes, + // don't NeedDiscreteBoundary() attached to super-shapes, // check that a conform mesh will be produced // -------------------------------------------------------- @@ -553,46 +808,32 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh, for (dim = 3; dim > 0; dim--) { if (aGlobAlgoArr[ dim ] && - !aGlobAlgoArr[ dim ]->NeedDescretBoundary()) + !aGlobAlgoArr[ dim ]->NeedDiscreteBoundary()) { aGlobIgnoAlgo = aGlobAlgoArr[ dim ]; break; } } - const map& smMap = sm->DependsOn(); - map::const_reverse_iterator revItSub = smMap.rbegin(); - map aCheckedMap; + set aCheckedSubs; bool checkConform = ( !theMesh.IsNotConformAllowed() ); - int aKey = 1; - SMESH_subMesh* smToCheck = sm; // loop on theShape and its sub-shapes - while ( smToCheck ) + SMESH_subMeshIteratorPtr revItSub = sm->getDependsOnIterator( /*includeSelf=*/true, + /*complexShapeFirst=*/true); + while ( revItSub->more() ) { + SMESH_subMesh* smToCheck = revItSub->next(); if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX) break; - if ( aCheckedMap.find( aKey ) == aCheckedMap.end() ) + if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked if (!checkConformIgnoredAlgos (theMesh, smToCheck, aGlobIgnoAlgo, - 0, checkConform, aCheckedMap, theErrors)) + 0, checkConform, aCheckedSubs, theErrors)) ret = false; if ( smToCheck->GetAlgoState() != SMESH_subMesh::NO_ALGO ) hasAlgo = true; - - // next subMesh - if (revItSub != smMap.rend()) - { - aKey = (*revItSub).first; - smToCheck = (*revItSub).second; - revItSub++; - } - else - { - smToCheck = 0; - } - } // ---------------------------------------------------------------- @@ -612,36 +853,26 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh& theMesh, break; } } - aCheckedMap.clear(); - smToCheck = sm; - revItSub = smMap.rbegin(); bool checkNoAlgo = theMesh.HasShapeToMesh() ? bool( aTopAlgoDim ) : false; bool globalChecked[] = { false, false, false, false }; // loop on theShape and its sub-shapes - while ( smToCheck ) + aCheckedSubs.clear(); + revItSub = sm->getDependsOnIterator( /*includeSelf=*/true, /*complexShapeFirst=*/true); + while ( revItSub->more() ) { + SMESH_subMesh* smToCheck = revItSub->next(); if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX) break; - if ( aCheckedMap.find( aKey ) == aCheckedMap.end() ) + if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim, - globalChecked, checkNoAlgo, aCheckedMap, theErrors)) + globalChecked, checkNoAlgo, aCheckedSubs, theErrors)) { ret = false; if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO ) checkNoAlgo = false; } - - // next subMesh - if (revItSub != smMap.rend()) - { - aKey = (*revItSub).first; - smToCheck = (*revItSub).second; - revItSub++; - } - else - smToCheck = 0; } if ( !hasAlgo ) { @@ -667,7 +898,7 @@ bool SMESH_Gen::IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& a //============================================================================= /*! - * + * Finds algo to mesh a shape. Optionally returns a shape the found algo is bound to */ //============================================================================= @@ -675,7 +906,6 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, TopoDS_Shape* assignedTo) { - SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); filter.And( filter.IsApplicableTo( aShape )); @@ -684,59 +914,28 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh & aMesh, //============================================================================= /*! - * + * Returns StudyContextStruct for a study */ //============================================================================= StudyContextStruct *SMESH_Gen::GetStudyContext(int studyId) { - // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document - - if (_mapStudyContext.find(studyId) == _mapStudyContext.end()) - { - _mapStudyContext[studyId] = new StudyContextStruct; - _mapStudyContext[studyId]->myDocument = new SMESHDS_Document(studyId); - } - StudyContextStruct *myStudyContext = _mapStudyContext[studyId]; -// ASSERT(_mapStudyContext.find(studyId) != _mapStudyContext.end()); - return myStudyContext; -} - -// //============================================================================= -// /*! -// * -// */ -// //============================================================================= - -// void SMESH_Gen::Save(int studyId, const char *aUrlOfFile) -// { -// } - -// //============================================================================= -// /*! -// * -// */ -// //============================================================================= - -// void SMESH_Gen::Load(int studyId, const char *aUrlOfFile) -// { -// } - -// //============================================================================= -// /*! -// * -// */ -// //============================================================================= + // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document -// void SMESH_Gen::Close(int studyId) -// { -// } + if (_mapStudyContext.find(studyId) == _mapStudyContext.end()) + { + _mapStudyContext[studyId] = new StudyContextStruct; + _mapStudyContext[studyId]->myDocument = new SMESHDS_Document(studyId); + } + StudyContextStruct *myStudyContext = _mapStudyContext[studyId]; + return myStudyContext; +} -//============================================================================= +//================================================================================ /*! - * + * \brief Return shape dimension by TopAbs_ShapeEnum */ -//============================================================================= +//================================================================================ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType) { @@ -747,7 +946,7 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType) dim[ TopAbs_COMPOUND ] = MeshDim_3D; dim[ TopAbs_COMPSOLID ] = MeshDim_3D; dim[ TopAbs_SOLID ] = MeshDim_3D; - dim[ TopAbs_SHELL ] = MeshDim_3D; + dim[ TopAbs_SHELL ] = MeshDim_2D; dim[ TopAbs_FACE ] = MeshDim_2D; dim[ TopAbs_WIRE ] = MeshDim_1D; dim[ TopAbs_EDGE ] = MeshDim_1D; @@ -758,12 +957,11 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType) //============================================================================= /*! - * + * Genarate a new id unique withing this Gen */ //============================================================================= int SMESH_Gen::GetANewId() { - //MESSAGE("SMESH_Gen::GetANewId"); - return _hypId++; + return _hypId++; } diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index 46c00dc2c..353cba6df 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Gen.hxx // Author : Paul RASCLE, EDF // Module : SMESH // - #ifndef _SMESH_GEN_HXX_ #define _SMESH_GEN_HXX_ @@ -41,6 +41,8 @@ #include "SMESH_3D_Algo.hxx" #include "SMESH_Mesh.hxx" +#include "chrono.hxx" + #include #include @@ -61,7 +63,7 @@ typedef std::set TSetOfInt; class SMESH_EXPORT SMESH_Gen { - public: +public: SMESH_Gen(); ~SMESH_Gen(); @@ -78,8 +80,28 @@ class SMESH_EXPORT SMESH_Gen bool Compute(::SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool anUpward=false, - const ::MeshDimension aDim=::MeshDim_3D, - TSetOfInt* aShapesId=0); + const ::MeshDimension aDim=::MeshDim_3D, + TSetOfInt* aShapesId=0); + +#ifdef WITH_SMESH_CANCEL_COMPUTE + void PrepareCompute(::SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape); + void CancelCompute(::SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape); +#endif + + /*! + * \brief evaluates size of prospective mesh on a shape + * \param aMesh - the mesh + * \param aShape - the shape + * \param aResMap - map for prospective numbers of elements + * \retval bool - is a success + */ + bool Evaluate(::SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap, + const bool anUpward=false, + TSetOfInt* aShapesId=0); bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); // notify on bad state of attached algos, return false @@ -96,7 +118,7 @@ class SMESH_EXPORT SMESH_Gen */ void SetDefaultNbSegments(int nb) { _nbSegments = nb; } int GetDefaultNbSegments() const { return _nbSegments; } - + struct TAlgoStateError { TAlgoStateErrorName _name; @@ -125,16 +147,6 @@ class SMESH_EXPORT SMESH_Gen SMESH_Algo* GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, TopoDS_Shape* assignedTo=0); static bool IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& aMesh); - // inherited methods from SALOMEDS::Driver - -// void Save(int studyId, const char *aUrlOfFile); -// void Load(int studyId, const char *aUrlOfFile); -// void Close(int studyId); -// const char *ComponentDataType(); - -// const char *IORToLocalPersistentID(const char *IORString, bool & IsAFile); -// const char *LocalPersistentIDToIOR(const char *aLocalPersistentID); - int GetANewId(); std::map < int, SMESH_Algo * >_mapAlgo; @@ -143,9 +155,9 @@ class SMESH_EXPORT SMESH_Gen std::map < int, SMESH_2D_Algo * >_map2D_Algo; std::map < int, SMESH_3D_Algo * >_map3D_Algo; - private: +private: - int _localId; // unique Id of created objects, within SMESH_Gen entity + int _localId; // unique Id of created objects, within SMESH_Gen entity std::map < int, StudyContextStruct * >_mapStudyContext; // hypotheses managing @@ -156,6 +168,12 @@ class SMESH_EXPORT SMESH_Gen int _segmentation; // default of segments int _nbSegments; + counters *_counters; + +#ifdef WITH_SMESH_CANCEL_COMPUTE + volatile bool _compute_canceled; + SMESH_subMesh* _sm_current; +#endif }; #endif diff --git a/src/SMESH/SMESH_Group.cxx b/src/SMESH/SMESH_Group.cxx index a05204d31..7ef568593 100644 --- a/src/SMESH/SMESH_Group.cxx +++ b/src/SMESH/SMESH_Group.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Group.cxx // Author : Michael Sazonov (OCC) @@ -29,6 +30,7 @@ #include "SMESH_Mesh.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_GroupOnGeom.hxx" +#include "SMESHDS_GroupOnFilter.hxx" //============================================================================= /*! @@ -40,18 +42,36 @@ SMESH_Group::SMESH_Group (int theID, const SMESH_Mesh* theMesh, const SMDSAbs_ElementType theType, const char* theName, - const TopoDS_Shape& theShape) + const TopoDS_Shape& theShape, + const SMESH_PredicatePtr& thePredicate) : myName(theName) { - if ( theShape.IsNull() ) - myGroupDS = new SMESHDS_Group (theID, - const_cast(theMesh)->GetMeshDS(), - theType); - else + if ( !theShape.IsNull() ) myGroupDS = new SMESHDS_GroupOnGeom (theID, const_cast(theMesh)->GetMeshDS(), theType, theShape); + else if ( thePredicate ) + myGroupDS = new SMESHDS_GroupOnFilter (theID, + const_cast(theMesh)->GetMeshDS(), + theType, + thePredicate); + else + myGroupDS = new SMESHDS_Group (theID, + const_cast(theMesh)->GetMeshDS(), + theType); +} + +//================================================================================ +/*! + * \brief Constructor accesible to SMESH_Mesh only + */ +//================================================================================ + +SMESH_Group::SMESH_Group (SMESHDS_GroupBase* groupDS): myGroupDS( groupDS ) +{ + if ( myGroupDS ) + myName = myGroupDS->GetStoreName(); } //============================================================================= @@ -62,5 +82,5 @@ SMESH_Group::SMESH_Group (int theID, SMESH_Group::~SMESH_Group () { - delete myGroupDS; + delete myGroupDS; myGroupDS=0; } diff --git a/src/SMESH/SMESH_Group.hxx b/src/SMESH/SMESH_Group.hxx index ab3530827..f378be296 100644 --- a/src/SMESH/SMESH_Group.hxx +++ b/src/SMESH/SMESH_Group.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Group.hxx // Author : Michael Sazonov (OCC) // Module : SMESH -// $Header$ // #ifndef _SMESH_Group_HeaderFile #define _SMESH_Group_HeaderFile @@ -31,6 +31,7 @@ #include "SMESH_SMESH.hxx" #include "SMDSAbs_ElementType.hxx" +#include "SMESH_Controls.hxx" #include #include @@ -46,7 +47,9 @@ class SMESH_EXPORT SMESH_Group const SMESH_Mesh* theMesh, const SMDSAbs_ElementType theType, const char* theName, - const TopoDS_Shape& theShape = TopoDS_Shape()); + const TopoDS_Shape& theShape = TopoDS_Shape(), + const SMESH_PredicatePtr& thePredicate = SMESH_PredicatePtr()); + SMESH_Group (SMESHDS_GroupBase* groupDS); ~SMESH_Group (); void SetName (const char* theName) { myName = theName; } diff --git a/src/SMESH/SMESH_HypoFilter.cxx b/src/SMESH/SMESH_HypoFilter.cxx index d23f7cbe0..5552964bb 100644 --- a/src/SMESH/SMESH_HypoFilter.cxx +++ b/src/SMESH/SMESH_HypoFilter.cxx @@ -1,34 +1,38 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_HypoFilter.cxx // Module : SMESH -// $Header$ // #include "SMESH_HypoFilter.hxx" +#include "SMESH_Gen.hxx" #include "SMESH_Hypothesis.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" +#include + using namespace std; @@ -112,11 +116,39 @@ bool SMESH_HypoFilter::InstancePredicate::IsOk(const SMESH_Hypothesis* aHyp, //======================================================================= bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp, - const TopoDS_Shape& aShape) const + const TopoDS_Shape& aShape) const { return ( !_mainShape.IsNull() && !aShape.IsNull() && _mainShape.IsSame( aShape )); } +//================================================================================ +/*! + * \brief Finds shapes preferable over _shape due to sub-mesh order + */ +//================================================================================ + +void SMESH_HypoFilter::IsMoreLocalThanPredicate::findPreferable() +{ + const int shapeID = _mesh.GetMeshDS()->ShapeToIndex( _shape ); + const TListOfListOfInt& listOfShapeIDList = _mesh.GetMeshOrder(); + TListOfListOfInt::const_iterator listsIt = listOfShapeIDList.begin(); + for ( ; listsIt != listOfShapeIDList.end(); ++listsIt ) + { + const TListOfInt& idList = *listsIt; + TListOfInt::const_iterator idIt = + std::find( idList.begin(), idList.end(), shapeID ); + if ( idIt != idList.end() && *idIt != idList.front() ) + { + for ( ; idIt != idList.end(); --idIt ) + { + const TopoDS_Shape& shape = _mesh.GetMeshDS()->IndexToShape( *idIt ); + if ( !shape.IsNull()) + _preferableShapes.Add( shape ); + } + } + } +} + //======================================================================= //function : IsMoreLocalThanPredicate::IsOk //purpose : @@ -125,7 +157,26 @@ bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp, bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp, const TopoDS_Shape& aShape) const { - return ( aShape.ShapeType() > _shapeType ); + if ( aShape.IsSame( _mesh.GetShapeToMesh() )) + return false; // aHyp is global + + if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape )) + return true; + + if ( aShape.ShapeType() == TopAbs_COMPOUND && + !SMESH_MesherHelper::IsSubShape( _shape, /*mainShape=*/aShape)) // issue 0020963 + { + for ( int type = TopAbs_SOLID; type < TopAbs_SHAPE; ++type ) + if ( aHyp->GetDim() == SMESH_Gen::GetShapeDim( TopAbs_ShapeEnum( type ))) + for ( TopExp_Explorer exp( aShape, TopAbs_ShapeEnum( type )); exp.More(); exp.Next()) + if ( SMESH_MesherHelper::IsSubShape( exp.Current(), /*mainShape=*/_shape )) + return true; + } + + if ( _preferableShapes.Contains( aShape )) + return true; // issue 21559, Mesh_6 + + return false; } //======================================================================= @@ -277,9 +328,10 @@ SMESH_HypoPredicate* SMESH_HypoFilter::IsApplicableTo(const TopoDS_Shape& theSha //purpose : //======================================================================= -SMESH_HypoPredicate* SMESH_HypoFilter::IsMoreLocalThan(const TopoDS_Shape& theShape) +SMESH_HypoPredicate* SMESH_HypoFilter::IsMoreLocalThan(const TopoDS_Shape& theShape, + const SMESH_Mesh& theMesh) { - return new IsMoreLocalThanPredicate( theShape ); + return new IsMoreLocalThanPredicate( theShape, theMesh ); } //======================================================================= @@ -346,3 +398,5 @@ SMESH_HypoFilter::~SMESH_HypoFilter() Init(0); } + + diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx index c7aa1ed82..b4ace7d2a 100644 --- a/src/SMESH/SMESH_HypoFilter.hxx +++ b/src/SMESH/SMESH_HypoFilter.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_HypoFilter.hxx // Module : SMESH -// $Header$ // #ifndef SMESH_HypoFilter_HeaderFile #define SMESH_HypoFilter_HeaderFile @@ -36,9 +36,11 @@ #include #include #include +#include class SMESH_HypoFilter; class SMESH_Hypothesis; +class SMESH_Mesh; class SMESH_EXPORT SMESH_HypoPredicate { public: @@ -72,11 +74,14 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape); static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo); static SMESH_HypoPredicate* IsGlobal(const TopoDS_Shape& theMainShape); - static SMESH_HypoPredicate* IsMoreLocalThan(const TopoDS_Shape& theShape); + static SMESH_HypoPredicate* IsMoreLocalThan(const TopoDS_Shape& theShape, + const SMESH_Mesh& theMesh); static SMESH_HypoPredicate* HasName(const std::string & theName); static SMESH_HypoPredicate* HasDim(const int theDim); static SMESH_HypoPredicate* HasType(const int theHypType); + bool IsEmpty() const { return myPredicates.empty(); } + /*! * \brief check aHyp or/and aShape it is assigned to */ @@ -167,10 +172,15 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate }; struct IsMoreLocalThanPredicate : public SMESH_HypoPredicate { - TopAbs_ShapeEnum _shapeType; - IsMoreLocalThanPredicate( const TopoDS_Shape& shape ):_shapeType(shape.ShapeType()){} + TopoDS_Shape _shape; + const SMESH_Mesh& _mesh; + TopTools_MapOfShape _preferableShapes; + IsMoreLocalThanPredicate( const TopoDS_Shape& shape, + const SMESH_Mesh& mesh ) + :_shape(shape),_mesh(mesh) { findPreferable(); } bool IsOk(const SMESH_Hypothesis* aHyp, const TopoDS_Shape& aShape) const; + void findPreferable(); }; struct IsAuxiliaryPredicate : public SMESH_HypoPredicate { diff --git a/src/SMESH/SMESH_Hypothesis.cxx b/src/SMESH/SMESH_Hypothesis.cxx index 4b288a0d9..fee310f27 100644 --- a/src/SMESH/SMESH_Hypothesis.cxx +++ b/src/SMESH/SMESH_Hypothesis.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Hypothesis.cxx // Author : Paul RASCLE, EDF @@ -39,8 +40,8 @@ using namespace std; //============================================================================= SMESH_Hypothesis::SMESH_Hypothesis(int hypId, - int studyId, - SMESH_Gen* gen) : SMESHDS_Hypothesis(hypId) + int studyId, + SMESH_Gen* gen) : SMESHDS_Hypothesis(hypId) { //MESSAGE("SMESH_Hypothesis::SMESH_Hypothesis"); _gen = gen; @@ -51,6 +52,8 @@ SMESH_Hypothesis::SMESH_Hypothesis(int hypId, _shapeType = 0; // to be set by algo with TopAbs_Enum _param_algo_dim = -1; // to be set by algo parameter _parameters = string(); + _lastParameters = string(); + _libName = string(); } //============================================================================= @@ -151,6 +154,24 @@ void SMESH_Hypothesis::SetLibName(const char* theLibName) _libName = string(theLibName); } +//======================================================================= +//function : GetMeshByPersistentID +//purpose : Find a mesh with given persistent ID +//======================================================================= + +SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id) +{ + StudyContextStruct* myStudyContext = _gen->GetStudyContext(_studyId); + map::iterator itm = itm = myStudyContext->mapMesh.begin(); + for ( ; itm != myStudyContext->mapMesh.end(); itm++) + { + SMESH_Mesh* mesh = (*itm).second; + if ( mesh->GetMeshDS()->GetPersistentId() == id ) + return mesh; + } + return 0; +} + //============================================================================= /*! * diff --git a/src/SMESH/SMESH_Hypothesis.hxx b/src/SMESH/SMESH_Hypothesis.hxx index 55ed9dd5f..0c81caac7 100644 --- a/src/SMESH/SMESH_Hypothesis.hxx +++ b/src/SMESH/SMESH_Hypothesis.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_Hypothesis.hxx // Author : Paul RASCLE, EDF // Module : SMESH // - #ifndef _SMESH_HYPOTHESIS_HXX_ #define _SMESH_HYPOTHESIS_HXX_ @@ -61,7 +61,7 @@ public: HYP_NOTCONFORM, // not conform mesh is produced appling a hypothesis HYP_ALREADY_EXIST,// such hypothesis already exist HYP_BAD_DIM, // bad dimension - HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its subshape, nor a group + HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group HYP_BAD_GEOMETRY, // shape geometry mismatches algorithm's expectation HYP_NEED_SHAPE // algorithm can work on shape only }; @@ -94,8 +94,9 @@ public: struct TDefaults { - double _elemLength; - int _nbSegments; + double _elemLength; + int _nbSegments; + TopoDS_Shape* _shape; // future shape of the mesh being created }; /*! * \brief Initialize my parameter values by default parameters. @@ -114,11 +115,16 @@ public: virtual bool IsAuxiliary() const { return GetType() == PARAM_ALGO && _param_algo_dim < 0; } + /*! + * \brief Find a mesh with given persistent ID + */ + SMESH_Mesh* GetMeshByPersistentID(int id); + protected: SMESH_Gen* _gen; int _studyId; int _shapeType; - int _param_algo_dim; + int _param_algo_dim; // to be set at descendant hypothesis constructor private: std::string _libName; diff --git a/src/SMESH/SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx b/src/SMESH/SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx deleted file mode 100644 index 7daa8b4bc..000000000 --- a/src/SMESH/SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File: SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx -// Created: 20.09.05 09:51:12 -// Author: Sergey KUUL -// -#ifndef SMESH_IndexedMapOfShape_HeaderFile -#define SMESH_IndexedMapOfShape_HeaderFile - -#include "SMESH_SMESH.hxx" - -#include "SMESHDS_DataMapOfShape.hxx" - -#include - -#include - -/// Class SMESH_IndexedMapOfShape - -DEFINE_BASECOLLECTION (SMESH_BaseCollectionShape, TopoDS_Shape) -DEFINE_INDEXEDMAP (SMESH_IndexedMapOfShape, SMESH_BaseCollectionShape, TopoDS_Shape) - -#endif - -#ifndef SMESH_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile -#define SMESH_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile - -#include - -/// Class SMESH_IndexedDataMapOfShapeIndexedMapOfShape - -DEFINE_BASECOLLECTION (SMESH_BaseCollectionIndexedMapOfShape, SMESH_IndexedMapOfShape) -DEFINE_INDEXEDDATAMAP (SMESH_IndexedDataMapOfShapeIndexedMapOfShape, - SMESH_BaseCollectionIndexedMapOfShape, TopoDS_Shape, - SMESH_IndexedMapOfShape) -#endif diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 866fda739..1057d3dee 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -1,30 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : SMESH_Mesh.cxx // Author : Paul RASCLE, EDF // Module : SMESH // #include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Hypothesis.hxx" @@ -47,6 +48,10 @@ #include "DriverMED_R_SMESHDS_Mesh.h" #include "DriverUNV_R_SMDS_Mesh.h" #include "DriverSTL_R_SMDS_Mesh.h" +#ifdef WITH_CGNS +#include "DriverCGNS_Read.hxx" +#include "DriverCGNS_Write.hxx" +#endif #undef _Precision_HeaderFile #include @@ -61,6 +66,11 @@ #include "Utils_ExceptHandlers.hxx" +#include +#include + +using namespace std; + // maximum stored group name length in MED file #define MAX_MED_GROUP_NAME_LENGTH 80 @@ -81,11 +91,11 @@ typedef SMESH_HypoFilter THypType; //============================================================================= SMESH_Mesh::SMESH_Mesh(int theLocalId, - int theStudyId, - SMESH_Gen* theGen, - bool theIsEmbeddedMode, - SMESHDS_Document* theDocument): - _groupId( 0 ) + int theStudyId, + SMESH_Gen* theGen, + bool theIsEmbeddedMode, + SMESHDS_Document* theDocument): + _groupId( 0 ), _nbSubShapes( 0 ) { MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)"); _id = theLocalId; @@ -96,10 +106,44 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, _myMeshDS = theDocument->GetMesh(_idDoc); _isShapeToMesh = false; _isAutoColor = false; + _isModified = false; _shapeDiagonal = 0.0; + _callUp = 0; _myMeshDS->ShapeToMesh( PseudoShape() ); } +//================================================================================ +/*! + * \brief Constructor of SMESH_Mesh being a base of some descendant class + */ +//================================================================================ + +SMESH_Mesh::SMESH_Mesh(): + _id(-1), + _studyId(-1), + _idDoc(-1), + _groupId( 0 ), + _nbSubShapes( 0 ), + _isShapeToMesh( false ), + _myDocument( 0 ), + _myMeshDS( 0 ), + _gen( 0 ), + _isAutoColor( false ), + _isModified( false ), + _shapeDiagonal( 0.0 ), + _callUp( 0 ) +{ +} + +namespace +{ + void deleteMeshDS(SMESHDS_Mesh* meshDS) + { + //cout << "deleteMeshDS( " << meshDS << endl; + delete meshDS; + } +} + //============================================================================= /*! * @@ -108,15 +152,57 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, SMESH_Mesh::~SMESH_Mesh() { - INFOS("SMESH_Mesh::~SMESH_Mesh"); + MESSAGE("SMESH_Mesh::~SMESH_Mesh"); + + // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study + // Notify event listeners at least that something happens + if ( SMESH_subMesh * sm = GetSubMeshContaining(1)) + sm->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); // delete groups - std::map < int, SMESH_Group * >::iterator itg; + map < int, SMESH_Group * >::iterator itg; for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) { SMESH_Group *aGroup = (*itg).second; delete aGroup; } _mapGroup.clear(); + + // delete sub-meshes + map ::iterator sm = _mapSubMesh.begin(); + for ( ; sm != _mapSubMesh.end(); ++sm ) + { + delete sm->second; + sm->second = 0; + } + _mapSubMesh.clear(); + + if ( _callUp) delete _callUp; + _callUp = 0; + + // remove self from studyContext + if ( _gen ) + { + StudyContextStruct * studyContext = _gen->GetStudyContext( _studyId ); + studyContext->mapMesh.erase( _id ); + } + if ( _myDocument ) + _myDocument->RemoveMesh( _id ); + _myDocument = 0; + + if ( _myMeshDS ) + // delete _myMeshDS, in a thread in order not to block closing a study with large meshes + boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS )); +} + +//================================================================================ +/*! + * \brief Return true if a mesh with given id exists + */ +//================================================================================ + +bool SMESH_Mesh::MeshExists( int meshId ) const +{ + return _myDocument ? _myDocument->GetMesh( meshId ) : false; } //============================================================================= @@ -129,20 +215,22 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) { if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh"); - if ( !aShape.IsNull() && _isShapeToMesh ) - throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined")); - + if ( !aShape.IsNull() && _isShapeToMesh ) { + if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change + _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND ) + 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 - std::map ::iterator i_sm = _mapSubMesh.begin(); + map ::iterator i_sm = _mapSubMesh.begin(); for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) delete i_sm->second; _mapSubMesh.clear(); // - groups on geometry - std::map ::iterator i_gr = _mapGroup.begin(); + map ::iterator i_gr = _mapGroup.begin(); while ( i_gr != _mapGroup.end() ) { if ( dynamic_cast( i_gr->second->GetGroupDS() )) { _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() ); @@ -166,16 +254,18 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape) { _myMeshDS->ShapeToMesh(aShape); _isShapeToMesh = true; + _nbSubShapes = _myMeshDS->MaxShapeIndex(); - // 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 ); + // fill map of ancestors + fillAncestorsMap(aShape); } + else + { + _isShapeToMesh = false; + _shapeDiagonal = 0.0; + _myMeshDS->ShapeToMesh( PseudoShape() ); + } + _isModified = false; } //======================================================================= @@ -236,6 +326,18 @@ double SMESH_Mesh::GetShapeDiagonalSize() const return _shapeDiagonal; } +//================================================================================ +/*! + * \brief Load mesh from study file + */ +//================================================================================ + +void SMESH_Mesh::Load() +{ + if (_callUp) + _callUp->Load(); +} + //======================================================================= /*! * \brief Remove all nodes and elements @@ -248,55 +350,14 @@ void SMESH_Mesh::Clear() _myMeshDS->ClearMesh(); // update compute state of submeshes - if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) { - SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, - /*complexShapeFirst=*/false); - while ( smIt->more() ) { - sm = smIt->next(); - sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - } + if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) + { + sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918) + sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN ); } - -// // clear sub-meshes; get ready to re-compute as a side-effect - -// if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) -// { -// SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, -// /*complexShapeFirst=*/false); -// while ( smIt->more() ) -// { -// sm = smIt->next(); -// TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); -// if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID ) -// // all other shapes depends on vertices so they are already cleaned -// sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); -// // to recompute even if failed -// sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); -// } -// } - -// // clear entities not on sub-meshes - -// SMDS_VolumeIteratorPtr vIt = _myMeshDS->volumesIterator(); -// while ( vIt->more() ) -// _myMeshDS->RemoveFreeElement( vIt->next(), 0 ); - -// SMDS_FaceIteratorPtr fIt = _myMeshDS->facesIterator(); -// while ( fIt->more() ) -// _myMeshDS->RemoveFreeElement( fIt->next(), 0 ); - -// SMDS_EdgeIteratorPtr eIt = _myMeshDS->edgesIterator(); -// while ( eIt->more() ) -// _myMeshDS->RemoveFreeElement( eIt->next(), 0 ); - -// SMDS_NodeIteratorPtr nIt = _myMeshDS->nodesIterator(); -// while ( nIt->more() ) { -// const SMDS_MeshNode * node = nIt->next(); -// if ( node->NbInverseElements() == 0 ) -// _myMeshDS->RemoveFreeNode( node, 0 ); -// else -// _myMeshDS->RemoveNode(node); -// } + _isModified = false; } //======================================================================= @@ -311,14 +372,14 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId) if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) ) { SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, - /*complexShapeFirst=*/false); + /*complexShapeFirst=*/false); while ( smIt->more() ) { sm = smIt->next(); TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID ) - // all other shapes depends on vertices so they are already cleaned - sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + // all other shapes depends on vertices so they are already cleaned + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // to recompute even if failed sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } @@ -354,26 +415,26 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName) aGroup->InitSubGroupsIterator(); while (aGroup->MoreSubGroups()) { SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup(); - std::string aName = aGroupNames[aSubGroup]; + string aName = aGroupNames[aSubGroup]; int aId; SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId ); if ( aSMESHGroup ) { - if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<( aSMESHGroup->GetGroupDS() ); - if ( aGroupDS ) { - aGroupDS->SetStoreName(aName.c_str()); - aSubGroup->InitIterator(); - const SMDS_MeshElement* aElement = 0; - while (aSubGroup->More()) { - aElement = aSubGroup->Next(); - if (aElement) { - aGroupDS->SMDSGroup().Add(aElement); - } - } - if (aElement) - aGroupDS->SetType(aElement->GetType()); - } + if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<( aSMESHGroup->GetGroupDS() ); + if ( aGroupDS ) { + aGroupDS->SetStoreName(aName.c_str()); + aSubGroup->InitIterator(); + const SMDS_MeshElement* aElement = 0; + while (aSubGroup->More()) { + aElement = aSubGroup->Next(); + if (aElement) { + aGroupDS->SMDSGroup().Add(aElement); + } + } + if (aElement) + aGroupDS->SetType(aElement->GetType()); + } } } } @@ -405,10 +466,10 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName) } // Reading groups (sub-meshes are out of scope of MED import functionality) - std::list aGroupNames = myReader.GetGroupNamesAndTypes(); + list aGroupNames = myReader.GetGroupNamesAndTypes(); if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<::iterator name_type = aGroupNames.begin(); + list::iterator name_type = aGroupNames.begin(); for ( ; name_type != aGroupNames.end(); name_type++ ) { SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId ); if ( aGroup ) { @@ -448,6 +509,35 @@ int SMESH_Mesh::STLToMesh(const char* theFileName) return 1; } +//================================================================================ +/*! + * \brief Reads the given mesh from the CGNS file + * \param theFileName - name of the file + * \retval int - Driver_Mesh::Status + */ +//================================================================================ + +int SMESH_Mesh::CGNSToMesh(const char* theFileName, + const int theMeshIndex, + std::string& theMeshName) +{ + int res = Driver_Mesh::DRS_FAIL; +#ifdef WITH_CGNS + + DriverCGNS_Read myReader; + myReader.SetMesh(_myMeshDS); + myReader.SetFile(theFileName); + myReader.SetMeshId(theMeshIndex); + res = myReader.Perform(); + theMeshName = myReader.GetMeshName(); + + // create groups + SynchronizeGroups(); + +#endif + return res; +} + //============================================================================= /*! * @@ -465,33 +555,6 @@ SMESH_Hypothesis::Hypothesis_Status if ( !subMesh || !subMesh->GetId()) return SMESH_Hypothesis::HYP_BAD_SUBSHAPE; - SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); - if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub- - { - MESSAGE("AddHypothesis() to complex submesh"); - // return the worst but not fatal state of all group memebers - SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret; - aBestRet = SMESH_Hypothesis::HYP_BAD_DIM; - aWorstNotFatal = SMESH_Hypothesis::HYP_OK; - for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next()) - { - if ( !GetMeshDS()->ShapeToIndex( itS.Value() )) - continue; // not sub-shape - ret = AddHypothesis( itS.Value(), anHypId ); - if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal ) - aWorstNotFatal = ret; - if ( ret < aBestRet ) - aBestRet = ret; - } - // bind hypotheses to a group just to know - SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId]; - GetMeshDS()->AddHypothesis( aSubShape, anHyp ); - - if ( SMESH_Hypothesis::IsStatusFatal( aBestRet )) - return aBestRet; - return aWorstNotFatal; - } - StudyContextStruct *sc = _gen->GetStudyContext(_studyId); if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end()) { @@ -511,6 +574,9 @@ SMESH_Hypothesis::Hypothesis_Status // NotConformAllowed can be only global if ( !isGlobalHyp ) { + // NOTE: this is not a correct way to check a name of hypothesis, + // there should be an attribute of hypothesis saying that it can/can't + // be global/local string hypName = anHyp->GetName(); if ( hypName == "NotConformAllowed" ) { @@ -526,7 +592,7 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp); - // subShapes + // sub-shapes if (!SMESH_Hypothesis::IsStatusFatal(ret) && anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father { @@ -537,7 +603,7 @@ SMESH_Hypothesis::Hypothesis_Status if (ret2 > ret) ret = ret2; - // check concurent hypotheses on ansestors + // check concurent hypotheses on ancestors if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp ) { SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); @@ -553,9 +619,12 @@ SMESH_Hypothesis::Hypothesis_Status } } } + HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty + + GetMeshDS()->Modified(); if(MYDEBUG) subMesh->DumpAlgoState(true); - SCRUTE(ret); + if(MYDEBUG) SCRUTE(ret); return ret; } @@ -572,45 +641,23 @@ SMESH_Hypothesis::Hypothesis_Status Unexpect aCatch(SalomeException); if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis"); - SMESH_subMesh *subMesh = GetSubMesh(aSubShape); - SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); - if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) - { - // return the worst but not fatal state of all group memebers - SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret; - aBestRet = SMESH_Hypothesis::HYP_BAD_DIM; - aWorstNotFatal = SMESH_Hypothesis::HYP_OK; - for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next()) - { - if ( !GetMeshDS()->ShapeToIndex( itS.Value() )) - continue; // not sub-shape - ret = RemoveHypothesis( itS.Value(), anHypId ); - if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal ) - aWorstNotFatal = ret; - if ( ret < aBestRet ) - aBestRet = ret; - } - SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId]; - GetMeshDS()->RemoveHypothesis( aSubShape, anHyp ); - - if ( SMESH_Hypothesis::IsStatusFatal( aBestRet )) - return aBestRet; - return aWorstNotFatal; - } - StudyContextStruct *sc = _gen->GetStudyContext(_studyId); if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end()) throw SALOME_Exception(LOCALIZED("hypothesis does not exist")); SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId]; - int hypType = anHyp->GetType(); - if(MYDEBUG) SCRUTE(hypType); + if(MYDEBUG) { + int hypType = anHyp->GetType(); + SCRUTE(hypType); + } // shape bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ); int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP; + SMESH_subMesh *subMesh = GetSubMesh(aSubShape); + SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp); // there may appear concurrent hyps that were covered by the removed hyp @@ -619,7 +666,7 @@ SMESH_Hypothesis::Hypothesis_Status subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK) ret = SMESH_Hypothesis::HYP_CONCURENT; - // subShapes + // sub-shapes if (!SMESH_Hypothesis::IsStatusFatal(ret) && anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father { @@ -630,7 +677,7 @@ SMESH_Hypothesis::Hypothesis_Status if (ret2 > ret) // more severe ret = ret2; - // check concurent hypotheses on ansestors + // check concurent hypotheses on ancestors if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) ) { SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); @@ -646,7 +693,11 @@ SMESH_Hypothesis::Hypothesis_Status } } } - + + HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty + + GetMeshDS()->Modified(); + if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); return ret; @@ -658,7 +709,7 @@ SMESH_Hypothesis::Hypothesis_Status */ //============================================================================= -const std::list& +const list& SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const throw(SALOME_Exception) { @@ -683,8 +734,8 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubS TopoDS_Shape* assignedTo) const { { - const std::list& hypList = _myMeshDS->GetHypothesis(aSubShape); - std::list::const_iterator hyp = hypList.begin(); + const list& hypList = _myMeshDS->GetHypothesis(aSubShape); + list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); if ( aFilter.IsOk( h, aSubShape)) { @@ -695,15 +746,18 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape & aSubS } if ( andAncestors ) { - TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - for (; it.More(); it.Next() ) + // user sorted submeshes of ancestors, according to stored submesh priority + const list smList = getAncestorsSubMeshes( aSubShape ); + list::const_iterator smIt = smList.begin(); + for ( ; smIt != smList.end(); smIt++ ) { - const std::list& hypList = _myMeshDS->GetHypothesis(it.Value()); - std::list::const_iterator hyp = hypList.begin(); + const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); + const list& hypList = _myMeshDS->GetHypothesis(curSh); + list::const_iterator hyp = hypList.begin(); for ( ; hyp != hypList.end(); hyp++ ) { const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp ); - if (aFilter.IsOk( h, it.Value() )) { - if ( assignedTo ) *assignedTo = it.Value(); + if (aFilter.IsOk( h, curSh )) { + if ( assignedTo ) *assignedTo = curSh; return h; } } @@ -735,7 +789,7 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, bool mainHypFound = false; // fill in hypTypes - std::list::const_iterator hyp; + list::const_iterator hyp; for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) { if ( hypTypes.insert( (*hyp)->GetName() ).second ) nbHyps++; @@ -745,7 +799,7 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, // get hypos from aSubShape { - const std::list& hypList = _myMeshDS->GetHypothesis(aSubShape); + const list& hypList = _myMeshDS->GetHypothesis(aSubShape); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) && ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) && @@ -762,14 +816,18 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, if ( andAncestors ) { TopTools_MapOfShape map; - TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape )); - for (; it.More(); it.Next() ) + + // user sorted submeshes of ancestors, according to stored submesh priority + const list smList = getAncestorsSubMeshes( aSubShape ); + list::const_iterator smIt = smList.begin(); + for ( ; smIt != smList.end(); smIt++ ) { - if ( !map.Add( it.Value() )) + const TopoDS_Shape& curSh = (*smIt)->GetSubShape(); + if ( !map.Add( curSh )) continue; - const std::list& hypList = _myMeshDS->GetHypothesis(it.Value()); + const list& hypList = _myMeshDS->GetHypothesis(curSh); for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ ) - if (aFilter.IsOk( cSMESH_Hyp( *hyp ), it.Value() ) && + if (aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh ) && ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) && hypTypes.insert( (*hyp)->GetName() ).second ) { @@ -789,7 +847,7 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape & aSubShape, */ //============================================================================= -const std::list & SMESH_Mesh::GetLog() throw(SALOME_Exception) +const list & SMESH_Mesh::GetLog() throw(SALOME_Exception) { Unexpect aCatch(SalomeException); if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog"); @@ -822,10 +880,16 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape) int index = _myMeshDS->ShapeToIndex(aSubShape); // for submeshes on GEOM Group - if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) { + if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) { TopoDS_Iterator it( aSubShape ); if ( it.More() ) + { index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() ); + if ( index > _nbSubShapes ) _nbSubShapes = index; // not to create sm for this group again + + // fill map of Ancestors + fillAncestorsMap(aSubShape); + } } // if ( !index ) // return NULL; // neither sub-shape nor a group @@ -883,37 +947,47 @@ throw(SALOME_Exception) } //================================================================================ /*! - * \brief Return submeshes of groups containing the given subshape + * \brief Return submeshes of groups containing the given sub-shape */ //================================================================================ -std::list +list SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); - std::list found; + list found; SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape); if ( !subMesh ) return found; // submeshes of groups have max IDs, so search from the map end - std::map::const_reverse_iterator i_sm; + map::const_reverse_iterator i_sm; for ( i_sm = _mapSubMesh.rbegin(); i_sm != _mapSubMesh.rend(); ++i_sm) { SMESHDS_SubMesh * ds = i_sm->second->GetSubMeshDS(); if ( ds && ds->IsComplexSubmesh() ) { - TopExp_Explorer exp( i_sm->second->GetSubShape(), aSubShape.ShapeType() ); - for ( ; exp.More(); exp.Next() ) { - if ( aSubShape.IsSame( exp.Current() )) { - found.push_back( i_sm->second ); - break; - } + if ( SMESH_MesherHelper::IsSubShape( aSubShape, i_sm->second->GetSubShape() )) + { + found.push_back( i_sm->second ); + //break; } } else { - break; + break; // the rest sub-meshes are not those of groups } } + + if ( found.empty() ) // maybe the main shape is a COMPOUND (issue 0021530) + { + if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1)) + if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND ) + { + TopoDS_Iterator it( mainSM->GetSubShape() ); + if ( it.Value().ShapeType() == aSubShape.ShapeType() && + SMESH_MesherHelper::IsSubShape( aSubShape, mainSM->GetSubShape() )) + found.push_back( mainSM ); + } + } return found; } //======================================================================= @@ -987,6 +1061,12 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h { Unexpect aCatch(SalomeException); + if ( !GetMeshDS()->IsUsedHypothesis( hyp )) + return; + + if (_callUp) + _callUp->HypothesisModified(); + const SMESH_Algo *foundAlgo = 0; SMESH_HypoFilter algoKind, compatibleHypoKind; list usedHyps; @@ -1029,6 +1109,8 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h } } } + HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty + GetMeshDS()->Modified(); } //============================================================================= @@ -1048,37 +1130,98 @@ bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception) return _isAutoColor; } -//============================================================================= -/*! Export* methods. - * To store mesh contents on disk in different formats. +//======================================================================= +//function : SetIsModified +//purpose : Set the flag meaning that the mesh has been edited "manually" +//======================================================================= + +void SMESH_Mesh::SetIsModified(bool isModified) +{ + _isModified = isModified; + + if ( _isModified ) + // check if mesh becomes empty as result of modification + HasModificationsToDiscard(); +} + +//======================================================================= +//function : HasModificationsToDiscard +//purpose : Return true if the mesh has been edited since a total re-compute +// and those modifications may prevent successful partial re-compute. +// As a side effect reset _isModified flag if mesh is empty +//issue : 0020693 +//======================================================================= + +bool SMESH_Mesh::HasModificationsToDiscard() const +{ + if ( ! _isModified ) + return false; + + // return true if the next Compute() will be partial and + // existing but changed elements may prevent successful re-compute + bool hasComputed = false, hasNotComputed = false; + map ::const_iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end() ; ++i_sm ) + switch ( i_sm->second->GetSubShape().ShapeType() ) + { + case TopAbs_EDGE: + case TopAbs_FACE: + case TopAbs_SOLID: + if ( i_sm->second->IsMeshComputed() ) + hasComputed = true; + else + hasNotComputed = true; + if ( hasComputed && hasNotComputed) + return true; + } + + if ( NbNodes() < 1 ) + const_cast(this)->_isModified = false; + + return false; +} + +//================================================================================ +/*! + * \brief Check if any groups of the same type have equal names */ -//============================================================================= +//================================================================================ bool SMESH_Mesh::HasDuplicatedGroupNamesMED() { - set aGroupNames; - for ( std::map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + //set aGroupNames; // Corrected for Mantis issue 0020028 + map< SMDSAbs_ElementType, set > aGroupNames; + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) + { SMESH_Group* aGroup = it->second; - std::string aGroupName = aGroup->GetName(); + SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType(); + string aGroupName = aGroup->GetName(); aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); - if (!aGroupNames.insert(aGroupName).second) + if (!aGroupNames[aType].insert(aGroupName).second) return true; } return false; } -void SMESH_Mesh::ExportMED(const char *file, - const char* theMeshName, - bool theAutoGroups, - int theVersion) +//================================================================================ +/*! + * \brief Export the mesh to a med file + */ +//================================================================================ + +void SMESH_Mesh::ExportMED(const char * file, + const char* theMeshName, + bool theAutoGroups, + int theVersion, + const SMESHDS_Mesh* meshPart) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); DriverMED_W_SMESHDS_Mesh myWriter; myWriter.SetFile ( file, MED::EVersion(theVersion) ); - myWriter.SetMesh ( _myMeshDS ); + myWriter.SetMesh ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); if ( !theMeshName ) myWriter.SetMeshId ( _idDoc ); else { @@ -1094,79 +1237,167 @@ void SMESH_Mesh::ExportMED(const char *file, } // Pass groups to writer. Provide unique group names. - set aGroupNames; - char aString [256]; - int maxNbIter = 10000; // to guarantee cycle finish - for ( std::map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { - SMESH_Group* aGroup = it->second; - SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); - if ( aGroupDS ) { - string aGroupName0 = aGroup->GetName(); - aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH); - string aGroupName = aGroupName0; - for (int i = 1; !aGroupNames.insert(aGroupName).second && i < maxNbIter; i++) { - sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str()); - aGroupName = aString; - aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); + //set aGroupNames; // Corrected for Mantis issue 0020028 + if ( !meshPart ) + { + map< SMDSAbs_ElementType, set > aGroupNames; + char aString [256]; + int maxNbIter = 10000; // to guarantee cycle finish + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + SMESH_Group* aGroup = it->second; + SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); + if ( aGroupDS ) { + SMDSAbs_ElementType aType = aGroupDS->GetType(); + string aGroupName0 = aGroup->GetName(); + aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH); + string aGroupName = aGroupName0; + for (int i = 1; !aGroupNames[aType].insert(aGroupName).second && i < maxNbIter; i++) { + sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str()); + aGroupName = aString; + aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH); + } + aGroupDS->SetStoreName( aGroupName.c_str() ); + myWriter.AddGroup( aGroupDS ); } - aGroupDS->SetStoreName( aGroupName.c_str() ); - myWriter.AddGroup( aGroupDS ); } } - // Perform export myWriter.Perform(); } -void SMESH_Mesh::ExportDAT(const char *file) throw(SALOME_Exception) +void SMESH_Mesh::ExportSAUV(const char *file, + const char* theMeshName, + bool theAutoGroups) + throw(SALOME_Exception) +{ + std::string medfilename(file); + medfilename += ".med"; + std::string cmd; +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; + cmd += "\""; + system(cmd.c_str()); + ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1); +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')"; + cmd += "\""; + system(cmd.c_str()); +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; + cmd += "\""; + system(cmd.c_str()); +} + +//================================================================================ +/*! + * \brief Export the mesh to a DAT file + */ +//================================================================================ + +void SMESH_Mesh::ExportDAT(const char * file, + const SMESHDS_Mesh* meshPart) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); DriverDAT_W_SMDS_Mesh myWriter; - myWriter.SetFile(string(file)); - myWriter.SetMesh(_myMeshDS); + myWriter.SetFile( file ); + myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); myWriter.SetMeshId(_idDoc); myWriter.Perform(); } -void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Export the mesh to an UNV file + */ +//================================================================================ + +void SMESH_Mesh::ExportUNV(const char * file, + const SMESHDS_Mesh* meshPart) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); DriverUNV_W_SMDS_Mesh myWriter; - myWriter.SetFile(string(file)); - myWriter.SetMesh(_myMeshDS); + myWriter.SetFile( file ); + myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS ); myWriter.SetMeshId(_idDoc); // myWriter.SetGroups(_mapGroup); - for ( std::map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { - SMESH_Group* aGroup = it->second; - SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); - if ( aGroupDS ) { - std::string aGroupName = aGroup->GetName(); - aGroupDS->SetStoreName( aGroupName.c_str() ); - myWriter.AddGroup( aGroupDS ); + if ( !meshPart ) + { + for ( map::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) { + SMESH_Group* aGroup = it->second; + SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS(); + if ( aGroupDS ) { + string aGroupName = aGroup->GetName(); + aGroupDS->SetStoreName( aGroupName.c_str() ); + myWriter.AddGroup( aGroupDS ); + } } } myWriter.Perform(); } -void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception) +//================================================================================ +/*! + * \brief Export the mesh to an STL file + */ +//================================================================================ + +void SMESH_Mesh::ExportSTL(const char * file, + const bool isascii, + const SMESHDS_Mesh* meshPart) throw(SALOME_Exception) { Unexpect aCatch(SalomeException); DriverSTL_W_SMDS_Mesh myWriter; - myWriter.SetFile(string(file)); + myWriter.SetFile( file ); myWriter.SetIsAscii( isascii ); - myWriter.SetMesh(_myMeshDS); + myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS); myWriter.SetMeshId(_idDoc); myWriter.Perform(); } +//================================================================================ +/*! + * \brief Export the mesh to the CGNS file + */ +//================================================================================ + +void SMESH_Mesh::ExportCGNS(const char * file, + const SMESHDS_Mesh* meshDS) +{ + int res = Driver_Mesh::DRS_FAIL; +#ifdef WITH_CGNS + DriverCGNS_Write myWriter; + myWriter.SetFile( file ); + myWriter.SetMesh( const_cast( meshDS )); + myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId()); + res = myWriter.Perform(); +#endif + if ( res != Driver_Mesh::DRS_OK ) + throw SALOME_Exception("Export failed"); +} + //================================================================================ /*! * \brief Return number of nodes in the mesh */ //================================================================================ -int SMESH_Mesh::NbNodes() throw(SALOME_Exception) +int SMESH_Mesh::NbNodes() const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->NbNodes(); @@ -1178,7 +1409,19 @@ int SMESH_Mesh::NbNodes() throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().Nb0DElements(); +} + +//================================================================================ +/*! + * \brief Return number of edges of given order in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbEdges(order); @@ -1190,7 +1433,7 @@ int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbFaces(order); @@ -1202,7 +1445,7 @@ int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbTriangles(order); @@ -1214,19 +1457,31 @@ int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbQuadrangles(order); } +//================================================================================ +/*! + * \brief Return number of biquadratic quadrangles in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles(); +} + //================================================================================ /*! * \brief Return the number of polygonal faces in the mesh */ //================================================================================ -int SMESH_Mesh::NbPolygons() throw(SALOME_Exception) +int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbPolygons(); @@ -1238,7 +1493,7 @@ int SMESH_Mesh::NbPolygons() throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbVolumes(order); @@ -1250,7 +1505,7 @@ int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbTetras(order); @@ -1262,19 +1517,31 @@ int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbHexas(order); } +//================================================================================ +/*! + * \brief Return number of triquadratic hexahedrons in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbTriQuadHexas(); +} + //================================================================================ /*! * \brief Return number of pyramids of given order in the mesh */ //================================================================================ -int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbPyramids(order); @@ -1286,31 +1553,55 @@ int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) throw(SALOME_Exception) */ //================================================================================ -int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) throw(SALOME_Exception) +int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbPrisms(order); } +//================================================================================ +/*! + * \brief Return number of hexagonal prisms in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbHexPrisms(); +} + //================================================================================ /*! * \brief Return number of polyhedrons in the mesh */ //================================================================================ -int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception) +int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->GetMeshInfo().NbPolyhedrons(); } +//================================================================================ +/*! + * \brief Return number of ball elements in the mesh + */ +//================================================================================ + +int SMESH_Mesh::NbBalls() const throw(SALOME_Exception) +{ + Unexpect aCatch(SalomeException); + return _myMeshDS->GetMeshInfo().NbBalls(); +} + //================================================================================ /*! * \brief Return number of submeshes in the mesh */ //================================================================================ -int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception) +int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception) { Unexpect aCatch(SalomeException); return _myMeshDS->NbSubMesh(); @@ -1347,18 +1638,45 @@ bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType, const char* theName, - int& theId, - const TopoDS_Shape& theShape) + int& theId, + const TopoDS_Shape& theShape, + const SMESH_PredicatePtr& thePredicate) { - if (_mapGroup.find(_groupId) != _mapGroup.end()) + if (_mapGroup.count(_groupId)) return NULL; theId = _groupId; - SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape); + SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape, thePredicate); GetMeshDS()->AddGroup( aGroup->GetGroupDS() ); _mapGroup[_groupId++] = aGroup; return aGroup; } +//================================================================================ +/*! + * \brief Creates SMESH_Groups for not wrapped SMESHDS_Groups + * \retval bool - true if new SMESH_Groups have been created + * + */ +//================================================================================ + +bool SMESH_Mesh::SynchronizeGroups() +{ + int nbGroups = _mapGroup.size(); + const set& groups = _myMeshDS->GetGroups(); + set::const_iterator gIt = groups.begin(); + for ( ; gIt != groups.end(); ++gIt ) + { + SMESHDS_GroupBase* groupDS = (SMESHDS_GroupBase*) *gIt; + _groupId = groupDS->GetID(); + if ( !_mapGroup.count( _groupId )) + _mapGroup[_groupId] = new SMESH_Group( groupDS ); + } + if ( !_mapGroup.empty() ) + _groupId = _mapGroup.rbegin()->first + 1; + + return nbGroups < _mapGroup.size(); +} + //================================================================================ /*! * \brief Return iterator on all existing groups @@ -1391,15 +1709,27 @@ SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID) */ //============================================================================= -std::list SMESH_Mesh::GetGroupIds() const +list SMESH_Mesh::GetGroupIds() const { - std::list anIds; - for ( std::map::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) + list anIds; + for ( map::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) anIds.push_back( it->first ); return anIds; } +//================================================================================ +/*! + * \brief Set a caller of methods at level of CORBA API implementation. + * The set upCaller will be deleted by SMESH_Mesh + */ +//================================================================================ + +void SMESH_Mesh::SetCallUp( TCallUp* upCaller ) +{ + if ( _callUp ) delete _callUp; + _callUp = upCaller; +} //============================================================================= /*! @@ -1407,13 +1737,16 @@ std::list SMESH_Mesh::GetGroupIds() const */ //============================================================================= -void SMESH_Mesh::RemoveGroup (const int theGroupID) +bool SMESH_Mesh::RemoveGroup (const int theGroupID) { if (_mapGroup.find(theGroupID) == _mapGroup.end()) - return; + return false; GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() ); delete _mapGroup[theGroupID]; _mapGroup.erase (theGroupID); + if (_callUp) + _callUp->RemoveGroup( theGroupID ); + return true; } //======================================================================= @@ -1459,7 +1792,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) save << clause << ".1) Number of " << orderStr << " triangles: \t" << nb3 << endl; save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl; if ( nb3 + nb4 != NbFaces(order) ) { - std::map myFaceMap; + map myFaceMap; SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator(); while( itFaces->more( ) ) { int nbNodes = itFaces->next()->NbNodes(); @@ -1484,7 +1817,7 @@ ostream& SMESH_Mesh::Dump(ostream& save) save << clause << ".3) Number of " << orderStr << " prisms: \t" << nb6 << endl; save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl; if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) { - std::map myVolumesMap; + map myVolumesMap; SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator(); while( itVolumes->more( ) ) { int nbNodes = itVolumes->next()->NbNodes(); @@ -1523,7 +1856,7 @@ SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID ) { SMESH_Group* aGroup = 0; - std::map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID ); + map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID ); if ( itg == _mapGroup.end() ) return aGroup; @@ -1545,9 +1878,153 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID ) while ( anItr->more() ) aNewGrpDS->Add( (anItr->next())->GetID() ); + // set color + aNewGrpDS->SetColor( anOldGrpDS->GetColor() ); + // remove old group delete anOldGrp; return aGroup; } +//============================================================================= +/*! + * \brief remove submesh order from Mesh + */ +//============================================================================= + +void SMESH_Mesh::ClearMeshOrder() +{ + _mySubMeshOrder.clear(); +} + +//============================================================================= +/*! + * \brief remove submesh order from Mesh + */ +//============================================================================= + +void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder ) +{ + _mySubMeshOrder = theOrder; +} + +//============================================================================= +/*! + * \brief return submesh order if any + */ +//============================================================================= + +const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const +{ + return _mySubMeshOrder; +} + +//============================================================================= +/*! + * \brief fill _mapAncestors + */ +//============================================================================= + +void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) +{ + + int desType, ancType; + if ( !theShape.IsSame( GetShapeToMesh()) && theShape.ShapeType() == TopAbs_COMPOUND ) + { + // a geom group is added. Insert it into lists of ancestors before + // the first ancestor more complex than group members + int memberType = TopoDS_Iterator( theShape ).Value().ShapeType(); + for ( desType = TopAbs_VERTEX; desType >= memberType; desType-- ) + for (TopExp_Explorer des( theShape, TopAbs_ShapeEnum( desType )); des.More(); des.Next()) + { + if ( !_mapAncestors.Contains( des.Current() )) continue;// issue 0020982 + TopTools_ListOfShape& ancList = _mapAncestors.ChangeFromKey( des.Current() ); + TopTools_ListIteratorOfListOfShape ancIt (ancList); + while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType ) + ancIt.Next(); + if ( ancIt.More() ) + ancList.InsertBefore( theShape, ancIt ); + } + } + { + for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- ) + for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- ) + TopExp::MapShapesAndAncestors ( theShape, + (TopAbs_ShapeEnum) desType, + (TopAbs_ShapeEnum) ancType, + _mapAncestors ); + } +} + +//============================================================================= +/*! + * \brief sort submeshes according to stored mesh order + * \param theListToSort in out list to be sorted + * \return FALSE if nothing sorted + */ +//============================================================================= + +bool SMESH_Mesh::SortByMeshOrder(list& theListToSort) const +{ + if ( !_mySubMeshOrder.size() || theListToSort.size() < 2) + return true; + + bool res = false; + list onlyOrderedList; + // collect all ordered submeshes in one list as pointers + // and get their positions within theListToSort + typedef list::iterator TPosInList; + map< int, TPosInList > sortedPos; + TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end(); + TListOfListOfInt::const_iterator listIddIt = _mySubMeshOrder.begin(); + for( ; listIddIt != _mySubMeshOrder.end(); listIddIt++) { + const TListOfInt& listOfId = *listIddIt; + TListOfInt::const_iterator idIt = listOfId.begin(); + for ( ; idIt != listOfId.end(); idIt++ ) { + if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) { + TPosInList smPos = find( smBeg, smEnd, sm ); + if ( smPos != smEnd ) { + onlyOrderedList.push_back( sm ); + sortedPos[ distance( smBeg, smPos )] = smPos; + } + } + } + } + if (onlyOrderedList.size() < 2) + return res; + res = true; + + list::iterator onlyBIt = onlyOrderedList.begin(); + list::iterator onlyEIt = onlyOrderedList.end(); + + // iterate on ordered submeshes and insert them in detected positions + map< int, TPosInList >::iterator i_pos = sortedPos.begin(); + for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos ) + *(i_pos->second) = *onlyBIt; + + return res; +} + +//============================================================================= +/*! + * \brief sort submeshes according to stored mesh order + * \param theListToSort in out list to be sorted + * \return FALSE if nothing sorted + */ +//============================================================================= + +list SMESH_Mesh::getAncestorsSubMeshes + (const TopoDS_Shape& theSubShape) const +{ + list listOfSubMesh; + TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape )); + for (; it.More(); it.Next() ) + if ( SMESH_subMesh* sm = GetSubMeshContaining( it.Value() )) + listOfSubMesh.push_back(sm); + + // sort submeshes according to stored mesh order + SortByMeshOrder( listOfSubMesh ); + + return listOfSubMesh; +} diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 91ae67eda..5ae3cc61c 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -1,25 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : SMESH_Mesh.hxx // Author : Paul RASCLE, EDF // Module : SMESH @@ -30,6 +30,7 @@ #include "SMESH_SMESH.hxx" #include "SMESH_Hypothesis.hxx" +#include "SMESH_Controls.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESHDS_Command.hxx" @@ -40,8 +41,13 @@ #include #include -#include #include +#include + +#ifdef WNT +#pragma warning(disable:4251) // Warning DLL Interface ... +#pragma warning(disable:4290) // Warning Exception ... +#endif class SMESH_Gen; class SMESHDS_Document; @@ -51,14 +57,17 @@ class SMESH_subMesh; class SMESH_HypoFilter; class TopoDS_Solid; +typedef std::list TListOfInt; +typedef std::list TListOfListOfInt; + class SMESH_EXPORT SMESH_Mesh { public: SMESH_Mesh(int theLocalId, - int theStudyId, - SMESH_Gen* theGen, - bool theIsEmbeddedMode, - SMESHDS_Document* theDocument); + int theStudyId, + SMESH_Gen* theGen, + bool theIsEmbeddedMode, + SMESHDS_Document* theDocument); virtual ~SMESH_Mesh(); @@ -88,24 +97,30 @@ public: */ static const TopoDS_Solid& PseudoShape(); + /*! + * \brief Load mesh from study file + */ + void Load(); /*! * \brief Remove all nodes and elements */ void Clear(); - /*! * \brief Remove all nodes and elements of indicated shape */ void ClearSubMesh(const int theShapeId); - int UNVToMesh(const char* theFileName); /*! * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value */ + int UNVToMesh(const char* theFileName); + int MEDToMesh(const char* theFileName, const char* theMeshName); int STLToMesh(const char* theFileName); + int CGNSToMesh(const char* theFileName, const int theMeshIndex, std::string& theMeshName); + SMESH_Hypothesis::Hypothesis_Status AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId) throw(SALOME_Exception); @@ -132,12 +147,16 @@ public: void ClearLog() throw(SALOME_Exception); - int GetId() { return _id; } + int GetId() const { return _id; } + + bool MeshExists( int meshId ) const; SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; } - SMESH_Gen *GetGen() { return _gen; } + const SMESHDS_Mesh * GetMeshDS() const { return _myMeshDS; } + SMESH_Gen *GetGen() { return _gen; } + SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape) throw(SALOME_Exception); @@ -162,7 +181,7 @@ public: * \brief Return True if anHyp is used to mesh aSubShape */ bool IsUsedHypothesis(SMESHDS_Hypothesis * anHyp, - const SMESH_subMesh * aSubMesh); + const SMESH_subMesh * aSubMesh); /*! * \brief check if a hypothesis alowing notconform mesh is present */ @@ -179,6 +198,21 @@ public: bool GetAutoColor() throw(SALOME_Exception); + /*! + * \brief Set the flag meaning that the mesh has been edited "manually". + * It is to set to false after Clear() and to set to true by MeshEditor + */ + void SetIsModified(bool isModified); + + bool GetIsModified() const { return _isModified; } + + /*! + * \brief Return true if the mesh has been edited since a total re-compute + * and those modifications may prevent successful partial re-compute. + * As a side effect reset _isModified flag if mesh is empty + */ + bool HasModificationsToDiscard() const; + /*! * \brief Return data map of descendant to ancestor shapes */ @@ -191,47 +225,68 @@ public: bool HasDuplicatedGroupNamesMED(); void ExportMED(const char *file, - const char* theMeshName = NULL, - bool theAutoGroups = true, - int theVersion = 0) + const char* theMeshName = NULL, + bool theAutoGroups = true, + int theVersion = 0, + const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception); - void ExportDAT(const char *file) throw(SALOME_Exception); - void ExportUNV(const char *file) throw(SALOME_Exception); - void ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception); + void ExportDAT(const char * file, + const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception); + void ExportUNV(const char * file, + const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception); + void ExportSTL(const char * file, + const bool isascii, + const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception); + void ExportCGNS(const char * file, + const SMESHDS_Mesh* mesh); + void ExportSAUV(const char *file, + const char* theMeshName = NULL, + bool theAutoGroups = true) throw(SALOME_Exception); + + int NbNodes() const throw(SALOME_Exception); - int NbNodes() throw(SALOME_Exception); + int Nb0DElements() const throw(SALOME_Exception); - int NbEdges(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbEdges(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbFaces(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbFaces(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbTriangles(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbTriangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbPolygons() throw(SALOME_Exception); + int NbBiQuadQuadrangles() const throw(SALOME_Exception); + + int NbPolygons() const throw(SALOME_Exception); - int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbHexas(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbHexas(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbTriQuadraticHexas() const throw(SALOME_Exception); + + int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception); + int NbPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception); - int NbPolyhedrons() throw(SALOME_Exception); + int NbHexagonalPrisms() const throw(SALOME_Exception); - int NbSubMesh() throw(SALOME_Exception); + int NbPolyhedrons() const throw(SALOME_Exception); - int NbGroup() const { return _mapGroup.size(); } + int NbBalls() const throw(SALOME_Exception); + + int NbSubMesh() const throw(SALOME_Exception); + int NbGroup() const { return _mapGroup.size(); } + SMESH_Group* AddGroup (const SMDSAbs_ElementType theType, - const char* theName, - int& theId, - const TopoDS_Shape& theShape=TopoDS_Shape()); + const char* theName, + int& theId, + const TopoDS_Shape& theShape=TopoDS_Shape(), + const SMESH_PredicatePtr& thePredicate=SMESH_PredicatePtr()); typedef boost::shared_ptr< SMDS_Iterator > GroupIteratorPtr; GroupIteratorPtr GetGroups() const; @@ -240,39 +295,76 @@ public: SMESH_Group* GetGroup (const int theGroupID); - void RemoveGroup (const int theGroupID); + bool RemoveGroup (const int theGroupID); SMESH_Group* ConvertToStandalone ( int theGroupID ); + struct TCallUp // callback from SMESH to SMESH_I level + { + virtual void RemoveGroup (const int theGroupID)=0; + virtual void HypothesisModified ()=0; + virtual void Load ()=0; + virtual ~TCallUp() {} + }; + void SetCallUp( TCallUp * upCaller ); + + bool SynchronizeGroups(); + + SMDSAbs_ElementType GetElementType( const int id, const bool iselem ); + void ClearMeshOrder(); + void SetMeshOrder(const TListOfListOfInt& theOrder ); + const TListOfListOfInt& GetMeshOrder() const; + + /*! + * \brief sort submeshes according to stored mesh order + * \param theListToSort in out list to be sorted + * \return FALSE if nothing sorted + */ + bool SortByMeshOrder(std::list& theListToSort) const; + // ostream& Dump(ostream & save); private: + + void fillAncestorsMap(const TopoDS_Shape& theShape); + std::list getAncestorsSubMeshes + (const TopoDS_Shape& theSubShape) const; protected: int _id; // id given by creator (unique within the creator instance) int _studyId; int _idDoc; // id given by SMESHDS_Document int _groupId; // id generator for group objects + int _nbSubShapes; // initial nb of subshapes in the shape to mesh bool _isShapeToMesh;// set to true when a shape is given (only once) std::list _subMeshesUsingHypothesisList; SMESHDS_Document * _myDocument; SMESHDS_Mesh * _myMeshDS; + SMESH_Gen * _gen; std::map _mapSubMesh; std::map _mapGroup; - SMESH_Gen * _gen; - + bool _isAutoColor; + bool _isModified; //!< modified since last total re-compute, issue 0020693 double _shapeDiagonal; //!< diagonal size of bounding box of shape to mesh TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors; + TListOfListOfInt _mySubMeshOrder; + + // Struct calling methods at CORBA API implementation level, used to + // 1) make an upper level be consistent with a lower one when group removal + // is invoked by hyp modification (issue 0020918) + // 2) to forget not loaded mesh data at hyp modification + TCallUp* _callUp; + protected: - SMESH_Mesh() {}; + SMESH_Mesh(); SMESH_Mesh(const SMESH_Mesh&) {}; }; diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 063f68819..324b6b81d 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1,66 +1,83 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : idl implementation based on 'SMESH' unit's classes + // File : SMESH_MeshEditor.cxx // Created : Mon Apr 12 16:10:22 2004 // Author : Edward AGAPOV (eap) -// + #include "SMESH_MeshEditor.hxx" #include "SMDS_FaceOfNodes.hxx" #include "SMDS_VolumeTool.hxx" #include "SMDS_EdgePosition.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" -#include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_MeshGroup.hxx" +#include "SMDS_LinearEdge.hxx" +#include "SMDS_Downward.hxx" +#include "SMDS_SetIterator.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" -#include "SMESH_subMesh.hxx" +#include "SMESH_Algo.hxx" #include "SMESH_ControlsDef.hxx" +#include "SMESH_Group.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_OctreeNode.hxx" -#include "SMESH_Group.hxx" +#include "SMESH_subMesh.hxx" + +#include #include "utilities.h" +#include +#include +#include #include #include #include +#include #include +#include #include +#include #include #include +#include #include +#include +#include +#include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -70,10 +87,18 @@ #include #include #include -#include + +#include #include #include +#include +#include +#include +#include + +#include +#include #define cast2Node(elem) static_cast( elem ) @@ -82,13 +107,8 @@ using namespace SMESH::Controls; typedef map > TElemOfNodeListMap; typedef map > TElemOfElemListMap; -//typedef map > TNodeOfNodeVecMap; -//typedef TNodeOfNodeVecMap::iterator TNodeOfNodeVecMapItr; -//typedef map > TElemOfVecOfMapNodesMap; -struct TNodeXYZ : public gp_XYZ { - TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {} -}; +typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator> TSetIterator; //======================================================================= //function : SMESH_MeshEditor @@ -110,101 +130,170 @@ SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector & node, const SMDSAbs_ElementType type, const bool isPoly, - const int ID) + const int ID, + const double ballDiameter) { + //MESSAGE("AddElement " <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] ); + if (nbnode == 3) { + if ( ID >= 1 ) 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 >= 1 ) 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 >= 1 ) 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 >= 1 ) 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 (nbnode == 9) { + if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], + node[4], node[5], node[6], node[7], node[8], ID); + else e = mesh->AddFace (node[0], node[1], node[2], node[3], + node[4], node[5], node[6], node[7], node[8] ); + } } else { - if ( ID ) e = mesh->AddPolygonalFaceWithID(node, ID); - else e = mesh->AddPolygonalFace (node ); + if ( ID >= 1 ) 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] ); + if (nbnode == 4) { + if ( ID >= 1 ) 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 >= 1 ) 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 >= 1 ) 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 >= 1 ) 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 >= 1 ) 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 == 12) { + if ( ID >= 1 ) 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], 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] ); + } + else if (nbnode == 13) { + if ( ID >= 1 ) 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 >= 1 ) 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 >= 1 ) 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] ); + } + else if (nbnode == 27) { + if ( ID >= 1 ) 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], + node[20],node[21],node[22],node[23], + node[24],node[25],node[26], ID); + else e = mesh->AddVolume (node[0], node[1], node[2], node[3], + node[4], node[5], node[6], node[7], + node[8], node[9], node[10],node[11], + node[12],node[13],node[14],node[15], + node[16],node[17],node[18],node[19], + node[20],node[21],node[22],node[23], + node[24],node[25],node[26] ); + } } + break; + + case SMDSAbs_Edge: + if ( nbnode == 2 ) { + if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], ID); + else e = mesh->AddEdge (node[0], node[1] ); + } + else if ( nbnode == 3 ) { + if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID); + else e = mesh->AddEdge (node[0], node[1], node[2] ); + } + break; + + case SMDSAbs_0DElement: + if ( nbnode == 1 ) { + if ( ID >= 1 ) e = mesh->Add0DElementWithID(node[0], ID); + else e = mesh->Add0DElement (node[0] ); + } + break; + + case SMDSAbs_Node: + if ( ID >= 1 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID); + else e = mesh->AddNode (node[0]->X(), node[0]->Y(), node[0]->Z()); + break; + + case SMDSAbs_Ball: + if ( ID >= 1 ) e = mesh->AddBallWithID(node[0], ballDiameter, ID); + else e = mesh->AddBall (node[0], ballDiameter); + break; + + default:; } + if ( e ) myLastCreatedElems.Append( e ); return e; } @@ -237,8 +326,8 @@ SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector & nodeIDs // Modify a compute state of sub-meshes which become empty //======================================================================= -bool SMESH_MeshEditor::Remove (const list< int >& theIDs, - const bool isNodes ) +int SMESH_MeshEditor::Remove (const list< int >& theIDs, + const bool isNodes ) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -246,6 +335,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, SMESHDS_Mesh* aMesh = GetMeshDS(); set< SMESH_subMesh *> smmap; + int removed = 0; list::const_iterator it = theIDs.begin(); for ( ; it != theIDs.end(); it++ ) { const SMDS_MeshElement * elem; @@ -260,28 +350,29 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, if ( isNodes ) { const SMDS_MeshNode* node = cast2Node( elem ); if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) - if ( int aShapeID = node->GetPosition()->GetShapeId() ) + if ( int aShapeID = node->getshapeId() ) if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) smmap.insert( sm ); } // Find sub-meshes to notify about modification -// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); -// while ( nodeIt->more() ) { -// const SMDS_MeshNode* node = static_cast( nodeIt->next() ); -// const SMDS_PositionPtr& aPosition = node->GetPosition(); -// if ( aPosition.get() ) { -// if ( int aShapeID = aPosition->GetShapeId() ) { -// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) -// smmap.insert( sm ); -// } -// } -// } + // SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); + // while ( nodeIt->more() ) { + // const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + // const SMDS_PositionPtr& aPosition = node->GetPosition(); + // if ( aPosition.get() ) { + // if ( int aShapeID = aPosition->GetShapeId() ) { + // if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) + // smmap.insert( sm ); + // } + // } + // } // Do remove if ( isNodes ) aMesh->RemoveNode( static_cast< const SMDS_MeshNode* >( elem )); else aMesh->RemoveElement( elem ); + removed++; } // Notify sub-meshes about modification @@ -291,11 +382,11 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, (*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); } -// // Check if the whole mesh becomes empty -// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) ) -// sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + // // Check if the whole mesh becomes empty + // if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) ) + // sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - return true; + return removed; } //======================================================================= @@ -313,46 +404,55 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) if ( aMesh->ShapeToMesh().IsNull() ) return 0; + int aShapeID = theElem->getshapeId(); + if ( aShapeID < 1 ) + return 0; + + if ( SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID )) + if ( sm->Contains( theElem )) + return aShapeID; + if ( theElem->GetType() == SMDSAbs_Node ) { - const SMDS_PositionPtr& aPosition = - static_cast( theElem )->GetPosition(); - if ( aPosition.get() ) - return aPosition->GetShapeId(); - else - return 0; + MESSAGE( ":( Error: invalid myShapeId of node " << theElem->GetID() ); + } + else { + MESSAGE( ":( Error: invalid myShapeId of element " << theElem->GetID() ); } - TopoDS_Shape aShape; // the shape a node is on - SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - const SMDS_PositionPtr& aPosition = node->GetPosition(); - if ( aPosition.get() ) { - int aShapeID = aPosition->GetShapeId(); - SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ); - if ( sm ) { - if ( sm->Contains( theElem )) - return aShapeID; - if ( aShape.IsNull() ) - aShape = aMesh->IndexToShape( aShapeID ); - } - else { - //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID ); + TopoDS_Shape aShape; // the shape a node of theElem is on + if ( theElem->GetType() != SMDSAbs_Node ) + { + SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + if ((aShapeID = node->getshapeId()) > 0) { + if ( SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ) ) { + if ( sm->Contains( theElem )) + return aShapeID; + if ( aShape.IsNull() ) + aShape = aMesh->IndexToShape( aShapeID ); + } } } } // None of nodes is on a proper shape, // find the shape among ancestors of aShape on which a node is - if ( aShape.IsNull() ) { - //MESSAGE ("::FindShape() - NONE node is on shape") - return 0; + if ( !aShape.IsNull() ) { + TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape )); + for ( ; ancIt.More(); ancIt.Next() ) { + SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() ); + if ( sm && sm->Contains( theElem )) + return aMesh->ShapeToIndex( ancIt.Value() ); + } } - TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape )); - for ( ; ancIt.More(); ancIt.Next() ) { - SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() ); - if ( sm && sm->Contains( theElem )) - return aMesh->ShapeToIndex( ancIt.Value() ); + else + { + const map& id2sm = GetMeshDS()->SubMeshes(); + map::const_iterator id_sm = id2sm.begin(); + for ( ; id_sm != id2sm.end(); ++id_sm ) + if ( id_sm->second->Contains( theElem )) + return id_sm->first; } //MESSAGE ("::FindShape() - SHAPE NOT FOUND") @@ -394,6 +494,25 @@ static void ShiftNodesQuadTria(const SMDS_MeshNode* aNodes[]) aNodes[5] = nd2; } +//======================================================================= +//function : edgeConnectivity +//purpose : auxilary +// return number of the edges connected with the theNode. +// if theEdges has connections with the other type of the +// elements, return -1 +//======================================================================= +static int nbEdgeConnectivity(const SMDS_MeshNode* theNode) +{ + SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(); + int nb=0; + while(elemIt->more()) { + elemIt->next(); + nb++; + } + return nb; +} + + //======================================================================= //function : GetNodesFromTwoTria //purpose : auxilary @@ -459,15 +578,19 @@ static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1, bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, const SMDS_MeshElement * theTria2 ) { + MESSAGE("InverseDiag"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); if (!theTria1 || !theTria2) return false; - const SMDS_FaceOfNodes* F1 = dynamic_cast( theTria1 ); - const SMDS_FaceOfNodes* F2 = dynamic_cast( theTria2 ); - if (F1 && F2) { + const SMDS_VtkFace* F1 = dynamic_cast( theTria1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( theTria2 ); + if (!F2) return false; + if ((theTria1->GetEntityType() == SMDSEntity_Triangle) && + (theTria2->GetEntityType() == SMDSEntity_Triangle)) { // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | @@ -504,12 +627,14 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, // 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++ ) { - if ( sameInd [ i ] == 0 ) + if ( sameInd [ i ] == 0 ) { if ( i < 3 ) i1 = i; else i2 = i; - else if (i < 3) + } + else if (i < 3) { if ( iA ) iB = i; else iA = i; + } } // nodes 1 and 2 should not be the same if ( aNodes[ i1 ] == aNodes[ i2 ] ) @@ -520,24 +645,18 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, // theTria2: B->1 aNodes[ sameInd[ iB ]] = aNodes[ i1 ]; - //MESSAGE( theTria1 << theTria2 ); - GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 ); GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 ); - //MESSAGE( theTria1 << theTria2 ); - return true; } // end if(F1 && F2) // check case of quadratic faces - const SMDS_QuadraticFaceOfNodes* QF1 = - dynamic_cast (theTria1); - if(!QF1) return false; - const SMDS_QuadraticFaceOfNodes* QF2 = - dynamic_cast (theTria2); - if(!QF2) return false; + if (theTria1->GetEntityType() != SMDSEntity_Quad_Triangle) + return false; + if (theTria2->GetEntityType() != SMDSEntity_Quad_Triangle) + return false; // 5 // 1 +--+--+ 2 theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9) @@ -602,7 +721,7 @@ static bool findTriangles(const SMDS_MeshNode * theNode1, it = theNode2->GetInverseElementIterator(SMDSAbs_Face); while (it->more()) { const SMDS_MeshElement* elem = it->next(); - if ( 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() ) { @@ -617,6 +736,7 @@ static bool findTriangles(const SMDS_MeshNode * theNode1, else { theTria1 = elem; } + } } return ( theTria1 && theTria2 ); } @@ -640,11 +760,12 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; - const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - //if (!F1) return false; - const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - //if (!F2) return false; - if (F1 && F2) { + const SMDS_VtkFace* F1 = dynamic_cast( tr1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( tr2 ); + if (!F2) return false; + if ((tr1->GetEntityType() == SMDSEntity_Triangle) && + (tr2->GetEntityType() == SMDSEntity_Triangle)) { // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ | @@ -682,23 +803,13 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, // tr2: B->1 aNodes2[ iB2 ] = aNodes1[ i1 ]; - //MESSAGE( tr1 << tr2 ); - GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 ); GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 ); - //MESSAGE( tr1 << tr2 ); - return true; } // check case of quadratic faces - const SMDS_QuadraticFaceOfNodes* QF1 = - dynamic_cast (tr1); - if(!QF1) return false; - const SMDS_QuadraticFaceOfNodes* QF2 = - dynamic_cast (tr2); - if(!QF2) return false; return InverseDiag(tr1,tr2); } @@ -772,34 +883,39 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, if ( !findTriangles( theNode1, theNode2, tr1, tr2 )) return false; - const SMDS_FaceOfNodes* F1 = dynamic_cast( tr1 ); - //if (!F1) return false; - const SMDS_FaceOfNodes* F2 = dynamic_cast( tr2 ); - //if (!F2) return false; - if (F1 && F2) { + const SMDS_VtkFace* F1 = dynamic_cast( tr1 ); + if (!F1) return false; + const SMDS_VtkFace* F2 = dynamic_cast( tr2 ); + if (!F2) return false; + SMESHDS_Mesh * aMesh = GetMeshDS(); + + if ((tr1->GetEntityType() == SMDSEntity_Triangle) && + (tr2->GetEntityType() == SMDSEntity_Triangle)) { const SMDS_MeshNode* aNodes [ 4 ]; if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 )) return false; - //MESSAGE( endl << tr1 << tr2 ); - - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr2 ); - - //MESSAGE( endl << tr1 ); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3] ); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr2 ); return true; } // check case of quadratic faces - const SMDS_QuadraticFaceOfNodes* QF1 = - dynamic_cast (tr1); - if(!QF1) return false; - const SMDS_QuadraticFaceOfNodes* QF2 = - dynamic_cast (tr2); - if(!QF2) return false; + if (tr1->GetEntityType() != SMDSEntity_Quad_Triangle) + return false; + if (tr2->GetEntityType() != SMDSEntity_Quad_Triangle) + return false; // 5 // 1 +--+--+ 2 tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9) @@ -829,9 +945,18 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, aNodes[6] = N2[3]; aNodes[7] = N1[5]; - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr2 ); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3], + aNodes[4], aNodes[5], aNodes[6], aNodes[7]); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr2 ); // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); @@ -846,6 +971,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) { + MESSAGE("Reorient"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -892,8 +1018,10 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) } case SMDSAbs_Volume: { if (theElem->IsPoly()) { - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - static_cast( theElem ); + // TODO reorient vtk polyhedron + MESSAGE("reorient vtk polyhedron ?"); + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( theElem ); if (!aPolyedre) { MESSAGE("Warning: bad volumic element"); return false; @@ -922,6 +1050,7 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) if ( !vTool.Set( theElem )) return false; vTool.Inverse(); + MESSAGE("ChangeElementNodes reorient: check vTool.Inverse"); return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() ); } } @@ -931,6 +1060,97 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) return false; } +//================================================================================ +/*! + * \brief Reorient faces. + * \param theFaces - the faces to reorient. If empty the whole mesh is meant + * \param theDirection - desired direction of normal of \a theFace + * \param theFace - one of \a theFaces that sould be orientated according to + * \a theDirection and whose orientation defines orientation of other faces + * \return number of reoriented faces. + */ +//================================================================================ + +int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet & theFaces, + const gp_Dir& theDirection, + const SMDS_MeshElement * theFace) +{ + int nbReori = 0; + if ( !theFace || theFace->GetType() != SMDSAbs_Face ) return nbReori; + + if ( theFaces.empty() ) + { + SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=*/true); + while ( fIt->more() ) + theFaces.insert( theFaces.end(), fIt->next() ); + } + + // orient theFace according to theDirection + gp_XYZ normal; + SMESH_Algo::FaceNormal( theFace, normal, /*normalized=*/false ); + if ( normal * theDirection.XYZ() < 0 ) + nbReori += Reorient( theFace ); + + // Orient other faces + + set< const SMDS_MeshElement* > startFaces; + TIDSortedElemSet avoidSet; + set< SMESH_TLink > checkedLinks; + pair< set< SMESH_TLink >::iterator, bool > linkIt_isNew; + + if ( theFaces.size() > 1 )// leave 1 face to prevent finding not selected faces + theFaces.erase( theFace ); + startFaces.insert( theFace ); + + set< const SMDS_MeshElement* >::iterator startFace = startFaces.begin(); + while ( startFace != startFaces.end() ) + { + theFace = *startFace; + const int nbNodes = theFace->NbCornerNodes(); + + avoidSet.clear(); + avoidSet.insert(theFace); + + NLink link( theFace->GetNode( 0 ), 0 ); + for ( int i = 0; i < nbNodes; ++i ) // loop on links of theFace + { + link.second = theFace->GetNode(( i+1 ) % nbNodes ); + linkIt_isNew = checkedLinks.insert( link ); + if ( !linkIt_isNew.second ) + { + // link has already been checked and won't be encountered more + // if the group (theFaces) is manifold + checkedLinks.erase( linkIt_isNew.first ); + } + else + { + int nodeInd1, nodeInd2; + const SMDS_MeshElement* otherFace = FindFaceInSet( link.first, link.second, + theFaces, avoidSet, + & nodeInd1, & nodeInd2); + if ( otherFace && otherFace != theFace) + { + // link must be reversed in otherFace if orientation ot otherFace + // is same as that of theFace + if ( abs(nodeInd2-nodeInd1) == 1 ? nodeInd2 > nodeInd1 : nodeInd1 > nodeInd2 ) + { + // cout << "Reorient " << otherFace->GetID() << " near theFace=" <GetID() + // << " \tlink( " << link.first->GetID() << " " << link.second->GetID() << endl; + nbReori += Reorient( otherFace ); + } + startFaces.insert( otherFace ); + if ( theFaces.size() > 1 ) // leave 1 face to prevent finding not selected faces + theFaces.erase( otherFace ); + } + } + std::swap( link.first, link.second ); + } + startFaces.erase( startFace ); + startFace = startFaces.begin(); + } + return nbReori; +} + //======================================================================= //function : getBadRate //purpose : @@ -973,15 +1193,11 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, const SMDS_MeshElement* elem = *itElem; if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; - if ( elem->NbNodes() != ( elem->IsQuadratic() ? 8 : 4 )) + if ( elem->NbCornerNodes() != 4 ) continue; // retrieve element nodes - const SMDS_MeshNode* aNodes [8]; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - int i = 0; - while ( itN->more() ) - aNodes[ i++ ] = static_cast( itN->next() ); + vector< const SMDS_MeshNode* > aNodes( elem->begin_nodes(), elem->end_nodes() ); // compare two sets of possible triangles double aBadRate1, aBadRate2; // to what extent a set is bad @@ -994,7 +1210,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit ); int aShapeId = FindShape( elem ); - const SMDS_MeshElement* newElem = 0; + const SMDS_MeshElement* newElem1 = 0; + const SMDS_MeshElement* newElem2 = 0; if( !elem->IsQuadratic() ) { @@ -1002,13 +1219,13 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, if ( aBadRate1 <= aBadRate2 ) { // tr1 + tr2 is better - aMesh->ChangeElementNodes( elem, aNodes, 3 ); - newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + newElem1 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + newElem2 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] ); } else { // tr3 + tr4 is better - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] ); } } else { @@ -1028,72 +1245,70 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, helper.SetSubShape( shape ); } } - // get elem nodes - const SMDS_MeshNode* aNodes [8]; - const SMDS_MeshNode* inFaceNode = 0; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - int i = 0; - while ( itN->more() ) { - aNodes[ i++ ] = static_cast( itN->next() ); - if ( !inFaceNode && helper.GetNodeUVneedInFaceNode() && - 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; - gp_XYZ p( 0,0,0 ); - if ( surface.IsNull() ) { - for(i=0; i<4; i++) - p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), aNodes[i]->Z() ); - p /= 4; + const SMDS_MeshNode* newN = 0; + if ( aNodes.size() == 9 ) + { + // SMDSEntity_BiQuad_Quadrangle + newN = aNodes.back(); } - else { - TopoDS_Face face = TopoDS::Face( helper.GetSubShape() ); - gp_XY uv( 0,0 ); - for(i=0; i<4; i++) - uv += helper.GetNodeUV( face, aNodes[i], inFaceNode ); - uv /= 4.; - p = surface->Value( uv.X(), uv.Y() ).XYZ(); + else + { + gp_XYZ p( 0,0,0 ); + if ( surface.IsNull() ) + { + for ( int i = 0; i < 4; i++ ) + p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), aNodes[i]->Z() ); + p /= 4; + } + else + { + const SMDS_MeshNode* inFaceNode = 0; + if ( helper.GetNodeUVneedInFaceNode() ) + for ( size_t i = 0; i < aNodes.size() && !inFaceNode; ++i ) + if ( aNodes[ i ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) + inFaceNode = aNodes[ i ]; + + TopoDS_Face face = TopoDS::Face( helper.GetSubShape() ); + gp_XY uv( 0,0 ); + for ( int i = 0; i < 4; i++ ) + uv += helper.GetNodeUV( face, aNodes[i], inFaceNode ); + uv /= 4.; + p = surface->Value( uv.X(), uv.Y() ).XYZ(); + } + newN = aMesh->AddNode( p.X(), p.Y(), p.Z() ); + myLastCreatedNodes.Append(newN); } - const SMDS_MeshNode* newN = aMesh->AddNode( p.X(), p.Y(), p.Z() ); - myLastCreatedNodes.Append(newN); - // create a new element - const SMDS_MeshNode* N[6]; if ( aBadRate1 <= aBadRate2 ) { - N[0] = aNodes[0]; - N[1] = aNodes[1]; - N[2] = aNodes[2]; - N[3] = aNodes[4]; - N[4] = aNodes[5]; - N[5] = newN; - newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], - aNodes[6], aNodes[7], newN ); + newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1], + newN, aNodes[4], aNodes[5] ); } else { - N[0] = aNodes[1]; - N[1] = aNodes[2]; - N[2] = aNodes[3]; - N[3] = aNodes[5]; - N[4] = aNodes[6]; - N[5] = newN; - newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], - aNodes[7], aNodes[4], newN ); + newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2], + newN, aNodes[5], aNodes[6] ); } - aMesh->ChangeElementNodes( elem, N, 6 ); - } // quadratic case // care of a new element - myLastCreatedElems.Append(newElem); - AddToSameGroups( newElem, elem, aMesh ); + myLastCreatedElems.Append(newElem1); + myLastCreatedElems.Append(newElem2); + AddToSameGroups( newElem1, elem, aMesh ); + AddToSameGroups( newElem2, elem, aMesh ); // put a new triangle on the same shape if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } + aMesh->RemoveElement( elem ); } return true; } @@ -1102,6 +1317,7 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, //function : BestSplit //purpose : Find better diagonal for cutting. //======================================================================= + int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad, SMESH::Controls::NumericalFunctorPtr theCrit) { @@ -1143,85 +1359,681 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad, return -1; } -//======================================================================= -//function : AddToSameGroups -//purpose : add elemToAdd to the groups the elemInGroups belongs to -//======================================================================= - -void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd, - const SMDS_MeshElement* elemInGroups, - SMESHDS_Mesh * aMesh) +namespace { - const set& groups = aMesh->GetGroups(); - if (!groups.empty()) { - set::const_iterator grIt = groups.begin(); - for ( ; grIt != groups.end(); grIt++ ) { - SMESHDS_Group* group = dynamic_cast( *grIt ); - if ( group && group->Contains( elemInGroups )) - group->SMDSGroup().Add( elemToAdd ); - } - } -} + // Methods of splitting volumes into tetra + const int theHexTo5_1[5*4+1] = + { + 0, 1, 2, 5, 0, 4, 5, 7, 0, 2, 3, 7, 2, 5, 6, 7, 0, 5, 2, 7, -1 + }; + const int theHexTo5_2[5*4+1] = + { + 1, 2, 3, 6, 1, 4, 5, 6, 0, 1, 3, 4, 3, 4, 6, 7, 1, 3, 4, 6, -1 + }; + const int* theHexTo5[2] = { theHexTo5_1, theHexTo5_2 }; -//======================================================================= -//function : RemoveElemFromGroups -//purpose : Remove removeelem to the groups the elemInGroups belongs to -//======================================================================= -void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem, - SMESHDS_Mesh * aMesh) -{ - const set& groups = aMesh->GetGroups(); - if (!groups.empty()) - { - set::const_iterator GrIt = groups.begin(); - for (; GrIt != groups.end(); GrIt++) + const int theHexTo6_1[6*4+1] = { - SMESHDS_Group* grp = dynamic_cast(*GrIt); - if (!grp || grp->IsEmpty()) continue; - grp->SMDSGroup().Remove(removeelem); - } - } -} + 1, 5, 6, 0, 0, 1, 2, 6, 0, 4, 5, 6, 0, 4, 6, 7, 0, 2, 3, 6, 0, 3, 7, 6, -1 + }; + const int theHexTo6_2[6*4+1] = + { + 2, 6, 7, 1, 1, 2, 3, 7, 1, 5, 6, 7, 1, 5, 7, 4, 1, 3, 0, 7, 1, 0, 4, 7, -1 + }; + const int theHexTo6_3[6*4+1] = + { + 3, 7, 4, 2, 2, 3, 0, 4, 2, 6, 7, 4, 2, 6, 4, 5, 2, 0, 1, 4, 2, 1, 5, 4, -1 + }; + const int theHexTo6_4[6*4+1] = + { + 0, 4, 5, 3, 3, 0, 1, 5, 3, 7, 4, 5, 3, 7, 5, 6, 3, 1, 2, 5, 3, 2, 6, 5, -1 + }; + const int* theHexTo6[4] = { theHexTo6_1, theHexTo6_2, theHexTo6_3, theHexTo6_4 }; -//======================================================================= -//function : ReplaceElemInGroups -//purpose : replace elemToRm by elemToAdd in the all groups -//======================================================================= + const int thePyraTo2_1[2*4+1] = + { + 0, 1, 2, 4, 0, 2, 3, 4, -1 + }; + const int thePyraTo2_2[2*4+1] = + { + 1, 2, 3, 4, 1, 3, 0, 4, -1 + }; + const int* thePyraTo2[2] = { thePyraTo2_1, thePyraTo2_2 }; -void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* elemToRm, - const SMDS_MeshElement* elemToAdd, - SMESHDS_Mesh * aMesh) -{ - const set& groups = aMesh->GetGroups(); - if (!groups.empty()) { - set::const_iterator grIt = groups.begin(); - for ( ; grIt != groups.end(); grIt++ ) { - SMESHDS_Group* group = dynamic_cast( *grIt ); - if ( group && group->SMDSGroup().Remove( elemToRm ) && elemToAdd ) - group->SMDSGroup().Add( elemToAdd ); + const int thePentaTo3_1[3*4+1] = + { + 0, 1, 2, 3, 1, 3, 4, 2, 2, 3, 4, 5, -1 + }; + const int thePentaTo3_2[3*4+1] = + { + 1, 2, 0, 4, 2, 4, 5, 0, 0, 4, 5, 3, -1 + }; + const int thePentaTo3_3[3*4+1] = + { + 2, 0, 1, 5, 0, 5, 3, 1, 1, 5, 3, 4, -1 + }; + const int thePentaTo3_4[3*4+1] = + { + 0, 1, 2, 3, 1, 3, 4, 5, 2, 3, 1, 5, -1 + }; + const int thePentaTo3_5[3*4+1] = + { + 1, 2, 0, 4, 2, 4, 5, 3, 0, 4, 2, 3, -1 + }; + const int thePentaTo3_6[3*4+1] = + { + 2, 0, 1, 5, 0, 5, 3, 4, 1, 5, 0, 4, -1 + }; + const int* thePentaTo3[6] = { thePentaTo3_1, thePentaTo3_2, thePentaTo3_3, + thePentaTo3_4, thePentaTo3_5, thePentaTo3_6 }; + + struct TTriangleFacet //!< stores indices of three nodes of tetra facet + { + int _n1, _n2, _n3; + TTriangleFacet(int n1, int n2, int n3): _n1(n1), _n2(n2), _n3(n3) {} + bool contains(int n) const { return ( n == _n1 || n == _n2 || n == _n3 ); } + bool hasAdjacentTetra( const SMDS_MeshElement* elem ) const; + }; + struct TSplitMethod + { + int _nbTetra; + const int* _connectivity; //!< foursomes of tetra connectivy finished by -1 + bool _baryNode; //!< additional node is to be created at cell barycenter + bool _ownConn; //!< to delete _connectivity in destructor + map _faceBaryNode; //!< map face index to node at BC of face + + TSplitMethod( int nbTet=0, const int* conn=0, bool addNode=false) + : _nbTetra(nbTet), _connectivity(conn), _baryNode(addNode), _ownConn(false) {} + ~TSplitMethod() { if ( _ownConn ) delete [] _connectivity; _connectivity = 0; } + bool hasFacet( const TTriangleFacet& facet ) const + { + const int* tetConn = _connectivity; + for ( ; tetConn[0] >= 0; tetConn += 4 ) + if (( facet.contains( tetConn[0] ) + + facet.contains( tetConn[1] ) + + facet.contains( tetConn[2] ) + + facet.contains( tetConn[3] )) == 3 ) + return true; + return false; } - } -} + }; -//======================================================================= -//function : QuadToTri -//purpose : Cut quadrangles into triangles. -// theCrit is used to select a diagonal to cut -//======================================================================= + //======================================================================= + /*! + * \brief return TSplitMethod for the given element + */ + //======================================================================= -bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, - const bool the13Diag) -{ - myLastCreatedElems.Clear(); - myLastCreatedNodes.Clear(); + TSplitMethod getSplitMethod( SMDS_VolumeTool& vol, const int theMethodFlags) + { + const int iQ = vol.Element()->IsQuadratic() ? 2 : 1; - MESSAGE( "::QuadToTri()" ); + // at HEXA_TO_24 method, each face of volume is split into triangles each based on + // an edge and a face barycenter; tertaherdons are based on triangles and + // a volume barycenter + const bool is24TetMode = ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_24 ); - SMESHDS_Mesh * aMesh = GetMeshDS(); + // Find out how adjacent volumes are split - Handle(Geom_Surface) surface; - SMESH_MesherHelper helper( *GetMesh() ); + vector < list< TTriangleFacet > > triaSplitsByFace( vol.NbFaces() ); // splits of each side + int hasAdjacentSplits = 0, maxTetConnSize = 0; + for ( int iF = 0; iF < vol.NbFaces(); ++iF ) + { + int nbNodes = vol.NbFaceNodes( iF ) / iQ; + maxTetConnSize += 4 * ( nbNodes - (is24TetMode ? 0 : 2)); + if ( nbNodes < 4 ) continue; + + list< TTriangleFacet >& triaSplits = triaSplitsByFace[ iF ]; + const int* nInd = vol.GetFaceNodesIndices( iF ); + if ( nbNodes == 4 ) + { + TTriangleFacet t012( nInd[0*iQ], nInd[1*iQ], nInd[2*iQ] ); + TTriangleFacet t123( nInd[1*iQ], nInd[2*iQ], nInd[3*iQ] ); + if ( t012.hasAdjacentTetra( vol.Element() )) triaSplits.push_back( t012 ); + else if ( t123.hasAdjacentTetra( vol.Element() )) triaSplits.push_back( t123 ); + } + else + { + int iCom = 0; // common node of triangle faces to split into + for ( int iVar = 0; iVar < nbNodes; ++iVar, ++iCom ) + { + TTriangleFacet t012( nInd[ iQ * ( iCom )], + nInd[ iQ * ( (iCom+1)%nbNodes )], + nInd[ iQ * ( (iCom+2)%nbNodes )]); + TTriangleFacet t023( nInd[ iQ * ( iCom )], + nInd[ iQ * ( (iCom+2)%nbNodes )], + nInd[ iQ * ( (iCom+3)%nbNodes )]); + if ( t012.hasAdjacentTetra( vol.Element() ) && t023.hasAdjacentTetra( vol.Element() )) + { + triaSplits.push_back( t012 ); + triaSplits.push_back( t023 ); + break; + } + } + } + if ( !triaSplits.empty() ) + hasAdjacentSplits = true; + } + + // Among variants of split method select one compliant with adjacent volumes + + TSplitMethod method; + if ( !vol.Element()->IsPoly() && !is24TetMode ) + { + int nbVariants = 2, nbTet = 0; + const int** connVariants = 0; + switch ( vol.Element()->GetEntityType() ) + { + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + if ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_5 ) + connVariants = theHexTo5, nbTet = 5; + else + connVariants = theHexTo6, nbTet = 6, nbVariants = 4; + break; + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + connVariants = thePyraTo2; nbTet = 2; + break; + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + connVariants = thePentaTo3; nbTet = 3; nbVariants = 6; + break; + default: + nbVariants = 0; + } + for ( int variant = 0; variant < nbVariants && method._nbTetra == 0; ++variant ) + { + // check method compliancy with adjacent tetras, + // all found splits must be among facets of tetras described by this method + method = TSplitMethod( nbTet, connVariants[variant] ); + if ( hasAdjacentSplits && method._nbTetra > 0 ) + { + bool facetCreated = true; + for ( int iF = 0; facetCreated && iF < triaSplitsByFace.size(); ++iF ) + { + list< TTriangleFacet >::const_iterator facet = triaSplitsByFace[iF].begin(); + for ( ; facetCreated && facet != triaSplitsByFace[iF].end(); ++facet ) + facetCreated = method.hasFacet( *facet ); + } + if ( !facetCreated ) + method = TSplitMethod(0); // incompatible method + } + } + } + if ( method._nbTetra < 1 ) + { + // No standard method is applicable, use a generic solution: + // each facet of a volume is split into triangles and + // each of triangles and a volume barycenter form a tetrahedron. + + const bool isHex27 = ( vol.Element()->GetEntityType() == SMDSEntity_TriQuad_Hexa ); + + int* connectivity = new int[ maxTetConnSize + 1 ]; + method._connectivity = connectivity; + method._ownConn = true; + method._baryNode = !isHex27; // to create central node or not + + int connSize = 0; + int baryCenInd = vol.NbNodes() - int( isHex27 ); + for ( int iF = 0; iF < vol.NbFaces(); ++iF ) + { + const int nbNodes = vol.NbFaceNodes( iF ) / iQ; + const int* nInd = vol.GetFaceNodesIndices( iF ); + // find common node of triangle facets of tetra to create + int iCommon = 0; // index in linear numeration + const list< TTriangleFacet >& triaSplits = triaSplitsByFace[ iF ]; + if ( !triaSplits.empty() ) + { + // by found facets + const TTriangleFacet* facet = &triaSplits.front(); + for ( ; iCommon < nbNodes-1 ; ++iCommon ) + if ( facet->contains( nInd[ iQ * iCommon ]) && + facet->contains( nInd[ iQ * ((iCommon+2)%nbNodes) ])) + break; + } + else if ( nbNodes > 3 && !is24TetMode ) + { + // find the best method of splitting into triangles by aspect ratio + SMESH::Controls::NumericalFunctorPtr aspectRatio( new SMESH::Controls::AspectRatio); + map< double, int > badness2iCommon; + const SMDS_MeshNode** nodes = vol.GetFaceNodes( iF ); + int nbVariants = ( nbNodes == 4 ? 2 : nbNodes ); + for ( int iVar = 0; iVar < nbVariants; ++iVar, ++iCommon ) + { + double badness = 0; + for ( int iLast = iCommon+2; iLast < iCommon+nbNodes; ++iLast ) + { + SMDS_FaceOfNodes tria ( nodes[ iQ*( iCommon )], + nodes[ iQ*((iLast-1)%nbNodes)], + nodes[ iQ*((iLast )%nbNodes)]); + badness += getBadRate( &tria, aspectRatio ); + } + badness2iCommon.insert( make_pair( badness, iCommon )); + } + // use iCommon with lowest badness + iCommon = badness2iCommon.begin()->second; + } + if ( iCommon >= nbNodes ) + iCommon = 0; // something wrong + + // fill connectivity of tetrahedra based on a current face + int nbTet = nbNodes - 2; + if ( is24TetMode && nbNodes > 3 && triaSplits.empty()) + { + int faceBaryCenInd; + if ( isHex27 ) + { + faceBaryCenInd = vol.GetCenterNodeIndex( iF ); + method._faceBaryNode[ iF ] = vol.GetNodes()[ faceBaryCenInd ]; + } + else + { + method._faceBaryNode[ iF ] = 0; + faceBaryCenInd = baryCenInd + method._faceBaryNode.size(); + } + nbTet = nbNodes; + for ( int i = 0; i < nbTet; ++i ) + { + int i1 = i, i2 = (i+1) % nbNodes; + if ( !vol.IsFaceExternal( iF )) swap( i1, i2 ); + connectivity[ connSize++ ] = nInd[ iQ * i1 ]; + connectivity[ connSize++ ] = nInd[ iQ * i2 ]; + connectivity[ connSize++ ] = faceBaryCenInd; + connectivity[ connSize++ ] = baryCenInd; + } + } + else + { + for ( int i = 0; i < nbTet; ++i ) + { + int i1 = (iCommon+1+i) % nbNodes, i2 = (iCommon+2+i) % nbNodes; + if ( !vol.IsFaceExternal( iF )) swap( i1, i2 ); + connectivity[ connSize++ ] = nInd[ iQ * iCommon ]; + connectivity[ connSize++ ] = nInd[ iQ * i1 ]; + connectivity[ connSize++ ] = nInd[ iQ * i2 ]; + connectivity[ connSize++ ] = baryCenInd; + } + } + method._nbTetra += nbTet; + + } // loop on volume faces + + connectivity[ connSize++ ] = -1; + + } // end of generic solution + + return method; + } + //================================================================================ + /*! + * \brief Check if there is a tetraherdon adjacent to the given element via this facet + */ + //================================================================================ + + bool TTriangleFacet::hasAdjacentTetra( const SMDS_MeshElement* elem ) const + { + // find the tetrahedron including the three nodes of facet + const SMDS_MeshNode* n1 = elem->GetNode(_n1); + const SMDS_MeshNode* n2 = elem->GetNode(_n2); + const SMDS_MeshNode* n3 = elem->GetNode(_n3); + SMDS_ElemIteratorPtr volIt1 = n1->GetInverseElementIterator(SMDSAbs_Volume); + while ( volIt1->more() ) + { + const SMDS_MeshElement* v = volIt1->next(); + SMDSAbs_EntityType type = v->GetEntityType(); + if ( type != SMDSEntity_Tetra && type != SMDSEntity_Quad_Tetra ) + continue; + if ( type == SMDSEntity_Quad_Tetra && v->GetNodeIndex( n1 ) > 3 ) + continue; // medium node not allowed + const int ind2 = v->GetNodeIndex( n2 ); + if ( ind2 < 0 || 3 < ind2 ) + continue; + const int ind3 = v->GetNodeIndex( n3 ); + if ( ind3 < 0 || 3 < ind3 ) + continue; + return true; + } + return false; + } + + //======================================================================= + /*! + * \brief A key of a face of volume + */ + //======================================================================= + + struct TVolumeFaceKey: pair< pair< int, int>, pair< int, int> > + { + TVolumeFaceKey( SMDS_VolumeTool& vol, int iF ) + { + TIDSortedNodeSet sortedNodes; + const int iQ = vol.Element()->IsQuadratic() ? 2 : 1; + int nbNodes = vol.NbFaceNodes( iF ); + const SMDS_MeshNode** fNodes = vol.GetFaceNodes( iF ); + for ( int i = 0; i < nbNodes; i += iQ ) + sortedNodes.insert( fNodes[i] ); + TIDSortedNodeSet::iterator n = sortedNodes.begin(); + first.first = (*(n++))->GetID(); + first.second = (*(n++))->GetID(); + second.first = (*(n++))->GetID(); + second.second = ( sortedNodes.size() > 3 ) ? (*(n++))->GetID() : 0; + } + }; +} // namespace + +//======================================================================= +//function : SplitVolumesIntoTetra +//purpose : Split volume elements into tetrahedra. +//======================================================================= + +void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, + const int theMethodFlags) +{ + // std-like iterator on coordinates of nodes of mesh element + typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > NXyzIterator; + NXyzIterator xyzEnd; + + SMDS_VolumeTool volTool; + SMESH_MesherHelper helper( *GetMesh()); + + SMESHDS_SubMesh* subMesh = 0;//GetMeshDS()->MeshElements(1); + SMESHDS_SubMesh* fSubMesh = 0;//subMesh; + + SMESH_SequenceOfElemPtr newNodes, newElems; + + // map face of volume to it's baricenrtic node + map< TVolumeFaceKey, const SMDS_MeshNode* > volFace2BaryNode; + double bc[3]; + + TIDSortedElemSet::const_iterator elem = theElems.begin(); + for ( ; elem != theElems.end(); ++elem ) + { + if ( (*elem)->GetType() != SMDSAbs_Volume ) + continue; + SMDSAbs_EntityType geomType = (*elem)->GetEntityType(); + if ( geomType == SMDSEntity_Tetra || geomType == SMDSEntity_Quad_Tetra ) + continue; + + if ( !volTool.Set( *elem, /*ignoreCentralNodes=*/false )) continue; // strange... + + TSplitMethod splitMethod = getSplitMethod( volTool, theMethodFlags ); + if ( splitMethod._nbTetra < 1 ) continue; + + // find submesh to add new tetras to + if ( !subMesh || !subMesh->Contains( *elem )) + { + int shapeID = FindShape( *elem ); + helper.SetSubShape( shapeID ); // helper will add tetras to the found submesh + subMesh = GetMeshDS()->MeshElements( shapeID ); + } + int iQ; + if ( (*elem)->IsQuadratic() ) + { + iQ = 2; + // add quadratic links to the helper + for ( int iF = 0; iF < volTool.NbFaces(); ++iF ) + { + const SMDS_MeshNode** fNodes = volTool.GetFaceNodes( iF ); + int nbN = volTool.NbFaceNodes( iF ) - bool( volTool.GetCenterNodeIndex(iF) > 0 ); + for ( int iN = 0; iN < nbN; iN += iQ ) + helper.AddTLinkNode( fNodes[iN], fNodes[iN+2], fNodes[iN+1] ); + } + helper.SetIsQuadratic( true ); + } + else + { + iQ = 1; + helper.SetIsQuadratic( false ); + } + vector nodes( (*elem)->begin_nodes(), (*elem)->end_nodes() ); + helper.SetElementsOnShape( true ); + if ( splitMethod._baryNode ) + { + // make a node at barycenter + volTool.GetBaryCenter( bc[0], bc[1], bc[2] ); + SMDS_MeshNode* gcNode = helper.AddNode( bc[0], bc[1], bc[2] ); + nodes.push_back( gcNode ); + newNodes.Append( gcNode ); + } + if ( !splitMethod._faceBaryNode.empty() ) + { + // make or find baricentric nodes of faces + map::iterator iF_n = splitMethod._faceBaryNode.begin(); + for ( ; iF_n != splitMethod._faceBaryNode.end(); ++iF_n ) + { + map< TVolumeFaceKey, const SMDS_MeshNode* >::iterator f_n = + volFace2BaryNode.insert + ( make_pair( TVolumeFaceKey( volTool,iF_n->first ), iF_n->second )).first; + if ( !f_n->second ) + { + volTool.GetFaceBaryCenter( iF_n->first, bc[0], bc[1], bc[2] ); + newNodes.Append( f_n->second = helper.AddNode( bc[0], bc[1], bc[2] )); + } + nodes.push_back( iF_n->second = f_n->second ); + } + } + + // make tetras + vector tetras( splitMethod._nbTetra ); // splits of a volume + const int* tetConn = splitMethod._connectivity; + for ( int i = 0; i < splitMethod._nbTetra; ++i, tetConn += 4 ) + newElems.Append( tetras[ i ] = helper.AddVolume( nodes[ tetConn[0] ], + nodes[ tetConn[1] ], + nodes[ tetConn[2] ], + nodes[ tetConn[3] ])); + + ReplaceElemInGroups( *elem, tetras, GetMeshDS() ); + + // Split faces on sides of the split volume + + const SMDS_MeshNode** volNodes = volTool.GetNodes(); + for ( int iF = 0; iF < volTool.NbFaces(); ++iF ) + { + const int nbNodes = volTool.NbFaceNodes( iF ) / iQ; + if ( nbNodes < 4 ) continue; + + // find an existing face + vector fNodes( volTool.GetFaceNodes( iF ), + volTool.GetFaceNodes( iF ) + volTool.NbFaceNodes( iF )); + while ( const SMDS_MeshElement* face = GetMeshDS()->FindElement( fNodes, SMDSAbs_Face, + /*noMedium=*/false)) + { + // make triangles + helper.SetElementsOnShape( false ); + vector< const SMDS_MeshElement* > triangles; + + // find submesh to add new triangles in + if ( !fSubMesh || !fSubMesh->Contains( face )) + { + int shapeID = FindShape( face ); + fSubMesh = GetMeshDS()->MeshElements( shapeID ); + } + map::iterator iF_n = splitMethod._faceBaryNode.find(iF); + if ( iF_n != splitMethod._faceBaryNode.end() ) + { + for ( int iN = 0; iN < nbNodes*iQ; iN += iQ ) + { + const SMDS_MeshNode* n1 = fNodes[iN]; + const SMDS_MeshNode *n2 = fNodes[(iN+iQ)%(nbNodes*iQ)]; + const SMDS_MeshNode *n3 = iF_n->second; + if ( !volTool.IsFaceExternal( iF )) + swap( n2, n3 ); + triangles.push_back( helper.AddFace( n1,n2,n3 )); + + if ( fSubMesh && n3->getshapeId() < 1 ) + fSubMesh->AddNode( n3 ); + } + } + else + { + // among possible triangles create ones discribed by split method + const int* nInd = volTool.GetFaceNodesIndices( iF ); + int nbVariants = ( nbNodes == 4 ? 2 : nbNodes ); + int iCom = 0; // common node of triangle faces to split into + list< TTriangleFacet > facets; + for ( int iVar = 0; iVar < nbVariants; ++iVar, ++iCom ) + { + TTriangleFacet t012( nInd[ iQ * ( iCom )], + nInd[ iQ * ( (iCom+1)%nbNodes )], + nInd[ iQ * ( (iCom+2)%nbNodes )]); + TTriangleFacet t023( nInd[ iQ * ( iCom )], + nInd[ iQ * ( (iCom+2)%nbNodes )], + nInd[ iQ * ( (iCom+3)%nbNodes )]); + if ( splitMethod.hasFacet( t012 ) && splitMethod.hasFacet( t023 )) + { + facets.push_back( t012 ); + facets.push_back( t023 ); + for ( int iLast = iCom+4; iLast < iCom+nbNodes; ++iLast ) + facets.push_back( TTriangleFacet( nInd[ iQ * ( iCom )], + nInd[ iQ * ((iLast-1)%nbNodes )], + nInd[ iQ * ((iLast )%nbNodes )])); + break; + } + } + list< TTriangleFacet >::iterator facet = facets.begin(); + for ( ; facet != facets.end(); ++facet ) + { + if ( !volTool.IsFaceExternal( iF )) + swap( facet->_n2, facet->_n3 ); + triangles.push_back( helper.AddFace( volNodes[ facet->_n1 ], + volNodes[ facet->_n2 ], + volNodes[ facet->_n3 ])); + } + } + for ( int i = 0; i < triangles.size(); ++i ) + { + if ( !triangles[i] ) continue; + if ( fSubMesh ) + fSubMesh->AddElement( triangles[i]); + newElems.Append( triangles[i] ); + } + ReplaceElemInGroups( face, triangles, GetMeshDS() ); + GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false ); + } + + } // loop on volume faces to split them into triangles + + GetMeshDS()->RemoveFreeElement( *elem, subMesh, /*fromGroups=*/false ); + + if ( geomType == SMDSEntity_TriQuad_Hexa ) + { + // remove medium nodes that could become free + for ( int i = 20; i < volTool.NbNodes(); ++i ) + if ( volNodes[i]->NbInverseElements() == 0 ) + GetMeshDS()->RemoveNode( volNodes[i] ); + } + } // loop on volumes to split + + myLastCreatedNodes = newNodes; + myLastCreatedElems = newElems; +} + +//======================================================================= +//function : AddToSameGroups +//purpose : add elemToAdd to the groups the elemInGroups belongs to +//======================================================================= + +void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd, + const SMDS_MeshElement* elemInGroups, + SMESHDS_Mesh * aMesh) +{ + const set& groups = aMesh->GetGroups(); + if (!groups.empty()) { + set::const_iterator grIt = groups.begin(); + for ( ; grIt != groups.end(); grIt++ ) { + SMESHDS_Group* group = dynamic_cast( *grIt ); + if ( group && group->Contains( elemInGroups )) + group->SMDSGroup().Add( elemToAdd ); + } + } +} + + +//======================================================================= +//function : RemoveElemFromGroups +//purpose : Remove removeelem to the groups the elemInGroups belongs to +//======================================================================= +void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem, + SMESHDS_Mesh * aMesh) +{ + const set& groups = aMesh->GetGroups(); + if (!groups.empty()) + { + set::const_iterator GrIt = groups.begin(); + for (; GrIt != groups.end(); GrIt++) + { + SMESHDS_Group* grp = dynamic_cast(*GrIt); + if (!grp || grp->IsEmpty()) continue; + grp->SMDSGroup().Remove(removeelem); + } + } +} + +//================================================================================ +/*! + * \brief Replace elemToRm by elemToAdd in the all groups + */ +//================================================================================ + +void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* elemToRm, + const SMDS_MeshElement* elemToAdd, + SMESHDS_Mesh * aMesh) +{ + const set& groups = aMesh->GetGroups(); + if (!groups.empty()) { + set::const_iterator grIt = groups.begin(); + for ( ; grIt != groups.end(); grIt++ ) { + SMESHDS_Group* group = dynamic_cast( *grIt ); + if ( group && group->SMDSGroup().Remove( elemToRm ) && elemToAdd ) + group->SMDSGroup().Add( elemToAdd ); + } + } +} + +//================================================================================ +/*! + * \brief Replace elemToRm by elemToAdd in the all groups + */ +//================================================================================ + +void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* elemToRm, + const vector& elemToAdd, + SMESHDS_Mesh * aMesh) +{ + const set& groups = aMesh->GetGroups(); + if (!groups.empty()) + { + set::const_iterator grIt = groups.begin(); + for ( ; grIt != groups.end(); grIt++ ) { + SMESHDS_Group* group = dynamic_cast( *grIt ); + if ( group && group->SMDSGroup().Remove( elemToRm ) ) + for ( int i = 0; i < elemToAdd.size(); ++i ) + group->SMDSGroup().Add( elemToAdd[ i ] ); + } + } +} + +//======================================================================= +//function : QuadToTri +//purpose : Cut quadrangles into triangles. +// theCrit is used to select a diagonal to cut +//======================================================================= + +bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, + const bool the13Diag) +{ + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + + MESSAGE( "::QuadToTri()" ); + + SMESHDS_Mesh * aMesh = GetMeshDS(); + + Handle(Geom_Surface) surface; + SMESH_MesherHelper helper( *GetMesh() ); TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { @@ -1240,20 +2052,28 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, aNodes[ i++ ] = static_cast( itN->next() ); int aShapeId = FindShape( elem ); - const SMDS_MeshElement* newElem = 0; + const SMDS_MeshElement* newElem1 = 0; + const SMDS_MeshElement* newElem2 = 0; if ( the13Diag ) { - aMesh->ChangeElementNodes( elem, aNodes, 3 ); - newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); + newElem1 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] ); + newElem2 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] ); } else { - aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); - newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); + newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] ); } - myLastCreatedElems.Append(newElem); + myLastCreatedElems.Append(newElem1); + myLastCreatedElems.Append(newElem2); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); - AddToSameGroups( newElem, elem, aMesh ); + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } + AddToSameGroups( newElem1, elem, aMesh ); + AddToSameGroups( newElem2, elem, aMesh ); + //aMesh->RemoveFreeElement(elem, aMesh->MeshElements(aShapeId), true); + aMesh->RemoveElement( elem ); } // Quadratic quadrangle @@ -1308,34 +2128,31 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems, myLastCreatedNodes.Append(newN); // create a new element - const SMDS_MeshElement* newElem = 0; - const SMDS_MeshNode* N[6]; + const SMDS_MeshElement* newElem1 = 0; + const SMDS_MeshElement* newElem2 = 0; if ( the13Diag ) { - N[0] = aNodes[0]; - N[1] = aNodes[1]; - N[2] = aNodes[2]; - N[3] = aNodes[4]; - N[4] = aNodes[5]; - N[5] = newN; - newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], - aNodes[6], aNodes[7], newN ); + newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0], + aNodes[6], aNodes[7], newN ); + newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1], + newN, aNodes[4], aNodes[5] ); } else { - N[0] = aNodes[1]; - N[1] = aNodes[2]; - N[2] = aNodes[3]; - N[3] = aNodes[5]; - N[4] = aNodes[6]; - N[5] = newN; - newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], - aNodes[7], aNodes[4], newN ); + newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], + aNodes[7], aNodes[4], newN ); + newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2], + newN, aNodes[5], aNodes[6] ); } - myLastCreatedElems.Append(newElem); - aMesh->ChangeElementNodes( elem, N, 6 ); + myLastCreatedElems.Append(newElem1); + myLastCreatedElems.Append(newElem2); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) - aMesh->SetMeshElementOnShape( newElem, aShapeId ); - AddToSameGroups( newElem, elem, aMesh ); + { + aMesh->SetMeshElementOnShape( newElem1, aShapeId ); + aMesh->SetMeshElementOnShape( newElem2, aShapeId ); + } + AddToSameGroups( newElem1, elem, aMesh ); + AddToSameGroups( newElem2, elem, aMesh ); + aMesh->RemoveElement( elem ); } } @@ -1352,7 +2169,7 @@ double getAngle(const SMDS_MeshElement * tr1, const SMDS_MeshNode * n1, const SMDS_MeshNode * n2) { - double angle = 2*PI; // bad angle + double angle = 2. * M_PI; // bad angle // get normals SMESH::Controls::TSequenceOfXYZ P1, P2; @@ -1381,7 +2198,7 @@ double getAngle(const SMDS_MeshElement * tr1, int i = 0, iDiag = -1; while ( it->more()) { const SMDS_MeshElement *n = it->next(); - if ( n == n1 || n == n2 ) + if ( n == n1 || n == n2 ) { if ( iDiag < 0) iDiag = i; else { @@ -1391,6 +2208,7 @@ double getAngle(const SMDS_MeshElement * tr1, nFirst[ t ] = n; break; } + } i++; } } @@ -1407,7 +2225,7 @@ double getAngle(const SMDS_MeshElement * tr1, // and able to return nodes by that ID // ================================================= class LinkID_Gen { - public: +public: LinkID_Gen( const SMESHDS_Mesh* theMesh ) :myMesh( theMesh ), myMaxID( theMesh->MaxNodeID() + 1) @@ -1430,7 +2248,7 @@ class LinkID_Gen { return true; } - private: +private: LinkID_Gen(); const SMESHDS_Mesh* myMesh; long myMaxID; @@ -1631,16 +2449,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, mapEl_setLi.erase( tr2 ); mapLi_listEl.erase( *link12 ); if(tr1->NbNodes()==3) { - if( tr1->GetID() < tr2->GetID() ) { - aMesh->ChangeElementNodes( tr1, n12, 4 ); - myLastCreatedElems.Append(tr1); - aMesh->RemoveElement( tr2 ); - } - else { - aMesh->ChangeElementNodes( tr2, n12, 4 ); - myLastCreatedElems.Append(tr2); - aMesh->RemoveElement( tr1); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(n12[0], n12[1], n12[2], n12[3] ); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr2 ); } else { const SMDS_MeshNode* N1 [6]; @@ -1658,16 +2477,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, aNodes[5] = N2[5]; aNodes[6] = N2[3]; aNodes[7] = N1[5]; - if( tr1->GetID() < tr2->GetID() ) { - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr2 ); - } - else { - GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 ); - myLastCreatedElems.Append(tr2); - GetMeshDS()->RemoveElement( tr1 ); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3], + aNodes[4], aNodes[5], aNodes[6], aNodes[7]); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr2 ); // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); } @@ -1676,16 +2497,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, mapEl_setLi.erase( tr3 ); mapLi_listEl.erase( *link13 ); if(tr1->NbNodes()==3) { - if( tr1->GetID() < tr2->GetID() ) { - aMesh->ChangeElementNodes( tr1, n13, 4 ); - myLastCreatedElems.Append(tr1); - aMesh->RemoveElement( tr3 ); - } - else { - aMesh->ChangeElementNodes( tr3, n13, 4 ); - myLastCreatedElems.Append(tr3); - aMesh->RemoveElement( tr1 ); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(n13[0], n13[1], n13[2], n13[3] ); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr3 ); } else { const SMDS_MeshNode* N1 [6]; @@ -1703,16 +2525,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, aNodes[5] = N2[5]; aNodes[6] = N2[3]; aNodes[7] = N1[5]; - if( tr1->GetID() < tr2->GetID() ) { - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - myLastCreatedElems.Append(tr1); - GetMeshDS()->RemoveElement( tr3 ); - } - else { - GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 ); - myLastCreatedElems.Append(tr3); - GetMeshDS()->RemoveElement( tr1 ); - } + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3], + aNodes[4], aNodes[5], aNodes[6], aNodes[7]); + myLastCreatedElems.Append(newElem); + AddToSameGroups( newElem, tr1, aMesh ); + int aShapeId = tr1->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + aMesh->RemoveElement( tr1 ); + aMesh->RemoveElement( tr3 ); // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); } @@ -1739,15 +2563,15 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, //============================================================================= static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] ) { - if ( i1 == i2 ) - return; - int tmp = idNodes[ i1 ]; - idNodes[ i1 ] = idNodes[ i2 ]; - idNodes[ i2 ] = tmp; - gp_Pnt Ptmp = P[ i1 ]; - P[ i1 ] = P[ i2 ]; - P[ i2 ] = Ptmp; - DUMPSO( i1 << "(" << idNodes[ i2 ] << ") <-> " << i2 << "(" << idNodes[ i1 ] << ")"); +if ( i1 == i2 ) +return; +int tmp = idNodes[ i1 ]; +idNodes[ i1 ] = idNodes[ i2 ]; +idNodes[ i2 ] = tmp; +gp_Pnt Ptmp = P[ i1 ]; +P[ i1 ] = P[ i2 ]; +P[ i2 ] = Ptmp; +DUMPSO( i1 << "(" << idNodes[ i2 ] << ") <-> " << i2 << "(" << idNodes[ i1 ] << ")"); } //======================================================================= @@ -1758,7 +2582,7 @@ static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] ) //======================================================================= int SMESH_MeshEditor::SortQuadNodes (const SMDS_Mesh * theMesh, - int idNodes[] ) +int idNodes[] ) { gp_Pnt P[4]; int i; @@ -1787,10 +2611,10 @@ int SMESH_MeshEditor::SortQuadNodes (const SMDS_Mesh * theMesh, i = 1; swap ( i, i + 1, idNodes, P ); -// for ( int ii = 0; ii < 4; ii++ ) { -// const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] ); -// DUMPSO( ii << "(" << idNodes[ii] <<") : "<X()<<" "<Y()<<" "<Z()); -// } + // for ( int ii = 0; ii < 4; ii++ ) { + // const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] ); + // DUMPSO( ii << "(" << idNodes[ii] <<") : "<X()<<" "<Y()<<" "<Z()); + // } } return i; } @@ -1906,7 +2730,7 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh, faceNodes.insert( idNodes[ 2 ] ); faceNodes.insert( idNodes[ iMin ] ); DUMPSO( "loop " << iLoop2 << " id2 " << idNodes[ 1 ] << " id3 " << idNodes[ 2 ] - << " leastDist = " << leastDist); + << " leastDist = " << leastDist); if ( leastDist <= DBL_MIN ) break; } @@ -1944,11 +2768,11 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh, P[ i ] = P[ i+1 ]; P[ i+1 ] = Ptmp; } -// else -// for ( int ii = 0; ii < 4; ii++ ) { -// const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] ); -// DUMPSO( ii << "(" << idNodes[ii] <<") : "<X()<<" "<Y()<<" "<Z()); -// } + // else + // for ( int ii = 0; ii < 4; ii++ ) { + // const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] ); + // DUMPSO( ii << "(" << idNodes[ii] <<") : "<X()<<" "<Y()<<" "<Z()); + // } // Gravity center of the top and bottom faces gp_Pnt aGCb = ( P[0].XYZ() + P[1].XYZ() + P[2].XYZ() + P[3].XYZ() ) / 4.; @@ -2000,11 +2824,11 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh, swap( 5, 7, idNodes, P ); } -// DUMPSO( "OUTPUT: ========================================"); -// for ( i = 0; i < 8; i++ ) { -// float *p = ugrid->GetPoint(idNodes[i]); -// DUMPSO( i << "(" << idNodes[i] << ") : " << p[0] << " " << p[1] << " " << p[2]); -// } + // DUMPSO( "OUTPUT: ========================================"); + // for ( i = 0; i < 8; i++ ) { + // float *p = ugrid->GetPoint(idNodes[i]); + // DUMPSO( i << "(" << idNodes[i] << ") : " << p[0] << " " << p[1] << " " << p[2]); + // } return true; }*/ @@ -2012,11 +2836,11 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh, //================================================================================ /*! * \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 + * \param theNode - the node + * \param linkedNodes - the found nodes + * \param type - the type of elements to check + * + * Medium nodes are ignored */ //================================================================================ @@ -2028,6 +2852,9 @@ void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode, while ( elemIt->more() ) { const SMDS_MeshElement* elem = elemIt->next(); + if(elem->GetType() == SMDSAbs_0DElement) + continue; + SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); if ( elem->GetType() == SMDSAbs_Volume ) { @@ -2050,8 +2877,8 @@ void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode, iAfter = SMESH_MesherHelper::WrapIndex( iAfter, nb ); iBefore = SMESH_MesherHelper::WrapIndex( iBefore, nb ); } - linkedNodes.insert( elem->GetNode( iAfter )); - linkedNodes.insert( elem->GetNode( iBefore )); + linkedNodes.insert( elem->GetNodeWrap( iAfter )); + linkedNodes.insert( elem->GetNodeWrap( iBefore )); } } } @@ -2184,8 +3011,13 @@ static bool getClosestUV (Extrema_GenExtPS& projector, if ( projector.IsDone() ) { double u, v, minVal = DBL_MAX; for ( int i = projector.NbExt(); i > 0; i-- ) +#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 + if ( projector.SquareDistance( i ) < minVal ) { + minVal = projector.SquareDistance( i ); +#else if ( projector.Value( i ) < minVal ) { minVal = projector.Value( i ); +#endif projector.Point( i ).Parameter( u, v ); } result.SetCoord( u, v ); @@ -2260,7 +3092,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, Handle(Geom_Surface) surface; SMESHDS_SubMesh* faceSubMesh = 0; TopoDS_Face face; - double fToler2 = 0, vPeriod = 0., uPeriod = 0., f,l; + double fToler2 = 0, f,l; double u1 = 0, u2 = 0, v1 = 0, v2 = 0; bool isUPeriodic = false, isVPeriodic = false; if ( *fId ) { @@ -2271,10 +3103,10 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, fToler2 *= fToler2 * 10.; isUPeriodic = surface->IsUPeriodic(); if ( isUPeriodic ) - vPeriod = surface->UPeriod(); + surface->UPeriod(); isVPeriodic = surface->IsVPeriodic(); if ( isVPeriodic ) - uPeriod = surface->VPeriod(); + surface->VPeriod(); surface->Bounds( u1, u2, v1, v2 ); } // --------------------------------------------------------- @@ -2296,14 +3128,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, } int nbElemOnFace = 0; itElem = theElems.begin(); - // loop on not yet smoothed elements: look for elems on a face + // loop on not yet smoothed elements: look for elems on a face while ( itElem != theElems.end() ) { if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() ) break; // all elements found const SMDS_MeshElement* elem = *itElem; if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 || - ( faceSubMesh && !faceSubMesh->Contains( elem ))) { + ( faceSubMesh && !faceSubMesh->Contains( elem ))) { ++itElem; continue; } @@ -2324,7 +3156,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, while ( nn++ < nbn ) { node = static_cast( itN->next() ); const SMDS_PositionPtr& pos = node->GetPosition(); - posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; + posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; if (posType != SMDS_TOP_EDGE && posType != SMDS_TOP_VERTEX && theFixedNodes.find( node ) == theFixedNodes.end()) @@ -2362,19 +3194,19 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, if ( uvMap.find( node ) == uvMap.end() ) uvCheckNodes.push_back( node ); // add nodes of elems sharing node -// SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face); -// while ( eIt->more() ) { -// const SMDS_MeshElement* e = eIt->next(); -// if ( e != elem ) { -// SMDS_ElemIteratorPtr nIt = e->nodesIterator(); -// while ( nIt->more() ) { -// const SMDS_MeshNode* n = -// static_cast( nIt->next() ); -// if ( uvMap.find( n ) == uvMap.end() ) -// uvCheckNodes.push_back( n ); -// } -// } -// } + // SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face); + // while ( eIt->more() ) { + // const SMDS_MeshElement* e = eIt->next(); + // if ( e != elem ) { + // SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + // while ( nIt->more() ) { + // const SMDS_MeshNode* n = + // static_cast( nIt->next() ); + // if ( uvMap.find( n ) == uvMap.end() ) + // uvCheckNodes.push_back( n ); + // } + // } + // } } // check UV on face list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin(); @@ -2382,27 +3214,27 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, node = *n; gp_XY uv( 0, 0 ); const SMDS_PositionPtr& pos = node->GetPosition(); - posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; + posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE; // get existing UV switch ( posType ) { case SMDS_TOP_FACE: { - SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get(); + SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos; uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() ); break; } case SMDS_TOP_EDGE: { - TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() ); + TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() ); Handle(Geom2d_Curve) pcurve; if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE ) pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l ); if ( !pcurve.IsNull() ) { - double u = (( SMDS_EdgePosition* ) pos.get() )->GetUParameter(); + double u = (( SMDS_EdgePosition* ) pos )->GetUParameter(); uv = pcurve->Value( u ).XY(); } break; } case SMDS_TOP_VERTEX: { - TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() ); + TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() ); if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX ) uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY(); break; @@ -2446,35 +3278,27 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, // fix nodes on mesh boundary if ( checkBoundaryNodes ) { - map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace - map< NLink, int >::iterator link_nb; + map< SMESH_TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace + map< SMESH_TLink, int >::iterator link_nb; // put all elements links to linkNbMap list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { const SMDS_MeshElement* elem = (*elemIt); - int nbn = elem->NbNodes(); - if(elem->IsQuadratic()) - nbn = nbn/2; + int nbn = elem->NbCornerNodes(); // loop on elem links: insert them in linkNbMap - const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn ); for ( int iN = 0; iN < nbn; ++iN ) { - curNode = elem->GetNode( iN ); - NLink link; - if ( curNode < prevNode ) link = make_pair( curNode , prevNode ); - else link = make_pair( prevNode , curNode ); - prevNode = curNode; - link_nb = linkNbMap.find( link ); - if ( link_nb == linkNbMap.end() ) - linkNbMap.insert( make_pair ( link, 1 )); - else - link_nb->second++; + const SMDS_MeshNode* n1 = elem->GetNode( iN ); + const SMDS_MeshNode* n2 = elem->GetNode(( iN+1 ) % nbn); + SMESH_TLink link( n1, n2 ); + link_nb = linkNbMap.insert( make_pair( link, 0 )).first; + link_nb->second++; } } // remove nodes that are in links encountered only once from setMovableNodes for ( link_nb = linkNbMap.begin(); link_nb != linkNbMap.end(); ++link_nb ) { if ( link_nb->second == 1 ) { - setMovableNodes.erase( link_nb->first.first ); - setMovableNodes.erase( link_nb->first.second ); + setMovableNodes.erase( link_nb->first.node1() ); + setMovableNodes.erase( link_nb->first.node2() ); } } } @@ -2665,7 +3489,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, if ( node_uv != uvMap.end() ) { gp_XY* uv = node_uv->second; node->SetPosition - ( SMDS_PositionPtr( new SMDS_FacePosition( *fId, uv->X(), uv->Y() ))); + ( SMDS_PositionPtr( new SMDS_FacePosition( uv->X(), uv->Y() ))); } } @@ -2677,14 +3501,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, helper.SetSubShape( face ); list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin(); for ( ; elemIt != elemsOnFace.end(); ++elemIt ) { - const SMDS_QuadraticFaceOfNodes* QF = - dynamic_cast (*elemIt); - if(QF) { + const SMDS_VtkFace* QF = + dynamic_cast (*elemIt); + if(QF && QF->IsQuadratic()) { vector Ns; Ns.reserve(QF->NbNodes()+1); - SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = QF->interlacedNodesElemIterator(); while ( anIter->more() ) - Ns.push_back( anIter->next() ); + Ns.push_back( cast2Node(anIter->next()) ); Ns.push_back( Ns[0] ); double x, y, z; for(int i=0; iNbNodes(); i=i+2) { @@ -2719,30 +3543,22 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, //function : isReverse //purpose : Return true if normal of prevNodes is not co-directied with // gp_Vec(prevNodes[iNotSame],nextNodes[iNotSame]). -// iNotSame is where prevNodes and nextNodes are different +// iNotSame is where prevNodes and nextNodes are different. +// If result is true then future volume orientation is OK //======================================================================= -static bool isReverse(vector prevNodes, - vector nextNodes, - const int nbNodes, - const int iNotSame) +static bool isReverse(const SMDS_MeshElement* face, + const vector& prevNodes, + const vector& nextNodes, + const int iNotSame) { - int iBeforeNotSame = ( iNotSame == 0 ? nbNodes - 1 : iNotSame - 1 ); - int iAfterNotSame = ( iNotSame + 1 == nbNodes ? 0 : iNotSame + 1 ); - - const SMDS_MeshNode* nB = prevNodes[ iBeforeNotSame ]; - const SMDS_MeshNode* nA = prevNodes[ iAfterNotSame ]; - const SMDS_MeshNode* nP = prevNodes[ iNotSame ]; - const SMDS_MeshNode* nN = nextNodes[ iNotSame ]; - gp_Pnt pB ( nB->X(), nB->Y(), nB->Z() ); - gp_Pnt pA ( nA->X(), nA->Y(), nA->Z() ); - gp_Pnt pP ( nP->X(), nP->Y(), nP->Z() ); - gp_Pnt pN ( nN->X(), nN->Y(), nN->Z() ); + SMESH_TNodeXYZ pP = prevNodes[ iNotSame ]; + SMESH_TNodeXYZ pN = nextNodes[ iNotSame ]; + gp_XYZ extrDir( pN - pP ), faceNorm; + SMESH_Algo::FaceNormal( face, faceNorm, /*normalized=*/false ); - gp_Vec vB ( pP, pB ), vA ( pP, pA ), vN ( pP, pN ); - - return (vA ^ vB) * vN < 0.0; + return faceNorm * extrDir < 0.0; } //======================================================================= @@ -2762,296 +3578,413 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, const int nbSteps, SMESH_SequenceOfElemPtr& srcElements) { + //MESSAGE("sweepElement " << nbSteps); SMESHDS_Mesh* aMesh = GetMeshDS(); + const int nbNodes = elem->NbNodes(); + const int nbCorners = elem->NbCornerNodes(); + SMDSAbs_EntityType baseType = elem->GetEntityType(); /* it can change in case of + polyhedron creation !!! */ // Loop on elem nodes: // find new nodes and detect same nodes indices - int nbNodes = elem->NbNodes(); vector < list< const SMDS_MeshNode* >::const_iterator > itNN( nbNodes ); vector prevNod( nbNodes ); vector nextNod( nbNodes ); vector midlNod( nbNodes ); - int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0; + int iNode, nbSame = 0, nbDouble = 0, iNotSameNode = 0; vector sames(nbNodes); - - //bool issimple[nbNodes]; - vector issimple(nbNodes); + vector isSingleNode(nbNodes); for ( iNode = 0; iNode < nbNodes; iNode++ ) { - TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ]; - const SMDS_MeshNode* node = nnIt->first; + TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ]; + const SMDS_MeshNode* node = nnIt->first; const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second; if ( listNewNodes.empty() ) return; - if(listNewNodes.size()==nbSteps) { - issimple[iNode] = true; - } - else { - issimple[iNode] = false; - } - - itNN[ iNode ] = listNewNodes.begin(); + itNN [ iNode ] = listNewNodes.begin(); prevNod[ iNode ] = node; nextNod[ iNode ] = listNewNodes.front(); -//cout<<"iNode="<GetID() ); return; } -// if( elem->IsQuadratic() && nbSame>0 ) { -// MESSAGE( "Can not rotate quadratic element " << elem->GetID() ); -// return; -// } - - int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0; - if ( nbSame > 0 ) { - iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 ); - iAfterSame = ( iSameNode + 1 == nbNodes ? 0 : iSameNode + 1 ); - iOpposSame = ( iSameNode - 2 < 0 ? iSameNode + 2 : iSameNode - 2 ); + if ( elem->GetType() == SMDSAbs_Face && !isReverse( elem, prevNod, nextNod, iNotSameNode )) + { + // fix nodes order to have bottom normal external + if ( baseType == SMDSEntity_Polygon ) + { + std::reverse( itNN.begin(), itNN.end() ); + std::reverse( prevNod.begin(), prevNod.end() ); + std::reverse( midlNod.begin(), midlNod.end() ); + std::reverse( nextNod.begin(), nextNod.end() ); + std::reverse( isSingleNode.begin(), isSingleNode.end() ); + } + else + { + const vector& ind = SMDS_MeshCell::reverseSmdsOrder( baseType ); + SMDS_MeshCell::applyInterlace( ind, itNN ); + SMDS_MeshCell::applyInterlace( ind, prevNod ); + SMDS_MeshCell::applyInterlace( ind, nextNod ); + SMDS_MeshCell::applyInterlace( ind, midlNod ); + SMDS_MeshCell::applyInterlace( ind, isSingleNode ); + if ( nbSame > 0 ) + { + sames[nbSame] = iNotSameNode; + for ( int j = 0; j <= nbSame; ++j ) + for ( size_t i = 0; i < ind.size(); ++i ) + if ( ind[i] == sames[j] ) + { + sames[j] = i; + break; + } + iNotSameNode = sames[nbSame]; + } + } } -//if(nbNodes==8) -//cout<<" prevNod[0]="<< prevNod[0]<<" prevNod[1]="<< prevNod[1] -// <<" prevNod[2]="<< prevNod[2]<<" prevNod[3]="<< prevNod[4] -// <<" prevNod[4]="<< prevNod[4]<<" prevNod[5]="<< prevNod[5] -// <<" prevNod[6]="<< prevNod[6]<<" prevNod[7]="<< prevNod[7]< 2 && !isReverse( prevNod, nextNod, nbNodes, iNotSameNode )) { - //MESSAGE("Reversed elem " << elem ); - i0 = 2; - i2 = 0; - if ( nbSame > 0 ) { - int iAB = iAfterSame + iBeforeSame; - iBeforeSame = iAB - iBeforeSame; - iAfterSame = iAB - iAfterSame; - } + int iSameNode = 0, iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0; + if ( nbSame > 0 ) { + iSameNode = sames[ nbSame-1 ]; + iBeforeSame = ( iSameNode + nbCorners - 1 ) % nbCorners; + iAfterSame = ( iSameNode + 1 ) % nbCorners; + iOpposSame = ( iSameNode - 2 < 0 ? iSameNode + 2 : iSameNode - 2 ); } // make new elements - for (int iStep = 0; iStep < nbSteps; iStep++ ) { + for (int iStep = 0; iStep < nbSteps; iStep++ ) + { // get next nodes - for ( iNode = 0; iNode < nbNodes; iNode++ ) { - if(issimple[iNode]) { - nextNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; - } - else { - if( elem->GetType()==SMDSAbs_Node ) { - // we have to use two nodes - midlNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; - nextNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; - } - else if(!elem->IsQuadratic() || - elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) { - // we have to use each second node - itNN[ iNode ]++; - nextNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; - } - else { - // we have to use two nodes - midlNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; - nextNod[ iNode ] = *itNN[ iNode ]; - itNN[ iNode ]++; - } - } + for ( iNode = 0; iNode < nbNodes; iNode++ ) + { + midlNod[ iNode ] = isSingleNode[iNode] ? 0 : *itNN[ iNode ]++; + nextNod[ iNode ] = *itNN[ iNode ]++; } + SMDS_MeshElement* aNewElem = 0; - if(!elem->IsPoly()) { - switch ( nbNodes ) { - case 0: - return; - case 1: { // NODE + /*if(!elem->IsPoly())*/ { + switch ( baseType ) { + case SMDSEntity_0D: + case SMDSEntity_Node: { // sweep NODE if ( nbSame == 0 ) { - if(issimple[0]) + if ( isSingleNode[0] ) aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] ); else aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ], midlNod[ 0 ] ); } + else + return; break; } - case 2: { // EDGE - if ( nbSame == 0 ) - aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], - nextNod[ 1 ], nextNod[ 0 ] ); - else - aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], - nextNod[ iNotSameNode ] ); + case SMDSEntity_Edge: { // sweep EDGE + if ( nbDouble == 0 ) + { + if ( nbSame == 0 ) // ---> quadrangle + aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], + nextNod[ 1 ], nextNod[ 0 ] ); + else // ---> triangle + aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ], + nextNod[ iNotSameNode ] ); + } + else // ---> polygon + { + vector poly_nodes; + poly_nodes.push_back( prevNod[0] ); + poly_nodes.push_back( prevNod[1] ); + if ( prevNod[1] != nextNod[1] ) + { + if ( midlNod[1]) poly_nodes.push_back( midlNod[1]); + poly_nodes.push_back( nextNod[1] ); + } + if ( prevNod[0] != nextNod[0] ) + { + poly_nodes.push_back( nextNod[0] ); + if ( midlNod[0]) poly_nodes.push_back( midlNod[0]); + } + switch ( poly_nodes.size() ) { + case 3: + aNewElem = aMesh->AddFace( poly_nodes[ 0 ], poly_nodes[ 1 ], poly_nodes[ 2 ]); + break; + case 4: + aNewElem = aMesh->AddFace( poly_nodes[ 0 ], poly_nodes[ 1 ], + poly_nodes[ 2 ], poly_nodes[ 3 ]); + break; + default: + aNewElem = aMesh->AddPolygonalFace (poly_nodes); + } + } break; } - - case 3: { // TRIANGLE or quadratic edge - if(elem->GetType() == SMDSAbs_Face) { // TRIANGLE - - if ( nbSame == 0 ) // --- pentahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], - nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] ); - - else if ( nbSame == 1 ) // --- pyramid - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], - nextNod[ iAfterSame ], nextNod[ iBeforeSame ], + case SMDSEntity_Triangle: // TRIANGLE ---> + { + if ( nbDouble > 0 ) break; + if ( nbSame == 0 ) // ---> pentahedron + aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ], + nextNod[ 0 ], nextNod[ 1 ], nextNod[ 2 ] ); + + else if ( nbSame == 1 ) // ---> pyramid + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], + nextNod[ iAfterSame ], nextNod[ iBeforeSame ], nextNod[ iSameNode ]); - else // 2 same nodes: --- tetrahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], + else // 2 same nodes: ---> tetrahedron + aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ], nextNod[ iNotSameNode ]); + break; } - else { // quadratic edge - if(nbSame==0) { // quadratic quadrangle - aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], nextNod[1], prevNod[1], - midlNod[0], nextNod[2], midlNod[1], prevNod[2]); - } - else if(nbSame==1) { // quadratic triangle - if(sames[0]==2) - return; // medium node on axis - else if(sames[0]==0) { - aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1], - nextNod[2], midlNod[1], prevNod[2]); + case SMDSEntity_Quad_Edge: // sweep quadratic EDGE ---> + { + if ( nbSame == 2 ) + return; + if ( nbDouble+nbSame == 2 ) + { + if(nbSame==0) { // ---> quadratic quadrangle + aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0], + prevNod[2], midlNod[1], nextNod[2], midlNod[0]); + } + else { //(nbSame==1) // ---> quadratic triangle + if(sames[0]==2) { + return; // medium node on axis + } + else if(sames[0]==0) + aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1], + nextNod[2], midlNod[1], prevNod[2]); + else // sames[0]==1 + aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1], + midlNod[0], nextNod[2], prevNod[2]); } - else { // sames[0]==1 - aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1], - midlNod[0], nextNod[2], prevNod[2]); + } + else if ( nbDouble == 3 ) + { + if ( nbSame == 0 ) { // ---> bi-quadratic quadrangle + aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0], + prevNod[2], midlNod[1], nextNod[2], midlNod[0], midlNod[2]); } } else return; + break; } - break; - } - case 4: { // QUADRANGLE + case SMDSEntity_Quadrangle: { // sweep QUADRANGLE ---> + if ( nbDouble > 0 ) break; - if ( nbSame == 0 ) // --- hexahedron - aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ], - nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]); + if ( nbSame == 0 ) // ---> hexahedron + aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ], prevNod[ 3 ], + nextNod[ 0 ], nextNod[ 1 ], nextNod[ 2 ], nextNod[ 3 ]); - else if ( nbSame == 1 ) { // --- pyramid + pentahedron - aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], - nextNod[ iAfterSame ], nextNod[ iBeforeSame ], + else if ( nbSame == 1 ) { // ---> pyramid + pentahedron + aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ], + nextNod[ iAfterSame ], nextNod[ iBeforeSame ], nextNod[ iSameNode ]); newElems.push_back( aNewElem ); - aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ], - prevNod[ iBeforeSame ], nextNod[ iAfterSame ], + aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ], + prevNod[ iBeforeSame ], nextNod[ iAfterSame ], nextNod[ iOpposSame ], nextNod[ iBeforeSame ] ); } - else if ( nbSame == 2 ) { // pentahedron + else if ( nbSame == 2 ) { // ---> pentahedron if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) // iBeforeSame is same too aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ], - nextNod[ iOpposSame ], prevNod[ iSameNode ], + nextNod[ iOpposSame ], prevNod[ iSameNode ], prevNod[ iAfterSame ], nextNod[ iAfterSame ]); else // iAfterSame is same too - aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ], + aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ], nextNod[ iBeforeSame ], prevNod[ iAfterSame ], prevNod[ iOpposSame ], nextNod[ iOpposSame ]); } break; } - case 6: { // quadratic triangle - // create pentahedron with 15 nodes - if(i0>0) { // reversed case - aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1], - nextNod[0], nextNod[2], nextNod[1], - prevNod[5], prevNod[4], prevNod[3], - nextNod[5], nextNod[4], nextNod[3], - midlNod[0], midlNod[2], midlNod[1]); - } - else { // not reversed case + case SMDSEntity_Quad_Triangle: { // sweep Quadratic TRIANGLE ---> + if ( nbDouble+nbSame != 3 ) break; + if(nbSame==0) { + // ---> pentahedron with 15 nodes aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], nextNod[0], nextNod[1], nextNod[2], prevNod[3], prevNod[4], prevNod[5], nextNod[3], nextNod[4], nextNod[5], midlNod[0], midlNod[1], midlNod[2]); } + else if(nbSame==1) { + // ---> 2d order pyramid of 13 nodes + int apex = iSameNode; + int i0 = ( apex + 1 ) % nbCorners; + int i1 = ( apex - 1 + nbCorners ) % nbCorners; + int i0a = apex + 3; + int i1a = i1 + 3; + int i01 = i0 + 3; + aNewElem = aMesh->AddVolume(prevNod[i1], prevNod[i0], + nextNod[i0], nextNod[i1], prevNod[apex], + prevNod[i01], midlNod[i0], + nextNod[i01], midlNod[i1], + prevNod[i1a], prevNod[i0a], + nextNod[i0a], nextNod[i1a]); + } + else if(nbSame==2) { + // ---> 2d order tetrahedron of 10 nodes + int n1 = iNotSameNode; + int n2 = ( n1 + 1 ) % nbCorners; + int n3 = ( n1 + nbCorners - 1 ) % nbCorners; + int n12 = n1 + 3; + int n23 = n2 + 3; + int n31 = n3 + 3; + aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], prevNod[n3], nextNod[n1], + prevNod[n12], prevNod[n23], prevNod[n31], + midlNod[n1], nextNod[n12], nextNod[n31]); + } break; } - case 8: { // quadratic quadrangle - // create hexahedron with 20 nodes - if(i0>0) { // reversed case - aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1], - nextNod[0], nextNod[3], nextNod[2], nextNod[1], - prevNod[7], prevNod[6], prevNod[5], prevNod[4], - nextNod[7], nextNod[6], nextNod[5], nextNod[4], - midlNod[0], midlNod[3], midlNod[2], midlNod[1]); - } - else { // not reversed case + case SMDSEntity_Quad_Quadrangle: { // sweep Quadratic QUADRANGLE ---> + if( nbSame == 0 ) { + if ( nbDouble != 4 ) break; + // ---> hexahedron with 20 nodes aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3], nextNod[0], nextNod[1], nextNod[2], nextNod[3], prevNod[4], prevNod[5], prevNod[6], prevNod[7], nextNod[4], nextNod[5], nextNod[6], nextNod[7], midlNod[0], midlNod[1], midlNod[2], midlNod[3]); } + else if(nbSame==1) { + // ---> pyramid + pentahedron - can not be created since it is needed + // additional middle node at the center of face + INFOS( " Sweep for face " << elem->GetID() << " can not be created" ); + return; + } + else if( nbSame == 2 ) { + if ( nbDouble != 2 ) break; + // ---> 2d order Pentahedron with 15 nodes + int n1,n2,n4,n5; + if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) { + // iBeforeSame is same too + n1 = iBeforeSame; + n2 = iOpposSame; + n4 = iSameNode; + n5 = iAfterSame; + } + else { + // iAfterSame is same too + n1 = iSameNode; + n2 = iBeforeSame; + n4 = iAfterSame; + n5 = iOpposSame; + } + int n12 = n2 + 4; + int n45 = n4 + 4; + int n14 = n1 + 4; + int n25 = n5 + 4; + aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], nextNod[n2], + prevNod[n4], prevNod[n5], nextNod[n5], + prevNod[n12], midlNod[n2], nextNod[n12], + prevNod[n45], midlNod[n5], nextNod[n45], + prevNod[n14], prevNod[n25], nextNod[n25]); + } break; } - default: { - // realized for extrusion only - //vector polyedre_nodes (nbNodes*2 + 4*nbNodes); - //vector quantities (nbNodes + 2); - - //quantities[0] = nbNodes; // bottom of prism - //for (int inode = 0; inode < nbNodes; inode++) { - // polyedre_nodes[inode] = prevNod[inode]; - //} - - //quantities[1] = nbNodes; // top of prism - //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; - // polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface]; - // polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface]; - // polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface]; - // polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface]; - //} - //aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities); + case SMDSEntity_BiQuad_Quadrangle: { // sweep BiQuadratic QUADRANGLE ---> + + if( nbSame == 0 && nbDouble == 9 ) { + // ---> tri-quadratic hexahedron with 27 nodes + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3], + nextNod[0], nextNod[1], nextNod[2], nextNod[3], + prevNod[4], prevNod[5], prevNod[6], prevNod[7], + nextNod[4], nextNod[5], nextNod[6], nextNod[7], + midlNod[0], midlNod[1], midlNod[2], midlNod[3], + prevNod[8], // bottom center + midlNod[4], midlNod[5], midlNod[6], midlNod[7], + nextNod[8], // top center + midlNod[8]);// elem center + } + else + { + return; + } break; } - } - } - - if(!aNewElem) { - // realized for extrusion only - vector polyedre_nodes (nbNodes*2 + 4*nbNodes); - vector quantities (nbNodes + 2); + case SMDSEntity_Polygon: { // sweep POLYGON - quantities[0] = nbNodes; // bottom of prism - for (int inode = 0; inode < nbNodes; inode++) { - polyedre_nodes[inode] = prevNod[inode]; + if ( nbNodes == 6 && nbSame == 0 && nbDouble == 0 ) { + // ---> hexagonal prism + aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], + prevNod[3], prevNod[4], prevNod[5], + nextNod[0], nextNod[1], nextNod[2], + nextNod[3], nextNod[4], nextNod[5]); + } + break; } + case SMDSEntity_Ball: + return; - quantities[1] = nbNodes; // top of prism - for (int inode = 0; inode < nbNodes; inode++) { - polyedre_nodes[nbNodes + inode] = nextNod[inode]; + default: + break; } + } - for (int iface = 0; iface < nbNodes; iface++) { - quantities[iface + 2] = 4; - int inextface = (iface == nbNodes - 1) ? 0 : iface + 1; - polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface]; - polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface]; - polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface]; - polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface]; + if ( !aNewElem && elem->GetType() == SMDSAbs_Face ) // try to create a polyherdal prism + { + if ( baseType != SMDSEntity_Polygon ) + { + const std::vector& ind = SMDS_MeshCell::interlacedSmdsOrder(baseType); + SMDS_MeshCell::applyInterlace( ind, prevNod ); + SMDS_MeshCell::applyInterlace( ind, nextNod ); + SMDS_MeshCell::applyInterlace( ind, midlNod ); + SMDS_MeshCell::applyInterlace( ind, itNN ); + SMDS_MeshCell::applyInterlace( ind, isSingleNode ); + baseType = SMDSEntity_Polygon; // WARNING: change baseType !!!! + } + vector polyedre_nodes (nbNodes*2 + 4*nbNodes); + vector quantities (nbNodes + 2); + polyedre_nodes.clear(); + quantities.clear(); + + // bottom of prism + for (int inode = 0; inode < nbNodes; inode++) + polyedre_nodes.push_back( prevNod[inode] ); + quantities.push_back( nbNodes ); + + // top of prism + polyedre_nodes.push_back( nextNod[0] ); + for (int inode = nbNodes; inode-1; --inode ) + polyedre_nodes.push_back( nextNod[inode-1] ); + quantities.push_back( nbNodes ); + + // side faces + for (int iface = 0; iface < nbNodes; iface++) + { + const int prevNbNodes = polyedre_nodes.size(); + int inextface = (iface+1) % nbNodes; + polyedre_nodes.push_back( prevNod[inextface] ); + polyedre_nodes.push_back( prevNod[iface] ); + if ( prevNod[iface] != nextNod[iface] ) + { + if ( midlNod[ iface ]) polyedre_nodes.push_back( midlNod[ iface ]); + polyedre_nodes.push_back( nextNod[iface] ); + } + if ( prevNod[inextface] != nextNod[inextface] ) + { + polyedre_nodes.push_back( nextNod[inextface] ); + if ( midlNod[ inextface ]) polyedre_nodes.push_back( midlNod[ inextface ]); + } + const int nbFaceNodes = polyedre_nodes.size() - prevNbNodes; + if ( nbFaceNodes > 2 ) + quantities.push_back( nbFaceNodes ); + else // degenerated face + polyedre_nodes.resize( prevNbNodes ); } aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities); } @@ -3094,7 +4027,8 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, // Find nodes belonging to only one initial element - sweep them to get edges. TNodeOfNodeListMapItr nList = mapNewNodes.begin(); - for ( ; nList != mapNewNodes.end(); nList++ ) { + for ( ; nList != mapNewNodes.end(); nList++ ) + { const SMDS_MeshNode* node = static_cast( nList->first ); SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(); @@ -3109,11 +4043,10 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, nbInitElems = 0; highType = type; } - if ( elemSet.find(el) != elemSet.end() ) - nbInitElems++; + nbInitElems += elemSet.count(el); } if ( nbInitElems < 2 ) { - bool NotCreateEdge = el && el->IsQuadratic() && el->IsMediumNode(node); + bool NotCreateEdge = el && el->IsMediumNode(node); if(!NotCreateEdge) { vector newNodesItVec( 1, nList ); list newEdges; @@ -3127,13 +4060,18 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, TElemOfElemListMap::iterator itElem = newElemsMap.begin(); TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin(); - for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) { + for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) + { const SMDS_MeshElement* elem = itElem->first; vector& vecNewNodes = itElemNodes->second; + if(itElem->second.size()==0) continue; + + const bool isQuadratic = elem->IsQuadratic(); + if ( elem->GetType() == SMDSAbs_Edge ) { // create a ceiling edge - if (!elem->IsQuadratic()) { + if ( !isQuadratic ) { if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(), vecNewNodes[ 1 ]->second.back())) { myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), @@ -3155,8 +4093,6 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, if ( elem->GetType() != SMDSAbs_Face ) continue; - if(itElem->second.size()==0) continue; - bool hasFreeLinks = false; TIDSortedElemSet avoidSet; @@ -3164,7 +4100,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, set aFaceLastNodes; int iNode, nbNodes = vecNewNodes.size(); - if(!elem->IsQuadratic()) { + if ( !isQuadratic ) { // loop on the face nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) { aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); @@ -3196,12 +4132,14 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, int iNext = ( iNode + 1 == nbn ) ? 0 : iNode + 1; const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first; const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first; + const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first; // check if a link is free - if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) { + if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet ) && + ! SMESH_MeshEditor::FindFaceInSet ( n1, n3, elemSet, avoidSet ) && + ! SMESH_MeshEditor::FindFaceInSet ( n3, n2, elemSet, avoidSet ) ) { hasFreeLinks = true; // make an edge and a ceiling for a new edge // find medium node - const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first; if ( !aMesh->FindEdge( n1, n2, n3 )) { myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // free link edge srcElements.Append( myLastCreatedElems.Last() ); @@ -3215,7 +4153,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, } } } - for ( iNode = nbn; iNode < 2*nbn; iNode++ ) { + for ( iNode = nbn; iNode < nbNodes; iNode++ ) { aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() ); } } @@ -3233,12 +4171,11 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, } for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) { list::iterator v = newVolumes.begin(); - iVol = 0; - while ( iVol++ < volNb ) v++; + std::advance( v, volNb ); // find indices of free faces of a volume and their source edges list< int > freeInd; list< const SMDS_MeshElement* > srcEdges; // source edges of free faces - SMDS_VolumeTool vTool( *v ); + SMDS_VolumeTool vTool( *v, /*ignoreCentralNodes=*/false ); int iF, nbF = vTool.NbFaces(); for ( iF = 0; iF < nbF; iF ++ ) { if (vTool.IsFreeFace( iF ) && @@ -3273,62 +4210,137 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, // create faces for all steps; // if such a face has been already created by sweep of edge, // assure that its orientation is OK - for ( int iStep = 0; iStep < nbSteps; iStep++ ) { - vTool.Set( *v ); + for ( int iStep = 0; iStep < nbSteps; iStep++ ) { + vTool.Set( *v, /*ignoreCentralNodes=*/false ); vTool.SetExternalNormal(); + const int nextShift = vTool.IsForward() ? +1 : -1; list< int >::iterator ind = freeInd.begin(); list< const SMDS_MeshElement* >::iterator srcEdge = srcEdges.begin(); for ( ; ind != freeInd.end(); ++ind, ++srcEdge ) // loop on free faces { const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind ); int nbn = vTool.NbFaceNodes( *ind ); - switch ( nbn ) { - case 3: { ///// triangle - const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]); - if ( !f ) - myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); - else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); - break; + const SMDS_MeshElement * f = 0; + if ( nbn == 3 ) ///// triangle + { + f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]); + if ( !f || + nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ]) + nextShift )) + { + const SMDS_MeshNode* newOrder[3] = { nodes[ 1 - nextShift ], + nodes[ 1 ], + nodes[ 1 + nextShift ] }; + if ( f ) + aMesh->ChangeElementNodes( f, &newOrder[0], nbn ); + else + myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ], + newOrder[ 2 ] )); + } } - case 4: { ///// quadrangle - const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]); - if ( !f ) - myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); - else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); - break; + else if ( nbn == 4 ) ///// quadrangle + { + f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]); + if ( !f || + nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ]) + nextShift )) + { + const SMDS_MeshNode* newOrder[4] = { nodes[ 0 ], nodes[ 2-nextShift ], + nodes[ 2 ], nodes[ 2+nextShift ] }; + if ( f ) + aMesh->ChangeElementNodes( f, &newOrder[0], nbn ); + else + myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ], + newOrder[ 2 ], newOrder[ 3 ])); + } } - default: - if( (*v)->IsQuadratic() ) { - if(nbn==6) { /////// quadratic triangle - const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], - nodes[1], nodes[3], nodes[5] ); - if ( !f ) - myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], - nodes[1], nodes[3], nodes[5])); - else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); - } - else { /////// quadratic quadrangle - const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[6], - nodes[1], nodes[3], nodes[5], nodes[7] ); - if ( !f ) - myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], - nodes[1], nodes[3], nodes[5], nodes[7])); - else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); - } + else if ( nbn == 6 && isQuadratic ) /////// quadratic triangle + { + f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5] ); + if ( !f || + nodes[2] != f->GetNodeWrap( f->GetNodeIndex( nodes[0] ) + 2*nextShift )) + { + const SMDS_MeshNode* newOrder[6] = { nodes[2 - 2*nextShift], + nodes[2], + nodes[2 + 2*nextShift], + nodes[3 - 2*nextShift], + nodes[3], + nodes[3 + 2*nextShift]}; + if ( f ) + aMesh->ChangeElementNodes( f, &newOrder[0], nbn ); + else + myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ], + newOrder[ 1 ], + newOrder[ 2 ], + newOrder[ 3 ], + newOrder[ 4 ], + newOrder[ 5 ] )); + } + } + else if ( nbn == 8 && isQuadratic ) /////// quadratic quadrangle + { + f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7] ); + if ( !f || + nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 2*nextShift )) + { + const SMDS_MeshNode* newOrder[8] = { nodes[0], + nodes[4 - 2*nextShift], + nodes[4], + nodes[4 + 2*nextShift], + nodes[1], + nodes[5 - 2*nextShift], + nodes[5], + nodes[5 + 2*nextShift] }; + if ( f ) + aMesh->ChangeElementNodes( f, &newOrder[0], nbn ); + else + myLastCreatedElems.Append(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ], + newOrder[ 2 ], newOrder[ 3 ], + newOrder[ 4 ], newOrder[ 5 ], + newOrder[ 6 ], newOrder[ 7 ])); + } + } + else if ( nbn == 9 && isQuadratic ) /////// bi-quadratic quadrangle + { + f = aMesh->FindElement( vector( nodes, nodes+nbn ), + SMDSAbs_Face, /*noMedium=*/false); + if ( !f || + nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 2*nextShift )) + { + const SMDS_MeshNode* newOrder[9] = { nodes[0], + nodes[4 - 2*nextShift], + nodes[4], + nodes[4 + 2*nextShift], + nodes[1], + nodes[5 - 2*nextShift], + nodes[5], + nodes[5 + 2*nextShift], + nodes[8] }; + if ( f ) + aMesh->ChangeElementNodes( f, &newOrder[0], nbn ); + else + myLastCreatedElems.Append(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ], + newOrder[ 2 ], newOrder[ 3 ], + newOrder[ 4 ], newOrder[ 5 ], + newOrder[ 6 ], newOrder[ 7 ], + newOrder[ 8 ])); } - else { //////// polygon - vector polygon_nodes ( nodes, &nodes[nbn] ); - const SMDS_MeshFace * f = aMesh->FindFace( polygon_nodes ); - if ( !f ) - myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); - else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 )) - aMesh->ChangeElementNodes( f, nodes, nbn ); + } + else //////// polygon + { + vector polygon_nodes ( nodes, nodes+nbn ); + const SMDS_MeshFace * f = aMesh->FindFace( polygon_nodes ); + if ( !f || + nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + nextShift )) + { + if ( !vTool.IsForward() ) + std::reverse( polygon_nodes.begin(), polygon_nodes.end()); + if ( f ) + aMesh->ChangeElementNodes( f, &polygon_nodes[0], nbn ); + else + AddElement(polygon_nodes, SMDSAbs_Face, polygon_nodes.size()>4); } } + while ( srcElements.Length() < myLastCreatedElems.Length() ) srcElements.Append( *srcEdge ); @@ -3337,54 +4349,60 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, // go to the next volume iVol = 0; while ( iVol++ < nbVolumesByStep ) v++; - } - } + + } // loop on steps + } // loop on volumes of one step } // sweep free links into faces // Make a ceiling face with a normal external to a volume - SMDS_VolumeTool lastVol( itElem->second.back() ); + SMDS_VolumeTool lastVol( itElem->second.back(), /*ignoreCentralNodes=*/false ); int iF = lastVol.GetFaceIndex( aFaceLastNodes ); if ( iF >= 0 ) { lastVol.SetExternalNormal(); const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF ); int nbn = lastVol.NbFaceNodes( iF ); - switch ( nbn ) { - case 3: + if ( nbn == 3 ) { if (!hasFreeLinks || !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ])) myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); - break; - case 4: + } + else if ( nbn == 4 ) + { if (!hasFreeLinks || !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ])) - myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); - break; - default: - if(itElem->second.back()->IsQuadratic()) { - if(nbn==6) { - if (!hasFreeLinks || - !aMesh->FindFace(nodes[0], nodes[2], nodes[4], - nodes[1], nodes[3], nodes[5]) ) { - myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], - nodes[1], nodes[3], nodes[5])); - } - } - else { // nbn==8 - if (!hasFreeLinks || - !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6], - nodes[1], nodes[3], nodes[5], nodes[7]) ) - myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], - nodes[1], nodes[3], nodes[5], nodes[7])); - } - } - else { - vector polygon_nodes ( nodes, &nodes[nbn] ); - if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes)) - myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); - } - } // switch + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ])); + } + else if ( nbn == 6 && isQuadratic ) + { + if (!hasFreeLinks || + !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5]) ) + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5])); + } + else if ( nbn == 8 && isQuadratic ) + { + if (!hasFreeLinks || + !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7]) ) + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7])); + } + else if ( nbn == 9 && isQuadratic ) + { + if (!hasFreeLinks || + !aMesh->FindElement(vector( nodes, nodes+nbn ), + SMDSAbs_Face, /*noMedium=*/false) ) + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7], + nodes[8])); + } + else { + vector polygon_nodes ( nodes, nodes + nbn ); + if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes)) + myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); + } while ( srcElements.Length() < myLastCreatedElems.Length() ) srcElements.Append( myLastCreatedElems.Last() ); @@ -3427,6 +4445,9 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, TElemOfVecOfNnlmiMap mapElemNewNodes; TElemOfElemListMap newElemsMap; + const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) + + myMesh->NbFaces(ORDER_QUADRATIC) + + myMesh->NbVolumes(ORDER_QUADRATIC) ); // loop on theElems TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { @@ -3442,64 +4463,58 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, { // check if a node has been already sweeped const SMDS_MeshNode* node = cast2Node( itN->next() ); - TNodeOfNodeListMapItr nIt = mapNewNodes.find( node ); - if ( nIt == mapNewNodes.end() ) { - nIt = mapNewNodes.insert( make_pair( node, list() )).first; - list& listNewNodes = nIt->second; + + gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); + double coord[3]; + aXYZ.Coord( coord[0], coord[1], coord[2] ); + bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol ); + + TNodeOfNodeListMapItr nIt = + mapNewNodes.insert( make_pair( node, list() )).first; + list& listNewNodes = nIt->second; + if ( listNewNodes.empty() ) + { + // check if we are to create medium nodes between corner ones + bool needMediumNodes = false; + if ( isQuadraticMesh ) + { + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while (it->more() && !needMediumNodes ) + { + const SMDS_MeshElement* invElem = it->next(); + if ( invElem != elem && !theElems.count( invElem )) continue; + needMediumNodes = ( invElem->IsQuadratic() && !invElem->IsMediumNode(node) ); + if ( !needMediumNodes && invElem->GetEntityType() == SMDSEntity_BiQuad_Quadrangle ) + needMediumNodes = true; + } + } // make new nodes - gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); - double coord[3]; - aXYZ.Coord( coord[0], coord[1], coord[2] ); - bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol ); const SMDS_MeshNode * newNode = node; for ( int i = 0; i < theNbSteps; i++ ) { if ( !isOnAxis ) { - if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { - // create two nodes + if ( needMediumNodes ) // create a medium node + { aTrsf2.Transforms( coord[0], coord[1], coord[2] ); - //aTrsf.Transforms( coord[0], coord[1], coord[2] ); newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); srcNodes.Append( node ); listNewNodes.push_back( newNode ); aTrsf2.Transforms( coord[0], coord[1], coord[2] ); - //aTrsf.Transforms( coord[0], coord[1], coord[2] ); } else { aTrsf.Transforms( coord[0], coord[1], coord[2] ); } + // create a corner node newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); srcNodes.Append( node ); + listNewNodes.push_back( newNode ); } - listNewNodes.push_back( newNode ); - } - } - else { - // if current elem is quadratic and current node is not medium - // we have to check - may be it is needed to insert additional nodes - if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { - list< const SMDS_MeshNode* > & listNewNodes = nIt->second; - if(listNewNodes.size()==theNbSteps) { - listNewNodes.clear(); - // make new nodes - gp_XYZ aXYZ( node->X(), node->Y(), node->Z() ); - double coord[3]; - aXYZ.Coord( coord[0], coord[1], coord[2] ); - const SMDS_MeshNode * newNode = node; - for(int i = 0; iAddNode( coord[0], coord[1], coord[2] ); - myLastCreatedNodes.Append(newNode); - listNewNodes.push_back( newNode ); - srcNodes.Append( node ); - aTrsf2.Transforms( coord[0], coord[1], coord[2] ); - newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); - myLastCreatedNodes.Append(newNode); - srcNodes.Append( node ); - listNewNodes.push_back( newNode ); - } + else { + listNewNodes.push_back( newNode ); + // if ( needMediumNodes ) + // listNewNodes.push_back( newNode ); } } } @@ -3511,7 +4526,7 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, if ( theMakeWalls ) makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, srcElems ); - + PGroupIDs newGroupIDs; if ( theMakeGroups ) newGroupIDs = generateGroups( srcNodes, srcElems, "rotated"); @@ -3530,8 +4545,8 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x, const double tolnode, SMESH_SequenceOfNode& aNodes) { - myLastCreatedElems.Clear(); - myLastCreatedNodes.Clear(); + // myLastCreatedElems.Clear(); + // myLastCreatedNodes.Clear(); gp_Pnt P1(x,y,z); SMESHDS_Mesh * aMesh = myMesh->GetMeshDS(); @@ -3559,7 +4574,7 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x, // create new node and return it const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z); - myLastCreatedNodes.Append(NewNode); + //myLastCreatedNodes.Append(NewNode); return NewNode; } @@ -3619,6 +4634,9 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, TElemOfVecOfNnlmiMap mapElemNewNodes; //TElemOfVecOfMapNodesMap mapElemNewNodes; + const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) + + myMesh->NbFaces(ORDER_QUADRATIC) + + myMesh->NbVolumes(ORDER_QUADRATIC) ); // loop on theElems TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { @@ -3628,7 +4646,6 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, continue; vector & newNodesItVec = mapElemNewNodes[ elem ]; - //vector & newNodesItVec = mapElemNewNodes[ elem ]; newNodesItVec.reserve( elem->NbNodes() ); // loop on elem nodes @@ -3637,21 +4654,33 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, { // check if a node has been already sweeped const SMDS_MeshNode* node = cast2Node( itN->next() ); - TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node ); - //TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node ); - if ( nIt == mapNewNodes.end() ) { - nIt = mapNewNodes.insert( make_pair( node, list() )).first; - //nIt = mapNewNodes.insert( make_pair( node, vector() )).first; - list& listNewNodes = nIt->second; - //vector& vecNewNodes = nIt->second; - //vecNewNodes.reserve(nbsteps); - + TNodeOfNodeListMap::iterator nIt = + mapNewNodes.insert( make_pair( node, list() )).first; + list& listNewNodes = nIt->second; + if ( listNewNodes.empty() ) + { // make new nodes - double coord[] = { node->X(), node->Y(), node->Z() }; - //int nbsteps = theParams.mySteps->Length(); - for ( int i = 0; i < nbsteps; i++ ) { - if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { - // create additional node + + // check if we are to create medium nodes between corner ones + bool needMediumNodes = false; + if ( isQuadraticMesh ) + { + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while (it->more() && !needMediumNodes ) + { + const SMDS_MeshElement* invElem = it->next(); + if ( invElem != elem && !theElems.count( invElem )) continue; + needMediumNodes = ( invElem->IsQuadratic() && !invElem->IsMediumNode(node) ); + if ( !needMediumNodes && invElem->GetEntityType() == SMDSEntity_BiQuad_Quadrangle ) + needMediumNodes = true; + } + } + + double coord[] = { node->X(), node->Y(), node->Z() }; + for ( int i = 0; i < nbsteps; i++ ) + { + if ( needMediumNodes ) // create a medium node + { double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1)/2.; double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1)/2.; double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1)/2.; @@ -3667,7 +4696,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, listNewNodes.push_back( newNode ); } } - //aTrsf.Transforms( coord[0], coord[1], coord[2] ); + // create a corner node coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1); @@ -3675,55 +4704,12 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2], theTolerance, theParams.myNodes); listNewNodes.push_back( newNode ); - //vecNewNodes[i]=newNode; } else { const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); srcNodes.Append( node ); listNewNodes.push_back( newNode ); - //vecNewNodes[i]=newNode; - } - } - } - else { - // if current elem is quadratic and current node is not medium - // we have to check - may be it is needed to insert additional nodes - if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { - list< const SMDS_MeshNode* > & listNewNodes = nIt->second; - if(listNewNodes.size()==nbsteps) { - listNewNodes.clear(); - double coord[] = { node->X(), node->Y(), node->Z() }; - for ( int i = 0; i < nbsteps; i++ ) { - double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); - double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); - double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1); - if( theFlags & EXTRUSION_FLAG_SEW ) { - const SMDS_MeshNode * newNode = CreateNode(x, y, z, - theTolerance, theParams.myNodes); - listNewNodes.push_back( newNode ); - } - else { - const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); - myLastCreatedNodes.Append(newNode); - srcNodes.Append( node ); - listNewNodes.push_back( newNode ); - } - coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); - coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1); - coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1); - if( theFlags & EXTRUSION_FLAG_SEW ) { - const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2], - theTolerance, theParams.myNodes); - listNewNodes.push_back( newNode ); - } - else { - const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); - myLastCreatedNodes.Append(newNode); - srcNodes.Append( node ); - listNewNodes.push_back( newNode ); - } - } } } } @@ -3743,82 +4729,30 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, return newGroupIDs; } - -//======================================================================= -//class : SMESH_MeshEditor_PathPoint -//purpose : auxiliary class -//======================================================================= -class SMESH_MeshEditor_PathPoint { -public: - SMESH_MeshEditor_PathPoint() { - myPnt.SetCoord(99., 99., 99.); - myTgt.SetCoord(1.,0.,0.); - myAngle=0.; - myPrm=0.; - } - void SetPnt(const gp_Pnt& aP3D){ - myPnt=aP3D; - } - void SetTangent(const gp_Dir& aTgt){ - myTgt=aTgt; - } - void SetAngle(const double& aBeta){ - myAngle=aBeta; - } - void SetParameter(const double& aPrm){ - myPrm=aPrm; - } - const gp_Pnt& Pnt()const{ - return myPnt; - } - const gp_Dir& Tangent()const{ - return myTgt; - } - double Angle()const{ - return myAngle; - } - double Parameter()const{ - return myPrm; - } - -protected: - gp_Pnt myPnt; - gp_Dir myTgt; - double myAngle; - double myPrm; -}; - //======================================================================= //function : ExtrusionAlongTrack //purpose : //======================================================================= SMESH_MeshEditor::Extrusion_Error - SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, - SMESH_subMesh* theTrack, - const SMDS_MeshNode* theN1, - const bool theHasAngles, - list& theAngles, - const bool theHasRefPoint, - const gp_Pnt& theRefPoint, - const bool theMakeGroups) +SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, + SMESH_subMesh* theTrack, + const SMDS_MeshNode* theN1, + const bool theHasAngles, + list& theAngles, + const bool theLinearVariation, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint, + const bool theMakeGroups) { + MESSAGE("ExtrusionAlongTrack"); myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - // source elements for each generated one - SMESH_SequenceOfElemPtr srcElems, srcNodes; - - int j, aNbTP, aNbE, aNb; - double aT1, aT2, aT, aAngle, aX, aY, aZ; + int aNbE; std::list aPrms; - std::list::iterator aItD; TIDSortedElemSet::iterator itElem; - Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2; - gp_Pnt aP3D, aV0; - gp_Vec aVec; gp_XYZ aGC; - Handle(Geom_Curve) aC3D; TopoDS_Edge aTrackEdge; TopoDS_Vertex aV1, aV2; @@ -3827,11 +4761,6 @@ SMESH_MeshEditor::Extrusion_Error SMDSAbs_ElementType aTypeE; TNodeOfNodeListMap mapNewNodes; - TElemOfVecOfNnlmiMap mapElemNewNodes; - TElemOfElemListMap newElemsMap; - - aTolVec=1.e-7; - aTolVec2=aTolVec*aTolVec; // 1. Check data aNbE = theElements.size(); @@ -3842,7 +4771,7 @@ SMESH_MeshEditor::Extrusion_Error // 1.1 Track Pattern ASSERT( theTrack ); - SMESHDS_SubMesh* pSubMeshDS=theTrack->GetSubMeshDS(); + SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS(); aItE = pSubMeshDS->GetElements(); while ( aItE->more() ) { @@ -3853,63 +4782,441 @@ SMESH_MeshEditor::Extrusion_Error return EXTR_PATH_NOT_EDGE; } + list fullList; + const TopoDS_Shape& aS = theTrack->GetSubShape(); - // Sub shape for the Pattern must be an Edge - if ( aS.ShapeType() != TopAbs_EDGE ) + // Sub-shape for the Pattern must be an Edge or Wire + if( aS.ShapeType() == TopAbs_EDGE ) { + aTrackEdge = TopoDS::Edge( aS ); + // the Edge must not be degenerated + if ( BRep_Tool::Degenerated( aTrackEdge ) ) + return EXTR_BAD_PATH_SHAPE; + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1 == theN1 || aN2 == theN1 ) ) + return EXTR_BAD_STARTING_NODE; + aItN = pSubMeshDS->GetNodes(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + //Extrusion_Error err = + MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); + } else if( aS.ShapeType() == TopAbs_WIRE ) { + list< SMESH_subMesh* > LSM; + TopTools_SequenceOfShape Edges; + SMESH_subMeshIteratorPtr itSM = theTrack->getDependsOnIterator(false,true); + while(itSM->more()) { + SMESH_subMesh* SM = itSM->next(); + LSM.push_back(SM); + const TopoDS_Shape& aS = SM->GetSubShape(); + Edges.Append(aS); + } + list< list > LLPPs; + int startNid = theN1->GetID(); + TColStd_MapOfInteger UsedNums; + + int NbEdges = Edges.Length(); + int i = 1; + for(; i<=NbEdges; i++) { + int k = 0; + list< SMESH_subMesh* >::iterator itLSM = LSM.begin(); + for(; itLSM!=LSM.end(); itLSM++) { + k++; + if(UsedNums.Contains(k)) continue; + aTrackEdge = TopoDS::Edge( Edges.Value(k) ); + SMESH_subMesh* locTrack = *itLSM; + SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS(); + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue; + // 2. Collect parameters on the track edge + aPrms.clear(); + aItN = locMeshDS->GetNodes(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + list LPP; + //Extrusion_Error err = + MakeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP); + LLPPs.push_back(LPP); + UsedNums.Add(k); + // update startN for search following egde + if( aN1->GetID() == startNid ) startNid = aN2->GetID(); + else startNid = aN1->GetID(); + break; + } + } + list< list >::iterator itLLPP = LLPPs.begin(); + list firstList = *itLLPP; + list::iterator itPP = firstList.begin(); + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + SMESH_MeshEditor_PathPoint PP1 = fullList.back(); + fullList.pop_back(); + itLLPP++; + for(; itLLPP!=LLPPs.end(); itLLPP++) { + list currList = *itLLPP; + itPP = currList.begin(); + SMESH_MeshEditor_PathPoint PP2 = currList.front(); + gp_Dir D1 = PP1.Tangent(); + gp_Dir D2 = PP2.Tangent(); + gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2, + (D1.Z()+D2.Z())/2 ) ); + PP1.SetTangent(Dnew); + fullList.push_back(PP1); + itPP++; + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + PP1 = fullList.back(); + fullList.pop_back(); + } + // if wire not closed + fullList.push_back(PP1); + // else ??? + } + else { return EXTR_BAD_PATH_SHAPE; + } - aTrackEdge = TopoDS::Edge( aS ); - // the Edge must not be degenerated - if ( BRep_Tool::Degenerated( aTrackEdge ) ) - return EXTR_BAD_PATH_SHAPE; + return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation, + theHasRefPoint, theRefPoint, theMakeGroups); +} - TopExp::Vertices( aTrackEdge, aV1, aV2 ); - aT1=BRep_Tool::Parameter( aV1, aTrackEdge ); - aT2=BRep_Tool::Parameter( aV2, aTrackEdge ); - aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes(); - const SMDS_MeshNode* aN1 = aItN->next(); +//======================================================================= +//function : ExtrusionAlongTrack +//purpose : +//======================================================================= +SMESH_MeshEditor::Extrusion_Error +SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, + SMESH_Mesh* theTrack, + const SMDS_MeshNode* theN1, + const bool theHasAngles, + list& theAngles, + const bool theLinearVariation, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint, + const bool theMakeGroups) +{ + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + + int aNbE; + std::list aPrms; + TIDSortedElemSet::iterator itElem; + + gp_XYZ aGC; + TopoDS_Edge aTrackEdge; + TopoDS_Vertex aV1, aV2; + + SMDS_ElemIteratorPtr aItE; + SMDS_NodeIteratorPtr aItN; + SMDSAbs_ElementType aTypeE; - aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes(); - const SMDS_MeshNode* aN2 = aItN->next(); + TNodeOfNodeListMap mapNewNodes; - // starting node must be aN1 or aN2 - if ( !( aN1 == theN1 || aN2 == theN1 ) ) - return EXTR_BAD_STARTING_NODE; + // 1. Check data + aNbE = theElements.size(); + // nothing to do + if ( !aNbE ) + return EXTR_NO_ELEMENTS; - aNbTP = pSubMeshDS->NbNodes() + 2; + // 1.1 Track Pattern + ASSERT( theTrack ); - // 1.2. Angles - vector aAngles( aNbTP ); + SMESHDS_Mesh* pMeshDS = theTrack->GetMeshDS(); - for ( j=0; j < aNbTP; ++j ) { - aAngles[j] = 0.; + aItE = pMeshDS->elementsIterator(); + while ( aItE->more() ) { + const SMDS_MeshElement* pE = aItE->next(); + aTypeE = pE->GetType(); + // Pattern must contain links only + if ( aTypeE != SMDSAbs_Edge ) + return EXTR_PATH_NOT_EDGE; } - if ( theHasAngles ) { - aItD = theAngles.begin(); - for ( j=1; (aItD != theAngles.end()) && (j fullList; + + const TopoDS_Shape& aS = theTrack->GetShapeToMesh(); + + if( aS == SMESH_Mesh::PseudoShape() ) { + //Mesh without shape + const SMDS_MeshNode* currentNode = NULL; + const SMDS_MeshNode* prevNode = theN1; + std::vector aNodesList; + aNodesList.push_back(theN1); + int nbEdges = 0, conn=0; + const SMDS_MeshElement* prevElem = NULL; + const SMDS_MeshElement* currentElem = NULL; + int totalNbEdges = theTrack->NbEdges(); + SMDS_ElemIteratorPtr nIt; + + //check start node + if( !theTrack->GetMeshDS()->Contains(theN1) ) { + return EXTR_BAD_STARTING_NODE; + } + + conn = nbEdgeConnectivity(theN1); + if(conn > 2) + return EXTR_PATH_NOT_EDGE; + + aItE = theN1->GetInverseElementIterator(); + prevElem = aItE->next(); + currentElem = prevElem; + //Get all nodes + if(totalNbEdges == 1 ) { + nIt = currentElem->nodesIterator(); + currentNode = static_cast(nIt->next()); + if(currentNode == prevNode) + currentNode = static_cast(nIt->next()); + aNodesList.push_back(currentNode); + } else { + nIt = currentElem->nodesIterator(); + while( nIt->more() ) { + currentNode = static_cast(nIt->next()); + if(currentNode == prevNode) + currentNode = static_cast(nIt->next()); + aNodesList.push_back(currentNode); + + //case of the closed mesh + if(currentNode == theN1) { + nbEdges++; + break; + } + + conn = nbEdgeConnectivity(currentNode); + if(conn > 2) { + return EXTR_PATH_NOT_EDGE; + }else if( conn == 1 && nbEdges > 0 ) { + //End of the path + nbEdges++; + break; + }else { + prevNode = currentNode; + aItE = currentNode->GetInverseElementIterator(); + currentElem = aItE->next(); + if( currentElem == prevElem) + currentElem = aItE->next(); + nIt = currentElem->nodesIterator(); + prevElem = currentElem; + nbEdges++; + } + } + } + + if(nbEdges != totalNbEdges) + return EXTR_PATH_NOT_EDGE; + + TopTools_SequenceOfShape Edges; + double x1,x2,y1,y2,z1,z2; + list< list > LLPPs; + int startNid = theN1->GetID(); + for(int i = 1; i < aNodesList.size(); i++) { + x1 = aNodesList[i-1]->X();x2 = aNodesList[i]->X(); + y1 = aNodesList[i-1]->Y();y2 = aNodesList[i]->Y(); + z1 = aNodesList[i-1]->Z();z2 = aNodesList[i]->Z(); + TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp_Pnt(x1,y1,z1),gp_Pnt(x2,y2,z2)); + list LPP; + aPrms.clear(); + MakeEdgePathPoints(aPrms, e, (aNodesList[i-1]->GetID()==startNid), LPP); + LLPPs.push_back(LPP); + if( aNodesList[i-1]->GetID() == startNid ) startNid = aNodesList[i]->GetID(); + else startNid = aNodesList[i-1]->GetID(); + + } + + list< list >::iterator itLLPP = LLPPs.begin(); + list firstList = *itLLPP; + list::iterator itPP = firstList.begin(); + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + + SMESH_MeshEditor_PathPoint PP1 = fullList.back(); + SMESH_MeshEditor_PathPoint PP2; + fullList.pop_back(); + itLLPP++; + for(; itLLPP!=LLPPs.end(); itLLPP++) { + list currList = *itLLPP; + itPP = currList.begin(); + PP2 = currList.front(); + gp_Dir D1 = PP1.Tangent(); + gp_Dir D2 = PP2.Tangent(); + gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2, + (D1.Z()+D2.Z())/2 ) ); + PP1.SetTangent(Dnew); + fullList.push_back(PP1); + itPP++; + for(; itPP!=currList.end(); itPP++) { + fullList.push_back( *itPP ); + } + PP1 = fullList.back(); + fullList.pop_back(); + } + fullList.push_back(PP1); + + } // Sub-shape for the Pattern must be an Edge or Wire + else if( aS.ShapeType() == TopAbs_EDGE ) { + aTrackEdge = TopoDS::Edge( aS ); + // the Edge must not be degenerated + if ( BRep_Tool::Degenerated( aTrackEdge ) ) + return EXTR_BAD_PATH_SHAPE; + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = theTrack->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = theTrack->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1 == theN1 || aN2 == theN1 ) ) + return EXTR_BAD_STARTING_NODE; + aItN = pMeshDS->nodesIterator(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + if( pNode==aN1 || pNode==aN2 ) continue; + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + //Extrusion_Error err = + MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList); + } + else if( aS.ShapeType() == TopAbs_WIRE ) { + list< SMESH_subMesh* > LSM; + TopTools_SequenceOfShape Edges; + TopExp_Explorer eExp(aS, TopAbs_EDGE); + for(; eExp.More(); eExp.Next()) { + TopoDS_Edge E = TopoDS::Edge( eExp.Current() ); + if( BRep_Tool::Degenerated(E) ) continue; + SMESH_subMesh* SM = theTrack->GetSubMesh(E); + if(SM) { + LSM.push_back(SM); + Edges.Append(E); + } + } + list< list > LLPPs; + int startNid = theN1->GetID(); + TColStd_MapOfInteger UsedNums; + int NbEdges = Edges.Length(); + int i = 1; + for(; i<=NbEdges; i++) { + int k = 0; + list< SMESH_subMesh* >::iterator itLSM = LSM.begin(); + for(; itLSM!=LSM.end(); itLSM++) { + k++; + if(UsedNums.Contains(k)) continue; + aTrackEdge = TopoDS::Edge( Edges.Value(k) ); + SMESH_subMesh* locTrack = *itLSM; + SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS(); + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + // starting node must be aN1 or aN2 + if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue; + // 2. Collect parameters on the track edge + aPrms.clear(); + aItN = locMeshDS->GetNodes(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition() ); + double aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + list LPP; + //Extrusion_Error err = + MakeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP); + LLPPs.push_back(LPP); + UsedNums.Add(k); + // update startN for search following egde + if( aN1->GetID() == startNid ) startNid = aN2->GetID(); + else startNid = aN1->GetID(); + break; + } } + list< list >::iterator itLLPP = LLPPs.begin(); + list firstList = *itLLPP; + list::iterator itPP = firstList.begin(); + for(; itPP!=firstList.end(); itPP++) { + fullList.push_back( *itPP ); + } + SMESH_MeshEditor_PathPoint PP1 = fullList.back(); + fullList.pop_back(); + itLLPP++; + for(; itLLPP!=LLPPs.end(); itLLPP++) { + list currList = *itLLPP; + itPP = currList.begin(); + SMESH_MeshEditor_PathPoint PP2 = currList.front(); + gp_Dir D1 = PP1.Tangent(); + gp_Dir D2 = PP2.Tangent(); + gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2, + (D1.Z()+D2.Z())/2 ) ); + PP1.SetTangent(Dnew); + fullList.push_back(PP1); + itPP++; + for(; itPP!=currList.end(); itPP++) { + fullList.push_back( *itPP ); + } + PP1 = fullList.back(); + fullList.pop_back(); + } + // if wire not closed + fullList.push_back(PP1); + // else ??? + } + else { + return EXTR_BAD_PATH_SHAPE; } - // 2. Collect parameters on the track edge - aPrms.push_back( aT1 ); - aPrms.push_back( aT2 ); + return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation, + theHasRefPoint, theRefPoint, theMakeGroups); +} - aItN = pSubMeshDS->GetNodes(); - while ( aItN->more() ) { - const SMDS_MeshNode* pNode = aItN->next(); - const SMDS_EdgePosition* pEPos = - static_cast( pNode->GetPosition().get() ); - aT = pEPos->GetUParameter(); - aPrms.push_back( aT ); - } +//======================================================================= +//function : MakeEdgePathPoints +//purpose : auxilary for ExtrusionAlongTrack +//======================================================================= +SMESH_MeshEditor::Extrusion_Error +SMESH_MeshEditor::MakeEdgePathPoints(std::list& aPrms, + const TopoDS_Edge& aTrackEdge, + bool FirstIsStart, + list& LPP) +{ + Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2; + aTolVec=1.e-7; + aTolVec2=aTolVec*aTolVec; + double aT1, aT2; + TopoDS_Vertex aV1, aV2; + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aT1=BRep_Tool::Parameter( aV1, aTrackEdge ); + aT2=BRep_Tool::Parameter( aV2, aTrackEdge ); + // 2. Collect parameters on the track edge + aPrms.push_front( aT1 ); + aPrms.push_back( aT2 ); // sort parameters aPrms.sort(); - if ( aN1 == theN1 ) { + if( FirstIsStart ) { if ( aT1 > aT2 ) { aPrms.reverse(); } @@ -3919,33 +5226,87 @@ SMESH_MeshEditor::Extrusion_Error aPrms.reverse(); } } - // 3. Path Points SMESH_MeshEditor_PathPoint aPP; - vector aPPs( aNbTP ); - // - aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 ); - // - aItD = aPrms.begin(); - for ( j=0; aItD != aPrms.end(); ++aItD, ++j ) { - aT = *aItD; + Handle(Geom_Curve) aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 ); + std::list::iterator aItD = aPrms.begin(); + for(; aItD != aPrms.end(); ++aItD) { + double aT = *aItD; + gp_Pnt aP3D; + gp_Vec aVec; aC3D->D1( aT, aP3D, aVec ); aL2 = aVec.SquareMagnitude(); if ( aL2 < aTolVec2 ) return EXTR_CANT_GET_TANGENT; - gp_Dir aTgt( aVec ); - aAngle = aAngles[j]; - aPP.SetPnt( aP3D ); aPP.SetTangent( aTgt ); - aPP.SetAngle( aAngle ); aPP.SetParameter( aT ); - aPPs[j]=aPP; + LPP.push_back(aPP); + } + return EXTR_OK; +} + + +//======================================================================= +//function : MakeExtrElements +//purpose : auxilary for ExtrusionAlongTrack +//======================================================================= +SMESH_MeshEditor::Extrusion_Error +SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet& theElements, + list& fullList, + const bool theHasAngles, + list& theAngles, + const bool theLinearVariation, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint, + const bool theMakeGroups) +{ + MESSAGE("MakeExtrElements"); + //cout<<"MakeExtrElements fullList.size() = "< aPPs(aNbTP); + // Angles + if( theHasAngles && theAngles.size()>0 && theLinearVariation ) { + LinearAngleVariation(aNbTP-1, theAngles); + } + vector aAngles( aNbTP ); + int j = 0; + for(; j::iterator aItD = theAngles.begin(); + for ( j=1; (aItD != theAngles.end()) && (j::iterator itPP = fullList.begin(); + for(; itPP!=fullList.end(); itPP++) { + j++; + SMESH_MeshEditor_PathPoint PP = *itPP; + PP.SetAngle(aAngles[j]); + aPPs[j] = PP; } + TNodeOfNodeListMap mapNewNodes; + TElemOfVecOfNnlmiMap mapElemNewNodes; + TElemOfElemListMap newElemsMap; + TIDSortedElemSet::iterator itElem; + double aX, aY, aZ; + int aNb; + SMDSAbs_ElementType aTypeE; + // source elements for each generated one + SMESH_SequenceOfElemPtr srcElems, srcNodes; + // 3. Center of rotation aV0 - aV0 = theRefPoint; + gp_Pnt aV0 = theRefPoint; + gp_XYZ aGC; if ( !theHasRefPoint ) { aNb = 0; aGC.SetCoord( 0.,0.,0. ); @@ -3956,19 +5317,19 @@ SMESH_MeshEditor::Extrusion_Error SMDS_ElemIteratorPtr itN = elem->nodesIterator(); while ( itN->more() ) { - const SMDS_MeshNode* node = static_cast( itN->next() ); - aX = node->X(); - aY = node->Y(); - aZ = node->Z(); - - if ( mapNewNodes.find( node ) == mapNewNodes.end() ) { - list aLNx; - mapNewNodes[node] = aLNx; - // - gp_XYZ aXYZ( aX, aY, aZ ); - aGC += aXYZ; - ++aNb; - } + const SMDS_MeshNode* node = static_cast( itN->next() ); + aX = node->X(); + aY = node->Y(); + aZ = node->Z(); + + if ( mapNewNodes.find( node ) == mapNewNodes.end() ) { + list aLNx; + mapNewNodes[node] = aLNx; + // + gp_XYZ aXYZ( aX, aY, aZ ); + aGC += aXYZ; + ++aNb; + } } } aGC /= aNb; @@ -3997,65 +5358,67 @@ SMESH_MeshEditor::Extrusion_Error ++nodeIndex; // check if a node has been already processed const SMDS_MeshNode* node = - static_cast( itN->next() ); + static_cast( itN->next() ); TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node ); if ( nIt == mapNewNodes.end() ) { nIt = mapNewNodes.insert( make_pair( node, list() )).first; list& listNewNodes = nIt->second; - // make new nodes - aX = node->X(); aY = node->Y(); aZ = node->Z(); - - Standard_Real aAngle1x, aAngleT1T0, aTolAng; - gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x; - gp_Ax1 anAx1, anAxT1T0; - gp_Dir aDT1x, aDT0x, aDT1T0; - - aTolAng=1.e-4; - - aV0x = aV0; - aPN0.SetCoord(aX, aY, aZ); - - const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0]; - aP0x = aPP0.Pnt(); - aDT0x= aPP0.Tangent(); - - for ( j = 1; j < aNbTP; ++j ) { - const SMESH_MeshEditor_PathPoint& aPP1 = aPPs[j]; - aP1x = aPP1.Pnt(); - aDT1x = aPP1.Tangent(); - aAngle1x = aPP1.Angle(); - - gp_Trsf aTrsf, aTrsfRot, aTrsfRotT1T0; - // Translation - gp_Vec aV01x( aP0x, aP1x ); - aTrsf.SetTranslation( aV01x ); - - // traslated point - aV1x = aV0x.Transformed( aTrsf ); - aPN1 = aPN0.Transformed( aTrsf ); - - // rotation 1 [ T1,T0 ] - aAngleT1T0=-aDT1x.Angle( aDT0x ); - if (fabs(aAngleT1T0) > aTolAng) { - aDT1T0=aDT1x^aDT0x; - anAxT1T0.SetLocation( aV1x ); - anAxT1T0.SetDirection( aDT1T0 ); - aTrsfRotT1T0.SetRotation( anAxT1T0, aAngleT1T0 ); - - aPN1 = aPN1.Transformed( aTrsfRotT1T0 ); - } + // make new nodes + aX = node->X(); aY = node->Y(); aZ = node->Z(); + + Standard_Real aAngle1x, aAngleT1T0, aTolAng; + gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x; + gp_Ax1 anAx1, anAxT1T0; + gp_Dir aDT1x, aDT0x, aDT1T0; + + aTolAng=1.e-4; + + aV0x = aV0; + aPN0.SetCoord(aX, aY, aZ); + + const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0]; + aP0x = aPP0.Pnt(); + aDT0x= aPP0.Tangent(); + //cout<<"j = 0 PP: Pnt("< aTolAng) { + aDT1T0=aDT1x^aDT0x; + anAxT1T0.SetLocation( aV1x ); + anAxT1T0.SetDirection( aDT1T0 ); + aTrsfRotT1T0.SetRotation( anAxT1T0, aAngleT1T0 ); + + aPN1 = aPN1.Transformed( aTrsfRotT1T0 ); + } - // rotation 2 - if ( theHasAngles ) { - anAx1.SetLocation( aV1x ); - anAx1.SetDirection( aDT1x ); - aTrsfRot.SetRotation( anAx1, aAngle1x ); + // rotation 2 + if ( theHasAngles ) { + anAx1.SetLocation( aV1x ); + anAx1.SetDirection( aDT1x ); + aTrsfRot.SetRotation( anAx1, aAngle1x ); - aPN1 = aPN1.Transformed( aTrsfRot ); - } + aPN1 = aPN1.Transformed( aTrsfRot ); + } - // make new node + // make new node + //MESSAGE("elem->IsQuadratic " << elem->IsQuadratic() << " " << elem->IsMediumNode(node)); if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) { // create additional node double x = ( aPN1.X() + aPN0.X() )/2.; @@ -4066,19 +5429,19 @@ SMESH_MeshEditor::Extrusion_Error srcNodes.Append( node ); listNewNodes.push_back( newNode ); } - aX = aPN1.X(); - aY = aPN1.Y(); - aZ = aPN1.Z(); - const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ ); + aX = aPN1.X(); + aY = aPN1.Y(); + aZ = aPN1.Z(); + const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ ); myLastCreatedNodes.Append(newNode); srcNodes.Append( node ); - listNewNodes.push_back( newNode ); + listNewNodes.push_back( newNode ); - aPN0 = aPN1; - aP0x = aP1x; - aV0x = aV1x; - aDT0x = aDT1x; - } + aPN0 = aPN1; + aP0x = aP1x; + aV0x = aV1x; + aDT0x = aDT1x; + } } else { @@ -4127,10 +5490,67 @@ SMESH_MeshEditor::Extrusion_Error return EXTR_OK; } + //======================================================================= -//function : Transform -//purpose : +//function : LinearAngleVariation +//purpose : auxilary for ExtrusionAlongTrack //======================================================================= +void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, + list& Angles) +{ + int nbAngles = Angles.size(); + if( nbSteps > nbAngles ) { + vector theAngles(nbAngles); + list::iterator it = Angles.begin(); + int i = -1; + for(; it!=Angles.end(); it++) { + i++; + theAngles[i] = (*it); + } + list res; + double rAn2St = double( nbAngles ) / double( nbSteps ); + double angPrev = 0, angle; + for ( int iSt = 0; iSt < nbSteps; ++iSt ) { + double angCur = rAn2St * ( iSt+1 ); + double angCurFloor = floor( angCur ); + double angPrevFloor = floor( angPrev ); + if ( angPrevFloor == angCurFloor ) + angle = rAn2St * theAngles[ int( angCurFloor ) ]; + else { + int iP = int( angPrevFloor ); + double angPrevCeil = ceil(angPrev); + angle = ( angPrevCeil - angPrev ) * theAngles[ iP ]; + + int iC = int( angCurFloor ); + if ( iC < nbAngles ) + angle += ( angCur - angCurFloor ) * theAngles[ iC ]; + + iP = int( angPrevCeil ); + while ( iC-- > iP ) + angle += theAngles[ iC ]; + } + res.push_back(angle); + angPrev = angCur; + } + Angles.clear(); + it = res.begin(); + for(; it!=res.end(); it++) + Angles.push_back( *it ); + } +} + + +//================================================================================ +/*! + * \brief Move or copy theElements applying theTrsf to their nodes + * \param theElems - elements to transform, if theElems is empty then apply to all mesh nodes + * \param theTrsf - transformation to apply + * \param theCopy - if true, create translated copies of theElems + * \param theMakeGroups - if true and theCopy, create translated groups + * \param theTargetMesh - mesh to copy translated elements into + * \return SMESH_MeshEditor::PGroupIDs - list of ids of created groups + */ +//================================================================================ SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, @@ -4146,21 +5566,37 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, string groupPostfix; switch ( theTrsf.Form() ) { case gp_PntMirror: + MESSAGE("gp_PntMirror"); + needReverse = true; + groupPostfix = "mirrored"; + break; case gp_Ax1Mirror: + MESSAGE("gp_Ax1Mirror"); + groupPostfix = "mirrored"; + break; case gp_Ax2Mirror: + MESSAGE("gp_Ax2Mirror"); needReverse = true; groupPostfix = "mirrored"; break; case gp_Rotation: + MESSAGE("gp_Rotation"); groupPostfix = "rotated"; break; case gp_Translation: + MESSAGE("gp_Translation"); groupPostfix = "translated"; break; case gp_Scale: + MESSAGE("gp_Scale"); + groupPostfix = "scaled"; + break; + case gp_CompoundTrsf: // different scale by axis + MESSAGE("gp_CompoundTrsf"); groupPostfix = "scaled"; break; default: + MESSAGE("default"); needReverse = false; groupPostfix = "transformed"; } @@ -4168,7 +5604,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, SMESH_MeshEditor targetMeshEditor( theTargetMesh ); SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0; SMESHDS_Mesh* aMesh = GetMeshDS(); - + // map old node to new one TNodeNodeMap nodeMap; @@ -4180,9 +5616,29 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, // source elements for each generated one SMESH_SequenceOfElemPtr srcElems, srcNodes; - // loop on theElems + // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh + TIDSortedElemSet orphanNode; + + if ( theElems.empty() ) // transform the whole mesh + { + // add all elements + SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator(); + while ( eIt->more() ) theElems.insert( eIt->next() ); + // add orphan nodes + SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator(); + while ( nIt->more() ) + { + const SMDS_MeshNode* node = nIt->next(); + if ( node->NbInverseElements() == 0) + orphanNode.insert( node ); + } + } + + // loop on elements to transform nodes : first orphan nodes then elems TIDSortedElemSet::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { + TIDSortedElemSet *elements[] = {&orphanNode, &theElems }; + for (int i=0; i<2; i++) + for ( itElem = elements[i]->begin(); itElem != elements[i]->end(); itElem++ ) { const SMDS_MeshElement* elem = *itElem; if ( !elem ) continue; @@ -4191,8 +5647,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, SMDS_ElemIteratorPtr itN = elem->nodesIterator(); while ( itN->more() ) { - // check if a node has been already transformed const SMDS_MeshNode* node = cast2Node( itN->next() ); + // check if a node has been already transformed pair n2n_isnew = nodeMap.insert( make_pair ( node, node )); if ( !n2n_isnew.second ) @@ -4241,203 +5697,167 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, for ( ; invElemIt != inverseElemSet.end(); invElemIt++ ) theElems.insert( *invElemIt ); - // replicate or reverse elements - - enum { - REV_TETRA = 0, // = nbNodes - 4 - REV_PYRAMID = 1, // = nbNodes - 4 - REV_PENTA = 2, // = nbNodes - 4 - REV_FACE = 3, - REV_HEXA = 4, // = nbNodes - 4 - FORWARD = 5 - }; - int index[][8] = { - { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_TETRA - { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_PYRAMID - { 2, 1, 0, 5, 4, 3, 0, 0 }, // REV_PENTA - { 2, 1, 0, 3, 0, 0, 0, 0 }, // REV_FACE - { 2, 1, 0, 3, 6, 5, 4, 7 }, // REV_HEXA - { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD - }; + // Replicate or reverse elements + std::vector iForw; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = *itElem; - if ( !elem || elem->GetType() == SMDSAbs_Node ) - continue; + if ( !elem ) continue; - int nbNodes = elem->NbNodes(); - int elemType = elem->GetType(); + SMDSAbs_GeometryType geomType = elem->GetGeomType(); + int nbNodes = elem->NbNodes(); + if ( geomType == SMDSGeom_POINT ) continue; // node - if (elem->IsPoly()) { - // Polygon or Polyhedral Volume - switch ( elemType ) { - case SMDSAbs_Face: - { - vector poly_nodes (nbNodes); - int iNode = 0; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while (itN->more()) { - const SMDS_MeshNode* node = - static_cast(itN->next()); - TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); - if (nodeMapIt == nodeMap.end()) - break; // not all nodes transformed - if (needReverse) { - // reverse mirrored faces and volumes - poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second; - } else { - poly_nodes[iNode] = (*nodeMapIt).second; - } - iNode++; - } - if ( iNode != nbNodes ) - continue; // not all nodes transformed + switch ( geomType ) { - if ( theTargetMesh ) { - myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes)); - srcElems.Append( elem ); - } - else if ( theCopy ) { - myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes)); - srcElems.Append( elem ); - } - else { - aMesh->ChangePolygonNodes(elem, poly_nodes); + case SMDSGeom_POLYGON: // ---------------------- polygon + { + vector poly_nodes (nbNodes); + int iNode = 0; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while (itN->more()) { + const SMDS_MeshNode* node = + static_cast(itN->next()); + TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); + if (nodeMapIt == nodeMap.end()) + break; // not all nodes transformed + if (needReverse) { + // reverse mirrored faces and volumes + poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second; + } else { + poly_nodes[iNode] = (*nodeMapIt).second; } + iNode++; } - break; - case SMDSAbs_Volume: - { - // ATTENTION: Reversing is not yet done!!! - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - dynamic_cast( elem ); - if (!aPolyedre) { - MESSAGE("Warning: bad volumic element"); - continue; - } + if ( iNode != nbNodes ) + continue; // not all nodes transformed - vector poly_nodes; - vector quantities; + if ( theTargetMesh ) { + myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes)); + srcElems.Append( elem ); + } + else if ( theCopy ) { + myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes)); + srcElems.Append( elem ); + } + else { + aMesh->ChangePolygonNodes(elem, poly_nodes); + } + } + break; - bool allTransformed = true; - int nbFaces = aPolyedre->NbFaces(); - for (int iface = 1; iface <= nbFaces && allTransformed; iface++) { - int nbFaceNodes = aPolyedre->NbFaceNodes(iface); - for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) { - const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode); - TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); - if (nodeMapIt == nodeMap.end()) { - allTransformed = false; // not all nodes transformed - } else { - poly_nodes.push_back((*nodeMapIt).second); - } + case SMDSGeom_POLYHEDRA: // ------------------ polyhedral volume + { + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( elem ); + if (!aPolyedre) { + MESSAGE("Warning: bad volumic element"); + continue; + } + + vector poly_nodes; poly_nodes.reserve( nbNodes ); + vector quantities; quantities.reserve( nbNodes ); + + bool allTransformed = true; + int nbFaces = aPolyedre->NbFaces(); + for (int iface = 1; iface <= nbFaces && allTransformed; iface++) { + int nbFaceNodes = aPolyedre->NbFaceNodes(iface); + for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) { + const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode); + TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); + if (nodeMapIt == nodeMap.end()) { + allTransformed = false; // not all nodes transformed + } else { + poly_nodes.push_back((*nodeMapIt).second); } - quantities.push_back(nbFaceNodes); + if ( needReverse && allTransformed ) + std::reverse( poly_nodes.end() - nbFaceNodes, poly_nodes.end() ); } - if ( !allTransformed ) - continue; // not all nodes transformed + quantities.push_back(nbFaceNodes); + } + if ( !allTransformed ) + continue; // not all nodes transformed - if ( theTargetMesh ) { - myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities)); - srcElems.Append( elem ); - } - else if ( theCopy ) { - myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities)); - srcElems.Append( elem ); - } - else { - aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); - } - } - break; - default:; - } - continue; - } - - // Regular elements - int* i = index[ FORWARD ]; - if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes - if ( elemType == SMDSAbs_Face ) - i = index[ REV_FACE ]; - else - i = index[ nbNodes - 4 ]; - - if(elem->IsQuadratic()) { - static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; - i = anIds; - if(needReverse) { - if(nbNodes==3) { // quadratic edge - static int anIds[] = {1,0,2}; - i = anIds; + if ( theTargetMesh ) { + myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities)); + srcElems.Append( elem ); } - else if(nbNodes==6) { // quadratic triangle - static int anIds[] = {0,2,1,5,4,3}; - i = anIds; + else if ( theCopy ) { + myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities)); + srcElems.Append( elem ); } - else if(nbNodes==8) { // quadratic quadrangle - static int anIds[] = {0,3,2,1,7,6,5,4}; - i = anIds; - } - else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes - static int anIds[] = {0,2,1,3,6,5,4,7,9,8}; - i = anIds; - } - else if(nbNodes==13) { // quadratic pyramid of 13 nodes - static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; - i = anIds; + else { + aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); } - else if(nbNodes==15) { // quadratic pentahedron with 15 nodes - static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; - i = anIds; + } + break; + + case SMDSGeom_BALL: // -------------------- Ball + { + if ( !theCopy && !theTargetMesh ) continue; + + TNodeNodeMap::iterator nodeMapIt = nodeMap.find( elem->GetNode(0) ); + if (nodeMapIt == nodeMap.end()) + continue; // not all nodes transformed + + double diameter = static_cast(elem)->GetDiameter(); + if ( theTargetMesh ) { + myLastCreatedElems.Append(aTgtMesh->AddBall( nodeMapIt->second, diameter )); + srcElems.Append( elem ); } - else { // nbNodes==20 - quadratic hexahedron with 20 nodes - static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; - i = anIds; + else { + myLastCreatedElems.Append(aMesh->AddBall( nodeMapIt->second, diameter )); + srcElems.Append( elem ); } } - } + break; - // find transformed nodes - vector nodes(nbNodes); - int iNode = 0; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { - const SMDS_MeshNode* node = - static_cast( itN->next() ); - TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node ); - if ( nodeMapIt == nodeMap.end() ) - break; // not all nodes transformed - nodes[ i [ iNode++ ]] = (*nodeMapIt).second; - } - if ( iNode != nbNodes ) - continue; // not all nodes transformed + default: // ----------------------- Regular elements + + while ( iForw.size() < nbNodes ) iForw.push_back( iForw.size() ); + const std::vector& iRev = SMDS_MeshCell::reverseSmdsOrder( elem->GetEntityType() ); + const std::vector& i = needReverse ? iRev : iForw; + + // find transformed nodes + vector nodes(nbNodes); + int iNode = 0; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) { + const SMDS_MeshNode* node = + static_cast( itN->next() ); + TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node ); + if ( nodeMapIt == nodeMap.end() ) + break; // not all nodes transformed + nodes[ i [ iNode++ ]] = (*nodeMapIt).second; + } + if ( iNode != nbNodes ) + continue; // not all nodes transformed - if ( theTargetMesh ) { - if ( SMDS_MeshElement* copy = - targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) { - myLastCreatedElems.Append( copy ); - srcElems.Append( elem ); + if ( theTargetMesh ) { + if ( SMDS_MeshElement* copy = + targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) { + myLastCreatedElems.Append( copy ); + srcElems.Append( elem ); + } } - } - else if ( theCopy ) { - if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) { - myLastCreatedElems.Append( copy ); - srcElems.Append( elem ); + else if ( theCopy ) { + if ( AddElement( nodes, elem->GetType(), elem->IsPoly() )) + srcElems.Append( elem ); } - } - else { - // reverse element as it was reversed by transformation - if ( nbNodes > 2 ) - aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes ); - } - } + else { + // reverse element as it was reversed by transformation + if ( nbNodes > 2 ) + aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes ); + } + } // switch ( geomType ) + + } // loop on elements PGroupIDs newGroupIDs; - if ( theMakeGroups && theCopy || - theMakeGroups && theTargetMesh ) + if ( ( theMakeGroups && theCopy ) || + ( theMakeGroups && theTargetMesh ) ) newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh ); return newGroupIDs; @@ -4515,9 +5935,9 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, if ( resElem != sourceElem ) resultElems.push_back( resElem ); // do not generate element groups from node ones - if ( sourceElem->GetType() == SMDSAbs_Node && - elems( iElem )->GetType() != SMDSAbs_Node ) - continue; +// if ( sourceElem->GetType() == SMDSAbs_Node && +// elems( iElem )->GetType() != SMDSAbs_Node ) +// continue; // add resultElems to groups made by ones the sourceElem belongs to list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end(); @@ -4569,33 +5989,32 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, return newGroupIDs; } -//======================================================================= -//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 using -// an Octree algorithm -//======================================================================= +//================================================================================ +/*! + * \brief Return list of group of nodes close to each other within theTolerance + * Search among theNodes or in the whole mesh if theNodes is empty using + * an Octree algorithm + */ +//================================================================================ -void SMESH_MeshEditor::FindCoincidentNodes (set & theNodes, - const double theTolerance, - TListOfListOfNodes & theGroupsOfNodes) +void SMESH_MeshEditor::FindCoincidentNodes (TIDSortedNodeSet & theNodes, + const double theTolerance, + TListOfListOfNodes & theGroupsOfNodes) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - set nodes; if ( theNodes.empty() ) { // get all nodes in the mesh - SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(); + SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(/*idInceasingOrder=*/true); while ( nIt->more() ) - nodes.insert( nodes.end(),nIt->next()); + theNodes.insert( theNodes.end(),nIt->next()); } - else - nodes=theNodes; - SMESH_OctreeNode::FindCoincidentNodes ( nodes, &theGroupsOfNodes, theTolerance); + SMESH_OctreeNode::FindCoincidentNodes ( theNodes, &theGroupsOfNodes, theTolerance); } + //======================================================================= /*! * \brief Implementation of search for the node closest to point @@ -4604,31 +6023,57 @@ void SMESH_MeshEditor::FindCoincidentNodes (set & theNodes struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher { + //--------------------------------------------------------------------- /*! * \brief Constructor */ SMESH_NodeSearcherImpl( const SMESHDS_Mesh* theMesh ) { - set nodes; + myMesh = ( SMESHDS_Mesh* ) theMesh; + + TIDSortedNodeSet nodes; if ( theMesh ) { - SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(); + SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true); while ( nIt->more() ) nodes.insert( nodes.end(), nIt->next() ); } myOctreeNode = new SMESH_OctreeNode(nodes) ; + + // get max size of a leaf box + SMESH_OctreeNode* tree = myOctreeNode; + while ( !tree->isLeaf() ) + { + SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator(); + if ( cIt->more() ) + tree = cIt->next(); + } + myHalfLeafSize = tree->maxSize() / 2.; + } + + //--------------------------------------------------------------------- + /*! + * \brief Move node and update myOctreeNode accordingly + */ + void MoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt ) + { + myOctreeNode->UpdateByMoveNode( node, toPnt ); + myMesh->MoveNode( node, toPnt.X(), toPnt.Y(), toPnt.Z() ); } + + //--------------------------------------------------------------------- /*! * \brief Do it's job */ const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt ) { - SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() ); + map dist2Nodes; + myOctreeNode->NodesAround( thePnt.Coord(), dist2Nodes, myHalfLeafSize ); + if ( !dist2Nodes.empty() ) + return dist2Nodes.begin()->second; list nodes; - const double precision = 1e-6; - myOctreeNode->NodesAround( &tgtNode, &nodes, precision ); + //myOctreeNode->NodesAround( &tgtNode, &nodes, myHalfLeafSize ); double minSqDist = DBL_MAX; - Bnd_B3d box; if ( nodes.empty() ) // get all nodes of OctreeNode's closest to thePnt { // sort leafs by their distance from thePnt @@ -4637,20 +6082,26 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher list< SMESH_OctreeNode* > treeList; list< SMESH_OctreeNode* >::iterator trIt; treeList.push_back( myOctreeNode ); + + gp_XYZ pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() ); + bool pointInside = myOctreeNode->isInside( pointNode, myHalfLeafSize ); for ( trIt = treeList.begin(); trIt != treeList.end(); ++trIt) { SMESH_OctreeNode* tree = *trIt; - if ( !tree->isLeaf() ) { // put children to the queue + if ( !tree->isLeaf() ) // put children to the queue + { + if ( pointInside && !tree->isInside( pointNode, myHalfLeafSize )) continue; SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator(); while ( cIt->more() ) treeList.push_back( cIt->next() ); } - else if ( tree->NbNodes() ) { // put tree to treeMap - tree->getBox( box ); + else if ( tree->NbNodes() ) // put a tree to the treeMap + { + const Bnd_B3d& box = tree->getBox(); double sqDist = thePnt.SquareDistance( 0.5 * ( box.CornerMin() + box.CornerMax() )); pair 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 )); + 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 @@ -4658,7 +6109,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher TDistTreeMap::iterator sqDist_tree = treeMap.begin(); if ( treeMap.size() > 5 ) { SMESH_OctreeNode* closestTree = sqDist_tree->second; - closestTree->getBox( box ); + const Bnd_B3d& box = closestTree->getBox(); double limit = sqrt( sqDist_tree->first ) + sqrt ( box.SquareExtent() ); sqLimit = limit * limit; } @@ -4675,7 +6126,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher const SMDS_MeshNode* closestNode = 0; list::iterator nIt = nodes.begin(); for ( ; nIt != nodes.end(); ++nIt ) { - double sqDist = thePnt.SquareDistance( TNodeXYZ( *nIt ) ); + double sqDist = thePnt.SquareDistance( SMESH_TNodeXYZ( *nIt ) ); if ( minSqDist > sqDist ) { closestNode = *nIt; minSqDist = sqDist; @@ -4683,12 +6134,23 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher } return closestNode; } + + //--------------------------------------------------------------------- /*! * \brief Destructor */ ~SMESH_NodeSearcherImpl() { delete myOctreeNode; } + + //--------------------------------------------------------------------- + /*! + * \brief Return the node tree + */ + const SMESH_OctreeNode* getTree() const { return myOctreeNode; } + private: SMESH_OctreeNode* myOctreeNode; + SMESHDS_Mesh* myMesh; + double myHalfLeafSize; // max size of a leaf box }; //======================================================================= @@ -4702,156 +6164,1400 @@ SMESH_NodeSearcher* SMESH_MeshEditor::GetNodeSearcher() return new SMESH_NodeSearcherImpl( GetMeshDS() ); } -//======================================================================= -//function : SimplifyFace -//purpose : -//======================================================================= -int SMESH_MeshEditor::SimplifyFace (const vector faceNodes, - vector& poly_nodes, - vector& quantities) const +// ======================================================================== +namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() { - int nbNodes = faceNodes.size(); + const int MaxNbElemsInLeaf = 10; // maximal number of elements in a leaf of tree + const int MaxLevel = 7; // maximal tree height -> nb terminal boxes: 8^7 = 2097152 + const double NodeRadius = 1e-9; // to enlarge bnd box of element - if (nbNodes < 3) - return 0; + //======================================================================= + /*! + * \brief Octal tree of bounding boxes of elements + */ + //======================================================================= - set nodeSet; + class ElementBndBoxTree : public SMESH_Octree + { + public: + + ElementBndBoxTree(const SMDS_Mesh& mesh, + SMDSAbs_ElementType elemType, + SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(), + double tolerance = NodeRadius ); + void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems ); + void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems); + void getElementsInSphere ( const gp_XYZ& center, + const double radius, TIDSortedElemSet& foundElems); + size_t getSize() { return std::max( _size, _elements.size() ); } + ~ElementBndBoxTree(); + + protected: + ElementBndBoxTree():_size(0) {} + SMESH_Octree* allocateOctreeChild() const { return new ElementBndBoxTree; } + void buildChildrenData(); + Bnd_B3d* buildRootBox(); + private: + //!< Bounding box of element + struct ElementBox : public Bnd_B3d + { + const SMDS_MeshElement* _element; + int _refCount; // an ElementBox can be included in several tree branches + ElementBox(const SMDS_MeshElement* elem, double tolerance); + }; + vector< ElementBox* > _elements; + size_t _size; + }; - // get simple seq of nodes - //const SMDS_MeshNode* simpleNodes[ nbNodes ]; - vector simpleNodes( nbNodes ); - int iSimple = 0, nbUnique = 0; + //================================================================================ + /*! + * \brief ElementBndBoxTree creation + */ + //================================================================================ - simpleNodes[iSimple++] = faceNodes[0]; - nbUnique++; - for (int iCur = 1; iCur < nbNodes; iCur++) { - if (faceNodes[iCur] != simpleNodes[iSimple - 1]) { - simpleNodes[iSimple++] = faceNodes[iCur]; - if (nodeSet.insert( faceNodes[iCur] ).second) - nbUnique++; - } + ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance) + :SMESH_Octree( new SMESH_Octree::Limit( MaxLevel, /*minSize=*/0. )) + { + int nbElems = mesh.GetMeshInfo().NbElements( elemType ); + _elements.reserve( nbElems ); + + SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType ); + while ( elemIt->more() ) + _elements.push_back( new ElementBox( elemIt->next(),tolerance )); + + compute(); } - int nbSimple = iSimple; - if (simpleNodes[nbSimple - 1] == simpleNodes[0]) { - nbSimple--; - iSimple--; + + //================================================================================ + /*! + * \brief Destructor + */ + //================================================================================ + + ElementBndBoxTree::~ElementBndBoxTree() + { + for ( int i = 0; i < _elements.size(); ++i ) + if ( --_elements[i]->_refCount <= 0 ) + delete _elements[i]; } - if (nbUnique < 3) - return 0; + //================================================================================ + /*! + * \brief Return the maximal box + */ + //================================================================================ - // separate loops - int nbNew = 0; - bool foundLoop = (nbSimple > nbUnique); - while (foundLoop) { - foundLoop = false; - set loopSet; - for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) { - const SMDS_MeshNode* n = simpleNodes[iSimple]; - if (!loopSet.insert( n ).second) { - foundLoop = true; + Bnd_B3d* ElementBndBoxTree::buildRootBox() + { + Bnd_B3d* box = new Bnd_B3d; + for ( int i = 0; i < _elements.size(); ++i ) + box->Add( *_elements[i] ); + return box; + } - // separate loop - int iC = 0, curLast = iSimple; - for (; iC < curLast; iC++) { - if (simpleNodes[iC] == n) break; - } - int loopLen = curLast - iC; - if (loopLen > 2) { - // create sub-element - nbNew++; - quantities.push_back(loopLen); - for (; iC < curLast; iC++) { - poly_nodes.push_back(simpleNodes[iC]); - } - } - // shift the rest nodes (place from the first loop position) - for (iC = curLast + 1; iC < nbSimple; iC++) { - simpleNodes[iC - loopLen] = simpleNodes[iC]; + //================================================================================ + /*! + * \brief Redistrubute element boxes among children + */ + //================================================================================ + + void ElementBndBoxTree::buildChildrenData() + { + for ( int i = 0; i < _elements.size(); ++i ) + { + for (int j = 0; j < 8; j++) + { + if ( !_elements[i]->IsOut( myChildren[j]->getBox() )) + { + _elements[i]->_refCount++; + ((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]); } - nbSimple -= loopLen; - iSimple -= loopLen; } - } // for (iSimple = 0; iSimple < nbSimple; iSimple++) - } // while (foundLoop) + _elements[i]->_refCount--; + } + _size = _elements.size(); + SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory - if (iSimple > 2) { - nbNew++; - quantities.push_back(iSimple); - for (int i = 0; i < iSimple; i++) - poly_nodes.push_back(simpleNodes[i]); + for (int j = 0; j < 8; j++) + { + ElementBndBoxTree* child = static_cast( myChildren[j]); + if ( child->_elements.size() <= MaxNbElemsInLeaf ) + child->myIsLeaf = true; + + if ( child->_elements.capacity() - child->_elements.size() > 1000 ) + SMESHUtils::CompactVector( child->_elements ); + } } - return nbNew; -} + //================================================================================ + /*! + * \brief Return elements which can include the point + */ + //================================================================================ -//======================================================================= -//function : MergeNodes -//purpose : In each group, the cdr of nodes are substituted by the first one -// in all elements. -//======================================================================= + void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point, + TIDSortedElemSet& foundElems) + { + if ( getBox().IsOut( point.XYZ() )) + return; -void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) -{ - myLastCreatedElems.Clear(); - myLastCreatedNodes.Clear(); + if ( isLeaf() ) + { + for ( int i = 0; i < _elements.size(); ++i ) + if ( !_elements[i]->IsOut( point.XYZ() )) + foundElems.insert( _elements[i]->_element ); + } + else + { + for (int i = 0; i < 8; i++) + ((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems ); + } + } - SMESHDS_Mesh* aMesh = GetMeshDS(); + //================================================================================ + /*! + * \brief Return elements which can be intersected by the line + */ + //================================================================================ - TNodeNodeMap nodeNodeMap; // node to replace - new node - set elems; // all elements with changed nodes - list< int > rmElemIds, rmNodeIds; + void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line, + TIDSortedElemSet& foundElems) + { + if ( getBox().IsOut( line )) + return; - // Fill nodeNodeMap and elems + if ( isLeaf() ) + { + for ( int i = 0; i < _elements.size(); ++i ) + if ( !_elements[i]->IsOut( line )) + foundElems.insert( _elements[i]->_element ); + } + else + { + for (int i = 0; i < 8; i++) + ((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems ); + } + } - TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin(); - for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) { - list& nodes = *grIt; - list::iterator nIt = nodes.begin(); - const SMDS_MeshNode* nToKeep = *nIt; - for ( ++nIt; nIt != nodes.end(); nIt++ ) { - const SMDS_MeshNode* nToRemove = *nIt; - nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep )); - if ( nToRemove != nToKeep ) { - rmNodeIds.push_back( nToRemove->GetID() ); - AddToSameGroups( nToKeep, nToRemove, aMesh ); - } + //================================================================================ + /*! + * \brief Return elements from leaves intersecting the sphere + */ + //================================================================================ - SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); - while ( invElemIt->more() ) { - const SMDS_MeshElement* elem = invElemIt->next(); - elems.insert(elem); - } + void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center, + const double radius, + TIDSortedElemSet& foundElems) + { + if ( getBox().IsOut( center, radius )) + return; + + if ( isLeaf() ) + { + for ( int i = 0; i < _elements.size(); ++i ) + if ( !_elements[i]->IsOut( center, radius )) + foundElems.insert( _elements[i]->_element ); + } + else + { + for (int i = 0; i < 8; i++) + ((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems ); } } - // Change element nodes or remove an element - set::iterator eIt = elems.begin(); - for ( ; eIt != elems.end(); eIt++ ) { - const SMDS_MeshElement* elem = *eIt; - int nbNodes = elem->NbNodes(); - int aShapeId = FindShape( elem ); + //================================================================================ + /*! + * \brief Construct the element box + */ + //================================================================================ - set nodeSet; - vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes ); - int iUnique = 0, iCur = 0, nbRepl = 0; - vector iRepl( nbNodes ); + ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance) + { + _element = elem; + _refCount = 1; + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + while ( nIt->more() ) + Add( SMESH_TNodeXYZ( nIt->next() )); + Enlarge( tolerance ); + } - // get new seq of nodes - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { - const SMDS_MeshNode* n = - static_cast( itN->next() ); +} // namespace - TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n ); - if ( nnIt != nodeNodeMap.end() ) { // n sticks - n = (*nnIt).second; - iRepl[ nbRepl++ ] = iCur; +//======================================================================= +/*! + * \brief Implementation of search for the elements by point and + * of classification of point in 2D mesh + */ +//======================================================================= + +struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher +{ + SMESHDS_Mesh* _mesh; + SMDS_ElemIteratorPtr _meshPartIt; + ElementBndBoxTree* _ebbTree; + SMESH_NodeSearcherImpl* _nodeSearcher; + SMDSAbs_ElementType _elementType; + double _tolerance; + bool _outerFacesFound; + set _outerFaces; // empty means "no internal faces at all" + + SMESH_ElementSearcherImpl( SMESHDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr()) + : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {} + ~SMESH_ElementSearcherImpl() + { + if ( _ebbTree ) delete _ebbTree; _ebbTree = 0; + if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0; + } + virtual int FindElementsByPoint(const gp_Pnt& point, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElements); + virtual TopAbs_State GetPointState(const gp_Pnt& point); + virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point, + SMDSAbs_ElementType type ); + + void GetElementsNearLine( const gp_Ax1& line, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElems); + double getTolerance(); + bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face, + const double tolerance, double & param); + void findOuterBoundary(const SMDS_MeshElement* anyOuterFace); + bool isOuterBoundary(const SMDS_MeshElement* face) const + { + return _outerFaces.empty() || _outerFaces.count(face); + } + struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState()) + { + const SMDS_MeshElement* _face; + gp_Vec _faceNorm; + bool _coincides; //!< the line lays in face plane + TInters(const SMDS_MeshElement* face, const gp_Vec& faceNorm, bool coinc=false) + : _face(face), _faceNorm( faceNorm ), _coincides( coinc ) {} + }; + struct TFaceLink //!< link and faces sharing it (used in findOuterBoundary()) + { + SMESH_TLink _link; + TIDSortedElemSet _faces; + TFaceLink( const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshElement* face) + : _link( n1, n2 ), _faces( &face, &face + 1) {} + }; +}; + +ostream& operator<< (ostream& out, const SMESH_ElementSearcherImpl::TInters& i) +{ + return out << "TInters(face=" << ( i._face ? i._face->GetID() : 0) + << ", _coincides="<GetMeshInfo(); + + _tolerance = 0; + if ( _nodeSearcher && meshInfo.NbNodes() > 1 ) + { + double boxSize = _nodeSearcher->getTree()->maxSize(); + _tolerance = 1e-8 * boxSize/* / meshInfo.NbNodes()*/; + } + else if ( _ebbTree && meshInfo.NbElements() > 0 ) + { + double boxSize = _ebbTree->maxSize(); + _tolerance = 1e-8 * boxSize/* / meshInfo.NbElements()*/; + } + if ( _tolerance == 0 ) + { + // define tolerance by size of a most complex element + int complexType = SMDSAbs_Volume; + while ( complexType > SMDSAbs_All && + meshInfo.NbElements( SMDSAbs_ElementType( complexType )) < 1 ) + --complexType; + if ( complexType == SMDSAbs_All ) return 0; // empty mesh + double elemSize; + if ( complexType == int( SMDSAbs_Node )) + { + SMDS_NodeIteratorPtr nodeIt = _mesh->nodesIterator(); + elemSize = 1; + if ( meshInfo.NbNodes() > 2 ) + elemSize = SMESH_TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() ); + } + else + { + SMDS_ElemIteratorPtr elemIt = + _mesh->elementsIterator( SMDSAbs_ElementType( complexType )); + const SMDS_MeshElement* elem = elemIt->next(); + SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); + SMESH_TNodeXYZ n1( cast2Node( nodeIt->next() )); + elemSize = 0; + while ( nodeIt->more() ) + { + double dist = n1.Distance( cast2Node( nodeIt->next() )); + elemSize = max( dist, elemSize ); + } + } + _tolerance = 1e-4 * elemSize; + } + } + return _tolerance; +} + +//================================================================================ +/*! + * \brief Find intersection of the line and an edge of face and return parameter on line + */ +//================================================================================ + +bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin& line, + const SMDS_MeshElement* face, + const double tol, + double & param) +{ + int nbInts = 0; + param = 0; + + GeomAPI_ExtremaCurveCurve anExtCC; + Handle(Geom_Curve) lineCurve = new Geom_Line( line ); + + int nbNodes = face->IsQuadratic() ? face->NbNodes()/2 : face->NbNodes(); + for ( int i = 0; i < nbNodes && nbInts < 2; ++i ) + { + GC_MakeSegment edge( SMESH_TNodeXYZ( face->GetNode( i )), + SMESH_TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); + anExtCC.Init( lineCurve, edge); + if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol) + { + Quantity_Parameter pl, pe; + anExtCC.LowerDistanceParameters( pl, pe ); + param += pl; + if ( ++nbInts == 2 ) + break; + } + } + if ( nbInts > 0 ) param /= nbInts; + return nbInts > 0; +} +//================================================================================ +/*! + * \brief Find all faces belonging to the outer boundary of mesh + */ +//================================================================================ + +void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerFace) +{ + if ( _outerFacesFound ) return; + + // Collect all outer faces by passing from one outer face to another via their links + // and BTW find out if there are internal faces at all. + + // checked links and links where outer boundary meets internal one + set< SMESH_TLink > visitedLinks, seamLinks; + + // links to treat with already visited faces sharing them + list < TFaceLink > startLinks; + + // load startLinks with the first outerFace + startLinks.push_back( TFaceLink( outerFace->GetNode(0), outerFace->GetNode(1), outerFace)); + _outerFaces.insert( outerFace ); + + TIDSortedElemSet emptySet; + while ( !startLinks.empty() ) + { + const SMESH_TLink& link = startLinks.front()._link; + TIDSortedElemSet& faces = startLinks.front()._faces; + + outerFace = *faces.begin(); + // find other faces sharing the link + const SMDS_MeshElement* f; + while (( f = SMESH_MeshEditor::FindFaceInSet(link.node1(), link.node2(), emptySet, faces ))) + faces.insert( f ); + + // select another outer face among the found + const SMDS_MeshElement* outerFace2 = 0; + if ( faces.size() == 2 ) + { + outerFace2 = (outerFace == *faces.begin() ? *faces.rbegin() : *faces.begin()); + } + else if ( faces.size() > 2 ) + { + seamLinks.insert( link ); + + // link direction within the outerFace + gp_Vec n1n2( SMESH_TNodeXYZ( link.node1()), + SMESH_TNodeXYZ( link.node2())); + int i1 = outerFace->GetNodeIndex( link.node1() ); + int i2 = outerFace->GetNodeIndex( link.node2() ); + bool rev = ( abs(i2-i1) == 1 ? i1 > i2 : i2 > i1 ); + if ( rev ) n1n2.Reverse(); + // outerFace normal + gp_XYZ ofNorm, fNorm; + if ( SMESH_Algo::FaceNormal( outerFace, ofNorm, /*normalized=*/false )) + { + // direction from the link inside outerFace + gp_Vec dirInOF = gp_Vec( ofNorm ) ^ n1n2; + // sort all other faces by angle with the dirInOF + map< double, const SMDS_MeshElement* > angle2Face; + set< const SMDS_MeshElement*, TIDCompare >::const_iterator face = faces.begin(); + for ( ; face != faces.end(); ++face ) + { + if ( !SMESH_Algo::FaceNormal( *face, fNorm, /*normalized=*/false )) + continue; + gp_Vec dirInF = gp_Vec( fNorm ) ^ n1n2; + double angle = dirInOF.AngleWithRef( dirInF, n1n2 ); + if ( angle < 0 ) angle += 2. * M_PI; + angle2Face.insert( make_pair( angle, *face )); + } + if ( !angle2Face.empty() ) + outerFace2 = angle2Face.begin()->second; + } + } + // store the found outer face and add its links to continue seaching from + if ( outerFace2 ) + { + _outerFaces.insert( outerFace ); + int nbNodes = outerFace2->NbNodes()/( outerFace2->IsQuadratic() ? 2 : 1 ); + for ( int i = 0; i < nbNodes; ++i ) + { + SMESH_TLink link2( outerFace2->GetNode(i), outerFace2->GetNode((i+1)%nbNodes)); + if ( visitedLinks.insert( link2 ).second ) + startLinks.push_back( TFaceLink( link2.node1(), link2.node2(), outerFace2 )); + } + } + startLinks.pop_front(); + } + _outerFacesFound = true; + + if ( !seamLinks.empty() ) + { + // There are internal boundaries touching the outher one, + // find all faces of internal boundaries in order to find + // faces of boundaries of holes, if any. + + } + else + { + _outerFaces.clear(); + } +} + +//======================================================================= +/*! + * \brief Find elements of given type where the given point is IN or ON. + * Returns nb of found elements and elements them-selves. + * + * 'ALL' type means elements of any type excluding nodes, balls and 0D elements + */ +//======================================================================= + +int SMESH_ElementSearcherImpl:: +FindElementsByPoint(const gp_Pnt& point, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElements) +{ + foundElements.clear(); + + double tolerance = getTolerance(); + + // ================================================================================= + if ( type == SMDSAbs_Node || type == SMDSAbs_0DElement || type == SMDSAbs_Ball) + { + if ( !_nodeSearcher ) + _nodeSearcher = new SMESH_NodeSearcherImpl( _mesh ); + + const SMDS_MeshNode* closeNode = _nodeSearcher->FindClosestTo( point ); + if ( !closeNode ) return foundElements.size(); + + if ( point.Distance( SMESH_TNodeXYZ( closeNode )) > tolerance ) + return foundElements.size(); // to far from any node + + if ( type == SMDSAbs_Node ) + { + foundElements.push_back( closeNode ); + } + else + { + SMDS_ElemIteratorPtr elemIt = closeNode->GetInverseElementIterator( type ); + while ( elemIt->more() ) + foundElements.push_back( elemIt->next() ); + } + } + // ================================================================================= + else // elements more complex than 0D + { + if ( !_ebbTree || _elementType != type ) + { + if ( _ebbTree ) delete _ebbTree; + _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt, tolerance ); + } + TIDSortedElemSet suspectElems; + _ebbTree->getElementsNearPoint( point, suspectElems ); + TIDSortedElemSet::iterator elem = suspectElems.begin(); + for ( ; elem != suspectElems.end(); ++elem ) + if ( !SMESH_MeshEditor::IsOut( *elem, point, tolerance )) + foundElements.push_back( *elem ); + } + return foundElements.size(); +} + +//======================================================================= +/*! + * \brief Find an element of given type most close to the given point + * + * WARNING: Only face search is implemeneted so far + */ +//======================================================================= + +const SMDS_MeshElement* +SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point, + SMDSAbs_ElementType type ) +{ + const SMDS_MeshElement* closestElem = 0; + + if ( type == SMDSAbs_Face ) + { + if ( !_ebbTree || _elementType != type ) + { + if ( _ebbTree ) delete _ebbTree; + _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt ); + } + TIDSortedElemSet suspectElems; + _ebbTree->getElementsNearPoint( point, suspectElems ); + + if ( suspectElems.empty() && _ebbTree->maxSize() > 0 ) + { + gp_Pnt boxCenter = 0.5 * ( _ebbTree->getBox().CornerMin() + + _ebbTree->getBox().CornerMax() ); + double radius; + if ( _ebbTree->getBox().IsOut( point.XYZ() )) + radius = point.Distance( boxCenter ) - 0.5 * _ebbTree->maxSize(); + else + radius = _ebbTree->maxSize() / pow( 2., _ebbTree->getHeight()) / 2; + while ( suspectElems.empty() ) + { + _ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems ); + radius *= 1.1; + } + } + double minDist = std::numeric_limits::max(); + multimap< double, const SMDS_MeshElement* > dist2face; + TIDSortedElemSet::iterator elem = suspectElems.begin(); + for ( ; elem != suspectElems.end(); ++elem ) + { + double dist = SMESH_MeshEditor::GetDistance( dynamic_cast(*elem), + point ); + if ( dist < minDist + 1e-10) + { + minDist = dist; + dist2face.insert( dist2face.begin(), make_pair( dist, *elem )); + } + } + if ( !dist2face.empty() ) + { + multimap< double, const SMDS_MeshElement* >::iterator d2f = dist2face.begin(); + closestElem = d2f->second; + // if there are several elements at the same distance, select one + // with GC closest to the point + typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator; + double minDistToGC = 0; + for ( ++d2f; d2f != dist2face.end() && fabs( d2f->first - minDist ) < 1e-10; ++d2f ) + { + if ( minDistToGC == 0 ) + { + gp_XYZ gc(0,0,0); + gc = accumulate( TXyzIterator(closestElem->nodesIterator()), + TXyzIterator(), gc ) / closestElem->NbNodes(); + minDistToGC = point.SquareDistance( gc ); + } + gp_XYZ gc(0,0,0); + gc = accumulate( TXyzIterator( d2f->second->nodesIterator()), + TXyzIterator(), gc ) / d2f->second->NbNodes(); + double d = point.SquareDistance( gc ); + if ( d < minDistToGC ) + { + minDistToGC = d; + closestElem = d2f->second; + } + } + // cout << "FindClosestTo( " <GetID() << " DIST " << minDist << endl; + } + } + else + { + // NOT IMPLEMENTED SO FAR + } + return closestElem; +} + + +//================================================================================ +/*! + * \brief Classify the given point in the closed 2D mesh + */ +//================================================================================ + +TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) +{ + double tolerance = getTolerance(); + if ( !_ebbTree || _elementType != SMDSAbs_Face ) + { + if ( _ebbTree ) delete _ebbTree; + _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face, _meshPartIt ); + } + // Algo: analyse transition of a line starting at the point through mesh boundary; + // try three lines parallel to axis of the coordinate system and perform rough + // analysis. If solution is not clear perform thorough analysis. + + const int nbAxes = 3; + gp_Dir axisDir[ nbAxes ] = { gp::DX(), gp::DY(), gp::DZ() }; + map< double, TInters > paramOnLine2TInters[ nbAxes ]; + list< TInters > tangentInters[ nbAxes ]; // of faces whose plane includes the line + multimap< int, int > nbInt2Axis; // to find the simplest case + for ( int axis = 0; axis < nbAxes; ++axis ) + { + gp_Ax1 lineAxis( point, axisDir[axis]); + gp_Lin line ( lineAxis ); + + TIDSortedElemSet suspectFaces; // faces possibly intersecting the line + _ebbTree->getElementsNearLine( lineAxis, suspectFaces ); + + // Intersect faces with the line + + map< double, TInters > & u2inters = paramOnLine2TInters[ axis ]; + TIDSortedElemSet::iterator face = suspectFaces.begin(); + for ( ; face != suspectFaces.end(); ++face ) + { + // get face plane + gp_XYZ fNorm; + if ( !SMESH_Algo::FaceNormal( *face, fNorm, /*normalized=*/false)) continue; + gp_Pln facePlane( SMESH_TNodeXYZ( (*face)->GetNode(0)), fNorm ); + + // perform intersection + IntAna_IntConicQuad intersection( line, IntAna_Quadric( facePlane )); + if ( !intersection.IsDone() ) + continue; + if ( intersection.IsInQuadric() ) + { + tangentInters[ axis ].push_back( TInters( *face, fNorm, true )); + } + else if ( ! intersection.IsParallel() && intersection.NbPoints() > 0 ) + { + gp_Pnt intersectionPoint = intersection.Point(1); + if ( !SMESH_MeshEditor::IsOut( *face, intersectionPoint, tolerance )) + u2inters.insert(make_pair( intersection.ParamOnConic(1), TInters( *face, fNorm ))); + } + } + // Analyse intersections roughly + + int nbInter = u2inters.size(); + if ( nbInter == 0 ) + return TopAbs_OUT; + + double f = u2inters.begin()->first, l = u2inters.rbegin()->first; + if ( nbInter == 1 ) // not closed mesh + return fabs( f ) < tolerance ? TopAbs_ON : TopAbs_UNKNOWN; + + if ( fabs( f ) < tolerance || fabs( l ) < tolerance ) + return TopAbs_ON; + + if ( (f<0) == (l<0) ) + return TopAbs_OUT; + + int nbIntBeforePoint = std::distance( u2inters.begin(), u2inters.lower_bound(0)); + int nbIntAfterPoint = nbInter - nbIntBeforePoint; + if ( nbIntBeforePoint == 1 || nbIntAfterPoint == 1 ) + return TopAbs_IN; + + nbInt2Axis.insert( make_pair( min( nbIntBeforePoint, nbIntAfterPoint ), axis )); + + if ( _outerFacesFound ) break; // pass to thorough analysis + + } // three attempts - loop on CS axes + + // Analyse intersections thoroughly. + // We make two loops maximum, on the first one we only exclude touching intersections, + // on the second, if situation is still unclear, we gather and use information on + // position of faces (internal or outer). If faces position is already gathered, + // we make the second loop right away. + + for ( int hasPositionInfo = _outerFacesFound; hasPositionInfo < 2; ++hasPositionInfo ) + { + multimap< int, int >::const_iterator nb_axis = nbInt2Axis.begin(); + for ( ; nb_axis != nbInt2Axis.end(); ++nb_axis ) + { + int axis = nb_axis->second; + map< double, TInters > & u2inters = paramOnLine2TInters[ axis ]; + + gp_Ax1 lineAxis( point, axisDir[axis]); + gp_Lin line ( lineAxis ); + + // add tangent intersections to u2inters + double param; + list< TInters >::const_iterator tgtInt = tangentInters[ axis ].begin(); + for ( ; tgtInt != tangentInters[ axis ].end(); ++tgtInt ) + if ( getIntersParamOnLine( line, tgtInt->_face, tolerance, param )) + u2inters.insert(make_pair( param, *tgtInt )); + tangentInters[ axis ].clear(); + + // Count intersections before and after the point excluding touching ones. + // If hasPositionInfo we count intersections of outer boundary only + + int nbIntBeforePoint = 0, nbIntAfterPoint = 0; + double f = numeric_limits::max(), l = -numeric_limits::max(); + map< double, TInters >::iterator u_int1 = u2inters.begin(), u_int2 = u_int1; + bool ok = ! u_int1->second._coincides; + while ( ok && u_int1 != u2inters.end() ) + { + double u = u_int1->first; + bool touchingInt = false; + if ( ++u_int2 != u2inters.end() ) + { + // skip intersections at the same point (if the line passes through edge or node) + int nbSamePnt = 0; + while ( u_int2 != u2inters.end() && fabs( u_int2->first - u ) < tolerance ) + { + ++nbSamePnt; + ++u_int2; + } + + // skip tangent intersections + int nbTgt = 0; + const SMDS_MeshElement* prevFace = u_int1->second._face; + while ( ok && u_int2->second._coincides ) + { + if ( SMESH_Algo::GetCommonNodes(prevFace , u_int2->second._face).empty() ) + ok = false; + else + { + nbTgt++; + u_int2++; + ok = ( u_int2 != u2inters.end() ); + } + } + if ( !ok ) break; + + // skip intersections at the same point after tangent intersections + if ( nbTgt > 0 ) + { + double u2 = u_int2->first; + ++u_int2; + while ( u_int2 != u2inters.end() && fabs( u_int2->first - u2 ) < tolerance ) + { + ++nbSamePnt; + ++u_int2; + } + } + // decide if we skipped a touching intersection + if ( nbSamePnt + nbTgt > 0 ) + { + double minDot = numeric_limits::max(), maxDot = -numeric_limits::max(); + map< double, TInters >::iterator u_int = u_int1; + for ( ; u_int != u_int2; ++u_int ) + { + if ( u_int->second._coincides ) continue; + double dot = u_int->second._faceNorm * line.Direction(); + if ( dot > maxDot ) maxDot = dot; + if ( dot < minDot ) minDot = dot; + } + touchingInt = ( minDot*maxDot < 0 ); + } + } + if ( !touchingInt ) + { + if ( !hasPositionInfo || isOuterBoundary( u_int1->second._face )) + { + if ( u < 0 ) + ++nbIntBeforePoint; + else + ++nbIntAfterPoint; + } + if ( u < f ) f = u; + if ( u > l ) l = u; + } + + u_int1 = u_int2; // to next intersection + + } // loop on intersections with one line + + if ( ok ) + { + if ( fabs( f ) < tolerance || fabs( l ) < tolerance ) + return TopAbs_ON; + + if ( nbIntBeforePoint == 0 || nbIntAfterPoint == 0) + return TopAbs_OUT; + + if ( nbIntBeforePoint + nbIntAfterPoint == 1 ) // not closed mesh + return fabs( f ) < tolerance ? TopAbs_ON : TopAbs_UNKNOWN; + + if ( nbIntBeforePoint == 1 || nbIntAfterPoint == 1 ) + return TopAbs_IN; + + if ( (f<0) == (l<0) ) + return TopAbs_OUT; + + if ( hasPositionInfo ) + return nbIntBeforePoint % 2 ? TopAbs_IN : TopAbs_OUT; + } + } // loop on intersections of the tree lines - thorough analysis + + if ( !hasPositionInfo ) + { + // gather info on faces position - is face in the outer boundary or not + map< double, TInters > & u2inters = paramOnLine2TInters[ 0 ]; + findOuterBoundary( u2inters.begin()->second._face ); + } + + } // two attempts - with and w/o faces position info in the mesh + + return TopAbs_UNKNOWN; +} + +//======================================================================= +/*! + * \brief Return elements possibly intersecting the line + */ +//======================================================================= + +void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1& line, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElems) +{ + if ( !_ebbTree || _elementType != type ) + { + if ( _ebbTree ) delete _ebbTree; + _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt ); + } + TIDSortedElemSet suspectFaces; // elements possibly intersecting the line + _ebbTree->getElementsNearLine( line, suspectFaces ); + foundElems.assign( suspectFaces.begin(), suspectFaces.end()); +} + +//======================================================================= +/*! + * \brief Return SMESH_ElementSearcher + */ +//======================================================================= + +SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher() +{ + return new SMESH_ElementSearcherImpl( *GetMeshDS() ); +} + +//======================================================================= +/*! + * \brief Return SMESH_ElementSearcher acting on a sub-set of elements + */ +//======================================================================= + +SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher(SMDS_ElemIteratorPtr elemIt) +{ + return new SMESH_ElementSearcherImpl( *GetMeshDS(), elemIt ); +} + +//======================================================================= +/*! + * \brief Return true if the point is IN or ON of the element + */ +//======================================================================= + +bool SMESH_MeshEditor::IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol ) +{ + if ( element->GetType() == SMDSAbs_Volume) + { + return SMDS_VolumeTool( element ).IsOut( point.X(), point.Y(), point.Z(), tol ); + } + + // get ordered nodes + + vector< gp_XYZ > xyz; + vector nodeList; + + SMDS_ElemIteratorPtr nodeIt = element->nodesIterator(); + if ( element->IsQuadratic() ) { + if (const SMDS_VtkFace* f=dynamic_cast(element)) + nodeIt = f->interlacedNodesElemIterator(); + else if (const SMDS_VtkEdge* e =dynamic_cast(element)) + nodeIt = e->interlacedNodesElemIterator(); + } + while ( nodeIt->more() ) + { + const SMDS_MeshNode* node = cast2Node( nodeIt->next() ); + xyz.push_back( SMESH_TNodeXYZ(node) ); + nodeList.push_back(node); + } + + int i, nbNodes = element->NbNodes(); + + if ( element->GetType() == SMDSAbs_Face ) // -------------------------------------------------- + { + // compute face normal + gp_Vec faceNorm(0,0,0); + xyz.push_back( xyz.front() ); + nodeList.push_back( nodeList.front() ); + for ( i = 0; i < nbNodes; ++i ) + { + gp_Vec edge1( xyz[i+1], xyz[i]); + gp_Vec edge2( xyz[i+1], xyz[(i+2)%nbNodes] ); + faceNorm += edge1 ^ edge2; + } + double normSize = faceNorm.Magnitude(); + if ( normSize <= tol ) + { + // degenerated face: point is out if it is out of all face edges + for ( i = 0; i < nbNodes; ++i ) + { + SMDS_LinearEdge edge( nodeList[i], nodeList[i+1] ); + if ( !IsOut( &edge, point, tol )) + return false; + } + return true; + } + faceNorm /= normSize; + + // check if the point lays on face plane + gp_Vec n2p( xyz[0], point ); + if ( fabs( n2p * faceNorm ) > tol ) + return true; // not on face plane + + // check if point is out of face boundary: + // define it by closest transition of a ray point->infinity through face boundary + // on the face plane. + // First, find normal of a plane perpendicular to face plane, to be used as a cutting tool + // to find intersections of the ray with the boundary. + gp_Vec ray = n2p; + gp_Vec plnNorm = ray ^ faceNorm; + normSize = plnNorm.Magnitude(); + if ( normSize <= tol ) return false; // point coincides with the first node + plnNorm /= normSize; + // for each node of the face, compute its signed distance to the plane + vector dist( nbNodes + 1); + for ( i = 0; i < nbNodes; ++i ) + { + gp_Vec n2p( xyz[i], point ); + dist[i] = n2p * plnNorm; + } + dist.back() = dist.front(); + // find the closest intersection + int iClosest = -1; + double rClosest, distClosest = 1e100;; + gp_Pnt pClosest; + for ( i = 0; i < nbNodes; ++i ) + { + double r; + if ( fabs( dist[i]) < tol ) + r = 0.; + else if ( fabs( dist[i+1]) < tol ) + r = 1.; + else if ( dist[i] * dist[i+1] < 0 ) + r = dist[i] / ( dist[i] - dist[i+1] ); + else + continue; // no intersection + gp_Pnt pInt = xyz[i] * (1.-r) + xyz[i+1] * r; + gp_Vec p2int ( point, pInt); + if ( p2int * ray > -tol ) // right half-space + { + double intDist = p2int.SquareMagnitude(); + if ( intDist < distClosest ) + { + iClosest = i; + rClosest = r; + pClosest = pInt; + distClosest = intDist; + } + } + } + if ( iClosest < 0 ) + return true; // no intesections - out + + // analyse transition + gp_Vec edge( xyz[iClosest], xyz[iClosest+1] ); + gp_Vec edgeNorm = -( edge ^ faceNorm ); // normal to intersected edge pointing out of face + gp_Vec p2int ( point, pClosest ); + bool out = (edgeNorm * p2int) < -tol; + if ( rClosest > 0. && rClosest < 1. ) // not node intersection + return out; + + // ray pass through a face node; analyze transition through an adjacent edge + gp_Pnt p1 = xyz[ (rClosest == 0.) ? ((iClosest+nbNodes-1) % nbNodes) : (iClosest+1) ]; + gp_Pnt p2 = xyz[ (rClosest == 0.) ? iClosest : ((iClosest+2) % nbNodes) ]; + gp_Vec edgeAdjacent( p1, p2 ); + gp_Vec edgeNorm2 = -( edgeAdjacent ^ faceNorm ); + bool out2 = (edgeNorm2 * p2int) < -tol; + + bool covexCorner = ( edgeNorm * edgeAdjacent * (rClosest==1. ? 1. : -1.)) < 0; + return covexCorner ? (out || out2) : (out && out2); + } + if ( element->GetType() == SMDSAbs_Edge ) // -------------------------------------------------- + { + // point is out of edge if it is NOT ON any straight part of edge + // (we consider quadratic edge as being composed of two straight parts) + for ( i = 1; i < nbNodes; ++i ) + { + gp_Vec edge( xyz[i-1], xyz[i]); + gp_Vec n1p ( xyz[i-1], point); + double dist = ( edge ^ n1p ).Magnitude() / edge.Magnitude(); + if ( dist > tol ) + continue; + gp_Vec n2p( xyz[i], point ); + if ( fabs( edge.Magnitude() - n1p.Magnitude() - n2p.Magnitude()) > tol ) + continue; + return false; // point is ON this part + } + return true; + } + // Node or 0D element ------------------------------------------------------------------------- + { + gp_Vec n2p ( xyz[0], point ); + return n2p.Magnitude() <= tol; + } + return true; +} + +//======================================================================= + +namespace +{ + // Position of a point relative to a segment + // . . + // . LEFT . + // . . + // VERTEX 1 o----ON-----> VERTEX 2 + // . . + // . RIGHT . + // . . + enum PositionName { POS_LEFT = 1, POS_VERTEX = 2, POS_RIGHT = 4, //POS_ON = 8, + POS_ALL = POS_LEFT | POS_RIGHT | POS_VERTEX }; + struct PointPos + { + PositionName _name; + int _index; // index of vertex or segment + + PointPos( PositionName n, int i=-1 ): _name(n), _index(i) {} + bool operator < (const PointPos& other ) const + { + if ( _name == other._name ) + return ( _index < 0 || other._index < 0 ) ? false : _index < other._index; + return _name < other._name; + } + }; + + //================================================================================ + /*! + * \brief Return of a point relative to a segment + * \param point2D - the point to analyze position of + * \param xyVec - end points of segments + * \param index0 - 0-based index of the first point of segment + * \param posToFindOut - flags of positions to detect + * \retval PointPos - point position + */ + //================================================================================ + + PointPos getPointPosition( const gp_XY& point2D, + const gp_XY* segEnds, + const int index0 = 0, + const int posToFindOut = POS_ALL) + { + const gp_XY& p1 = segEnds[ index0 ]; + const gp_XY& p2 = segEnds[ index0+1 ]; + const gp_XY grad = p2 - p1; + + if ( posToFindOut & POS_VERTEX ) + { + // check if the point2D is at "vertex 1" zone + gp_XY pp1[2] = { p1, gp_XY( p1.X() - grad.Y(), + p1.Y() + grad.X() ) }; + if ( getPointPosition( point2D, pp1, 0, POS_LEFT|POS_RIGHT )._name == POS_LEFT ) + return PointPos( POS_VERTEX, index0 ); + + // check if the point2D is at "vertex 2" zone + gp_XY pp2[2] = { p2, gp_XY( p2.X() - grad.Y(), + p2.Y() + grad.X() ) }; + if ( getPointPosition( point2D, pp2, 0, POS_LEFT|POS_RIGHT )._name == POS_RIGHT ) + return PointPos( POS_VERTEX, index0 + 1); + } + double edgeEquation = + ( point2D.X() - p1.X() ) * grad.Y() - ( point2D.Y() - p1.Y() ) * grad.X(); + return PointPos( edgeEquation < 0 ? POS_LEFT : POS_RIGHT, index0 ); + } +} + +//======================================================================= +/*! + * \brief Return minimal distance from a point to a face + * + * Currently we ignore non-planarity and 2nd order of face + */ +//======================================================================= + +double SMESH_MeshEditor::GetDistance( const SMDS_MeshFace* face, + const gp_Pnt& point ) +{ + double badDistance = -1; + if ( !face ) return badDistance; + + // coordinates of nodes (medium nodes, if any, ignored) + typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator; + vector xyz( TXyzIterator( face->nodesIterator()), TXyzIterator() ); + xyz.resize( face->NbCornerNodes()+1 ); + + // transformation to get xyz[0] lies on the origin, xyz[1] lies on the Z axis, + // and xyz[2] lies in the XZ plane. This is to pass to 2D space on XZ plane. + gp_Trsf trsf; + gp_Vec OZ ( xyz[0], xyz[1] ); + gp_Vec OX ( xyz[0], xyz[2] ); + if ( OZ.Magnitude() < std::numeric_limits::min() ) + { + if ( xyz.size() < 4 ) return badDistance; + OZ = gp_Vec ( xyz[0], xyz[2] ); + OX = gp_Vec ( xyz[0], xyz[3] ); + } + gp_Ax3 tgtCS; + try { + tgtCS = gp_Ax3( xyz[0], OZ, OX ); + } + catch ( Standard_Failure ) { + return badDistance; + } + trsf.SetTransformation( tgtCS ); + + // move all the nodes to 2D + vector xy( xyz.size() ); + for ( size_t i = 0;i < xyz.size()-1; ++i ) + { + gp_XYZ p3d = xyz[i]; + trsf.Transforms( p3d ); + xy[i].SetCoord( p3d.X(), p3d.Z() ); + } + xyz.back() = xyz.front(); + xy.back() = xy.front(); + + // // move the point in 2D + gp_XYZ tmpPnt = point.XYZ(); + trsf.Transforms( tmpPnt ); + gp_XY point2D( tmpPnt.X(), tmpPnt.Z() ); + + // loop on segments of the face to analyze point position ralative to the face + set< PointPos > pntPosSet; + for ( size_t i = 1; i < xy.size(); ++i ) + { + PointPos pos = getPointPosition( point2D, &xy[0], i-1 ); + pntPosSet.insert( pos ); + } + + // compute distance + PointPos pos = *pntPosSet.begin(); + // cout << "Face " << face->GetID() << " DIST: "; + switch ( pos._name ) + { + case POS_LEFT: { + // point is most close to a segment + gp_Vec p0p1( point, xyz[ pos._index ] ); + gp_Vec p1p2( xyz[ pos._index ], xyz[ pos._index+1 ]); // segment vector + p1p2.Normalize(); + double projDist = p0p1 * p1p2; // distance projected to the segment + gp_Vec projVec = p1p2 * projDist; + gp_Vec distVec = p0p1 - projVec; + // cout << distVec.Magnitude() << ", SEG " << face->GetNode(pos._index)->GetID() + // << " - " << face->GetNodeWrap(pos._index+1)->GetID() << endl; + return distVec.Magnitude(); + } + case POS_RIGHT: { + // point is inside the face + double distToFacePlane = tmpPnt.Y(); + // cout << distToFacePlane << ", INSIDE " << endl; + return Abs( distToFacePlane ); + } + case POS_VERTEX: { + // point is most close to a node + gp_Vec distVec( point, xyz[ pos._index ]); + // cout << distVec.Magnitude() << " VERTEX " << face->GetNode(pos._index)->GetID() << endl; + return distVec.Magnitude(); + } + } + return badDistance; +} + +//======================================================================= +//function : SimplifyFace +//purpose : +//======================================================================= +int SMESH_MeshEditor::SimplifyFace (const vector faceNodes, + vector& poly_nodes, + vector& quantities) const +{ + int nbNodes = faceNodes.size(); + + if (nbNodes < 3) + return 0; + + set nodeSet; + + // get simple seq of nodes + //const SMDS_MeshNode* simpleNodes[ nbNodes ]; + vector simpleNodes( nbNodes ); + int iSimple = 0, nbUnique = 0; + + simpleNodes[iSimple++] = faceNodes[0]; + nbUnique++; + for (int iCur = 1; iCur < nbNodes; iCur++) { + if (faceNodes[iCur] != simpleNodes[iSimple - 1]) { + simpleNodes[iSimple++] = faceNodes[iCur]; + if (nodeSet.insert( faceNodes[iCur] ).second) + nbUnique++; + } + } + int nbSimple = iSimple; + if (simpleNodes[nbSimple - 1] == simpleNodes[0]) { + nbSimple--; + iSimple--; + } + + if (nbUnique < 3) + return 0; + + // separate loops + int nbNew = 0; + bool foundLoop = (nbSimple > nbUnique); + while (foundLoop) { + foundLoop = false; + set loopSet; + for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) { + const SMDS_MeshNode* n = simpleNodes[iSimple]; + if (!loopSet.insert( n ).second) { + foundLoop = true; + + // separate loop + int iC = 0, curLast = iSimple; + for (; iC < curLast; iC++) { + if (simpleNodes[iC] == n) break; + } + int loopLen = curLast - iC; + if (loopLen > 2) { + // create sub-element + nbNew++; + quantities.push_back(loopLen); + for (; iC < curLast; iC++) { + poly_nodes.push_back(simpleNodes[iC]); + } + } + // shift the rest nodes (place from the first loop position) + for (iC = curLast + 1; iC < nbSimple; iC++) { + simpleNodes[iC - loopLen] = simpleNodes[iC]; + } + nbSimple -= loopLen; + iSimple -= loopLen; + } + } // for (iSimple = 0; iSimple < nbSimple; iSimple++) + } // while (foundLoop) + + if (iSimple > 2) { + nbNew++; + quantities.push_back(iSimple); + for (int i = 0; i < iSimple; i++) + poly_nodes.push_back(simpleNodes[i]); + } + + return nbNew; +} + +//======================================================================= +//function : MergeNodes +//purpose : In each group, the cdr of nodes are substituted by the first one +// in all elements. +//======================================================================= + +void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) +{ + MESSAGE("MergeNodes"); + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + + SMESHDS_Mesh* aMesh = GetMeshDS(); + + TNodeNodeMap nodeNodeMap; // node to replace - new node + set elems; // all elements with changed nodes + list< int > rmElemIds, rmNodeIds; + + // Fill nodeNodeMap and elems + + TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin(); + for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) { + list& nodes = *grIt; + list::iterator nIt = nodes.begin(); + const SMDS_MeshNode* nToKeep = *nIt; + //MESSAGE("node to keep " << nToKeep->GetID()); + for ( ++nIt; nIt != nodes.end(); nIt++ ) { + const SMDS_MeshNode* nToRemove = *nIt; + nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep )); + if ( nToRemove != nToKeep ) { + //MESSAGE(" node to remove " << nToRemove->GetID()); + rmNodeIds.push_back( nToRemove->GetID() ); + AddToSameGroups( nToKeep, nToRemove, aMesh ); + } + + SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); + while ( invElemIt->more() ) { + const SMDS_MeshElement* elem = invElemIt->next(); + elems.insert(elem); + } + } + } + // Change element nodes or remove an element + + set::iterator eIt = elems.begin(); + for ( ; eIt != elems.end(); eIt++ ) { + const SMDS_MeshElement* elem = *eIt; + //MESSAGE(" ---- inverse elem on node to remove " << elem->GetID()); + int nbNodes = elem->NbNodes(); + int aShapeId = FindShape( elem ); + + set nodeSet; + vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes ); + int iUnique = 0, iCur = 0, nbRepl = 0; + vector iRepl( nbNodes ); + + // get new seq of nodes + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) { + const SMDS_MeshNode* n = + static_cast( itN->next() ); + + TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n ); + if ( nnIt != nodeNodeMap.end() ) { // n sticks + n = (*nnIt).second; + // BUG 0020185: begin + { + bool stopRecur = false; + set nodesRecur; + nodesRecur.insert(n); + while (!stopRecur) { + TNodeNodeMap::iterator nnIt_i = nodeNodeMap.find( n ); + if ( nnIt_i != nodeNodeMap.end() ) { // n sticks + n = (*nnIt_i).second; + if (!nodesRecur.insert(n).second) { + // error: recursive dependancy + stopRecur = true; + } + } + else + stopRecur = true; + } + } + // BUG 0020185: end } curNodes[ iCur ] = n; bool isUnique = nodeSet.insert( n ).second; if ( isUnique ) uniqueNodes[ iUnique++ ] = n; + else + iRepl[ nbRepl++ ] = iCur; iCur++; } @@ -4859,6 +7565,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) bool isOk = true; int nbUniqueNodes = nodeSet.size(); + //MESSAGE("nbNodes nbUniqueNodes " << nbNodes << " " << nbUniqueNodes); if ( nbNodes != nbUniqueNodes ) { // some nodes stick // Polygons and Polyhedral volumes if (elem->IsPoly()) { @@ -4874,10 +7581,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) vector polygons_nodes; vector quantities; int nbNew = SimplifyFace(face_nodes, polygons_nodes, quantities); - if (nbNew > 0) { inode = 0; - for (int iface = 0; iface < nbNew - 1; iface++) { + for (int iface = 0; iface < nbNew; iface++) { int nbNodes = quantities[iface]; vector poly_nodes (nbNodes); for (int ii = 0; ii < nbNodes; ii++, inode++) { @@ -4888,7 +7594,19 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) if (aShapeId) aMesh->SetMeshElementOnShape(newElem, aShapeId); } - aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]); + + MESSAGE("ChangeElementNodes MergeNodes Polygon"); + //aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]); + vector polynodes(polygons_nodes.begin()+inode,polygons_nodes.end()); + int quid =0; + if (nbNew > 0) quid = nbNew - 1; + vector newquant(quantities.begin()+quid, quantities.end()); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddPolyhedralVolume(polynodes, newquant); + myLastCreatedElems.Append(newElem); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + rmElemIds.push_back(elem->GetID()); } else { rmElemIds.push_back(elem->GetID()); @@ -4901,9 +7619,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) rmElemIds.push_back(elem->GetID()); } else { - // each face has to be analized in order to check volume validity - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - static_cast( elem ); + // each face has to be analyzed in order to check volume validity + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( elem ); if (aPolyedre) { int nbFaces = aPolyedre->NbFaces(); @@ -4931,10 +7649,16 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } if (quantities.size() > 3) - aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); - else - rmElemIds.push_back(elem->GetID()); - + { + MESSAGE("ChangeElementNodes MergeNodes Polyhedron"); + //aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); + const SMDS_MeshElement* newElem = 0; + newElem = aMesh->AddPolyhedralVolume(poly_nodes, quantities); + myLastCreatedElems.Append(newElem); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + rmElemIds.push_back(elem->GetID()); + } } else { rmElemIds.push_back(elem->GetID()); @@ -4945,9 +7669,10 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } continue; - } + } // poly element // Regular elements + // TODO not all the possible cases are solved. Find something more generic? switch ( nbNodes ) { case 2: ///////////////////////////////////// EDGE isOk = false; break; @@ -4961,6 +7686,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) isOk = false; else if ( nbRepl == 2 && iRepl[ 1 ] - iRepl[ 0 ] == 2 ) isOk = false; // opposite nodes stick + //MESSAGE("isOk " << isOk); } break; case 6: ///////////////////////////////////// PENTAHEDRON @@ -5025,7 +7751,11 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // +---+---+ // 0 7 3 isOk = false; + if(nbRepl==2) { + MESSAGE("nbRepl=2: " << iRepl[0] << " " << iRepl[1]); + } if(nbRepl==3) { + MESSAGE("nbRepl=3: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2]); nbUniqueNodes = 6; if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) { uniqueNodes[0] = curNodes[0]; @@ -5100,14 +7830,20 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) isOk = true; } } + if(nbRepl==4) { + MESSAGE("nbRepl=4: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3]); + } + if(nbRepl==5) { + MESSAGE("nbRepl=5: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3] << " " << iRepl[4]); + } break; } //////////////////////////////////// HEXAHEDRON isOk = false; SMDS_VolumeTool hexa (elem); hexa.SetExternalNormal(); - if ( nbUniqueNodes == 4 && nbRepl == 6 ) { - //////////////////////// ---> tetrahedron + if ( nbUniqueNodes == 4 && nbRepl == 4 ) { + //////////////////////// HEX ---> 1 tetrahedron for ( int iFace = 0; iFace < 6; iFace++ ) { const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] && @@ -5117,12 +7853,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) int iOppFace = hexa.GetOppFaceIndex( iFace ); ind = hexa.GetFaceNodesIndices( iOppFace ); int nbStick = 0; - iUnique = 2; // reverse a tetrahedron bottom for ( iCur = 0; iCur < 4 && nbStick < 2; iCur++ ) { if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] ) nbStick++; - else if ( iUnique >= 0 ) - uniqueNodes[ iUnique-- ] = curNodes[ind[ iCur ]]; } if ( nbStick == 1 ) { // ... and the opposite one - into a triangle. @@ -5135,6 +7868,45 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } } } + else if ( nbUniqueNodes == 6 && nbRepl == 2 ) { + //////////////////////// HEX ---> 1 prism + int nbTria = 0, iTria[3]; + const int *ind; // indices of face nodes + // look for triangular faces + for ( int iFace = 0; iFace < 6 && nbTria < 3; iFace++ ) { + ind = hexa.GetFaceNodesIndices( iFace ); + TIDSortedNodeSet faceNodes; + for ( iCur = 0; iCur < 4; iCur++ ) + faceNodes.insert( curNodes[ind[iCur]] ); + if ( faceNodes.size() == 3 ) + iTria[ nbTria++ ] = iFace; + } + // check if triangles are opposite + if ( nbTria == 2 && iTria[0] == hexa.GetOppFaceIndex( iTria[1] )) + { + isOk = true; + // set nodes of the bottom triangle + ind = hexa.GetFaceNodesIndices( iTria[ 0 ]); + vector indB; + for ( iCur = 0; iCur < 4; iCur++ ) + if ( ind[iCur] != iRepl[0] && ind[iCur] != iRepl[1]) + indB.push_back( ind[iCur] ); + if ( !hexa.IsForward() ) + std::swap( indB[0], indB[2] ); + for ( iCur = 0; iCur < 3; iCur++ ) + uniqueNodes[ iCur ] = curNodes[indB[iCur]]; + // set nodes of the top triangle + const int *indT = hexa.GetFaceNodesIndices( iTria[ 1 ]); + for ( iCur = 0; iCur < 3; ++iCur ) + for ( int j = 0; j < 4; ++j ) + if ( hexa.IsLinked( indB[ iCur ], indT[ j ] )) + { + uniqueNodes[ iCur + 3 ] = curNodes[ indT[ j ]]; + break; + } + } + break; + } else if (nbUniqueNodes == 5 && nbRepl == 4 ) { //////////////////// HEXAHEDRON ---> 2 tetrahedrons for ( int iFace = 0; iFace < 6; iFace++ ) { @@ -5272,6 +8044,10 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } } } // if ( nbUniqueNodes == 6 && nbRepl == 4 ) + else + { + MESSAGE("MergeNodes() removes hexahedron "<< elem); + } break; } // HEXAHEDRON @@ -5281,11 +8057,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } // if ( nbNodes != nbUniqueNodes ) // some nodes stick - if ( isOk ) { - if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) { + if ( isOk ) { // the elem remains valid after sticking nodes + if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) + { // Change nodes of polyedre - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - static_cast( elem ); + const SMDS_VtkVolume* aPolyedre = + dynamic_cast( elem ); if (aPolyedre) { int nbFaces = aPolyedre->NbFaces(); @@ -5309,9 +8086,21 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities ); } } - else { - // Change regular element or polygon - aMesh->ChangeElementNodes( elem, & uniqueNodes[0], nbUniqueNodes ); + else // replace non-polyhedron elements + { + const SMDSAbs_ElementType etyp = elem->GetType(); + const int elemId = elem->GetID(); + const bool isPoly = (elem->GetEntityType() == SMDSEntity_Polygon); + uniqueNodes.resize(nbUniqueNodes); + + SMESHDS_SubMesh * sm = aShapeId > 0 ? aMesh->MeshElements(aShapeId) : 0; + + aMesh->RemoveFreeElement(elem, sm, /*fromGroups=*/false); + SMDS_MeshElement* newElem = this->AddElement(uniqueNodes, etyp, isPoly, elemId); + if ( sm && newElem ) + sm->AddElement( newElem ); + if ( elem != newElem ) + ReplaceElemInGroups( elem, newElem, aMesh ); } } else { @@ -5321,10 +8110,10 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } // loop on elements - // Remove equal nodes and bad elements + // Remove bad elements, then equal nodes (order important) - Remove( rmNodeIds, true ); Remove( rmElemIds, false ); + Remove( rmNodeIds, true ); } @@ -5335,24 +8124,24 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) // ======================================================== class SortableElement : public set { - public: +public: SortableElement( const SMDS_MeshElement* theElem ) - { - myElem = theElem; - SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); - while ( nodeIt->more() ) - this->insert( nodeIt->next() ); - } + { + myElem = theElem; + SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); + while ( nodeIt->more() ) + this->insert( nodeIt->next() ); + } const SMDS_MeshElement* Get() const - { return myElem; } + { return myElem; } void Set(const SMDS_MeshElement* e) const - { myElem = e; } + { myElem = e; } - private: +private: mutable const SMDS_MeshElement* myElem; }; @@ -5362,7 +8151,7 @@ class SortableElement : public set // Search among theElements or in the whole mesh if theElements is empty //======================================================================= void SMESH_MeshEditor::FindEqualElements(set & theElements, - TListOfListOfElementsID & theGroupsOfElementsID) + TListOfListOfElementsID & theGroupsOfElementsID) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -5460,7 +8249,7 @@ void SMESH_MeshEditor::MergeElements(TListOfListOfElementsID & theGroupsOfElemen void SMESH_MeshEditor::MergeEqualElements() { set aMeshElements; /* empty input - - to merge equal elements in the whole mesh */ + to merge equal elements in the whole mesh */ TListOfListOfElementsID aGroupsOfElementsID; FindEqualElements(aMeshElements, aGroupsOfElementsID); MergeElements(aGroupsOfElementsID); @@ -5471,83 +8260,68 @@ void SMESH_MeshEditor::MergeEqualElements() //purpose : Return a face having linked nodes n1 and n2 and which is // - not in avoidSet, // - in elemSet provided that !elemSet.empty() +// i1 and i2 optionally returns indices of n1 and n2 //======================================================================= const SMDS_MeshElement* - SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const TIDSortedElemSet& elemSet, - const TIDSortedElemSet& avoidSet) +SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const TIDSortedElemSet& elemSet, + const TIDSortedElemSet& avoidSet, + int* n1ind, + int* n2ind) { + int i1, i2; + const SMDS_MeshElement* face = 0; + SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face); - while ( invElemIt->more() ) { // loop on inverse elements of n1 + //MESSAGE("n1->GetInverseElementIterator(SMDSAbs_Face) " << invElemIt); + while ( invElemIt->more() && !face ) // loop on inverse faces of n1 + { + //MESSAGE("in while ( invElemIt->more() && !face )"); const SMDS_MeshElement* elem = invElemIt->next(); - if (avoidSet.find( elem ) != avoidSet.end() ) + if (avoidSet.count( elem )) continue; - if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end()) + if ( !elemSet.empty() && !elemSet.count( elem )) continue; - // get face nodes and find index of n1 - int i1, nbN = elem->NbNodes(), iNode = 0; - //const SMDS_MeshNode* faceNodes[ nbN ], *n; - vector faceNodes( nbN ); - const SMDS_MeshNode* n; - SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); - while ( nIt->more() ) { - faceNodes[ iNode ] = static_cast( nIt->next() ); - if ( faceNodes[ iNode++ ] == n1 ) - i1 = iNode - 1; - } + // index of n1 + i1 = elem->GetNodeIndex( n1 ); // find a n2 linked to n1 - if(!elem->IsQuadratic()) { - for ( iNode = 0; iNode < 2; iNode++ ) { - if ( iNode ) // node before n1 - n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; - else // node after n1 - n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; - if ( n == n2 ) - return elem; - } - } - else { // analysis for quadratic elements - bool IsFind = false; - // check using only corner nodes - for ( iNode = 0; iNode < 2; iNode++ ) { - if ( iNode ) // node before n1 - n = faceNodes[ i1 == 0 ? nbN/2 - 1 : i1 - 1 ]; - else // node after n1 - n = faceNodes[ i1 + 1 == nbN/2 ? 0 : i1 + 1 ]; - if ( n == n2 ) - IsFind = true; - } - if(IsFind) { - return elem; - } - else { - // check using all nodes - const SMDS_QuadraticFaceOfNodes* F = - static_cast(elem); - // use special nodes iterator - iNode = 0; - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); - while ( anIter->more() ) { - faceNodes[iNode] = static_cast(anIter->next()); - if ( faceNodes[ iNode++ ] == n1 ) - i1 = iNode - 1; - } - for ( iNode = 0; iNode < 2; iNode++ ) { - if ( iNode ) // node before n1 - n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ]; - else // node after n1 - n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ]; - if ( n == n2 ) { - return elem; - } + int nbN = elem->IsQuadratic() ? elem->NbNodes()/2 : elem->NbNodes(); + for ( int di = -1; di < 2 && !face; di += 2 ) + { + i2 = (i1+di+nbN) % nbN; + if ( elem->GetNode( i2 ) == n2 ) + face = elem; + } + if ( !face && elem->IsQuadratic()) + { + // analysis for quadratic elements using all nodes + const SMDS_VtkFace* F = + dynamic_cast(elem); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); + // use special nodes iterator + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); + const SMDS_MeshNode* prevN = cast2Node( anIter->next() ); + for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ ) + { + const SMDS_MeshNode* n = cast2Node( anIter->next() ); + if ( n1 == prevN && n2 == n ) + { + face = elem; + } + else if ( n2 == prevN && n1 == n ) + { + face = elem; swap( i1, i2 ); } + prevN = n; } - } // end analysis for quadratic elements + } } - return 0; + if ( n1ind ) *n1ind = i1; + if ( n2ind ) *n2ind = i2; + return face; } //======================================================================= @@ -5591,7 +8365,7 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst //vector nodes; const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode; - set < const SMDS_MeshElement* > foundElems; + TIDSortedElemSet foundElems; bool needTheLast = ( theLastNode != 0 ); while ( nStart != theLastNode ) { @@ -5610,14 +8384,15 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst int iNode = 0, nbNodes = e->NbNodes(); //const SMDS_MeshNode* nodes[nbNodes+1]; vector nodes(nbNodes+1); - + if(e->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(e); + const SMDS_VtkFace* F = + dynamic_cast(e); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() ) { - nodes[ iNode++ ] = anIter->next(); + nodes[ iNode++ ] = cast2Node(anIter->next()); } } else { @@ -5730,15 +8505,15 @@ bool SMESH_MeshEditor::CheckFreeBorderNodes(const SMDS_MeshNode* theNode1, //======================================================================= SMESH_MeshEditor::Sew_Error - SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, - const SMDS_MeshNode* theBordSecondNode, - const SMDS_MeshNode* theBordLastNode, - const SMDS_MeshNode* theSideFirstNode, - const SMDS_MeshNode* theSideSecondNode, - const SMDS_MeshNode* theSideThirdNode, - const bool theSideIsFreeBorder, - const bool toCreatePolygons, - const bool toCreatePolyedrs) +SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode, + const SMDS_MeshNode* theBordSecondNode, + const SMDS_MeshNode* theBordLastNode, + const SMDS_MeshNode* theSideFirstNode, + const SMDS_MeshNode* theSideSecondNode, + const SMDS_MeshNode* theSideThirdNode, + const bool theSideIsFreeBorder, + const bool toCreatePolygons, + const bool toCreatePolyedrs) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -5787,7 +8562,7 @@ SMESH_MeshEditor::Sew_Error // links of the free border // ------------------------------------------------------------------------- - // 1. Since sewing may brake if there are volumes to split on the side 2, + // 1. Since sewing may break if there are volumes to split on the side 2, // we wont move nodes but just compute new coordinates for them typedef map TNodeXYZMap; TNodeXYZMap nBordXYZ; @@ -5885,12 +8660,13 @@ SMESH_MeshEditor::Sew_Error else if ( elem->GetType()==SMDSAbs_Face ) { // --face // retrieve all face nodes and find iPrevNode - an index of the prevSideNode if(elem->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(elem); + const SMDS_VtkFace* F = + dynamic_cast(elem); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() ) { - nodes[ iNode ] = anIter->next(); + nodes[ iNode ] = cast2Node(anIter->next()); if ( nodes[ iNode++ ] == prevSideNode ) iPrevNode = iNode - 1; } @@ -5992,7 +8768,7 @@ SMESH_MeshEditor::Sew_Error TListOfListOfNodes nodeGroupsToMerge; if ( nbNodes[0] == nbNodes[1] || - ( theSideIsFreeBorder && !theSideThirdNode)) { + ( theSideIsFreeBorder && !theSideThirdNode)) { // all nodes are to be merged @@ -6204,12 +8980,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, vector nodes( theFace->NbNodes() ); if(theFace->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(theFace); + const SMDS_VtkFace* F = + dynamic_cast(theFace); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() ) { - const SMDS_MeshNode* n = anIter->next(); + const SMDS_MeshNode* n = cast2Node(anIter->next()); if ( n == theBetweenNode1 ) il1 = iNode; else if ( n == theBetweenNode2 ) @@ -6265,12 +9042,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, bool isFLN = false; if(theFace->IsQuadratic()) { - const SMDS_QuadraticFaceOfNodes* F = - static_cast(theFace); + const SMDS_VtkFace* F = + dynamic_cast(theFace); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); + SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator(); while( anIter->more() && !isFLN ) { - const SMDS_MeshNode* n = anIter->next(); + const SMDS_MeshNode* n = cast2Node(anIter->next()); poly_nodes[iNode++] = n; if (n == nodes[il1]) { isFLN = true; @@ -6283,7 +9061,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, } // add nodes of face starting from last node of link while ( anIter->more() ) { - poly_nodes[iNode++] = anIter->next(); + poly_nodes[iNode++] = cast2Node(anIter->next()); } } else { @@ -6326,6 +9104,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, return; } + SMESHDS_Mesh *aMesh = GetMeshDS(); if( !theFace->IsQuadratic() ) { // put aNodesToInsert between theBetweenNode1 and theBetweenNode2 @@ -6376,7 +9155,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, } // create new elements - SMESHDS_Mesh *aMesh = GetMeshDS(); int aShapeId = FindShape( theFace ); i1 = 0; i2 = 1; @@ -6402,8 +9180,16 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, newNodes[ 1 ] = linkNodes[ i2 ]; newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ]; newNodes[ 3 ] = nodes[ i4 ]; - aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); - } // end if(!theFace->IsQuadratic()) + //aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); + const SMDS_MeshElement* newElem = 0; + if (iSplit == iBestQuad) + newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] ); + else + newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] ); + myLastCreatedElems.Append(newElem); + if ( aShapeId && newElem ) + aMesh->SetMeshElementOnShape( newElem, aShapeId ); +} // end if(!theFace->IsQuadratic()) else { // theFace is quadratic // we have to split theFace on simple triangles and one simple quadrangle int tmp = il1/2; @@ -6430,7 +9216,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, // n4 n6 n5 n4 // create new elements - SMESHDS_Mesh *aMesh = GetMeshDS(); int aShapeId = FindShape( theFace ); int n1,n2,n3; @@ -6513,9 +9298,9 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); } - // remove old quadratic face - aMesh->RemoveElement(theFace); } + // remove old face + aMesh->RemoveElement(theFace); } //======================================================================= @@ -6604,10 +9389,34 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode } } +namespace +{ + //================================================================================ + /*! + * \brief Transform any volume into data of SMDSEntity_Polyhedra + */ + //================================================================================ + + void volumeToPolyhedron( const SMDS_MeshElement* elem, + vector & nodes, + vector & nbNodeInFaces ) + { + nodes.clear(); + nbNodeInFaces.clear(); + SMDS_VolumeTool vTool ( elem ); + for ( int iF = 0; iF < vTool.NbFaces(); ++iF ) + { + const SMDS_MeshNode** fNodes = vTool.GetFaceNodes( iF ); + nodes.insert( nodes.end(), fNodes, fNodes + vTool.NbFaceNodes( iF )); + nbNodeInFaces.push_back( vTool.NbFaceNodes( iF )); + } + } +} + //======================================================================= /*! * \brief Convert elements contained in a submesh to quadratic - * \retval int - nb of checked elements + * \return int - nb of checked elements */ //======================================================================= @@ -6618,7 +9427,8 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, int nbElem = 0; if( !theSm ) return nbElem; - const bool notFromGroups = false; + vector nbNodeInFaces; + vector nodes; SMDS_ElemIteratorPtr ElemItr = theSm->GetElements(); while(ElemItr->more()) { @@ -6626,61 +9436,69 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, const SMDS_MeshElement* elem = ElemItr->next(); if( !elem || elem->IsQuadratic() ) continue; - int id = elem->GetID(); - int nbNodes = elem->NbNodes(); - vector aNds (nbNodes); - - for(int i = 0; i < nbNodes; i++) - { - aNds[i] = elem->GetNode(i); - } - SMDSAbs_ElementType aType = elem->GetType(); - - GetMeshDS()->RemoveFreeElement(elem, theSm, notFromGroups); + // get elem data needed to re-create it + // + const int id = elem->GetID(); + const int nbNodes = elem->NbNodes(); + const SMDSAbs_ElementType aType = elem->GetType(); + const SMDSAbs_EntityType aGeomType = elem->GetEntityType(); + nodes.assign(elem->begin_nodes(), elem->end_nodes()); + if ( aGeomType == SMDSEntity_Polyhedra ) + nbNodeInFaces = static_cast( elem )->GetQuantities(); + else if ( aGeomType == SMDSEntity_Hexagonal_Prism ) + volumeToPolyhedron( elem, nodes, nbNodeInFaces ); + + // remove a linear element + GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false); const SMDS_MeshElement* NewElem = 0; switch( aType ) { case SMDSAbs_Edge : - { - NewElem = theHelper.AddEdge(aNds[0], aNds[1], id, theForce3d); - break; - } + { + NewElem = theHelper.AddEdge(nodes[0], nodes[1], id, theForce3d); + break; + } case SMDSAbs_Face : - { - switch(nbNodes) { - case 3: - 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); - break; - default: - continue; + switch(nbNodes) + { + case 3: + NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d); + break; + case 4: + NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); + break; + default: + NewElem = theHelper.AddPolygonalFace(nodes, id, theForce3d); + continue; + } + break; } - break; - } case SMDSAbs_Volume : - { - switch(nbNodes) { - case 4: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d); - break; - case 6: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, theForce3d); - break; - case 8: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], - aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d); - break; - default: - continue; + switch( aGeomType ) + { + case SMDSEntity_Tetra: + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); + break; + case SMDSEntity_Pyramid: + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d); + break; + case SMDSEntity_Penta: + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d); + break; + case SMDSEntity_Hexa: + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); + break; + case SMDSEntity_Hexagonal_Prism: + default: + NewElem = theHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d); + } + break; } - break; - } default : continue; } @@ -6695,13 +9513,13 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, //function : ConvertToQuadratic //purpose : //======================================================================= + void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) { SMESHDS_Mesh* meshDS = GetMeshDS(); SMESH_MesherHelper aHelper(*myMesh); aHelper.SetIsQuadratic( true ); - const bool notFromGroups = false; int nbCheckedElems = 0; if ( myMesh->HasShapeToMesh() ) @@ -6728,11 +9546,12 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) const SMDS_MeshEdge* edge = aEdgeItr->next(); if(edge && !edge->IsQuadratic()) { - int id = edge->GetID(); - const SMDS_MeshNode* n1 = edge->GetNode(0); - const SMDS_MeshNode* n2 = edge->GetNode(1); + int id = edge->GetID(); + //MESSAGE("edge->GetID() " << id); + const SMDS_MeshNode* n1 = edge->GetNode(0); + const SMDS_MeshNode* n2 = edge->GetNode(1); - meshDS->RemoveFreeElement(edge, smDS, notFromGroups); + meshDS->RemoveFreeElement(edge, smDS, /*fromGroups=*/false); const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d); ReplaceElemInGroups( edge, NewEdge, GetMeshDS()); @@ -6744,75 +9563,220 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) const SMDS_MeshFace* face = aFaceItr->next(); if(!face || face->IsQuadratic() ) continue; - int id = face->GetID(); - int nbNodes = face->NbNodes(); - vector aNds (nbNodes); + const int id = face->GetID(); + const SMDSAbs_EntityType type = face->GetEntityType(); + vector nodes ( face->begin_nodes(), face->end_nodes()); + + meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false); + + SMDS_MeshFace * NewFace = 0; + switch( type ) + { + case SMDSEntity_Triangle: + NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d); + break; + case SMDSEntity_Quadrangle: + NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); + break; + default: + NewFace = aHelper.AddPolygonalFace(nodes, id, theForce3d); + } + ReplaceElemInGroups( face, NewFace, GetMeshDS()); + } + vector nbNodeInFaces; + SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator(); + while(aVolumeItr->more()) + { + const SMDS_MeshVolume* volume = aVolumeItr->next(); + if(!volume || volume->IsQuadratic() ) continue; + + const int id = volume->GetID(); + const SMDSAbs_EntityType type = volume->GetEntityType(); + vector nodes (volume->begin_nodes(), volume->end_nodes()); + if ( type == SMDSEntity_Polyhedra ) + nbNodeInFaces = static_cast(volume)->GetQuantities(); + else if ( type == SMDSEntity_Hexagonal_Prism ) + volumeToPolyhedron( volume, nodes, nbNodeInFaces ); + + meshDS->RemoveFreeElement(volume, smDS, /*fromGroups=*/false); + + SMDS_MeshVolume * NewVolume = 0; + switch ( type ) + { + case SMDSEntity_Tetra: + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d ); + break; + case SMDSEntity_Hexa: + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); + break; + case SMDSEntity_Pyramid: + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], + nodes[3], nodes[4], id, theForce3d); + break; + case SMDSEntity_Penta: + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], + nodes[3], nodes[4], nodes[5], id, theForce3d); + break; + case SMDSEntity_Hexagonal_Prism: + default: + NewVolume = aHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d); + } + ReplaceElemInGroups(volume, NewVolume, meshDS); + } + } + + if ( !theForce3d ) + { // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion + aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh + aHelper.FixQuadraticElements(); + } +} + +//================================================================================ +/*! + * \brief Makes given elements quadratic + * \param theForce3d - if true, the medium nodes will be placed in the middle of link + * \param theElements - elements to make quadratic + */ +//================================================================================ - for(int i = 0; i < nbNodes; i++) +void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, + TIDSortedElemSet& theElements) +{ + if ( theElements.empty() ) return; + + // we believe that all theElements are of the same type + const SMDSAbs_ElementType elemType = (*theElements.begin())->GetType(); + + // get all nodes shared by theElements + TIDSortedNodeSet allNodes; + TIDSortedElemSet::iterator eIt = theElements.begin(); + for ( ; eIt != theElements.end(); ++eIt ) + allNodes.insert( (*eIt)->begin_nodes(), (*eIt)->end_nodes() ); + + // complete theElements with elements of lower dim whose all nodes are in allNodes + + TIDSortedElemSet quadAdjacentElems [ SMDSAbs_NbElementTypes ]; // quadratic adjacent elements + TIDSortedElemSet checkedAdjacentElems [ SMDSAbs_NbElementTypes ]; + TIDSortedNodeSet::iterator nIt = allNodes.begin(); + for ( ; nIt != allNodes.end(); ++nIt ) + { + const SMDS_MeshNode* n = *nIt; + SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(); + while ( invIt->more() ) + { + const SMDS_MeshElement* e = invIt->next(); + if ( e->IsQuadratic() ) { - aNds[i] = face->GetNode(i); + quadAdjacentElems[ e->GetType() ].insert( e ); + continue; } - - meshDS->RemoveFreeElement(face, smDS, notFromGroups); - - SMDS_MeshFace * NewFace = 0; - switch(nbNodes) + if ( e->GetType() >= elemType ) { - case 3: - 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); - break; - default: - continue; + continue; // same type of more complex linear element } - ReplaceElemInGroups( face, NewFace, GetMeshDS()); + + if ( !checkedAdjacentElems[ e->GetType() ].insert( e ).second ) + continue; // e is already checked + + // check nodes + bool allIn = true; + SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); + while ( nodeIt->more() && allIn ) + allIn = allNodes.count( cast2Node( nodeIt->next() )); + if ( allIn ) + theElements.insert(e ); } - SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator(); - while(aVolumeItr->more()) + } + + SMESH_MesherHelper helper(*myMesh); + helper.SetIsQuadratic( true ); + + // add links of quadratic adjacent elements to the helper + + if ( !quadAdjacentElems[SMDSAbs_Edge].empty() ) + for ( eIt = quadAdjacentElems[SMDSAbs_Edge].begin(); + eIt != quadAdjacentElems[SMDSAbs_Edge].end(); ++eIt ) { - const SMDS_MeshVolume* volume = aVolumeItr->next(); - if(!volume || volume->IsQuadratic() ) continue; + helper.AddTLinks( static_cast< const SMDS_MeshEdge*> (*eIt) ); + } + if ( !quadAdjacentElems[SMDSAbs_Face].empty() ) + for ( eIt = quadAdjacentElems[SMDSAbs_Face].begin(); + eIt != quadAdjacentElems[SMDSAbs_Face].end(); ++eIt ) + { + helper.AddTLinks( static_cast< const SMDS_MeshFace*> (*eIt) ); + } + if ( !quadAdjacentElems[SMDSAbs_Volume].empty() ) + for ( eIt = quadAdjacentElems[SMDSAbs_Volume].begin(); + eIt != quadAdjacentElems[SMDSAbs_Volume].end(); ++eIt ) + { + helper.AddTLinks( static_cast< const SMDS_MeshVolume*> (*eIt) ); + } - int id = volume->GetID(); - int nbNodes = volume->NbNodes(); - vector aNds (nbNodes); + // make quadratic elements instead of linear ones - for(int i = 0; i < nbNodes; i++) - { - aNds[i] = volume->GetNode(i); - } + SMESHDS_Mesh* meshDS = GetMeshDS(); + SMESHDS_SubMesh* smDS = 0; + for ( eIt = theElements.begin(); eIt != theElements.end(); ++eIt ) + { + const SMDS_MeshElement* elem = *eIt; + if( elem->IsQuadratic() || elem->NbNodes() < 2 || elem->IsPoly() ) + continue; - meshDS->RemoveFreeElement(volume, smDS, notFromGroups); + const int id = elem->GetID(); + const SMDSAbs_ElementType type = elem->GetType(); + vector nodes ( elem->begin_nodes(), elem->end_nodes()); - SMDS_MeshVolume * NewVolume = 0; - switch(nbNodes) - { - case 4: - NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], - aNds[3], id, theForce3d ); - break; - case 6: - NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], - aNds[3], aNds[4], aNds[5], id, theForce3d); - break; - case 8: - NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], - aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d); - break; - default: - continue; - } - ReplaceElemInGroups(volume, NewVolume, meshDS); + if ( !smDS || !smDS->Contains( elem )) + smDS = meshDS->MeshElements( elem->getshapeId() ); + meshDS->RemoveFreeElement(elem, smDS, /*fromGroups=*/false); + + SMDS_MeshElement * newElem = 0; + switch( nodes.size() ) + { + case 4: // cases for most frequently used element types go first (for optimization) + if ( type == SMDSAbs_Volume ) + newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); + else + newElem = helper.AddFace (nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); + break; + case 8: + newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); + break; + case 3: + newElem = helper.AddFace (nodes[0], nodes[1], nodes[2], id, theForce3d); + break; + case 2: + newElem = helper.AddEdge(nodes[0], nodes[1], id, theForce3d); + break; + case 5: + newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], id, theForce3d); + break; + case 6: + newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], id, theForce3d); + break; + default:; } + ReplaceElemInGroups( elem, newElem, meshDS); + if( newElem && smDS ) + smDS->AddElement( newElem ); + } + + if ( !theForce3d && !getenv("NO_FixQuadraticElements")) + { // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion + helper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh + helper.FixQuadraticElements(); } } //======================================================================= /*! * \brief Convert quadratic elements to linear ones and remove quadratic nodes - * \retval int - nb of checked elements + * \return int - nb of checked elements */ //======================================================================= @@ -6822,7 +9786,6 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, { int nbElem = 0; SMESHDS_Mesh* meshDS = GetMeshDS(); - const bool notFromGroups = false; while( theItr->more() ) { @@ -6830,44 +9793,28 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, nbElem++; if( elem && elem->IsQuadratic()) { - int id = elem->GetID(); - int nbNodes = elem->NbNodes(); - vector 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 ) ) - mediumNodes.push_back( n ); - else - aNds.push_back( n ); - } - if( aNds.empty() ) continue; + int id = elem->GetID(); + int nbCornerNodes = elem->NbCornerNodes(); SMDSAbs_ElementType aType = elem->GetType(); - //remove old quadratic element - meshDS->RemoveFreeElement( elem, theSm, notFromGroups ); + vector nodes( elem->begin_nodes(), elem->end_nodes() ); - SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id ); - ReplaceElemInGroups(elem, NewElem, meshDS); - if( theSm && NewElem ) - theSm->AddElement( NewElem ); + //remove a quadratic element + if ( !theSm || !theSm->Contains( elem )) + theSm = meshDS->MeshElements( elem->getshapeId() ); + meshDS->RemoveFreeElement( elem, theSm, /*fromGroups=*/false ); // remove medium nodes - vector::iterator nIt = mediumNodes.begin(); - for ( ; nIt != mediumNodes.end(); ++nIt ) { - const SMDS_MeshNode* n = *nIt; - if ( n->NbInverseElements() == 0 ) { - if ( n->GetPosition()->GetShapeId() != theShapeID ) - meshDS->RemoveFreeNode( n, meshDS->MeshElements - ( n->GetPosition()->GetShapeId() )); - else - meshDS->RemoveFreeNode( n, theSm ); - } - } + for ( unsigned i = nbCornerNodes; i < nodes.size(); ++i ) + if ( nodes[i]->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode( nodes[i], theSm ); + + // add a linear element + nodes.resize( nbCornerNodes ); + SMDS_MeshElement * newElem = AddElement( nodes, aType, false, id ); + ReplaceElemInGroups(elem, newElem, meshDS); + if( theSm && newElem ) + theSm->AddElement( newElem ); } } return nbElem; @@ -6877,7 +9824,8 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, //function : ConvertFromQuadratic //purpose : //======================================================================= -bool SMESH_MeshEditor::ConvertFromQuadratic() + +bool SMESH_MeshEditor::ConvertFromQuadratic() { int nbCheckedElems = 0; if ( myMesh->HasShapeToMesh() ) @@ -6892,7 +9840,7 @@ bool SMESH_MeshEditor::ConvertFromQuadratic() } } } - + int totalNbElems = GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes(); if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes @@ -6904,18 +9852,114 @@ bool SMESH_MeshEditor::ConvertFromQuadratic() return true; } +namespace +{ + //================================================================================ + /*! + * \brief Return true if all medium nodes of the element are in the node set + */ + //================================================================================ + + bool allMediumNodesIn(const SMDS_MeshElement* elem, TIDSortedNodeSet& nodeSet ) + { + for ( int i = elem->NbCornerNodes(); i < elem->NbNodes(); ++i ) + if ( !nodeSet.count( elem->GetNode(i) )) + return false; + return true; + } +} + +//================================================================================ +/*! + * \brief Makes given elements linear + */ +//================================================================================ + +void SMESH_MeshEditor::ConvertFromQuadratic(TIDSortedElemSet& theElements) +{ + if ( theElements.empty() ) return; + + // collect IDs of medium nodes of theElements; some of these nodes will be removed + set mediumNodeIDs; + TIDSortedElemSet::iterator eIt = theElements.begin(); + for ( ; eIt != theElements.end(); ++eIt ) + { + const SMDS_MeshElement* e = *eIt; + for ( int i = e->NbCornerNodes(); i < e->NbNodes(); ++i ) + mediumNodeIDs.insert( e->GetNode(i)->GetID() ); + } + + // replace given elements by linear ones + typedef SMDS_SetIterator TSetIterator; + SMDS_ElemIteratorPtr elemIt( new TSetIterator( theElements.begin(), theElements.end() )); + removeQuadElem( /*theSm=*/0, elemIt, /*theShapeID=*/0 ); + + // we need to convert remaining elements whose all medium nodes are in mediumNodeIDs + // except those elements sharing medium nodes of quadratic element whose medium nodes + // are not all in mediumNodeIDs + + // get remaining medium nodes + TIDSortedNodeSet mediumNodes; + set::iterator nIdsIt = mediumNodeIDs.begin(); + for ( ; nIdsIt != mediumNodeIDs.end(); ++nIdsIt ) + if ( const SMDS_MeshNode* n = GetMeshDS()->FindNode( *nIdsIt )) + mediumNodes.insert( mediumNodes.end(), n ); + + // find more quadratic elements to convert + TIDSortedElemSet moreElemsToConvert; + TIDSortedNodeSet::iterator nIt = mediumNodes.begin(); + for ( ; nIt != mediumNodes.end(); ++nIt ) + { + SMDS_ElemIteratorPtr invIt = (*nIt)->GetInverseElementIterator(); + while ( invIt->more() ) + { + const SMDS_MeshElement* e = invIt->next(); + if ( e->IsQuadratic() && allMediumNodesIn( e, mediumNodes )) + { + // find a more complex element including e and + // whose medium nodes are not in mediumNodes + bool complexFound = false; + for ( int type = e->GetType() + 1; type < SMDSAbs_0DElement; ++type ) + { + SMDS_ElemIteratorPtr invIt2 = + (*nIt)->GetInverseElementIterator( SMDSAbs_ElementType( type )); + while ( invIt2->more() ) + { + const SMDS_MeshElement* eComplex = invIt2->next(); + if ( eComplex->IsQuadratic() && !allMediumNodesIn( eComplex, mediumNodes)) + { + int nbCommonNodes = SMESH_Algo::GetCommonNodes( e, eComplex ).size(); + if ( nbCommonNodes == e->NbNodes()) + { + complexFound = true; + type = SMDSAbs_NbElementTypes; // to quit from the outer loop + break; + } + } + } + } + if ( !complexFound ) + moreElemsToConvert.insert( e ); + } + } + } + elemIt = SMDS_ElemIteratorPtr + (new TSetIterator( moreElemsToConvert.begin(), moreElemsToConvert.end() )); + removeQuadElem( /*theSm=*/0, elemIt, /*theShapeID=*/0 ); +} + //======================================================================= //function : SewSideElements //purpose : //======================================================================= SMESH_MeshEditor::Sew_Error - SMESH_MeshEditor::SewSideElements (TIDSortedElemSet& theSide1, - TIDSortedElemSet& 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(); @@ -6934,25 +9978,27 @@ SMESH_MeshEditor::Sew_Error // 1. Build set of faces representing each side: // ======================================================================= // a. build set of nodes belonging to faces - // b. complete set of faces: find missing fices whose nodes are in set of nodes + // b. complete set of faces: find missing faces whose nodes are in set of nodes // c. create temporary faces representing side of volumes if correspondent // face does not exist SMESHDS_Mesh* aMesh = GetMeshDS(); - SMDS_Mesh aTmpFacesMesh; - set faceSet1, faceSet2; + // TODO algoritm not OK with vtkUnstructuredGrid: 2 meshes can't share nodes + //SMDS_Mesh aTmpFacesMesh; // try to use the same mesh + TIDSortedElemSet faceSet1, faceSet2; set volSet1, volSet2; set nodeSet1, nodeSet2; - set * faceSetPtr[] = { &faceSet1, &faceSet2 }; - set * volSetPtr[] = { &volSet1, &volSet2 }; + TIDSortedElemSet * faceSetPtr[] = { &faceSet1, &faceSet2 }; + set * volSetPtr[] = { &volSet1, &volSet2 }; set * nodeSetPtr[] = { &nodeSet1, &nodeSet2 }; - TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 }; + TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 }; int iSide, iFace, iNode; + list tempFaceList; for ( iSide = 0; iSide < 2; iSide++ ) { set * nodeSet = nodeSetPtr[ iSide ]; - TIDSortedElemSet * elemSet = elemSetPtr[ iSide ]; - set * faceSet = faceSetPtr[ iSide ]; + TIDSortedElemSet * elemSet = elemSetPtr[ iSide ]; + TIDSortedElemSet * faceSet = faceSetPtr[ iSide ]; set * volSet = volSetPtr [ iSide ]; set::iterator vIt; TIDSortedElemSet::iterator eIt; @@ -6976,7 +10022,7 @@ SMESH_MeshEditor::Sew_Error // ----------------------------------------------------------- // 1a. Collect nodes of existing faces // and build set of face nodes in order to detect missing - // faces corresponing to sides of volumes + // faces corresponding to sides of volumes // ----------------------------------------------------------- set< set > setOfFaceNodeSet; @@ -7000,7 +10046,7 @@ SMESH_MeshEditor::Sew_Error volSet->insert( elem ); } // ------------------------------------------------------------------------------ - // 1b. Complete set of faces: find missing fices whose nodes are in set of nodes + // 1b. Complete set of faces: find missing faces whose nodes are in set of nodes // ------------------------------------------------------------------------------ for ( nIt = nodeSet->begin(); nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide @@ -7054,40 +10100,38 @@ SMESH_MeshEditor::Sew_Error bool isNewFace = setOfFaceNodeSet.insert( faceNodeSet ).second; if ( isNewFace ) { // no such a face is given but it still can exist, check it - if ( nbNodes == 3 ) { - aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] ); - } - else if ( nbNodes == 4 ) { - aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); - } - else { - vector poly_nodes ( fNodes, & fNodes[nbNodes]); - aFreeFace = aMesh->FindFace(poly_nodes); - } + vector nodes ( fNodes, fNodes + nbNodes); + aFreeFace = aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false ); } if ( !aFreeFace ) { // create a temporary face if ( nbNodes == 3 ) { - aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] ); + //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] ); + aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2] ); } else if ( nbNodes == 4 ) { - aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); + //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); + aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] ); } else { vector poly_nodes ( fNodes, & fNodes[nbNodes]); - aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes); + //aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes); + aFreeFace = aMesh->AddPolygonalFace(poly_nodes); } + if ( aFreeFace ) + tempFaceList.push_back( aFreeFace ); } + if ( aFreeFace ) freeFaceList.push_back( aFreeFace ); } // loop on faces of a volume - // choose one of several free faces - // -------------------------------------- + // choose one of several free faces of a volume + // -------------------------------------------- if ( freeFaceList.size() > 1 ) { // choose a face having max nb of nodes shared by other elems of a side - int maxNbNodes = -1/*, nbExcludedFaces = 0*/; + int maxNbNodes = -1; list::iterator fIt = freeFaceList.begin(); while ( fIt != freeFaceList.end() ) { // loop on free faces int nbSharedNodes = 0; @@ -7098,18 +10142,20 @@ SMESH_MeshEditor::Sew_Error SMDS_ElemIteratorPtr invElemIt = n->GetInverseElementIterator(); while ( invElemIt->more() ) { const SMDS_MeshElement* e = invElemIt->next(); - if ( faceSet->find( e ) != faceSet->end() ) - nbSharedNodes++; - if ( elemSet->find( e ) != elemSet->end() ) - nbSharedNodes++; + nbSharedNodes += faceSet->count( e ); + nbSharedNodes += elemSet->count( e ); } } - if ( nbSharedNodes >= maxNbNodes ) { + if ( nbSharedNodes > maxNbNodes ) { maxNbNodes = nbSharedNodes; + freeFaceList.erase( freeFaceList.begin(), fIt++ ); + } + else if ( nbSharedNodes == maxNbNodes ) { fIt++; } - else - freeFaceList.erase( fIt++ ); // here fIt++ occures before erase + else { + freeFaceList.erase( fIt++ ); // here fIt++ occurs before erase + } } if ( freeFaceList.size() > 1 ) { @@ -7154,48 +10200,51 @@ SMESH_MeshEditor::Sew_Error const SMDS_MeshElement* aFreeFace = freeFaceList.front(); faceSet->insert( aFreeFace ); // complete a node set with nodes of a found free face -// for ( iNode = 0; iNode < ; iNode++ ) -// nodeSet->insert( fNodes[ iNode ] ); + // for ( iNode = 0; iNode < ; iNode++ ) + // nodeSet->insert( fNodes[ iNode ] ); } } // loop on volumes of a side -// // complete a set of faces if new nodes in a nodeSet appeared -// // ---------------------------------------------------------- -// if ( nodeSetSize != nodeSet->size() ) { -// for ( ; nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide -// 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() ) { -// // check if all nodes are in nodeSet and -// // complete setOfFaceNodeSet if they are -// set faceNodeSet; -// SMDS_ElemIteratorPtr nodeIt = f->nodesIterator(); -// bool allInSet = true; -// while ( nodeIt->more() && allInSet ) { // loop on nodes of a face -// const SMDS_MeshNode* n = static_cast( nodeIt->next() ); -// if ( nodeSet->find( n ) == nodeSet->end() ) -// allInSet = false; -// else -// faceNodeSet.insert( n ); -// } -// if ( allInSet ) { -// faceSet->insert( f ); -// setOfFaceNodeSet.insert( faceNodeSet ); -// } -// } -// } -// } -// } + // // complete a set of faces if new nodes in a nodeSet appeared + // // ---------------------------------------------------------- + // if ( nodeSetSize != nodeSet->size() ) { + // for ( ; nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide + // 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() ) { + // // check if all nodes are in nodeSet and + // // complete setOfFaceNodeSet if they are + // set faceNodeSet; + // SMDS_ElemIteratorPtr nodeIt = f->nodesIterator(); + // bool allInSet = true; + // while ( nodeIt->more() && allInSet ) { // loop on nodes of a face + // const SMDS_MeshNode* n = static_cast( nodeIt->next() ); + // if ( nodeSet->find( n ) == nodeSet->end() ) + // allInSet = false; + // else + // faceNodeSet.insert( n ); + // } + // if ( allInSet ) { + // faceSet->insert( f ); + // setOfFaceNodeSet.insert( faceNodeSet ); + // } + // } + // } + // } + // } } // Create temporary faces, if there are volumes given } // loop on sides if ( faceSet1.size() != faceSet2.size() ) { // delete temporary faces: they are in reverseElements of actual nodes - SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); - while ( tmpFaceIt->more() ) - aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); +// SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); +// while ( tmpFaceIt->more() ) +// aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); +// list::iterator tmpFaceIt = tempFaceList.begin(); +// for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt) +// aMesh->RemoveElement(*tmpFaceIt); MESSAGE("Diff nb of faces"); return SEW_TOPO_DIFF_SETS_OF_ELEMENTS; } @@ -7205,27 +10254,254 @@ SMESH_MeshEditor::Sew_Error // bind a node to remove to a node to put instead // ============================================================ - TNodeNodeMap nReplaceMap; // bind a node to remove to a node to put instead + TNodeNodeMap nReplaceMap; // bind a node to remove to a node to put instead + if ( theFirstNode1 != theFirstNode2 ) + nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 )); + if ( theSecondNode1 != theSecondNode2 ) + nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 )); + + LinkID_Gen aLinkID_Gen( GetMeshDS() ); + set< long > linkIdSet; // links to process + linkIdSet.insert( aLinkID_Gen.GetLinkID( theFirstNode1, theSecondNode1 )); + + typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink; + list< NLink > linkList[2]; + linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 )); + linkList[1].push_back( NLink( theFirstNode2, theSecondNode2 )); + // loop on links in linkList; find faces by links and append links + // of the found faces to linkList + list< NLink >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ; + for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) + { + NLink link[] = { *linkIt[0], *linkIt[1] }; + long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second ); + if ( !linkIdSet.count( linkID ) ) + continue; + + // by links, find faces in the face sets, + // and find indices of link nodes in the found faces; + // in a face set, there is only one or no face sharing a link + // --------------------------------------------------------------- + + const SMDS_MeshElement* face[] = { 0, 0 }; + vector fnodes[2]; + int iLinkNode[2][2]; + TIDSortedElemSet avoidSet; + for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides + const SMDS_MeshNode* n1 = link[iSide].first; + const SMDS_MeshNode* n2 = link[iSide].second; + //cout << "Side " << iSide << " "; + //cout << "L( " << n1->GetID() << ", " << n2->GetID() << " ) " << endl; + // find a face by two link nodes + face[ iSide ] = FindFaceInSet( n1, n2, *faceSetPtr[ iSide ], avoidSet, + &iLinkNode[iSide][0], &iLinkNode[iSide][1] ); + if ( face[ iSide ]) + { + //cout << " F " << face[ iSide]->GetID() <erase( face[ iSide ]); + // put face nodes to fnodes + if ( face[ iSide ]->IsQuadratic() ) + { + // use interlaced nodes iterator + const SMDS_VtkFace* F = dynamic_cast( face[ iSide ]); + if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace")); + SMDS_ElemIteratorPtr nIter = F->interlacedNodesElemIterator(); + while ( nIter->more() ) + fnodes[ iSide ].push_back( cast2Node( nIter->next() )); + } + else + { + fnodes[ iSide ].assign( face[ iSide ]->begin_nodes(), + face[ iSide ]->end_nodes() ); + } + fnodes[ iSide ].push_back( fnodes[ iSide ].front()); + } + } + + // check similarity of elements of the sides + if (aResult == SEW_OK && (( face[0] && !face[1] ) || ( !face[0] && face[1] ))) { + MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 )); + if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found + aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); + } + else { + aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + } + break; // do not return because it's necessary to remove tmp faces + } + + // set nodes to merge + // ------------------- + + if ( face[0] && face[1] ) { + const int nbNodes = face[0]->NbNodes(); + if ( nbNodes != face[1]->NbNodes() ) { + MESSAGE("Diff nb of face nodes"); + aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + break; // do not return because it s necessary to remove tmp faces + } + bool reverse[] = { false, false }; // order of nodes in the link + for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides + // analyse link orientation in faces + int i1 = iLinkNode[ iSide ][ 0 ]; + int i2 = iLinkNode[ iSide ][ 1 ]; + reverse[ iSide ] = Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1; + } + int di1 = reverse[0] ? -1 : +1, i1 = iLinkNode[0][1] + di1; + int di2 = reverse[1] ? -1 : +1, i2 = iLinkNode[1][1] + di2; + for ( int i = nbNodes - 2; i > 0; --i, i1 += di1, i2 += di2 ) + { + nReplaceMap.insert ( make_pair ( fnodes[0][ ( i1 + nbNodes ) % nbNodes ], + fnodes[1][ ( i2 + nbNodes ) % nbNodes ])); + } + + // add other links of the faces to linkList + // ----------------------------------------- + + for ( iNode = 0; iNode < nbNodes; iNode++ ) { + linkID = aLinkID_Gen.GetLinkID( fnodes[0][iNode], fnodes[0][iNode+1] ); + pair< set::iterator, bool > iter_isnew = linkIdSet.insert( linkID ); + if ( !iter_isnew.second ) { // already in a set: no need to process + linkIdSet.erase( iter_isnew.first ); + } + else // new in set == encountered for the first time: add + { + const SMDS_MeshNode* n1 = fnodes[0][ iNode ]; + const SMDS_MeshNode* n2 = fnodes[0][ iNode + 1]; + linkList[0].push_back ( NLink( n1, n2 )); + linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] )); + } + } + } // 2 faces found + + if ( faceSetPtr[0]->empty() || faceSetPtr[1]->empty() ) + break; + + } // loop on link lists + + if ( aResult == SEW_OK && + ( //linkIt[0] != linkList[0].end() || + !faceSetPtr[0]->empty() || !faceSetPtr[1]->empty() )) { + MESSAGE( (linkIt[0] != linkList[0].end()) <<" "<< (faceSetPtr[0]->empty()) << + " " << (faceSetPtr[1]->empty())); + aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + } + + // ==================================================================== + // 3. Replace nodes in elements of the side 1 and remove replaced nodes + // ==================================================================== + + // delete temporary faces +// SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); +// while ( tmpFaceIt->more() ) +// aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); + list::iterator tmpFaceIt = tempFaceList.begin(); + for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt) + aMesh->RemoveElement(*tmpFaceIt); + + if ( aResult != SEW_OK) + return aResult; + + list< int > nodeIDsToRemove/*, elemIDsToRemove*/; + // loop on nodes replacement map + TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt; + for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ ) + if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) { + const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first; + nodeIDsToRemove.push_back( nToRemove->GetID() ); + // loop on elements sharing nToRemove + SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); + while ( invElemIt->more() ) { + const SMDS_MeshElement* e = invElemIt->next(); + // get a new suite of nodes: make replacement + int nbReplaced = 0, i = 0, nbNodes = e->NbNodes(); + vector< const SMDS_MeshNode*> nodes( nbNodes ); + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + while ( nIt->more() ) { + const SMDS_MeshNode* n = + static_cast( nIt->next() ); + nnIt = nReplaceMap.find( n ); + if ( nnIt != nReplaceMap.end() ) { + nbReplaced++; + n = (*nnIt).second; + } + nodes[ i++ ] = n; + } + // if ( nbReplaced == nbNodes && e->GetType() == SMDSAbs_Face ) + // elemIDsToRemove.push_back( e->GetID() ); + // else + if ( nbReplaced ) + { + SMDSAbs_ElementType etyp = e->GetType(); + SMDS_MeshElement* newElem = this->AddElement(nodes, etyp, false); + if (newElem) + { + myLastCreatedElems.Append(newElem); + AddToSameGroups(newElem, e, aMesh); + int aShapeId = e->getshapeId(); + if ( aShapeId ) + { + aMesh->SetMeshElementOnShape( newElem, aShapeId ); + } + } + aMesh->RemoveElement(e); + } + } + } + + Remove( nodeIDsToRemove, true ); + + return aResult; +} + +//================================================================================ +/*! + * \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 + * \param theFirstNode2 - a node of set 2 corresponding to theFirstNode1 + * \param theSecondNode1 - a boundary node of set 1 linked with theFirstNode1 + * \param theSecondNode2 - a node of set 2 corresponding to theSecondNode1 + * \param nReplaceMap - output map of corresponding nodes + * \return bool - is a success or not + */ +//================================================================================ + +#ifdef _DEBUG_ +//#define DEBUG_MATCHING_NODES +#endif + +SMESH_MeshEditor::Sew_Error +SMESH_MeshEditor::FindMatchingNodes(set& theSide1, + set& theSide2, + const SMDS_MeshNode* theFirstNode1, + const SMDS_MeshNode* theFirstNode2, + const SMDS_MeshNode* theSecondNode1, + const SMDS_MeshNode* theSecondNode2, + TNodeNodeMap & nReplaceMap) +{ + set * faceSetPtr[] = { &theSide1, &theSide2 }; + + nReplaceMap.clear(); if ( theFirstNode1 != theFirstNode2 ) - nReplaceMap.insert( TNodeNodeMap::value_type( theFirstNode1, theFirstNode2 )); + nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 )); if ( theSecondNode1 != theSecondNode2 ) - nReplaceMap.insert( TNodeNodeMap::value_type( theSecondNode1, theSecondNode2 )); + nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 )); - LinkID_Gen aLinkID_Gen( GetMeshDS() ); - set< long > linkIdSet; // links to process - linkIdSet.insert( aLinkID_Gen.GetLinkID( theFirstNode1, theSecondNode1 )); + set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored + linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 )); - typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink; list< NLink > linkList[2]; linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 )); linkList[1].push_back( NLink( theFirstNode2, theSecondNode2 )); + // loop on links in linkList; find faces by links and append links // of the found faces to linkList list< NLink >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ; for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) { NLink link[] = { *linkIt[0], *linkIt[1] }; - long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second ); - if ( linkIdSet.find( linkID ) == linkIdSet.end() ) + if ( linkSet.find( link[0] ) == linkSet.end() ) continue; // by links, find faces in the face sets, @@ -7234,525 +10510,1467 @@ SMESH_MeshEditor::Sew_Error // --------------------------------------------------------------- const SMDS_MeshElement* face[] = { 0, 0 }; - //const SMDS_MeshNode* faceNodes[ 2 ][ 5 ]; - vector fnodes1(9); - vector fnodes2(9); - //const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ; - vector notLinkNodes1(6); - vector notLinkNodes2(6); - int iLinkNode[2][2]; - for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides + list notLinkNodes[2]; + //bool reverse[] = { false, false }; // order of notLinkNodes + int nbNodes[2]; + for ( int iSide = 0; iSide < 2; iSide++ ) // loop on 2 sides + { const SMDS_MeshNode* n1 = link[iSide].first; const SMDS_MeshNode* n2 = link[iSide].second; set * faceSet = faceSetPtr[ iSide ]; - 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 + set< const SMDS_MeshElement* > facesOfNode1; + for ( int iNode = 0; iNode < 2; iNode++ ) // loop on 2 nodes of a link + { + // 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(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 - ! fMap.insert( f ).second ) // f encounters twice + ! facesOfNode1.insert( f ).second ) // f encounters twice { if ( face[ iSide ] ) { MESSAGE( "2 faces per link " ); - aResult = iSide ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES; - break; + return ( iSide ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); } face[ iSide ] = f; faceSet->erase( f ); - // get face nodes and find ones of a link - iNode = 0; - int nbl = -1; - if(f->IsPoly()) { - if(iSide==0) { - fnodes1.resize(f->NbNodes()+1); - notLinkNodes1.resize(f->NbNodes()-2); - } - else { - fnodes2.resize(f->NbNodes()+1); - notLinkNodes2.resize(f->NbNodes()-2); - } - } - if(!f->IsQuadratic()) { - SMDS_ElemIteratorPtr nIt = f->nodesIterator(); - while ( nIt->more() ) { - const SMDS_MeshNode* n = - static_cast( nIt->next() ); - if ( n == n1 ) { - iLinkNode[ iSide ][ 0 ] = iNode; - } - else if ( n == n2 ) { - iLinkNode[ iSide ][ 1 ] = iNode; - } - //else if ( notLinkNodes[ iSide ][ 0 ] ) - // notLinkNodes[ iSide ][ 1 ] = n; - //else - // notLinkNodes[ iSide ][ 0 ] = n; - else { - nbl++; - if(iSide==0) - notLinkNodes1[nbl] = n; - //notLinkNodes1.push_back(n); - else - notLinkNodes2[nbl] = n; - //notLinkNodes2.push_back(n); - } - //faceNodes[ iSide ][ iNode++ ] = n; - if(iSide==0) { - fnodes1[iNode++] = n; - } - else { - fnodes2[iNode++] = n; - } - } - } - else { // f->IsQuadratic() - const SMDS_QuadraticFaceOfNodes* F = - static_cast(f); - // use special nodes iterator - SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator(); - while ( anIter->more() ) { - const SMDS_MeshNode* n = - static_cast( anIter->next() ); - if ( n == n1 ) { - iLinkNode[ iSide ][ 0 ] = iNode; - } - else if ( n == n2 ) { - iLinkNode[ iSide ][ 1 ] = iNode; - } - else { - nbl++; - if(iSide==0) { - notLinkNodes1[nbl] = n; - } - else { - notLinkNodes2[nbl] = n; - } - } - if(iSide==0) { - fnodes1[iNode++] = n; - } - else { - fnodes2[iNode++] = n; - } - } - } - //faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ]; - if(iSide==0) { - fnodes1[iNode] = fnodes1[0]; + + // get not link nodes + int nbN = f->NbNodes(); + if ( f->IsQuadratic() ) + nbN /= 2; + nbNodes[ iSide ] = nbN; + list< const SMDS_MeshNode* > & nodes = notLinkNodes[ iSide ]; + int i1 = f->GetNodeIndex( n1 ); + int i2 = f->GetNodeIndex( n2 ); + int iEnd = nbN, iBeg = -1, iDelta = 1; + bool reverse = ( Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1 ); + if ( reverse ) { + std::swap( iEnd, iBeg ); iDelta = -1; } - else { - fnodes2[iNode] = fnodes1[0]; + int i = i2; + while ( true ) { + i += iDelta; + if ( i == iEnd ) i = iBeg + iDelta; + if ( i == i1 ) break; + nodes.push_back ( f->GetNode( i ) ); } } } } } + // check similarity of elements of the sides + if (( face[0] && !face[1] ) || ( !face[0] && face[1] )) { + MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 )); + if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found + return ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); + } + else { + return SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + } + } + + // set nodes to merge + // ------------------- + + if ( face[0] && face[1] ) { + if ( nbNodes[0] != nbNodes[1] ) { + MESSAGE("Diff nb of face nodes"); + return SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + } +#ifdef DEBUG_MATCHING_NODES + MESSAGE ( " Link 1: " << link[0].first->GetID() <<" "<< link[0].second->GetID() + << " F 1: " << face[0] << "| Link 2: " << link[1].first->GetID() <<" " + << link[1].second->GetID() << " F 2: " << face[1] << " | Bind: " ) ; +#endif + int nbN = nbNodes[0]; + { + list::iterator n1 = notLinkNodes[0].begin(); + list::iterator n2 = notLinkNodes[1].begin(); + for ( int i = 0 ; i < nbN - 2; ++i ) { +#ifdef DEBUG_MATCHING_NODES + MESSAGE ( (*n1)->GetID() << " to " << (*n2)->GetID() ); +#endif + nReplaceMap.insert( make_pair( *(n1++), *(n2++) )); + } + } + + // add other links of the face 1 to linkList + // ----------------------------------------- + + const SMDS_MeshElement* f0 = face[0]; + const SMDS_MeshNode* n1 = f0->GetNode( nbN - 1 ); + for ( int i = 0; i < nbN; i++ ) + { + const SMDS_MeshNode* n2 = f0->GetNode( i ); + pair< set< SMESH_TLink >::iterator, bool > iter_isnew = + linkSet.insert( SMESH_TLink( n1, n2 )); + if ( !iter_isnew.second ) { // already in a set: no need to process + linkSet.erase( iter_isnew.first ); + } + else // new in set == encountered for the first time: add + { +#ifdef DEBUG_MATCHING_NODES + MESSAGE ( "Add link 1: " << n1->GetID() << " " << n2->GetID() << " " + << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " ); +#endif + linkList[0].push_back ( NLink( n1, n2 )); + linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] )); + } + n1 = n2; + } + } // 2 faces found + } // loop on link lists + + return SEW_OK; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - the list of elements (edges or faces) to be replicated + The nodes for duplication could be found from these elements + \param theNodesNot - list of nodes to NOT replicate + \param theAffectedElems - the list of elements (cells and edges) to which the + replicated nodes should be associated to. + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ +//================================================================================ + +bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TIDSortedElemSet& theAffectedElems ) +{ + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + + if ( theElems.size() == 0 ) + return false; + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + if ( !aMeshDS ) + return false; + + bool res = false; + std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode; + // duplicate elements and nodes + res = doubleNodes( aMeshDS, theElems, theNodesNot, anOldNodeToNewNode, true ); + // replce nodes by duplications + res = doubleNodes( aMeshDS, theAffectedElems, theNodesNot, anOldNodeToNewNode, false ); + return res; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theMeshDS - mesh instance + \param theElems - the elements replicated or modified (nodes should be changed) + \param theNodesNot - nodes to NOT replicate + \param theNodeNodeMap - relation of old node to new created node + \param theIsDoubleElem - flag os to replicate element or modify + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ +//================================================================================ + +bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS, + const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + std::map< const SMDS_MeshNode*, + const SMDS_MeshNode* >& theNodeNodeMap, + const bool theIsDoubleElem ) +{ + MESSAGE("doubleNodes"); + // iterate on through element and duplicate them (by nodes duplication) + bool res = false; + TIDSortedElemSet::const_iterator elemItr = theElems.begin(); + for ( ; elemItr != theElems.end(); ++elemItr ) + { + const SMDS_MeshElement* anElem = *elemItr; + if (!anElem) + continue; + + bool isDuplicate = false; + // duplicate nodes to duplicate element + std::vector newNodes( anElem->NbNodes() ); + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + int ind = 0; + while ( anIter->more() ) + { + + SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next(); + SMDS_MeshNode* aNewNode = aCurrNode; + if ( theNodeNodeMap.find( aCurrNode ) != theNodeNodeMap.end() ) + aNewNode = (SMDS_MeshNode*)theNodeNodeMap[ aCurrNode ]; + else if ( theIsDoubleElem && theNodesNot.find( aCurrNode ) == theNodesNot.end() ) + { + // duplicate node + aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() ); + theNodeNodeMap[ aCurrNode ] = aNewNode; + myLastCreatedNodes.Append( aNewNode ); + } + isDuplicate |= (aCurrNode != aNewNode); + newNodes[ ind++ ] = aNewNode; + } + if ( !isDuplicate ) + continue; + + if ( theIsDoubleElem ) + AddElement(newNodes, anElem->GetType(), anElem->IsPoly()); + else + { + MESSAGE("ChangeElementNodes"); + theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() ); + } + res = true; + } + return res; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theNodes - identifiers of nodes to be doubled + \param theModifiedElems - identifiers of elements to be updated by the new (doubled) + nodes. If list of element identifiers is empty then nodes are doubled but + they not assigned to elements + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ +//================================================================================ + +bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, + const std::list< int >& theListOfModifiedElems ) +{ + MESSAGE("DoubleNodes"); + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + + if ( theListOfNodes.size() == 0 ) + return false; + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + if ( !aMeshDS ) + return false; + + // iterate through nodes and duplicate them + + std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode; + + std::list< int >::const_iterator aNodeIter; + for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter ) + { + int aCurr = *aNodeIter; + SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr ); + if ( !aNode ) + continue; + + // duplicate node + + const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() ); + if ( aNewNode ) + { + anOldNodeToNewNode[ aNode ] = aNewNode; + myLastCreatedNodes.Append( aNewNode ); + } + } + + // Create map of new nodes for modified elements + + std::map< SMDS_MeshElement*, vector > anElemToNodes; + + std::list< int >::const_iterator anElemIter; + for ( anElemIter = theListOfModifiedElems.begin(); + anElemIter != theListOfModifiedElems.end(); ++anElemIter ) + { + int aCurr = *anElemIter; + SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr ); + if ( !anElem ) + continue; - // check similarity of elements of the sides - if (aResult == SEW_OK && ( face[0] && !face[1] ) || ( !face[0] && face[1] )) { - MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 )); - if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found - aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); - } - else { - aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + vector aNodeArr( anElem->NbNodes() ); + + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + int ind = 0; + while ( anIter->more() ) + { + SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next(); + if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() ) + { + const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ]; + aNodeArr[ ind++ ] = aNewNode; } - break; // do not return because it s necessary to remove tmp faces + else + aNodeArr[ ind++ ] = aCurrNode; } + anElemToNodes[ anElem ] = aNodeArr; + } - // set nodes to merge - // ------------------- + // Change nodes of elements - if ( face[0] && face[1] ) { - int nbNodes = face[0]->NbNodes(); - if ( nbNodes != face[1]->NbNodes() ) { - MESSAGE("Diff nb of face nodes"); - aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; - break; // do not return because it s necessary to remove tmp faces - } - bool reverse[] = { false, false }; // order of notLinkNodes of quadrangle - if ( nbNodes == 3 ) { - //nReplaceMap.insert( TNodeNodeMap::value_type - // ( notLinkNodes[0][0], notLinkNodes[1][0] )); - nReplaceMap.insert( TNodeNodeMap::value_type - ( notLinkNodes1[0], notLinkNodes2[0] )); - } - else { - for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides - // analyse link orientation in faces - int i1 = iLinkNode[ iSide ][ 0 ]; - int i2 = iLinkNode[ iSide ][ 1 ]; - reverse[ iSide ] = Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1; - // if notLinkNodes are the first and the last ones, then - // their order does not correspond to the link orientation - if (( i1 == 1 && i2 == 2 ) || - ( i1 == 2 && i2 == 1 )) - reverse[ iSide ] = !reverse[ iSide ]; - } - if ( reverse[0] == reverse[1] ) { - //nReplaceMap.insert( TNodeNodeMap::value_type - // ( notLinkNodes[0][0], notLinkNodes[1][0] )); - //nReplaceMap.insert( TNodeNodeMap::value_type - // ( notLinkNodes[0][1], notLinkNodes[1][1] )); - for(int nn=0; nn >::iterator + anElemToNodesIter = anElemToNodes.begin(); + for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter ) + { + const SMDS_MeshElement* anElem = anElemToNodesIter->first; + vector aNodeArr = anElemToNodesIter->second; + if ( anElem ) + { + MESSAGE("ChangeElementNodes"); + aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() ); } + } - // add other links of the faces to linkList - // ----------------------------------------- + return true; +} - //const SMDS_MeshNode** nodes = faceNodes[ 0 ]; - for ( iNode = 0; iNode < nbNodes; iNode++ ) { - //linkID = aLinkID_Gen.GetLinkID( nodes[iNode], nodes[iNode+1] ); - linkID = aLinkID_Gen.GetLinkID( fnodes1[iNode], fnodes1[iNode+1] ); - pair< set::iterator, bool > iter_isnew = linkIdSet.insert( linkID ); - if ( !iter_isnew.second ) { // already in a set: no need to process - linkIdSet.erase( iter_isnew.first ); - } - else // new in set == encountered for the first time: add - { - //const SMDS_MeshNode* n1 = nodes[ iNode ]; - //const SMDS_MeshNode* n2 = nodes[ iNode + 1]; - const SMDS_MeshNode* n1 = fnodes1[ iNode ]; - const SMDS_MeshNode* n2 = fnodes1[ iNode + 1]; - linkList[0].push_back ( NLink( n1, n2 )); - linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] )); - } - } - } // 2 faces found - } // loop on link lists +namespace { - if ( aResult == SEW_OK && - ( linkIt[0] != linkList[0].end() || - !faceSetPtr[0]->empty() || !faceSetPtr[1]->empty() )) { - MESSAGE( (linkIt[0] != linkList[0].end()) <<" "<< (faceSetPtr[0]->empty()) << - " " << (faceSetPtr[1]->empty())); - aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS; + //================================================================================ + /*! + \brief Check if element located inside shape + \return TRUE if IN or ON shape, FALSE otherwise + */ + //================================================================================ + + template + bool isInside(const SMDS_MeshElement* theElem, + Classifier& theClassifier, + const double theTol) + { + gp_XYZ centerXYZ (0, 0, 0); + SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator(); + while (aNodeItr->more()) + centerXYZ += SMESH_TNodeXYZ(cast2Node( aNodeItr->next())); + + gp_Pnt aPnt = centerXYZ / theElem->NbNodes(); + theClassifier.Perform(aPnt, theTol); + TopAbs_State aState = theClassifier.State(); + return (aState == TopAbs_IN || aState == TopAbs_ON ); } - // ==================================================================== - // 3. Replace nodes in elements of the side 1 and remove replaced nodes - // ==================================================================== - - // delete temporary faces: they are in reverseElements of actual nodes - SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator(); - while ( tmpFaceIt->more() ) - aTmpFacesMesh.RemoveElement( tmpFaceIt->next() ); + //================================================================================ + /*! + * \brief Classifier of the 3D point on the TopoDS_Face + * with interaface suitable for isInside() + */ + //================================================================================ - if ( aResult != SEW_OK) - return aResult; + struct _FaceClassifier + { + Extrema_ExtPS _extremum; + BRepAdaptor_Surface _surface; + TopAbs_State _state; - list< int > nodeIDsToRemove/*, elemIDsToRemove*/; - // loop on nodes replacement map - TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt; - for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ ) - if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) { - const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first; - nodeIDsToRemove.push_back( nToRemove->GetID() ); - // loop on elements sharing nToRemove - SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); - while ( invElemIt->more() ) { - const SMDS_MeshElement* e = invElemIt->next(); - // get a new suite of nodes: make replacement - int nbReplaced = 0, i = 0, nbNodes = e->NbNodes(); - vector< const SMDS_MeshNode*> nodes( nbNodes ); - SMDS_ElemIteratorPtr nIt = e->nodesIterator(); - while ( nIt->more() ) { - const SMDS_MeshNode* n = - static_cast( nIt->next() ); - nnIt = nReplaceMap.find( n ); - if ( nnIt != nReplaceMap.end() ) { - nbReplaced++; - n = (*nnIt).second; - } - nodes[ i++ ] = n; - } - // if ( nbReplaced == nbNodes && e->GetType() == SMDSAbs_Face ) - // elemIDsToRemove.push_back( e->GetID() ); - // else - if ( nbReplaced ) - aMesh->ChangeElementNodes( e, & nodes[0], nbNodes ); - } + _FaceClassifier(const TopoDS_Face& face):_extremum(),_surface(face),_state(TopAbs_OUT) + { + _extremum.Initialize( _surface, + _surface.FirstUParameter(), _surface.LastUParameter(), + _surface.FirstVParameter(), _surface.LastVParameter(), + _surface.Tolerance(), _surface.Tolerance() ); } - - Remove( nodeIDsToRemove, true ); - - return aResult; + void Perform(const gp_Pnt& aPnt, double theTol) + { + _state = TopAbs_OUT; + _extremum.Perform(aPnt); + if ( _extremum.IsDone() ) + for ( int iSol = 1; iSol <= _extremum.NbExt() && _state == TopAbs_OUT; ++iSol) +#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 + _state = ( _extremum.SquareDistance(iSol) <= theTol ? TopAbs_IN : TopAbs_OUT ); +#else + _state = ( _extremum.Value(iSol) <= theTol ? TopAbs_IN : TopAbs_OUT ); +#endif + } + TopAbs_State State() const + { + return _state; + } + }; } //================================================================================ - /*! - * \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 - * \param theFirstNode2 - a node of set 2 corresponding to theFirstNode1 - * \param theSecondNode1 - a boundary node of set 1 linked with theFirstNode1 - * \param theSecondNode2 - a node of set 2 corresponding to theSecondNode1 - * \param nReplaceMap - output map of corresponding nodes - * \retval bool - is a success or not - */ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - group of of elements (edges or faces) to be replicated + \param theNodesNot - group of nodes not to replicate + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ //================================================================================ -#ifdef _DEBUG_ -//#define DEBUG_MATCHING_NODES -#endif +bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TopoDS_Shape& theShape ) +{ + if ( theShape.IsNull() ) + return false; -SMESH_MeshEditor::Sew_Error -SMESH_MeshEditor::FindMatchingNodes(set& theSide1, - set& theSide2, - const SMDS_MeshNode* theFirstNode1, - const SMDS_MeshNode* theFirstNode2, - const SMDS_MeshNode* theSecondNode1, - const SMDS_MeshNode* theSecondNode2, - TNodeNodeMap & nReplaceMap) + const double aTol = Precision::Confusion(); + auto_ptr< BRepClass3d_SolidClassifier> bsc3d; + auto_ptr<_FaceClassifier> aFaceClassifier; + if ( theShape.ShapeType() == TopAbs_SOLID ) + { + bsc3d.reset( new BRepClass3d_SolidClassifier(theShape));; + bsc3d->PerformInfinitePoint(aTol); + } + else if (theShape.ShapeType() == TopAbs_FACE ) + { + aFaceClassifier.reset( new _FaceClassifier(TopoDS::Face(theShape))); + } + + // iterates on indicated elements and get elements by back references from their nodes + TIDSortedElemSet anAffected; + TIDSortedElemSet::const_iterator elemItr = theElems.begin(); + for ( ; elemItr != theElems.end(); ++elemItr ) + { + SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; + if (!anElem) + continue; + + SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); + while ( nodeItr->more() ) + { + const SMDS_MeshNode* aNode = cast2Node(nodeItr->next()); + if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) + continue; + SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); + while ( backElemItr->more() ) + { + const SMDS_MeshElement* curElem = backElemItr->next(); + if ( curElem && theElems.find(curElem) == theElems.end() && + ( bsc3d.get() ? + isInside( curElem, *bsc3d, aTol ) : + isInside( curElem, *aFaceClassifier, aTol ))) + anAffected.insert( curElem ); + } + } + } + return DoubleNodes( theElems, theNodesNot, anAffected ); +} + +/*! + * \brief compute an oriented angle between two planes defined by four points. + * The vector (p0,p1) defines the intersection of the 2 planes (p0,p1,g1) and (p0,p1,g2) + * @param p0 base of the rotation axe + * @param p1 extremity of the rotation axe + * @param g1 belongs to the first plane + * @param g2 belongs to the second plane + */ +double SMESH_MeshEditor::OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const gp_Pnt& g1, const gp_Pnt& g2) { - set * faceSetPtr[] = { &theSide1, &theSide2 }; +// MESSAGE(" p0: " << p0.X() << " " << p0.Y() << " " << p0.Z()); +// MESSAGE(" p1: " << p1.X() << " " << p1.Y() << " " << p1.Z()); +// MESSAGE(" g1: " << g1.X() << " " << g1.Y() << " " << g1.Z()); +// MESSAGE(" g2: " << g2.X() << " " << g2.Y() << " " << g2.Z()); + gp_Vec vref(p0, p1); + gp_Vec v1(p0, g1); + gp_Vec v2(p0, g2); + gp_Vec n1 = vref.Crossed(v1); + gp_Vec n2 = vref.Crossed(v2); + return n2.AngleWithRef(n1, vref); +} - nReplaceMap.clear(); - if ( theFirstNode1 != theFirstNode2 ) - nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 )); - if ( theSecondNode1 != theSecondNode2 ) - nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 )); +/*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * The flat elements are stored in groups of volumes. + * @param theElems - list of groups of volumes, where a group of volume is a set of + * SMDS_MeshElements sorted by Id. + * @param createJointElems - if TRUE, create the elements + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ +bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector& theElems, + bool createJointElems) +{ + MESSAGE("----------------------------------------------"); + MESSAGE("SMESH_MeshEditor::doubleNodesOnGroupBoundaries"); + MESSAGE("----------------------------------------------"); + + SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS(); + meshDS->BuildDownWardConnectivity(true); + CHRONO(50); + SMDS_UnstructuredGrid *grid = meshDS->getGrid(); + + // --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes + // build the list of cells with only a node or an edge on the border, with their domain and volume indexes + // build the list of nodes shared by 2 or more domains, with their domain indexes + + std::map, DownIdCompare> faceDomains; // face --> (id domain --> id volume) + std::mapcelldom; // cell vtkId --> domain + std::map, DownIdCompare> cellDomains; // oldNode --> (id domain --> id cell) + std::map > nodeDomains; // oldId --> (domainId --> newId) + faceDomains.clear(); + celldom.clear(); + cellDomains.clear(); + nodeDomains.clear(); + std::map emptyMap; + std::set emptySet; + emptyMap.clear(); + + for (int idom = 0; idom < theElems.size(); idom++) + { - set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored - linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 )); + // --- build a map (face to duplicate --> volume to modify) + // with all the faces shared by 2 domains (group of elements) + // and corresponding volume of this domain, for each shared face. + // a volume has a face shared by 2 domains if it has a neighbor which is not in is domain. - list< NLink > linkList[2]; - linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 )); - linkList[1].push_back( NLink( theFirstNode2, theSecondNode2 )); + //MESSAGE("Domain " << idom); + const TIDSortedElemSet& domain = theElems[idom]; + TIDSortedElemSet::const_iterator elemItr = domain.begin(); + for (; elemItr != domain.end(); ++elemItr) + { + SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr; + if (!anElem) + continue; + int vtkId = anElem->getVtkId(); + //MESSAGE(" vtkId " << vtkId << " smdsId " << anElem->GetID()); + int neighborsVtkIds[NBMAXNEIGHBORS]; + int downIds[NBMAXNEIGHBORS]; + unsigned char downTypes[NBMAXNEIGHBORS]; + int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId); + for (int n = 0; n < nbNeighbors; n++) + { + int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]); + const SMDS_MeshElement* elem = meshDS->FindElement(smdsId); + if (! domain.count(elem)) // neighbor is in another domain : face is shared + { + DownIdType face(downIds[n], downTypes[n]); + if (!faceDomains.count(face)) + faceDomains[face] = emptyMap; // create an empty entry for face + if (!faceDomains[face].count(idom)) + { + faceDomains[face][idom] = vtkId; // volume associated to face in this domain + celldom[vtkId] = idom; + //MESSAGE(" cell with a border " << vtkId << " domain " << idom); + } + } + } + } + } - // loop on links in linkList; find faces by links and append links - // of the found faces to linkList - list< NLink >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ; - for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) { - NLink link[] = { *linkIt[0], *linkIt[1] }; - if ( linkSet.find( link[0] ) == linkSet.end() ) - continue; + //MESSAGE("Number of shared faces " << faceDomains.size()); + std::map, DownIdCompare>::iterator itface; - // by links, find faces in the face sets, - // and find indices of link nodes in the found faces; - // in a face set, there is only one or no face sharing a link - // --------------------------------------------------------------- + // --- explore the shared faces domain by domain, + // explore the nodes of the face and see if they belong to a cell in the domain, + // which has only a node or an edge on the border (not a shared face) - const SMDS_MeshElement* face[] = { 0, 0 }; - list notLinkNodes[2]; - //bool reverse[] = { false, false }; // order of notLinkNodes - int nbNodes[2]; - for ( int iSide = 0; iSide < 2; iSide++ ) // loop on 2 sides + for (int idomain = 0; idomain < theElems.size(); idomain++) { - const SMDS_MeshNode* n1 = link[iSide].first; - const SMDS_MeshNode* n2 = link[iSide].second; - set * faceSet = faceSetPtr[ iSide ]; - set< const SMDS_MeshElement* > facesOfNode1; - for ( int iNode = 0; iNode < 2; iNode++ ) // loop on 2 nodes of a link - { - // 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(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 - ! facesOfNode1.insert( f ).second ) // f encounters twice - { - if ( face[ iSide ] ) { - MESSAGE( "2 faces per link " ); - return ( iSide ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); + //MESSAGE("Domain " << idomain); + const TIDSortedElemSet& domain = theElems[idomain]; + itface = faceDomains.begin(); + for (; itface != faceDomains.end(); ++itface) + { + std::map domvol = itface->second; + if (!domvol.count(idomain)) + continue; + DownIdType face = itface->first; + //MESSAGE(" --- face " << face.cellId); + std::set oldNodes; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::set::iterator itn = oldNodes.begin(); + for (; itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + //MESSAGE(" node " << oldId); + std::set cells; + cells.clear(); + vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); + for (int i=0; iFindElement(GetMeshDS()->fromVtkToSmds(vtkId)); + if (!domain.count(anElem)) + continue; + int vtkType = grid->GetCellType(vtkId); + int downId = grid->CellIdToDownId(vtkId); + if (downId < 0) + { + MESSAGE("doubleNodesOnGroupBoundaries: internal algorithm problem"); + continue; // not OK at this stage of the algorithm: + //no cells created after BuildDownWardConnectivity + } + DownIdType aCell(downId, vtkType); + if (celldom.count(vtkId)) + continue; + cellDomains[aCell][idomain] = vtkId; + celldom[vtkId] = idomain; + //MESSAGE(" cell " << vtkId << " domain " << idomain); + } } - face[ iSide ] = f; - faceSet->erase( f ); + } + } - // get not link nodes - int nbN = f->NbNodes(); - if ( f->IsQuadratic() ) - nbN /= 2; - nbNodes[ iSide ] = nbN; - list< const SMDS_MeshNode* > & nodes = notLinkNodes[ iSide ]; - int i1 = f->GetNodeIndex( n1 ); - int i2 = f->GetNodeIndex( n2 ); - int iEnd = nbN, iBeg = -1, iDelta = 1; - bool reverse = ( Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1 ); - if ( reverse ) { - std::swap( iEnd, iBeg ); iDelta = -1; + // --- explore the shared faces domain by domain, to duplicate the nodes in a coherent way + // for each shared face, get the nodes + // for each node, for each domain of the face, create a clone of the node + + // --- edges at the intersection of 3 or 4 domains, with the order of domains to build + // junction elements of type prism or hexa. the key is the pair of nodesId (lower first) + // the value is the ordered domain ids. (more than 4 domains not taken into account) + + std::map, std::vector > edgesMultiDomains; // nodes of edge --> ordered domains + std::map > mutipleNodes; // nodes multi domains with domain order + std::map > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains) + + for (int idomain = 0; idomain < theElems.size(); idomain++) + { + itface = faceDomains.begin(); + for (; itface != faceDomains.end(); ++itface) + { + std::map domvol = itface->second; + if (!domvol.count(idomain)) + continue; + DownIdType face = itface->first; + //MESSAGE(" --- face " << face.cellId); + std::set oldNodes; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + bool isMultipleDetected = false; + std::set::iterator itn = oldNodes.begin(); + for (; itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + //MESSAGE(" node " << oldId); + if (!nodeDomains.count(oldId)) + nodeDomains[oldId] = emptyMap; // create an empty entry for node + if (nodeDomains[oldId].empty()) + nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain + std::map::iterator itdom = domvol.begin(); + for (; itdom != domvol.end(); ++itdom) + { + int idom = itdom->first; + //MESSAGE(" domain " << idom); + if (!nodeDomains[oldId].count(idom)) // --- node to clone + { + if (nodeDomains[oldId].size() >= 2) // a multiple node + { + vector orderedDoms; + //MESSAGE("multiple node " << oldId); + isMultipleDetected =true; + if (mutipleNodes.count(oldId)) + orderedDoms = mutipleNodes[oldId]; + else + { + map::iterator it = nodeDomains[oldId].begin(); + for (; it != nodeDomains[oldId].end(); ++it) + orderedDoms.push_back(it->first); + } + orderedDoms.push_back(idom); // TODO order ==> push_front or back + //stringstream txt; + //for (int i=0; iGetPoint(oldId); + SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]); + int newId = newNode->getVtkId(); + nodeDomains[oldId][idom] = newId; // cloned node for other domains + //MESSAGE(" newNode " << newId << " oldNode " << oldId << " size=" <= 3) + { + //MESSAGE("confirm multiple node " << oldId); + isMultipleDetected =true; + } + } } - int i = i2; - while ( true ) { - i += iDelta; - if ( i == iEnd ) i = iBeg + iDelta; - if ( i == i1 ) break; - nodes.push_back ( f->GetNode( i ) ); + if (isMultipleDetected) // check if an edge of the face is shared between 3 or more domains + { + //MESSAGE("multiple Nodes detected on a shared face"); + int downId = itface->first.cellId; + unsigned char cellType = itface->first.cellType; + // --- shared edge or shared face ? + if ((cellType == VTK_LINE) || (cellType == VTK_QUADRATIC_EDGE)) // shared edge (between two faces) + { + int nodes[3]; + int nbNodes = grid->getDownArray(cellType)->getNodes(downId, nodes); + for (int i=0; i< nbNodes; i=i+nbNodes-1) // i=0 , i=nbNodes-1 + if (mutipleNodes.count(nodes[i])) + if (!mutipleNodesToFace.count(nodes[i])) + mutipleNodesToFace[nodes[i]] = mutipleNodes[nodes[i]]; + } + else // shared face (between two volumes) + { + int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId); + const int* downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId); + const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId); + for (int ie =0; ie < nbEdges; ie++) + { + int nodes[3]; + int nbNodes = grid->getDownArray(edgeType[ie])->getNodes(downEdgeIds[ie], nodes); + if (mutipleNodes.count(nodes[0]) && mutipleNodes.count(nodes[nbNodes-1])) + { + vector vn0 = mutipleNodes[nodes[0]]; + vector vn1 = mutipleNodes[nodes[nbNodes - 1]]; + sort( vn0.begin(), vn0.end() ); + sort( vn1.begin(), vn1.end() ); + if (vn0 == vn1) + { + //MESSAGE(" detect edgesMultiDomains " << nodes[0] << " " << nodes[nbNodes - 1]); + double *coords = grid->GetPoint(nodes[0]); + gp_Pnt p0(coords[0], coords[1], coords[2]); + coords = grid->GetPoint(nodes[nbNodes - 1]); + gp_Pnt p1(coords[0], coords[1], coords[2]); + gp_Pnt gref; + int vtkVolIds[1000]; // an edge can belong to a lot of volumes + map domvol; // domain --> a volume with the edge + map angleDom; // oriented angles between planes defined by edge and volume centers + int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]); + for (int id=0; id < vn0.size(); id++) + { + int idom = vn0[id]; + for (int ivol=0; ivolfromVtkToSmds(vtkVolIds[ivol]); + SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId); + if (theElems[idom].count(elem)) + { + SMDS_VtkVolume* svol = dynamic_cast(elem); + domvol[idom] = svol; + //MESSAGE(" domain " << idom << " volume " << elem->GetID()); + double values[3]; + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(vtkVolIds[ivol], npts, pts); + SMDS_VtkVolume::gravityCenter(grid, pts, npts, values); + if (id ==0) + { + gref.SetXYZ(gp_XYZ(values[0], values[1], values[2])); + angleDom[idom] = 0; + } + else + { + gp_Pnt g(values[0], values[1], values[2]); + angleDom[idom] = OrientedAngle(p0, p1, gref, g); // -pisecond << " angle " << ib->first); + } + for (int ino = 0; ino < nbNodes; ino++) + vnodes.push_back(nodes[ino]); + edgesMultiDomains[vnodes] = vdom; // nodes vector --> ordered domains + } + } + } + } } - } } - } } - // check similarity of elements of the sides - if (( face[0] && !face[1] ) || ( !face[0] && face[1] )) { - MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 )); - if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found - return ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES ); - } - else { - return SEW_TOPO_DIFF_SETS_OF_ELEMENTS; - } + + // --- iterate on shared faces (volumes to modify, face to extrude) + // get node id's of the face (id SMDS = id VTK) + // create flat element with old and new nodes if requested + + // --- new quad nodes on flat quad elements: oldId --> ((domain1 X domain2) --> newId) + // (domain1 X domain2) = domain1 + MAXINT*domain2 + + std::map > nodeQuadDomains; + std::map mapOfJunctionGroups; + + if (createJointElems) + { + itface = faceDomains.begin(); + for (; itface != faceDomains.end(); ++itface) + { + DownIdType face = itface->first; + std::set oldNodes; + std::set::iterator itn; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + + std::map domvol = itface->second; + std::map::iterator itdom = domvol.begin(); + int dom1 = itdom->first; + int vtkVolId = itdom->second; + itdom++; + int dom2 = itdom->first; + SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains, + nodeQuadDomains); + stringstream grpname; + grpname << "j_"; + if (dom1 < dom2) + grpname << dom1 << "_" << dom2; + else + grpname << dom2 << "_" << dom1; + int idg; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(vol->GetID()); + } } - // set nodes to merge - // ------------------- + // --- create volumes on multiple domain intersection if requested + // iterate on mutipleNodesToFace + // iterate on edgesMultiDomains - if ( face[0] && face[1] ) { - if ( nbNodes[0] != nbNodes[1] ) { - MESSAGE("Diff nb of face nodes"); - return SEW_TOPO_DIFF_SETS_OF_ELEMENTS; - } -#ifdef DEBUG_MATCHING_NODES - MESSAGE ( " Link 1: " << link[0].first->GetID() <<" "<< link[0].second->GetID() - << " F 1: " << face[0] << "| Link 2: " << link[1].first->GetID() <<" " - << link[1].second->GetID() << " F 2: " << face[1] << " | Bind: " ) ; -#endif - int nbN = nbNodes[0]; - { - list::iterator n1 = notLinkNodes[0].begin(); - list::iterator n2 = notLinkNodes[1].begin(); - for ( int i = 0 ; i < nbN - 2; ++i ) { -#ifdef DEBUG_MATCHING_NODES - MESSAGE ( (*n1)->GetID() << " to " << (*n2)->GetID() ); -#endif - nReplaceMap.insert( make_pair( *(n1++), *(n2++) )); + if (createJointElems) + { + // --- iterate on mutipleNodesToFace + + std::map >::iterator itn = mutipleNodesToFace.begin(); + for (; itn != mutipleNodesToFace.end(); ++itn) + { + int node = itn->first; + vector orderDom = itn->second; + vector orderedNodes; + for (int idom = 0; idom GetMeshDS()->AddFaceFromVtkIds(orderedNodes); + + stringstream grpname; + grpname << "m2j_"; + grpname << 0 << "_" << 0; + int idg; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(face->GetID()); } - } - // add other links of the face 1 to linkList - // ----------------------------------------- + // --- iterate on edgesMultiDomains - const SMDS_MeshElement* f0 = face[0]; - const SMDS_MeshNode* n1 = f0->GetNode( nbN - 1 ); - for ( int i = 0; i < nbN; i++ ) - { - const SMDS_MeshNode* n2 = f0->GetNode( i ); - pair< set< SMESH_TLink >::iterator, bool > iter_isnew = - linkSet.insert( SMESH_TLink( n1, n2 )); - if ( !iter_isnew.second ) { // already in a set: no need to process - linkSet.erase( iter_isnew.first ); + std::map, std::vector >::iterator ite = edgesMultiDomains.begin(); + for (; ite != edgesMultiDomains.end(); ++ite) + { + vector nodes = ite->first; + vector orderDom = ite->second; + vector orderedNodes; + if (nodes.size() == 2) + { + //MESSAGE(" use edgesMultiDomains " << nodes[0] << " " << nodes[1]); + for (int ino=0; ino < nodes.size(); ino++) + if (orderDom.size() == 3) + for (int idom = 0; idom =0; idom--) + orderedNodes.push_back( nodeDomains[nodes[ino]][orderDom[idom]] ); + SMDS_MeshVolume* vol = this->GetMeshDS()->AddVolumeFromVtkIds(orderedNodes); + + stringstream grpname; + grpname << "mj_"; + grpname << 0 << "_" << 0; + int idg; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(vol->GetID()); + } + else + { + MESSAGE("Quadratic multiple joints not implemented"); + // TODO quadratic nodes + } } - else // new in set == encountered for the first time: add + } + + // --- list the explicit faces and edges of the mesh that need to be modified, + // i.e. faces and edges built with one or more duplicated nodes. + // associate these faces or edges to their corresponding domain. + // only the first domain found is kept when a face or edge is shared + + std::map, DownIdCompare> faceOrEdgeDom; // cellToModify --> (id domain --> id cell) + std::map feDom; // vtk id of cell to modify --> id domain + faceOrEdgeDom.clear(); + feDom.clear(); + + for (int idomain = 0; idomain < theElems.size(); idomain++) + { + std::map >::const_iterator itnod = nodeDomains.begin(); + for (; itnod != nodeDomains.end(); ++itnod) { -#ifdef DEBUG_MATCHING_NODES - MESSAGE ( "Add link 1: " << n1->GetID() << " " << n2->GetID() << " " - << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " ); -#endif - linkList[0].push_back ( NLink( n1, n2 )); - linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] )); + int oldId = itnod->first; + //MESSAGE(" node " << oldId); + vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); + for (int i = 0; i < l.ncells; i++) + { + int vtkId = l.cells[i]; + int vtkType = grid->GetCellType(vtkId); + int downId = grid->CellIdToDownId(vtkId); + if (downId < 0) + continue; // new cells: not to be modified + DownIdType aCell(downId, vtkType); + int volParents[1000]; + int nbvol = grid->GetParentVolumes(volParents, vtkId); + for (int j = 0; j < nbvol; j++) + if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain)) + if (!feDom.count(vtkId)) + { + feDom[vtkId] = idomain; + faceOrEdgeDom[aCell] = emptyMap; + faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only + //MESSAGE("affect cell " << this->GetMeshDS()->fromVtkToSmds(vtkId) << " domain " << idomain + // << " type " << vtkType << " downId " << downId); + } + } } - n1 = n2; - } - } // 2 faces found - } // loop on link lists + } - return SEW_OK; + // --- iterate on shared faces (volumes to modify, face to extrude) + // get node id's of the face + // replace old nodes by new nodes in volumes, and update inverse connectivity + + std::map, DownIdCompare>* maps[3] = {&faceDomains, &cellDomains, &faceOrEdgeDom}; + for (int m=0; m<3; m++) + { + std::map, DownIdCompare>* amap = maps[m]; + itface = (*amap).begin(); + for (; itface != (*amap).end(); ++itface) + { + DownIdType face = itface->first; + std::set oldNodes; + std::set::iterator itn; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + //MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType)); + std::map localClonedNodeIds; + + std::map domvol = itface->second; + std::map::iterator itdom = domvol.begin(); + for (; itdom != domvol.end(); ++itdom) + { + int idom = itdom->first; + int vtkVolId = itdom->second; + //MESSAGE("modify nodes of cell " << this->GetMeshDS()->fromVtkToSmds(vtkVolId) << " domain " << idom); + localClonedNodeIds.clear(); + for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + if (nodeDomains[oldId].count(idom)) + { + localClonedNodeIds[oldId] = nodeDomains[oldId][idom]; + //MESSAGE(" node " << oldId << " --> " << localClonedNodeIds[oldId]); + } + } + meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds); + } + } + } + + meshDS->CleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory + grid->BuildLinks(); + + CHRONOSTOP(50); + counters::stats(); + return true; } /*! - \brief Creates a hole in a mesh by doubling the nodes of some particular elements - \param theNodes - identifiers of nodes to be doubled - \param theModifiedElems - identifiers of elements to be updated by the new (doubled) - nodes. If list of element identifiers is empty then nodes are doubled but - they not assigned to elements - \return TRUE if operation has been completed successfully, FALSE otherwise -*/ -bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, - const std::list< int >& theListOfModifiedElems ) + * \brief Double nodes on some external faces and create flat elements. + * Flat elements are mainly used by some types of mechanic calculations. + * + * Each group of the list must be constituted of faces. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * @param theElems - list of groups of faces, where a group of faces is a set of + * SMDS_MeshElements sorted by Id. + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ +bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector& theElems) { - myLastCreatedElems.Clear(); - myLastCreatedNodes.Clear(); + MESSAGE("-------------------------------------------------"); + MESSAGE("SMESH_MeshEditor::CreateFlatElementsOnFacesGroups"); + MESSAGE("-------------------------------------------------"); - if ( theListOfNodes.size() == 0 ) - return false; + SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS(); - SMESHDS_Mesh* aMeshDS = GetMeshDS(); - if ( !aMeshDS ) - return false; + // --- For each group of faces + // duplicate the nodes, create a flat element based on the face + // replace the nodes of the faces by their clones - // iterate through nodes and duplicate them + std::map clonedNodes; + std::map intermediateNodes; + clonedNodes.clear(); + intermediateNodes.clear(); + std::map mapOfJunctionGroups; + mapOfJunctionGroups.clear(); - std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode; + for (int idom = 0; idom < theElems.size(); idom++) + { + const TIDSortedElemSet& domain = theElems[idom]; + TIDSortedElemSet::const_iterator elemItr = domain.begin(); + for (; elemItr != domain.end(); ++elemItr) + { + SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr; + SMDS_MeshFace* aFace = dynamic_cast (anElem); + if (!aFace) + continue; + // MESSAGE("aFace=" << aFace->GetID()); + bool isQuad = aFace->IsQuadratic(); + vector ln0, ln1, ln2, ln3, ln4; - std::list< int >::const_iterator aNodeIter; - for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter ) - { - int aCurr = *aNodeIter; - SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr ); - if ( !aNode ) - continue; + // --- clone the nodes, create intermediate nodes for non medium nodes of a quad face - // duplicate node + SMDS_ElemIteratorPtr nodeIt = aFace->nodesIterator(); + while (nodeIt->more()) + { + const SMDS_MeshNode* node = static_cast (nodeIt->next()); + bool isMedium = isQuad && (aFace->IsMediumNode(node)); + if (isMedium) + ln2.push_back(node); + else + ln0.push_back(node); - const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() ); - if ( aNewNode ) + const SMDS_MeshNode* clone = 0; + if (!clonedNodes.count(node)) + { + clone = meshDS->AddNode(node->X(), node->Y(), node->Z()); + clonedNodes[node] = clone; + } + else + clone = clonedNodes[node]; + + if (isMedium) + ln3.push_back(clone); + else + ln1.push_back(clone); + + const SMDS_MeshNode* inter = 0; + if (isQuad && (!isMedium)) + { + if (!intermediateNodes.count(node)) + { + inter = meshDS->AddNode(node->X(), node->Y(), node->Z()); + intermediateNodes[node] = inter; + } + else + inter = intermediateNodes[node]; + ln4.push_back(inter); + } + } + + // --- extrude the face + + vector ln; + SMDS_MeshVolume* vol = 0; + vtkIdType aType = aFace->GetVtkType(); + switch (aType) + { + case VTK_TRIANGLE: + vol = meshDS->AddVolume(ln0[2], ln0[1], ln0[0], ln1[2], ln1[1], ln1[0]); + // MESSAGE("vol prism " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + break; + case VTK_QUAD: + vol = meshDS->AddVolume(ln0[3], ln0[2], ln0[1], ln0[0], ln1[3], ln1[2], ln1[1], ln1[0]); + // MESSAGE("vol hexa " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + ln.push_back(ln1[3]); + break; + case VTK_QUADRATIC_TRIANGLE: + vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln0[0], ln0[1], ln0[2], ln3[0], ln3[1], ln3[2], + ln2[0], ln2[1], ln2[2], ln4[0], ln4[1], ln4[2]); + // MESSAGE("vol quad prism " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + ln.push_back(ln3[0]); + ln.push_back(ln3[1]); + ln.push_back(ln3[2]); + break; + case VTK_QUADRATIC_QUAD: +// vol = meshDS->AddVolume(ln0[0], ln0[1], ln0[2], ln0[3], ln1[0], ln1[1], ln1[2], ln1[3], +// ln2[0], ln2[1], ln2[2], ln2[3], ln3[0], ln3[1], ln3[2], ln3[3], +// ln4[0], ln4[1], ln4[2], ln4[3]); + vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln1[3], ln0[0], ln0[1], ln0[2], ln0[3], + ln3[0], ln3[1], ln3[2], ln3[3], ln2[0], ln2[1], ln2[2], ln2[3], + ln4[0], ln4[1], ln4[2], ln4[3]); + // MESSAGE("vol quad hexa " << vol->GetID()); + ln.push_back(ln1[0]); + ln.push_back(ln1[1]); + ln.push_back(ln1[2]); + ln.push_back(ln1[3]); + ln.push_back(ln3[0]); + ln.push_back(ln3[1]); + ln.push_back(ln3[2]); + ln.push_back(ln3[3]); + break; + case VTK_POLYGON: + break; + default: + break; + } + + if (vol) + { + stringstream grpname; + grpname << "jf_"; + grpname << idom; + int idg; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(vol->GetID()); + } + + // --- modify the face + + aFace->ChangeNodes(&ln[0], ln.size()); + } + } + return true; +} + +//================================================================================ +/*! + * \brief Generates skin mesh (containing 2D cells) from 3D mesh + * The created 2D mesh elements based on nodes of free faces of boundary volumes + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ +//================================================================================ + +bool SMESH_MeshEditor::Make2DMeshFrom3D() +{ + // iterates on volume elements and detect all free faces on them + SMESHDS_Mesh* aMesh = GetMeshDS(); + if (!aMesh) + return false; + //bool res = false; + int nbFree = 0, nbExisted = 0, nbCreated = 0; + SMDS_VolumeIteratorPtr vIt = aMesh->volumesIterator(); + while(vIt->more()) + { + const SMDS_MeshVolume* volume = vIt->next(); + SMDS_VolumeTool vTool( volume, /*ignoreCentralNodes=*/false ); + vTool.SetExternalNormal(); + //const bool isPoly = volume->IsPoly(); + const int iQuad = volume->IsQuadratic(); + for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ ) { - anOldNodeToNewNode[ aNode ] = aNewNode; - myLastCreatedNodes.Append( aNewNode ); + if (!vTool.IsFreeFace(iface)) + continue; + nbFree++; + vector nodes; + int nbFaceNodes = vTool.NbFaceNodes(iface); + const SMDS_MeshNode** faceNodes = vTool.GetFaceNodes(iface); + int inode = 0; + for ( ; inode < nbFaceNodes; inode += iQuad+1) + nodes.push_back(faceNodes[inode]); + if (iQuad) { // add medium nodes + for ( inode = 1; inode < nbFaceNodes; inode += 2) + nodes.push_back(faceNodes[inode]); + if ( nbFaceNodes == 9 ) // bi-quadratic quad + nodes.push_back(faceNodes[8]); + } + // add new face based on volume nodes + if (aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false) ) { + nbExisted++; + continue; // face already exsist + } + AddElement(nodes, SMDSAbs_Face, ( !iQuad && nbFaceNodes/(iQuad+1) > 4 )); + nbCreated++; } } + return ( nbFree==(nbExisted+nbCreated) ); +} - // Create map of new nodes for modified elements +namespace +{ + inline const SMDS_MeshNode* getNodeWithSameID(SMESHDS_Mesh* mesh, const SMDS_MeshNode* node) + { + if ( const SMDS_MeshNode* n = mesh->FindNode( node->GetID() )) + return n; + return mesh->AddNodeWithID( node->X(),node->Y(),node->Z(), node->GetID() ); + } +} +//================================================================================ +/*! + * \brief Creates missing boundary elements + * \param elements - elements whose boundary is to be checked + * \param dimension - defines type of boundary elements to create + * \param group - a group to store created boundary elements in + * \param targetMesh - a mesh to store created boundary elements in + * \param toCopyElements - if true, the checked elements will be copied into the targetMesh + * \param toCopyExistingBoundary - if true, not only new but also pre-existing + * boundary elements will be copied into the targetMesh + * \param toAddExistingBondary - if true, not only new but also pre-existing + * boundary elements will be added into the new group + * \param aroundElements - if true, elements will be created on boundary of given + * elements else, on boundary of the whole mesh. + * \return nb of added boundary elements + */ +//================================================================================ - std::map< SMDS_MeshElement*, vector > anElemToNodes; +int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, + Bnd_Dimension dimension, + SMESH_Group* group/*=0*/, + SMESH_Mesh* targetMesh/*=0*/, + bool toCopyElements/*=false*/, + bool toCopyExistingBoundary/*=false*/, + bool toAddExistingBondary/*= false*/, + bool aroundElements/*= false*/) +{ + SMDSAbs_ElementType missType = (dimension == BND_2DFROM3D) ? SMDSAbs_Face : SMDSAbs_Edge; + SMDSAbs_ElementType elemType = (dimension == BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume; + // hope that all elements are of the same type, do not check them all + if ( !elements.empty() && (*elements.begin())->GetType() != elemType ) + throw SALOME_Exception(LOCALIZED("wrong element type")); + + if ( !targetMesh ) + toCopyElements = toCopyExistingBoundary = false; + + SMESH_MeshEditor tgtEditor( targetMesh ? targetMesh : myMesh ); + SMESHDS_Mesh* aMesh = GetMeshDS(), *tgtMeshDS = tgtEditor.GetMeshDS(); + int nbAddedBnd = 0; + + // editor adding present bnd elements and optionally holding elements to add to the group + SMESH_MeshEditor* presentEditor; + SMESH_MeshEditor tgtEditor2( tgtEditor.GetMesh() ); + presentEditor = toAddExistingBondary ? &tgtEditor : &tgtEditor2; + + SMESH_MesherHelper helper( *myMesh ); + const TopAbs_ShapeEnum missShapeType = ( missType==SMDSAbs_Face ? TopAbs_FACE : TopAbs_EDGE ); + SMDS_VolumeTool vTool; + TIDSortedElemSet avoidSet; + const TIDSortedElemSet emptySet, *elemSet = aroundElements ? &elements : &emptySet; + int inode; + + typedef vector TConnectivity; + + SMDS_ElemIteratorPtr eIt; + if (elements.empty()) + eIt = aMesh->elementsIterator(elemType); + else + eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() )); - std::list< int >::const_iterator anElemIter; - for ( anElemIter = theListOfModifiedElems.begin(); - anElemIter != theListOfModifiedElems.end(); ++anElemIter ) + while (eIt->more()) { - int aCurr = *anElemIter; - SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr ); - if ( !anElem ) - continue; - - vector aNodeArr( anElem->NbNodes() ); + const SMDS_MeshElement* elem = eIt->next(); + const int iQuad = elem->IsQuadratic(); + + // ------------------------------------------------------------------------------------ + // 1. For an elem, get present bnd elements and connectivities of missing bnd elements + // ------------------------------------------------------------------------------------ + vector presentBndElems; + vector missingBndElems; + TConnectivity nodes; + if ( vTool.Set(elem, /*ignoreCentralNodes=*/true) ) // elem is a volume -------------- + { + vTool.SetExternalNormal(); + const SMDS_MeshElement* otherVol = 0; + for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ ) + { + if ( !vTool.IsFreeFace(iface, &otherVol) && + ( !aroundElements || elements.count( otherVol ))) + continue; + const int nbFaceNodes = vTool.NbFaceNodes(iface); + const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface); + if ( missType == SMDSAbs_Edge ) // boundary edges + { + nodes.resize( 2+iQuad ); + for ( int i = 0; i < nbFaceNodes; i += 1+iQuad) + { + for ( int j = 0; j < nodes.size(); ++j ) + nodes[j] =nn[i+j]; + if ( const SMDS_MeshElement* edge = + aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/false)) + presentBndElems.push_back( edge ); + else + missingBndElems.push_back( nodes ); + } + } + else // boundary face + { + nodes.clear(); + for ( inode = 0; inode < nbFaceNodes; inode += 1+iQuad) + nodes.push_back( nn[inode] ); + if (iQuad) // add medium nodes + for ( inode = 1; inode < nbFaceNodes; inode += 2) + nodes.push_back( nn[inode] ); + int iCenter = vTool.GetCenterNodeIndex(iface); // for HEX27 + if ( iCenter > 0 ) + nodes.push_back( vTool.GetNodes()[ iCenter ] ); + + if (const SMDS_MeshElement * f = aMesh->FindElement( nodes, + SMDSAbs_Face, /*noMedium=*/false )) + presentBndElems.push_back( f ); + else + missingBndElems.push_back( nodes ); - SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); - int ind = 0; - while ( anIter->more() ) - { - SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next(); - if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() ) + if ( targetMesh != myMesh ) + { + // add 1D elements on face boundary to be added to a new mesh + const SMDS_MeshElement* edge; + for ( inode = 0; inode < nbFaceNodes; inode += 1+iQuad) + { + if ( iQuad ) + edge = aMesh->FindEdge( nn[inode], nn[inode+1], nn[inode+2]); + else + edge = aMesh->FindEdge( nn[inode], nn[inode+1]); + if ( edge && avoidSet.insert( edge ).second ) + presentBndElems.push_back( edge ); + } + } + } + } + } + else // elem is a face ------------------------------------------ + { + avoidSet.clear(), avoidSet.insert( elem ); + int nbNodes = elem->NbCornerNodes(); + nodes.resize( 2 /*+ iQuad*/); + for ( int i = 0; i < nbNodes; i++ ) { - const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ]; - aNodeArr[ ind++ ] = aNewNode; + nodes[0] = elem->GetNode(i); + nodes[1] = elem->GetNode((i+1)%nbNodes); + if ( FindFaceInSet( nodes[0], nodes[1], *elemSet, avoidSet)) + continue; // not free link + + //if ( iQuad ) + //nodes[2] = elem->GetNode( i + nbNodes ); + if ( const SMDS_MeshElement* edge = + aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/true)) + presentBndElems.push_back( edge ); + else + missingBndElems.push_back( nodes ); } - else - aNodeArr[ ind++ ] = aCurrNode; } - anElemToNodes[ anElem ] = aNodeArr; - } - // Change nodes of elements + // --------------------------------- + // 2. Add missing boundary elements + // --------------------------------- + if ( targetMesh != myMesh ) + // instead of making a map of nodes in this mesh and targetMesh, + // we create nodes with same IDs. + for ( int i = 0; i < missingBndElems.size(); ++i ) + { + TConnectivity& srcNodes = missingBndElems[i]; + TConnectivity nodes( srcNodes.size() ); + for ( inode = 0; inode < nodes.size(); ++inode ) + nodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] ); + if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes, + missType, + /*noMedium=*/false)) + continue; + tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4); + ++nbAddedBnd; + } + else + for ( int i = 0; i < missingBndElems.size(); ++i ) + { + TConnectivity& nodes = missingBndElems[i]; + if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes, + missType, + /*noMedium=*/false)) + continue; + SMDS_MeshElement* elem = + tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4); + ++nbAddedBnd; - std::map< SMDS_MeshElement*, vector >::iterator - anElemToNodesIter = anElemToNodes.begin(); - for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter ) + // try to set a new element to a shape + if ( myMesh->HasShapeToMesh() ) + { + bool ok = true; + set< pair > mediumShapes; + const int nbN = nodes.size() / (iQuad+1 ); + for ( inode = 0; inode < nbN && ok; ++inode ) + { + pair i_stype = + helper.GetMediumPos( nodes[inode], nodes[(inode+1)%nbN]); + if (( ok = ( i_stype.first > 0 && i_stype.second >= TopAbs_FACE ))) + mediumShapes.insert( make_pair ( i_stype.second, i_stype.first )); + } + if ( ok && mediumShapes.size() > 1 ) + { + set< pair >::iterator stype_i = mediumShapes.begin(); + pair stype_i_0 = *stype_i; + for ( ++stype_i; stype_i != mediumShapes.end() && ok; ++stype_i ) + { + if (( ok = ( stype_i->first != stype_i_0.first ))) + ok = helper.IsSubShape( aMesh->IndexToShape( stype_i->second ), + aMesh->IndexToShape( stype_i_0.second )); + } + } + if ( ok && mediumShapes.begin()->first == missShapeType ) + aMesh->SetMeshElementOnShape( elem, mediumShapes.begin()->second ); + } + } + + // ---------------------------------- + // 3. Copy present boundary elements + // ---------------------------------- + if ( toCopyExistingBoundary ) + for ( int i = 0 ; i < presentBndElems.size(); ++i ) + { + const SMDS_MeshElement* e = presentBndElems[i]; + TConnectivity nodes( e->NbNodes() ); + for ( inode = 0; inode < nodes.size(); ++inode ) + nodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) ); + presentEditor->AddElement(nodes, e->GetType(), e->IsPoly()); + } + else // store present elements to add them to a group + for ( int i = 0 ; i < presentBndElems.size(); ++i ) + { + presentEditor->myLastCreatedElems.Append(presentBndElems[i]); + } + + } // loop on given elements + + // --------------------------------------------- + // 4. Fill group with boundary elements + // --------------------------------------------- + if ( group ) { - const SMDS_MeshElement* anElem = anElemToNodesIter->first; - vector aNodeArr = anElemToNodesIter->second; - if ( anElem ) - aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() ); + if ( SMESHDS_Group* g = dynamic_cast( group->GetGroupDS() )) + for ( int i = 0; i < tgtEditor.myLastCreatedElems.Size(); ++i ) + g->SMDSGroup().Add( tgtEditor.myLastCreatedElems( i+1 )); } + tgtEditor.myLastCreatedElems.Clear(); + tgtEditor2.myLastCreatedElems.Clear(); - return true; + // ----------------------- + // 5. Copy given elements + // ----------------------- + if ( toCopyElements && targetMesh != myMesh ) + { + if (elements.empty()) + eIt = aMesh->elementsIterator(elemType); + else + eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() )); + while (eIt->more()) + { + const SMDS_MeshElement* elem = eIt->next(); + TConnectivity nodes( elem->NbNodes() ); + for ( inode = 0; inode < nodes.size(); ++inode ) + nodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) ); + tgtEditor.AddElement(nodes, elemType, elem->IsPoly()); + + tgtEditor.myLastCreatedElems.Clear(); + } + } + return nbAddedBnd; } diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index ccab3fbb6..4bd455825 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -1,25 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses + // File : SMESH_MeshEditor.hxx // Created : Mon Apr 12 14:56:19 2004 // Author : Edward AGAPOV (eap) @@ -30,70 +30,72 @@ #include "SMESH_SMESH.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_Controls.hxx" -#include "SMESH_SequenceOfNode.hxx" -#include "SMESH_SequenceOfElemPtr.hxx" -#include "TColStd_HSequenceOfReal.hxx" -#include "SMESH_MesherHelper.hxx" #include "SMDS_MeshElement.hxx" +#include "SMESH_Controls.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_TypeDefs.hxx" + +#include +#include #include #include #include - -typedef std::map > TElemOfElemListMap; -typedef std::map TNodeNodeMap; - - -typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink; - -//======================================================================= -/*! - * \brief A sorted pair of nodes - */ -//======================================================================= - -struct SMESH_TLink: public NLink -{ - SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 ) - { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); } - SMESH_TLink(const NLink& link ):NLink( link ) - { if ( first->GetID() < second->GetID() ) std::swap( first, second ); } -}; - +#include class SMDS_MeshFace; class SMDS_MeshNode; class gp_Ax1; class gp_Vec; class gp_Pnt; +class SMESH_MesherHelper; -// ============================================================ + +//======================================================================= /*! - * \brief Set of elements sorted by ID, to be used to assure - * predictability of edition + * \brief Searcher for the node closest to point */ -// ============================================================ - -template < class TMeshElem = SMDS_MeshElement> -struct TIDCompare { - bool operator () (const TMeshElem* e1, const TMeshElem* e2) const - { return e1->GetID() < e2->GetID(); } +//======================================================================= +struct SMESH_NodeSearcher +{ + virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0; + virtual void MoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt ) = 0; }; -typedef std::set< const SMDS_MeshElement*, TIDCompare< SMDS_MeshElement> > TIDSortedElemSet; -// ============================================================ +//======================================================================= /*! - * \brief Searcher for the node closest to point + * \brief Searcher for elements */ -// ============================================================ +//======================================================================= -struct SMESH_NodeSearcher +struct SMESH_ElementSearcher { - virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0; + /*! + * \brief Find elements of given type where the given point is IN or ON. + * Returns nb of found elements and elements them-selves. + * + * 'ALL' type means elements of any type excluding nodes and 0D elements + */ + virtual int FindElementsByPoint(const gp_Pnt& point, + SMDSAbs_ElementType type, + std::vector< const SMDS_MeshElement* >& foundElems)=0; + /*! + * \brief Return an element most close to the given point + */ + virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point, + SMDSAbs_ElementType type) = 0; + /*! + * \brief Return elements possibly intersecting the line + */ + virtual void GetElementsNearLine( const gp_Ax1& line, + SMDSAbs_ElementType type, + std::vector< const SMDS_MeshElement* >& foundElems)=0; + /*! + * \brief Find out if the given point is out of closed 2D mesh. + */ + virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0; + }; // ============================================================ @@ -102,8 +104,8 @@ struct SMESH_NodeSearcher */ // ============================================================ -class SMESH_EXPORT SMESH_MeshEditor { - +class SMESH_EXPORT SMESH_MeshEditor +{ public: SMESH_MeshEditor( SMESH_Mesh* theMesh ); @@ -114,16 +116,17 @@ public: SMDS_MeshElement* AddElement(const std::vector & nodes, const SMDSAbs_ElementType type, const bool isPoly, - const int ID = 0); + const int ID = -1, + const double ballDiameter=0.); /*! * \brief Add element */ SMDS_MeshElement* AddElement(const std::vector & nodeIDs, const SMDSAbs_ElementType type, const bool isPoly, - const int ID = 0); + const int ID = -1); - bool Remove (const std::list< int >& theElemIDs, const bool isNodes); + int Remove (const std::list< int >& theElemIDs, const bool isNodes); // Remove a node or an element. // Modify a compute state of sub-meshes which become empty @@ -148,6 +151,11 @@ public: bool Reorient (const SMDS_MeshElement * theElement); // Reverse theElement orientation + int Reorient2D (TIDSortedElemSet & theFaces, + const gp_Dir& theDirection, + const SMDS_MeshElement * theFace); + // Reverse theFaces whose orientation to be same as that of theFace + // oriented according to theDirection. Return nb of reoriented faces /*! * \brief Fuse neighbour triangles into quadrangles. @@ -155,7 +163,7 @@ public: * \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. - * \retval bool - Success or not. + * \return bool - Success or not. */ bool TriToQuad (TIDSortedElemSet & theElems, SMESH::Controls::NumericalFunctorPtr theCriterion, @@ -165,7 +173,7 @@ public: * \brief Split quadrangles into triangles. * \param theElems - The faces to be splitted. * \param theCriterion - Is used to choose a diagonal for splitting. - * \retval bool - Success or not. + * \return bool - Success or not. */ bool QuadToTri (TIDSortedElemSet & theElems, SMESH::Controls::NumericalFunctorPtr theCriterion); @@ -174,7 +182,7 @@ public: * \brief Split quadrangles into triangles. * \param theElems - The faces to be splitted. * \param the13Diag - Is used to choose a diagonal for splitting. - * \retval bool - Success or not. + * \return bool - Success or not. */ bool QuadToTri (TIDSortedElemSet & theElems, const bool the13Diag); @@ -183,12 +191,19 @@ public: * \brief Find better diagonal for splitting. * \param theQuad - The face to find better splitting of. * \param theCriterion - Is used to choose a diagonal for splitting. - * \retval int - 1 for 1-3 diagonal, 2 for 2-4, -1 - for errors. + * \return int - 1 for 1-3 diagonal, 2 for 2-4, -1 - for errors. */ int BestSplit (const SMDS_MeshElement* theQuad, SMESH::Controls::NumericalFunctorPtr theCriterion); + enum SplitVolumToTetraFlags { HEXA_TO_5 = 1, HEXA_TO_6 = 2, HEXA_TO_24 = 3 };//!& theAngles, + const bool theLinearVariation, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint, + const bool theMakeGroups); + Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet & theElements, + SMESH_Mesh* theTrackPattern, + const SMDS_MeshNode* theNodeStart, + const bool theHasAngles, + std::list& theAngles, + const bool theLinearVariation, const bool theHasRefPoint, const gp_Pnt& theRefPoint, const bool theMakeGroups); @@ -316,19 +341,32 @@ public: SMESH_Mesh* theTargetMesh=0); // Move or copy theElements applying theTrsf to their nodes + typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes; - void FindCoincidentNodes (std::set & theNodes, - const double theTolerance, - TListOfListOfNodes & theGroupsOfNodes); + void FindCoincidentNodes (TIDSortedNodeSet & theNodes, + const double theTolerance, + TListOfListOfNodes & theGroupsOfNodes); // Return list of group of nodes close to each other within theTolerance. // Search among theNodes or in the whole mesh if theNodes is empty. /*! - * \brief Return SMESH_NodeSearcher + * \brief Return SMESH_NodeSearcher. The caller is responsible for deleteing it */ SMESH_NodeSearcher* GetNodeSearcher(); + /*! + * \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it + */ + SMESH_ElementSearcher* GetElementSearcher(); + SMESH_ElementSearcher* GetElementSearcher( SMDS_ElemIteratorPtr elemIt ); + /*! + * \brief Return true if the point is IN or ON of the element + */ + static bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol ); + + static double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point ); + int SimplifyFace (const std::vector faceNodes, std::vector& poly_nodes, std::vector& quantities) const; @@ -342,7 +380,7 @@ public: typedef std::list< std::list< int > > TListOfListOfElementsID; void FindEqualElements(std::set & theElements, - TListOfListOfElementsID & theGroupsOfElementsID); + 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. @@ -439,24 +477,20 @@ public: // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2. void ConvertToQuadratic(const bool theForce3d); - //converts all mesh to quadratic one, deletes old elements, replacing - //them with quadratic ones with the same id. + void ConvertToQuadratic(const bool theForce3d, TIDSortedElemSet& theElements); + // Converts all mesh to quadratic one, deletes old elements, replacing + // them with quadratic ones with the same id. + // If theForce3d = 1; this results in the medium node lying at the + // middle of the line segments connecting start and end node of a mesh + // element + // If theForce3d = 0; this results in the medium node lying at the + // geometrical edge from which the mesh element is built bool ConvertFromQuadratic(); - //converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing - //them with ordinary mesh elements with the same id. - - -// static int SortQuadNodes (const SMDS_Mesh * theMesh, -// int theNodeIds[] ); -// // Set 4 nodes of a quadrangle face in a good order. -// // Swap 1<->2 or 2<->3 nodes and correspondingly return -// // 1 or 2 else 0. -// -// static bool SortHexaNodes (const SMDS_Mesh * theMesh, -// int theNodeIds[] ); -// // Set 8 nodes of a hexahedron in a good order. -// // Return success status + void ConvertFromQuadratic(TIDSortedElemSet& theElements); + // Converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing + // them with ordinary mesh elements with the same id. + // Returns true in case of success, false otherwise. static void AddToSameGroups (const SMDS_MeshElement* elemToAdd, const SMDS_MeshElement* elemInGroups, @@ -472,6 +506,11 @@ public: SMESHDS_Mesh * aMesh); // replace elemToRm by elemToAdd in the all groups + static void ReplaceElemInGroups (const SMDS_MeshElement* elemToRm, + const std::vector& elemToAdd, + SMESHDS_Mesh * aMesh); + // replace elemToRm by elemToAdd in the all groups + /*! * \brief Return nodes linked to the given one in elements of the type */ @@ -479,14 +518,16 @@ public: TIDSortedElemSet & linkedNodes, SMDSAbs_ElementType type = SMDSAbs_All ); - static const SMDS_MeshElement* - FindFaceInSet(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const TIDSortedElemSet& elemSet, - const TIDSortedElemSet& avoidSet); + static const SMDS_MeshElement* FindFaceInSet(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const TIDSortedElemSet& elemSet, + const TIDSortedElemSet& avoidSet, + int* i1=0, + int* i2=0); // Return a face having linked nodes n1 and n2 and which is // - not in avoidSet, // - in elemSet provided that !elemSet.empty() + // i1 and i2 optionally returns indices of n1 and n2 /*! * \brief Find corresponding nodes in two sets of faces @@ -497,21 +538,21 @@ public: * \param theSecondNode1 - a boundary node of set 1 linked with theFirstNode1 * \param theSecondNode2 - a node of set 2 corresponding to theSecondNode1 * \param nReplaceMap - output map of corresponding nodes - * \retval Sew_Error - is a success or not + * \return Sew_Error - is a success or not */ static Sew_Error FindMatchingNodes(std::set& theSide1, std::set& theSide2, - const SMDS_MeshNode* theFirstNode1, - const SMDS_MeshNode* theFirstNode2, - const SMDS_MeshNode* theSecondNode1, - const SMDS_MeshNode* theSecondNode2, - TNodeNodeMap & nReplaceMap); + const SMDS_MeshNode* theFirstNode1, + const SMDS_MeshNode* theFirstNode2, + const SMDS_MeshNode* theSecondNode1, + const SMDS_MeshNode* theSecondNode2, + TNodeNodeMap & theNodeReplaceMap); /*! * \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 + * \return bool - check result */ static bool IsMedium(const SMDS_MeshNode* node, const SMDSAbs_ElementType typeToCheck = SMDSAbs_All); @@ -527,15 +568,49 @@ public: const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; } const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; } - + bool DoubleNodes( const std::list< int >& theListOfNodes, const std::list< int >& theListOfModifiedElems ); + + bool DoubleNodes( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TIDSortedElemSet& theAffectedElems ); -private: + bool DoubleNodesInRegion( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TopoDS_Shape& theShape ); + + double OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const gp_Pnt& g1, const gp_Pnt& g2); + + bool DoubleNodesOnGroupBoundaries( const std::vector& theElems, + bool createJointElems); + + bool CreateFlatElementsOnFacesGroups( const std::vector& theElems ); + + /*! + * \brief Generated skin mesh (containing 2D cells) from 3D mesh + * The created 2D mesh elements based on nodes of free faces of boundary volumes + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ + bool Make2DMeshFrom3D(); + + enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D }; + + int MakeBoundaryMesh(const TIDSortedElemSet& elements, + Bnd_Dimension dimension, + SMESH_Group* group = 0, + SMESH_Mesh* targetMesh = 0, + bool toCopyElements = false, + bool toCopyExistingBondary = false, + bool toAddExistingBondary = false, + bool aroundElements = false); + + + private: /*! * \brief Convert elements contained in a submesh to quadratic - * \retval int - nb of checked elements + * \return int - nb of checked elements */ int convertElemToQuadratic(SMESHDS_SubMesh * theSm, SMESH_MesherHelper& theHelper, @@ -543,7 +618,7 @@ private: /*! * \brief Convert quadratic elements to linear ones and remove quadratic nodes - * \retval int - nb of checked elements + * \return nb of checked elements */ int removeQuadElem( SMESHDS_SubMesh * theSm, SMDS_ElemIteratorPtr theItr, @@ -567,11 +642,11 @@ private: /*! * \brief Create elements by sweeping an element - * \param elem - element to sweep - * \param newNodesItVec - nodes generated from each node of the element - * \param newElems - generated elements - * \param nbSteps - number of sweeping steps - * \param srcElements - to append elem for each generated element + * \param elem - element to sweep + * \param newNodesItVec - nodes generated from each node of the element + * \param newElems - generated elements + * \param nbSteps - number of sweeping steps + * \param srcElements - to append elem for each generated element */ void sweepElement(const SMDS_MeshElement* elem, const std::vector & newNodesItVec, @@ -581,12 +656,12 @@ private: /*! * \brief Create 1D and 2D elements around swept elements - * \param mapNewNodes - source nodes and ones generated from them - * \param newElemsMap - source elements and ones generated from them - * \param elemNewNodesMap - nodes generated from each node of each element - * \param elemSet - all swept elements - * \param nbSteps - number of sweeping steps - * \param srcElements - to append elem for each generated element + * \param mapNewNodes - source nodes and ones generated from them + * \param newElemsMap - source elements and ones generated from them + * \param elemNewNodesMap - nodes generated from each node of each element + * \param elemSet - all swept elements + * \param nbSteps - number of sweeping steps + * \param srcElements - to append elem for each generated element */ void makeWalls (TNodeOfNodeListMap & mapNewNodes, TElemOfElemListMap & newElemsMap, @@ -594,6 +669,44 @@ private: TIDSortedElemSet& elemSet, const int nbSteps, SMESH_SequenceOfElemPtr& srcElements); + + struct SMESH_MeshEditor_PathPoint + { + gp_Pnt myPnt; + gp_Dir myTgt; + double myAngle, myPrm; + + SMESH_MeshEditor_PathPoint(): myPnt(99., 99., 99.), myTgt(1.,0.,0.), myAngle(0), myPrm(0) {} + void SetPnt (const gp_Pnt& aP3D) { myPnt =aP3D; } + void SetTangent (const gp_Dir& aTgt) { myTgt =aTgt; } + void SetAngle (const double& aBeta) { myAngle=aBeta; } + void SetParameter(const double& aPrm) { myPrm =aPrm; } + const gp_Pnt& Pnt ()const { return myPnt; } + const gp_Dir& Tangent ()const { return myTgt; } + double Angle ()const { return myAngle; } + double Parameter ()const { return myPrm; } + }; + Extrusion_Error MakeEdgePathPoints(std::list& aPrms, + const TopoDS_Edge& aTrackEdge, + bool aFirstIsStart, + std::list& aLPP); + Extrusion_Error MakeExtrElements(TIDSortedElemSet& theElements, + std::list& theFullList, + const bool theHasAngles, + std::list& theAngles, + const bool theLinearVariation, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint, + const bool theMakeGroups); + void LinearAngleVariation(const int NbSteps, + list& theAngles); + + bool doubleNodes( SMESHDS_Mesh* theMeshDS, + const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap, + const bool theIsDoubleElem ); + private: SMESH_Mesh * myMesh; diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 292c29ecb..efaf7a853 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File: SMESH_MesherHelper.cxx // Created: 15.02.06 15:22:41 // Author: Sergey KUUL @@ -27,30 +28,49 @@ #include "SMDS_FacePosition.hxx" #include "SMDS_EdgePosition.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMDS_VolumeTool.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_ProxyMesh.hxx" #include #include -#include #include +#include #include +#include +#include #include +#include #include #include #include #include #include +#include #include #include +#include #include +#include #include #include #include +#include + +using namespace std; + #define RETURN_BAD_RESULT(msg) { MESSAGE(msg); return false; } +namespace { + + gp_XYZ XYZ(const SMDS_MeshNode* n) { return gp_XYZ(n->X(), n->Y(), n->Z()); } + + enum { U_periodic = 1, V_periodic = 2 }; +} + //================================================================================ /*! * \brief Constructor @@ -58,94 +78,140 @@ //================================================================================ SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh) - : myMesh(&theMesh), myShapeID(-1), myCreateQuadratic(false) + : myParIndex(0), myMesh(&theMesh), myShapeID(0), myCreateQuadratic(false), + myFixNodeParameters(false) { + myPar1[0] = myPar2[0] = myPar1[1] = myPar2[1] = 0; mySetElemOnShape = ( ! myMesh->HasShapeToMesh() ); } //======================================================================= -//function : CheckShape +//function : ~SMESH_MesherHelper //purpose : //======================================================================= +SMESH_MesherHelper::~SMESH_MesherHelper() +{ + { + TID2ProjectorOnSurf::iterator i_proj = myFace2Projector.begin(); + for ( ; i_proj != myFace2Projector.end(); ++i_proj ) + delete i_proj->second; + } + { + TID2ProjectorOnCurve::iterator i_proj = myEdge2Projector.begin(); + for ( ; i_proj != myEdge2Projector.end(); ++i_proj ) + delete i_proj->second; + } +} + +//======================================================================= +//function : IsQuadraticSubMesh +//purpose : Check submesh for given shape: if all elements on this shape +// are quadratic, quadratic elements will be created. +// Also fill myTLinkNodeMap +//======================================================================= + bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh) { SMESHDS_Mesh* meshDS = GetMeshDS(); // we can create quadratic elements only if all elements - // created on subshapes of given shape are quadratic - // also we have to fill myNLinkNodeMap + // created on sub-shapes of given shape are quadratic + // also we have to fill myTLinkNodeMap myCreateQuadratic = true; mySeamShapeIds.clear(); myDegenShapeIds.clear(); TopAbs_ShapeEnum subType( aSh.ShapeType()==TopAbs_FACE ? TopAbs_EDGE : TopAbs_FACE ); + if ( aSh.ShapeType()==TopAbs_COMPOUND ) + { + TopoDS_Iterator subIt( aSh ); + if ( subIt.More() ) + subType = ( subIt.Value().ShapeType()==TopAbs_FACE ) ? TopAbs_EDGE : TopAbs_FACE; + } SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge ); - TopExp_Explorer exp( aSh, subType ); - for (; exp.More() && myCreateQuadratic; exp.Next()) { - if ( SMESHDS_SubMesh * subMesh = meshDS->MeshElements( exp.Current() )) { - if ( SMDS_ElemIteratorPtr it = subMesh->GetElements() ) { - while(it->more()) { - const SMDS_MeshElement* e = it->next(); - if ( e->GetType() != elemType || !e->IsQuadratic() ) { - myCreateQuadratic = false; - break; - } - else { - // fill NLinkNodeMap - switch ( e->NbNodes() ) { - case 3: - AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(2)); break; - case 6: - AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(3)); - AddNLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(4)); - AddNLinkNode(e->GetNode(2),e->GetNode(0),e->GetNode(5)); break; - case 8: - AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(4)); - AddNLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(5)); - AddNLinkNode(e->GetNode(2),e->GetNode(3),e->GetNode(6)); - AddNLinkNode(e->GetNode(3),e->GetNode(0),e->GetNode(7)); - break; - default: + + int nbOldLinks = myTLinkNodeMap.size(); + + if ( !myMesh->HasShapeToMesh() ) + { + if (( myCreateQuadratic = myMesh->NbFaces( ORDER_QUADRATIC ))) + { + SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(); + while ( fIt->more() ) + AddTLinks( static_cast< const SMDS_MeshFace* >( fIt->next() )); + } + } + else + { + TopExp_Explorer exp( aSh, subType ); + TopTools_MapOfShape checkedSubShapes; + for (; exp.More() && myCreateQuadratic; exp.Next()) { + if ( !checkedSubShapes.Add( exp.Current() )) + continue; // needed if aSh is compound of solids + if ( SMESHDS_SubMesh * subMesh = meshDS->MeshElements( exp.Current() )) { + if ( SMDS_ElemIteratorPtr it = subMesh->GetElements() ) { + while(it->more()) { + const SMDS_MeshElement* e = it->next(); + if ( e->GetType() != elemType || !e->IsQuadratic() ) { myCreateQuadratic = false; break; } + else { + // fill TLinkNodeMap + switch ( e->NbNodes() ) { + case 3: + AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(2)); break; + case 6: + AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(3)); + AddTLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(4)); + AddTLinkNode(e->GetNode(2),e->GetNode(0),e->GetNode(5)); break; + case 8: + AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(4)); + AddTLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(5)); + AddTLinkNode(e->GetNode(2),e->GetNode(3),e->GetNode(6)); + AddTLinkNode(e->GetNode(3),e->GetNode(0),e->GetNode(7)); + break; + default: + myCreateQuadratic = false; + break; + } + } } } } } } + if ( nbOldLinks == myTLinkNodeMap.size() ) + myCreateQuadratic = false; + if(!myCreateQuadratic) { - myNLinkNodeMap.clear(); + myTLinkNodeMap.clear(); } SetSubShape( aSh ); return myCreateQuadratic; } -//================================================================================ -/*! - * \brief Set geomerty to make elements on - * \param aSh - geomertic shape - */ -//================================================================================ +//======================================================================= +//function : SetSubShape +//purpose : Set geomerty to make elements on +//======================================================================= void SMESH_MesherHelper::SetSubShape(const int aShID) { if ( aShID == myShapeID ) return; - if ( aShID > 1 ) + if ( aShID > 0 ) SetSubShape( GetMeshDS()->IndexToShape( aShID )); else SetSubShape( TopoDS_Shape() ); } -//================================================================================ -/*! - * \brief Set geomerty to make elements on - * \param aSh - geomertic shape - */ -//================================================================================ +//======================================================================= +//function : SetSubShape +//purpose : Set geomerty to create elements on +//======================================================================= void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) { @@ -157,39 +223,45 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) myDegenShapeIds.clear(); if ( myShape.IsNull() ) { - myShapeID = -1; + myShapeID = 0; return; } SMESHDS_Mesh* meshDS = GetMeshDS(); myShapeID = meshDS->ShapeToIndex(aSh); + myParIndex = 0; // treatment of periodic faces for ( TopExp_Explorer eF( aSh, TopAbs_FACE ); eF.More(); eF.Next() ) { const TopoDS_Face& face = TopoDS::Face( eF.Current() ); - BRepAdaptor_Surface surface( face ); - if ( surface.IsUPeriodic() || surface.IsVPeriodic() ) + TopLoc_Location loc; + Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc ); + + if ( surface->IsUPeriodic() || surface->IsVPeriodic() || + surface->IsUClosed() || surface->IsVClosed() ) { + //while ( surface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface ))) + //surface = Handle(Geom_RectangularTrimmedSurface)::DownCast( surface )->BasisSurface(); + GeomAdaptor_Surface surf( surface ); + for (TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next()) { // look for a seam edge const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); if ( BRep_Tool::IsClosed( edge, face )) { // initialize myPar1, myPar2 and myParIndex - if ( mySeamShapeIds.empty() ) { - gp_Pnt2d uv1, uv2; - BRep_Tool::UVPoints( edge, face, uv1, uv2 ); - if ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Abs( uv1.Coord(2) - uv2.Coord(2) )) - { - myParIndex = 1; // U periodic - myPar1 = surface.FirstUParameter(); - myPar2 = surface.LastUParameter(); - } - else { - myParIndex = 2; // V periodic - myPar1 = surface.FirstVParameter(); - myPar2 = surface.LastVParameter(); - } + gp_Pnt2d uv1, uv2; + BRep_Tool::UVPoints( edge, face, uv1, uv2 ); + if ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Abs( uv1.Coord(2) - uv2.Coord(2) )) + { + myParIndex |= U_periodic; + myPar1[0] = surf.FirstUParameter(); + myPar2[0] = surf.LastUParameter(); + } + else { + myParIndex |= V_periodic; + myPar1[1] = surf.FirstVParameter(); + myPar2[1] = surf.LastVParameter(); } // store seam shape indices, negative if shape encounters twice int edgeID = meshDS->ShapeToIndex( edge ); @@ -211,13 +283,13 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) } } -//================================================================================ - /*! - * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..) - * \param F - the face - * \retval bool - return true if the face is periodic - */ -//================================================================================ +//======================================================================= +//function : GetNodeUVneedInFaceNode +//purpose : Check if inFaceNode argument is necessary for call GetNodeUV(F,..) +// Return true if the face is periodic. +// If F is Null, answer about sub-shape set through IsQuadraticSubMesh() or +// * SetSubShape() +//======================================================================= bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const { @@ -226,7 +298,8 @@ bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const if ( !F.IsNull() && !myShape.IsNull() && myShape.IsSame( F )) return !mySeamShapeIds.empty(); - Handle(Geom_Surface) aSurface = BRep_Tool::Surface( F ); + TopLoc_Location loc; + Handle(Geom_Surface) aSurface = BRep_Tool::Surface( F,loc ); if ( !aSurface.IsNull() ) return ( aSurface->IsUPeriodic() || aSurface->IsVPeriodic() ); @@ -239,125 +312,273 @@ bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const //======================================================================= bool SMESH_MesherHelper::IsMedium(const SMDS_MeshNode* node, - const SMDSAbs_ElementType typeToCheck) + const SMDSAbs_ElementType typeToCheck) { return SMESH_MeshEditor::IsMedium( node, typeToCheck ); } //======================================================================= -//function : AddNLinkNode -//purpose : +//function : GetSubShapeByNode +//purpose : Return support shape of a node +//======================================================================= + +TopoDS_Shape SMESH_MesherHelper::GetSubShapeByNode(const SMDS_MeshNode* node, + const SMESHDS_Mesh* meshDS) +{ + int shapeID = node->getshapeId(); + if ( 0 < shapeID && shapeID <= meshDS->MaxShapeIndex() ) + return meshDS->IndexToShape( shapeID ); + else + return TopoDS_Shape(); +} + + +//======================================================================= +//function : AddTLinkNode +//purpose : add a link in my data structure //======================================================================= + +void SMESH_MesherHelper::AddTLinkNode(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + // add new record to map + SMESH_TLink link( n1, n2 ); + myTLinkNodeMap.insert( make_pair(link,n12)); +} + +//================================================================================ /*! - * Auxilary function for filling myNLinkNodeMap + * \brief Add quadratic links of edge to own data structure */ -void SMESH_MesherHelper::AddNLinkNode(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const SMDS_MeshNode* n12) +//================================================================================ + +void SMESH_MesherHelper::AddTLinks(const SMDS_MeshEdge* edge) { - NLink link( n1, n2 ); - if ( n1 > n2 ) link = NLink( n2, n1 ); - // add new record to map - myNLinkNodeMap.insert( make_pair(link,n12)); + if ( edge->IsQuadratic() ) + AddTLinkNode(edge->GetNode(0), edge->GetNode(1), edge->GetNode(2)); } -//======================================================================= +//================================================================================ +/*! + * \brief Add quadratic links of face to own data structure + */ +//================================================================================ + +void SMESH_MesherHelper::AddTLinks(const SMDS_MeshFace* f) +{ + if ( !f->IsPoly() ) + switch ( f->NbNodes() ) { + case 6: + AddTLinkNode(f->GetNode(0),f->GetNode(1),f->GetNode(3)); + AddTLinkNode(f->GetNode(1),f->GetNode(2),f->GetNode(4)); + AddTLinkNode(f->GetNode(2),f->GetNode(0),f->GetNode(5)); break; + case 8: + AddTLinkNode(f->GetNode(0),f->GetNode(1),f->GetNode(4)); + AddTLinkNode(f->GetNode(1),f->GetNode(2),f->GetNode(5)); + AddTLinkNode(f->GetNode(2),f->GetNode(3),f->GetNode(6)); + AddTLinkNode(f->GetNode(3),f->GetNode(0),f->GetNode(7)); + default:; + } +} + +//================================================================================ +/*! + * \brief Add quadratic links of volume to own data structure + */ +//================================================================================ + +void SMESH_MesherHelper::AddTLinks(const SMDS_MeshVolume* volume) +{ + if ( volume->IsQuadratic() ) + { + SMDS_VolumeTool vTool( volume ); + const SMDS_MeshNode** nodes = vTool.GetNodes(); + set addedLinks; + for ( int iF = 1; iF < vTool.NbFaces(); ++iF ) + { + const int nbN = vTool.NbFaceNodes( iF ); + const int* iNodes = vTool.GetFaceNodesIndices( iF ); + for ( int i = 0; i < nbN; ) + { + int iN1 = iNodes[i++]; + int iN12 = iNodes[i++]; + int iN2 = iNodes[i++]; + if ( iN1 > iN2 ) std::swap( iN1, iN2 ); + int linkID = iN1 * vTool.NbNodes() + iN2; + pair< set::iterator, bool > it_isNew = addedLinks.insert( linkID ); + if ( it_isNew.second ) + AddTLinkNode( nodes[iN1], nodes[iN2], nodes[iN12] ); + else + addedLinks.erase( it_isNew.first ); // each link encounters only twice + } + } + } +} + +//================================================================================ +/*! + * \brief Return true if position of nodes on the shape hasn't yet been checked or + * the positions proved to be invalid + */ +//================================================================================ + +bool SMESH_MesherHelper::toCheckPosOnShape(int shapeID ) const +{ + map< int,bool >::const_iterator id_ok = myNodePosShapesValidity.find( shapeID ); + return ( id_ok == myNodePosShapesValidity.end() || !id_ok->second ); +} + +//================================================================================ /*! - * \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV - * \param uv1 - UV on the seam - * \param uv2 - UV within a face - * \retval gp_Pnt2d - selected UV + * \brief Set validity of positions of nodes on the shape. + * Once set, validity is not changed */ +//================================================================================ + +void SMESH_MesherHelper::setPosOnShapeValidity(int shapeID, bool ok ) const +{ + ((SMESH_MesherHelper*)this)->myNodePosShapesValidity.insert( make_pair( shapeID, ok)); +} + +//======================================================================= +//function : ToFixNodeParameters +//purpose : Enables fixing node parameters on EDGEs and FACEs in +// GetNodeU(...,check=true), GetNodeUV(...,check=true), CheckNodeUV() and +// CheckNodeU() in case if a node lies on a shape set via SetSubShape(). +// Default is False +//======================================================================= + +void SMESH_MesherHelper::ToFixNodeParameters(bool toFix) +{ + myFixNodeParameters = toFix; +} + + +//======================================================================= +//function : GetUVOnSeam +//purpose : Select UV on either of 2 pcurves of a seam edge, closest to the given UV //======================================================================= gp_Pnt2d SMESH_MesherHelper::GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const { - double p1 = uv1.Coord( myParIndex ); - double p2 = uv2.Coord( myParIndex ); - double p3 = ( Abs( p1 - myPar1 ) < Abs( p1 - myPar2 )) ? myPar2 : myPar1; - if ( Abs( p2 - p1 ) > Abs( p2 - p3 )) - p1 = p3; gp_Pnt2d result = uv1; - result.SetCoord( myParIndex, p1 ); + for ( int i = U_periodic; i <= V_periodic ; ++i ) + { + if ( myParIndex & i ) + { + double p1 = uv1.Coord( i ); + double dp1 = Abs( p1-myPar1[i-1]), dp2 = Abs( p1-myPar2[i-1]); + if ( myParIndex == i || + dp1 < ( myPar2[i-1] - myPar2[i-1] ) / 100. || + dp2 < ( myPar2[i-1] - myPar2[i-1] ) / 100. ) + { + double p2 = uv2.Coord( i ); + double p1Alt = ( dp1 < dp2 ) ? myPar2[i-1] : myPar1[i-1]; + if ( Abs( p2 - p1 ) > Abs( p2 - p1Alt )) + result.SetCoord( i, p1Alt ); + } + } + } return result; } //======================================================================= -/*! - * \brief Return node UV on face - * \param F - the face - * \param n - the node - * \param n2 - a node of element being created located inside a face - * \retval gp_XY - resulting UV - * - * Auxilary function called form GetMediumNode() - */ +//function : GetNodeUV +//purpose : Return node UV on face //======================================================================= gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, const SMDS_MeshNode* n, - const SMDS_MeshNode* n2) const + const SMDS_MeshNode* n2, + bool* check) const { - gp_Pnt2d uv( 1e100, 1e100 ); + gp_Pnt2d uv( Precision::Infinite(), Precision::Infinite() ); const SMDS_PositionPtr Pos = n->GetPosition(); + bool uvOK = false; if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE) { // node has position on face const SMDS_FacePosition* fpos = - static_cast(n->GetPosition().get()); - uv = gp_Pnt2d(fpos->GetUParameter(),fpos->GetVParameter()); + static_cast(n->GetPosition()); + uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter()); + if ( check ) + uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F )); } else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) { // node has position on edge => it is needed to find // corresponding edge from face, get pcurve for this - // edge and recieve value from this pcurve + // edge and retrieve value from this pcurve const SMDS_EdgePosition* epos = - static_cast(n->GetPosition().get()); - SMESHDS_Mesh* meshDS = GetMeshDS(); - int edgeID = Pos->GetShapeId(); - TopoDS_Edge E = TopoDS::Edge(meshDS->IndexToShape(edgeID)); - double f, l; + static_cast(n->GetPosition()); + int edgeID = n->getshapeId(); + TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID)); + double f, l, u = epos->GetUParameter(); Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l); - uv = C2d->Value( epos->GetUParameter() ); + bool validU = ( f < u && u < l ); + if ( validU ) + uv = C2d->Value( u ); + else + uv.SetCoord( Precision::Infinite(),0.); + if ( check || !validU ) + uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ),/*force=*/ !validU ); + // for a node on a seam edge select one of UVs on 2 pcurves if ( n2 && IsSeamShape( edgeID ) ) - uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 )); + { + uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0, check )); + } + else + { // adjust uv to period + TopLoc_Location loc; + Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc); + Standard_Boolean isUPeriodic = S->IsUPeriodic(); + Standard_Boolean isVPeriodic = S->IsVPeriodic(); + if ( isUPeriodic || isVPeriodic ) { + Standard_Real UF,UL,VF,VL; + S->Bounds(UF,UL,VF,VL); + if(isUPeriodic) + uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL)); + if(isVPeriodic) + uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL)); + } + } } else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) { - if ( int vertexID = n->GetPosition()->GetShapeId() ) { - bool ok = true; + if ( int vertexID = n->getshapeId() ) { const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID)); try { uv = BRep_Tool::Parameters( V, F ); + uvOK = true; } catch (Standard_Failure& exc) { - ok = false; } - if ( !ok ) { - for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() ) - ok = ( V == vert.Current() ); - if ( !ok ) { + if ( !uvOK ) { + for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) + uvOK = ( V == vert.Current() ); + if ( !uvOK ) { #ifdef _DEBUG_ MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID << " not in face " << GetMeshDS()->ShapeToIndex( F ) ); #endif // get UV of a vertex closest to the node double dist = 1e100; - gp_Pnt pn ( n->X(),n->Y(),n->Z() ); - for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() ) { + gp_Pnt pn = XYZ( n ); + for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) { TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() ); gp_Pnt p = BRep_Tool::Pnt( curV ); double curDist = p.SquareDistance( pn ); if ( curDist < dist ) { dist = curDist; uv = BRep_Tool::Parameters( curV, F ); - if ( dist < DBL_MIN ) break; + uvOK = ( dist < DBL_MIN ); } } } else { + uvOK = false; TopTools_ListIteratorOfListOfShape it( myMesh->GetAncestors( V )); for ( ; it.More(); it.Next() ) { if ( it.Value().ShapeType() == TopAbs_EDGE ) { @@ -367,6 +588,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, if ( !C2d.IsNull() ) { double u = ( V == TopExp::FirstVertex( edge ) ) ? f : l; uv = C2d->Value( u ); + uvOK = true; break; } } @@ -377,269 +599,694 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 )); } } - return uv.XY(); -} + else + { + uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F )); + } -//======================================================================= -/*! - * \brief Return node U on edge - * \param E - the Edge - * \param n - the node - * \retval double - resulting U - * - * Auxilary function called form GetMediumNode() - */ -//======================================================================= + if ( check ) + *check = uvOK; -double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, - const SMDS_MeshNode* n) -{ - double param = 0; - const SMDS_PositionPtr Pos = n->GetPosition(); - if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) { - const SMDS_EdgePosition* epos = - static_cast(n->GetPosition().get()); - param = epos->GetUParameter(); - } - else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) { - SMESHDS_Mesh * meshDS = GetMeshDS(); - int vertexID = n->GetPosition()->GetShapeId(); - const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID)); - param = BRep_Tool::Parameter( V, E ); - } - return param; + return uv.XY(); } //======================================================================= -//function : GetMediumNode -//purpose : +//function : CheckNodeUV +//purpose : Check and fix node UV on a face //======================================================================= -/*! - * Special function for search or creation medium node - */ -const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - bool force3d) -{ - TopAbs_ShapeEnum shapeType = myShape.IsNull() ? TopAbs_SHAPE : myShape.ShapeType(); - NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 )); - ItNLinkNode itLN = myNLinkNodeMap.find( link ); - if ( itLN != myNLinkNodeMap.end() ) { - return (*itLN).second; - } - else { - // create medium node - SMDS_MeshNode* n12; - SMESHDS_Mesh* meshDS = GetMeshDS(); - int faceID = -1, edgeID = -1; - const SMDS_PositionPtr Pos1 = n1->GetPosition(); - const SMDS_PositionPtr Pos2 = n2->GetPosition(); - - if( myShape.IsNull() ) +bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F, + const SMDS_MeshNode* n, + gp_XY& uv, + const double tol, + const bool force, + double distXYZ[4]) const +{ + int shapeID = n->getshapeId(); + bool infinit = ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() )); + if ( force || toCheckPosOnShape( shapeID ) || infinit ) + { + // check that uv is correct + TopLoc_Location loc; + Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc ); + gp_Pnt nodePnt = XYZ( n ), surfPnt(0,0,0); + double dist = 0; + if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() ); + if ( infinit || + (dist = nodePnt.Distance( surfPnt = surface->Value( uv.X(), uv.Y() ))) > tol ) { - if( Pos1->GetTypeOfPosition()==SMDS_TOP_FACE ) { - faceID = Pos1->GetShapeId(); + setPosOnShapeValidity( shapeID, false ); + if ( !infinit && distXYZ ) { + surfPnt.Transform( loc ); + distXYZ[0] = dist; + distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z(); } - else if( Pos2->GetTypeOfPosition()==SMDS_TOP_FACE ) { - faceID = Pos2->GetShapeId(); + // uv incorrect, project the node to surface + GeomAPI_ProjectPointOnSurf& projector = GetProjector( F, loc, tol ); + projector.Perform( nodePnt ); + if ( !projector.IsDone() || projector.NbPoints() < 1 ) + { + MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" ); + return false; } - - if( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - edgeID = Pos1->GetShapeId(); + Quantity_Parameter U,V; + projector.LowerDistanceParameters(U,V); + uv.SetCoord( U,V ); + surfPnt = surface->Value( U, V ); + dist = nodePnt.Distance( surfPnt ); + if ( distXYZ ) { + surfPnt.Transform( loc ); + distXYZ[0] = dist; + distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z(); } - if( Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE ) { - edgeID = Pos2->GetShapeId(); + if ( dist > tol ) + { + MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" ); + return false; } + // store the fixed UV on the face + if ( myShape.IsSame(F) && shapeID == myShapeID && myFixNodeParameters ) + const_cast(n)->SetPosition + ( SMDS_PositionPtr( new SMDS_FacePosition( U, V ))); } - - if(!force3d) { - // we try to create medium node using UV parameters of - // nodes, else - medium between corresponding 3d points - if(faceID>-1 || shapeType == TopAbs_FACE) { - // obtaining a face and 2d points for nodes - TopoDS_Face F; - if( myShape.IsNull() ) - F = TopoDS::Face(meshDS->IndexToShape(faceID)); - else { - F = TopoDS::Face(myShape); - faceID = myShapeID; - } - - gp_XY p1 = GetNodeUV(F,n1,n2); - gp_XY p2 = GetNodeUV(F,n2,n1); - - if ( IsDegenShape( Pos1->GetShapeId() )) - p1.SetCoord( myParIndex, p2.Coord( myParIndex )); - else if ( IsDegenShape( Pos2->GetShapeId() )) - p2.SetCoord( myParIndex, p1.Coord( myParIndex )); - - //checking if surface is periodic - Handle(Geom_Surface) S = BRep_Tool::Surface(F); - Standard_Real UF,UL,VF,VL; - S->Bounds(UF,UL,VF,VL); - - Standard_Real u,v; - Standard_Boolean isUPeriodic = S->IsUPeriodic(); - if(isUPeriodic) { - Standard_Real UPeriod = S->UPeriod(); - Standard_Real p2x = p2.X()+ShapeAnalysis::AdjustByPeriod(p2.X(),p1.X(),UPeriod); - Standard_Real pmid = (p1.X()+p2x)/2.; - u = pmid+ShapeAnalysis::AdjustToPeriod(pmid,UF,UL); - } - else - u= (p1.X()+p2.X())/2.; - - Standard_Boolean isVPeriodic = S->IsVPeriodic(); - if(isVPeriodic) { - Standard_Real VPeriod = S->VPeriod(); - Standard_Real p2y = p2.Y()+ShapeAnalysis::AdjustByPeriod(p2.Y(),p1.Y(),VPeriod); - Standard_Real pmid = (p1.Y()+p2y)/2.; - v = pmid+ShapeAnalysis::AdjustToPeriod(pmid,VF,VL); - } - else - v = (p1.Y()+p2.Y())/2.; - - gp_Pnt P = S->Value(u, v); - n12 = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnFace(n12, faceID, u, v); - myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12)); - return n12; - } - if (edgeID>-1 || shapeType == TopAbs_EDGE) { - - TopoDS_Edge E; - if( myShape.IsNull() ) - E = TopoDS::Edge(meshDS->IndexToShape(edgeID)); - else { - E = TopoDS::Edge(myShape); - edgeID = myShapeID; - } - - double p1 = GetNodeU(E,n1); - double p2 = GetNodeU(E,n2); - - double f,l; - Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l); - if(!C.IsNull()) { - - Standard_Boolean isPeriodic = C->IsPeriodic(); - double u; - if(isPeriodic) { - Standard_Real Period = C->Period(); - Standard_Real p = p2+ShapeAnalysis::AdjustByPeriod(p2,p1,Period); - Standard_Real pmid = (p1+p)/2.; - u = pmid+ShapeAnalysis::AdjustToPeriod(pmid,C->FirstParameter(),C->LastParameter()); - } - else - u = (p1+p2)/2.; - - gp_Pnt P = C->Value( u ); - n12 = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnEdge(n12, edgeID, u); - myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12)); - return n12; - } - } + else if ( uv.Modulus() > numeric_limits::min() ) + { + setPosOnShapeValidity( shapeID, true ); } - // 3d variant - double x = ( n1->X() + n2->X() )/2.; - double y = ( n1->Y() + n2->Y() )/2.; - double z = ( n1->Z() + n2->Z() )/2.; - n12 = meshDS->AddNode(x,y,z); - if(edgeID>-1) - meshDS->SetNodeOnEdge(n12, edgeID); - else if(faceID>-1) - meshDS->SetNodeOnFace(n12, faceID); - else - meshDS->SetNodeInVolume(n12, myShapeID); - myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12)); - return n12; } + return true; } //======================================================================= -/*! - * Creates a node - */ +//function : GetProjector +//purpose : Return projector intitialized by given face without location, which is returned //======================================================================= -SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID) +GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& F, + TopLoc_Location& loc, + double tol ) const { - 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: ; - } + Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc ); + int faceID = GetMeshDS()->ShapeToIndex( F ); + TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector ); + TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID ); + if ( i_proj == i2proj.end() ) + { + if ( tol == 0 ) tol = BRep_Tool::Tolerance( F ); + double U1, U2, V1, V2; + surface->Bounds(U1, U2, V1, V2); + GeomAPI_ProjectPointOnSurf* proj = new GeomAPI_ProjectPointOnSurf(); + proj->Init( surface, U1, U2, V1, V2, tol ); + i_proj = i2proj.insert( make_pair( faceID, proj )).first; } - return node; + return *( i_proj->second ); +} + +namespace +{ + gp_XY AverageUV(const gp_XY& uv1, const gp_XY& uv2) { return ( uv1 + uv2 ) / 2.; } + gp_XY_FunPtr(Added); // define gp_XY_Added pointer to function calling gp_XY::Added(gp_XY) + gp_XY_FunPtr(Subtracted); } //======================================================================= -/*! - * Creates quadratic or linear edge - */ +//function : applyIn2D +//purpose : Perform given operation on two 2d points in parameric space of given surface. +// It takes into account period of the surface. Use gp_XY_FunPtr macro +// to easily define pointer to function of gp_XY class. //======================================================================= -SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const int id, - const bool force3d) +gp_XY SMESH_MesherHelper::applyIn2D(const Handle(Geom_Surface)& surface, + const gp_XY& uv1, + const gp_XY& uv2, + xyFunPtr fun, + const bool resultInPeriod) { - SMESHDS_Mesh * meshDS = GetMeshDS(); - - 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); + Standard_Boolean isUPeriodic = surface.IsNull() ? false : surface->IsUPeriodic(); + Standard_Boolean isVPeriodic = surface.IsNull() ? false : surface->IsVPeriodic(); + if ( !isUPeriodic && !isVPeriodic ) + return fun(uv1,uv2); + + // move uv2 not far than half-period from uv1 + double u2 = + uv2.X()+(isUPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.X(),uv1.X(),surface->UPeriod()) :0); + double v2 = + uv2.Y()+(isVPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.Y(),uv1.Y(),surface->VPeriod()) :0); + + // execute operation + gp_XY res = fun( uv1, gp_XY(u2,v2) ); + + // move result within period + if ( resultInPeriod ) + { + Standard_Real UF,UL,VF,VL; + surface->Bounds(UF,UL,VF,VL); + if ( isUPeriodic ) + res.SetX( res.X() + ShapeAnalysis::AdjustToPeriod(res.X(),UF,UL)); + if ( isVPeriodic ) + res.SetY( res.Y() + ShapeAnalysis::AdjustToPeriod(res.Y(),VF,VL)); } - if ( mySetElemOnShape && myShapeID > 0 ) - meshDS->SetMeshElementOnShape( edge, myShapeID ); + return res; +} +//======================================================================= +//function : GetMiddleUV +//purpose : Return middle UV taking in account surface period +//======================================================================= - return edge; +gp_XY SMESH_MesherHelper::GetMiddleUV(const Handle(Geom_Surface)& surface, + const gp_XY& p1, + const gp_XY& p2) +{ + // NOTE: + // the proper place of getting basic surface seems to be in applyIn2D() + // but we put it here to decrease a risk of regressions just before releasing a version + Handle(Geom_Surface) surf = surface; + while ( !surf.IsNull() && surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface ))) + surf = Handle(Geom_RectangularTrimmedSurface)::DownCast( surf )->BasisSurface(); + + return applyIn2D( surf, p1, p2, & AverageUV ); } //======================================================================= -/*! - * Creates quadratic or linear triangle - */ +//function : GetNodeU +//purpose : Return node U on edge //======================================================================= -SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const SMDS_MeshNode* n3, - const int id, - const bool force3d) +double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, + const SMDS_MeshNode* n, + const SMDS_MeshNode* inEdgeNode, + bool* check) { - SMESHDS_Mesh * meshDS = GetMeshDS(); - SMDS_MeshFace* elem = 0; - if(!myCreateQuadratic) { - if(id) - elem = meshDS->AddFaceWithID(n1, n2, n3, id); - else - elem = meshDS->AddFace(n1, n2, n3); - } - else { + double param = 0; + const SMDS_PositionPtr pos = n->GetPosition(); + if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) + { + const SMDS_EdgePosition* epos = static_cast( pos ); + param = epos->GetUParameter(); + } + else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + { + if ( inEdgeNode && TopExp::FirstVertex( E ).IsSame( TopExp::LastVertex( E ))) // issue 0020128 + { + Standard_Real f,l; + BRep_Tool::Range( E, f,l ); + double uInEdge = GetNodeU( E, inEdgeNode ); + param = ( fabs( uInEdge - f ) < fabs( l - uInEdge )) ? f : l; + } + else + { + SMESHDS_Mesh * meshDS = GetMeshDS(); + int vertexID = n->getshapeId(); + const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID)); + param = BRep_Tool::Parameter( V, E ); + } + } + if ( check ) + { + double tol = BRep_Tool::Tolerance( E ); + double f,l; BRep_Tool::Range( E, f,l ); + bool force = ( param < f-tol || param > l+tol ); + if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) + force = ( GetMeshDS()->ShapeToIndex( E ) != n->getshapeId() ); + + *check = CheckNodeU( E, n, param, 2*tol, force ); + } + return param; +} + +//======================================================================= +//function : CheckNodeU +//purpose : Check and fix node U on an edge +// Return false if U is bad and could not be fixed +//======================================================================= + +bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, + const SMDS_MeshNode* n, + double& u, + const double tol, + const bool force, + double distXYZ[4]) const +{ + int shapeID = n->getshapeId(); + if ( force || toCheckPosOnShape( shapeID )) + { + TopLoc_Location loc; double f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l ); + if ( curve.IsNull() ) // degenerated edge + { + if ( u+tol < f || u-tol > l ) + { + double r = Max( 0.5, 1 - tol*n->GetID()); // to get a unique u on edge + u = f*r + l*(1-r); + } + } + else + { + gp_Pnt nodePnt = SMESH_TNodeXYZ( n ); + if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() ); + gp_Pnt curvPnt = curve->Value( u ); + double dist = nodePnt.Distance( curvPnt ); + if ( distXYZ ) { + curvPnt.Transform( loc ); + distXYZ[0] = dist; + distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z(); + } + if ( dist > tol ) + { + setPosOnShapeValidity( shapeID, false ); + // u incorrect, project the node to the curve + int edgeID = GetMeshDS()->ShapeToIndex( E ); + TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector ); + TID2ProjectorOnCurve::iterator i_proj = + i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first; + if ( !i_proj->second ) + { + i_proj->second = new GeomAPI_ProjectPointOnCurve(); + i_proj->second->Init( curve, f, l ); + } + GeomAPI_ProjectPointOnCurve* projector = i_proj->second; + projector->Perform( nodePnt ); + if ( projector->NbPoints() < 1 ) + { + MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" ); + return false; + } + Quantity_Parameter U = projector->LowerDistanceParameter(); + u = double( U ); + curvPnt = curve->Value( u ); + dist = nodePnt.Distance( curvPnt ); + if ( distXYZ ) { + curvPnt.Transform( loc ); + distXYZ[0] = dist; + distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z(); + } + if ( dist > tol ) + { + MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" ); + MESSAGE("distance " << dist << " " << tol ); + return false; + } + // store the fixed U on the edge + if ( myShape.IsSame(E) && shapeID == myShapeID && myFixNodeParameters ) + const_cast(n)->SetPosition + ( SMDS_PositionPtr( new SMDS_EdgePosition( U ))); + } + else if ( fabs( u ) > numeric_limits::min() ) + { + setPosOnShapeValidity( shapeID, true ); + } + if (( u < f-tol || u > l+tol ) && force ) + { + // node is on vertex but is set on periodic but trimmed edge (issue 0020890) + try + { + // do not use IsPeriodic() as Geom_TrimmedCurve::IsPeriodic () returns false + double period = curve->Period(); + u = ( u < f ) ? u + period : u - period; + } + catch (Standard_Failure& exc) + { + return false; + } + } + } + } + return true; +} + +//======================================================================= +//function : GetMediumPos +//purpose : Return index and type of the shape (EDGE or FACE only) to +// set a medium node on +//======================================================================= + +std::pair SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2) +{ + TopAbs_ShapeEnum shapeType = TopAbs_SHAPE; + int shapeID = -1; + TopoDS_Shape shape; + + if (( myShapeID == n1->getshapeId() || myShapeID == n2->getshapeId() ) && myShapeID > 0 ) + { + shapeType = myShape.ShapeType(); + shapeID = myShapeID; + } + else if ( n1->getshapeId() == n2->getshapeId() ) + { + shapeID = n2->getshapeId(); + shape = GetSubShapeByNode( n1, GetMeshDS() ); + } + else + { + const SMDS_TypeOfPosition Pos1 = n1->GetPosition()->GetTypeOfPosition(); + const SMDS_TypeOfPosition Pos2 = n2->GetPosition()->GetTypeOfPosition(); + + if ( Pos1 == SMDS_TOP_3DSPACE || Pos2 == SMDS_TOP_3DSPACE ) + { + } + else if ( Pos1 == SMDS_TOP_FACE || Pos2 == SMDS_TOP_FACE ) + { + if ( Pos1 != SMDS_TOP_FACE || Pos2 != SMDS_TOP_FACE ) + { + if ( Pos1 != SMDS_TOP_FACE ) std::swap( n1,n2 ); + TopoDS_Shape F = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape S = GetSubShapeByNode( n2, GetMeshDS() ); + if ( IsSubShape( S, F )) + { + shapeType = TopAbs_FACE; + shapeID = n1->getshapeId(); + } + } + } + else if ( Pos1 == SMDS_TOP_EDGE && Pos2 == SMDS_TOP_EDGE ) + { + TopoDS_Shape E1 = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape E2 = GetSubShapeByNode( n2, GetMeshDS() ); + shape = GetCommonAncestor( E1, E2, *myMesh, TopAbs_FACE ); + } + else if ( Pos1 == SMDS_TOP_VERTEX && Pos2 == SMDS_TOP_VERTEX ) + { + TopoDS_Shape V1 = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape V2 = GetSubShapeByNode( n2, GetMeshDS() ); + shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_EDGE ); + if ( shape.IsNull() ) shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_FACE ); + } + else // VERTEX and EDGE + { + if ( Pos1 != SMDS_TOP_VERTEX ) std::swap( n1,n2 ); + TopoDS_Shape V = GetSubShapeByNode( n1, GetMeshDS() ); + TopoDS_Shape E = GetSubShapeByNode( n2, GetMeshDS() ); + if ( IsSubShape( V, E )) + shape = E; + else + shape = GetCommonAncestor( V, E, *myMesh, TopAbs_FACE ); + } + } + + if ( !shape.IsNull() ) + { + if ( shapeID < 1 ) + shapeID = GetMeshDS()->ShapeToIndex( shape ); + shapeType = shape.ShapeType(); + } + return make_pair( shapeID, shapeType ); +} + +//======================================================================= +//function : GetMediumNode +//purpose : Return existing or create new medium nodes between given ones +//======================================================================= + +const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + bool force3d) +{ + // Find existing node + + SMESH_TLink link(n1,n2); + ItTLinkNode itLN = myTLinkNodeMap.find( link ); + if ( itLN != myTLinkNodeMap.end() ) { + return (*itLN).second; + } + + // Create medium node + + SMDS_MeshNode* n12; + SMESHDS_Mesh* meshDS = GetMeshDS(); + + if ( IsSeamShape( n1->getshapeId() )) + // to get a correct UV of a node on seam, the second node must have checked UV + std::swap( n1, n2 ); + + // get type of shape for the new medium node + int faceID = -1, edgeID = -1; + TopoDS_Edge E; double u [2]; + TopoDS_Face F; gp_XY uv[2]; + bool uvOK[2] = { false, false }; + + pair pos = GetMediumPos( n1, n2 ); + + // get positions of the given nodes on shapes + if ( pos.second == TopAbs_FACE ) + { + F = TopoDS::Face(meshDS->IndexToShape( faceID = pos.first )); + uv[0] = GetNodeUV(F,n1,n2, force3d ? 0 : &uvOK[0]); + uv[1] = GetNodeUV(F,n2,n1, force3d ? 0 : &uvOK[1]); + } + else if ( pos.second == TopAbs_EDGE ) + { + const SMDS_PositionPtr Pos1 = n1->GetPosition(); + const SMDS_PositionPtr Pos2 = n2->GetPosition(); + if ( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE && + Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE && + n1->getshapeId() != n2->getshapeId() ) + { + // issue 0021006 + return getMediumNodeOnComposedWire(n1,n2,force3d); + } + E = TopoDS::Edge(meshDS->IndexToShape( edgeID = pos.first )); + u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]); + u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]); + } + + if ( !force3d & uvOK[0] && uvOK[1] ) + { + // we try to create medium node using UV parameters of + // nodes, else - medium between corresponding 3d points + if( ! F.IsNull() ) + { + //if ( uvOK[0] && uvOK[1] ) + { + if ( IsDegenShape( n1->getshapeId() )) { + if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 )); + else uv[0].SetCoord( 2, uv[1].Coord( 2 )); + } + else if ( IsDegenShape( n2->getshapeId() )) { + if ( myParIndex & U_periodic ) uv[1].SetCoord( 1, uv[0].Coord( 1 )); + else uv[1].SetCoord( 2, uv[0].Coord( 2 )); + } + + TopLoc_Location loc; + Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc); + gp_XY UV = GetMiddleUV( S, uv[0], uv[1] ); + gp_Pnt P = S->Value( UV.X(), UV.Y() ).Transformed(loc); + n12 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y()); + myTLinkNodeMap.insert(make_pair(link,n12)); + return n12; + } + } + else if ( !E.IsNull() ) + { + double f,l; + Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l); + if(!C.IsNull()) + { + Standard_Boolean isPeriodic = C->IsPeriodic(); + double U; + if(isPeriodic) { + Standard_Real Period = C->Period(); + Standard_Real p = u[1]+ShapeAnalysis::AdjustByPeriod(u[1],u[0],Period); + Standard_Real pmid = (u[0]+p)/2.; + U = pmid+ShapeAnalysis::AdjustToPeriod(pmid,C->FirstParameter(),C->LastParameter()); + } + else + U = (u[0]+u[1])/2.; + + gp_Pnt P = C->Value( U ); + n12 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnEdge(n12, edgeID, U); + myTLinkNodeMap.insert(make_pair(link,n12)); + return n12; + } + } + } + + // 3d variant + double x = ( n1->X() + n2->X() )/2.; + double y = ( n1->Y() + n2->Y() )/2.; + double z = ( n1->Z() + n2->Z() )/2.; + n12 = meshDS->AddNode(x,y,z); + + if ( !F.IsNull() ) + { + gp_XY UV = ( uv[0] + uv[1] ) / 2.; + CheckNodeUV( F, n12, UV, 2*BRep_Tool::Tolerance( F ), /*force=*/true); + meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y() ); + } + else if ( !E.IsNull() ) + { + double U = ( u[0] + u[1] ) / 2.; + CheckNodeU( E, n12, U, 2*BRep_Tool::Tolerance( E ), /*force=*/true); + meshDS->SetNodeOnEdge(n12, edgeID, U); + } + else if ( myShapeID > 0 ) + { + meshDS->SetNodeInVolume(n12, myShapeID); + } + + myTLinkNodeMap.insert( make_pair( link, n12 )); + return n12; +} + +//================================================================================ +/*! + * \brief Makes a medium node if nodes reside different edges + */ +//================================================================================ + +const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + bool force3d) +{ + gp_Pnt middle = 0.5 * XYZ(n1) + 0.5 * XYZ(n2); + SMDS_MeshNode* n12 = AddNode( middle.X(), middle.Y(), middle.Z() ); + + // To find position on edge and 3D position for n12, + // project to 2 edges and select projection most close to + + double u = 0, distMiddleProj = Precision::Infinite(), distXYZ[4]; + int iOkEdge = 0; + TopoDS_Edge edges[2]; + for ( int is2nd = 0; is2nd < 2; ++is2nd ) + { + // get an edge + const SMDS_MeshNode* n = is2nd ? n2 : n1; + TopoDS_Shape shape = GetSubShapeByNode( n, GetMeshDS() ); + if ( shape.IsNull() || shape.ShapeType() != TopAbs_EDGE ) + continue; + + // project to get U of projection and distance from middle to projection + TopoDS_Edge edge = edges[ is2nd ] = TopoDS::Edge( shape ); + double node2MiddleDist = middle.Distance( XYZ(n) ); + double foundU = GetNodeU( edge, n ); + CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, distXYZ ); + if ( distXYZ[0] < node2MiddleDist ) + { + distMiddleProj = distXYZ[0]; + u = foundU; + iOkEdge = is2nd; + } + } + if ( Precision::IsInfinite( distMiddleProj )) + { + // both projections failed; set n12 on the edge of n1 with U of a common vertex + TopoDS_Vertex vCommon; + if ( TopExp::CommonVertex( edges[0], edges[1], vCommon )) + u = BRep_Tool::Parameter( vCommon, edges[0] ); + else + { + double f,l, u0 = GetNodeU( edges[0], n1 ); + BRep_Tool::Range( edges[0],f,l ); + u = ( fabs(u0-f) < fabs(u0-l) ) ? f : l; + } + iOkEdge = 0; + distMiddleProj = 0; + } + + // move n12 to position of a successfull projection + double tol = BRep_Tool::Tolerance(edges[ iOkEdge ]); + if ( !force3d && distMiddleProj > 2*tol ) + { + TopLoc_Location loc; double f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve( edges[iOkEdge],loc,f,l ); + gp_Pnt p = curve->Value( u ); + GetMeshDS()->MoveNode( n12, p.X(), p.Y(), p.Z() ); + } + + GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u); + + myTLinkNodeMap.insert( make_pair( SMESH_TLink(n1,n2), n12 )); + + return n12; +} + +//======================================================================= +//function : AddNode +//purpose : Creates a node +//======================================================================= + +SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID, + double u, double v) +{ + 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, u, v); break; + case TopAbs_EDGE: meshDS->SetNodeOnEdge( node, myShapeID, u); break; + case TopAbs_VERTEX: meshDS->SetNodeOnVertex( node, myShapeID); break; + default: ; + } + } + return node; +} + +//======================================================================= +//function : AddEdge +//purpose : Creates quadratic or linear edge +//======================================================================= + +SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const int id, + const bool force3d) +{ + SMESHDS_Mesh * meshDS = GetMeshDS(); + + 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 ( mySetElemOnShape && myShapeID > 0 ) + meshDS->SetMeshElementOnShape( edge, myShapeID ); + + return edge; +} + +//======================================================================= +//function : AddFace +//purpose : 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 = GetMeshDS(); + SMDS_MeshFace* elem = 0; + + if( n1==n2 || n2==n3 || n3==n1 ) + return elem; + + if(!myCreateQuadratic) { + if(id) + elem = meshDS->AddFaceWithID(n1, n2, n3, id); + else + 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); @@ -656,20 +1303,39 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, } //======================================================================= -/*! - * Creates quadratic or linear quadrangle - */ +//function : AddFace +//purpose : Creates quadratic or linear quadrangle //======================================================================= SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n3, const SMDS_MeshNode* n4, - const int id, - const bool force3d) + const int id, + const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); SMDS_MeshFace* elem = 0; + + if( n1==n2 ) { + return AddFace(n1,n3,n4,id,force3d); + } + if( n1==n3 ) { + return AddFace(n1,n2,n4,id,force3d); + } + if( n1==n4 ) { + return AddFace(n1,n2,n3,id,force3d); + } + if( n2==n3 ) { + return AddFace(n1,n2,n4,id,force3d); + } + if( n2==n4 ) { + return AddFace(n1,n2,n3,id,force3d); + } + if( n3==n4 ) { + return AddFace(n1,n2,n3,id,force3d); + } + if(!myCreateQuadratic) { if(id) elem = meshDS->AddFaceWithID(n1, n2, n3, n4, id); @@ -694,32 +1360,70 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, } //======================================================================= -/*! - * Creates quadratic or linear volume - */ +//function : AddPolygonalFace +//purpose : Creates polygon, with additional nodes in quadratic mesh //======================================================================= -SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const SMDS_MeshNode* n3, - const SMDS_MeshNode* n4, - const SMDS_MeshNode* n5, - const SMDS_MeshNode* n6, - const int id, - const bool force3d) +SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector& nodes, + const int id, + const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); - SMDS_MeshVolume* elem = 0; + SMDS_MeshFace* elem = 0; + if(!myCreateQuadratic) { if(id) - elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id); + elem = meshDS->AddPolygonalFaceWithID(nodes, id); else - elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6); + elem = meshDS->AddPolygonalFace(nodes); } 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); + vector newNodes; + for ( int i = 0; i < nodes.size(); ++i ) + { + const SMDS_MeshNode* n1 = nodes[i]; + const SMDS_MeshNode* n2 = nodes[(i+1)%nodes.size()]; + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d); + newNodes.push_back( n1 ); + newNodes.push_back( n12 ); + } + if(id) + elem = meshDS->AddPolygonalFaceWithID(newNodes, id); + else + elem = meshDS->AddPolygonalFace(newNodes); + } + if ( mySetElemOnShape && myShapeID > 0 ) + meshDS->SetMeshElementOnShape( elem, myShapeID ); + + return elem; +} + +//======================================================================= +//function : AddVolume +//purpose : Creates quadratic or linear prism +//======================================================================= + +SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4, + const SMDS_MeshNode* n5, + const SMDS_MeshNode* n6, + const int id, + const bool force3d) +{ + SMESHDS_Mesh * meshDS = GetMeshDS(); + SMDS_MeshVolume* elem = 0; + if(!myCreateQuadratic) { + if(id) + elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id); + else + 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* n45 = GetMediumNode(n4,n5,force3d); const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d); @@ -743,9 +1447,8 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, } //======================================================================= -/*! - * Creates quadratic or linear volume - */ +//function : AddVolume +//purpose : Creates quadratic or linear tetrahedron //======================================================================= SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, @@ -753,7 +1456,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n3, const SMDS_MeshNode* n4, const int id, - const bool force3d) + const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); SMDS_MeshVolume* elem = 0; @@ -784,9 +1487,8 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, } //======================================================================= -/*! - * Creates quadratic or linear pyramid - */ +//function : AddVolume +//purpose : Creates quadratic or linear pyramid //======================================================================= SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, @@ -795,7 +1497,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n4, const SMDS_MeshNode* n5, const int id, - const bool force3d) + const bool force3d) { SMDS_MeshVolume* elem = 0; if(!myCreateQuadratic) { @@ -832,9 +1534,8 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, } //======================================================================= -/*! - * Creates quadratic or linear hexahedron - */ +//function : AddVolume +//purpose : Creates quadratic or linear hexahedron //======================================================================= SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, @@ -846,7 +1547,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n7, const SMDS_MeshNode* n8, const int id, - const bool force3d) + const bool force3d) { SMESHDS_Mesh * meshDS = GetMeshDS(); SMDS_MeshVolume* elem = 0; @@ -888,273 +1589,369 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, } //======================================================================= -/*! - * \brief Load nodes bound to face into a map of node columns - * \param theParam2ColumnMap - map of node columns to fill - * \param theFace - the face on which nodes are searched for - * \param theBaseEdge - the edge nodes of which are columns' bases - * \param theMesh - the mesh containing nodes - * \retval bool - false if something is wrong - * - * The key of the map is a normalized parameter of each - * base node on theBaseEdge. - * This method works in supposition that nodes on the face - * forms a rectangular grid and elements can be quardrangles or triangles - */ +//function : AddVolume +//purpose : Creates LINEAR!!!!!!!!! octahedron //======================================================================= -bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, - const TopoDS_Face& theFace, - const TopoDS_Edge& theBaseEdge, - SMESHDS_Mesh* theMesh) +SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4, + const SMDS_MeshNode* n5, + const SMDS_MeshNode* n6, + const SMDS_MeshNode* n7, + const SMDS_MeshNode* n8, + const SMDS_MeshNode* n9, + const SMDS_MeshNode* n10, + const SMDS_MeshNode* n11, + const SMDS_MeshNode* n12, + const int id, + bool force3d) { - // get vertices of theBaseEdge - TopoDS_Vertex vfb, vlb, vft; // first and last, bottom and top vertices - TopoDS_Edge eFrw = TopoDS::Edge( theBaseEdge.Oriented( TopAbs_FORWARD )); - TopExp::Vertices( eFrw, vfb, vlb ); - - // find the other edges of theFace and orientation of e1 - TopoDS_Edge e1, e2, eTop; - bool rev1, CumOri = false; - TopExp_Explorer exp( theFace, TopAbs_EDGE ); - int nbEdges = 0; - for ( ; exp.More(); exp.Next() ) { - if ( ++nbEdges > 4 ) { - return false; // more than 4 edges in theFace - } - TopoDS_Edge e = TopoDS::Edge( exp.Current() ); - if ( theBaseEdge.IsSame( e )) - continue; - TopoDS_Vertex vCommon; - if ( !TopExp::CommonVertex( theBaseEdge, e, vCommon )) - eTop = e; - else if ( vCommon.IsSame( vfb )) { - e1 = e; - vft = TopExp::LastVertex( e1, CumOri ); - rev1 = vfb.IsSame( vft ); - if ( rev1 ) - vft = TopExp::FirstVertex( e1, CumOri ); - } + SMESHDS_Mesh * meshDS = GetMeshDS(); + SMDS_MeshVolume* elem = 0; + if(id) + elem = meshDS->AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,id); + else + elem = meshDS->AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12); + if ( mySetElemOnShape && myShapeID > 0 ) + meshDS->SetMeshElementOnShape( elem, myShapeID ); + return elem; +} + +//======================================================================= +//function : AddPolyhedralVolume +//purpose : Creates polyhedron. In quadratic mesh, adds medium nodes +//======================================================================= + +SMDS_MeshVolume* +SMESH_MesherHelper::AddPolyhedralVolume (const std::vector& nodes, + const std::vector& quantities, + const int id, + const bool force3d) +{ + SMESHDS_Mesh * meshDS = GetMeshDS(); + SMDS_MeshVolume* elem = 0; + if(!myCreateQuadratic) + { + if(id) + elem = meshDS->AddPolyhedralVolumeWithID(nodes, quantities, id); else - e2 = e; - } - if ( nbEdges < 4 ) { - return false; // less than 4 edges in theFace - } - if ( e2.IsNull() && vfb.IsSame( vlb )) - e2 = e1; - - // submeshes corresponding to shapes - SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace ); - SMESHDS_SubMesh* smb = theMesh->MeshElements( theBaseEdge ); - SMESHDS_SubMesh* smt = theMesh->MeshElements( eTop ); - SMESHDS_SubMesh* sm1 = theMesh->MeshElements( e1 ); - SMESHDS_SubMesh* sm2 = theMesh->MeshElements( e2 ); - SMESHDS_SubMesh* smVfb = theMesh->MeshElements( vfb ); - SMESHDS_SubMesh* smVlb = theMesh->MeshElements( vlb ); - SMESHDS_SubMesh* smVft = theMesh->MeshElements( vft ); - if (!smFace || !smb || !smt || !sm1 || !sm2 || !smVfb || !smVlb || !smVft ) { - RETURN_BAD_RESULT( "NULL submesh " <NbNodes() != smt->NbNodes() || sm1->NbNodes() != sm2->NbNodes() ) { - RETURN_BAD_RESULT(" Diff nb of nodes on opposite edges" ); - } - if (smVfb->NbNodes() != 1 || smVlb->NbNodes() != 1 || smVft->NbNodes() != 1) { - RETURN_BAD_RESULT("Empty submesh of vertex"); - } - // define whether mesh is quadratic - bool isQuadraticMesh = false; - SMDS_ElemIteratorPtr eIt = smFace->GetElements(); - if ( !eIt->more() ) { - RETURN_BAD_RESULT("No elements on the face"); - } - const SMDS_MeshElement* e = eIt->next(); - isQuadraticMesh = e->IsQuadratic(); - - if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) { - // check quadratic case - if ( isQuadraticMesh ) { - // what if there are quadrangles and triangles mixed? -// int n1 = sm1->NbNodes()/2; -// int n2 = smb->NbNodes()/2; -// int n3 = sm1->NbNodes() - n1; -// int n4 = smb->NbNodes() - n2; -// int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4; -// if( nf != smFace->NbNodes() ) { -// MESSAGE( "Wrong nb face nodes: " << -// sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); -// return false; -// } - } - else { - RETURN_BAD_RESULT( "Wrong nb face nodes: " << - sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); - } + elem = meshDS->AddPolyhedralVolume(nodes, quantities); } - // IJ size - int vsize = sm1->NbNodes() + 2; - int hsize = smb->NbNodes() + 2; - if(isQuadraticMesh) { - vsize = vsize - sm1->NbNodes()/2 -1; - hsize = hsize - smb->NbNodes()/2 -1; + else + { + vector newNodes; + vector newQuantities; + for ( int iFace=0, iN=0; iFace < quantities.size(); ++iFace) + { + int nbNodesInFace = quantities[iFace]; + newQuantities.push_back(0); + for ( int i = 0; i < nbNodesInFace; ++i ) + { + const SMDS_MeshNode* n1 = nodes[ iN + i ]; + newNodes.push_back( n1 ); + newQuantities.back()++; + + const SMDS_MeshNode* n2 = nodes[ iN + ( i+1==nbNodesInFace ? 0 : i+1 )]; +// if ( n1->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE && +// n2->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE ) + { + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d); + newNodes.push_back( n12 ); + newQuantities.back()++; + } + } + iN += nbNodesInFace; + } + if(id) + elem = meshDS->AddPolyhedralVolumeWithID( newNodes, newQuantities, id ); + else + elem = meshDS->AddPolyhedralVolume( newNodes, newQuantities ); } + if ( mySetElemOnShape && myShapeID > 0 ) + meshDS->SetMeshElementOnShape( elem, myShapeID ); + + return elem; +} - // load nodes from theBaseEdge +//======================================================================= +//function : LoadNodeColumns +//purpose : Load nodes bound to face into a map of node columns +//======================================================================= - std::set loadedNodes; - const SMDS_MeshNode* nullNode = 0; +bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, + const TopoDS_Face& theFace, + const TopoDS_Edge& theBaseEdge, + SMESHDS_Mesh* theMesh, + SMESH_ProxyMesh* theProxyMesh) +{ + return LoadNodeColumns(theParam2ColumnMap, + theFace, + std::list(1,theBaseEdge), + theMesh, + theProxyMesh); +} - std::vector & nVecf = theParam2ColumnMap[ 0.]; - nVecf.resize( vsize, nullNode ); - loadedNodes.insert( nVecf[ 0 ] = smVfb->GetNodes()->next() ); +//======================================================================= +//function : LoadNodeColumns +//purpose : Load nodes bound to face into a map of node columns +//======================================================================= - std::vector & nVecl = theParam2ColumnMap[ 1.]; - nVecl.resize( vsize, nullNode ); - loadedNodes.insert( nVecl[ 0 ] = smVlb->GetNodes()->next() ); +bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, + const TopoDS_Face& theFace, + const std::list& theBaseSide, + SMESHDS_Mesh* theMesh, + SMESH_ProxyMesh* theProxyMesh) +{ + // get a right submesh of theFace - double f, l; - BRep_Tool::Range( eFrw, f, l ); - double range = l - f; - SMDS_NodeIteratorPtr nIt = smb->GetNodes(); - const SMDS_MeshNode* node; - while ( nIt->more() ) { - node = nIt->next(); - if(IsMedium(node, SMDSAbs_Edge)) - continue; - const SMDS_EdgePosition* pos = - dynamic_cast( node->GetPosition().get() ); - if ( !pos ) { - return false; + const SMESHDS_SubMesh* faceSubMesh = 0; + if ( theProxyMesh ) + { + faceSubMesh = theProxyMesh->GetSubMesh( theFace ); + if ( !faceSubMesh || + faceSubMesh->NbElements() == 0 || + theProxyMesh->IsTemporary( faceSubMesh->GetElements()->next() )) + { + // can use a proxy sub-mesh with not temporary elements only + faceSubMesh = 0; + theProxyMesh = 0; } - double u = ( pos->GetUParameter() - f ) / range; - std::vector & nVec = theParam2ColumnMap[ u ]; - nVec.resize( vsize, nullNode ); - loadedNodes.insert( nVec[ 0 ] = node ); } - if ( theParam2ColumnMap.size() != hsize ) { - RETURN_BAD_RESULT( "Wrong node positions on theBaseEdge" ); + if ( !faceSubMesh ) + faceSubMesh = theMesh->MeshElements( theFace ); + if ( !faceSubMesh || faceSubMesh->NbElements() == 0 ) + return false; + + // get data of edges for normalization of params + + vector< double > length; + double fullLen = 0; + list::const_iterator edge; + { + for ( edge = theBaseSide.begin(); edge != theBaseSide.end(); ++edge ) + { + double len = std::max( 1e-10, SMESH_Algo::EdgeLength( *edge )); + fullLen += len; + length.push_back( len ); + } } - // load nodes from e1 + // get nodes on theBaseEdge sorted by param on edge and initialize theParam2ColumnMap with them + edge = theBaseSide.begin(); + for ( int iE = 0; edge != theBaseSide.end(); ++edge, ++iE ) + { + map< double, const SMDS_MeshNode*> sortedBaseNodes; + SMESH_Algo::GetSortedNodesOnEdge( theMesh, *edge,/*noMedium=*/true, sortedBaseNodes); + if ( sortedBaseNodes.empty() ) continue; - std::map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge - nIt = sm1->GetNodes(); - while ( nIt->more() ) { - node = nIt->next(); - if(IsMedium(node)) - continue; - const SMDS_EdgePosition* pos = - dynamic_cast( node->GetPosition().get() ); - if ( !pos ) { - return false; + double f, l; + BRep_Tool::Range( *edge, f, l ); + if ( edge->Orientation() == TopAbs_REVERSED ) std::swap( f, l ); + const double coeff = 1. / ( l - f ) * length[iE] / fullLen; + const double prevPar = theParam2ColumnMap.empty() ? 0 : theParam2ColumnMap.rbegin()->first; + map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNodes.begin(); + for ( ; u_n != sortedBaseNodes.end(); u_n++ ) + { + double par = prevPar + coeff * ( u_n->first - f ); + TParam2ColumnMap::iterator u2nn = + theParam2ColumnMap.insert( theParam2ColumnMap.end(), make_pair( par, TNodeColumn())); + u2nn->second.push_back( u_n->second ); } - sortedNodes.insert( std::make_pair( pos->GetUParameter(), node )); - } - loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() ); - std::map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin(); - int row = rev1 ? vsize - 1 : 0; - int dRow = rev1 ? -1 : +1; - for ( ; u_n != sortedNodes.end(); u_n++ ) { - row += dRow; - loadedNodes.insert( nVecf[ row ] = u_n->second ); - } - - // try to load the rest nodes - - // get all faces from theFace - TIDSortedElemSet allFaces, foundFaces; - eIt = smFace->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* e = eIt->next(); - if ( e->GetType() == SMDSAbs_Face ) - 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, - // look for a not loaded node considering this node to be the next - // in a column of the starting second node. Repeat, starting - // from nodes next to the previous starting nodes in their columns, - // and so on while a face can be found. Then go the the next pair - // of nodes on theBaseEdge. - TParam2ColumnMap::iterator par_nVec_1 = theParam2ColumnMap.begin(); - TParam2ColumnMap::iterator par_nVec_2 = par_nVec_1; - // loop on columns - int col = 0; - for ( par_nVec_2++; par_nVec_2 != theParam2ColumnMap.end(); par_nVec_1++, par_nVec_2++ ) { - col++; - row = 0; - const SMDS_MeshNode* n1 = par_nVec_1->second[ row ]; - const SMDS_MeshNode* n2 = par_nVec_2->second[ row ]; - const SMDS_MeshElement* face = 0; - bool lastColOnClosedFace = ( nVecf[ row ] == n2 ); - do { - // look for a face by 2 nodes - face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces ); - if ( face ) { - int nbFaceNodes = face->NbNodes(); - if ( face->IsQuadratic() ) - nbFaceNodes /= 2; - if ( nbFaceNodes>4 ) { - RETURN_BAD_RESULT(" Too many nodes in a face: " << nbFaceNodes ); - } - // look for a not loaded node of the - bool found = false; - const SMDS_MeshNode* n3 = 0; // a node defferent from n1 and n2 - for ( int i = 0; i < nbFaceNodes && !found; ++i ) { - node = face->GetNode( i ); - found = loadedNodes.insert( node ).second; - if ( !found && node != n1 && node != n2 ) - n3 = node; - } - if ( lastColOnClosedFace && row + 1 < vsize ) { - node = nVecf[ row + 1 ]; - found = ( face->GetNodeIndex( node ) >= 0 ); - } - if ( found ) { - if ( ++row > vsize - 1 ) { - RETURN_BAD_RESULT( "Too many nodes in column "<< col <<": "<< row+1); - } - par_nVec_2->second[ row ] = node; - foundFaces.insert( face ); - n2 = node; - if ( nbFaceNodes==4 ) { - n1 = par_nVec_1->second[ row ]; - } - } - else if ( nbFaceNodes==3 && n3 == par_nVec_1->second[ row + 1 ] ) { - n1 = n3; - } - else { - RETURN_BAD_RESULT( "Not quad mesh, column "<< col ); - } - } + } + TParam2ColumnMap::iterator par_nVec_2, par_nVec_1 = theParam2ColumnMap.begin(); + if ( theProxyMesh ) + { + for ( ; par_nVec_1 != theParam2ColumnMap.end(); ++par_nVec_1 ) + { + const SMDS_MeshNode* & n = par_nVec_1->second[0]; + n = theProxyMesh->GetProxyNode( n ); } - while ( face && n1 && n2 ); - - if ( row < vsize - 1 ) { - MESSAGE( "Too few nodes in column "<< col <<": "<< row+1); - MESSAGE( "Base node 1: "<< par_nVec_1->second[0]); - MESSAGE( "Base node 2: "<< par_nVec_2->second[0]); - if ( n1 ) { MESSAGE( "Current node 1: "<< n1); } - else { MESSAGE( "Current node 1: NULL"); } - if ( n2 ) { MESSAGE( "Current node 2: "<< n2); } - else { MESSAGE( "Current node 2: NULL"); } - MESSAGE( "first base node: "<< theParam2ColumnMap.begin()->second[0]); - MESSAGE( "last base node: "<< theParam2ColumnMap.rbegin()->second[0]); - return false; + } + + int nbRows = 1 + faceSubMesh->NbElements() / ( theParam2ColumnMap.size()-1 ); + + // fill theParam2ColumnMap column by column by passing from nodes on + // theBaseEdge up via mesh faces on theFace + + par_nVec_2 = theParam2ColumnMap.begin(); + par_nVec_1 = par_nVec_2++; + TIDSortedElemSet emptySet, avoidSet; + for ( ; par_nVec_2 != theParam2ColumnMap.end(); ++par_nVec_1, ++par_nVec_2 ) + { + vector& nCol1 = par_nVec_1->second; + vector& nCol2 = par_nVec_2->second; + nCol1.resize( nbRows ); + nCol2.resize( nbRows ); + + int i1, i2, iRow = 0; + const SMDS_MeshNode *n1 = nCol1[0], *n2 = nCol2[0]; + // find face sharing node n1 and n2 and belonging to faceSubMesh + while ( const SMDS_MeshElement* face = + SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2)) + { + if ( faceSubMesh->Contains( face )) + { + int nbNodes = face->IsQuadratic() ? face->NbNodes()/2 : face->NbNodes(); + if ( nbNodes != 4 ) + return false; + n1 = face->GetNode( (i2+2) % 4 ); // opposite corner of quadrangle face + n2 = face->GetNode( (i1+2) % 4 ); + if ( ++iRow >= nbRows ) + return false; + nCol1[ iRow ] = n1; + nCol2[ iRow ] = n2; + avoidSet.clear(); + } + avoidSet.insert( face ); } - } // loop on columns + // set a real height + nCol1.resize( iRow + 1 ); + nCol2.resize( iRow + 1 ); + } + return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1; +} - return true; +//======================================================================= +//function : NbAncestors +//purpose : Return number of unique ancestors of the shape +//======================================================================= + +int SMESH_MesherHelper::NbAncestors(const TopoDS_Shape& shape, + const SMESH_Mesh& mesh, + TopAbs_ShapeEnum ancestorType/*=TopAbs_SHAPE*/) +{ + TopTools_MapOfShape ancestors; + TopTools_ListIteratorOfListOfShape ansIt( mesh.GetAncestors(shape) ); + for ( ; ansIt.More(); ansIt.Next() ) { + if ( ancestorType == TopAbs_SHAPE || ansIt.Value().ShapeType() == ancestorType ) + ancestors.Add( ansIt.Value() ); + } + return ancestors.Extent(); +} + +//======================================================================= +//function : GetSubShapeOri +//purpose : Return orientation of sub-shape in the main shape +//======================================================================= + +TopAbs_Orientation SMESH_MesherHelper::GetSubShapeOri(const TopoDS_Shape& shape, + const TopoDS_Shape& subShape) +{ + TopAbs_Orientation ori = TopAbs_Orientation(-1); + if ( !shape.IsNull() && !subShape.IsNull() ) + { + TopExp_Explorer e( shape, subShape.ShapeType() ); + if ( shape.Orientation() >= TopAbs_INTERNAL ) // TopAbs_INTERNAL or TopAbs_EXTERNAL + e.Init( shape.Oriented(TopAbs_FORWARD), subShape.ShapeType() ); + for ( ; e.More(); e.Next()) + if ( subShape.IsSame( e.Current() )) + break; + if ( e.More() ) + ori = e.Current().Orientation(); + } + return ori; +} + +//======================================================================= +//function : IsSubShape +//purpose : +//======================================================================= + +bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, + const TopoDS_Shape& mainShape ) +{ + if ( !shape.IsNull() && !mainShape.IsNull() ) + { + for ( TopExp_Explorer exp( mainShape, shape.ShapeType()); + exp.More(); + exp.Next() ) + if ( shape.IsSame( exp.Current() )) + return true; + } + SCRUTE((shape.IsNull())); + SCRUTE((mainShape.IsNull())); + return false; } //======================================================================= -/** - * Check mesh without geometry for: if all elements on this shape are quadratic, - * quadratic elements will be created. - * Used then generated 3D mesh without geometry. +//function : IsSubShape +//purpose : +//======================================================================= + +bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh ) +{ + if ( shape.IsNull() || !aMesh ) + return false; + return + aMesh->GetMeshDS()->ShapeToIndex( shape ) || + // PAL16202 + (shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape )); +} + +//================================================================================ +/*! + * \brief Return maximal tolerance of shape + */ +//================================================================================ + +double SMESH_MesherHelper::MaxTolerance( const TopoDS_Shape& shape ) +{ + double tol = Precision::Confusion(); + TopExp_Explorer exp; + for ( exp.Init( shape, TopAbs_FACE ); exp.More(); exp.Next() ) + tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Face( exp.Current()))); + for ( exp.Init( shape, TopAbs_EDGE ); exp.More(); exp.Next() ) + tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Edge( exp.Current()))); + for ( exp.Init( shape, TopAbs_VERTEX ); exp.More(); exp.Next() ) + tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Vertex( exp.Current()))); + + return tol; +} + +//================================================================================ +/*! + * \brief Check if the first and last vertices of an edge are the same + * \param anEdge - the edge to check + * \retval bool - true if same + */ +//================================================================================ + +bool SMESH_MesherHelper::IsClosedEdge( const TopoDS_Edge& anEdge ) +{ + if ( anEdge.Orientation() >= TopAbs_INTERNAL ) + return IsClosedEdge( TopoDS::Edge( anEdge.Oriented( TopAbs_FORWARD ))); + return TopExp::FirstVertex( anEdge ).IsSame( TopExp::LastVertex( anEdge )); +} + +//================================================================================ +/*! + * \brief Wrapper over TopExp::FirstVertex() and TopExp::LastVertex() fixing them + * in the case of INTERNAL edge */ +//================================================================================ + +TopoDS_Vertex SMESH_MesherHelper::IthVertex( const bool is2nd, + TopoDS_Edge anEdge, + const bool CumOri ) +{ + if ( anEdge.Orientation() >= TopAbs_INTERNAL ) + anEdge.Orientation( TopAbs_FORWARD ); + + const TopAbs_Orientation tgtOri = is2nd ? TopAbs_REVERSED : TopAbs_FORWARD; + TopoDS_Iterator vIt( anEdge, CumOri ); + while ( vIt.More() && vIt.Value().Orientation() != tgtOri ) + vIt.Next(); + + return ( vIt.More() ? TopoDS::Vertex(vIt.Value()) : TopoDS_Vertex() ); +} + +//======================================================================= +//function : IsQuadraticMesh +//purpose : Check mesh without geometry for: if all elements on this shape are quadratic, +// quadratic elements will be created. +// Used then generated 3D mesh without geometry. //======================================================================= SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh() @@ -1184,13 +1981,1520 @@ SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh() return SMESH_MesherHelper::COMP; } +//======================================================================= +//function : GetOtherParam +//purpose : Return an alternative parameter for a node on seam +//======================================================================= + +double SMESH_MesherHelper::GetOtherParam(const double param) const +{ + int i = myParIndex & U_periodic ? 0 : 1; + return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i]; +} + +namespace { + + //======================================================================= + /*! + * \brief Iterator on ancestors of the given type + */ + //======================================================================= + + struct TAncestorsIterator : public SMDS_Iterator + { + TopTools_ListIteratorOfListOfShape _ancIter; + TopAbs_ShapeEnum _type; + TopTools_MapOfShape _encountered; + TAncestorsIterator( const TopTools_ListOfShape& ancestors, TopAbs_ShapeEnum type) + : _ancIter( ancestors ), _type( type ) + { + if ( _ancIter.More() ) { + if ( _ancIter.Value().ShapeType() != _type ) next(); + else _encountered.Add( _ancIter.Value() ); + } + } + virtual bool more() + { + return _ancIter.More(); + } + virtual const TopoDS_Shape* next() + { + const TopoDS_Shape* s = _ancIter.More() ? & _ancIter.Value() : 0; + if ( _ancIter.More() ) + for ( _ancIter.Next(); _ancIter.More(); _ancIter.Next()) + if ( _ancIter.Value().ShapeType() == _type && _encountered.Add( _ancIter.Value() )) + break; + return s; + } + }; + +} // namespace + //======================================================================= /*! - * \brief Return an alternative parameter for a node on seam + * \brief Return iterator on ancestors of the given type */ //======================================================================= -double SMESH_MesherHelper::GetOtherParam(const double param) const +PShapeIteratorPtr SMESH_MesherHelper::GetAncestors(const TopoDS_Shape& shape, + const SMESH_Mesh& mesh, + TopAbs_ShapeEnum ancestorType) +{ + return PShapeIteratorPtr( new TAncestorsIterator( mesh.GetAncestors(shape), ancestorType)); +} + +//======================================================================= +//function : GetCommonAncestor +//purpose : Find a common ancestors of two shapes of the given type +//======================================================================= + +TopoDS_Shape SMESH_MesherHelper::GetCommonAncestor(const TopoDS_Shape& shape1, + const TopoDS_Shape& shape2, + const SMESH_Mesh& mesh, + TopAbs_ShapeEnum ancestorType) { - return fabs(param-myPar1) < fabs(param-myPar2) ? myPar2 : myPar1; + TopoDS_Shape commonAnc; + if ( !shape1.IsNull() && !shape2.IsNull() ) + { + PShapeIteratorPtr ancIt = GetAncestors( shape1, mesh, ancestorType ); + while ( const TopoDS_Shape* anc = ancIt->next() ) + if ( IsSubShape( shape2, *anc )) + { + commonAnc = *anc; + break; + } + } + return commonAnc; } + +//#include + +//======================================================================= +namespace { // Structures used by FixQuadraticElements() +//======================================================================= + +#define __DMP__(txt) \ + //cout << txt +#define MSG(txt) __DMP__(txt< < 1/15 * + return middleNodeMove2 < 1/15./15. * linkLen2; + } + + struct QFace; + // --------------------------------------- + /*! + * \brief Quadratic link knowing its faces + */ + struct QLink: public SMESH_TLink + { + const SMDS_MeshNode* _mediumNode; + mutable vector _faces; + mutable gp_Vec _nodeMove; + mutable int _nbMoves; + + QLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* nm): + SMESH_TLink( n1,n2 ), _mediumNode(nm), _nodeMove(0,0,0), _nbMoves(0) { + _faces.reserve(4); + //if ( MediumPos() != SMDS_TOP_3DSPACE ) + _nodeMove = MediumPnt() - MiddlePnt(); + } + void SetContinuesFaces() const; + const QFace* GetContinuesFace( const QFace* face ) const; + bool OnBoundary() const; + gp_XYZ MiddlePnt() const { return ( XYZ( node1() ) + XYZ( node2() )) / 2.; } + gp_XYZ MediumPnt() const { return XYZ( _mediumNode ); } + + SMDS_TypeOfPosition MediumPos() const + { return _mediumNode->GetPosition()->GetTypeOfPosition(); } + SMDS_TypeOfPosition EndPos(bool isSecond) const + { return (isSecond ? node2() : node1())->GetPosition()->GetTypeOfPosition(); } + const SMDS_MeshNode* EndPosNode(SMDS_TypeOfPosition pos) const + { return EndPos(0) == pos ? node1() : EndPos(1) == pos ? node2() : 0; } + + void Move(const gp_Vec& move, bool sum=false) const + { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; } + gp_XYZ Move() const { return _nodeMove.XYZ() / _nbMoves; } + bool IsMoved() const { return (_nbMoves > 0 /*&& !IsStraight()*/); } + bool IsStraight() const + { return isStraightLink( (XYZ(node1())-XYZ(node2())).SquareModulus(), + _nodeMove.SquareMagnitude()); + } + bool operator<(const QLink& other) const { + return (node1()->GetID() == other.node1()->GetID() ? + node2()->GetID() < other.node2()->GetID() : + node1()->GetID() < other.node1()->GetID()); + } +// struct PtrComparator { +// bool operator() (const QLink* l1, const QLink* l2 ) const { return *l1 < *l2; } +// }; + }; + // --------------------------------------------------------- + /*! + * \brief Link in the chain of links; it connects two faces + */ + struct TChainLink + { + const QLink* _qlink; + mutable const QFace* _qfaces[2]; + + TChainLink(const QLink* qlink=0):_qlink(qlink) { + _qfaces[0] = _qfaces[1] = 0; + } + void SetFace(const QFace* face) const { int iF = _qfaces[0] ? 1 : 0; _qfaces[iF]=face; } + + bool IsBoundary() const { return !_qfaces[1]; } + + void RemoveFace( const QFace* face ) const + { _qfaces[(face == _qfaces[1])] = 0; if (!_qfaces[0]) std::swap(_qfaces[0],_qfaces[1]); } + + const QFace* NextFace( const QFace* f ) const + { return _qfaces[0]==f ? _qfaces[1] : _qfaces[0]; } + + const SMDS_MeshNode* NextNode( const SMDS_MeshNode* n ) const + { return n == _qlink->node1() ? _qlink->node2() : _qlink->node1(); } + + bool operator<(const TChainLink& other) const { return *_qlink < *other._qlink; } + + operator bool() const { return (_qlink); } + + const QLink* operator->() const { return _qlink; } + + gp_Vec Normal() const; + + bool IsStraight() const; + }; + // -------------------------------------------------------------------- + typedef list< TChainLink > TChain; + typedef set < TChainLink > TLinkSet; + typedef TLinkSet::const_iterator TLinkInSet; + + const int theFirstStep = 5; + + enum { ERR_OK, ERR_TRI, ERR_PRISM, ERR_UNKNOWN }; // errors of QFace::GetLinkChain() + // -------------------------------------------------------------------- + /*! + * \brief Face shared by two volumes and bound by QLinks + */ + struct QFace: public TIDSortedNodeSet + { + mutable const SMDS_MeshElement* _volumes[2]; + mutable vector< const QLink* > _sides; + mutable bool _sideIsAdded[4]; // added in chain of links + gp_Vec _normal; +#ifdef _DEBUG_ + mutable const SMDS_MeshElement* _face; +#endif + + QFace( const vector< const QLink*>& links, const SMDS_MeshElement* face=0 ); + + void SetVolume(const SMDS_MeshElement* v) const { _volumes[ _volumes[0] ? 1 : 0 ] = v; } + + int NbVolumes() const { return !_volumes[0] ? 0 : !_volumes[1] ? 1 : 2; } + + void AddSelfToLinks() const { + for ( int i = 0; i < _sides.size(); ++i ) + _sides[i]->_faces.push_back( this ); + } + int LinkIndex( const QLink* side ) const { + for (int i=0; i<_sides.size(); ++i ) if ( _sides[i] == side ) return i; + return -1; + } + bool GetLinkChain( int iSide, TChain& chain, SMDS_TypeOfPosition pos, int& err) const; + + bool GetLinkChain( TChainLink& link, TChain& chain, SMDS_TypeOfPosition pos, int& err) const + { + int i = LinkIndex( link._qlink ); + if ( i < 0 ) return true; + _sideIsAdded[i] = true; + link.SetFace( this ); + // continue from opposite link + return GetLinkChain( (i+2)%_sides.size(), chain, pos, err ); + } + bool IsBoundary() const { return !_volumes[1]; } + + bool Contains( const SMDS_MeshNode* node ) const { return count(node); } + + bool IsSpoiled(const QLink* bentLink ) const; + + TLinkInSet GetBoundaryLink( const TLinkSet& links, + const TChainLink& avoidLink, + TLinkInSet * notBoundaryLink = 0, + const SMDS_MeshNode* nodeToContain = 0, + bool * isAdjacentUsed = 0, + int nbRecursionsLeft = -1) const; + + TLinkInSet GetLinkByNode( const TLinkSet& links, + const TChainLink& avoidLink, + const SMDS_MeshNode* nodeToContain) const; + + const SMDS_MeshNode* GetNodeInFace() const { + for ( int iL = 0; iL < _sides.size(); ++iL ) + if ( _sides[iL]->MediumPos() == SMDS_TOP_FACE ) return _sides[iL]->_mediumNode; + return 0; + } + + gp_Vec LinkNorm(const int i, SMESH_MesherHelper* theFaceHelper=0) const; + + double MoveByBoundary( const TChainLink& theLink, + const gp_Vec& theRefVec, + const TLinkSet& theLinks, + SMESH_MesherHelper* theFaceHelper=0, + const double thePrevLen=0, + const int theStep=theFirstStep, + gp_Vec* theLinkNorm=0, + double theSign=1.0) const; + }; + + //================================================================================ + /*! + * \brief Dump QLink and QFace + */ + ostream& operator << (ostream& out, const QLink& l) + { + out <<"QLink nodes: " + << l.node1()->GetID() << " - " + << l._mediumNode->GetID() << " - " + << l.node2()->GetID() << endl; + return out; + } + ostream& operator << (ostream& out, const QFace& f) + { + out <<"QFace nodes: "/*<< &f << " "*/; + for ( TIDSortedNodeSet::const_iterator n = f.begin(); n != f.end(); ++n ) + out << (*n)->GetID() << " "; + out << " \tvolumes: " + << (f._volumes[0] ? f._volumes[0]->GetID() : 0) << " " + << (f._volumes[1] ? f._volumes[1]->GetID() : 0); + out << " \tNormal: "<< f._normal.X() <<", "<& links, const SMDS_MeshElement* face ) + { + _volumes[0] = _volumes[1] = 0; + _sides = links; + _sideIsAdded[0]=_sideIsAdded[1]=_sideIsAdded[2]=_sideIsAdded[3]=false; + _normal.SetCoord(0,0,0); + for ( int i = 1; i < _sides.size(); ++i ) { + const QLink *l1 = _sides[i-1], *l2 = _sides[i]; + insert( l1->node1() ); insert( l1->node2() ); + // compute normal + gp_Vec v1( XYZ( l1->node2()), XYZ( l1->node1())); + gp_Vec v2( XYZ( l2->node1()), XYZ( l2->node2())); + if ( l1->node1() != l2->node1() && l1->node2() != l2->node2() ) + v1.Reverse(); + _normal += v1 ^ v2; + } + double normSqSize = _normal.SquareMagnitude(); + if ( normSqSize > numeric_limits::min() ) + _normal /= sqrt( normSqSize ); + else + _normal.SetCoord(1e-33,0,0); + +#ifdef _DEBUG_ + _face = face; +#endif + } + //================================================================================ + /*! + * \brief Make up a chain of links + * \param iSide - link to add first + * \param chain - chain to fill in + * \param pos - postion of medium nodes the links should have + * \param error - out, specifies what is wrong + * \retval bool - false if valid chain can't be built; "valid" means that links + * of the chain belongs to rectangles bounding hexahedrons + */ + //================================================================================ + + bool QFace::GetLinkChain( int iSide, TChain& chain, SMDS_TypeOfPosition pos, int& error) const + { + if ( iSide >= _sides.size() ) // wrong argument iSide + return false; + if ( _sideIsAdded[ iSide ]) // already in chain + return true; + + if ( _sides.size() != 4 ) { // triangle - visit all my continous faces + MSGBEG( *this ); + TLinkSet links; + list< const QFace* > faces( 1, this ); + while ( !faces.empty() ) { + const QFace* face = faces.front(); + for ( int i = 0; i < face->_sides.size(); ++i ) { + if ( !face->_sideIsAdded[i] && face->_sides[i] ) { + face->_sideIsAdded[i] = true; + // find a face side in the chain + TLinkInSet chLink = links.insert( TChainLink(face->_sides[i])).first; +// TChain::iterator chLink = chain.begin(); +// for ( ; chLink != chain.end(); ++chLink ) +// if ( chLink->_qlink == face->_sides[i] ) +// break; +// if ( chLink == chain.end() ) +// chLink = chain.insert( chain.begin(), TChainLink(face->_sides[i])); + // add a face to a chained link and put a continues face in the queue + chLink->SetFace( face ); + if ( face->_sides[i]->MediumPos() == pos ) + if ( const QFace* contFace = face->_sides[i]->GetContinuesFace( face )) + if ( contFace->_sides.size() == 3 ) + faces.push_back( contFace ); + } + } + faces.pop_front(); + } + if ( error < ERR_TRI ) + error = ERR_TRI; + chain.insert( chain.end(), links.begin(),links.end() ); + return false; + } + _sideIsAdded[iSide] = true; // not to add this link to chain again + const QLink* link = _sides[iSide]; + if ( !link) + return true; + + // add link into chain + TChain::iterator chLink = chain.insert( chain.begin(), TChainLink(link)); + chLink->SetFace( this ); + MSGBEG( *this ); + + // propagate from quadrangle to neighbour faces + if ( link->MediumPos() >= pos ) { + int nbLinkFaces = link->_faces.size(); + if ( nbLinkFaces == 4 || (/*nbLinkFaces < 4 && */link->OnBoundary())) { + // hexahedral mesh or boundary quadrangles - goto a continous face + if ( const QFace* f = link->GetContinuesFace( this )) + if ( f->_sides.size() == 4 ) + return f->GetLinkChain( *chLink, chain, pos, error ); + } + else { + TChainLink chLink(link); // side face of prismatic mesh - visit all faces of iSide + for ( int i = 0; i < nbLinkFaces; ++i ) + if ( link->_faces[i] ) + link->_faces[i]->GetLinkChain( chLink, chain, pos, error ); + if ( error < ERR_PRISM ) + error = ERR_PRISM; + return false; + } + } + return true; + } + + //================================================================================ + /*! + * \brief Return a boundary link of the triangle face + * \param links - set of all links + * \param avoidLink - link not to return + * \param notBoundaryLink - out, neither the returned link nor avoidLink + * \param nodeToContain - node the returned link must contain; if provided, search + * also performed on adjacent faces + * \param isAdjacentUsed - returns true if link is found in adjacent faces + * \param nbRecursionsLeft - to limit recursion + */ + //================================================================================ + + TLinkInSet QFace::GetBoundaryLink( const TLinkSet& links, + const TChainLink& avoidLink, + TLinkInSet * notBoundaryLink, + const SMDS_MeshNode* nodeToContain, + bool * isAdjacentUsed, + int nbRecursionsLeft) const + { + TLinkInSet linksEnd = links.end(), boundaryLink = linksEnd; + + typedef list< pair< const QFace*, TLinkInSet > > TFaceLinkList; + TFaceLinkList adjacentFaces; + + for ( int iL = 0; iL < _sides.size(); ++iL ) + { + if ( avoidLink._qlink == _sides[iL] ) + continue; + TLinkInSet link = links.find( _sides[iL] ); + if ( link == linksEnd ) continue; + if ( (*link)->MediumPos() > SMDS_TOP_FACE ) + continue; // We work on faces here, don't go inside a solid + + // check link + if ( link->IsBoundary() ) { + if ( !nodeToContain || + (*link)->node1() == nodeToContain || + (*link)->node2() == nodeToContain ) + { + boundaryLink = link; + if ( !notBoundaryLink ) break; + } + } + else if ( notBoundaryLink ) { + *notBoundaryLink = link; + if ( boundaryLink != linksEnd ) break; + } + + if ( boundaryLink == linksEnd && nodeToContain ) // collect adjacent faces + if ( const QFace* adj = link->NextFace( this )) + if ( adj->Contains( nodeToContain )) + adjacentFaces.push_back( make_pair( adj, link )); + } + + if ( isAdjacentUsed ) *isAdjacentUsed = false; + if ( boundaryLink == linksEnd && nodeToContain && nbRecursionsLeft) // check adjacent faces + { + if ( nbRecursionsLeft < 0 ) + nbRecursionsLeft = nodeToContain->NbInverseElements(); + TFaceLinkList::iterator adj = adjacentFaces.begin(); + for ( ; boundaryLink == linksEnd && adj != adjacentFaces.end(); ++adj ) + boundaryLink = adj->first->GetBoundaryLink( links, *(adj->second), 0, nodeToContain, + isAdjacentUsed, nbRecursionsLeft-1); + if ( isAdjacentUsed ) *isAdjacentUsed = true; + } + return boundaryLink; + } + //================================================================================ + /*! + * \brief Return a link ending at the given node but not avoidLink + */ + //================================================================================ + + TLinkInSet QFace::GetLinkByNode( const TLinkSet& links, + const TChainLink& avoidLink, + const SMDS_MeshNode* nodeToContain) const + { + for ( int i = 0; i < _sides.size(); ++i ) + if ( avoidLink._qlink != _sides[i] && + (_sides[i]->node1() == nodeToContain || _sides[i]->node2() == nodeToContain )) + return links.find( _sides[ i ]); + return links.end(); + } + + //================================================================================ + /*! + * \brief Return normal to the i-th side pointing outside the face + */ + //================================================================================ + + gp_Vec QFace::LinkNorm(const int i, SMESH_MesherHelper* /*uvHelper*/) const + { + gp_Vec norm, vecOut; +// if ( uvHelper ) { +// TopoDS_Face face = TopoDS::Face( uvHelper->GetSubShape()); +// const SMDS_MeshNode* inFaceNode = uvHelper->GetNodeUVneedInFaceNode() ? GetNodeInFace() : 0; +// gp_XY uv1 = uvHelper->GetNodeUV( face, _sides[i]->node1(), inFaceNode ); +// gp_XY uv2 = uvHelper->GetNodeUV( face, _sides[i]->node2(), inFaceNode ); +// norm.SetCoord( uv1.Y() - uv2.Y(), uv2.X() - uv1.X(), 0 ); + +// const QLink* otherLink = _sides[(i + 1) % _sides.size()]; +// const SMDS_MeshNode* otherNode = +// otherLink->node1() == _sides[i]->node1() ? otherLink->node2() : otherLink->node1(); +// gp_XY pIn = uvHelper->GetNodeUV( face, otherNode, inFaceNode ); +// vecOut.SetCoord( uv1.X() - pIn.X(), uv1.Y() - pIn.Y(), 0 ); +// } +// else { + norm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2())); + gp_XYZ pIn = ( XYZ( _sides[0]->node1() ) + + XYZ( _sides[0]->node2() ) + + XYZ( _sides[1]->node1() )) / 3.; + vecOut.SetXYZ( _sides[i]->MiddlePnt() - pIn ); + //} + if ( norm * vecOut < 0 ) + norm.Reverse(); + double mag2 = norm.SquareMagnitude(); + if ( mag2 > numeric_limits::min() ) + norm /= sqrt( mag2 ); + return norm; + } + //================================================================================ + /*! + * \brief Move medium node of theLink according to its distance from boundary + * \param theLink - link to fix + * \param theRefVec - movement of boundary + * \param theLinks - all adjacent links of continous triangles + * \param theFaceHelper - helper is not used so far + * \param thePrevLen - distance from the boundary + * \param theStep - number of steps till movement propagation limit + * \param theLinkNorm - out normal to theLink + * \param theSign - 1 or -1 depending on movement of boundary + * \retval double - distance from boundary to propagation limit or other boundary + */ + //================================================================================ + + double QFace::MoveByBoundary( const TChainLink& theLink, + const gp_Vec& theRefVec, + const TLinkSet& theLinks, + SMESH_MesherHelper* theFaceHelper, + const double thePrevLen, + const int theStep, + gp_Vec* theLinkNorm, + double theSign) const + { + if ( !theStep ) + return thePrevLen; // propagation limit reached + + int iL; // index of theLink + for ( iL = 0; iL < _sides.size(); ++iL ) + if ( theLink._qlink == _sides[ iL ]) + break; + + MSG(string(theStep,'.')<<" Ref( "<NextFace( this ); // adjacent faces + const QFace* f2 = link2->NextFace( this ); + + // propagate to adjacent faces till limit step or boundary + double len1 = thePrevLen + (theLink->MiddlePnt() - _sides[iL1]->MiddlePnt()).Modulus(); + double len2 = thePrevLen + (theLink->MiddlePnt() - _sides[iL2]->MiddlePnt()).Modulus(); + gp_Vec linkDir1(0,0,0); // initialize to avoid valgrind error ("Conditional jump...") + gp_Vec linkDir2(0,0,0); + try { + OCC_CATCH_SIGNALS; + if ( f1 && theLink->MediumPos() <= (*link1)->MediumPos() ) + len1 = f1->MoveByBoundary + ( *link1, theRefVec, theLinks, theFaceHelper, len1, theStep-1, &linkDir1, theSign); + else + linkDir1 = LinkNorm( iL1/*, theFaceHelper*/ ); + } catch (...) { + MSG( " --------------- EXCEPTION"); + return thePrevLen; + } + try { + OCC_CATCH_SIGNALS; + if ( f2 && theLink->MediumPos() <= (*link2)->MediumPos() ) + len2 = f2->MoveByBoundary + ( *link2, theRefVec, theLinks, theFaceHelper, len2, theStep-1, &linkDir2, theSign); + else + linkDir2 = LinkNorm( iL2/*, theFaceHelper*/ ); + } catch (...) { + MSG( " --------------- EXCEPTION"); + return thePrevLen; + } + + double fullLen = 0; + if ( theStep != theFirstStep ) + { + // choose chain length by direction of propagation most codirected with theRefVec + bool choose1 = ( theRefVec * linkDir1 * theSign > theRefVec * linkDir2 * theSign ); + fullLen = choose1 ? len1 : len2; + double r = thePrevLen / fullLen; + + gp_Vec move = linkNorm * refProj * ( 1 - r ); + theLink->Move( move, true ); + + MSG(string(theStep,'.')<<" Move "<< theLink->_mediumNode->GetID()<< + " by " << refProj * ( 1 - r ) << " following " << + (choose1 ? *link1->_qlink : *link2->_qlink)); + + if ( theLinkNorm ) *theLinkNorm = linkNorm; + } + return fullLen; + } + + //================================================================================ + /*! + * \brief Checks if the face is distorted due to bentLink + */ + //================================================================================ + + bool QFace::IsSpoiled(const QLink* bentLink ) const + { + // code is valid for convex faces only + gp_XYZ gc(0,0,0); + for ( TIDSortedNodeSet::const_iterator n = begin(); n!=end(); ++n) + gc += XYZ( *n ) / size(); + for (unsigned i = 0; i < _sides.size(); ++i ) + { + if ( _sides[i] == bentLink ) continue; + gp_Vec linkNorm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2())); + gp_Vec vecOut( gc, _sides[i]->MiddlePnt() ); + if ( linkNorm * vecOut < 0 ) + linkNorm.Reverse(); + double mag2 = linkNorm.SquareMagnitude(); + if ( mag2 > numeric_limits::min() ) + linkNorm /= sqrt( mag2 ); + gp_Vec vecBent ( _sides[i]->MiddlePnt(), bentLink->MediumPnt()); + gp_Vec vecStraight( _sides[i]->MiddlePnt(), bentLink->MiddlePnt()); + if ( vecBent * linkNorm > -0.1*vecStraight.Magnitude() ) + return true; + } + return false; + + } + + //================================================================================ + /*! + * \brief Find pairs of continues faces + */ + //================================================================================ + + void QLink::SetContinuesFaces() const + { + // x0 x - QLink, [-|] - QFace, v - volume + // v0 | v1 + // | Between _faces of link x2 two vertical faces are continues + // x1----x2-----x3 and two horizontal faces are continues. We set vertical faces + // | to _faces[0] and _faces[1] and horizontal faces to + // v2 | v3 _faces[2] and _faces[3] (or vise versa). + // x4 + + if ( _faces.empty() ) + return; + int iFaceCont = -1, nbBoundary = 0, iBoundary[2]={-1,-1}; + if ( _faces[0]->IsBoundary() ) + iBoundary[ nbBoundary++ ] = 0; + for ( int iF = 1; iFaceCont < 0 && iF < _faces.size(); ++iF ) + { + // look for a face bounding none of volumes bound by _faces[0] + bool sameVol = false; + int nbVol = _faces[iF]->NbVolumes(); + for ( int iV = 0; !sameVol && iV < nbVol; ++iV ) + sameVol = ( _faces[iF]->_volumes[iV] == _faces[0]->_volumes[0] || + _faces[iF]->_volumes[iV] == _faces[0]->_volumes[1]); + if ( !sameVol ) + iFaceCont = iF; + if ( _faces[iF]->IsBoundary() ) + iBoundary[ nbBoundary++ ] = iF; + } + // Set continues faces: arrange _faces to have + // _faces[0] continues to _faces[1] + // _faces[2] continues to _faces[3] + if ( nbBoundary == 2 ) // bnd faces are continues + { + if (( iBoundary[0] < 2 ) != ( iBoundary[1] < 2 )) + { + int iNear0 = iBoundary[0] < 2 ? 1-iBoundary[0] : 5-iBoundary[0]; + std::swap( _faces[ iBoundary[1] ], _faces[iNear0] ); + } + } + else if ( iFaceCont > 0 ) // continues faces found + { + if ( iFaceCont != 1 ) + std::swap( _faces[1], _faces[iFaceCont] ); + } + else if ( _faces.size() > 1 ) // not found, set NULL by the first face + { + _faces.insert( ++_faces.begin(), 0 ); + } + } + //================================================================================ + /*! + * \brief Return a face continues to the given one + */ + //================================================================================ + + const QFace* QLink::GetContinuesFace( const QFace* face ) const + { + for ( int i = 0; i < _faces.size(); ++i ) { + if ( _faces[i] == face ) { + int iF = i < 2 ? 1-i : 5-i; + return iF < _faces.size() ? _faces[iF] : 0; + } + } + return 0; + } + //================================================================================ + /*! + * \brief True if link is on mesh boundary + */ + //================================================================================ + + bool QLink::OnBoundary() const + { + for ( int i = 0; i < _faces.size(); ++i ) + if (_faces[i] && _faces[i]->IsBoundary()) return true; + return false; + } + //================================================================================ + /*! + * \brief Return normal of link of the chain + */ + //================================================================================ + + gp_Vec TChainLink::Normal() const { + gp_Vec norm; + if (_qfaces[0]) norm = _qfaces[0]->_normal; + if (_qfaces[1]) norm += _qfaces[1]->_normal; + return norm; + } + //================================================================================ + /*! + * \brief Test link curvature taking into account size of faces + */ + //================================================================================ + + bool TChainLink::IsStraight() const + { + bool isStraight = _qlink->IsStraight(); + if ( isStraight && _qfaces[0] && !_qfaces[1] ) + { + int i = _qfaces[0]->LinkIndex( _qlink ); + int iOpp = ( i + 2 ) % _qfaces[0]->_sides.size(); + gp_XYZ mid1 = _qlink->MiddlePnt(); + gp_XYZ mid2 = _qfaces[0]->_sides[ iOpp ]->MiddlePnt(); + double faceSize2 = (mid1-mid2).SquareModulus(); + isStraight = _qlink->_nodeMove.SquareMagnitude() < 1/10./10. * faceSize2; + } + return isStraight; + } + + //================================================================================ + /*! + * \brief Move medium nodes of vertical links of pentahedrons adjacent by side faces + */ + //================================================================================ + + void fixPrism( TChain& allLinks ) + { + // separate boundary links from internal ones + typedef set QLinkSet; + QLinkSet interLinks, bndLinks1, bndLink2; + + bool isCurved = false; + for ( TChain::iterator lnk = allLinks.begin(); lnk != allLinks.end(); ++lnk ) { + if ( (*lnk)->OnBoundary() ) + bndLinks1.insert( lnk->_qlink ); + else + interLinks.insert( lnk->_qlink ); + isCurved = isCurved || !lnk->IsStraight(); + } + if ( !isCurved ) + return; // no need to move + + QLinkSet *curBndLinks = &bndLinks1, *newBndLinks = &bndLink2; + + while ( !interLinks.empty() && !curBndLinks->empty() ) + { + // propagate movement from boundary links to connected internal links + QLinkSet::iterator bnd = curBndLinks->begin(), bndEnd = curBndLinks->end(); + for ( ; bnd != bndEnd; ++bnd ) + { + const QLink* bndLink = *bnd; + for ( int i = 0; i < bndLink->_faces.size(); ++i ) // loop on faces of bndLink + { + const QFace* face = bndLink->_faces[i]; // quadrange lateral face of a prism + if ( !face ) continue; + // find and move internal link opposite to bndLink within the face + int interInd = ( face->LinkIndex( bndLink ) + 2 ) % face->_sides.size(); + const QLink* interLink = face->_sides[ interInd ]; + QLinkSet::iterator pInterLink = interLinks.find( interLink ); + if ( pInterLink == interLinks.end() ) continue; // not internal link + interLink->Move( bndLink->_nodeMove ); + // treated internal links become new boundary ones + interLinks. erase( pInterLink ); + newBndLinks->insert( interLink ); + } + } + curBndLinks->clear(); + std::swap( curBndLinks, newBndLinks ); + } + } + + //================================================================================ + /*! + * \brief Fix links of continues triangles near curved boundary + */ + //================================================================================ + + void fixTriaNearBoundary( TChain & allLinks, SMESH_MesherHelper& /*helper*/) + { + if ( allLinks.empty() ) return; + + TLinkSet linkSet( allLinks.begin(), allLinks.end()); + TLinkInSet linkIt = linkSet.begin(), linksEnd = linkSet.end(); + + for ( linkIt = linkSet.begin(); linkIt != linksEnd; ++linkIt) + { + if ( linkIt->IsBoundary() && !linkIt->IsStraight() && linkIt->_qfaces[0]) + { + // move iff a boundary link is bent towards inside of a face (issue 0021084) + const QFace* face = linkIt->_qfaces[0]; + gp_XYZ pIn = ( face->_sides[0]->MiddlePnt() + + face->_sides[1]->MiddlePnt() + + face->_sides[2]->MiddlePnt() ) / 3.; + gp_XYZ insideDir( pIn - (*linkIt)->MiddlePnt()); + bool linkBentInside = ((*linkIt)->_nodeMove.Dot( insideDir ) > 0 ); + //if ( face->IsSpoiled( linkIt->_qlink )) + if ( linkBentInside ) + face->MoveByBoundary( *linkIt, (*linkIt)->_nodeMove, linkSet ); + } + } + } + + //================================================================================ + /*! + * \brief Detect rectangular structure of links and build chains from them + */ + //================================================================================ + + enum TSplitTriaResult { + _OK, _NO_CORNERS, _FEW_ROWS, _MANY_ROWS, _NO_SIDELINK, _BAD_MIDQUAD, _NOT_RECT, + _NO_MIDQUAD, _NO_UPTRIA, _BAD_SET_SIZE, _BAD_CORNER, _BAD_START, _NO_BOTLINK, _TWISTED_CHAIN }; + + TSplitTriaResult splitTrianglesIntoChains( TChain & allLinks, + vector< TChain> & resultChains, + SMDS_TypeOfPosition pos ) + { + // put links in the set and evalute number of result chains by number of boundary links + TLinkSet linkSet; + int nbBndLinks = 0; + for ( TChain::iterator lnk = allLinks.begin(); lnk != allLinks.end(); ++lnk ) { + linkSet.insert( *lnk ); + nbBndLinks += lnk->IsBoundary(); + } + resultChains.clear(); + resultChains.reserve( nbBndLinks / 2 ); + + TLinkInSet linkIt, linksEnd = linkSet.end(); + + // find a boundary link with corner node; corner node has position pos-2 + // i.e. SMDS_TOP_VERTEX for links on faces and SMDS_TOP_EDGE for + // links in volume + SMDS_TypeOfPosition cornerPos = SMDS_TypeOfPosition(pos-2); + const SMDS_MeshNode* corner = 0; + for ( linkIt = linkSet.begin(); linkIt != linksEnd; ++linkIt ) + if ( linkIt->IsBoundary() && (corner = (*linkIt)->EndPosNode(cornerPos))) + break; + if ( !corner) + return _NO_CORNERS; + + TLinkInSet startLink = linkIt; + const SMDS_MeshNode* startCorner = corner; + vector< TChain* > rowChains; + int iCol = 0; + + while ( startLink != linksEnd) // loop on columns + { + // We suppose we have a rectangular structure like shown here. We have found a + // corner of the rectangle (startCorner) and a boundary link sharing + // |/ |/ | the startCorner (startLink). We are going to loop on rows of the + // --o---o---o structure making several chains at once. One chain (columnChain) + // |\ | /| starts at startLink and continues upward (we look at the structure + // \ | \ | / | from such point that startLink is on the bottom of the structure). + // \| \|/ | While going upward we also fill horizontal chains (rowChains) we + // --o---o---o encounter. + // /|\ |\ | + // / | \ | \ | startCorner + // | \| \|,' + // --o---o---o + // `.startLink + + if ( resultChains.size() == nbBndLinks / 2 ) + return _NOT_RECT; + resultChains.push_back( TChain() ); + TChain& columnChain = resultChains.back(); + + TLinkInSet botLink = startLink; // current horizontal link to go up from + corner = startCorner; // current corner the botLink ends at + int iRow = 0; + while ( botLink != linksEnd ) // loop on rows + { + // add botLink to the columnChain + columnChain.push_back( *botLink ); + + const QFace* botTria = botLink->_qfaces[0]; // bottom triangle bound by botLink + if ( !botTria ) + { // the column ends + if ( botLink == startLink ) + return _TWISTED_CHAIN; // issue 0020951 + linkSet.erase( botLink ); + if ( iRow != rowChains.size() ) + return _FEW_ROWS; // different nb of rows in columns + break; + } + // find the link dividing the quadrangle (midQuadLink) and vertical boundary + // link ending at (sideLink); there are two cases: + // 1) midQuadLink does not end at , then we easily find it by botTria, + // since midQuadLink is not at boundary while sideLink is. + // 2) midQuadLink ends at + bool isCase2; + TLinkInSet midQuadLink = linksEnd; + TLinkInSet sideLink = botTria->GetBoundaryLink( linkSet, *botLink, &midQuadLink, + corner, &isCase2 ); + if ( isCase2 ) { // find midQuadLink among links of botTria + midQuadLink = botTria->GetLinkByNode( linkSet, *botLink, corner ); + if ( midQuadLink->IsBoundary() ) + return _BAD_MIDQUAD; + } + if ( sideLink == linksEnd || midQuadLink == linksEnd || sideLink == midQuadLink ) + return sideLink == linksEnd ? _NO_SIDELINK : _NO_MIDQUAD; + + // fill chains + columnChain.push_back( *midQuadLink ); + if ( iRow >= rowChains.size() ) { + if ( iCol > 0 ) + return _MANY_ROWS; // different nb of rows in columns + if ( resultChains.size() == nbBndLinks / 2 ) + return _NOT_RECT; + resultChains.push_back( TChain() ); + rowChains.push_back( & resultChains.back() ); + } + rowChains[iRow]->push_back( *sideLink ); + rowChains[iRow]->push_back( *midQuadLink ); + + const QFace* upTria = midQuadLink->NextFace( botTria ); // upper tria of the rectangle + if ( !upTria) + return _NO_UPTRIA; + if ( iRow == 0 ) { + // prepare startCorner and startLink for the next column + startCorner = startLink->NextNode( startCorner ); + if (isCase2) + startLink = botTria->GetBoundaryLink( linkSet, *botLink, 0, startCorner ); + else + startLink = upTria->GetBoundaryLink( linkSet, *midQuadLink, 0, startCorner ); + // check if no more columns remains + if ( startLink != linksEnd ) { + const SMDS_MeshNode* botNode = startLink->NextNode( startCorner ); + if ( (isCase2 ? botTria : upTria)->Contains( botNode )) + startLink = linksEnd; // startLink bounds upTria or botTria + else if ( startLink == botLink || startLink == midQuadLink || startLink == sideLink ) + return _BAD_START; + } + } + // find bottom link and corner for the next row + corner = sideLink->NextNode( corner ); + // next bottom link ends at the new corner + linkSet.erase( botLink ); + botLink = upTria->GetLinkByNode( linkSet, (isCase2 ? *sideLink : *midQuadLink), corner ); + if ( botLink == linksEnd || botLink == midQuadLink || botLink == sideLink) + return _NO_BOTLINK; + if ( midQuadLink == startLink || sideLink == startLink ) + return _TWISTED_CHAIN; // issue 0020951 + linkSet.erase( midQuadLink ); + linkSet.erase( sideLink ); + + // make faces neighboring the found ones be boundary + if ( startLink != linksEnd ) { + const QFace* tria = isCase2 ? botTria : upTria; + for ( int iL = 0; iL < 3; ++iL ) { + linkIt = linkSet.find( tria->_sides[iL] ); + if ( linkIt != linksEnd ) + linkIt->RemoveFace( tria ); + } + } + if ( botLink->_qfaces[0] == upTria || botLink->_qfaces[1] == upTria ) + botLink->RemoveFace( upTria ); // make next botTria first in vector + + iRow++; + } // loop on rows + + iCol++; + } + // In the linkSet, there must remain the last links of rowChains; add them + if ( linkSet.size() != rowChains.size() ) + return _BAD_SET_SIZE; + for ( int iRow = 0; iRow < rowChains.size(); ++iRow ) { + // find the link (startLink) ending at startCorner + corner = 0; + for ( startLink = linkSet.begin(); startLink != linksEnd; ++startLink ) { + if ( (*startLink)->node1() == startCorner ) { + corner = (*startLink)->node2(); break; + } + else if ( (*startLink)->node2() == startCorner) { + corner = (*startLink)->node1(); break; + } + } + if ( startLink == linksEnd ) + return _BAD_CORNER; + rowChains[ iRow ]->push_back( *startLink ); + linkSet.erase( startLink ); + startCorner = corner; + } + + return _OK; + } +} //namespace + +//======================================================================= +/*! + * \brief Move medium nodes of faces and volumes to fix distorted elements + * \param volumeOnly - to fix nodes on faces or not, if the shape is solid + * + * Issue 0020307: EDF 992 SMESH : Linea/Quadratic with Medium Node on Geometry + */ +//======================================================================= + +void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) +{ + // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion + if ( getenv("NO_FixQuadraticElements") ) + return; + + // 0. Apply algorithm to SOLIDs or FACEs + // ---------------------------------------------- + if ( myShape.IsNull() ) { + if ( !myMesh->HasShapeToMesh() ) return; + SetSubShape( myMesh->GetShapeToMesh() ); + +#ifdef _DEBUG_ + int nbSolids = 0; + TopTools_IndexedMapOfShape solids; + TopExp::MapShapes(myShape,TopAbs_SOLID,solids); + nbSolids = solids.Extent(); +#endif + TopTools_MapOfShape faces; // faces not in solid or in not meshed solid + for ( TopExp_Explorer f(myShape,TopAbs_FACE,TopAbs_SOLID); f.More(); f.Next() ) { + faces.Add( f.Current() ); // not in solid + } + for ( TopExp_Explorer s(myShape,TopAbs_SOLID); s.More(); s.Next() ) { + if ( myMesh->GetSubMesh( s.Current() )->IsEmpty() ) { // get faces of solid + for ( TopExp_Explorer f( s.Current(), TopAbs_FACE); f.More(); f.Next() ) + faces.Add( f.Current() ); // in not meshed solid + } + else { // fix nodes in the solid and its faces +#ifdef _DEBUG_ + MSG("FIX SOLID " << nbSolids-- << " #" << GetMeshDS()->ShapeToIndex(s.Current())); +#endif + SMESH_MesherHelper h(*myMesh); + h.SetSubShape( s.Current() ); + h.FixQuadraticElements(false); + } + } + // fix nodes on geom faces +#ifdef _DEBUG_ + int nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; +#endif + for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) { + MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); + SMESH_MesherHelper h(*myMesh); + h.SetSubShape( fIt.Key() ); + h.FixQuadraticElements(true); + h.ToFixNodeParameters(true); + } + //perf_print_all_meters(1); + return; + } + + // 1. Find out type of elements and get iterator on them + // --------------------------------------------------- + + SMDS_ElemIteratorPtr elemIt; + SMDSAbs_ElementType elemType = SMDSAbs_All; + + SMESH_subMesh* submesh = myMesh->GetSubMeshContaining( myShapeID ); + if ( !submesh ) + return; + if ( SMESHDS_SubMesh* smDS = submesh->GetSubMeshDS() ) { + elemIt = smDS->GetElements(); + if ( elemIt->more() ) { + elemType = elemIt->next()->GetType(); + elemIt = smDS->GetElements(); + } + } + if ( !elemIt || !elemIt->more() || elemType < SMDSAbs_Face ) + return; + + // 2. Fill in auxiliary data structures + // ---------------------------------- + + set< QLink > links; + set< QFace > faces; + set< QLink >::iterator pLink; + set< QFace >::iterator pFace; + + bool isCurved = false; + //bool hasRectFaces = false; + //set nbElemNodeSet; + SMDS_VolumeTool volTool; + + TIDSortedNodeSet apexOfPyramid; + const int apexIndex = 4; + + if ( elemType == SMDSAbs_Volume ) + { + while ( elemIt->more() ) // loop on volumes + { + const SMDS_MeshElement* vol = elemIt->next(); + if ( !vol->IsQuadratic() || !volTool.Set( vol )) + return; + double volMinSize2 = -1.; + for ( int iF = 0; iF < volTool.NbFaces(); ++iF ) // loop on faces of volume + { + int nbN = volTool.NbFaceNodes( iF ); + //nbElemNodeSet.insert( nbN ); + const SMDS_MeshNode** faceNodes = volTool.GetFaceNodes( iF ); + vector< const QLink* > faceLinks( nbN/2 ); + for ( int iN = 0; iN < nbN; iN += 2 ) // loop on links of a face + { + // store QLink + QLink link( faceNodes[iN], faceNodes[iN+2], faceNodes[iN+1] ); + pLink = links.insert( link ).first; + faceLinks[ iN/2 ] = & *pLink; + + if ( link.MediumPos() == SMDS_TOP_3DSPACE ) + { + if ( !link.IsStraight() ) + return; // already fixed + } + else if ( !isCurved ) + { + if ( volMinSize2 < 0 ) volMinSize2 = volTool.MinLinearSize2(); + isCurved = !isStraightLink( volMinSize2, link._nodeMove.SquareMagnitude() ); + } + } + // store QFace + pFace = faces.insert( QFace( faceLinks )).first; + if ( pFace->NbVolumes() == 0 ) + pFace->AddSelfToLinks(); + pFace->SetVolume( vol ); +// hasRectFaces = hasRectFaces || +// ( volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_HEXA || +// volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_PENTA ); +#ifdef _DEBUG_ + if ( nbN == 6 ) + pFace->_face = GetMeshDS()->FindFace(faceNodes[0],faceNodes[2],faceNodes[4]); + else + pFace->_face = GetMeshDS()->FindFace(faceNodes[0],faceNodes[2], + faceNodes[4],faceNodes[6] ); +#endif + } + // collect pyramid apexes for further correction + if ( vol->NbCornerNodes() == 5 ) + apexOfPyramid.insert( vol->GetNode( apexIndex )); + } + set< QLink >::iterator pLink = links.begin(); + for ( ; pLink != links.end(); ++pLink ) + pLink->SetContinuesFaces(); + } + else + { + while ( elemIt->more() ) // loop on faces + { + const SMDS_MeshElement* face = elemIt->next(); + if ( !face->IsQuadratic() ) + continue; + //nbElemNodeSet.insert( face->NbNodes() ); + int nbN = face->NbNodes()/2; + vector< const QLink* > faceLinks( nbN ); + for ( int iN = 0; iN < nbN; ++iN ) // loop on links of a face + { + // store QLink + QLink link( face->GetNode(iN), face->GetNode((iN+1)%nbN), face->GetNode(iN+nbN) ); + pLink = links.insert( link ).first; + faceLinks[ iN ] = & *pLink; + if ( !isCurved ) + isCurved = !link.IsStraight(); + } + // store QFace + pFace = faces.insert( QFace( faceLinks )).first; + pFace->AddSelfToLinks(); + //hasRectFaces = ( hasRectFaces || nbN == 4 ); + } + } + if ( !isCurved ) + return; // no curved edges of faces + + // 3. Compute displacement of medium nodes + // --------------------------------------- + + // two loops on QFaces: the first is to treat boundary links, the second is for internal ones + TopLoc_Location loc; + // not treat boundary of volumic submesh + int isInside = ( elemType == SMDSAbs_Volume && volumeOnly ) ? 1 : 0; + for ( ; isInside < 2; ++isInside ) { + MSG( "--------------- LOOP (inside=" << isInside << ") ------------------"); + SMDS_TypeOfPosition pos = isInside ? SMDS_TOP_3DSPACE : SMDS_TOP_FACE; + SMDS_TypeOfPosition bndPos = isInside ? SMDS_TOP_FACE : SMDS_TOP_EDGE; + + for ( pFace = faces.begin(); pFace != faces.end(); ++pFace ) { + if ( bool(isInside) == pFace->IsBoundary() ) + continue; + for ( int dir = 0; dir < 2; ++dir ) // 2 directions of propagation from the quadrangle + { + MSG( "CHAIN"); + // make chain of links connected via continues faces + int error = ERR_OK; + TChain rawChain; + if ( !pFace->GetLinkChain( dir, rawChain, pos, error) && error ==ERR_UNKNOWN ) continue; + rawChain.reverse(); + if ( !pFace->GetLinkChain( dir+2, rawChain, pos, error ) && error ==ERR_UNKNOWN ) continue; + + vector< TChain > chains; + if ( error == ERR_OK ) { // chain contains continues rectangles + chains.resize(1); + chains[0].splice( chains[0].begin(), rawChain ); + } + else if ( error == ERR_TRI ) { // chain contains continues triangles + TSplitTriaResult res = splitTrianglesIntoChains( rawChain, chains, pos ); + if ( res != _OK ) { // not quadrangles split into triangles + fixTriaNearBoundary( rawChain, *this ); + break; + } + } + else if ( error == ERR_PRISM ) { // quadrangle side faces of prisms + fixPrism( rawChain ); + break; + } + else { + continue; + } + for ( int iC = 0; iC < chains.size(); ++iC ) + { + TChain& chain = chains[iC]; + if ( chain.empty() ) continue; + if ( chain.front().IsStraight() && chain.back().IsStraight() ) { + MSG("3D straight - ignore"); + continue; + } + if ( chain.front()->MediumPos() > bndPos || + chain.back() ->MediumPos() > bndPos ) { + MSG("Internal chain - ignore"); + continue; + } + // mesure chain length and compute link position along the chain + double chainLen = 0; + vector< double > linkPos; + MSGBEG( "Link medium nodes: "); + TChain::iterator link0 = chain.begin(), link1 = chain.begin(), link2; + for ( ++link1; link1 != chain.end(); ++link1, ++link0 ) { + MSGBEG( (*link0)->_mediumNode->GetID() << "-" <<(*link1)->_mediumNode->GetID()<<" "); + double len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus(); + while ( len < numeric_limits::min() ) { // remove degenerated link + link1 = chain.erase( link1 ); + if ( link1 == chain.end() ) + break; + len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus(); + } + chainLen += len; + linkPos.push_back( chainLen ); + } + MSG(""); + if ( linkPos.size() < 2 ) + continue; + + gp_Vec move0 = chain.front()->_nodeMove; + gp_Vec move1 = chain.back ()->_nodeMove; + + TopoDS_Face face; + bool checkUV = true; + if ( !isInside ) + { + // compute node displacement of end links of chain in parametric space of face + TChainLink& linkOnFace = *(++chain.begin()); + const SMDS_MeshNode* nodeOnFace = linkOnFace->_mediumNode; + TopoDS_Shape f = GetSubShapeByNode( nodeOnFace, GetMeshDS() ); + if ( !f.IsNull() && f.ShapeType() == TopAbs_FACE ) + { + face = TopoDS::Face( f ); + Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc); + bool isStraight[2]; + for ( int is1 = 0; is1 < 2; ++is1 ) // move0 or move1 + { + TChainLink& link = is1 ? chain.back() : chain.front(); + gp_XY uvm = GetNodeUV( face, link->_mediumNode, nodeOnFace, &checkUV); + gp_XY uv1 = GetNodeUV( face, link->node1(), nodeOnFace, &checkUV); + gp_XY uv2 = GetNodeUV( face, link->node2(), nodeOnFace, &checkUV); + gp_XY uv12 = GetMiddleUV( surf, uv1, uv2); + // uvMove = uvm - uv12 + gp_XY uvMove = applyIn2D(surf, uvm, uv12, gp_XY_Subtracted, /*inPeriod=*/false); + ( is1 ? move1 : move0 ).SetCoord( uvMove.X(), uvMove.Y(), 0 ); + if ( !is1 ) // correct nodeOnFace for move1 (issue 0020919) + nodeOnFace = (*(++chain.rbegin()))->_mediumNode; + isStraight[is1] = isStraightLink( (uv2-uv1).SquareModulus(), + 10 * uvMove.SquareModulus()); + } + if ( isStraight[0] && isStraight[1] ) { + MSG("2D straight - ignore"); + continue; // straight - no need to move nodes of internal links + } + + // check if a chain is already fixed + gp_XY uvm = GetNodeUV( face, linkOnFace->_mediumNode, 0, &checkUV); + gp_XY uv1 = GetNodeUV( face, linkOnFace->node1(), nodeOnFace, &checkUV); + gp_XY uv2 = GetNodeUV( face, linkOnFace->node2(), nodeOnFace, &checkUV); + gp_XY uv12 = GetMiddleUV( surf, uv1, uv2); + if (( uvm - uv12 ).SquareModulus() > 1e-10 ) + { + MSG("Already fixed - ignore"); + continue; + } + } + } + gp_Trsf trsf; + if ( isInside || face.IsNull() ) + { + // compute node displacement of end links in their local coord systems + { + TChainLink& ln0 = chain.front(), ln1 = *(++chain.begin()); + trsf.SetTransformation( gp_Ax3( gp::Origin(), ln0.Normal(), + gp_Vec( ln0->MiddlePnt(), ln1->MiddlePnt() ))); + move0.Transform(trsf); + } + { + TChainLink& ln0 = *(++chain.rbegin()), ln1 = chain.back(); + trsf.SetTransformation( gp_Ax3( gp::Origin(), ln1.Normal(), + gp_Vec( ln0->MiddlePnt(), ln1->MiddlePnt() ))); + move1.Transform(trsf); + } + } + // compute displacement of medium nodes + link2 = chain.begin(); + link0 = link2++; + link1 = link2++; + for ( int i = 0; link2 != chain.end(); ++link0, ++link1, ++link2, ++i ) + { + double r = linkPos[i] / chainLen; + // displacement in local coord system + gp_Vec move = (1. - r) * move0 + r * move1; + if ( isInside || face.IsNull()) { + // transform to global + gp_Vec x01( (*link0)->MiddlePnt(), (*link1)->MiddlePnt() ); + gp_Vec x12( (*link1)->MiddlePnt(), (*link2)->MiddlePnt() ); + gp_Vec x = x01.Normalized() + x12.Normalized(); + trsf.SetTransformation( gp_Ax3( gp::Origin(), link1->Normal(), x), gp_Ax3() ); + move.Transform(trsf); + } + else { + // compute 3D displacement by 2D one + Handle(Geom_Surface) s = BRep_Tool::Surface(face,loc); + gp_XY oldUV = GetNodeUV( face, (*link1)->_mediumNode, 0, &checkUV); + gp_XY newUV = applyIn2D( s, oldUV, gp_XY( move.X(),move.Y()), gp_XY_Added); + gp_Pnt newPnt = s->Value( newUV.X(), newUV.Y()); + move = gp_Vec( XYZ((*link1)->_mediumNode), newPnt.Transformed(loc) ); +#ifdef _DEBUG_ + if ( (XYZ((*link1)->node1()) - XYZ((*link1)->node2())).SquareModulus() < + move.SquareMagnitude()) + { + gp_XY uv0 = GetNodeUV( face, (*link0)->_mediumNode, 0, &checkUV); + gp_XY uv2 = GetNodeUV( face, (*link2)->_mediumNode, 0, &checkUV); + MSG( "TOO LONG MOVE \t" << + "uv0: "<Move( move ); + MSG( "Move " << (*link1)->_mediumNode->GetID() << " following " + << chain.front()->_mediumNode->GetID() <<"-" + << chain.back ()->_mediumNode->GetID() << + " by " << move.Magnitude()); + } + } // loop on chains of links + } // loop on 2 directions of propagation from quadrangle + } // loop on faces + } + + // 4. Move nodes + // ------------- + +// vector vols( 100 ); +// vector volSize( 100 ); +// int nbVols; +// bool ok; + for ( pLink = links.begin(); pLink != links.end(); ++pLink ) { + if ( pLink->IsMoved() ) { + gp_Pnt p = pLink->MiddlePnt() + pLink->Move(); + GetMeshDS()->MoveNode( pLink->_mediumNode, p.X(), p.Y(), p.Z()); + // +// gp_Pnt pNew = pLink->MiddlePnt() + pLink->Move(); +// if ( pLink->MediumPos() != SMDS_TOP_3DSPACE ) +// { +// // avoid making distorted volumes near boundary +// SMDS_ElemIteratorPtr volIt = +// (*pLink)._mediumNode->GetInverseElementIterator( SMDSAbs_Volume ); +// for ( nbVols = 0; volIt->more() && volTool.Set( volIt->next() ); ++nbVols ) +// { +// vols [ nbVols ] = volTool.Element(); +// volSize[ nbVols ] = volTool.GetSize(); +// } +// gp_Pnt pOld = pLink->MediumPnt(); +// const_cast( pLink->_mediumNode )->setXYZ( pNew.X(), pNew.Y(), pNew.Z() ); +// ok = true; +// while ( nbVols-- && ok ) +// { +// volTool.Set( vols[ nbVols ]); +// ok = ( volSize[ nbVols ] * volTool.GetSize() > 1e-20 ); +// } +// if ( !ok ) +// { +// const_cast( pLink->_mediumNode )->setXYZ( pOld.X(), pOld.Y(), pOld.Z() ); +// MSG( "Do NOT move \t" << pLink->_mediumNode->GetID() +// << " because of distortion of volume " << vols[ nbVols+1 ]->GetID()); +// continue; +// } +// } +// GetMeshDS()->MoveNode( pLink->_mediumNode, pNew.X(), pNew.Y(), pNew.Z() ); + } + } + + //return; + + // issue 0020982 + // Move the apex of pyramid together with the most curved link + + TIDSortedNodeSet::iterator apexIt = apexOfPyramid.begin(); + for ( ; apexIt != apexOfPyramid.end(); ++apexIt ) + { + SMESH_TNodeXYZ apex = *apexIt; + + gp_Vec maxMove( 0,0,0 ); + double maxMoveSize2 = 0; + + // shift of node index to get medium nodes between the base nodes + const int base2MediumShift = 5; + + // find maximal movement of medium node + SMDS_ElemIteratorPtr volIt = apex._node->GetInverseElementIterator( SMDSAbs_Volume ); + vector< const SMDS_MeshElement* > pyramids; + while ( volIt->more() ) + { + const SMDS_MeshElement* pyram = volIt->next(); + if ( pyram->GetEntityType() != SMDSEntity_Quad_Pyramid ) continue; + pyramids.push_back( pyram ); + + for ( int iBase = 0; iBase < apexIndex; ++iBase ) + { + SMESH_TNodeXYZ medium = pyram->GetNode( iBase + base2MediumShift ); + if ( medium._node->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE ) + { + SMESH_TNodeXYZ n1 = pyram->GetNode( iBase ); + SMESH_TNodeXYZ n2 = pyram->GetNode( ( iBase+1 ) % 4 ); + gp_Pnt middle = 0.5 * ( n1 + n2 ); + gp_Vec move( middle, medium ); + double moveSize2 = move.SquareMagnitude(); + if ( moveSize2 > maxMoveSize2 ) + maxMove = move, maxMoveSize2 = moveSize2; + } + } + } + + // move the apex + if ( maxMoveSize2 > 1e-20 ) + { + apex += maxMove.XYZ(); + GetMeshDS()->MoveNode( apex._node, apex.X(), apex.Y(), apex.Z()); + + // move medium nodes neighboring the apex to the middle + const int base2MediumShift_2 = 9; + for ( unsigned i = 0; i < pyramids.size(); ++i ) + for ( int iBase = 0; iBase < apexIndex; ++iBase ) + { + SMESH_TNodeXYZ base = pyramids[i]->GetNode( iBase ); + const SMDS_MeshNode* medium = pyramids[i]->GetNode( iBase + base2MediumShift_2 ); + gp_XYZ middle = 0.5 * ( apex + base ); + GetMeshDS()->MoveNode( medium, middle.X(), middle.Y(), middle.Z()); + } + } + } +} + diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index f88f1fc08..c74dfb858 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File: SMESH_MesherHelper.hxx // Created: 15.02.06 14:48:09 // Author: Sergey KUUL @@ -28,19 +29,34 @@ #include "SMESH_SMESH.hxx" -#include -#include +#include "SMESH_MeshEditor.hxx" // needed for many meshers #include +#include + +#include #include +#include #include -#include #include +#include + +class GeomAPI_ProjectPointOnSurf; +class GeomAPI_ProjectPointOnCurve; +class SMESH_ProxyMesh; + +typedef std::map TLinkNodeMap; +typedef std::map::iterator ItTLinkNode; + +typedef SMDS_Iterator PShapeIterator; +typedef boost::shared_ptr< PShapeIterator > PShapeIteratorPtr; + +typedef std::vector TNodeColumn; +typedef std::map< double, TNodeColumn > TParam2ColumnMap; -typedef std::pair NLink; -typedef std::map NLinkNodeMap; -typedef std::map::iterator ItNLinkNode; +typedef gp_XY (*xyFunPtr)(const gp_XY& uv1, const gp_XY& uv2); +//======================================================================= /*! * \brief It helps meshers to add elements * @@ -49,9 +65,7 @@ typedef std::map::iterator ItNLinkNode; * It defines degree of elements to create when IsQuadraticSubMesh() * is called. */ - -typedef std::vector TNodeColumn; -typedef std::map< double, TNodeColumn > TParam2ColumnMap; +//======================================================================= class SMESH_EXPORT SMESH_MesherHelper { @@ -71,28 +85,36 @@ public: * \brief Load nodes bound to face into a map of node columns * \param theParam2ColumnMap - map of node columns to fill * \param theFace - the face on which nodes are searched for - * \param theBaseEdge - the edge nodes of which are columns' bases + * \param theBaseSide - the edges holding nodes on which columns' bases * \param theMesh - the mesh containing nodes * \retval bool - false if something is wrong * * The key of the map is a normalized parameter of each - * base node on theBaseEdge. + * base node on theBaseSide. Edges in theBaseSide must be sequenced. * This method works in supposition that nodes on the face * forms a rectangular grid and elements can be quardrangles or triangles */ + static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, + const TopoDS_Face& theFace, + const std::list& theBaseSide, + SMESHDS_Mesh* theMesh, + SMESH_ProxyMesh* theProxyMesh=0); + /*! + * \brief Variant of LoadNodeColumns() above with theBaseSide given by one edge + */ static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap, const TopoDS_Face& theFace, const TopoDS_Edge& theBaseEdge, - SMESHDS_Mesh* theMesh); + SMESHDS_Mesh* theMesh, + SMESH_ProxyMesh* theProxyMesh=0); /*! * \brief Return support shape of a node * \param node - the node * \param meshDS - mesh DS * \retval TopoDS_Shape - found support shape */ - static const TopoDS_Shape& GetSubShapeByNode(const SMDS_MeshNode* node, - SMESHDS_Mesh* meshDS) - { return meshDS->IndexToShape( node->GetPosition()->GetShapeId() ); } + static TopoDS_Shape GetSubShapeByNode(const SMDS_MeshNode* node, + const SMESHDS_Mesh* meshDS); /*! * \brief Return a valid node index, fixing the given one if necessary @@ -106,6 +128,43 @@ public: return ind; } + /*! + * \brief Return number of unique ancestors of the shape + */ + static int NbAncestors(const TopoDS_Shape& shape, + const SMESH_Mesh& mesh, + TopAbs_ShapeEnum ancestorType=TopAbs_SHAPE); + /*! + * \brief Return iterator on ancestors of the given type + */ + static PShapeIteratorPtr GetAncestors(const TopoDS_Shape& shape, + const SMESH_Mesh& mesh, + TopAbs_ShapeEnum ancestorType); + /*! + * \brief Find a common ancestors of two shapes of the given type + */ + static TopoDS_Shape GetCommonAncestor(const TopoDS_Shape& shape1, + const TopoDS_Shape& shape2, + const SMESH_Mesh& mesh, + TopAbs_ShapeEnum ancestorType); + + /*! + * \brief Return orientation of sub-shape in the main shape + */ + static TopAbs_Orientation GetSubShapeOri(const TopoDS_Shape& shape, + const TopoDS_Shape& subShape); + + static bool IsSubShape( const TopoDS_Shape& shape, const TopoDS_Shape& mainShape ); + + static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh ); + + static double MaxTolerance( const TopoDS_Shape& shape ); + + static bool IsClosedEdge( const TopoDS_Edge& anEdge ); + + static TopoDS_Vertex IthVertex( const bool is2nd, TopoDS_Edge anEdge, const bool CumOri=true ); + + public: // ---------- PUBLIC INSTANCE METHODS ---------- @@ -118,7 +177,7 @@ public: /*! * Check submesh for given shape: if all elements on this shape are quadratic, - * quadratic elements will be created. Also fill myNLinkNodeMap + * quadratic elements will be created. Also fill myTLinkNodeMap */ bool IsQuadraticSubMesh(const TopoDS_Shape& theShape); /*! @@ -131,6 +190,12 @@ public: */ bool GetIsQuadratic() const { return myCreateQuadratic; } + /*! + * \brief Move medium nodes of faces and volumes to fix distorted elements + * \param volumeOnly - fix nodes on geom faces or not if the shape is solid + */ + void FixQuadraticElements(bool volumeOnly=true); + /*! * \brief To set created elements on the shape set by IsQuadraticSubMesh() * or the next methods. By defaul elements are set on the shape if @@ -151,12 +216,12 @@ public: /*! * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape() */ - TopoDS_Shape GetSubShape() const { return myShape; } + const TopoDS_Shape& GetSubShape() const { return myShape; } /*! * Creates a node */ - SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0); + SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0, double u=0., double v=0.); /*! * Creates quadratic or linear edge */ @@ -171,7 +236,7 @@ public: const SMDS_MeshNode* n2, const SMDS_MeshNode* n3, const int id=0, - const bool force3d = false); + const bool force3d = false); /*! * Creates quadratic or linear quadrangle */ @@ -180,16 +245,23 @@ public: const SMDS_MeshNode* n3, const SMDS_MeshNode* n4, const int id = 0, - const bool force3d = false); + const bool force3d = false); + /*! - * Creates quadratic or linear tetraahedron + * Creates polygon, with additional nodes in quadratic mesh + */ + SMDS_MeshFace* AddPolygonalFace (const std::vector& nodes, + const int id = 0, + const bool force3d = false); + /*! + * Creates quadratic or linear tetrahedron */ SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n3, const SMDS_MeshNode* n4, const int id = 0, - const bool force3d = true); + const bool force3d = true); /*! * Creates quadratic or linear pyramid */ @@ -199,7 +271,7 @@ public: const SMDS_MeshNode* n4, const SMDS_MeshNode* n5, const int id = 0, - const bool force3d = true); + const bool force3d = true); /*! * Creates quadratic or linear pentahedron */ @@ -210,7 +282,7 @@ public: const SMDS_MeshNode* n5, const SMDS_MeshNode* n6, const int id = 0, - const bool force3d = true); + const bool force3d = true); /*! * Creates quadratic or linear hexahedron */ @@ -223,28 +295,124 @@ public: const SMDS_MeshNode* n7, const SMDS_MeshNode* n8, const int id = 0, - bool force3d = true); + bool force3d = true); + + /*! + * Creates LINEAR!!!!!!!!! octahedron + */ + SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4, + const SMDS_MeshNode* n5, + const SMDS_MeshNode* n6, + const SMDS_MeshNode* n7, + const SMDS_MeshNode* n8, + const SMDS_MeshNode* n9, + const SMDS_MeshNode* n10, + const SMDS_MeshNode* n11, + const SMDS_MeshNode* n12, + const int id = 0, + bool force3d = true); + + /*! + * Creates polyhedron. In quadratic mesh, adds medium nodes + */ + SMDS_MeshVolume* AddPolyhedralVolume (const std::vector& nodes, + const std::vector& quantities, + const int ID=0, + const bool force3d = true); + /*! + * \brief Enables fixing node parameters on EDGEs and FACEs by + * GetNodeU(...,check=true), GetNodeUV(...,check=true), CheckNodeUV() and + * CheckNodeU() in case if a node lies on a shape set via SetSubShape(). + * Default is False + */ + void ToFixNodeParameters(bool toFix); + /*! * \brief Return U of the given node on the edge */ double GetNodeU(const TopoDS_Edge& theEdge, - const SMDS_MeshNode* theNode); + const SMDS_MeshNode* theNode, + const SMDS_MeshNode* inEdgeNode=0, + bool* check=0); /*! * \brief Return node UV on face - * \param inFaceNode - a node of element being created located inside a face + * \param inFaceNode - a node of element being created located inside a face */ gp_XY GetNodeUV(const TopoDS_Face& F, const SMDS_MeshNode* n, - const SMDS_MeshNode* inFaceNode=0) const; + const SMDS_MeshNode* inFaceNode=0, + bool* check=0) const; + /*! + * \brief Check and fix node UV on a face + * \param force - check even if checks of other nodes on this face passed OK + * \param distXYZ - returns result distance and point coordinates + * \retval bool - false if UV is bad and could not be fixed + */ + bool CheckNodeUV(const TopoDS_Face& F, + const SMDS_MeshNode* n, + gp_XY& uv, + const double tol, + const bool force=false, + double distXYZ[4]=0) const; + /*! + * \brief Check and fix node U on an edge + * \param force - check even if checks of other nodes on this edge passed OK + * \param distXYZ - returns result distance and point coordinates + * \retval bool - false if U is bad and could not be fixed + */ + bool CheckNodeU(const TopoDS_Edge& E, + const SMDS_MeshNode* n, + double& u, + const double tol, + const bool force=false, + double distXYZ[4]=0) const; + /*! + * \brief Return middle UV taking in account surface period + */ + static gp_XY GetMiddleUV(const Handle(Geom_Surface)& surface, + const gp_XY& uv1, + const gp_XY& uv2); + /*! + * \brief Define a pointer to wrapper over a function of gp_XY class, + * suitable to pass as xyFunPtr to applyIn2D(). + * For exaple gp_XY_FunPtr(Added) defines pointer gp_XY_Added to function + * calling gp_XY::Added(gp_XY), which is to be used like following + * applyIn2D(surf, uv1, uv2, gp_XY_Added) + */ +#define gp_XY_FunPtr(meth) \ + static gp_XY __gpXY_##meth (const gp_XY& uv1, const gp_XY& uv2) { return uv1.meth( uv2 ); } \ + static xyFunPtr gp_XY_##meth = & __gpXY_##meth + + /*! + * \brief Perform given operation on two 2d points in parameric space of given surface. + * It takes into account period of the surface. Use gp_XY_FunPtr macro + * to easily define pointer to function of gp_XY class. + */ + static gp_XY applyIn2D(const Handle(Geom_Surface)& surface, + const gp_XY& uv1, + const gp_XY& uv2, + xyFunPtr fun, + const bool resultInPeriod=true); + /*! * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..) * \retval bool - return true if the face is periodic * - * if F is Null, answer about subshape set through IsQuadraticSubMesh() or + * If F is Null, answer about subshape set through IsQuadraticSubMesh() or * SetSubShape() */ bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const; + /*! + * \brief Return projector intitialized by given face without location, which is returned + */ + GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F, + TopLoc_Location& loc, + double tol=0 ) const; + /*! * \brief Check if shape is a degenerated edge or it's vertex * \param subShape - edge or vertex index in SMESHDS @@ -254,6 +422,13 @@ public: */ bool IsDegenShape(const int subShape) const { return myDegenShapeIds.find( subShape ) != myDegenShapeIds.end(); } + /*! + * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape() + * has a degenerated edges + * \retval bool - true if it has + */ + bool HasDegeneratedEdges() const { return !myDegenShapeIds.empty(); } + /*! * \brief Check if shape is a seam edge or it's vertex * \param subShape - edge or vertex index in SMESHDS @@ -302,28 +477,40 @@ public: */ double GetOtherParam(const double param) const; - /** - * Special function for search or creation medium node + /*! + * \brief Return existing or create new medium nodes between given ones + * \param force3d - true means node creation at the middle between the + * two given nodes, else node position is found on its + * supporting geometrical shape, if any. */ const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const bool force3d); /*! - * Auxilary function for filling myNLinkNodeMap + * \brief Return index and type of the shape (EDGE or FACE only) to set a medium node on + */ + std::pair GetMediumPos(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2); + /*! + * \brief Add a link in my data structure */ - void AddNLinkNode(const SMDS_MeshNode* n1, + void AddTLinkNode(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* n12); - /** - * Auxilary function for filling myNLinkNodeMap + /*! + * \brief Add many links in my data structure */ - void AddNLinkNodeMap(const NLinkNodeMap& aMap) - { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); } + void AddTLinkNodeMap(const TLinkNodeMap& aMap) + { myTLinkNodeMap.insert(aMap.begin(), aMap.end()); } + + void AddTLinks(const SMDS_MeshEdge* edge); + void AddTLinks(const SMDS_MeshFace* face); + void AddTLinks(const SMDS_MeshVolume* vol); /** - * Returns myNLinkNodeMap + * Returns myTLinkNodeMap */ - const NLinkNodeMap& GetNLinkNodeMap() const { return myNLinkNodeMap; } + const TLinkNodeMap& GetTLinkNodeMap() const { return myTLinkNodeMap; } /** * Check mesh without geometry for: if all elements on this shape are quadratic, @@ -333,6 +520,8 @@ public: enum MType{ LINEAR, QUADRATIC, COMP }; MType IsQuadraticMesh(); + virtual ~SMESH_MesherHelper(); + protected: /*! @@ -343,26 +532,38 @@ protected: */ gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const; + const SMDS_MeshNode* getMediumNodeOnComposedWire(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + bool force3d); private: // Forbiden copy constructor SMESH_MesherHelper (const SMESH_MesherHelper& theOther) {}; // special map for using during creation of quadratic elements - NLinkNodeMap myNLinkNodeMap; + TLinkNodeMap myTLinkNodeMap; std::set< int > myDegenShapeIds; std::set< int > mySeamShapeIds; - double myPar1, myPar2; // bounds of a closed periodic surface - int myParIndex; // bounds' index (1-U, 2-V) + double myPar1[2], myPar2[2]; // U and V bounds of a closed periodic surface + int myParIndex; // bounds' index (1-U, 2-V, 3-both) + + typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf; + TID2ProjectorOnSurf myFace2Projector; + typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve; + TID2ProjectorOnCurve myEdge2Projector; TopoDS_Shape myShape; SMESH_Mesh* myMesh; int myShapeID; - // to create quadratic elements bool myCreateQuadratic; bool mySetElemOnShape; + bool myFixNodeParameters; + + std::map< int,bool > myNodePosShapesValidity; + bool toCheckPosOnShape(int shapeID ) const; + void setPosOnShapeValidity(int shapeID, bool ok ) const; }; diff --git a/src/SMESH/SMESH_Octree.cxx b/src/SMESH/SMESH_Octree.cxx deleted file mode 100644 index 63457088e..000000000 --- a/src/SMESH/SMESH_Octree.cxx +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH_Octree : global Octree implementation -// File : SMESH_Octree.cxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux(OCC) -// Module : SMESH -// -#include "SMESH_Octree.hxx" - -//=========================================================================== -/*! - * \brief SMESH_Octree Constructor - * \param maxLevel - The level max the octree can reach (If <0 unlimited) - */ -//=========================================================================== -SMESH_Octree::SMESH_Octree (const int maxLevel, const double minBoxSize): - myChildren(NULL), - myFather(NULL), - myLevel(0), - myMaxLevel(maxLevel), - myMinBoxSize(minBoxSize), - myIsLeaf(-1) -{ - myBox = new Bnd_B3d(); -} - -//====================================== -/*! - * \brief SMESH_Octree Destructor - */ -//====================================== -SMESH_Octree::~SMESH_Octree () -{ - if(myChildren != NULL) - { - if(!myIsLeaf) - { - for(int i = 0; i<8; i++) - delete myChildren[i]; - delete[] myChildren ; - } - } - delete myBox; -} - -//=========================================================================== -/*! - * \brief Set the bounding box of the Octree - * \param box - 3d Bounding Box of the Octree - */ -//=========================================================================== -void SMESH_Octree::setBox(const Bnd_B3d* box) -{ -// delete myBox; -// myBox=new Bnd_B3d(*box); - *myBox = *box; -} - -//=========================================================================== -/*! - * \brief Set box to the 3d Bounding Box of the Octree - * \param box - Set box to the 3d Bounding Box of the Octree - */ -//=========================================================================== -void SMESH_Octree::getBox(Bnd_B3d& box) -{ -// if(box != NULL) -// delete box; -// box = new Bnd_B3d (*myBox); - box = *myBox; -} - -//=========================================================================== -/*! - * \brief Set the max level of the Octree - * \param maxLevel - The level max the octree can reach (If <0 unlimited) - */ -//=========================================================================== -void SMESH_Octree::setMaxLevel(const int maxLevel) -{myMaxLevel = maxLevel;} - - -//=========================================================================== -/*! - * \brief Compute the bigger dimension of the box - * \param box - 3d Box - * \retval double - bigger dimension of the box - */ -//=========================================================================== -double SMESH_Octree::maxSize(const Bnd_B3d* box) -{ - if(box ==NULL) - return 0; - gp_XYZ min = box->CornerMin(); - gp_XYZ max = box->CornerMax(); - gp_XYZ Size = (max - min); - double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y(); - return (returnVal>Size.Z())?returnVal:Size.Z(); -} - -//============================= -/*! - * \brief Compute the Octree - */ -//============================= -void SMESH_Octree::Compute() -{ - // As soon as the Octree is a Leaf, I stop building his children - if(!isLeaf()) - buildChildren(); -} - -//================================================================= -/*! - * \brief Build the 8 children boxes and call buildChildrenData() - */ -//================================================================= -void SMESH_Octree::buildChildren() -{ - myChildren = new SMESH_Octree*[8]; - - gp_XYZ min = myBox->CornerMin(); - gp_XYZ max = myBox->CornerMax(); - gp_XYZ HSize = (max - min)/2.; - gp_XYZ mid = min + HSize; - gp_XYZ childHsize = HSize/2.; - - Standard_Real XminChild, YminChild, ZminChild; - Bnd_B3d* box; - gp_XYZ minChild; - for (int i =0; i<8; i++) - { - // We build the eight boxes, we need 2 points to do that. - // Min, and Mid - // In binary, we can write i from 0 to 7 - // For instance : - // 5 is 101, it corresponds here in coordinates to ZYX - // If coordinate is 0 in Y-> box from Ymin to Ymid - // If coordinate is 1 in Y-> box from Ymid to Ymax - // Same scheme for X and Z - // I need the minChild to build the Bnd_B3d box. - - XminChild= (i%2==0)?min.X():mid.X(); - YminChild= ((i%4)/2==0)?min.Y():mid.Y(); - ZminChild= (i<4)?min.Z():mid.Z(); - minChild.SetCoord(XminChild, YminChild, ZminChild); - - box = new Bnd_B3d(minChild+childHsize,childHsize); - // The child is of the same type than its father (For instance, a SMESH_OctreeNode) - // We allocate the memory we need fot the child - myChildren[i] = allocateOctreeChild(); - // and we assign to him its box. - myChildren[i]->setBox(box); - delete box; - } - - // After building the 8 boxes, we put the data into the children.. - buildChildrenData(); - - //After we pass to the next level of the Octree - for (int i =0; i<8; i++) - myChildren[i]->Compute(); -} diff --git a/src/SMESH/SMESH_Octree.hxx b/src/SMESH/SMESH_Octree.hxx deleted file mode 100644 index 1d40b39e6..000000000 --- a/src/SMESH/SMESH_Octree.hxx +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH_Octree : global Octree implementation -// File : SMESH_Octree.hxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) -// Module : SMESH -// -#ifndef _SMESH_OCTREE_HXX_ -#define _SMESH_OCTREE_HXX_ - -#include - -class SMESH_Octree { - -public: - // Constructor - SMESH_Octree (const int maxLevel = -1, const double minBoxSize = 0.); - - // Destructor - virtual ~SMESH_Octree (); - - // Tell if Octree is a leaf or not (has to be implemented in inherited classes) - virtual const bool isLeaf() = 0; - - // Compute the Octree - void Compute(); - - // Set the maximal level of the Octree - void setMaxLevel(const int maxLevel); - - // Set the minimal size of the Box - void setMinBoxSize(const double minBoxSize){myMinBoxSize = minBoxSize;}; - - // Set the bounding box of the Octree - void setBox(const Bnd_B3d* box); - - // Set box to the 3d Bounding Box of the Octree - 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; - - // Build the 8 children boxes - void buildChildren(); - - // Build the data in the 8 children (has to be implemented in inherited classes) - virtual void buildChildrenData() = 0; - - // members - - // Box of the Octree - Bnd_B3d* myBox; - - // Array of 8 Octree children - SMESH_Octree** myChildren; - - // Point the father, set to NULL for the level 0 - SMESH_Octree* myFather; - - // Level of the Octree - int myLevel; - - // MaxLevel of the Octree - int myMaxLevel; - - // Minimal size of the Box - double myMinBoxSize; - - // Tell us if the Octree is a leaf or not (-1 if not initialized) - int myIsLeaf; -}; -#endif diff --git a/src/SMESH/SMESH_OctreeNode.cxx b/src/SMESH/SMESH_OctreeNode.cxx deleted file mode 100644 index 48e8c5a79..000000000 --- a/src/SMESH/SMESH_OctreeNode.cxx +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH_OctreeNode : Octree with Nodes set -// inherites global class SMESH_Octree -// File : SMESH_OctreeNode.cxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) -// Module : SMESH -// -#include "SMESH_OctreeNode.hxx" - -#include "SMDS_MeshNode.hxx" -#include "SMDS_SetIterator.hxx" -#include - -using namespace std; - -//=============================================================== -/*! - * \brief Constructor : Build all the Octree using Compute() - * \param theNodes - Set of nodes, the Octree is built from this nodes - * \param maxLevel - Maximum level for the leaves - * \param maxNbNodes - Maximum number of nodes, a leaf can contain - * \param minBoxSize - Minimal size of the Octree Box - */ -//================================================================ -SMESH_OctreeNode::SMESH_OctreeNode (const set & theNodes, const int maxLevel, - const int maxNbNodes , const double minBoxSize ) - :SMESH_Octree(maxLevel,minBoxSize), - myMaxNbNodes(maxNbNodes), - myNodes(theNodes) -{ - // We need to compute the first bounding box via a special method - computeBoxForFather(); - myNbNodes = myNodes.size(); - myIsLeaf = (myLevel == myMaxLevel)||(myNbNodes<=myMaxNbNodes)||(myMinBoxSize>=maxSize(myBox)); - // All the children (Boxes and Data) are computed in Compute() - Compute(); -} - -//================================================================================== -/*! - * \brief Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren() - */ -//================================================================================== -SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild() -{ - SMESH_OctreeNode * theOctree = new SMESH_OctreeNode(); - theOctree->myFather = this; - theOctree->myLevel = myLevel + 1; - theOctree->myMaxLevel = myMaxLevel; - theOctree->myMaxNbNodes = myMaxNbNodes; - theOctree->myMinBoxSize = myMinBoxSize; - theOctree->myNbNodes = 0; - return theOctree; -} - - - -//====================================== -/*! - * \brief Compute the first bounding box - * - * We take the max/min coord of the nodes - */ -//====================================== -void SMESH_OctreeNode::computeBoxForFather() -{ - set::iterator it=myNodes.begin(); - for( ;it!=myNodes.end();it++){ - const SMDS_MeshNode* n1 = *it; - gp_XYZ p1( n1->X(), n1->Y(), n1->Z() ); - myBox->Add(p1); - } -} - -//==================================================================================== -/*! - * \brief Tell if Octree is a leaf or not (has to be implemented in inherited classes) - * \retval - True if the Octree is a leaf - */ -//==================================================================================== -const bool SMESH_OctreeNode::isLeaf() -{ - return myIsLeaf; -} - -//==================================================================================== -/*! - * \brief Tells us if Node is inside the current box with the precision "precision" - * \param Node - Node - * \param precision - The box is enlarged with this precision - * \retval bool - True if Node is in the box within precision - */ -//==================================================================================== -const bool SMESH_OctreeNode::isInside(const SMDS_MeshNode * Node, const double precision ) -{ - double X=Node->X(); - double Y=Node->Y(); - double Z=Node->Z(); - bool Out = 1 ; - if (precision<=0.) - return !(myBox->IsOut(gp_XYZ(X,Y,Z))); - Bnd_B3d BoxWithPrecision; - getBox(BoxWithPrecision); - BoxWithPrecision.Enlarge(precision); - Out=BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z)); - return !(Out); -} - - -//================================================ -/*! - * \brief Set the data of the children - * Shares the father's data with each of his child - */ -//================================================ -void SMESH_OctreeNode::buildChildrenData() -{ - gp_XYZ min = myBox->CornerMin(); - gp_XYZ max = myBox->CornerMax(); - gp_XYZ mid = (min + max)/2.; - - set::iterator it=myNodes.begin(); - int ChildBoxNum; - while( it!=myNodes.end()) - { - const SMDS_MeshNode* n1 = *it; - ChildBoxNum= (n1->X()>mid.X()) + (n1->Y()>mid.Y())*2 + (n1->Z()>mid.Z())*4; - SMESH_OctreeNode* myChild = dynamic_cast (myChildren[ChildBoxNum]); - myChild->myNodes.insert(myChild->myNodes.end(),n1); - myNodes.erase( it ); - it=myNodes.begin(); - } - for (int i = 0; i<8; i++) - { - SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); - myChild->myNbNodes = (myChild->myNodes).size(); - myChild->myIsLeaf = (myChild->myLevel == myMaxLevel)||(myChild->myNbNodes<=myMaxNbNodes)||(myMinBoxSize>=maxSize(myChild->myBox)); - } -} - -//=================================================================== -/*! - * \brief Return in Result a list of Nodes potentials to be near Node - * \param Node - Node - * \param precision - precision used - * \param Result - list of Nodes potentials to be near Node - */ -//==================================================================== -void SMESH_OctreeNode::NodesAround( const SMDS_MeshNode * Node, - list* Result, const double precision) -{ - if (isInside(Node,precision)) - { - if (myIsLeaf) - { - Result->insert( Result->end(), myNodes.begin(), myNodes.end() ); - } - else - { - for(int i=0;i<8;i++) - { - SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); - myChild->NodesAround( Node, Result, precision); - } - } - } -} - - - -//============================= -/*! - * \brief Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance - * Search for all the nodes in nodes - * Static Method : no need to create an SMESH_OctreeNode - * \param nodes - set of nodes we look at, modified during research - * \param theGroupsOfNodes - list of nodes closed to each other returned - * \param theTolerance - Precision used, default value is 0.00001 - * \param maxLevel - Maximum level for SMESH_OctreeNode constructed, default value is -1 (Infinite) - * \param maxNbNodes - maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5 - */ -//============================= -void SMESH_OctreeNode::FindCoincidentNodes ( set nodes, - list< list< const SMDS_MeshNode*> >* theGroupsOfNodes, - const double theTolerance, const int maxLevel, - const int maxNbNodes) -{ - SMESH_OctreeNode* theOctreeNode = new SMESH_OctreeNode(nodes, maxLevel, maxNbNodes, theTolerance); - theOctreeNode->FindCoincidentNodes (&nodes, theTolerance, theGroupsOfNodes); - delete theOctreeNode; -} - - -//============================= -/*! - * \brief Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance - * Search for all the nodes in nodes - * \param nodes - set of nodes we look at, modified during research - * \param theTolerance - Precision used - * \param theGroupsOfNodes - list of nodes closed to each other returned - */ -//============================= -void SMESH_OctreeNode::FindCoincidentNodes ( set* nodes, - const double theTolerance, - list< list< const SMDS_MeshNode*> >* theGroupsOfNodes) -{ - set::iterator it1 = nodes->begin(); - list::iterator it2; - - while (it1 != nodes->end()) - { - const SMDS_MeshNode * n1 = *it1; - - list ListofCoincidentNodes;// Initialize the lists via a declaration, it's enough - - list * groupPtr = 0; - - // Searching for Nodes around n1 and put them in ListofCoincidentNodes - FindCoincidentNodes(n1, nodes, &ListofCoincidentNodes, theTolerance); - - // We build a list {n1 + his neigbours} and add this list in theGroupsOfNodes - for (it2=ListofCoincidentNodes.begin();it2 != ListofCoincidentNodes.end(); it2++) - { - const SMDS_MeshNode* n2 = *it2; - if ( !groupPtr ) - { - theGroupsOfNodes->push_back( list() ); - groupPtr = & theGroupsOfNodes->back(); - groupPtr->push_back( n1 ); - } - if(groupPtr->front()>n2) - groupPtr->push_front( n2 ); - else - groupPtr->push_back( n2 ); - } - if(groupPtr != 0) - groupPtr->sort(); - - nodes->erase(it1); - it1=nodes->begin(); - } -} - -//====================================================================================== -/*! - * \brief Return a list of nodes closed to Node and remove it from SetOfNodes - * \param Node - We're searching the nodes next to him. - * \param SetOfNodes - set of nodes in which we erase the found nodes - * \param Result - list of nodes closed to Node - * \param precision - Precision used - */ -//====================================================================================== -void SMESH_OctreeNode::FindCoincidentNodes( const SMDS_MeshNode * Node, - set* SetOfNodes, - list* Result, - const double precision) -{ - bool isInsideBool = isInside(Node,precision); - - if (isInsideBool) - { - // I'm only looking in the leaves, since all the nodes are stored there. - if (myIsLeaf) - { - gp_Pnt p1( Node->X(), Node->Y(), Node->Z() ); - - set myNodesCopy = myNodes; - set::iterator it = myNodesCopy.begin(); - double tol2 = precision * precision; - bool squareBool; - - while (it != myNodesCopy.end()) - { - const SMDS_MeshNode* n2 = *it; - // We're only looking at nodes with a superior Id. - if(Node->GetID() < n2->GetID()) - { - gp_Pnt p2( n2->X(), n2->Y(), n2->Z() ); - // Distance optimized computation - squareBool = (p1.SquareDistance( p2 ) <= tol2); - - // If n2 inside the SquareDistance, we add it in Result and remove it from SetOfNodes and myNodes - if(squareBool) - { - Result->insert(Result->begin(), n2); - SetOfNodes->erase( n2 ); - myNodes.erase( n2 ); - } - } - myNodesCopy.erase( it ); - it = myNodesCopy.begin(); - } - - } - else - { - // If I'm not a leaf, I'm going to see my children ! - for(int i = 0; i < 8; i++) - { - SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); - myChild->FindCoincidentNodes(Node, SetOfNodes, Result, precision); - } - } - } -} - -//================================================================================ -/*! - * \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() )); -} diff --git a/src/SMESH/SMESH_OctreeNode.hxx b/src/SMESH/SMESH_OctreeNode.hxx deleted file mode 100644 index 54ab75cc8..000000000 --- a/src/SMESH/SMESH_OctreeNode.hxx +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH_OctreeNode : Octree with Nodes set -// inherites global class SMESH_Octree -// File : SMESH_OctreeNode.hxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) -// Module : SMESH -// -#ifndef _SMESH_OCTREENODE_HXX_ -#define _SMESH_OCTREENODE_HXX_ - -#include "SMESH_Octree.hxx" - -#include -#include - -#include "SMDS_ElemIterator.hxx" - -//forward declaration -class SMDS_MeshNode; -class SMESH_OctreeNode; - -typedef SMDS_Iterator SMESH_OctreeNodeIterator; -typedef boost::shared_ptr SMESH_OctreeNodeIteratorPtr; - -class SMESH_OctreeNode : public SMESH_Octree{ - -public: - - // Constructor - SMESH_OctreeNode (const std::set& theNodes, const int maxLevel = -1, - const int maxNbNodes = 5 , const double minBoxSize = 0.); - -//============================= -/*! - * \brief Empty destructor - */ -//============================= - virtual ~SMESH_OctreeNode () {}; - - // Tells us if SMESH_OctreeNode is a leaf or not (-1 = not initialiazed) - virtual const bool isLeaf(); - - // Tells us if Node is inside the current box with the precision "precision" - virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0. ); - - // Return in Result a list of Nodes potentials to be near Node - void NodesAround( const SMDS_MeshNode * Node , std::list* Result, - const double precision = 0. ); - - // Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance - // Search for all the nodes in nodes - void FindCoincidentNodes ( std::set* nodes, - const double theTolerance, - std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes); - - // Static method that return in theGroupsOfNodes a list of group of nodes close to each other within - // theTolerance search for all the nodes in nodes - static void FindCoincidentNodes ( std::set nodes, - std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes, - const double theTolerance = 0.00001, const int maxLevel = -1, - const int maxNbNodes = 5); - /*! - * \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: - -//============================= -/*! - * \brief Empty constructor - */ -//============================= - SMESH_OctreeNode (){}; - - // Shares the father's data with each of his child - virtual void buildChildrenData(); - - // Compute the bounding box of the whole set of nodes myNodes (only used for OctreeNode level 0) - void computeBoxForFather(); - - // Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren() - virtual SMESH_Octree* allocateOctreeChild(); - - // Return in result a list of nodes closed to Node and remove it from SetOfNodes - void FindCoincidentNodes( const SMDS_MeshNode * Node, - std::set* SetOfNodes, - std::list* Result, - const double precision); - - // The max number of nodes a leaf box can contain - int myMaxNbNodes; - - // The set of nodes inside the box of the Octree (Empty if Octree is not a leaf) - std::set myNodes; - - // The number of nodes I have inside the box - int myNbNodes; -}; -#endif diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 7b5746773..cc493ca34 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Pattern.hxx // Created : Mon Aug 2 10:30:00 2004 // Author : Edward AGAPOV (eap) -// + #include "SMESH_Pattern.hxx" #include @@ -39,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -69,9 +71,12 @@ #include "SMESHDS_SubMesh.hxx" #include "SMESH_Block.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" +#include + +#include #include "utilities.h" using namespace std; @@ -209,6 +214,8 @@ bool SMESH_Pattern::Load (const char* theFileContents) { MESSAGE("Load( file ) "); + Kernel_Utils::Localizer loc; + // file structure: // ! This is a comment @@ -352,6 +359,9 @@ bool SMESH_Pattern::Load (const char* theFileContents) bool SMESH_Pattern::Save (ostream& theFile) { MESSAGE(" ::Save(file) " ); + + Kernel_Utils::Localizer loc; + if ( !IsLoaded() ) { MESSAGE(" Pattern not loaded "); return setErrorCode( ERR_SAVE_NOT_LOADED ); @@ -436,8 +446,13 @@ static gp_XY project (const SMDS_MeshNode* theNode, } double u, v, minVal = DBL_MAX; for ( int i = theProjectorPS.NbExt(); i > 0; i-- ) +#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 + if ( theProjectorPS.SquareDistance( i ) < minVal ) { + minVal = theProjectorPS.SquareDistance( i ); +#else if ( theProjectorPS.Value( i ) < minVal ) { minVal = theProjectorPS.Value( i ); +#endif theProjectorPS.Point( i ).Parameter( u, v ); } return gp_XY( u, v ); @@ -456,8 +471,7 @@ template bool areNodesBound( TFaceIterator & faceItr ) while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); - SMDS_PositionPtr pos = node->GetPosition(); - if ( !pos || !pos->GetShapeId() ) { + if (node->getshapeId() <1) { return false; } } @@ -508,6 +522,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS(); SMESHDS_SubMesh * fSubMesh = aMeshDS->MeshElements( theFace ); + const bool isQuadMesh = aMeshDS->GetMeshInfo().NbFaces( ORDER_QUADRATIC ); SMESH_MesherHelper helper( *theMesh ); helper.SetSubShape( theFace ); @@ -576,15 +591,15 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, { myElemPointIDs.push_back( TElemDef() ); TElemDef& elemPoints = myElemPointIDs.back(); - SMDS_ElemIteratorPtr nIt = (*fIt)->nodesIterator(); - while ( nIt->more() ) + int nbNodes = (*fIt)->NbCornerNodes(); + for ( int i = 0;i < nbNodes; ++i ) { - const SMDS_MeshElement* node = nIt->next(); - TNodePointIDMap::iterator nIdIt = nodePointIDMap.find( node ); - if ( nIdIt == nodePointIDMap.end() ) + const SMDS_MeshElement* node = (*fIt)->GetNode( i ); + TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first; + if ( nIdIt->second == -1 ) { elemPoints.push_back( iPoint ); - nodePointIDMap.insert( make_pair( node, iPoint++ )); + nIdIt->second = iPoint++; } else elemPoints.push_back( (*nIdIt).second ); @@ -728,12 +743,17 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // loop on nodes of an edge: sort them by param on edge typedef map < double, const SMDS_MeshNode* > TParamNodeMap; TParamNodeMap paramNodeMap; + int nbMeduimNodes = 0; SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes(); while ( nIt->more() ) { - const SMDS_MeshNode* node = smdsNode( nIt->next() ); + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) { + ++nbMeduimNodes; + continue; + } const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = epos->GetUParameter(); paramNodeMap.insert( make_pair( u, node )); } @@ -745,7 +765,9 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, paramNodeMap.clear(); nIt = eSubMesh->GetNodes(); for ( int iNode = 0; nIt->more(); ++iNode ) { - const SMDS_MeshNode* node = smdsNode( nIt->next() ); + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) + continue; proj.Perform( gp_Pnt( node->X(), node->Y(), node->Z())); double u = 0; if ( proj.IsDone() ) { @@ -759,7 +781,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, } paramNodeMap.insert( make_pair( u, node )); } + + //rnv : To fix the bug IPAL21999 Pattern Mapping - New - collapse of pattern mesh + if ( paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes ) + return setErrorCode(ERR_UNEXPECTED); } + // put U in [0,1] so that the first key-point has U==0 bool isSeam = helper.IsRealSeam( edge ); double du = l - f; @@ -842,7 +869,9 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); while ( nIt->more() ) { - const SMDS_MeshNode* node = smdsNode( nIt->next() ); + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) + continue; nodePointIDMap.insert( make_pair( node, iPoint )); TPoint* p = &myPoints[ iPoint++ ]; fPoints.push_back( p ); @@ -850,7 +879,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, p->myInitUV = project( node, projector ); else { const SMDS_FacePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() ); } p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 ); @@ -868,9 +897,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); - iPoint = nodePointIDMap[ node ]; // point index of interest + n_id = nodePointIDMap.find( node ); + if ( n_id == nodePointIDMap.end() ) + continue; // medium node + iPoint = n_id->second; // point index of interest // for a node on a seam edge there are two points - if ( helper.IsRealSeam( node->GetPosition()->GetShapeId() ) && + if ( helper.IsRealSeam( node->getshapeId() ) && ( n_id = closeNodePointIDMap.find( node )) != not_found ) { TPoint & p1 = myPoints[ iPoint ]; @@ -881,7 +913,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // find node not on a seam edge while ( nIt2->more() && !notSeamNode ) { const SMDS_MeshNode* n = smdsNode( nIt2->next() ); - if ( !helper.IsSeamShape( n->GetPosition()->GetShapeId() )) + if ( !helper.IsSeamShape( n->getshapeId() )) notSeamNode = n; } gp_Pnt2d uv = helper.GetNodeUV( theFace, node, notSeamNode ); @@ -894,6 +926,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, } } } + myPoints.resize( nodePointIDMap.size() + closeNodePointIDMap.size() ); myIsBoundaryPointsFound = true; } @@ -1228,7 +1261,7 @@ static bool checkQuads (const TIsoNode* node, maxLen2 = Max( maxLen2, ( n[1]->myUV - n[2]->myUV ).SquareModulus() ); } maxLen2 = Max( maxLen2, ( n[2]->myUV - node->myUV ).SquareModulus() ); - minDiag = sqrt( maxLen2 ) * PI / 60.; // ~ maxLen * Sin( 3 deg ) + minDiag = sqrt( maxLen2 ) * M_PI / 60.; // ~ maxLen * Sin( 3 deg ) } // check if newUV is behind 3 dirs: n[0]-n[1], n[1]-n[2] and n[0]-n[2] @@ -1779,7 +1812,7 @@ bool SMESH_Pattern:: double initAngle = initTgt1.Angle( initTgt2 ); double angle = node->myDir[0].Angle( node->myDir[1] ); if ( reversed ) angle = -angle; - if ( initAngle > angle && initAngle - angle > PI / 2.1 ) { + if ( initAngle > angle && initAngle - angle > M_PI / 2.1 ) { // find a close internal node TIsoNode* nClose = 0; list< TIsoNode* > testNodes; @@ -1873,7 +1906,7 @@ bool SMESH_Pattern:: for ( nIt = startNodes.begin(); nIt != startNodes.end(); nIt++ ) { - TIsoNode* prevN[2], *node = *nIt; + TIsoNode *node = *nIt; if ( node->IsUVComputed() || !node->IsMovable() ) continue; gp_XY newUV( 0, 0 ), sumDir( 0, 0 ); @@ -1934,7 +1967,6 @@ bool SMESH_Pattern:: newUV += prevNode1->myUV + dir * step[ iDir ]; } sumDir += dir; - prevN[ iDir ] = prevNode1; nbComp++; } } @@ -1996,7 +2028,7 @@ bool SMESH_Pattern:: } // define ratio bool ok = true; // <- stupid fix TO AVOID PB OF NODES WITH NULL BND NODES - double locR[2] = { 0, 0 }; +// double locR[2] = { 0, 0 }; for ( iDir = 0; iDir < 2; iDir++ ) { const int iCoord = 2 - iDir; // coord changing along an isoline @@ -2010,7 +2042,7 @@ bool SMESH_Pattern:: double par3 = bndNode2->myInitUV.Coord( iCoord ); double r = ( par2 - par1 ) / ( par3 - par1 ); r = Abs ( r - 0.5 ) * 2.0; // [0,1] - distance from the middle - locR[ iDir ] = ( 1 - r * r ) * 0.25; +// locR[ iDir ] = ( 1 - r * r ) * 0.25; } //locR[0] = locR[1] = 0.25; // intersect the 2 lines and move a node @@ -2589,8 +2621,9 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, } // check nb of nodes - if (theFace->NbNodes() != myNbKeyPntInBoundary.front() ) { - MESSAGE( myKeyPointIDs.size() << " != " << theFace->NbNodes() ); + const int nbFaceNodes = theFace->NbCornerNodes(); + if ( nbFaceNodes != myNbKeyPntInBoundary.front() ) { + MESSAGE( myKeyPointIDs.size() << " != " << nbFaceNodes ); return setErrorCode( ERR_APPL_BAD_NB_VERTICES ); } @@ -2609,7 +2642,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, list< const SMDS_MeshNode* >::iterator n = nodes.end(); SMDS_ElemIteratorPtr noIt = theFace->nodesIterator(); int iSub = 0; - while ( noIt->more() ) { + while ( noIt->more() && iSub < nbFaceNodes ) { const SMDS_MeshNode* node = smdsNode( noIt->next() ); nodes.push_back( node ); if ( iSub++ == theNodeIndexOnKeyPoint1 ) @@ -2625,7 +2658,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, nodes.splice( nodes.end(), nodes, nodes.begin(), n ); } list< gp_XYZ > xyzList; - myOrderedNodes.resize( theFace->NbNodes() ); + myOrderedNodes.resize( nbFaceNodes ); for ( iSub = 0, n = nodes.begin(); n != nodes.end(); ++n ) { xyzList.push_back( gp_XYZ( (*n)->X(), (*n)->Y(), (*n)->Z() )); myOrderedNodes[ iSub++] = *n; @@ -2980,7 +3013,7 @@ bool SMESH_Pattern::Apply (SMESH_Mesh* theMesh, } // put points on links to myIdsOnBoundary, // they will be used to sew new elements on adjacent refined elements - int nbNodes = (*face)->NbNodes(), eID = nbNodes + 1; + int nbNodes = (*face)->NbCornerNodes(), eID = nbNodes + 1; for ( int i = 0; i < nbNodes; i++ ) { list< TPoint* > & linkPoints = getShapePoints( eID++ ); @@ -3140,6 +3173,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, myIs2D = false; SMESHDS_SubMesh * aSubMesh; + const bool isQuadMesh = theMesh->NbVolumes( ORDER_QUADRATIC ); + // load shapes in myShapeIDMap SMESH_Block block; TopoDS_Vertex v1, v2; @@ -3172,6 +3207,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // store a node and a point while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); + if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Volume )) + continue; nodePointIDMap.insert( make_pair( node, iPoint )); if ( block.IsVertexID( shapeID )) myKeyPointIDs.push_back( iPoint ); @@ -3206,9 +3243,11 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, nIt = aSubMesh->GetNodes(); for ( ; nIt->more(); pIt++ ) { - const SMDS_MeshNode* node = smdsNode( nIt->next() ); + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = ( epos->GetUParameter() - f ) / ( l - f ); (*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u ); } @@ -3232,11 +3271,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, { SMDS_ElemIteratorPtr elemIt = aSubMesh->GetElements(); while ( elemIt->more() ) { - SMDS_ElemIteratorPtr nIt = elemIt->next()->nodesIterator(); + const SMDS_MeshElement* elem = elemIt->next(); myElemPointIDs.push_back( TElemDef() ); TElemDef& elemPoints = myElemPointIDs.back(); - while ( nIt->more() ) - elemPoints.push_back( nodePointIDMap[ nIt->next() ]); + int nbNodes = elem->NbCornerNodes(); + for ( int i = 0;i < nbNodes; ++i ) + elemPoints.push_back( nodePointIDMap[ elem->GetNode( i )]); } } @@ -3684,13 +3724,8 @@ bool SMESH_Pattern:: vector& theQuantity) { bool makePoly = false; -// cout << "FROM FACE NODES: " < bndNodeSet; - for ( int i = 0; i < theNbBndNodes; ++i ) - bndNodeSet.insert( theBndNodes[ i ]); + set< const SMDS_MeshNode* > bndNodeSet( theBndNodes, theBndNodes + theNbBndNodes); map< TNodeSet, list< list< int > > >::iterator nn_IdList; @@ -3699,12 +3734,13 @@ bool SMESH_Pattern:: if ( !myIs2D ) { // for 2D, merge only edges nn_IdList = myIdsOnBoundary.find( bndNodeSet ); if ( nn_IdList != myIdsOnBoundary.end() ) { - makePoly = true; list< int > & faceIds = nn_IdList->second.front(); - ids.insert( faceIds.begin(), faceIds.end() ); + if ( !faceIds.empty() ) { + makePoly = true; + ids.insert( faceIds.begin(), faceIds.end() ); + } } } - //bool hasIdsInFace = !ids.empty(); // add ids on links and bnd nodes int lastFreeId = Max( myXYZIdToNodeMap.rbegin()->first, theNodes.size() ); @@ -3720,22 +3756,26 @@ bool SMESH_Pattern:: bndId = nn_IdList->second.front().front(); ids.insert( bndId ); } - else + else { myXYZIdToNodeMap.insert( make_pair( bndId, theBndNodes[ iN ] )); + } faceDef.push_back( bndId ); // add ids on a link TNodeSet linkNodes; linkNodes.insert( theBndNodes[ iN ]); - linkNodes.insert( theBndNodes[ iN + 1 == theNbBndNodes ? 0 : iN + 1 ]); + linkNodes.insert( theBndNodes[ (iN + 1) % theNbBndNodes] ); nn_IdList = myIdsOnBoundary.find( linkNodes ); if ( nn_IdList != myIdsOnBoundary.end() ) { - makePoly = true; list< int > & linkIds = nn_IdList->second.front(); - ids.insert( linkIds.begin(), linkIds.end() ); - if ( isReversed( theBndNodes[ iN ], linkIds )) - faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() ); - else - faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() ); + if ( !linkIds.empty() ) + { + makePoly = true; + ids.insert( linkIds.begin(), linkIds.end() ); + if ( isReversed( theBndNodes[ iN ], linkIds )) + faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() ); + else + faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() ); + } } } @@ -3757,9 +3797,7 @@ bool SMESH_Pattern:: { if ( !checkedVolDefs.insert( *pIdList ).second ) continue; // skip already checked volume definition - vector< int > idVec; - idVec.reserve( (*pIdList)->size() ); - idVec.insert( idVec.begin(), (*pIdList)->begin(), (*pIdList)->end() ); + vector< int > idVec( (*pIdList)->begin(), (*pIdList)->end() ); // loop on face defs of a volume SMDS_VolumeTool::VolumeType volType = vol.GetType( idVec.size() ); if ( volType == SMDS_VolumeTool::UNKNOWN ) @@ -3789,7 +3827,7 @@ bool SMESH_Pattern:: } if ( !defsAdded ) { theQuantity.push_back( faceDef.size() ); - theFaceDefs.splice( theFaceDefs.end(), faceDef, faceDef.begin(), faceDef.end() ); + theFaceDefs.splice( theFaceDefs.end(), faceDef ); } return makePoly; @@ -3853,7 +3891,7 @@ void SMESH_Pattern::clearMesh(SMESH_Mesh* theMesh) const // coordinates computed by either of Apply...() methods // WARNING : StdMeshers_Projection_... relies on MakeMesh() behavior: that // it does not care of nodes and elements already existing on -// subshapes. DO NOT MERGE them or modify also StdMeshers_Projection_.. +// sub-shapes. DO NOT MERGE them or modify also StdMeshers_Projection_.. //======================================================================= bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, @@ -3922,7 +3960,7 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, point->myXYZ.Z()); nodesVector [ pIndex ] = node; - if ( true /*subMeshDS*/ ) { + if ( !S.IsNull() /*subMeshDS*/ ) { // !!!!! do not merge new nodes with ones existing on submeshes (see method comment) switch ( S.ShapeType() ) { case TopAbs_VERTEX: { @@ -3960,6 +3998,8 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, createElements( theMesh, nodesVector, myElemPointIDs, myElements ); } + aMeshDS->compactMesh(); + // const map& sm = aMeshDS->SubMeshes(); // map::const_iterator i_sm = sm.begin(); // for ( ; i_sm != sm.end(); i_sm++ ) @@ -4107,10 +4147,12 @@ void SMESH_Pattern::createElements(SMESH_Mesh* theMes SMDS_ElemIteratorPtr noIt = elem->nodesIterator(); while ( noIt->more() ) { SMDS_MeshNode* node = const_cast(smdsNode( noIt->next() )); - if (!node->GetPosition()->GetShapeId() && + if (!node->getshapeId() && shellNodes.find( node ) == shellNodes.end() ) { if ( S.ShapeType() == TopAbs_FACE ) - aMeshDS->SetNodeOnFace( node, shapeID ); + aMeshDS->SetNodeOnFace( node, shapeID, + Precision::Infinite(),// <- it's a sign that UV is not set + Precision::Infinite()); else { aMeshDS->SetNodeInVolume( node, shapeID ); shellNodes.insert( node ); @@ -4540,6 +4582,29 @@ void SMESH_Pattern::Clear() myShapeIDMap.Clear(); myShape.Nullify(); myNbKeyPntInBoundary.clear(); + + myXYZ.clear(); + myElemXYZIDs.clear(); + myXYZIdToNodeMap.clear(); + myElements.clear(); + myOrderedNodes.clear(); + myPolyElems.clear(); + myPolyElemXYZIDs.clear(); + myPolyhedronQuantities.clear(); + myIdsOnBoundary.clear(); + myReverseConnectivity.clear(); +} + +//================================================================================ +/*! + * \brief set ErrorCode and return true if it is Ok + */ +//================================================================================ + +bool SMESH_Pattern::setErrorCode( const ErrorCode theErrorCode ) +{ + myErrorCode = theErrorCode; + return myErrorCode == ERR_OK; } //======================================================================= diff --git a/src/SMESH/SMESH_Pattern.hxx b/src/SMESH/SMESH_Pattern.hxx index ee87cbfb8..2ba7666aa 100644 --- a/src/SMESH/SMESH_Pattern.hxx +++ b/src/SMESH/SMESH_Pattern.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Pattern.hxx // Created : Mon Aug 2 10:30:00 2004 // Author : Edward AGAPOV (eap) @@ -190,7 +191,9 @@ class SMESH_EXPORT SMESH_Pattern { // Apply(mesh_face) ERR_APPLF_BAD_FACE_GEOM, // bad face geometry // MakeMesh - ERR_MAKEM_NOT_COMPUTED // mapping failed + ERR_MAKEM_NOT_COMPUTED, // mapping failed + //Unexpected error + ERR_UNEXPECTED // Unexpected of the pattern mapping alorithm }; ErrorCode GetErrorCode() const { return myErrorCode; } @@ -241,8 +244,7 @@ private: }; friend std::ostream & operator <<(std::ostream & OS, const TPoint& p); - bool setErrorCode( const ErrorCode theErrorCode ) - { myErrorCode = theErrorCode; return myErrorCode == ERR_OK; } + bool setErrorCode( const ErrorCode theErrorCode ); // set ErrorCode and return true if it is Ok bool setShapeToMesh(const TopoDS_Shape& theShape); diff --git a/src/SMESH/SMESH_ProxyMesh.cxx b/src/SMESH/SMESH_ProxyMesh.cxx new file mode 100644 index 000000000..a4e4f5998 --- /dev/null +++ b/src/SMESH/SMESH_ProxyMesh.cxx @@ -0,0 +1,545 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_ProxyMesh.cxx +// Created : Thu Dec 2 12:32:53 2010 +// Author : Edward AGAPOV (eap) + +#include "SMESH_ProxyMesh.hxx" + +#include "SMDS_IteratorOnIterators.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMESH_MesherHelper.hxx" + +#include +#include +#include + +//================================================================================ +/*! + * \brief Constructor; mesh must be set by a descendant class + */ +//================================================================================ + +SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0) +{ +} +//================================================================================ +/*! + * \brief Make a proxy mesh from components. Components become empty + */ +//================================================================================ + +SMESH_ProxyMesh::SMESH_ProxyMesh(vector& components): + _mesh(0) +{ + if ( components.empty() ) return; + + for ( unsigned i = 0; i < components.size(); ++i ) + { + SMESH_ProxyMesh* m = components[i].get(); + if ( !m ) continue; + + takeTmpElemsInMesh( m ); + + if ( !_mesh ) _mesh = m->_mesh; + if ( _allowedTypes.empty() ) _allowedTypes = m->_allowedTypes; + + if ( _subMeshes.size() < m->_subMeshes.size() ) + _subMeshes.resize( m->_subMeshes.size(), 0 ); + for ( unsigned j = 0; j < m->_subMeshes.size(); ++j ) + { + if ( !m->_subMeshes[j] ) continue; + if ( _subMeshes[j] ) + { + // unite 2 sub-meshes + set< const SMDS_MeshElement * > elems( _subMeshes[j]->_elements.begin(), + _subMeshes[j]->_elements.end()); + elems.insert( m->_subMeshes[j]->_elements.begin(), + m->_subMeshes[j]->_elements.end()); + _subMeshes[j]->_elements.assign( elems.begin(), elems.end() ); + m->_subMeshes[j]->_elements.clear(); + + if ( !_subMeshes[j]->_n2n ) + _subMeshes[j]->_n2n = m->_subMeshes[j]->_n2n, m->_subMeshes[j]->_n2n = 0; + + else if ( _subMeshes[j]->_n2n && m->_subMeshes[j]->_n2n ) + _subMeshes[j]->_n2n->insert( m->_subMeshes[j]->_n2n->begin(), + m->_subMeshes[j]->_n2n->end()); + } + else + { + _subMeshes[j] = m->_subMeshes[j]; + m->_subMeshes[j] = 0; + } + } + } +} + +//================================================================================ +/*! + * \brief Destructor deletes proxy submeshes and tmp elemens + */ +//================================================================================ + +SMESH_ProxyMesh::~SMESH_ProxyMesh() +{ + for ( unsigned i = 0; i < _subMeshes.size(); ++i ) + delete _subMeshes[i]; + _subMeshes.clear(); + + set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.begin(); + for ( ; i != _elemsInMesh.end(); ++i ) + GetMeshDS()->RemoveFreeElement( *i, 0 ); + _elemsInMesh.clear(); +} + +//================================================================================ +/*! + * \brief Returns index of a shape + */ +//================================================================================ + +int SMESH_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const +{ + return ( shape.IsNull() || !_mesh->HasShapeToMesh() ? 0 : GetMeshDS()->ShapeToIndex(shape)); +} + +//================================================================================ +/*! + * \brief Returns the submesh of a shape; it can be a proxy sub-mesh + */ +//================================================================================ + +const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) const +{ + const SMESHDS_SubMesh* sm = 0; + + int i = shapeIndex(shape); + if ( i < _subMeshes.size() ) + sm = _subMeshes[i]; + if ( !sm ) + sm = GetMeshDS()->MeshElements( i ); + + return sm; +} + +//================================================================================ +/*! + * \brief Returns the proxy sub-mesh of a shape; it can be NULL + */ +//================================================================================ + +const SMESH_ProxyMesh::SubMesh* +SMESH_ProxyMesh::GetProxySubMesh(const TopoDS_Shape& shape) const +{ + int i = shapeIndex(shape); + return i < _subMeshes.size() ? _subMeshes[i] : 0; +} + +//================================================================================ +/*! + * \brief Returns the proxy node of a node; the input node is returned if no proxy exists + */ +//================================================================================ + +const SMDS_MeshNode* SMESH_ProxyMesh::GetProxyNode( const SMDS_MeshNode* node ) const +{ + const SMDS_MeshNode* proxy = node; + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) + { + if ( const SubMesh* proxySM = findProxySubMesh( node->getshapeId() )) + proxy = proxySM->GetProxyNode( node ); + } + else + { + TopoDS_Shape shape = SMESH_MesherHelper::GetSubShapeByNode( node, GetMeshDS()); + TopTools_ListIteratorOfListOfShape ancIt; + if ( !shape.IsNull() ) ancIt.Initialize( _mesh->GetAncestors( shape )); + for ( ; ancIt.More() && proxy == node; ancIt.Next() ) + if ( const SubMesh* proxySM = findProxySubMesh( shapeIndex(ancIt.Value()))) + proxy = proxySM->GetProxyNode( node ); + } + return proxy; +} + +namespace +{ + //================================================================================ + /*! + * \brief Iterator filtering elements by type + */ + //================================================================================ + + class TFilteringIterator : public SMDS_ElemIterator + { + SMDS_ElemIteratorPtr _iter; + const SMDS_MeshElement * _curElem; + vector< SMDSAbs_EntityType> _okTypes; + public: + TFilteringIterator( const vector< SMDSAbs_EntityType>& okTypes, + const SMDS_ElemIteratorPtr& elemIterator) + :_iter(elemIterator), _curElem(0), _okTypes(okTypes) + { + next(); + } + virtual bool more() + { + return _curElem; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _curElem; + _curElem = 0; + while ( _iter->more() && !_curElem ) + { + _curElem = _iter->next(); + if ( find( _okTypes.begin(), _okTypes.end(), _curElem->GetEntityType()) == _okTypes.end()) + _curElem = 0; + } + return res; + } + }; +} + +//================================================================================ +/*! + * \brief Returns iterator on all faces on the shape taking into account substitutions + */ +//================================================================================ + +SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces(const TopoDS_Shape& shape) const +{ + if ( !_mesh->HasShapeToMesh() ) + return SMDS_ElemIteratorPtr(); + + _subContainer.RemoveAllSubmeshes(); + + TopTools_IndexedMapOfShape FF; + TopExp::MapShapes( shape, TopAbs_FACE, FF ); + for ( int i = 1; i <= FF.Extent(); ++i ) + if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i))) + _subContainer.AddSubMesh( sm ); + + return _subContainer.SMESHDS_SubMesh::GetElements(); +} + +//================================================================================ +/*! + * \brief Returns iterator on all faces of the mesh taking into account substitutions + * To be used in case of mesh without shape + */ +//================================================================================ + +SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces() const +{ + if ( _mesh->HasShapeToMesh() ) + return SMDS_ElemIteratorPtr(); + + _subContainer.RemoveAllSubmeshes(); + for ( unsigned i = 0; i < _subMeshes.size(); ++i ) + if ( _subMeshes[i] ) + _subContainer.AddSubMesh( _subMeshes[i] ); + + if ( _subContainer.NbSubMeshes() == 0 ) // no elements substituted + return GetMeshDS()->elementsIterator(SMDSAbs_Face); + + // if _allowedTypes is empty, only elements from _subMeshes are returned,... + SMDS_ElemIteratorPtr proxyIter = _subContainer.SMESHDS_SubMesh::GetElements(); + if ( _allowedTypes.empty() || NbFaces() == _mesh->NbFaces() ) + return proxyIter; + + // ... else elements filtered using allowedTypes are additionally returned + SMDS_ElemIteratorPtr facesIter = GetMeshDS()->elementsIterator(SMDSAbs_Face); + SMDS_ElemIteratorPtr filterIter( new TFilteringIterator( _allowedTypes, facesIter )); + vector< SMDS_ElemIteratorPtr > iters(2); + iters[0] = proxyIter; + iters[1] = filterIter; + + typedef vector< SMDS_ElemIteratorPtr > TElemIterVector; + typedef SMDS_IteratorOnIterators TItersIter; + return SMDS_ElemIteratorPtr( new TItersIter( iters )); +} + +//================================================================================ +/*! + * \brief Return total nb of faces taking into account substitutions + */ +//================================================================================ + +int SMESH_ProxyMesh::NbFaces() const +{ + int nb = 0; + if ( _mesh->HasShapeToMesh() ) + { + TopTools_IndexedMapOfShape FF; + TopExp::MapShapes( _mesh->GetShapeToMesh(), TopAbs_FACE, FF ); + for ( int i = 1; i <= FF.Extent(); ++i ) + if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i))) + nb += sm->NbElements(); + } + else + { + if ( _subMeshes.empty() ) + return GetMeshDS()->NbFaces(); + + for ( unsigned i = 0; i < _subMeshes.size(); ++i ) + if ( _subMeshes[i] ) + nb += _subMeshes[i]->NbElements(); + + // if _allowedTypes is empty, only elements from _subMeshes are returned, + // else elements filtered using allowedTypes are additionally returned + if ( !_allowedTypes.empty() ) + { + for ( int t = SMDSEntity_Triangle; t <= SMDSEntity_Quad_Quadrangle; ++t ) + { + bool allowed = + ( find( _allowedTypes.begin(), _allowedTypes.end(), t ) != _allowedTypes.end() ); + if ( allowed ) + nb += GetMeshDS()->GetMeshInfo().NbEntities( SMDSAbs_EntityType( t )); + } + } + } + return nb; +} + +//================================================================================ +/*! + * \brief Returns a proxy sub-mesh; it is created if not yet exists + */ +//================================================================================ + +SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(int index) +{ + if ( int(_subMeshes.size()) <= index ) + _subMeshes.resize( index+1, 0 ); + if ( !_subMeshes[index] ) + _subMeshes[index] = new SubMesh( index ); + return _subMeshes[index]; +} + +//================================================================================ +/*! + * \brief Returns a proxy sub-mesh; it is created if not yet exists + */ +//================================================================================ + +SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(const TopoDS_Shape& shape) +{ + return getProxySubMesh( shapeIndex( shape )); +} + +//================================================================================ +/*! + * \brief Returns a proxy sub-mesh + */ +//================================================================================ + +SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::findProxySubMesh(int shapeIndex) const +{ + return shapeIndex < int(_subMeshes.size()) ? _subMeshes[shapeIndex] : 0; +} + +//================================================================================ +/*! + * \brief Returns mesh DS + */ +//================================================================================ + +SMESHDS_Mesh* SMESH_ProxyMesh::GetMeshDS() const +{ + return (SMESHDS_Mesh*)( _mesh ? _mesh->GetMeshDS() : 0 ); +} + +//================================================================================ +/*! + * \brief Move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found + */ +//================================================================================ + +bool SMESH_ProxyMesh::takeProxySubMesh( const TopoDS_Shape& shape, + SMESH_ProxyMesh* proxyMesh ) +{ + if ( proxyMesh && proxyMesh->_mesh == _mesh ) + { + int iS = shapeIndex( shape ); + if ( SubMesh* sm = proxyMesh->findProxySubMesh( iS )) + { + if ( iS >= int(_subMeshes.size()) ) + _subMeshes.resize( iS + 1, 0 ); + _subMeshes[iS] = sm; + proxyMesh->_subMeshes[iS] = 0; + return true; + } + } + return false; +} + +//================================================================================ +/*! + * \brief Move tmp elements residing the _mesh from other proxy mesh to this + */ +//================================================================================ + +void SMESH_ProxyMesh::takeTmpElemsInMesh( SMESH_ProxyMesh* proxyMesh ) +{ + if ( proxyMesh ) + { + _elemsInMesh.insert( proxyMesh->_elemsInMesh.begin(), + proxyMesh->_elemsInMesh.end()); + proxyMesh->_elemsInMesh.clear(); + } +} + +//================================================================================ +/*! + * \brief Removes tmp faces from the _mesh + */ +//================================================================================ + +void SMESH_ProxyMesh::removeTmpElement( const SMDS_MeshElement* face ) +{ + if ( face && face->GetID() > 0 ) + { + set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.find( face ); + if ( i != _elemsInMesh.end() ) + { + GetMeshDS()->RemoveFreeElement( face, 0 ); + _elemsInMesh.erase( i ); + } + } + else + { + delete face; + } +} + +//================================================================================ +/*! + * \brief Stores tmp element residing the _mesh + */ +//================================================================================ + +void SMESH_ProxyMesh::storeTmpElement( const SMDS_MeshElement* face ) +{ + _elemsInMesh.insert( face ); +} + +//================================================================================ +/*! + * \brief Set node-node correspondence + */ +//================================================================================ + +void SMESH_ProxyMesh::setNode2Node(const SMDS_MeshNode* srcNode, + const SMDS_MeshNode* proxyNode, + const SubMesh* subMesh) +{ + SubMesh* sm = const_cast( subMesh ); + if ( !subMesh->_n2n ) + sm->_n2n = new TN2NMap; + sm->_n2n->insert( make_pair( srcNode, proxyNode )); +} + +//================================================================================ +/*! + * \brief Return true if the element is a temporary one + */ +//================================================================================ + +bool SMESH_ProxyMesh::IsTemporary(const SMDS_MeshElement* elem ) const +{ + return ( elem->GetID() < 1 ) || _elemsInMesh.count( elem ); +} + +//================================================================================ +/*! + * \brief Return a proxy node or an input node + */ +//================================================================================ + +const SMDS_MeshNode* SMESH_ProxyMesh::SubMesh::GetProxyNode( const SMDS_MeshNode* n ) const +{ + TN2NMap::iterator n2n; + if ( _n2n && ( n2n = _n2n->find( n )) != _n2n->end()) + return n2n->second; + return n; +} + +//================================================================================ +/*! + * \brief Deletes temporary elements + */ +//================================================================================ + +void SMESH_ProxyMesh::SubMesh::Clear() +{ + for ( unsigned i = 0; i < _elements.size(); ++i ) + if ( _elements[i]->GetID() < 0 ) + delete _elements[i]; + _elements.clear(); + if ( _n2n ) + delete _n2n, _n2n = 0; +} + +//================================================================================ +/*! + * \brief Return number of elements in a proxy submesh + */ +//================================================================================ + +int SMESH_ProxyMesh::SubMesh::NbElements() const +{ + return _elements.size(); +} + +//================================================================================ +/*! + * \brief Return elements of a proxy submesh + */ +//================================================================================ + +SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements() const +{ + return SMDS_ElemIteratorPtr + ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() )); +} + +//================================================================================ +/*! + * \brief Store an element + */ +//================================================================================ + +void SMESH_ProxyMesh::SubMesh::AddElement(const SMDS_MeshElement * e) +{ + _elements.push_back( e ); +} + +//================================================================================ +/*! + * \brief Check presence of element inside it-self + */ +//================================================================================ + +bool SMESH_ProxyMesh::SubMesh::Contains(const SMDS_MeshElement * ME) const +{ + if ( ME->GetType() != SMDSAbs_Node ) + return find( _elements.begin(), _elements.end(), ME ) != _elements.end(); + return false; +} diff --git a/src/SMESH/SMESH_ProxyMesh.hxx b/src/SMESH/SMESH_ProxyMesh.hxx new file mode 100644 index 000000000..faf67734f --- /dev/null +++ b/src/SMESH/SMESH_ProxyMesh.hxx @@ -0,0 +1,173 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_ProxyMesh.hxx +// Created : Thu Dec 2 10:05:35 2010 +// Author : Edward AGAPOV (eap) + +#ifndef __SMESH_ProxyMesh_HXX__ +#define __SMESH_ProxyMesh_HXX__ + +#include "SMESH_SMESH.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMESHDS_SubMesh.hxx" + +#include + +#include +#include +#include + +class SMDS_MeshNode; +class SMESHDS_Mesh; +class SMESH_Mesh; + +/*! + * \brief Container of mesh faces substituting other faces in the input mesh of 3D algorithm + */ +class SMESH_EXPORT SMESH_ProxyMesh +{ +public: + + typedef boost::shared_ptr Ptr; + + typedef std::map TN2NMap; + + //-------------------------------------------------------------------------------- + /*! + * \brief Proxy sub-mesh + */ + class SubMesh : public SMESHDS_SubMesh + { + public: + + const TN2NMap* GetNodeNodeMap() const { return _n2n; } + const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* n ) const; + virtual void AddElement(const SMDS_MeshElement * e); + virtual int NbElements() const; + virtual SMDS_ElemIteratorPtr GetElements() const; + virtual void Clear(); + virtual bool Contains(const SMDS_MeshElement * ME) const; + + template< class ITERATOR > + void ChangeElements( ITERATOR it, ITERATOR end ) + { + // change SubMesh contents without deleting tmp faces + // for which the caller is responsible + _elements.clear(); + while ( it != end ) _elements.push_back( *it++ ); + } + SubMesh(int index=0):SMESHDS_SubMesh(0,index),_n2n(0) {} + ~SubMesh() { Clear(); } + + private: + std::vector _elements; + TN2NMap* _n2n; + friend class SMESH_ProxyMesh; + }; + //-------------------------------------------------------------------------------- + // Public interface + + SMESH_ProxyMesh(); + SMESH_ProxyMesh(std::vector& components); + SMESH_ProxyMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; } + virtual ~SMESH_ProxyMesh(); + + // Returns the submesh of a face; it can be a proxy sub-mesh + const SMESHDS_SubMesh* GetSubMesh(const TopoDS_Shape& face) const; + + // Returns the proxy sub-mesh of a face; it can be NULL + const SubMesh* GetProxySubMesh(const TopoDS_Shape& face) const; + + // Returns the proxy node of a node; the input node is returned if no proxy exists + const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* node ) const; + + // Returns iterator on all faces of the mesh taking into account substitutions + // To be used in case of mesh without shape + SMDS_ElemIteratorPtr GetFaces() const; + + // Returns iterator on all faces on the face taking into account substitutions + SMDS_ElemIteratorPtr GetFaces(const TopoDS_Shape& face) const; + + // Return total nb of faces taking into account substitutions + int NbFaces() const; + + bool IsTemporary(const SMDS_MeshElement* elem ) const; + + + + const SMESH_Mesh* GetMesh() const { return _mesh; } + + SMESHDS_Mesh* GetMeshDS() const; + + //-------------------------------------------------------------------------------- + // Interface for descendants + protected: + + void setMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; } + + int shapeIndex(const TopoDS_Shape& shape) const; + + // returns a proxy sub-mesh; zero index is for the case of mesh w/o shape + SubMesh* findProxySubMesh(int shapeIndex=0) const; + + // returns a proxy sub-mesh; it is created if not yet exists + SubMesh* getProxySubMesh(int shapeIndex); + + // returns a proxy sub-mesh; it is created if not yet exists + SubMesh* getProxySubMesh(const TopoDS_Shape& shape=TopoDS_Shape()); + + // move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found + bool takeProxySubMesh( const TopoDS_Shape& shape, SMESH_ProxyMesh* proxyMesh ); + + // move tmp elements residing the _mesh from other proxy mesh to this + void takeTmpElemsInMesh( SMESH_ProxyMesh* proxyMesh ); + + // removes tmp faces from the _mesh + void removeTmpElement( const SMDS_MeshElement* face ); + + // stores tmp element residing the _mesh + void storeTmpElement( const SMDS_MeshElement* face ); + + // store node-node correspondence + void setNode2Node(const SMDS_MeshNode* srcNode, + const SMDS_MeshNode* proxyNode, + const SubMesh* subMesh); + + // types of elements needed to implement NbFaces() and GetFaces(); + // if _allowedTypes is empty, only elements from _subMeshes are returned, + // else elements of _mesh filtered using allowedTypes are additionally returned + std::vector< SMDSAbs_EntityType> _allowedTypes; + + private: + + const SMESH_Mesh* _mesh; + + // proxy sub-meshes; index in vector == shapeIndex(shape) + std::vector< SubMesh* > _subMeshes; + + // tmp elements residing the _mesh, to be deleted at destruction + std::set< const SMDS_MeshElement* > _elemsInMesh; + + // Complex submesh used to iterate over elements in other sub-meshes + mutable SubMesh _subContainer; +}; + +#endif diff --git a/src/SMESH/SMESH_SMESH.hxx b/src/SMESH/SMESH_SMESH.hxx index 249fc6a85..977f5fa1f 100755 --- a/src/SMESH/SMESH_SMESH.hxx +++ b/src/SMESH/SMESH_SMESH.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_SMESH.hxx // Author : Alexander A. BORODIN // Module : SMESH @@ -27,7 +28,7 @@ #define _SMESH_SMESH_HXX_ #ifdef WNT - #if defined SMESH_EXPORTS + #if defined SMESHimpl_EXPORTS #define SMESH_EXPORT __declspec( dllexport ) #else #define SMESH_EXPORT __declspec( dllimport ) diff --git a/src/SMESH/SMESH_SequenceOfElemPtr.hxx b/src/SMESH/SMESH_SequenceOfElemPtr.hxx deleted file mode 100644 index 77c92ad5a..000000000 --- a/src/SMESH/SMESH_SequenceOfElemPtr.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File: SMESH_SequenceOfElemPtr.hxx -// Created: 26.09.05 17:41:10 -// Author: Sergey KUUL -// -#ifndef SMESH_SequenceOfElemPtr_HeaderFile -#define SMESH_SequenceOfElemPtr_HeaderFile - -#include "SMESH_SMESH.hxx" - -#include - -#include - -typedef const SMDS_MeshElement* SMDS_MeshElementPtr; - -DEFINE_BASECOLLECTION (SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr) -DEFINE_SEQUENCE (SMESH_SequenceOfElemPtr, SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr) - -#endif diff --git a/src/SMESH/SMESH_SequenceOfNode.hxx b/src/SMESH/SMESH_SequenceOfNode.hxx deleted file mode 100644 index 4eabe0ee6..000000000 --- a/src/SMESH/SMESH_SequenceOfNode.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File: SMESH_SequenceOfNode.hxx -// Created: 11.11.05 10:00:04 -// Author: Sergey KUUL -// -#ifndef SMESH_SequenceOfNode_HeaderFile -#define SMESH_SequenceOfNode_HeaderFile - -#include "SMESH_SMESH.hxx" - -#include - -typedef const SMDS_MeshNode* SMDS_MeshNodePtr; - -DEFINE_BASECOLLECTION (SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr) -DEFINE_SEQUENCE(SMESH_SequenceOfNode, - SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr) - - -#endif diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 6c484c80a..65ffac712 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_subMesh.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ -// + #include "SMESH_subMesh.hxx" #include "SMESH_Algo.hxx" @@ -36,9 +36,13 @@ #include "SMESH_subMeshEventListener.hxx" #include "SMESH_Comment.hxx" #include "SMDS_SetIterator.hxx" +#include "SMDSAbs_ElementType.hxx" + +#include #include "utilities.h" #include "OpUtil.hxx" +#include "Basics_Utils.hxx" #include #include @@ -54,6 +58,8 @@ #include #include +#include + using namespace std; //============================================================================= @@ -82,22 +88,22 @@ SMESH_subMesh::SMESH_subMesh(int Id, SMESHDS_Mesh * meshDS, const TopoDS_Shape & aSubShape) { - _subShape = aSubShape; - _subMeshDS = meshDS->MeshElements(_subShape); // may be null ... - _father = father; - _Id = Id; - _dependenceAnalysed = _alwaysComputed = false; - - if (_subShape.ShapeType() == TopAbs_VERTEX) - { - _algoState = HYP_OK; - _computeState = READY_TO_COMPUTE; - } - else - { + _subShape = aSubShape; + _subMeshDS = meshDS->MeshElements(_subShape); // may be null ... + _father = father; + _Id = Id; + _dependenceAnalysed = _alwaysComputed = false; + + if (_subShape.ShapeType() == TopAbs_VERTEX) + { + _algoState = HYP_OK; + _computeState = READY_TO_COMPUTE; + } + else + { _algoState = NO_ALGO; _computeState = NOT_READY; - } + } } //============================================================================= @@ -110,7 +116,7 @@ SMESH_subMesh::~SMESH_subMesh() { MESSAGE("SMESH_subMesh::~SMESH_subMesh"); // **** - DeleteOwnListeners(); + deleteOwnListeners(); } //============================================================================= @@ -171,7 +177,18 @@ SMESH_subMesh *SMESH_subMesh::GetFirstToCompute() //================================================================================ /*! - * \brief Allow algo->Compute() if a subshape of lower dim is meshed but + * \brief Returns a current algorithm + */ +//================================================================================ + +SMESH_Algo* SMESH_subMesh::GetAlgo() const +{ + return _father->GetGen()->GetAlgo(*_father, _subShape); +} + +//================================================================================ +/*! + * \brief Allow algo->Compute() if a sub-shape of lower dim is meshed but * none mesh entity is bound to it (PAL13615, 2nd part) */ //================================================================================ @@ -240,7 +257,7 @@ bool SMESH_subMesh::IsMeshComputed() const */ //============================================================================= -bool SMESH_subMesh::SubMeshesComputed() +bool SMESH_subMesh::subMeshesComputed() { int myDim = SMESH_Gen::GetShapeDim( _subShape ); int dimToCheck = myDim - 1; @@ -261,7 +278,7 @@ bool SMESH_subMesh::SubMeshesComputed() break; // the rest subMeshes are all of less dimension SMESHDS_SubMesh * ds = sm->GetSubMeshDS(); bool computeOk = (sm->GetComputeState() == COMPUTE_OK || - (ds && ( ds->NbNodes() || ds->NbElements() ))); + (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes() ))); if (!computeOk) { int type = ss.ShapeType(); @@ -324,23 +341,23 @@ bool SMESH_subMesh::SubMeshesComputed() */ //============================================================================= -bool SMESH_subMesh::SubMeshesReady() -{ - bool subMeshesReady = true; - 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; - SCRUTE(sm->GetId()); - break; - } - } - return subMeshesReady; -} +// bool SMESH_subMesh::SubMeshesReady() +// { +// bool subMeshesReady = true; +// 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; +// SCRUTE(sm->GetId()); +// break; +// } +// } +// return subMeshesReady; +// } //============================================================================= /*! @@ -368,55 +385,53 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_COMPOUND: { //MESSAGE("compound"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } - for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next()) { - InsertDependence(exp.Current()); //only shell not in solid + if ( BRep_Tool::IsClosed(exp.Current() )) + insertDependence(exp.Current()); //only shell not in solid + else + for (TopExp_Explorer expF(exp.Current(), TopAbs_FACE); expF.More();expF.Next()) + insertDependence(expF.Current()); // issue 0020959: HEXA_3D fails on shell + } - for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } break; } case TopAbs_COMPSOLID: { - //MESSAGE("compsolid"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); - exp.Next()) + //MESSAGE("compsolid"); + for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } break; } case TopAbs_SHELL: { //MESSAGE("shell"); - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } break; } case TopAbs_WIRE: { //MESSAGE("wire"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } break; } @@ -424,10 +439,9 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() { //MESSAGE("solid"); if(_father->HasShapeToMesh()) { - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } } break; @@ -435,21 +449,19 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_FACE: { //MESSAGE("face"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next()) { - InsertDependence(exp.Current()); + insertDependence(exp.Current()); } break; } case TopAbs_EDGE: { //MESSAGE("edge"); - for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next()) { - InsertDependence(exp.Current()); - } + insertDependence(exp.Current()); + } break; } case TopAbs_VERTEX: @@ -471,9 +483,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() */ //============================================================================= -void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape) +void SMESH_subMesh::insertDependence(const TopoDS_Shape aSubShape) { - //MESSAGE("SMESH_subMesh::InsertDependence"); SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape); int type = aSubShape.ShapeType(); int ordType = 9 - type; // 2 = Vertex, 8 = CompSolid @@ -495,8 +506,8 @@ void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape) const TopoDS_Shape & SMESH_subMesh::GetSubShape() const { - //MESSAGE("SMESH_subMesh::GetSubShape"); - return _subShape; + //MESSAGE("SMESH_subMesh::GetSubShape"); + return _subShape; } @@ -510,12 +521,13 @@ bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) cons { int aHypDim = theHypothesis->GetDim(); int aShapeDim = SMESH_Gen::GetShapeDim(_subShape); - if (aHypDim == 3 && aShapeDim == 3) { - // check case of open shell - //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed()) - if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape)) - return false; - } + // issue 21106. Forbid 3D mesh on the SHELL + // if (aHypDim == 3 && aShapeDim == 3) { + // // check case of open shell + // //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed()) + // if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape)) + // return false; + // } if ( aHypDim <= aShapeDim ) return true; @@ -531,8 +543,14 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, const TopAbs_ShapeEnum theShapeType) { if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO) + { // algorithm - return ( theHypothesis->GetShapeType() & (1<< theShapeType)); + if ( theHypothesis->GetShapeType() & (1<< theShapeType)) + // issue 21106. Forbid 3D mesh on the SHELL + return !( theHypothesis->GetDim() == 3 && theShapeType == TopAbs_SHELL ); + else + return false; + } // hypothesis switch ( theShapeType ) { @@ -579,7 +597,7 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK; SMESHDS_Mesh* meshDS =_father->GetMeshDS(); - SMESH_Gen* gen =_father->GetGen(); + //SMESH_Gen* gen =_father->GetGen(); SMESH_Algo* algo = 0; if (_subShape.ShapeType() == TopAbs_VERTEX ) @@ -596,7 +614,7 @@ SMESH_Hypothesis::Hypothesis_Status if ( event != REMOVE_FATHER_ALGO ) { _algoState = NO_ALGO; - algo = gen->GetAlgo(*_father, _subShape); + algo = GetAlgo(); if ( algo ) { _algoState = MISSING_HYP; if ( event == REMOVE_FATHER_HYP || @@ -609,6 +627,7 @@ SMESH_Hypothesis::Hypothesis_Status int oldAlgoState = _algoState; bool modifiedHyp = (event == MODIF_HYP); // if set to true, force event MODIF_ALGO_STATE + bool needFullClean = false; bool isApplicableHyp = IsApplicableHypotesis( anHyp ); @@ -625,6 +644,15 @@ SMESH_Hypothesis::Hypothesis_Status // ---------------------- if (isApplicableHyp && !_father->IsNotConformAllowed() && !IsConform( algo )) return SMESH_Hypothesis::HYP_NOTCONFORM; + + // check if all-dimensional algo is hidden by other local one + if ( event == ADD_ALGO ) { + SMESH_HypoFilter filter( SMESH_HypoFilter::HasType( algo->GetType() )); + filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 )); + filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 )); + if ( SMESH_Algo * curAlgo = (SMESH_Algo*) _father->GetHypothesis( _subShape, filter, true )) + needFullClean = ( !curAlgo->NeedDiscreteBoundary() ); + } } // ---------------------------------- @@ -635,7 +663,7 @@ SMESH_Hypothesis::Hypothesis_Status if ( ! CanAddHypothesis( anHyp )) // check dimension return SMESH_Hypothesis::HYP_BAD_DIM; - if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) ) + if ( /*!anHyp->IsAuxiliary() &&*/ getSimilarAttached( _subShape, anHyp ) ) return SMESH_Hypothesis::HYP_ALREADY_EXIST; if ( !meshDS->AddHypothesis(_subShape, anHyp)) @@ -653,15 +681,12 @@ SMESH_Hypothesis::Hypothesis_Status if (event == REMOVE_ALGO) { algo = dynamic_cast (anHyp); - if (!algo->NeedDescretBoundary()) + if (!algo->NeedDiscreteBoundary()) { // clean all mesh in the tree of the current submesh; // we must perform it now because later // we will have no information about the type of the removed algo - CleanDependants(); - ComputeStateEngine( CLEAN ); - CleanDependsOn(); - ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); + needFullClean = true; } } } @@ -682,16 +707,16 @@ SMESH_Hypothesis::Hypothesis_Status case ADD_HYP: break; case ADD_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if (algo->CheckHypothesis((*_father),_subShape, aux_ret)) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else if ( algo->IsStatusFatal( aux_ret )) { meshDS->RemoveHypothesis(_subShape, anHyp); ret = aux_ret; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); break; } case REMOVE_HYP: @@ -699,26 +724,26 @@ SMESH_Hypothesis::Hypothesis_Status case ADD_FATHER_HYP: break; case ADD_FATHER_ALGO: { // Algo just added in father - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo == anHyp ) { if ( algo->CheckHypothesis((*_father),_subShape, aux_ret)) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } case REMOVE_FATHER_HYP: break; case REMOVE_FATHER_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo) { if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } @@ -735,10 +760,10 @@ SMESH_Hypothesis::Hypothesis_Status switch (event) { case ADD_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, ret )) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); if (SMESH_Hypothesis::IsStatusFatal( ret )) meshDS->RemoveHypothesis(_subShape, anHyp); else if (!_father->IsUsedHypothesis( anHyp, this )) @@ -749,70 +774,70 @@ SMESH_Hypothesis::Hypothesis_Status break; } case ADD_ALGO: { //already existing algo : on father ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else if ( algo->IsStatusFatal( aux_ret )) { meshDS->RemoveHypothesis(_subShape, anHyp); ret = aux_ret; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); break; } case REMOVE_HYP: break; case REMOVE_ALGO: { // perhaps a father algo applies ? - algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // no more algo applying on subShape... + algo = GetAlgo(); + if (algo == NULL) // no more algo applying on sub-shape... { - SetAlgoState(NO_ALGO); + setAlgoState(NO_ALGO); } else { if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } case MODIF_HYP: // assigned hypothesis value may become good case ADD_FATHER_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); break; } case ADD_FATHER_ALGO: { // new father algo - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT( algo ); if ( algo == anHyp ) { if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } case REMOVE_FATHER_HYP: // nothing to do break; case REMOVE_FATHER_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo == NULL) // no more applying algo on father { - SetAlgoState(NO_ALGO); + setAlgoState(NO_ALGO); } else { if ( algo->CheckHypothesis((*_father),_subShape , aux_ret )) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } @@ -828,7 +853,7 @@ SMESH_Hypothesis::Hypothesis_Status switch (event) { case ADD_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if (!algo->CheckHypothesis((*_father),_subShape, ret )) { @@ -851,7 +876,7 @@ SMESH_Hypothesis::Hypothesis_Status break; } case ADD_ALGO: { //already existing algo : on father ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { // check if algo changes SMESH_HypoFilter f; @@ -864,24 +889,24 @@ SMESH_Hypothesis::Hypothesis_Status modifiedHyp = true; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); break; } case REMOVE_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) - SetAlgoState(HYP_OK); + setAlgoState(HYP_OK); else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); modifiedHyp = true; break; } case REMOVE_ALGO: { // perhaps a father algo applies ? - algo = gen->GetAlgo((*_father), _subShape); - if (algo == NULL) // no more algo applying on subShape... + algo = GetAlgo(); + if (algo == NULL) // no more algo applying on sub-shape... { - SetAlgoState(NO_ALGO); + setAlgoState(NO_ALGO); } else { @@ -891,13 +916,13 @@ SMESH_Hypothesis::Hypothesis_Status modifiedHyp = true; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } case MODIF_HYP: // hypothesis value may become bad case ADD_FATHER_HYP: { // new father hypothesis ? - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { @@ -905,11 +930,11 @@ SMESH_Hypothesis::Hypothesis_Status modifiedHyp = true; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); break; } case ADD_FATHER_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if ( algo == anHyp ) { // a new algo on father if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { // check if algo changes @@ -923,27 +948,33 @@ SMESH_Hypothesis::Hypothesis_Status modifiedHyp = true; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } case REMOVE_FATHER_HYP: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) { // is there the same local hyp or maybe a new father algo applied? - if ( !GetSimilarAttached( _subShape, anHyp ) ) + if ( !getSimilarAttached( _subShape, anHyp ) ) modifiedHyp = true; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); break; } case REMOVE_FATHER_ALGO: { - algo = gen->GetAlgo((*_father), _subShape); + // IPAL21346. Edges not removed when Netgen 1d-2d is removed from a SOLID. + // CLEAN was not called at event REMOVE_ALGO because the algo is not applicable to SOLID. + algo = dynamic_cast (anHyp); + if (!algo->NeedDiscreteBoundary()) + needFullClean = true; + + algo = GetAlgo(); if (algo == NULL) // no more applying algo on father { - SetAlgoState(NO_ALGO); + setAlgoState(NO_ALGO); } else { @@ -953,7 +984,7 @@ SMESH_Hypothesis::Hypothesis_Status modifiedHyp = true; } else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; } @@ -981,16 +1012,19 @@ SMESH_Hypothesis::Hypothesis_Status 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() && !upperAlgo->SupportSubmeshes()) + if ( !upperAlgo->NeedDiscreteBoundary() && !upperAlgo->SupportSubmeshes()) ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO; } // is algo hiding? if ( ret == SMESH_Hypothesis::HYP_OK && - !algo->NeedDescretBoundary() && + !algo->NeedDiscreteBoundary() && !algo->SupportSubmeshes()) { + TopoDS_Shape algoAssignedTo, otherAssignedTo; + gen->GetAlgo( *_father, _subShape, &algoAssignedTo ); map::reverse_iterator i_sm = _mapDepend.rbegin(); for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm ) - if ( gen->GetAlgo( *_father, i_sm->second->_subShape )) + if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) && + SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo )) ret = SMESH_Hypothesis::HYP_HIDING_ALGO; } } @@ -1000,10 +1034,10 @@ SMESH_Hypothesis::Hypothesis_Status if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK algo->SetEventListener( this ); - NotifyListenersOnEvent( event, ALGO_EVENT, anHyp ); + notifyListenersOnEvent( event, ALGO_EVENT, anHyp ); if ( stateChange && oldAlgoState == HYP_OK ) { // hyp becomes KO - DeleteOwnListeners(); + deleteOwnListeners(); SetIsAlwaysComputed( false ); if (_subShape.ShapeType() == TopAbs_VERTEX ) { // restore default states @@ -1012,6 +1046,13 @@ SMESH_Hypothesis::Hypothesis_Status } } + if ( needFullClean ) { + // added or removed algo is all-dimensional + ComputeStateEngine( CLEAN ); + cleanDependsOn(); + ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); + } + if (stateChange || modifiedHyp) ComputeStateEngine(MODIF_ALGO_STATE); @@ -1031,9 +1072,9 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo) // 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 + // check only algo that doesn't NeedDiscreteBoundary(): because mesh made // on a sub-shape will be ignored by theAlgo - if ( theAlgo->NeedDescretBoundary() || + if ( theAlgo->NeedDiscreteBoundary() || !theAlgo->OnlyUnaryInput() ) // all adjacent shapes will be meshed by this algo? return true; @@ -1062,7 +1103,7 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo) // check algo attached to smAdjacent SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent); if (algo && - !algo->NeedDescretBoundary() && + !algo->NeedDiscreteBoundary() && algo->OnlyUnaryInput()) return false; // NOT CONFORM MESH WILL BE PRODUCED } @@ -1077,7 +1118,7 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo) */ //============================================================================= -void SMESH_subMesh::SetAlgoState(int state) +void SMESH_subMesh::setAlgoState(int state) { _algoState = state; } @@ -1113,7 +1154,7 @@ SMESH_Hypothesis::Hypothesis_Status */ //============================================================================= -void SMESH_subMesh::CleanDependsOn() +void SMESH_subMesh::cleanDependsOn() { SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); while ( smIt->more() ) @@ -1128,48 +1169,48 @@ void SMESH_subMesh::CleanDependsOn() void SMESH_subMesh::DumpAlgoState(bool isMain) { - int dim = SMESH_Gen::GetShapeDim(_subShape); + int dim = SMESH_Gen::GetShapeDim(_subShape); // if (dim < 1) return; - if (isMain) - { - 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; - sm->DumpAlgoState(false); - } - } - int type = _subShape.ShapeType(); - MESSAGE("dim = " << dim << " type of shape " << type); - switch (_algoState) - { - case NO_ALGO: - MESSAGE(" AlgoState = NO_ALGO"); - break; - case MISSING_HYP: - MESSAGE(" AlgoState = MISSING_HYP"); - break; - case HYP_OK: - MESSAGE(" AlgoState = HYP_OK"); - break; - } - switch (_computeState) - { - case NOT_READY: - MESSAGE(" ComputeState = NOT_READY"); - break; - case READY_TO_COMPUTE: - MESSAGE(" ComputeState = READY_TO_COMPUTE"); - break; - case COMPUTE_OK: - MESSAGE(" ComputeState = COMPUTE_OK"); - break; - case FAILED_TO_COMPUTE: - MESSAGE(" ComputeState = FAILED_TO_COMPUTE"); - break; - } + if (isMain) + { + 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; + sm->DumpAlgoState(false); + } + } + int type = _subShape.ShapeType(); + MESSAGE("dim = " << dim << " type of shape " << type); + switch (_algoState) + { + case NO_ALGO: + MESSAGE(" AlgoState = NO_ALGO"); + break; + case MISSING_HYP: + MESSAGE(" AlgoState = MISSING_HYP"); + break; + case HYP_OK: + MESSAGE(" AlgoState = HYP_OK"); + break; + } + switch (_computeState) + { + case NOT_READY: + MESSAGE(" ComputeState = NOT_READY"); + break; + case READY_TO_COMPUTE: + MESSAGE(" ComputeState = READY_TO_COMPUTE"); + break; + case COMPUTE_OK: + MESSAGE(" ComputeState = COMPUTE_OK"); + break; + case FAILED_TO_COMPUTE: + MESSAGE(" ComputeState = FAILED_TO_COMPUTE"); + break; + } } //================================================================================ @@ -1225,7 +1266,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) SMESHDS_SubMesh* smDS = GetSubMeshDS(); if ( smDS && smDS->NbNodes() ) { if ( event == CLEAN ) { - CleanDependants(); + cleanDependants(); cleanSubMesh( this ); } else @@ -1240,7 +1281,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event) } } if ( event == MODIF_ALGO_STATE ) - CleanDependants(); + cleanDependants(); return true; } SMESH_Gen *gen = _father->GetGen(); @@ -1258,25 +1299,33 @@ bool SMESH_subMesh::ComputeStateEngine(int event) switch (event) { case MODIF_ALGO_STATE: - algo = gen->GetAlgo((*_father), _subShape); - if (algo && !algo->NeedDescretBoundary()) - CleanDependsOn(); // clean sub-meshes with event CLEAN + algo = GetAlgo(); + if (algo && !algo->NeedDiscreteBoundary()) + cleanDependsOn(); // clean sub-meshes with event CLEAN if ( _algoState == HYP_OK ) _computeState = READY_TO_COMPUTE; break; - case COMPUTE: // nothing to do + case COMPUTE: // nothing to do + break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: // nothing to do break; +#endif case CLEAN: - CleanDependants(); - RemoveSubMeshElementsAndNodes(); + cleanDependants(); + removeSubMeshElementsAndNodes(); break; - case SUBMESH_COMPUTED: // nothing to do + case SUBMESH_COMPUTED: // nothing to do break; case SUBMESH_RESTORED: ComputeSubMeshStateEngine( SUBMESH_RESTORED ); break; case MESH_ENTITY_REMOVED: break; + case SUBMESH_LOADED: + loadDependentMeshes(); + ComputeSubMeshStateEngine( SUBMESH_LOADED ); + //break; case CHECK_COMPUTE_STATE: if ( IsMeshComputed() ) _computeState = COMPUTE_OK; @@ -1294,25 +1343,25 @@ bool SMESH_subMesh::ComputeStateEngine(int event) { case MODIF_ALGO_STATE: _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo) { - if (!algo->NeedDescretBoundary()) - CleanDependsOn(); // clean sub-meshes with event CLEAN + if (!algo->NeedDiscreteBoundary()) + cleanDependsOn(); // clean sub-meshes with event CLEAN if ( _algoState == HYP_OK ) _computeState = READY_TO_COMPUTE; } break; case COMPUTE: { - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); ASSERT(algo); ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); if (!ret) { MESSAGE("***** verify compute state *****"); _computeState = NOT_READY; - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); break; } TopoDS_Shape shape = _subShape; @@ -1320,34 +1369,37 @@ bool SMESH_subMesh::ComputeStateEngine(int event) if (_father->HasShapeToMesh() ) { bool subComputed = false; if (!algo->OnlyUnaryInput()) - shape = GetCollection( gen, algo, subComputed ); + shape = getCollection( gen, algo, subComputed ); else - subComputed = SubMeshesComputed(); - ret = ( algo->NeedDescretBoundary() ? subComputed : + subComputed = subMeshesComputed(); + ret = ( algo->NeedDiscreteBoundary() ? subComputed : algo->SupportSubmeshes() ? true : ( !subComputed || _father->IsNotConformAllowed() )); if (!ret) { _computeState = FAILED_TO_COMPUTE; - if ( !algo->NeedDescretBoundary() ) + if ( !algo->NeedDiscreteBoundary() ) _computeError = SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH, "Unexpected computed submesh",algo); break; } } - // compute -// CleanDependants(); for "UseExisting_*D" algos -// RemoveSubMeshElementsAndNodes(); + // Compute + + //cleanDependants(); for "UseExisting_*D" algos + //removeSubMeshElementsAndNodes(); + loadDependentMeshes(); 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 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif algo->InitComputeError(); MemoryReserve aMemoryReserve; SMDS_Mesh::CheckMemory(); + Kernel_Utils::Localizer loc; if ( !_father->HasShapeToMesh() ) // no shape { SMESH_MesherHelper helper( *_father ); @@ -1362,6 +1414,11 @@ bool SMESH_subMesh::ComputeStateEngine(int event) if ( !_computeError || ( !ret && _computeError->IsOK() ) ) // algo can set _computeError of submesh _computeError = algo->GetComputeError(); } + catch ( ::SMESH_ComputeError& comperr ) { + cout << " SMESH_ComputeError caught" << endl; + if ( !_computeError ) _computeError = SMESH_ComputeError::New(); + *_computeError = comperr; + } catch ( std::bad_alloc& exc ) { MESSAGE("std::bad_alloc thrown inside algo->Compute()"); if ( _computeError ) { @@ -1405,38 +1462,53 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else ret = false; } - if (ret && !_alwaysComputed && shape == _subShape) { // check if anything was built - ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() )); + TopExp_Explorer subS(shape, _subShape.ShapeType()); + if (ret) // check if anything was built + { + for (; ret && subS.More(); subS.Next()) + ret = _father->GetSubMesh( subS.Current() )->IsMeshComputed(); } - bool isComputeErrorSet = !CheckComputeError( algo, shape ); + bool isComputeErrorSet = !checkComputeError( algo, shape ); if (!ret && !isComputeErrorSet) { // Set _computeError - if ( !_computeError ) - _computeError = SMESH_ComputeError::New(); - if ( _computeError->IsOK() ) - _computeError->myName = COMPERR_ALGO_FAILED; - _computeState = FAILED_TO_COMPUTE; + for (subS.ReInit(); subS.More(); subS.Next()) + { + SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() ); + if ( !sm->IsMeshComputed() ) + { + if ( !sm->_computeError ) + sm->_computeError = SMESH_ComputeError::New(); + if ( sm->_computeError->IsOK() ) + sm->_computeError->myName = COMPERR_ALGO_FAILED; + sm->_computeState = FAILED_TO_COMPUTE; + sm->_computeError->myAlgo = algo; + } + } } - if (ret) + if (ret && _computeError && _computeError->myName != COMPERR_WARNING ) { _computeError.reset(); } - UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED + updateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED } break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: // nothing to do + break; +#endif case CLEAN: - CleanDependants(); - RemoveSubMeshElementsAndNodes(); + cleanDependants(); + removeSubMeshElementsAndNodes(); _computeState = NOT_READY; - algo = gen->GetAlgo((*_father), _subShape); + algo = GetAlgo(); if (algo) { ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); if (ret) _computeState = READY_TO_COMPUTE; else - SetAlgoState(MISSING_HYP); + setAlgoState(MISSING_HYP); } break; case SUBMESH_COMPUTED: // nothing to do @@ -1446,11 +1518,15 @@ bool SMESH_subMesh::ComputeStateEngine(int event) // happen after retrieval from a file ComputeStateEngine( CHECK_COMPUTE_STATE ); ComputeSubMeshStateEngine( SUBMESH_RESTORED ); - algo = gen->GetAlgo(*_father, _subShape); + algo = GetAlgo(); if (algo) algo->SubmeshRestored( this ); break; case MESH_ENTITY_REMOVED: break; + case SUBMESH_LOADED: + loadDependentMeshes(); + ComputeSubMeshStateEngine( SUBMESH_LOADED ); + //break; case CHECK_COMPUTE_STATE: if ( IsMeshComputed() ) _computeState = COMPUTE_OK; @@ -1468,15 +1544,19 @@ bool SMESH_subMesh::ComputeStateEngine(int event) { case MODIF_ALGO_STATE: ComputeStateEngine( CLEAN ); - algo = gen->GetAlgo((*_father), _subShape); - if (algo && !algo->NeedDescretBoundary()) - CleanDependsOn(); // clean sub-meshes with event CLEAN + algo = GetAlgo(); + if (algo && !algo->NeedDiscreteBoundary()) + cleanDependsOn(); // clean sub-meshes with event CLEAN break; case COMPUTE: // nothing to do break; +#ifdef WITH_SMESH_CANCEL_COMPUTE + case COMPUTE_CANCELED: // nothing to do + break; +#endif case CLEAN: - CleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN - RemoveSubMeshElementsAndNodes(); + cleanDependants(); // clean sub-meshes, dependant on this one, with event CLEAN + removeSubMeshElementsAndNodes(); _computeState = NOT_READY; if ( _algoState == HYP_OK ) _computeState = READY_TO_COMPUTE; @@ -1486,20 +1566,24 @@ bool SMESH_subMesh::ComputeStateEngine(int event) case SUBMESH_RESTORED: ComputeStateEngine( CHECK_COMPUTE_STATE ); ComputeSubMeshStateEngine( SUBMESH_RESTORED ); - algo = gen->GetAlgo(*_father, _subShape); + algo = GetAlgo(); if (algo) algo->SubmeshRestored( this ); break; case MESH_ENTITY_REMOVED: - UpdateDependantsState( CHECK_COMPUTE_STATE ); - ComputeStateEngine( CHECK_COMPUTE_STATE ); + updateDependantsState ( CHECK_COMPUTE_STATE ); + ComputeStateEngine ( CHECK_COMPUTE_STATE ); ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE ); break; case CHECK_COMPUTE_STATE: - if ( !IsMeshComputed() ) + if ( !IsMeshComputed() ) { if (_algoState == HYP_OK) _computeState = READY_TO_COMPUTE; else _computeState = NOT_READY; + } + break; + case SUBMESH_LOADED: + // already treated event, thanks to which _computeState == COMPUTE_OK break; default: ASSERT(0); @@ -1513,9 +1597,11 @@ bool SMESH_subMesh::ComputeStateEngine(int event) switch (event) { case MODIF_ALGO_STATE: - algo = gen->GetAlgo((*_father), _subShape); - if (algo && !algo->NeedDescretBoundary()) - CleanDependsOn(); // clean sub-meshes with event CLEAN + if ( !IsEmpty() ) + ComputeStateEngine( CLEAN ); + algo = GetAlgo(); + if (algo && !algo->NeedDiscreteBoundary()) + cleanDependsOn(); // clean sub-meshes with event CLEAN if (_algoState == HYP_OK) _computeState = READY_TO_COMPUTE; else @@ -1523,9 +1609,15 @@ bool SMESH_subMesh::ComputeStateEngine(int event) break; case COMPUTE: // nothing to do break; + case COMPUTE_CANCELED: + { + algo = GetAlgo(); + algo->CancelCompute(); + } + break; case CLEAN: - CleanDependants(); // submeshes dependent on me should be cleaned as well - RemoveSubMeshElementsAndNodes(); + cleanDependants(); // submeshes dependent on me should be cleaned as well + removeSubMeshElementsAndNodes(); break; case SUBMESH_COMPUTED: // allow retry compute if (_algoState == HYP_OK) @@ -1547,6 +1639,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else _computeState = NOT_READY; break; + // case SUBMESH_LOADED: + // break; default: ASSERT(0); break; @@ -1559,11 +1653,68 @@ bool SMESH_subMesh::ComputeStateEngine(int event) break; } - NotifyListenersOnEvent( event, COMPUTE_EVENT ); + notifyListenersOnEvent( event, COMPUTE_EVENT ); + + return ret; +} + + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap) +{ + _computeError.reset(); + + bool ret = true; + + if (_subShape.ShapeType() == TopAbs_VERTEX) { + vector aVec(SMDSEntity_Last,0); + aVec[SMDSEntity_Node] = 1; + aResMap.insert(make_pair(this,aVec)); + return ret; + } + + //SMESH_Gen *gen = _father->GetGen(); + SMESH_Algo *algo = 0; + SMESH_Hypothesis::Hypothesis_Status hyp_status; + + algo = GetAlgo(); + if(algo && !aResMap.count(this) ) + { + ret = algo->CheckHypothesis((*_father), _subShape, hyp_status); + if (!ret) return false; + + if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary()) + { + // check submeshes needed + bool subMeshEvaluated = true; + int dimToCheck = SMESH_Gen::GetShapeDim( _subShape ) - 1; + SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,/*complexShapeFirst=*/true); + while ( smIt->more() && subMeshEvaluated ) + { + SMESH_subMesh* sm = smIt->next(); + int dim = SMESH_Gen::GetShapeDim( sm->GetSubShape() ); + if (dim < dimToCheck) break; // the rest subMeshes are all of less dimension + const vector & nbs = aResMap[ sm ]; + subMeshEvaluated = (std::accumulate( nbs.begin(), nbs.end(), 0 ) > 0 ); + } + if ( !subMeshEvaluated ) + return false; + } + _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo); + ret = algo->Evaluate((*_father), _subShape, aResMap); + + aResMap.insert( make_pair( this,vector(0))); + } return ret; } + //======================================================================= /*! * \brief Update compute_state by _computeError and send proper events to @@ -1572,18 +1723,18 @@ bool SMESH_subMesh::ComputeStateEngine(int event) */ //======================================================================= -bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape) +bool SMESH_subMesh::checkComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape) { bool noErrors = true; if ( !theShape.IsNull() ) { // Check state of submeshes - if ( !theAlgo->NeedDescretBoundary()) + if ( !theAlgo->NeedDiscreteBoundary()) { SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); while ( smIt->more() ) - if ( !smIt->next()->CheckComputeError( theAlgo )) + if ( !smIt->next()->checkComputeError( theAlgo )) noErrors = false; } @@ -1595,9 +1746,9 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t for (TopoDS_Iterator subIt( theShape ); subIt.More(); subIt.Next()) { SMESH_subMesh* sm = _father->GetSubMesh( subIt.Value() ); if ( sm != this ) { - if ( !sm->CheckComputeError( theAlgo, sm->GetSubShape() )) + if ( !sm->checkComputeError( theAlgo, sm->GetSubShape() )) noErrors = false; - UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED + updateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED } } } @@ -1606,7 +1757,8 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t // Check my state if ( !_computeError || _computeError->IsOK() ) { - _computeState = COMPUTE_OK; + // no error description is set to this sub-mesh, check if any mesh is computed + _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; } else { @@ -1615,7 +1767,7 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t // Show error SMESH_Comment text; - text << theAlgo->GetName() << " failed on subshape #" << _Id << " with error "; + text << theAlgo->GetName() << " failed on sub-shape #" << _Id << " with error "; if (_computeError->IsCommon() ) text << _computeError->CommonName(); else @@ -1623,73 +1775,22 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t if ( _computeError->myComment.size() > 0 ) text << " \"" << _computeError->myComment << "\""; -#ifdef _DEBUG_ - MESSAGE_BEGIN ( text ); - // Show vertices location of a failed shape - TopTools_IndexedMapOfShape vMap; - TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap ); - MESSAGE_ADD ( "Subshape vertices " << ( vMap.Extent()>10 ? "(first 10):" : ":") ); - for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) { - gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) ))); - MESSAGE_ADD ( "#" << _father->GetMeshDS()->ShapeToIndex( vMap( iv )) << " " - << P.X() << " " << P.Y() << " " << P.Z() << " " ); - } -#else INFOS( text ); -#endif - _computeState = FAILED_TO_COMPUTE; - noErrors = false; - } - } - return noErrors; -} - -//======================================================================= -//function : ApplyToCollection -//purpose : Apply theAlgo to all subshapes in theCollection -//======================================================================= - -bool SMESH_subMesh::ApplyToCollection (SMESH_Algo* theAlgo, - const TopoDS_Shape& theCollection) -{ - MESSAGE("SMESH_subMesh::ApplyToCollection"); - ASSERT ( !theAlgo->NeedDescretBoundary() ); - - if ( _computeError ) - _computeError->myName = COMPERR_OK; - bool ok = theAlgo->Compute( *_father, theCollection ); + _computeState = _computeError->IsKO() ? FAILED_TO_COMPUTE : COMPUTE_OK; - // set _computeState of subshapes - TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() ); - for ( ; anExplorer.More(); anExplorer.Next() ) - { - if ( SMESH_subMesh* subMesh = _father->GetSubMeshContaining( anExplorer.Current() )) - { - bool localOK = subMesh->CheckComputeError( theAlgo ); - if ( !ok && localOK && !subMesh->IsMeshComputed() ) - { - 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 ); + noErrors = false; } } - - return true; + return noErrors; } - //======================================================================= -//function : UpdateSubMeshState +//function : updateSubMeshState //purpose : //======================================================================= -void SMESH_subMesh::UpdateSubMeshState(const compute_state theState) +void SMESH_subMesh::updateSubMeshState(const compute_state theState) { SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); while ( smIt->more() ) @@ -1701,21 +1802,20 @@ void SMESH_subMesh::UpdateSubMeshState(const compute_state theState) //purpose : //======================================================================= -void SMESH_subMesh::ComputeSubMeshStateEngine(int event) +void SMESH_subMesh::ComputeSubMeshStateEngine(int event, const bool includeSelf) { - SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false); + SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(includeSelf,false); while ( smIt->more() ) smIt->next()->ComputeStateEngine(event); } //======================================================================= -//function : UpdateDependantsState +//function : updateDependantsState //purpose : //======================================================================= -void SMESH_subMesh::UpdateDependantsState(const compute_event theEvent) +void SMESH_subMesh::updateDependantsState(const compute_event theEvent) { - //MESSAGE("SMESH_subMesh::UpdateDependantsState"); TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape )); for (; it.More(); it.Next()) { @@ -1733,7 +1833,7 @@ void SMESH_subMesh::UpdateDependantsState(const compute_event theEvent) */ //============================================================================= -void SMESH_subMesh::CleanDependants() +void SMESH_subMesh::cleanDependants() { int dimToClean = SMESH_Gen::GetShapeDim( _subShape ) + 1; @@ -1746,7 +1846,8 @@ void SMESH_subMesh::CleanDependants() // will erase mesh on other shapes in a compound if ( ancestor.ShapeType() >= TopAbs_SOLID ) { SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor); - if (aSubMesh) + if (aSubMesh && + !aSubMesh->IsEmpty() ) // prevent infinite CLEAN via event lesteners aSubMesh->ComputeStateEngine(CLEAN); } } @@ -1759,10 +1860,8 @@ void SMESH_subMesh::CleanDependants() */ //============================================================================= -void SMESH_subMesh::RemoveSubMeshElementsAndNodes() +void SMESH_subMesh::removeSubMeshElementsAndNodes() { - //SCRUTE(_subShape.ShapeType()); - cleanSubMesh( this ); // algo may bind a submesh not to _subShape, eg 3D algo @@ -1783,18 +1882,16 @@ void SMESH_subMesh::RemoveSubMeshElementsAndNodes() } //======================================================================= -//function : GetCollection +//function : getCollection //purpose : return a shape containing all sub-shapes of the MainShape that can be // meshed at once along with _subShape //======================================================================= -TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, +TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo, bool & theSubComputed) { - MESSAGE("SMESH_subMesh::GetCollection"); - - theSubComputed = SubMeshesComputed(); + theSubComputed = subMeshesComputed(); TopoDS_Shape mainShape = _father->GetMeshDS()->ShapeToMesh(); @@ -1827,7 +1924,7 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps aBuilder.Add( aCompound, S ); - if ( !subMesh->SubMeshesComputed() ) + if ( !subMesh->subMeshesComputed() ) theSubComputed = false; } } @@ -1836,14 +1933,14 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, } //======================================================================= -//function : GetSimilarAttached +//function : getSimilarAttached //purpose : return a hypothesis attached to theShape. // If theHyp is provided, similar but not same hypotheses // is returned; else only applicable ones having theHypType // is returned //======================================================================= -const SMESH_Hypothesis* SMESH_subMesh::GetSimilarAttached(const TopoDS_Shape& theShape, +const SMESH_Hypothesis* SMESH_subMesh::getSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis * theHyp, const int theHypType) { @@ -1876,7 +1973,7 @@ SMESH_Hypothesis::Hypothesis_Status MESSAGE ("SMESH_subMesh::CheckConcurentHypothesis"); // is there local hypothesis on me? - if ( GetSimilarAttached( _subShape, 0, theHypType ) ) + if ( getSimilarAttached( _subShape, 0, theHypType ) ) return SMESH_Hypothesis::HYP_OK; @@ -1886,7 +1983,7 @@ SMESH_Hypothesis::Hypothesis_Status for (; it.More(); it.Next()) { const TopoDS_Shape& ancestor = it.Value(); - const SMESH_Hypothesis* hyp = GetSimilarAttached( ancestor, 0, theHypType ); + const SMESH_Hypothesis* hyp = getSimilarAttached( ancestor, 0, theHypType ); if ( hyp ) { if ( aPrevWithHyp.IsNull() || aPrevWithHyp.IsSame( ancestor )) @@ -1903,14 +2000,26 @@ SMESH_Hypothesis::Hypothesis_Status return SMESH_Hypothesis::HYP_OK; } +//================================================================================ +/*! + * \brief Constructor of OwnListenerData + */ +//================================================================================ + +SMESH_subMesh::OwnListenerData::OwnListenerData( SMESH_subMesh* sm, EventListener* el): + mySubMesh( sm ), + myMeshID( sm ? sm->GetFather()->GetId() : -1 ), + mySubMeshID( sm ? sm->GetId() : -1 ), + myListener( el ) +{ +} + //================================================================================ /*! * \brief Sets an event listener and its data to a submesh * \param listener - the listener to store * \param data - the listener data to store * \param where - the submesh to store the listener and it's data - * \param deleteListener - if true then the listener will be deleted as - * it is removed from where submesh * * It remembers the submesh where it puts the listener in order to delete * them when HYP_OK algo_state is lost @@ -1923,8 +2032,8 @@ void SMESH_subMesh::SetEventListener(EventListener* listener, SMESH_subMesh* where) { if ( listener && where ) { - where->SetEventListener( listener, data ); - myOwnListeners.push_back( make_pair( where, listener )); + where->setEventListener( listener, data ); + _ownListeners.push_back( OwnListenerData( where, listener )); } } @@ -1938,18 +2047,18 @@ void SMESH_subMesh::SetEventListener(EventListener* listener, */ //================================================================================ -void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData* data) +void SMESH_subMesh::setEventListener(EventListener* listener, EventListenerData* data) { map< EventListener*, EventListenerData* >::iterator l_d = - myEventListeners.find( listener ); - if ( l_d != myEventListeners.end() ) { + _eventListeners.find( listener ); + if ( l_d != _eventListeners.end() ) { EventListenerData* curData = l_d->second; if ( curData && curData != data && curData->IsDeletable() ) delete curData; l_d->second = data; } else - myEventListeners.insert( make_pair( listener, data )); + _eventListeners.insert( make_pair( listener, data )); } //================================================================================ @@ -1963,8 +2072,8 @@ void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData* EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) const { map< EventListener*, EventListenerData* >::const_iterator l_d = - myEventListeners.find( listener ); - if ( l_d != myEventListeners.end() ) + _eventListeners.find( listener ); + if ( l_d != _eventListeners.end() ) return l_d->second; return 0; } @@ -1974,19 +2083,27 @@ EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) * \brief Notify stored event listeners on the occured event * \param event - algo_event or compute_event itself * \param eventType - algo_event or compute_event - * \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 SMESH_subMesh::NotifyListenersOnEvent( const int event, +void SMESH_subMesh::notifyListenersOnEvent( const int event, const event_type eventType, SMESH_Hypothesis* hyp) { - map< EventListener*, EventListenerData* >::iterator l_d = myEventListeners.begin(); - for ( ; l_d != myEventListeners.end(); ++l_d ) - l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp ); + map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin(); + for ( ; l_d != _eventListeners.end(); ++l_d ) + { + std::pair< EventListener*, EventListenerData* > li_da = *l_d; /* copy to enable removal + of a listener from + _eventListeners by + its ProcessEvent() */ + if ( li_da.first->myBusySM.insert( this ).second ) + { + li_da.first->ProcessEvent( event, eventType, this, li_da.second, hyp ); + li_da.first->myBusySM.erase( this ); + } + } } //================================================================================ @@ -1999,11 +2116,11 @@ void SMESH_subMesh::NotifyListenersOnEvent( const int event, void SMESH_subMesh::DeleteEventListener(EventListener* listener) { map< EventListener*, EventListenerData* >::iterator l_d = - myEventListeners.find( listener ); - if ( l_d != myEventListeners.end() ) { + _eventListeners.find( listener ); + if ( l_d != _eventListeners.end() ) { 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 ); + _eventListeners.erase( l_d ); } } @@ -2013,12 +2130,42 @@ void SMESH_subMesh::DeleteEventListener(EventListener* listener) */ //================================================================================ -void SMESH_subMesh::DeleteOwnListeners() +void SMESH_subMesh::deleteOwnListeners() +{ + list< OwnListenerData >::iterator d; + for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d ) + { + if ( !_father->MeshExists( d->myMeshID )) + continue; + if ( _father->GetId() == d->myMeshID && !_father->GetSubMeshContaining( d->mySubMeshID )) + continue; + d->mySubMesh->DeleteEventListener( d->myListener ); + } + _ownListeners.clear(); +} + +//======================================================================= +//function : loadDependentMeshes +//purpose : loads dependent meshes on SUBMESH_LOADED event +//======================================================================= + +void SMESH_subMesh::loadDependentMeshes() { - list< pair< SMESH_subMesh*, EventListener* > >::iterator sm_l; - for ( sm_l = myOwnListeners.begin(); sm_l != myOwnListeners.end(); ++sm_l) - sm_l->first->DeleteEventListener( sm_l->second ); - myOwnListeners.clear(); + list< OwnListenerData >::iterator d; + for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d ) + if ( _father != d->mySubMesh->_father ) + d->mySubMesh->_father->Load(); + + // map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin(); + // for ( ; l_d != _eventListeners.end(); ++l_d ) + // if ( l_d->second ) + // { + // const list& smList = l_d->second->mySubMeshes; + // list::const_iterator sm = smList.begin(); + // for ( ; sm != smList.end(); ++sm ) + // if ( _father != (*sm)->_father ) + // (*sm)->_father->Load(); + // } } //================================================================================ @@ -2129,3 +2276,29 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS ( new _Iterator( new SMDS_mapIterator( DependsOn() ), prepend, append )); } } + +//================================================================================ +/*! + * \brief Find common submeshes (based on shared sub-shapes with other + * \param theOther submesh to check + * \param theSetOfCommon set of common submesh + */ +//================================================================================ + +bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther, + std::set& theSetOfCommon ) const +{ + int oldNb = theSetOfCommon.size(); + // check main submeshes + const map ::const_iterator otherEnd = theOther->_mapDepend.end(); + if ( theOther->_mapDepend.find(this->GetId()) != otherEnd ) + theSetOfCommon.insert( this ); + if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() ) + theSetOfCommon.insert( theOther ); + // check common submeshes + map ::const_iterator mapIt = _mapDepend.begin(); + for( ; mapIt != _mapDepend.end(); mapIt++ ) + if ( theOther->_mapDepend.find((*mapIt).first) != otherEnd ) + theSetOfCommon.insert( (*mapIt).second ); + return oldNb < theSetOfCommon.size(); +} diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index ace3a346f..ee4b96658 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : SMESH_subMesh.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_SUBMESH_HXX_ #define _SMESH_SUBMESH_HXX_ @@ -34,6 +33,7 @@ #include "SMESHDS_SubMesh.hxx" #include "SMESH_Hypothesis.hxx" #include "SMESH_ComputeError.hxx" +#include "SMESH_Algo.hxx" #include "Utils_SALOME_Exception.hxx" @@ -60,7 +60,7 @@ class SMESH_EXPORT SMESH_subMesh { public: SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS, - const TopoDS_Shape & aSubShape); + const TopoDS_Shape & aSubShape); virtual ~ SMESH_subMesh(); int GetId() const; @@ -74,8 +74,9 @@ class SMESH_EXPORT SMESH_subMesh SMESH_subMesh *GetFirstToCompute(); + SMESH_Algo* GetAlgo() const; + const std::map < int, SMESH_subMesh * >& DependsOn(); - //const map < int, SMESH_subMesh * >&Dependants(); /*! * \brief Return iterator on the submeshes this one depends on */ @@ -88,11 +89,11 @@ class SMESH_EXPORT SMESH_subMesh { NOT_READY, READY_TO_COMPUTE, COMPUTE_OK, FAILED_TO_COMPUTE - }; + }; enum algo_state { NO_ALGO, MISSING_HYP, HYP_OK - }; + }; enum algo_event { ADD_HYP , ADD_ALGO, @@ -100,13 +101,13 @@ class SMESH_EXPORT SMESH_subMesh ADD_FATHER_HYP , ADD_FATHER_ALGO, REMOVE_FATHER_HYP, REMOVE_FATHER_ALGO, MODIF_HYP - }; + }; enum compute_event { - MODIF_ALGO_STATE, COMPUTE, - CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED, + MODIF_ALGO_STATE, COMPUTE, COMPUTE_CANCELED, + CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED, SUBMESH_LOADED, MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE - }; + }; enum event_type { ALGO_EVENT, COMPUTE_EVENT @@ -123,7 +124,7 @@ class SMESH_EXPORT SMESH_subMesh * \param where - the submesh to store the listener and it's data * * The method remembers the submesh \awhere it puts the listener in order to delete - * them when HYP_OK algo_state is lost + * it when HYP_OK algo_state is lost * After being set, event listener is notified on each event of \awhere submesh. */ void SetEventListener(EventListener* listener, @@ -146,9 +147,17 @@ class SMESH_EXPORT SMESH_subMesh protected: //!< event listeners to notify - std::map< EventListener*, EventListenerData* > myEventListeners; + std::map< EventListener*, EventListenerData* > _eventListeners; + //!< event listeners to delete when HYP_OK algo_state is lost - std::list< std::pair< SMESH_subMesh*, EventListener* > > myOwnListeners; + struct OwnListenerData { + SMESH_subMesh* mySubMesh; + int myMeshID; // id of mySubMesh->GetFather() + int mySubMeshID; + EventListener* myListener; + OwnListenerData( SMESH_subMesh* sm=0, EventListener* el=0); + }; + std::list< OwnListenerData > _ownListeners; /*! * \brief Sets an event listener and its data to a submesh @@ -157,7 +166,7 @@ protected: * * After being set, event listener is notified on each event of a submesh. */ - void SetEventListener(EventListener* listener, EventListenerData* data); + void setEventListener(EventListener* listener, EventListenerData* data); /*! * \brief Notify stored event listeners on the occured event @@ -165,16 +174,22 @@ protected: * \param eventType - algo_event or compute_event * \param hyp - hypothesis, if eventType is algo_event */ - void NotifyListenersOnEvent( const int event, + void notifyListenersOnEvent( const int event, const event_type eventType, SMESH_Hypothesis* hyp = 0); /*! * \brief Delete event listeners depending on algo of this submesh */ - void DeleteOwnListeners(); + void deleteOwnListeners(); - // ================================================================== + /*! + * \brief loads dependent meshes on SUBMESH_LOADED event + */ + void loadDependentMeshes(); + + // END: Members to track non hierarchical dependencies between submeshes + // ===================================================================== public: @@ -191,6 +206,9 @@ public: void DumpAlgoState(bool isMain); bool ComputeStateEngine(int event); + void ComputeSubMeshStateEngine(int event, const bool includeSelf=false); + + bool Evaluate(MapShapeNbElems& aResMap); bool IsConform(const SMESH_Algo* theAlgo); // check if a conform mesh will be produced by the Algo @@ -223,43 +241,44 @@ public: * none mesh entity is bound to it */ void SetIsAlwaysComputed(bool isAlCo); + bool IsAlwaysComputed() { return _alwaysComputed; } + + /*! + * \brief Find common submeshes (based on shared subshapes with other + * \param theOther submesh to check + * \param theCommonIds set of common submesh IDs + * NOTE: this method does not cleat set before collect common IDs + */ + bool FindIntersection( const SMESH_subMesh * theOther, + std::set& theSetOfCommon ) const; protected: // ================================================================== - void InsertDependence(const TopoDS_Shape aSubShape); + void insertDependence(const TopoDS_Shape aSubShape); - bool SubMeshesComputed(); + bool subMeshesComputed(); + //bool SubMeshesReady(); - bool SubMeshesReady(); - - void RemoveSubMeshElementsAndNodes(); - void UpdateDependantsState(const compute_event theEvent); - void UpdateSubMeshState(const compute_state theState); - void ComputeSubMeshStateEngine(int event); - void CleanDependants(); - void CleanDependsOn(); - void SetAlgoState(int state); + void removeSubMeshElementsAndNodes(); + void updateDependantsState(const compute_event theEvent); + void updateSubMeshState(const compute_state theState); + void cleanDependants(); + 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, + TopoDS_Shape getCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo, bool & theSubComputed); - - /*! - * \brief Apply theAlgo to all subshapes in theCollection - */ - bool ApplyToCollection (SMESH_Algo* theAlgo, - const TopoDS_Shape& theCollection); - /*! * \brief Update compute_state by _computeError * \retval bool - false if there are errors */ - bool CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape=TopoDS_Shape()); + bool checkComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape=TopoDS_Shape()); /*! * \brief Return a hypothesis attached to theShape. @@ -268,7 +287,7 @@ protected: * is returned; else an applicable ones having theHypType * is returned */ - const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape& theShape, + const SMESH_Hypothesis* getSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis * theHyp, const int theHypType = 0); // diff --git a/src/SMESH/SMESH_subMeshEventListener.hxx b/src/SMESH/SMESH_subMeshEventListener.hxx index 51a79a9c2..ae911cfef 100644 --- a/src/SMESH/SMESH_subMeshEventListener.hxx +++ b/src/SMESH/SMESH_subMeshEventListener.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions -// File : SMESH_subMeshEventListener.hxx -// Created : Mon Nov 13 10:45:49 2006 -// Author : Edward AGAPOV (eap) + +// File : SMESH_subMeshEventListener.hxx +// Created : Mon Nov 13 10:45:49 2006 +// Author : Edward AGAPOV (eap) // #ifndef SMESH_subMeshEventListener_HeaderFile #define SMESH_subMeshEventListener_HeaderFile @@ -30,6 +30,7 @@ #include "SMESH_SMESH.hxx" #include +#include class SMESH_subMesh; class SMESH_Hypothesis; @@ -41,10 +42,21 @@ struct SMESH_subMeshEventListenerData; */ // ------------------------------------------------------------------ -class SMESH_EXPORT SMESH_subMeshEventListener { +class SMESH_EXPORT SMESH_subMeshEventListener +{ bool myIsDeletable; //!< if true, it will be deleted by SMESH_subMesh -public: - SMESH_subMeshEventListener(bool isDeletable):myIsDeletable(isDeletable) {} + mutable std::set myBusySM; //!< to avoid infinite recursion via events + friend class SMESH_subMesh; +#ifdef _DEBUG_ + const char* myName; //!< identifier used for debug +#endif + + public: + SMESH_subMeshEventListener(bool isDeletable, const char* name) :myIsDeletable(isDeletable) +#ifdef _DEBUG_ + ,myName(name) +#endif + {} bool IsDeletable() const { return myIsDeletable; } /*! * \brief Do something on a certain event @@ -54,9 +66,9 @@ public: * \param data - listener data stored in the subMesh * \param hyp - hypothesis, if eventType is algo_event * - * The base implementation translates CLEAN event to the subMesh stored - * in the listener data. Also it sends SUBMESH_COMPUTED event in case of - * successful COMPUTE event. + * The base implementation (see SMESH_subMesh.cxx) translates CLEAN event + * to the subMeshes stored in the listener data. Also it sends SUBMESH_COMPUTED + * event in case of successful COMPUTE event. */ virtual void ProcessEvent(const int event, const int eventType, @@ -75,10 +87,13 @@ struct SMESH_subMeshEventListenerData { bool myIsDeletable; //!< if true, it will be deleted by SMESH_subMesh int myType; //!< to recognize data type - std::list mySubMeshes; //!< generally: submeshes depending - // on the one storing this data + std::list mySubMeshes; /* generally: submeshes depending + on the one storing this data; + !! they are used to track intermesh + dependencies at mesh loading as well !! */ public: SMESH_subMeshEventListenerData(bool isDeletable):myIsDeletable(isDeletable) {} + virtual ~SMESH_subMeshEventListenerData() {} bool IsDeletable() const { return myIsDeletable; } /*! diff --git a/src/SMESH/memoire.h b/src/SMESH/memoire.h new file mode 100644 index 000000000..258eda28b --- /dev/null +++ b/src/SMESH/memoire.h @@ -0,0 +1,43 @@ +// Copyright (C) 2010-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _MEMOIRE_H_ +#define _MEMOIRE_H_ + +#include +#include + +void memostat(const char* f, int l); + +void memostat(const char* f, int l) +{ +#ifdef WIN32 + //rnv: TODO: find alternative of the malloc_stats() on windows platform +#else + /* struct mallinfo mem = mallinfo(); */ + /* std::cerr << f << ":"<< l << " " << mem.arena << " " << mem.ordblks << " " << mem.hblks << " " << mem.hblkhd << " " << mem.uordblks << " " << mem.fordblks << " " << mem.keepcost << std::endl; */ + std::cerr << f << ":" << l << " --------------------------" << std::endl; + malloc_stats(); + std::cerr << f << ":" << l << " --------------------------" << std::endl; +#endif +} + +#define MEMOSTAT //memostat( __FILE__, __LINE__ ) + +#endif diff --git a/src/SMESHClient/Makefile.am b/src/SMESHClient/Makefile.am index ebb0d97f7..86fd92dc0 100644 --- a/src/SMESHClient/Makefile.am +++ b/src/SMESHClient/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # GEOM GEOMClient : tool to transfer BREP files from GEOM server to GEOM client # File : Makefile.in # Author : Pavel TELKOV (OCC) @@ -47,6 +45,7 @@ libSMESHClient_la_CPPFLAGS = \ $(MED_CXXFLAGS) \ $(GEOM_CXXFLAGS) \ $(BOOST_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(CAS_CPPFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ @@ -59,8 +58,7 @@ libSMESHClient_la_CPPFLAGS = \ -I$(srcdir)/../SMDS \ -I$(srcdir)/../SMESHDS \ -I$(srcdir)/../SMESH \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix + -I$(top_builddir)/idl libSMESHClient_la_LDFLAGS = \ ../../idl/libSalomeIDLSMESH.la \ @@ -68,15 +66,16 @@ libSMESHClient_la_LDFLAGS = \ ../SMESH/libSMESHimpl.la \ ../SMESHDS/libSMESHDS.la \ ../Controls/libSMESHControls.la \ - $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA \ - $(GEOM_LDFLAGS) -lNMTDS \ - $(MED_LDFLAGS) -lMEDWrapper_V2_2 -lMEDWrapper_V2_1 \ + $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeNS -lOpUtil -lSALOMEBasics \ + -lSalomeIDLKernel -lSALOMELocalTrace \ + $(GEOM_LDFLAGS) -lNMTDS -lSalomeIDLGEOM \ + $(MED_LDFLAGS) -lMEDWrapper_V2_2 -lMEDWrapper_V2_1 -lSalomeIDLMED -lMEDWrapper \ $(CAS_KERNEL) SMESHClientBin_CPPFLAGS = \ $(libSMESHClient_la_CPPFLAGS) SMESHClientBin_LDADD = \ - $(libSMESHClient_la_LDFLAGS) + $(libSMESHClient_la_LDFLAGS) @CORBA_LIBS@ diff --git a/src/SMESHClient/SMESHClientBin.cxx b/src/SMESHClient/SMESHClientBin.cxx index df47e31f1..3183818ff 100644 --- a/src/SMESHClient/SMESHClientBin.cxx +++ b/src/SMESHClient/SMESHClientBin.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : // Author : // Module : diff --git a/src/SMESHClient/SMESH_Client.cxx b/src/SMESHClient/SMESH_Client.cxx index af83fe041..f7195b89e 100644 --- a/src/SMESHClient/SMESH_Client.cxx +++ b/src/SMESHClient/SMESH_Client.cxx @@ -1,31 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESHClient : tool to update client mesh structure by mesh from server // File : SMESH_Client.cxx // Author : Pavel TELKOV // Module : SMESH -// + #include "SMESH_Client.hxx" #include "SMESH_Mesh.hxx" +#include "SMESHDS_Script.hxx" #include "SALOME_NamingService.hxx" #include "SALOME_LifeCycleCORBA.hxx" @@ -54,7 +54,7 @@ #endif #ifdef _DEBUG_ -static int MYDEBUG = 0; +static int MYDEBUG = 1; #else static int MYDEBUG = 0; #endif @@ -83,9 +83,9 @@ namespace //======================================================================= //function : AddNodesWithID //======================================================================= - inline void AddNodesWithID(SMDS_Mesh* theMesh, - SMESH::log_array_var& theSeq, - CORBA::Long theId) + inline void AddNodesWithID(SMDS_Mesh* theMesh, + SMESH::log_array_var& theSeq, + CORBA::Long theId) { const SMESH::double_array& aCoords = theSeq[theId].coords; const SMESH::long_array& anIndexes = theSeq[theId].indexes; @@ -94,11 +94,59 @@ namespace EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()"); for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){ SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId], - aCoords[aCoordId+1], - aCoords[aCoordId+2], - anIndexes[anElemId]); + aCoords[aCoordId+1], + aCoords[aCoordId+2], + anIndexes[anElemId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<Add0DElementWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId]); + if (!anElem) + EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot Add0DElementWithID for ID = "<AddBallWithID(anIndexes[anIndexId+1], + aDiameter[anElemId], + anIndexes[anIndexId]); + if (!anElem) + EXCEPTION(runtime_error,"cannot SMDS_Mesh::AddBallsWithID for ID = "<AddEdgeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId+7], - anIndexes[anIndexId+8], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"AddHexPrismWithID - cannot AddVolumeWithID for ID = "<AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId); if (!anElem) - EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = " + EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = " << anElemId); } } @@ -332,7 +410,7 @@ namespace //======================================================================= //function : AddQuadEdgesWithID //======================================================================= - inline void AddQuadEdgesWithID(SMDS_Mesh* theMesh, + inline void AddQuadEdgesWithID(SMDS_Mesh* theMesh, SMESH::log_array_var& theSeq, CORBA::Long theId) { @@ -342,11 +420,11 @@ namespace EXCEPTION(runtime_error,"AddQuadEdgeWithID - 4*aNbElems != aCoords.length()"); for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){ SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId+7], - anIndexes[anIndexId+8], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<AddFaceWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"AddBiQuadQuadsWithID() - cannot AddFaceWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId+7], - anIndexes[anIndexId+8], - anIndexes[anIndexId+9], - anIndexes[anIndexId+10], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId+7], - anIndexes[anIndexId+8], - anIndexes[anIndexId+9], - anIndexes[anIndexId+10], - anIndexes[anIndexId+11], - anIndexes[anIndexId+12], - anIndexes[anIndexId+13], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId+13], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId+7], - anIndexes[anIndexId+8], - anIndexes[anIndexId+9], - anIndexes[anIndexId+10], - anIndexes[anIndexId+11], - anIndexes[anIndexId+12], - anIndexes[anIndexId+13], - anIndexes[anIndexId+14], - anIndexes[anIndexId+15], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId+13], + anIndexes[anIndexId+14], + anIndexes[anIndexId+15], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], - anIndexes[anIndexId+2], - anIndexes[anIndexId+3], - anIndexes[anIndexId+4], - anIndexes[anIndexId+5], - anIndexes[anIndexId+6], - anIndexes[anIndexId+7], - anIndexes[anIndexId+8], - anIndexes[anIndexId+9], - anIndexes[anIndexId+10], - anIndexes[anIndexId+11], - anIndexes[anIndexId+12], - anIndexes[anIndexId+13], - anIndexes[anIndexId+14], - anIndexes[anIndexId+15], - anIndexes[anIndexId+16], - anIndexes[anIndexId+17], - anIndexes[anIndexId+18], - anIndexes[anIndexId+19], - anIndexes[anIndexId+20], - anIndexes[anIndexId]); + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId+13], + anIndexes[anIndexId+14], + anIndexes[anIndexId+15], + anIndexes[anIndexId+16], + anIndexes[anIndexId+17], + anIndexes[anIndexId+18], + anIndexes[anIndexId+19], + anIndexes[anIndexId+20], + anIndexes[anIndexId]); if(!anElem) - EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<AddVolumeWithID(anIndexes[anIndexId+1], + anIndexes[anIndexId+2], + anIndexes[anIndexId+3], + anIndexes[anIndexId+4], + anIndexes[anIndexId+5], + anIndexes[anIndexId+6], + anIndexes[anIndexId+7], + anIndexes[anIndexId+8], + anIndexes[anIndexId+9], + anIndexes[anIndexId+10], + anIndexes[anIndexId+11], + anIndexes[anIndexId+12], + anIndexes[anIndexId+13], + anIndexes[anIndexId+14], + anIndexes[anIndexId+15], + anIndexes[anIndexId+16], + anIndexes[anIndexId+17], + anIndexes[anIndexId+18], + anIndexes[anIndexId+19], + anIndexes[anIndexId+20], + anIndexes[anIndexId+21], + anIndexes[anIndexId+22], + anIndexes[anIndexId+23], + anIndexes[anIndexId+24], + anIndexes[anIndexId+25], + anIndexes[anIndexId+26], + anIndexes[anIndexId+27], + anIndexes[anIndexId]); + if(!anElem) + EXCEPTION(runtime_error,"AddTriQuadHexasWithID() - cannot AddVolumeWithID for ID = "<GetContainerRef(); CORBA::String_var aServerHostName = aServerContainer->getHostName(); @@ -604,14 +754,15 @@ SMESH_Client::GetSMESHGen(CORBA::ORB_ptr theORB, //======================================================================= // function : Create() -// purpose : +// purpose : //======================================================================= SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB, - SMESH::SMESH_Mesh_ptr theMesh): + SMESH::SMESH_Mesh_ptr theMesh): myMeshServer(SMESH::SMESH_Mesh::_duplicate(theMesh)), mySMESHDSMesh(NULL), mySMDSMesh(NULL) { + MESSAGE("SMESH_Client::SMESH_Client"); myMeshServer->Register(); CORBA::Boolean anIsEmbeddedMode; @@ -627,7 +778,8 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB, SMESH_Mesh* aMesh = reinterpret_cast (pointeur); if ( MYDEBUG ) MESSAGE("SMESH_Client::SMESH_Client aMesh "<GetMeshDS()->IsEmbeddedMode()){ + //if(aMesh->GetMeshDS()->IsEmbeddedMode()){ + if(anIsEmbeddedMode){ mySMESHDSMesh = aMesh->GetMeshDS(); mySMDSMesh = mySMESHDSMesh; } @@ -643,17 +795,17 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB, //================================================================================= SMESH_Client::~SMESH_Client() { - myMeshServer->Destroy(); + myMeshServer->UnRegister(); if(!mySMESHDSMesh) delete mySMDSMesh; } //================================================================================= -SMDS_Mesh* -SMESH_Client::GetMesh() const +SMDS_Mesh* +SMESH_Client::GetMesh() const { - return mySMDSMesh; + return mySMDSMesh; } @@ -669,7 +821,7 @@ SMESH_Client::operator->() const SMESH::SMESH_Mesh_ptr SMESH_Client::GetMeshServer() { - return myMeshServer.in(); + return myMeshServer.in(); } @@ -682,16 +834,18 @@ SMESH_Client::Update(bool theIsClear) { bool anIsModified = true; if(mySMESHDSMesh){ + MESSAGE("Update mySMESHDSMesh"); SMESHDS_Script* aScript = mySMESHDSMesh->GetScript(); anIsModified = aScript->IsModified(); aScript->SetModified(false); }else{ + MESSAGE("Update CORBA"); SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear ); CORBA::Long aLength = aSeq->length(); anIsModified = aLength > 0; if( MYDEBUG ) MESSAGE( "Update: length of the script is "<Clear(); @@ -734,7 +893,7 @@ SMESH_Client::Update(bool theIsClear) for( ; anElemId < aNbElems; anElemId++ ) mySMDSMesh->RemoveNode( FindNode( mySMDSMesh, anIndexes[anElemId] ) ); break; - + case SMESH::REMOVE_ELEMENT: for( ; anElemId < aNbElems; anElemId++ ) mySMDSMesh->RemoveElement( FindElement( mySMDSMesh, anIndexes[anElemId] ) ); @@ -775,9 +934,9 @@ SMESH_Client::Update(bool theIsClear) mySMDSMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] ); } break; - + default:; - } + } } } catch ( SALOME::SALOME_Exception& exc ) @@ -796,11 +955,12 @@ SMESH_Client::Update(bool theIsClear) if ( MYDEBUG && mySMDSMesh ) { MESSAGE("Update - mySMDSMesh->NbNodes() = "<NbNodes()); + MESSAGE("Update - mySMDSMesh->Nb0DElements() = "<Nb0DElements()); MESSAGE("Update - mySMDSMesh->NbEdges() = "<NbEdges()); MESSAGE("Update - mySMDSMesh->NbFaces() = "<NbFaces()); MESSAGE("Update - mySMDSMesh->NbVolumes() = "<NbVolumes()); } } // end of update mesh by log script - + return anIsModified; } diff --git a/src/SMESHClient/SMESH_Client.hxx b/src/SMESHClient/SMESH_Client.hxx index 99e3de4b8..65c111c2e 100644 --- a/src/SMESHClient/SMESH_Client.hxx +++ b/src/SMESHClient/SMESH_Client.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHClient : tool to update client mesh structure by mesh from server // File : SMESH_Client.hxx // Author : Pavel TELKOV @@ -32,7 +33,7 @@ #include CORBA_SERVER_HEADER(SMESH_Mesh) #ifdef WNT -# ifdef SMESHCLIENT_EXPORTS +# if defined SMESHCLIENT_EXPORTS || defined SMESHClient_EXPORTS # define SMESHCLIENT_EXPORT __declspec( dllexport ) # else # define SMESHCLIENT_EXPORT __declspec( dllimport ) @@ -54,10 +55,10 @@ public: static SMESH::SMESH_Gen_var GetSMESHGen(CORBA::ORB_ptr theORB, - CORBA::Boolean& theIsEmbeddedMode); + CORBA::Boolean& theIsEmbeddedMode); SMESH_Client(CORBA::ORB_ptr theORB, - SMESH::SMESH_Mesh_ptr theMesh); + SMESH::SMESH_Mesh_ptr theMesh); ~SMESH_Client(); bool diff --git a/src/SMESHDS/Makefile.am b/src/SMESHDS/Makefile.am index b9c3673f3..745ccca8f 100644 --- a/src/SMESHDS/Makefile.am +++ b/src/SMESHDS/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESHDS : management of mesh data and SMESH document # File : Makefile.in # Author : Patrick GOLDBRONN (CEA) @@ -39,8 +37,10 @@ salomeinclude_HEADERS = \ SMESHDS_GroupBase.hxx \ SMESHDS_Group.hxx \ SMESHDS_GroupOnGeom.hxx \ + SMESHDS_GroupOnFilter.hxx \ SMESH_SMESHDS.hxx \ - SMESHDS_DataMapOfShape.hxx + SMESHDS_DataMapOfShape.hxx \ + SMESH_Controls.hxx # Libraries targets lib_LTLIBRARIES = libSMESHDS.la @@ -54,12 +54,14 @@ dist_libSMESHDS_la_SOURCES = \ SMESHDS_Mesh.cxx \ SMESHDS_GroupBase.cxx \ SMESHDS_Group.cxx \ - SMESHDS_GroupOnGeom.cxx + SMESHDS_GroupOnGeom.cxx \ + SMESHDS_GroupOnFilter.cxx # additionnal information to compil and link file libSMESHDS_la_CPPFLAGS = \ $(KERNEL_CXXFLAGS) \ $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ -I$(srcdir)/../SMDS diff --git a/src/SMESHDS/SMESHDS_Command.cxx b/src/SMESHDS/SMESHDS_Command.cxx index be0e5e632..658ad24ae 100644 --- a/src/SMESHDS/SMESHDS_Command.cxx +++ b/src/SMESHDS/SMESHDS_Command.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESH_Command.cxx // Author : Yves FRICAUD, OCC // Module : SMESH -// $Header: // #include "SMESHDS_Command.hxx" @@ -54,16 +54,16 @@ SMESHDS_Command::~SMESHDS_Command() //======================================================================= void SMESHDS_Command::AddNode(int NewNodeID, double x, double y, double z) { - if (!myType == SMESHDS_AddNode) - { - MESSAGE("SMESHDS_Command::AddNode : Bad Type"); - return; - } - myIntegers.push_back(NewNodeID); - myReals.push_back(x); - myReals.push_back(y); - myReals.push_back(z); - myNumber++; + if (!myType == SMESHDS_AddNode) + { + MESSAGE("SMESHDS_Command::AddNode : Bad Type"); + return; + } + myIntegers.push_back(NewNodeID); + myReals.push_back(x); + myReals.push_back(y); + myReals.push_back(z); + myNumber++; } //======================================================================= @@ -72,16 +72,32 @@ void SMESHDS_Command::AddNode(int NewNodeID, double x, double y, double z) //======================================================================= void SMESHDS_Command::MoveNode(int NodeID, double x, double y, double z) { - if (!myType == SMESHDS_MoveNode) - { - MESSAGE("SMESHDS_Command::MoveNode : Bad Type"); - return; - } - myIntegers.push_back(NodeID); - myReals.push_back(x); - myReals.push_back(y); - myReals.push_back(z); - myNumber++; + if (!myType == SMESHDS_MoveNode) + { + MESSAGE("SMESHDS_Command::MoveNode : Bad Type"); + return; + } + myIntegers.push_back(NodeID); + myReals.push_back(x); + myReals.push_back(y); + myReals.push_back(z); + myNumber++; +} + +//======================================================================= +//function : +//purpose : +//======================================================================= +void SMESHDS_Command::Add0DElement(int New0DElementID, int idnode) +{ + if (!myType == SMESHDS_Add0DElement) + { + MESSAGE("SMESHDS_Command::Add0DElement : Bad Type"); + return; + } + myIntegers.push_back(New0DElementID); + myIntegers.push_back(idnode); + myNumber++; } //======================================================================= @@ -90,15 +106,15 @@ void SMESHDS_Command::MoveNode(int NodeID, double x, double y, double z) //======================================================================= void SMESHDS_Command::AddEdge(int NewEdgeID, int idnode1, int idnode2) { - if (!myType == SMESHDS_AddEdge) - { - MESSAGE("SMESHDS_Command::AddEdge : Bad Type"); - return; - } - myIntegers.push_back(NewEdgeID); - myIntegers.push_back(idnode1); - myIntegers.push_back(idnode2); - myNumber++; + if (!myType == SMESHDS_AddEdge) + { + MESSAGE("SMESHDS_Command::AddEdge : Bad Type"); + return; + } + myIntegers.push_back(NewEdgeID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myNumber++; } //======================================================================= @@ -106,18 +122,18 @@ void SMESHDS_Command::AddEdge(int NewEdgeID, int idnode1, int idnode2) //purpose : //======================================================================= void SMESHDS_Command::AddFace(int NewFaceID, - int idnode1, int idnode2, int idnode3) + int idnode1, int idnode2, int idnode3) { - if (!myType == SMESHDS_AddTriangle) - { - MESSAGE("SMESHDS_Command::AddFace : Bad Type"); - return; - } - myIntegers.push_back(NewFaceID); - myIntegers.push_back(idnode1); - myIntegers.push_back(idnode2); - myIntegers.push_back(idnode3); - myNumber++; + if (!myType == SMESHDS_AddTriangle) + { + MESSAGE("SMESHDS_Command::AddFace : Bad Type"); + return; + } + myIntegers.push_back(NewFaceID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myIntegers.push_back(idnode3); + myNumber++; } //======================================================================= @@ -125,19 +141,19 @@ void SMESHDS_Command::AddFace(int NewFaceID, //purpose : //======================================================================= void SMESHDS_Command::AddFace(int NewFaceID, - int idnode1, int idnode2, int idnode3, int idnode4) + int idnode1, int idnode2, int idnode3, int idnode4) { - if (!myType == SMESHDS_AddQuadrangle) - { - MESSAGE("SMESHDS_Command::AddFace : Bad Type"); - return; - } - myIntegers.push_back(NewFaceID); - myIntegers.push_back(idnode1); - myIntegers.push_back(idnode2); - myIntegers.push_back(idnode3); - myIntegers.push_back(idnode4); - myNumber++; + if (!myType == SMESHDS_AddQuadrangle) + { + MESSAGE("SMESHDS_Command::AddFace : Bad Type"); + return; + } + myIntegers.push_back(NewFaceID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myIntegers.push_back(idnode3); + myIntegers.push_back(idnode4); + myNumber++; } //======================================================================= @@ -145,19 +161,19 @@ void SMESHDS_Command::AddFace(int NewFaceID, //purpose : //======================================================================= void SMESHDS_Command::AddVolume(int NewVolID, - int idnode1, int idnode2, int idnode3, int idnode4) + int idnode1, int idnode2, int idnode3, int idnode4) { - if (!myType == SMESHDS_AddTetrahedron) - { - MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); - return; - } - myIntegers.push_back(NewVolID); - myIntegers.push_back(idnode1); - myIntegers.push_back(idnode2); - myIntegers.push_back(idnode3); - myIntegers.push_back(idnode4); - myNumber++; + if (!myType == SMESHDS_AddTetrahedron) + { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myIntegers.push_back(idnode3); + myIntegers.push_back(idnode4); + myNumber++; } //======================================================================= @@ -165,20 +181,20 @@ void SMESHDS_Command::AddVolume(int NewVolID, //purpose : //======================================================================= void SMESHDS_Command::AddVolume(int NewVolID, - int idnode1, int idnode2, int idnode3, int idnode4, int idnode5) + int idnode1, int idnode2, int idnode3, int idnode4, int idnode5) { - if (!myType == SMESHDS_AddPyramid) - { - MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); - return; - } - myIntegers.push_back(NewVolID); - myIntegers.push_back(idnode1); - myIntegers.push_back(idnode2); - myIntegers.push_back(idnode3); - myIntegers.push_back(idnode4); - myIntegers.push_back(idnode5); - myNumber++; + if (!myType == SMESHDS_AddPyramid) + { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myIntegers.push_back(idnode3); + myIntegers.push_back(idnode4); + myIntegers.push_back(idnode5); + myNumber++; } //======================================================================= @@ -186,22 +202,22 @@ void SMESHDS_Command::AddVolume(int NewVolID, //purpose : //======================================================================= void SMESHDS_Command::AddVolume(int NewVolID, - int idnode1, - int idnode2, int idnode3, int idnode4, int idnode5, int idnode6) + int idnode1, + int idnode2, int idnode3, int idnode4, int idnode5, int idnode6) { - if (!myType == SMESHDS_AddPrism) - { - MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); - return; - } - myIntegers.push_back(NewVolID); - myIntegers.push_back(idnode1); - myIntegers.push_back(idnode2); - myIntegers.push_back(idnode3); - myIntegers.push_back(idnode4); - myIntegers.push_back(idnode5); - myIntegers.push_back(idnode6); - myNumber++; + if (!myType == SMESHDS_AddPrism) + { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myIntegers.push_back(idnode3); + myIntegers.push_back(idnode4); + myIntegers.push_back(idnode5); + myIntegers.push_back(idnode6); + myNumber++; } //======================================================================= @@ -209,34 +225,60 @@ void SMESHDS_Command::AddVolume(int NewVolID, //purpose : //======================================================================= void SMESHDS_Command::AddVolume(int NewVolID, - int idnode1, - int idnode2, - int idnode3, - int idnode4, int idnode5, int idnode6, int idnode7, int idnode8) -{ - if (!myType == SMESHDS_AddHexahedron) - { - MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); - return; - } - myIntegers.push_back(NewVolID); - myIntegers.push_back(idnode1); - myIntegers.push_back(idnode2); - myIntegers.push_back(idnode3); - myIntegers.push_back(idnode4); - myIntegers.push_back(idnode5); - myIntegers.push_back(idnode6); - myIntegers.push_back(idnode7); - myIntegers.push_back(idnode8); - myNumber++; + int idnode1, + int idnode2, + int idnode3, + int idnode4, int idnode5, int idnode6, int idnode7, int idnode8) +{ + if (!myType == SMESHDS_AddHexahedron) + { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myIntegers.push_back(idnode3); + myIntegers.push_back(idnode4); + myIntegers.push_back(idnode5); + myIntegers.push_back(idnode6); + myIntegers.push_back(idnode7); + myIntegers.push_back(idnode8); + myNumber++; +} + +void SMESHDS_Command::AddVolume(int NewVolID, + int idnode1,int idnode2,int idnode3,int idnode4, + int idnode5, int idnode6, int idnode7, int idnode8, + int idnode9, int idnode10, int idnode11, int idnode12) +{ + if (myType != SMESHDS_AddHexagonalPrism) + { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(idnode1); + myIntegers.push_back(idnode2); + myIntegers.push_back(idnode3); + myIntegers.push_back(idnode4); + myIntegers.push_back(idnode5); + myIntegers.push_back(idnode6); + myIntegers.push_back(idnode7); + myIntegers.push_back(idnode8); + myIntegers.push_back(idnode9); + myIntegers.push_back(idnode10); + myIntegers.push_back(idnode11); + myIntegers.push_back(idnode12); + myNumber++; } //======================================================================= //function : AddPolygonalFace //purpose : //======================================================================= -void SMESHDS_Command::AddPolygonalFace (const int ElementID, - std::vector nodes_ids) +void SMESHDS_Command::AddPolygonalFace (const int ElementID, + const std::vector& nodes_ids) { if (!myType == SMESHDS_AddPolygon) { MESSAGE("SMESHDS_Command::AddPolygonalFace : Bad Type"); @@ -257,9 +299,9 @@ void SMESHDS_Command::AddPolygonalFace (const int ElementID, //function : AddPolyhedralVolume //purpose : //======================================================================= -void SMESHDS_Command::AddPolyhedralVolume (const int ElementID, - std::vector nodes_ids, - std::vector quantities) +void SMESHDS_Command::AddPolyhedralVolume (const int ElementID, + const std::vector& nodes_ids, + const std::vector& quantities) { if (!myType == SMESHDS_AddPolyhedron) { MESSAGE("SMESHDS_Command::AddPolyhedralVolume : Bad Type"); @@ -288,13 +330,13 @@ void SMESHDS_Command::AddPolyhedralVolume (const int ElementID, //======================================================================= void SMESHDS_Command::RemoveNode(int NodeID) { - if (!myType == SMESHDS_RemoveNode) - { - MESSAGE("SMESHDS_Command::RemoveNode : Bad Type"); - return; - } - myIntegers.push_back(NodeID); - myNumber++; + if (!myType == SMESHDS_RemoveNode) + { + MESSAGE("SMESHDS_Command::RemoveNode : Bad Type"); + return; + } + myIntegers.push_back(NodeID); + myNumber++; } //======================================================================= @@ -303,13 +345,13 @@ void SMESHDS_Command::RemoveNode(int NodeID) //======================================================================= void SMESHDS_Command::RemoveElement(int ElementID) { - if (!myType == SMESHDS_RemoveElement) - { - MESSAGE("SMESHDS_Command::RemoveElement : Bad Type"); - return; - } - myIntegers.push_back(ElementID); - myNumber++; + if (!myType == SMESHDS_RemoveElement) + { + MESSAGE("SMESHDS_Command::RemoveElement : Bad Type"); + return; + } + myIntegers.push_back(ElementID); + myNumber++; } //======================================================================= @@ -336,9 +378,9 @@ void SMESHDS_Command::ChangeElementNodes(int ElementID, int nodes[], int nbnodes //function : ChangePolyhedronNodes //purpose : //======================================================================= -void SMESHDS_Command::ChangePolyhedronNodes (const int ElementID, - std::vector nodes_ids, - std::vector quantities) +void SMESHDS_Command::ChangePolyhedronNodes (const int ElementID, + const std::vector& nodes_ids, + const std::vector& quantities) { if (myType != SMESHDS_ChangePolyhedronNodes) { @@ -386,7 +428,7 @@ void SMESHDS_Command::Renumber (const bool isNodes, const int startID, const int //======================================================================= SMESHDS_CommandType SMESHDS_Command::GetType() { - return myType; + return myType; } //======================================================================= @@ -395,7 +437,7 @@ SMESHDS_CommandType SMESHDS_Command::GetType() //======================================================================= int SMESHDS_Command::GetNumber() { - return myNumber; + return myNumber; } //======================================================================= @@ -404,7 +446,7 @@ int SMESHDS_Command::GetNumber() //======================================================================= const list < int >&SMESHDS_Command::GetIndexes() { - return myIntegers; + return myIntegers; } //======================================================================= @@ -413,7 +455,7 @@ const list < int >&SMESHDS_Command::GetIndexes() //======================================================================= const list < double >&SMESHDS_Command::GetCoords() { - return myReals; + return myReals; } @@ -484,6 +526,31 @@ void SMESHDS_Command::AddFace(int NewFaceID, myNumber++; } +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Command::AddFace(int NewFaceID, + int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41, int nCenter) +{ + if (myType != SMESHDS_AddBiQuadQuadrangle) { + MESSAGE("SMESHDS_Command::AddFace : Bad Type"); + return; + } + myIntegers.push_back(NewFaceID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myIntegers.push_back(nCenter); + myNumber++; +} + //======================================================================= //function : AddVolume //purpose : @@ -611,3 +678,68 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, myNumber++; } +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter) +{ + if (!myType == SMESHDS_AddQuadHexahedron) { + MESSAGE("SMESHDS_Command::AddVolume : Bad Type"); + return; + } + myIntegers.push_back(NewVolID); + myIntegers.push_back(n1); + myIntegers.push_back(n2); + myIntegers.push_back(n3); + myIntegers.push_back(n4); + myIntegers.push_back(n5); + myIntegers.push_back(n6); + myIntegers.push_back(n7); + myIntegers.push_back(n8); + myIntegers.push_back(n12); + myIntegers.push_back(n23); + myIntegers.push_back(n34); + myIntegers.push_back(n41); + myIntegers.push_back(n56); + myIntegers.push_back(n67); + myIntegers.push_back(n78); + myIntegers.push_back(n85); + myIntegers.push_back(n15); + myIntegers.push_back(n26); + myIntegers.push_back(n37); + myIntegers.push_back(n48); + myIntegers.push_back(n1234); + myIntegers.push_back(n1256); + myIntegers.push_back(n2367); + myIntegers.push_back(n3478); + myIntegers.push_back(n1458); + myIntegers.push_back(n5678); + myIntegers.push_back(nCenter); + myNumber++; +} + +//================================================================================ +/*! + * \brief Record adding a Ball + */ +//================================================================================ + +void SMESHDS_Command::AddBall(int NewBallID, int node, double diameter) +{ + if (!myType == SMESHDS_AddBall) + { + MESSAGE("SMESHDS_Command::SMESHDS_AddBall : Bad Type"); + return; + } + myIntegers.push_back(NewBallID); + myIntegers.push_back(node); + myReals.push_back(diameter); + myNumber++; +} diff --git a/src/SMESHDS/SMESHDS_Command.hxx b/src/SMESHDS/SMESHDS_Command.hxx index 09d720b9a..72acadc58 100644 --- a/src/SMESHDS/SMESHDS_Command.hxx +++ b/src/SMESHDS/SMESHDS_Command.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Command.hxx // Module : SMESH @@ -36,31 +37,38 @@ class SMESHDS_EXPORT SMESHDS_Command { public: - SMESHDS_Command(const SMESHDS_CommandType aType); - void AddNode(int NewNodeID, double x, double y, double z); - void AddEdge(int NewEdgeID, int idnode1, int idnode2); - void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3); - void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3, - int idnode4); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4, int idnode5); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4, int idnode5, int idnode6); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4, int idnode5, int idnode6, int idnode7, int idnode8); - void AddPolygonalFace (const int ElementID, - std::vector nodes_ids); - void AddPolyhedralVolume (const int ElementID, - std::vector nodes_ids, - std::vector quantities); + SMESHDS_Command(const SMESHDS_CommandType aType); + void AddNode(int NewNodeID, double x, double y, double z); + void Add0DElement(int New0DElementID, int idnode); + void AddEdge(int NewEdgeID, int idnode1, int idnode2); + void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3); + void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3, + int idnode4); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6, int idnode7, int idnode8); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6, int idnode7, int idnode8, + int idnode9, int idnode10, int idnode11, int idnode12); + void AddPolygonalFace (const int ElementID, + const std::vector& nodes_ids); + void AddPolyhedralVolume (const int ElementID, + const std::vector& nodes_ids, + const std::vector& quantities); + void AddBall(int NewBallID, int node, double diameter); // special methods for quadratic elements - void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddEdge(int NewEdgeID, int n1, int n2, int n12); void AddFace(int NewFaceID, int n1, int n2, int n3, int n12, int n23, int n31); void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, int n12, int n23, int n34, int n41); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41, int nCenter); void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n12, int n23, int n31, int n14, int n24, int n34); void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, @@ -72,28 +80,35 @@ class SMESHDS_EXPORT SMESHDS_Command int n45, int n56, int n64, int n14, int n25, int n36); void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, - int n5, int n6, int n7, int n8, + int n5, int n6, int n7, int n8, int n12, int n23, int n34, int n41, int n56, int n67, int n78, int n85, int n15, int n26, int n37, int n48); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter); - void MoveNode(int NewNodeID, double x, double y, double z); - void RemoveNode(int NodeID); - void RemoveElement(int ElementID); - void ChangeElementNodes(int ElementID, int nodes[], int nbnodes); - void ChangePolyhedronNodes(const int ElementID, - std::vector nodes_ids, - std::vector quantities); - void Renumber (const bool isNodes, const int startID, const int deltaID); - SMESHDS_CommandType GetType(); - int GetNumber(); - const std::list & GetIndexes(); - const std::list & GetCoords(); - ~SMESHDS_Command(); + void MoveNode(int NewNodeID, double x, double y, double z); + void RemoveNode(int NodeID); + void RemoveElement(int ElementID); + void ChangeElementNodes(int ElementID, int nodes[], int nbnodes); + void ChangePolyhedronNodes(const int ElementID, + const std::vector& nodes_ids, + const std::vector& quantities); + void Renumber (const bool isNodes, const int startID, const int deltaID); + SMESHDS_CommandType GetType(); + int GetNumber(); + const std::list & GetIndexes(); + const std::list & GetCoords(); + ~SMESHDS_Command(); private: - SMESHDS_CommandType myType; - int myNumber; - std::list myReals; - std::list myIntegers; + SMESHDS_CommandType myType; + int myNumber; + std::list myReals; + std::list myIntegers; }; #endif diff --git a/src/SMESHDS/SMESHDS_CommandType.hxx b/src/SMESHDS/SMESHDS_CommandType.hxx index bafaba863..7870d1e67 100644 --- a/src/SMESHDS/SMESHDS_CommandType.hxx +++ b/src/SMESHDS/SMESHDS_CommandType.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_CommandType.hxx // Module : SMESH @@ -26,8 +27,6 @@ #ifndef _SMESHDS_CommandType_HeaderFile #define _SMESHDS_CommandType_HeaderFile -//#include - enum SMESHDS_CommandType { SMESHDS_AddNode, SMESHDS_AddEdge, @@ -53,7 +52,13 @@ enum SMESHDS_CommandType { SMESHDS_AddQuadTetrahedron, SMESHDS_AddQuadPyramid, SMESHDS_AddQuadPentahedron, - SMESHDS_AddQuadHexahedron + SMESHDS_AddQuadHexahedron, + // + SMESHDS_Add0DElement, + SMESHDS_AddBiQuadQuadrangle, + SMESHDS_AddTriQuadHexa, + SMESHDS_AddHexagonalPrism, + SMESHDS_AddBall }; diff --git a/src/SMESHDS/SMESHDS_DataMapOfShape.hxx b/src/SMESHDS/SMESHDS_DataMapOfShape.hxx index ae7489564..e9482e7bb 100755 --- a/src/SMESHDS/SMESHDS_DataMapOfShape.hxx +++ b/src/SMESHDS/SMESHDS_DataMapOfShape.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File: SMESHDS_DataMapOfShape.hxx // Created: 20.09.05 09:51:12 // Author: Alexander BORODIN diff --git a/src/SMESHDS/SMESHDS_Document.cxx b/src/SMESHDS/SMESHDS_Document.cxx index 9e568e297..315275e33 100644 --- a/src/SMESHDS/SMESHDS_Document.cxx +++ b/src/SMESHDS/SMESHDS_Document.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Document.cxx // Author : Yves FRICAUD, OCC @@ -69,13 +70,13 @@ int SMESHDS_Document::NewMesh(bool theIsEmbeddedMode) //======================================================================= SMESHDS_Mesh *SMESHDS_Document::GetMesh(int MeshID) { - map::iterator it=myMeshes.find(MeshID); - if (it==myMeshes.end()) - { - MESSAGE("SMESHDS_Document::GetMesh : ID not found"); - return NULL; - } - else return (*it).second; + map::iterator it=myMeshes.find(MeshID); + if (it==myMeshes.end()) + { + MESSAGE("SMESHDS_Document::GetMesh : ID not found"); + return NULL; + } + else return (*it).second; } //======================================================================= @@ -84,10 +85,9 @@ SMESHDS_Mesh *SMESHDS_Document::GetMesh(int MeshID) //======================================================================= void SMESHDS_Document::RemoveMesh(int MeshID) { - map::iterator it=myMeshes.find(MeshID); - if (it==myMeshes.end()) - MESSAGE("SMESHDS_Document::RemoveMesh : ID not found"); - myMeshes.erase(it); + map::iterator it=myMeshes.find(MeshID); + if (it!=myMeshes.end()) + myMeshes.erase(it); } //======================================================================= @@ -96,7 +96,7 @@ void SMESHDS_Document::RemoveMesh(int MeshID) //======================================================================= void SMESHDS_Document::AddHypothesis(SMESHDS_Hypothesis * H) { - myHypothesis[H->GetID()]=H; + myHypothesis[H->GetID()]=H; } //======================================================================= @@ -105,13 +105,13 @@ void SMESHDS_Document::AddHypothesis(SMESHDS_Hypothesis * H) //======================================================================= SMESHDS_Hypothesis * SMESHDS_Document::GetHypothesis(int HypID) { - map::iterator it=myHypothesis.find(HypID); - if (it==myHypothesis.end()) - { - MESSAGE("SMESHDS_Document::GetHypothesis : ID not found"); - return NULL; - } - else return (*it).second; + map::iterator it=myHypothesis.find(HypID); + if (it==myHypothesis.end()) + { + MESSAGE("SMESHDS_Document::GetHypothesis : ID not found"); + return NULL; + } + else return (*it).second; } //======================================================================= @@ -120,10 +120,10 @@ SMESHDS_Hypothesis * SMESHDS_Document::GetHypothesis(int HypID) //======================================================================= void SMESHDS_Document::RemoveHypothesis(int HypID) { - map::iterator it=myHypothesis.find(HypID); - if (it==myHypothesis.end()) - MESSAGE("SMESHDS_Document::RemoveHypothesis : ID not found"); - myHypothesis.erase(it); + map::iterator it=myHypothesis.find(HypID); + if (it==myHypothesis.end()) + MESSAGE("SMESHDS_Document::RemoveHypothesis : ID not found"); + myHypothesis.erase(it); } //======================================================================= @@ -132,7 +132,7 @@ void SMESHDS_Document::RemoveHypothesis(int HypID) //======================================================================= int SMESHDS_Document::NbMeshes() { - return myMeshes.size(); + return myMeshes.size(); } //======================================================================= @@ -141,7 +141,7 @@ int SMESHDS_Document::NbMeshes() //======================================================================= int SMESHDS_Document::NbHypothesis() { - return myHypothesis.size(); + return myHypothesis.size(); } //======================================================================= @@ -150,7 +150,7 @@ int SMESHDS_Document::NbHypothesis() //======================================================================= void SMESHDS_Document::InitMeshesIterator() { - myMeshesIt=myMeshes.begin(); + myMeshesIt=myMeshes.begin(); } //======================================================================= @@ -159,9 +159,9 @@ void SMESHDS_Document::InitMeshesIterator() //======================================================================= SMESHDS_Mesh * SMESHDS_Document::NextMesh() { - SMESHDS_Mesh * toReturn=(*myMeshesIt).second; - myMeshesIt++; - return toReturn; + SMESHDS_Mesh * toReturn=(*myMeshesIt).second; + myMeshesIt++; + return toReturn; } //======================================================================= @@ -170,7 +170,7 @@ SMESHDS_Mesh * SMESHDS_Document::NextMesh() //======================================================================= bool SMESHDS_Document::MoreMesh() { - return myMeshesIt!=myMeshes.end(); + return myMeshesIt!=myMeshes.end(); } //======================================================================= @@ -179,7 +179,7 @@ bool SMESHDS_Document::MoreMesh() //======================================================================= void SMESHDS_Document::InitHypothesisIterator() { - myHypothesisIt=myHypothesis.begin(); + myHypothesisIt=myHypothesis.begin(); } //======================================================================= @@ -188,9 +188,9 @@ void SMESHDS_Document::InitHypothesisIterator() //======================================================================= SMESHDS_Hypothesis * SMESHDS_Document::NextHypothesis() { - SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second; - myHypothesisIt++; - return toReturn; + SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second; + myHypothesisIt++; + return toReturn; } //======================================================================= @@ -199,5 +199,5 @@ SMESHDS_Hypothesis * SMESHDS_Document::NextHypothesis() //======================================================================= bool SMESHDS_Document::MoreHypothesis() { - return myHypothesisIt!=myHypothesis.end(); + return myHypothesisIt!=myHypothesis.end(); } diff --git a/src/SMESHDS/SMESHDS_Document.hxx b/src/SMESHDS/SMESHDS_Document.hxx index 6abea04a4..182581256 100644 --- a/src/SMESHDS/SMESHDS_Document.hxx +++ b/src/SMESHDS/SMESHDS_Document.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Document.hxx // Module : SMESH @@ -36,29 +37,29 @@ class SMESHDS_EXPORT SMESHDS_Document { public: - SMESHDS_Document(int UserID); - int NewMesh(bool theIsEmbeddedMode); - void RemoveMesh(int MeshID); - SMESHDS_Mesh * GetMesh(int MeshID); - void AddHypothesis(SMESHDS_Hypothesis * H); - void RemoveHypothesis(int HypID); - SMESHDS_Hypothesis * GetHypothesis(int HypID); - int NbMeshes(); - int NbHypothesis(); - void InitMeshesIterator(); - SMESHDS_Mesh * NextMesh(); - bool MoreMesh(); - void InitHypothesisIterator(); - SMESHDS_Hypothesis * NextHypothesis(); - bool MoreHypothesis(); - ~SMESHDS_Document(); + SMESHDS_Document(int UserID); + int NewMesh(bool theIsEmbeddedMode); + void RemoveMesh(int MeshID); + SMESHDS_Mesh * GetMesh(int MeshID); + void AddHypothesis(SMESHDS_Hypothesis * H); + void RemoveHypothesis(int HypID); + SMESHDS_Hypothesis * GetHypothesis(int HypID); + int NbMeshes(); + int NbHypothesis(); + void InitMeshesIterator(); + SMESHDS_Mesh * NextMesh(); + bool MoreMesh(); + void InitHypothesisIterator(); + SMESHDS_Hypothesis * NextHypothesis(); + bool MoreHypothesis(); + ~SMESHDS_Document(); private: - int myUserID; - std::map myMeshes; - std::map myHypothesis; - std::map::iterator myMeshesIt; - std::map::iterator myHypothesisIt; + int myUserID; + std::map myMeshes; + std::map myHypothesis; + std::map::iterator myMeshesIt; + std::map::iterator myHypothesisIt; }; #endif diff --git a/src/SMESHDS/SMESHDS_Group.cxx b/src/SMESHDS/SMESHDS_Group.cxx index fd0ba61d5..c3e1820e5 100644 --- a/src/SMESHDS/SMESHDS_Group.cxx +++ b/src/SMESHDS/SMESHDS_Group.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes // File : SMESHDS_Group.cxx // Module : SMESH @@ -48,7 +49,7 @@ SMESHDS_Group::SMESHDS_Group (const int theID, //purpose : //======================================================================= -int SMESHDS_Group::Extent() +int SMESHDS_Group::Extent() const { return myGroup.Extent(); } @@ -155,11 +156,22 @@ class MyGroupIterator: public SMDS_ElemIterator //purpose : //======================================================================= -SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() +SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() const { return SMDS_ElemIteratorPtr( new MyGroupIterator ( myGroup )); } +//================================================================================ +/*! + * \brief Return a value allowing to find out if a group has changed or not + */ +//================================================================================ + +int SMESHDS_Group::GetTic() const +{ + return myGroup.Tic(); +} + //======================================================================= //function : SetType //purpose : diff --git a/src/SMESHDS/SMESHDS_Group.hxx b/src/SMESHDS/SMESHDS_Group.hxx index 85d7d14c2..6c798d961 100644 --- a/src/SMESHDS/SMESHDS_Group.hxx +++ b/src/SMESHDS/SMESHDS_Group.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Group.hxx // Module : SMESH @@ -45,7 +46,7 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase virtual void SetType(SMDSAbs_ElementType theType); - virtual int Extent(); + virtual int Extent() const; virtual bool IsEmpty(); @@ -53,7 +54,9 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase virtual bool Contains (const SMDS_MeshElement* elem); - virtual SMDS_ElemIteratorPtr GetElements(); + virtual SMDS_ElemIteratorPtr GetElements() const; + + virtual int GetTic() const; bool Add (const int theID); diff --git a/src/SMESHDS/SMESHDS_GroupBase.cxx b/src/SMESHDS/SMESHDS_GroupBase.cxx index b14afd408..383d796a2 100644 --- a/src/SMESHDS/SMESHDS_GroupBase.cxx +++ b/src/SMESHDS/SMESHDS_GroupBase.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes // File : SMESHDS_Group.cxx // Module : SMESH @@ -104,7 +105,7 @@ void SMESHDS_GroupBase::resetIterator() //purpose : //======================================================================= -int SMESHDS_GroupBase::Extent() +int SMESHDS_GroupBase::Extent() const { SMDS_ElemIteratorPtr it = GetElements(); int nb = 0; diff --git a/src/SMESHDS/SMESHDS_GroupBase.hxx b/src/SMESHDS/SMESHDS_GroupBase.hxx index ced9543fa..cc9411f99 100644 --- a/src/SMESHDS/SMESHDS_GroupBase.hxx +++ b/src/SMESHDS/SMESHDS_GroupBase.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Group.hxx // Module : SMESH @@ -57,7 +58,7 @@ class SMESHDS_EXPORT SMESHDS_GroupBase const char* GetStoreName () const { return myStoreName.c_str(); } - virtual int Extent(); + virtual int Extent() const; virtual bool IsEmpty(); @@ -65,11 +66,13 @@ class SMESHDS_EXPORT SMESHDS_GroupBase virtual bool Contains (const SMDS_MeshElement* elem); - virtual SMDS_ElemIteratorPtr GetElements() = 0; + virtual SMDS_ElemIteratorPtr GetElements() const = 0; - int GetID (const int theIndex); + virtual int GetID (const int theIndex); // use it for iterations 1..Extent() + virtual int GetTic() const = 0; + virtual ~SMESHDS_GroupBase() {} void SetColor (const Quantity_Color& theColor) @@ -96,11 +99,12 @@ class SMESHDS_EXPORT SMESHDS_GroupBase const SMESHDS_Mesh* myMesh; SMDSAbs_ElementType myType; std::string myStoreName; + Quantity_Color myColor; + // for GetID() int myCurIndex; int myCurID; SMDS_ElemIteratorPtr myIterator; - Quantity_Color myColor; }; #endif diff --git a/src/SMESHDS/SMESHDS_GroupOnFilter.cxx b/src/SMESHDS/SMESHDS_GroupOnFilter.cxx new file mode 100644 index 000000000..32bd8c7f3 --- /dev/null +++ b/src/SMESHDS/SMESHDS_GroupOnFilter.cxx @@ -0,0 +1,190 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHDS_GroupOnFilter.cxx +// Module : SMESH +// +#include "SMESHDS_GroupOnFilter.hxx" + +#include "SMESHDS_Mesh.hxx" +#include "SMDS_SetIterator.hxx" + +using namespace std; + +//============================================================================= +/*! + * Creates a group based on thePredicate + */ +//============================================================================= + +SMESHDS_GroupOnFilter::SMESHDS_GroupOnFilter (const int theID, + const SMESHDS_Mesh* theMesh, + const SMDSAbs_ElementType theType, + const SMESH_PredicatePtr& thePredicate) + : SMESHDS_GroupBase(theID,theMesh,theType), myMeshModifTime(0), myPredicateTic(0) +{ + setChanged(); + SetPredicate( thePredicate ); +} + +//================================================================================ +/*! + * \brief Sets a new predicate + */ +//================================================================================ + +void SMESHDS_GroupOnFilter::SetPredicate( const SMESH_PredicatePtr& thePredicate) +{ + myPredicate = thePredicate; + ++myPredicateTic; + setChanged(); + if ( myPredicate ) + myPredicate->SetMesh( GetMesh() ); +} + +//================================================================================ +/*! + * \brief Returns nb of elements + */ +//================================================================================ + +int SMESHDS_GroupOnFilter::Extent() const +{ + update(); + return myElements.size(); +} + +//================================================================================ +/*! + * \brief Checks if the element belongs to the group + */ +//================================================================================ + +bool SMESHDS_GroupOnFilter::Contains (const int theID) +{ + return myPredicate ? myPredicate->IsSatisfy( theID ) : false; +} + +//================================================================================ +/*! + * \brief Checks if the element belongs to the group + */ +//================================================================================ + +bool SMESHDS_GroupOnFilter::Contains (const SMDS_MeshElement* elem) +{ + return myPredicate ? myPredicate->IsSatisfy( elem->GetID() ) : false; +} + +//================================================================================ +/*! + * \brief Return iterator on all elements + */ +//================================================================================ + +SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const +{ + update(); + return SMDS_ElemIteratorPtr + ( new SMDS_ElementVectorIterator( myElements.begin(), myElements.end() )); +} + +//================================================================================ +/*! + * \brief return ID of theIndex-th element + * \param theIndex - index countered from 1 + * \retval int - element ID + */ +//================================================================================ + +int SMESHDS_GroupOnFilter::GetID (const int theIndex) +{ + update(); + if ( theIndex < 1 || theIndex > myElements.size() ) + return -1; + return myElements[ theIndex-1 ]->GetID(); +} + +//================================================================================ +/*! + * \brief Return a value allowing to find out if a group has changed or not + */ +//================================================================================ + +int SMESHDS_GroupOnFilter::GetTic() const +{ + return GetMesh()->GetMTime() * myPredicateTic; +} + +//================================================================================ +/*! + * \brief Return false if update() is needed + */ +//================================================================================ + +bool SMESHDS_GroupOnFilter::IsUpToDate() const +{ + return !( myMeshModifTime < GetMesh()->GetMTime() ); +} + +//================================================================================ +/*! + * \brief Updates myElements if necessary + */ +//================================================================================ + +void SMESHDS_GroupOnFilter::update() const +{ + if ( !IsUpToDate() ) + { + SMESHDS_GroupOnFilter* me = const_cast( this ); + me->myElements.clear(); + if ( myPredicate ) + { + myPredicate->SetMesh( GetMesh() ); // hope myPredicate updates self here if necessary + me->myElements.reserve( GetMesh()->GetMeshInfo().NbElements(GetType())); + SMDS_ElemIteratorPtr elIt = GetMesh()->elementsIterator(GetType()); + while ( elIt->more() ) + { + const SMDS_MeshElement* e = elIt->next(); + if ( myPredicate->IsSatisfy( e->GetID() )) + me->myElements.push_back( e ); + } + vector< const SMDS_MeshElement*> elems( me->myElements.begin(), me->myElements.end() ); + me->myElements.swap( elems ); + } + me->setChanged( false ); + } +} + +//================================================================================ +/*! + * \brief Sets myMeshModifTime according to modification state + */ +//================================================================================ + +void SMESHDS_GroupOnFilter::setChanged(bool changed) +{ + myMeshModifTime = GetMesh()->GetMTime(); + if ( changed && myMeshModifTime != 0 ) + --myMeshModifTime; +} diff --git a/src/SMESHDS/SMESHDS_GroupOnFilter.hxx b/src/SMESHDS/SMESHDS_GroupOnFilter.hxx new file mode 100644 index 000000000..b1e33e5fc --- /dev/null +++ b/src/SMESHDS/SMESHDS_GroupOnFilter.hxx @@ -0,0 +1,74 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHDS_GroupOnFilter.hxx +// Module : SMESH +// +#ifndef _SMESHDS_GroupOnFilter_HeaderFile +#define _SMESHDS_GroupOnFilter_HeaderFile + +#include "SMESH_SMESHDS.hxx" + +#include "SMESHDS_GroupBase.hxx" +#include "SMESH_Controls.hxx" + +/*! + * \brief Groups whose contents is dynamically updated using the filter + */ +class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase +{ + public: + + SMESHDS_GroupOnFilter (const int theID, + const SMESHDS_Mesh* theMesh, + const SMDSAbs_ElementType theType, + const SMESH_PredicatePtr& thePredicate); + + void SetPredicate( const SMESH_PredicatePtr& thePredicate); + + SMESH_PredicatePtr GetPredicate() const { return myPredicate; } + + virtual int Extent() const; + + virtual bool Contains (const int theID); + + virtual bool Contains (const SMDS_MeshElement* elem); + + virtual SMDS_ElemIteratorPtr GetElements() const; + + virtual int GetID (const int theIndex); + + virtual int GetTic() const; + + bool IsUpToDate() const; + + private: + + void update() const; + void setChanged(bool changed=true); + + SMESH_PredicatePtr myPredicate; + std::vector< const SMDS_MeshElement*> myElements; + unsigned long myMeshModifTime; // when myElements was filled + int myPredicateTic; +}; + +#endif diff --git a/src/SMESHDS/SMESHDS_GroupOnGeom.cxx b/src/SMESHDS/SMESHDS_GroupOnGeom.cxx index 73e1654db..51d762028 100644 --- a/src/SMESHDS/SMESHDS_GroupOnGeom.cxx +++ b/src/SMESHDS/SMESHDS_GroupOnGeom.cxx @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes // File : SMESHDS_GroupOnGeom.cxx // Module : SMESH -// $Header$ // #include "SMESHDS_GroupOnGeom.hxx" #include "SMESHDS_Mesh.hxx" @@ -40,10 +40,16 @@ SMESHDS_GroupOnGeom::SMESHDS_GroupOnGeom (const int theID, const SMESHDS_Mesh* theMesh, const SMDSAbs_ElementType theType, const TopoDS_Shape& theShape) - : SMESHDS_GroupBase(theID,theMesh,theType), myShape(theShape) + : SMESHDS_GroupBase(theID,theMesh,theType) +{ + SetShape( theShape ); +} + +void SMESHDS_GroupOnGeom::SetShape( const TopoDS_Shape& theShape) { - SMESHDS_Mesh* aMesh = const_cast(theMesh); + SMESHDS_Mesh* aMesh = const_cast( GetMesh() ); mySubMesh = aMesh->MeshElements( aMesh->AddCompoundSubmesh( theShape )); + myShape = theShape; } // ===================== @@ -60,13 +66,14 @@ class MyIterator: public SMDS_ElemIterator MyIterator(SMDSAbs_ElementType type, const SMESHDS_SubMesh* subMesh) : myType(type), myElem(0) { - if ( subMesh ) + if ( subMesh ) { if ( myType == SMDSAbs_Node ) myNodeIt = subMesh->GetNodes(); else { myElemIt = subMesh->GetElements(); next(); } + } } bool more() { @@ -96,7 +103,7 @@ class MyIterator: public SMDS_ElemIterator //purpose : //======================================================================= -SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements() +SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements() const { return SMDS_ElemIteratorPtr( new MyIterator ( GetType(), mySubMesh )); } @@ -121,3 +128,14 @@ bool SMESHDS_GroupOnGeom::Contains (const SMDS_MeshElement* elem) return mySubMesh->Contains( elem ); } +//================================================================================ +/*! + * \brief Return a value allowing to find out if a group has changed or not + */ +//================================================================================ + +int SMESHDS_GroupOnGeom::GetTic() const +{ + return GetMesh()->GetMTime(); +} + diff --git a/src/SMESHDS/SMESHDS_GroupOnGeom.hxx b/src/SMESHDS/SMESHDS_GroupOnGeom.hxx index a1fa3cb26..1895912b4 100644 --- a/src/SMESHDS/SMESHDS_GroupOnGeom.hxx +++ b/src/SMESHDS/SMESHDS_GroupOnGeom.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_GroupOnGeom.hxx // Module : SMESH -// $Header$ // #ifndef _SMESHDS_GroupOnGeom_HeaderFile #define _SMESHDS_GroupOnGeom_HeaderFile @@ -43,13 +43,17 @@ class SMESHDS_EXPORT SMESHDS_GroupOnGeom: public SMESHDS_GroupBase const SMDSAbs_ElementType theType, const TopoDS_Shape& theShape); + void SetShape( const TopoDS_Shape& theShape); + TopoDS_Shape GetShape() const { return myShape; } virtual bool Contains (const int theID); virtual bool Contains (const SMDS_MeshElement* elem); - virtual SMDS_ElemIteratorPtr GetElements(); + virtual SMDS_ElemIteratorPtr GetElements() const; + + virtual int GetTic() const; private: diff --git a/src/SMESHDS/SMESHDS_Hypothesis.cxx b/src/SMESHDS/SMESHDS_Hypothesis.cxx index 84b3a6c32..ea7c5c6e5 100644 --- a/src/SMESHDS/SMESHDS_Hypothesis.cxx +++ b/src/SMESHDS/SMESHDS_Hypothesis.cxx @@ -1,32 +1,34 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Hypothesis.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "SMESHDS_Hypothesis.hxx" +#include + using namespace std; //============================================================================= @@ -37,11 +39,8 @@ using namespace std; SMESHDS_Hypothesis::SMESHDS_Hypothesis(int hypId) { -// MESSAGE("SMESHDS_Hypothesis::SMESHDS_Hypothesis"); _hypId = hypId; _name = "generic"; -// SCRUTE(_name); -// SCRUTE(_hypId); } //============================================================================= @@ -52,7 +51,6 @@ SMESHDS_Hypothesis::SMESHDS_Hypothesis(int hypId) SMESHDS_Hypothesis::~SMESHDS_Hypothesis() { -// MESSAGE("SMESHDS_Hypothesis::~SMESHDS_Hypothesis"); } //============================================================================= @@ -63,9 +61,6 @@ SMESHDS_Hypothesis::~SMESHDS_Hypothesis() const char* SMESHDS_Hypothesis::GetName() const { -// MESSAGE("SMESHDS_Hypothesis::GetName"); -// SCRUTE(_name); -// SCRUTE(&_name); return _name.c_str(); } @@ -77,8 +72,6 @@ const char* SMESHDS_Hypothesis::GetName() const int SMESHDS_Hypothesis::GetID() const { -// MESSAGE("SMESHDS_Hypothesis::GetId"); -// SCRUTE(_hypId); return _hypId; } @@ -90,8 +83,23 @@ int SMESHDS_Hypothesis::GetID() const int SMESHDS_Hypothesis::GetType() const { -// MESSAGE("SMESHDS_Hypothesis::GetType"); -// SCRUTE(_type); return _type; } +//============================================================================= +/*! + * Equality + */ +//============================================================================= + +bool SMESHDS_Hypothesis::operator==(const SMESHDS_Hypothesis& other) const +{ + if ( this == &other ) + return true; + if ( _name != other._name ) + return false; + ostringstream mySave, otherSave; + ((SMESHDS_Hypothesis*)this )->SaveTo(mySave); + ((SMESHDS_Hypothesis*)&other)->SaveTo(otherSave); + return mySave.str() == otherSave.str(); +} diff --git a/src/SMESHDS/SMESHDS_Hypothesis.hxx b/src/SMESHDS/SMESHDS_Hypothesis.hxx index 4478b4a0b..d819684af 100644 --- a/src/SMESHDS/SMESHDS_Hypothesis.hxx +++ b/src/SMESHDS/SMESHDS_Hypothesis.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Hypothesis.hxx // Author : Paul RASCLE, EDF @@ -46,6 +47,9 @@ public: virtual std::ostream & SaveTo(std::ostream & save)=0; virtual std::istream & LoadFrom(std::istream & load)=0; + virtual bool operator==(const SMESHDS_Hypothesis& other) const; + bool operator!=(const SMESHDS_Hypothesis& other) const { return !(*this==other); } + enum hypothesis_type {PARAM_ALGO, ALGO_0D, ALGO_1D, ALGO_2D, ALGO_3D}; protected: diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index b2dab7719..a42b9acc0 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESH_Mesh.cxx // Author : Yves FRICAUD, OCC // Module : SMESH -// $Header: // #include "SMESHDS_Mesh.hxx" @@ -32,21 +32,25 @@ #include "SMDS_EdgePosition.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" +#include "SMDS_Downward.hxx" #include "SMESHDS_GroupOnGeom.hxx" +#include "SMESHDS_Script.hxx" -#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include #include "utilities.h" using namespace std; -/*Standard_Boolean IsEqual( const TopoDS_Shape& S1, const TopoDS_Shape& S2 ) - { - return S1.IsSame( S2 ); - }*/ - //======================================================================= //function : Create //purpose : @@ -58,6 +62,7 @@ SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode): { myScript = new SMESHDS_Script(theIsEmbeddedMode); myCurSubMesh = 0; + SetPersistentId(theMeshID); } //======================================================================= @@ -66,6 +71,30 @@ bool SMESHDS_Mesh::IsEmbeddedMode() return myIsEmbeddedMode; } +//================================================================================ +/*! + * \brief Store ID persistent during lifecycle + * + * Initially it was used to have a persistent reference to the mesh from the hypothesis + */ +//================================================================================ + +void SMESHDS_Mesh::SetPersistentId(int id) +{ + if (NbNodes() == 0) + myPersistentID = id; +} +//================================================================================ +/*! + * \brief Return ID persistent during lifecycle + */ +//================================================================================ + +int SMESHDS_Mesh::GetPersistentId() const +{ + return myPersistentID; +} + //======================================================================= //function : ShapeToMesh //purpose : @@ -83,12 +112,15 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S) if ( !i_sub->second->IsComplexSubmesh() ) { SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes(); while ( nIt->more() ) - nIt->next()->GetPosition()->SetShapeId( 0 ); + i_sub->second->RemoveNode(nIt->next(), false); } } // - sub-meshes - myIndexToShape.Clear(); + TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin(); + for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm ) + delete i_sm->second; myShapeIndexToSubMesh.clear(); + myIndexToShape.Clear(); // - groups on geometry set::iterator gr = myGroups.begin(); while ( gr != myGroups.end() ) { @@ -186,6 +218,7 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, const SMDS_MeshNode * nodes[], const int nbnodes) { + //MESSAGE("SMESHDS_Mesh::ChangeElementNodes"); if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes )) return false; @@ -241,14 +274,71 @@ bool SMESHDS_Mesh::ChangePolyhedronNodes void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) { - SMDS_Mesh::Renumber( isNodes, startID, deltaID ); - myScript->Renumber( isNodes, startID, deltaID ); + // TODO not possible yet to have node numbers not starting to O and continuous. + if (!this->isCompacted()) + this->compactMesh(); +// SMDS_Mesh::Renumber( isNodes, startID, deltaID ); +// myScript->Renumber( isNodes, startID, deltaID ); +} + +//======================================================================= +//function : Add0DElement +//purpose : +//======================================================================= +SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID) +{ + SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID); + if (anElem) myScript->Add0DElement(ID, nodeID); + return anElem; +} + +SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID + (const SMDS_MeshNode * node, int ID) +{ + return Add0DElementWithID(node->GetID(), ID); +} + +SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node) +{ + SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node); + if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID()); + return anElem; +} + +//======================================================================= +//function :AddBallWithID +//purpose : +//======================================================================= + +SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(int node, double diameter, int ID) +{ + SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID); + if (anElem) myScript->AddBall(anElem->GetID(), node, diameter); + return anElem; +} + +SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(const SMDS_MeshNode * node, + double diameter, + int ID) +{ + SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID); + if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter); + return anElem; +} + +SMDS_BallElement* SMESHDS_Mesh::AddBall (const SMDS_MeshNode * node, + double diameter) +{ + SMDS_BallElement* anElem = SMDS_Mesh::AddBall(node,diameter); + if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter); + return anElem; } //======================================================================= //function :AddEdgeWithID //purpose : //======================================================================= + SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID); @@ -257,21 +347,21 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID) } SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - int ID) + const SMDS_MeshNode * n2, + int ID) { return AddEdgeWithID(n1->GetID(), - n2->GetID(), - ID); + n2->GetID(), + ID); } SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2) + const SMDS_MeshNode * n2) { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2); if(anElem) myScript->AddEdge(anElem->GetID(), - n1->GetID(), - n2->GetID()); + n1->GetID(), + n2->GetID()); return anElem; } @@ -287,25 +377,25 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID) } SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID) { return AddFaceWithID(n1->GetID(), - n2->GetID(), - n3->GetID(), - ID); + n2->GetID(), + n3->GetID(), + ID); } SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3); if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), - n2->GetID(), - n3->GetID()); + n1->GetID(), + n2->GetID(), + n3->GetID()); return anElem; } @@ -321,29 +411,29 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int I } SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) { return AddFaceWithID(n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - ID); + n2->GetID(), + n3->GetID(), + n4->GetID(), + ID); } SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4); if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID()); + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID()); return anElem; } @@ -359,29 +449,29 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i } SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID) { return AddVolumeWithID(n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - ID); + n2->GetID(), + n3->GetID(), + n4->GetID(), + ID); } SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4); if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID()); + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID()); return anElem; } @@ -397,33 +487,33 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i } SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID) { return AddVolumeWithID(n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - n5->GetID(), - ID); + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + ID); } SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5); if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - n5->GetID()); + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID()); return anElem; } @@ -439,37 +529,37 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i } SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID) { return AddVolumeWithID(n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID(), - ID); + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + ID); } SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6); if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID()); + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID()); return anElem; } @@ -485,54 +575,129 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i } SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - int ID) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID) { return AddVolumeWithID(n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID(), - n7->GetID(), - n8->GetID(), - ID); + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID(), + ID); } SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8) + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8); if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), - n2->GetID(), - n3->GetID(), - n4->GetID(), - n5->GetID(), - n6->GetID(), - n7->GetID(), - n8->GetID()); + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID()); return anElem; } + +//======================================================================= +//function :AddVolume +//purpose : add hexagonal prism +//======================================================================= +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n9, int n10, int n11, int n12, + int ID) +{ + SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, ID); + if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, + int ID) +{ + return AddVolumeWithID(n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID(), + n9->GetID(), + n10->GetID(), + n11->GetID(), + n12->GetID(), + ID); +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12); + if(anElem) myScript->AddVolume(anElem->GetID(), + n1->GetID(), + n2->GetID(), + n3->GetID(), + n4->GetID(), + n5->GetID(), + n6->GetID(), + n7->GetID(), + n8->GetID(), + n9->GetID(), + n10->GetID(), + n11->GetID(), + n12->GetID()); + return anElem; +} + + //======================================================================= //function : AddPolygonalFace //purpose : //======================================================================= -SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, - const int ID) +SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector& nodes_ids, + const int ID) { SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID); if (anElem) { @@ -542,8 +707,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, } SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID - (std::vector nodes, - const int ID) + (const std::vector& nodes, + const int ID) { SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); if (anElem) { @@ -558,7 +723,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID } SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace - (std::vector nodes) + (const std::vector& nodes) { SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes); if (anElem) { @@ -576,9 +741,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace //function : AddPolyhedralVolume //purpose : //======================================================================= -SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector nodes_ids, - std::vector quantities, - const int ID) +SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector& nodes_ids, + const std::vector& quantities, + const int ID) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID); if (anElem) { @@ -588,9 +753,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector nodes } SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID - (std::vector nodes, - std::vector quantities, - const int ID) + (const std::vector& nodes, + const std::vector& quantities, + const int ID) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); if (anElem) { @@ -605,8 +770,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID } SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume - (std::vector nodes, - std::vector quantities) + (const std::vector& nodes, + const std::vector& quantities) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities); if (anElem) { @@ -652,43 +817,50 @@ static void removeFromContainers (map& theSubMeshes, } } + const bool deleted=true; + // Rm from sub-meshes // Element should belong to only one sub-mesh - map::iterator SubIt = theSubMeshes.begin(); - for ( ; SubIt != theSubMeshes.end(); SubIt++ ) + if ( !theSubMeshes.empty() ) { - int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements(); - if ( size == 0 ) continue; - + SMESHDS_Mesh* mesh = theSubMeshes.begin()->second->getParent(); list::iterator elIt = theElems.begin(); - while ( elIt != theElems.end() ) - { - bool removed = false; - if ( isNode ) - removed = (*SubIt).second->RemoveNode( static_cast (*elIt) ); - else - removed = (*SubIt).second->RemoveElement( *elIt ); - - if (removed) - { - elIt = theElems.erase( elIt ); - if ( theElems.empty() ) - return; // all elements are found and removed - } - else - { - elIt++ ; - } + if ( isNode ) { + for ( ; elIt != theElems.end(); ++elIt ) + if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() )) + sm->RemoveNode( static_cast (*elIt), deleted ); + } + else { + for ( ; elIt != theElems.end(); ++elIt ) + if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() )) + sm->RemoveElement( *elIt, deleted ); } } } - + //======================================================================= //function : RemoveNode //purpose : //======================================================================= void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n) { + if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces())) + { + SMESHDS_SubMesh* subMesh=0; + map::iterator SubIt = + myShapeIndexToSubMesh.find( n->getshapeId() ); + if ( SubIt != myShapeIndexToSubMesh.end() ) + subMesh = SubIt->second; + else + SubIt = myShapeIndexToSubMesh.begin(); + for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ ) + if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n )) + subMesh = SubIt->second; + + RemoveFreeNode( n, subMesh, true); + return; + } + myScript->RemoveNode(n->GetID()); list removedElems; @@ -724,7 +896,7 @@ void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n, // Rm from sub-mesh // Node should belong to only one sub-mesh if( subMesh ) - subMesh->RemoveNode(n); + subMesh->RemoveNode(n,/*deleted=*/false); SMDS_Mesh::RemoveFreeElement(n); } @@ -740,7 +912,18 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt) RemoveNode( static_cast( elt )); return; } - + if (!hasConstructionEdges() && !hasConstructionFaces()) + { + SMESHDS_SubMesh* subMesh=0; + map::iterator SubIt = myShapeIndexToSubMesh.begin(); + for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ ) + if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt )) + subMesh = SubIt->second; + //MESSAGE("subMesh " << elt->getshapeId()); + RemoveFreeElement( elt, subMesh, true); + return; + } + myScript->RemoveElement(elt->GetID()); list removedElems; @@ -759,6 +942,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, SMESHDS_SubMesh * subMesh, bool fromGroups) { + //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups); if (elt->GetType() == SMDSAbs_Node) { RemoveFreeNode( static_cast(elt), subMesh); return; @@ -784,7 +968,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt, // Rm from sub-mesh // Element should belong to only one sub-mesh if( subMesh ) - subMesh->RemoveElement(elt); + subMesh->RemoveElement(elt, /*deleted=*/false); SMDS_Mesh::RemoveFreeElement(elt); } @@ -819,7 +1003,7 @@ void SMESHDS_Mesh::ClearMesh() //================================================================================ /*! * \brief return submesh by shape - * \param shape - the subshape + * \param shape - the sub-shape * \retval SMESHDS_SubMesh* - the found submesh * * search of submeshes is optimized @@ -841,8 +1025,8 @@ SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape ) //================================================================================ /*! - * \brief return submesh by subshape index - * \param Index - the subshape index + * \brief return submesh by sub-shape index + * \param Index - the sub-shape index * \retval SMESHDS_SubMesh* - the found submesh * search of submeshes is optimized */ @@ -854,7 +1038,7 @@ SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index ) if ( Index != myCurSubID ) { map::iterator it = myShapeIndexToSubMesh.find( Index ); if ( it == myShapeIndexToSubMesh.end() ) - it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first; + it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first; myCurSubMesh = it->second; myCurSubID = Index; myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh @@ -882,22 +1066,6 @@ bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh ) return false; } -namespace { - - //================================================================================ - /*! - * \brief Creates a node position in volume - */ - //================================================================================ - - inline SMDS_PositionPtr volumePosition(int volId) - { - SMDS_SpacePosition* pos = new SMDS_SpacePosition(); - pos->SetShapeId( volId ); - return SMDS_PositionPtr(pos); - } -} - //======================================================================= //function : SetNodeOnVolume //purpose : @@ -906,8 +1074,9 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition ( volumePosition( myCurSubID )); + aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() ); } + //======================================================================= //function : SetNodeOnVolume //purpose : @@ -916,7 +1085,7 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Solid & S) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition ( volumePosition( myCurSubID )); + aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() ); } //======================================================================= @@ -929,7 +1098,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode, double v) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v))); } //======================================================================= @@ -941,7 +1110,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode, double u) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u))); } //======================================================================= @@ -952,7 +1121,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S) { if ( add( aNode, getSubmesh(S) )) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition())); } //======================================================================= @@ -961,12 +1130,13 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode, //======================================================================= void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode) { - if ( aNode && aNode->GetPosition() ) { - map::iterator it = - myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() ); - if ( it != myShapeIndexToSubMesh.end() ) - it->second->RemoveNode( aNode ); - } + int shapeId = aNode->getshapeId(); + if (shapeId >= 0) + { + map::iterator it = myShapeIndexToSubMesh.find(shapeId); + if (it != myShapeIndexToSubMesh.end()) + it->second->RemoveNode(aNode, /*deleted=*/false); + } } //======================================================================= @@ -990,10 +1160,12 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, map::iterator it = myShapeIndexToSubMesh.find( Index ); if ( it != myShapeIndexToSubMesh.end() ) - if ( elem->GetType() == SMDSAbs_Node ) - it->second->RemoveNode( static_cast( elem )); - else - it->second->RemoveElement( elem ); + { + if (elem->GetType() == SMDSAbs_Node) + it->second->RemoveNode(static_cast (elem), /*deleted=*/false); + else + it->second->RemoveElement(elem, /*deleted=*/false); + } } //======================================================================= @@ -1002,26 +1174,24 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem, //======================================================================= TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const { - return myShape; + return myShape; } //======================================================================= //function : IsGroupOfSubShapes -//purpose : return true if at least one subshape of theShape is a subshape +//purpose : return true if at least one sub-shape of theShape is a sub-shape // of myShape or theShape == myShape //======================================================================= bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const { - if ( myShape.IsSame( theShape )) + if ( myIndexToShape.Contains(theShape) ) return true; - for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) { - if (myIndexToShape.Contains( it.Value() ) || - IsGroupOfSubShapes( it.Value() )) + for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) + if (IsGroupOfSubShapes( it.Value() )) return true; - } - + return false; } @@ -1042,7 +1212,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const /////////////////////////////////////////////////////////////////////////////// /// Return the sub mesh by Id of shape it is linked to /////////////////////////////////////////////////////////////////////////////// -SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) +SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const { TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index); if (anIter != myShapeIndexToSubMesh.end()) @@ -1055,10 +1225,10 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) //function : SubMeshIndices //purpose : //======================================================================= -list SMESHDS_Mesh::SubMeshIndices() +list SMESHDS_Mesh::SubMeshIndices() const { list anIndices; - std::map::iterator anIter = myShapeIndexToSubMesh.begin(); + std::map::const_iterator anIter = myShapeIndexToSubMesh.begin(); for (; anIter != myShapeIndexToSubMesh.end(); anIter++) { anIndices.push_back((*anIter).first); } @@ -1080,13 +1250,28 @@ SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const return empty; } +//================================================================================ +/*! + * \brief returns true if the hypothesis is assigned to any sub-shape + */ +//================================================================================ + +bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const +{ + ShapeToHypothesis::Iterator s2h( myShapeToHypothesis ); + for ( ; s2h.More(); s2h.Next() ) + if ( std::find( s2h.Value().begin(), s2h.Value().end(), H ) != s2h.Value().end() ) + return true; + return false; +} + //======================================================================= //function : GetScript //purpose : //======================================================================= SMESHDS_Script* SMESHDS_Mesh::GetScript() { - return myScript; + return myScript; } //======================================================================= @@ -1095,18 +1280,18 @@ SMESHDS_Script* SMESHDS_Mesh::GetScript() //======================================================================= void SMESHDS_Mesh::ClearScript() { - myScript->Clear(); + myScript->Clear(); } //======================================================================= //function : HasMeshElements //purpose : //======================================================================= -bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) +bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const { - if (myShape.IsNull()) MESSAGE("myShape is NULL"); - int Index = myIndexToShape.FindIndex(S); - return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end(); + if (myShape.IsNull()) MESSAGE("myShape is NULL"); + int Index = myIndexToShape.FindIndex(S); + return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end(); } //======================================================================= @@ -1128,7 +1313,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index) TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index); if (anIter == myShapeIndexToSubMesh.end()) { - SM = new SMESHDS_SubMesh(); + SM = new SMESHDS_SubMesh(this, Index); myShapeIndexToSubMesh[Index]=SM; } else @@ -1145,7 +1330,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, TopAbs_ShapeEnum type) { int aMainIndex = 0; - if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) ) + if ( IsGroupOfSubShapes( S )) { aMainIndex = myIndexToShape.Add( S ); bool all = ( type == TopAbs_SHAPE ); @@ -1155,7 +1340,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex ); if ( !aNewSub->IsComplexSubmesh() ) // is empty { - int shapeType = all ? myShape.ShapeType() : type; + int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type ); int typeLimit = all ? TopAbs_VERTEX : type; for ( ; shapeType <= typeLimit; shapeType++ ) { @@ -1178,7 +1363,26 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, //======================================================================= const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const { - return myIndexToShape.FindKey(ShapeIndex); + try + { + return myIndexToShape.FindKey(ShapeIndex); + } + catch ( Standard_OutOfRange ) + { + } + static TopoDS_Shape nullShape; + return nullShape; +} + +//================================================================================ +/*! + * \brief Return max index of sub-mesh + */ +//================================================================================ + +int SMESHDS_Mesh::MaxSubMeshIndex() const +{ + return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first; } //======================================================================= @@ -1201,8 +1405,9 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const //======================================================================= void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index) { + //add(aNode, getSubmesh(Index)); if ( add( aNode, getSubmesh( Index ))) - ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index )); + ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition()); } //======================================================================= @@ -1213,7 +1418,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, doub { //Set Position on Node if ( add( aNode, getSubmesh( Index ))) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v))); } //======================================================================= @@ -1226,7 +1431,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode, { //Set Position on Node if ( add( aNode, getSubmesh( Index ))) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u))); } //======================================================================= @@ -1237,7 +1442,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index) { //Set Position on Node if ( add( aNode, getSubmesh( Index ))) - aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index))); + aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition())); } //======================================================================= @@ -1294,8 +1499,8 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1, { SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12); if(anElem) myScript->AddEdge(anElem->GetID(), - n1->GetID(), - n2->GetID(), + n1->GetID(), + n2->GetID(), n12->GetID()); return anElem; } @@ -1310,9 +1515,9 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, int ID) { return AddEdgeWithID(n1->GetID(), - n2->GetID(), + n2->GetID(), n12->GetID(), - ID); + ID); } @@ -1329,7 +1534,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31); if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), n2->GetID(), n3->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n12->GetID(), n23->GetID(), n31->GetID()); return anElem; } @@ -1360,7 +1565,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n12->GetID(), n23->GetID(), n31->GetID(), - ID); + ID); } @@ -1379,7 +1584,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, { SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41); if(anElem) myScript->AddFace(anElem->GetID(), - n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID()); return anElem; } @@ -1412,7 +1617,63 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, { return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), - ID); + ID); +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41,nCenter); + if(anElem) myScript->AddFace(anElem->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + nCenter->GetID()); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, + int nCenter, int ID) +{ + SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,ID); + if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41,nCenter); + return anElem; +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, + int ID) +{ + return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + nCenter->GetID(), ID); } @@ -1433,8 +1694,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, { SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); if(anElem) myScript->AddVolume(anElem->GetID(), - n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), - n12->GetID(), n23->GetID(), n31->GetID(), + n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n12->GetID(), n23->GetID(), n31->GetID(), n14->GetID(), n24->GetID(), n34->GetID()); return anElem; } @@ -1452,7 +1713,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order tetrahedron of 10 nodes @@ -1518,7 +1779,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i n15,n25,n35,n45); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order pyramid of 13 nodes @@ -1595,7 +1856,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, n45,n56,n64,n14,n25,n36); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order Pentahedron with 15 nodes @@ -1628,7 +1889,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //======================================================================= //function : AddVolume -//purpose : +//purpose : add quadratic hexahedron //======================================================================= SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, @@ -1683,7 +1944,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, n56,n67,n78,n85,n15,n26,n37,n48); return anElem; } - + //======================================================================= //function : AddVolumeWithID //purpose : 2d order Hexahedrons with 20 nodes @@ -1718,4 +1979,293 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, ID); } +//======================================================================= +//function : AddVolume +//purpose : add tri-quadratic hexahedron of 27 nodes +//======================================================================= + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8, + n12,n23,n34,n41, + n56,n67,n78,n85, + n15,n26,n37,n48, + n1234,n1256,n2367,n3478,n1458,n5678,nCenter); + if(anElem) + myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(), + n3->GetID(), n4->GetID(), n5->GetID(), + n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(), + n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(), + n1458->GetID(),n5678->GetID(),nCenter->GetID()); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter, + int ID) +{ + SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8, + n12,n23,n34,n41, + n56,n67,n78,n85, + n15,n26,n37,n48, + n1234, n1256, n2367, n3478, + n1458, n5678, nCenter, + ID); + if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, + n56,n67,n78,n85,n15,n26,n37,n48, + n1234, n1256, n2367, n3478, + n1458, n5678, nCenter); + return anElem; +} + +SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter, + int ID) +{ + return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(), + n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(), + n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(), + n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(), + n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(), + n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(), + n1458->GetID(),n5678->GetID(),nCenter->GetID(), ID); +} + +void SMESHDS_Mesh::compactMesh() +{ + int newNodeSize = 0; + int nbNodes = myNodes.size(); + int nbVtkNodes = myGrid->GetNumberOfPoints(); + MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes); + int nbNodeTemp = nbVtkNodes; + if (nbNodes > nbVtkNodes) + nbNodeTemp = nbNodes; + vector idNodesOldToNew; + idNodesOldToNew.clear(); + idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1 + + for (int i = 0; i < nbNodes; i++) + { + if (myNodes[i]) + { + int vtkid = myNodes[i]->getVtkId(); + idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0) + newNodeSize++; + } + } + bool areNodesModified = (newNodeSize < nbVtkNodes); + MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified); + areNodesModified = true; + + int newCellSize = 0; + int nbCells = myCells.size(); + int nbVtkCells = myGrid->GetNumberOfCells(); + MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells); + int nbCellTemp = nbVtkCells; + if (nbCells > nbVtkCells) + nbCellTemp = nbCells; + vector idCellsOldToNew; + idCellsOldToNew.clear(); + idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1 + + for (int i = 0; i < nbCells; i++) + { + if (myCells[i]) + { +// //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0 +// int vtkid = myCells[i]->getVtkId(); +// idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input) + newCellSize++; + } + } + if (areNodesModified) + myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize); + else + myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize); + + int nbVtkPts = myGrid->GetNumberOfPoints(); + nbVtkCells = myGrid->GetNumberOfCells(); + if (nbVtkPts != newNodeSize) + { + MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize); + if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id + } + if (nbVtkCells != newCellSize) + { + MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize); + if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id + } + + // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory + + if (areNodesModified) + { + MESSAGE("-------------- modify myNodes"); + SetOfNodes newNodes; + newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n + int newSmdsId = 0; + for (int i = 0; i < nbNodes; i++) + { + if (myNodes[i]) + { + newSmdsId++; // SMDS id start to 1 + int oldVtkId = myNodes[i]->getVtkId(); + int newVtkId = idNodesOldToNew[oldVtkId]; + //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId); + myNodes[i]->setVtkId(newVtkId); + myNodes[i]->setId(newSmdsId); + newNodes[newSmdsId] = myNodes[i]; + //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]"); + } + } + myNodes.swap(newNodes); + this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes + MESSAGE("myNodes.size " << myNodes.size()); + } + + // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells + + int vtkIndexSize = myCellIdVtkToSmds.size(); + int maxVtkId = -1; + for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++) + { + int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId]; + if (oldSmdsId > 0) + { + int newVtkId = idCellsOldToNew[oldVtkId]; + if (newVtkId > maxVtkId) + maxVtkId = newVtkId; + //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId); + myCells[oldSmdsId]->setVtkId(newVtkId); + } + } +// MESSAGE("myCells.size()=" << myCells.size() +// << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size() +// << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() ); + + SetOfCells newCells; + //vector newSmdsToVtk; + vector newVtkToSmds; + + assert(maxVtkId < newCellSize); + newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n + //newSmdsToVtk.resize(newCellSize+1, -1); + newVtkToSmds.resize(newCellSize+1, -1); + + int myCellsSize = myCells.size(); + int newSmdsId = 0; + for (int i = 0; i < myCellsSize; i++) + { + if (myCells[i]) + { + newSmdsId++; // SMDS id start to 1 + assert(newSmdsId <= newCellSize); + newCells[newSmdsId] = myCells[i]; + newCells[newSmdsId]->setId(newSmdsId); + //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]"); + int idvtk = myCells[i]->getVtkId(); + //newSmdsToVtk[newSmdsId] = idvtk; + assert(idvtk < newCellSize); + newVtkToSmds[idvtk] = newSmdsId; + } + } + + myCells.swap(newCells); + //myCellIdSmdsToVtk.swap(newSmdsToVtk); + myCellIdVtkToSmds.swap(newVtkToSmds); + MESSAGE("myCells.size()=" << myCells.size() + << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() ); + this->myElementIDFactory->emptyPool(newSmdsId); + + this->myScript->SetModified(true); // notify GUI client for buildPrs when update + + // --- compact list myNodes and myElements in submeshes + + map::iterator it = myShapeIndexToSubMesh.begin(); + for(; it != myShapeIndexToSubMesh.end(); ++it) + { + (*it).second->compactList(); + } + +} + +void SMESHDS_Mesh::CleanDownWardConnectivity() +{ + myGrid->CleanDownwardConnectivity(); +} +void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges) +{ + myGrid->BuildDownwardConnectivity(withEdges); +} + +/*! change some nodes in cell without modifying type or internal connectivity. + * Nodes inverse connectivity is maintained up to date. + * @param vtkVolId vtk id of the cell. + * @param localClonedNodeIds map old node id to new node id. + * @return ok if success. + */ +bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds) +{ + myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds); + return true; +} diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index d3df2e688..573e06b91 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Mesh.hxx // Module : SMESH @@ -29,36 +30,43 @@ #include "SMESH_SMESHDS.hxx" #include "SMDS_Mesh.hxx" -#include "SMDS_MeshNode.hxx" -#include "SMDS_MeshEdge.hxx" -#include "SMDS_MeshFace.hxx" -#include "SMDS_MeshVolume.hxx" -#include "SMESHDS_Hypothesis.hxx" #include "SMESHDS_SubMesh.hxx" -#include "SMESHDS_Script.hxx" #include #include -#include -#include -#include -#include -#include + +class TopoDS_Solid ; +class TopoDS_Shell ; +class TopoDS_Face ; +class TopoDS_Vertex; +class TopoDS_Edge ; + +class SMESHDS_Script; +class SMESHDS_Hypothesis; +class SMDS_MeshNode ; +class SMDS_MeshEdge ; +class SMDS_MeshFace ; +class SMDS_MeshVolume ; +class SMDS_Mesh0DElement; +class SMDS_BallElement; #include #include /* - * Using of native haah_map isn't portable and don't work on WIN32 platform. + * Using of native hash_map isn't portable and don't work on WIN32 platform. * So this functionality implement on new NCollection_DataMap technology */ #include "SMESHDS_DataMapOfShape.hxx" class SMESHDS_GroupBase; +class DownIdType; class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{ public: SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode); bool IsEmbeddedMode(); + void SetPersistentId(int id); + int GetPersistentId() const; void ShapeToMesh(const TopoDS_Shape & S); TopoDS_Shape ShapeToMesh() const; @@ -66,160 +74,219 @@ public: bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H); virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID); - virtual SMDS_MeshNode * AddNode(double x, double y, double z); + virtual SMDS_MeshNode* AddNode(double x, double y, double z); + virtual SMDS_Mesh0DElement* Add0DElementWithID(int nodeID, int ID); + virtual SMDS_Mesh0DElement* Add0DElementWithID(const SMDS_MeshNode * node, int ID); + virtual SMDS_Mesh0DElement* Add0DElement (const SMDS_MeshNode * node); + + virtual SMDS_BallElement* AddBallWithID(int n, double diameter, int ID); + virtual SMDS_BallElement* AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID); + virtual SMDS_BallElement* AddBall (const SMDS_MeshNode * n, double diameter); + virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID); virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - int ID); + const SMDS_MeshNode * n2, + int ID); virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2); + const SMDS_MeshNode * n2); // 2d order edge with 3 nodes: n12 - node between n1 and n2 virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID); virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n12, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID); virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, const SMDS_MeshNode * n12); - + // tria 3 virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3); + // quad 4 virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); // 2d order triangle of 6 nodes virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n12,int n23,int n31, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31); + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31); // 2d order quadrangle virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n34,int n41, int ID); virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID); virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41); + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41); + // bi-quadratic quadrangle of 9 nodes + virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int nCenter, int ID); + virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter, + int ID); + virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * nCenter); + // tetra 4 virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4); + // pyra 5 virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5); + // penta 6 virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6); + // hexa 8 virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8); - + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8); + // hexagonal prism of 12 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, + int n7, int n8, int n9, int n10, int n11, int n12, int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12); + // 2d order tetrahedron of 10 nodes virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n12,int n23,int n31, int n14,int n24,int n34, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - const SMDS_MeshNode * n14, - const SMDS_MeshNode * n24, - const SMDS_MeshNode * n34, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, @@ -233,24 +300,24 @@ public: int n15,int n25,int n35,int n45, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - const SMDS_MeshNode * n15, - const SMDS_MeshNode * n25, - const SMDS_MeshNode * n35, - const SMDS_MeshNode * n45, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, @@ -268,27 +335,27 @@ public: int n14,int n25,int n36, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n31, - const SMDS_MeshNode * n45, - const SMDS_MeshNode * n56, - const SMDS_MeshNode * n64, - const SMDS_MeshNode * n14, - const SMDS_MeshNode * n25, - const SMDS_MeshNode * n36, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n31, @@ -307,34 +374,34 @@ public: int n15,int n26,int n37,int n48, int ID); virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, - const SMDS_MeshNode * n12, - const SMDS_MeshNode * n23, - const SMDS_MeshNode * n34, - const SMDS_MeshNode * n41, - const SMDS_MeshNode * n56, - const SMDS_MeshNode * n67, - const SMDS_MeshNode * n78, - const SMDS_MeshNode * n85, - const SMDS_MeshNode * n15, - const SMDS_MeshNode * n26, - const SMDS_MeshNode * n37, - const SMDS_MeshNode * n48, - int ID); + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID); virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, - const SMDS_MeshNode * n2, - const SMDS_MeshNode * n3, - const SMDS_MeshNode * n4, - const SMDS_MeshNode * n5, - const SMDS_MeshNode * n6, - const SMDS_MeshNode * n7, - const SMDS_MeshNode * n8, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, const SMDS_MeshNode * n12, const SMDS_MeshNode * n23, const SMDS_MeshNode * n34, @@ -348,27 +415,92 @@ public: const SMDS_MeshNode * n37, const SMDS_MeshNode * n48); - virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, - const int ID); + // 2d order Hexahedrons with 27 nodes + virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter, + int ID); + virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter, + int ID); + virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter); + + virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector& nodes_ids, + const int ID); - virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes, - const int ID); + virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector& nodes, + const int ID); - virtual SMDS_MeshFace* AddPolygonalFace (std::vector nodes); + virtual SMDS_MeshFace* AddPolygonalFace (const std::vector& nodes); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (std::vector nodes_ids, - std::vector quantities, - const int ID); + (const std::vector& nodes_ids, + const std::vector& quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (std::vector nodes, - std::vector quantities, - const int ID); + (const std::vector& nodes, + const std::vector& quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolume - (std::vector nodes, - std::vector quantities); + (const std::vector& nodes, + const std::vector& quantities); void MoveNode(const SMDS_MeshNode *, double x, double y, double z); virtual void RemoveNode(const SMDS_MeshNode *); @@ -391,6 +523,7 @@ public: bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, std::vector nodes, std::vector quantities); + bool ModifyCellNodes(int smdsVolId, std::map localClonedNodeIds); void Renumber (const bool isNodes, const int startID=1, const int deltaID=1); void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S); @@ -400,23 +533,25 @@ public: void SetNodeOnVertex(SMDS_MeshNode * aNode, const TopoDS_Vertex & S); void UnSetNodeOnShape(const SMDS_MeshNode * aNode); void SetMeshElementOnShape(const SMDS_MeshElement * anElt, - const TopoDS_Shape & S); + const TopoDS_Shape & S); void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt, - const TopoDS_Shape & S); - bool HasMeshElements(const TopoDS_Shape & S); + const TopoDS_Shape & S); + bool HasMeshElements(const TopoDS_Shape & S) const; SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S) const; - SMESHDS_SubMesh * MeshElements(const int Index); - std::list SubMeshIndices(); + SMESHDS_SubMesh * MeshElements(const int Index) const; + std::list SubMeshIndices() const; const std::map& SubMeshes() const { return myShapeIndexToSubMesh; } bool HasHypothesis(const TopoDS_Shape & S); const std::list& GetHypothesis(const TopoDS_Shape & S) const; + bool IsUsedHypothesis(const SMESHDS_Hypothesis * H) const; SMESHDS_Script * GetScript(); void ClearScript(); int ShapeToIndex(const TopoDS_Shape & aShape) const; const TopoDS_Shape& IndexToShape(int ShapeIndex) const; int MaxShapeIndex() const { return myIndexToShape.Extent(); } + int MaxSubMeshIndex() const; SMESHDS_SubMesh * NewSubMesh(int Index); int AddCompoundSubmesh(const TopoDS_Shape& S, TopAbs_ShapeEnum type = TopAbs_SHAPE); @@ -426,6 +561,7 @@ public: void SetNodeOnVertex(SMDS_MeshNode * aNode, int Index); void SetMeshElementOnShape(const SMDS_MeshElement * anElt, int Index); + // Groups. SMESHDS_Mesh is not an owner of groups void AddGroup (SMESHDS_GroupBase* theGroup) { myGroups.insert(theGroup); } void RemoveGroup (SMESHDS_GroupBase* theGroup) { myGroups.erase(theGroup); } int GetNbGroups() const { return myGroups.size(); } @@ -433,6 +569,10 @@ public: bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const; + virtual void compactMesh(); + void CleanDownWardConnectivity(); + void BuildDownWardConnectivity(bool withEdges); + ~SMESHDS_Mesh(); private: @@ -441,9 +581,9 @@ private: //Update or build submesh std::map::iterator it = myShapeIndexToSubMesh.find( Index ); if ( it == myShapeIndexToSubMesh.end() ) - it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh() )).first; + it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first; it->second->AddNode( aNode ); // add aNode to submesh - } + } /*int HashCode( const TopoDS_Shape& S, const Standard_Integer theUpper ) const { @@ -456,7 +596,7 @@ private: ShapeToHypothesis myShapeToHypothesis; - int myMeshID; + int myMeshID, myPersistentID; TopoDS_Shape myShape; typedef std::map TShapeIndexToSubMesh; diff --git a/src/SMESHDS/SMESHDS_Script.cxx b/src/SMESHDS/SMESHDS_Script.cxx index 9b6daa8b1..b4ec13f7c 100644 --- a/src/SMESHDS/SMESHDS_Script.cxx +++ b/src/SMESHDS/SMESHDS_Script.cxx @@ -1,31 +1,32 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESH_Script.cxx // Author : Yves FRICAUD, OCC // Module : SMESH -// $Header: // #include "SMESHDS_Script.hxx" +#include using namespace std; @@ -35,7 +36,9 @@ using namespace std; //======================================================================= SMESHDS_Script::SMESHDS_Script(bool theIsEmbeddedMode): myIsEmbeddedMode(theIsEmbeddedMode) -{} +{ + //cerr << "=========================== myIsEmbeddedMode " << myIsEmbeddedMode << endl; +} //======================================================================= //function : Destructor @@ -95,6 +98,19 @@ void SMESHDS_Script::AddNode(int NewNodeID, double x, double y, double z) getCommand(SMESHDS_AddNode)->AddNode(NewNodeID, x, y, z); } +//======================================================================= +//function : +//purpose : +//======================================================================= +void SMESHDS_Script::Add0DElement (int New0DElementID, int idnode) +{ + if (myIsEmbeddedMode) { + myIsModified = true; + return; + } + getCommand(SMESHDS_Add0DElement)->Add0DElement(New0DElementID, idnode); +} + //======================================================================= //function : //purpose : @@ -208,11 +224,29 @@ void SMESHDS_Script::AddVolume(int NewID, idnode5, idnode6, idnode7, idnode8); } +//======================================================================= +//function : +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6, int idnode7, int idnode8, + int idnode9, int idnode10, int idnode11, int idnode12) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddHexagonalPrism)->AddVolume(NewVolID, + idnode1, idnode2, idnode3, idnode4, + idnode5, idnode6, idnode7, idnode8, + idnode9, idnode10, idnode11, idnode12); +} + //======================================================================= //function : AddPolygonalFace //purpose : //======================================================================= -void SMESHDS_Script::AddPolygonalFace (int NewFaceID, std::vector nodes_ids) +void SMESHDS_Script::AddPolygonalFace (int NewFaceID, const std::vector& nodes_ids) { if(myIsEmbeddedMode){ myIsModified = true; @@ -225,9 +259,9 @@ void SMESHDS_Script::AddPolygonalFace (int NewFaceID, std::vector nodes_ids //function : AddPolyhedralVolume //purpose : //======================================================================= -void SMESHDS_Script::AddPolyhedralVolume (int NewID, - std::vector nodes_ids, - std::vector quantities) +void SMESHDS_Script::AddPolyhedralVolume (int NewID, + const std::vector& nodes_ids, + const std::vector& quantities) { if(myIsEmbeddedMode){ myIsModified = true; @@ -237,6 +271,19 @@ void SMESHDS_Script::AddPolyhedralVolume (int NewID, (NewID, nodes_ids, quantities); } +//======================================================================= +//function : AddBall +//purpose : Record adding a Ball +//======================================================================= + +void SMESHDS_Script::AddBall(int NewBallID, int node, double diameter) +{ + if ( myIsEmbeddedMode ) + myIsModified = true; + else + getCommand(SMESHDS_AddBall)->AddBall(NewBallID, node, diameter); +} + //======================================================================= //function : //purpose : @@ -294,9 +341,9 @@ void SMESHDS_Script::ChangeElementNodes(int ElementID, int nodes[], int nbnodes) //function : ChangePolyhedronNodes //purpose : //======================================================================= -void SMESHDS_Script::ChangePolyhedronNodes (const int ElementID, - std::vector nodes_ids, - std::vector quantities) +void SMESHDS_Script::ChangePolyhedronNodes (const int ElementID, + const std::vector& nodes_ids, + const std::vector& quantities) { if(myIsEmbeddedMode){ myIsModified = true; @@ -403,6 +450,21 @@ void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4, n12, n23, n34, n41); } +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41, int nCenter) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddBiQuadQuadrangle)->AddFace(NewFaceID, n1, n2, n3, n4, + n12, n23, n34, n41, nCenter); +} + //======================================================================= //function : AddVolume //purpose : @@ -477,3 +539,28 @@ void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, n15, n26, n37, n48); } +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3, + int n4, int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter) +{ + if(myIsEmbeddedMode){ + myIsModified = true; + return; + } + getCommand(SMESHDS_AddTriQuadHexa)->AddVolume(NewVolID, n1, n2, n3, n4, + n5, n6, n7, n8, + n12, n23, n34, n41, + n56, n67, n78, n85, + n15, n26, n37, n48, + n1234, n1256, n2367, n3478, + n1458, n5678, nCenter); +} + diff --git a/src/SMESHDS/SMESHDS_Script.hxx b/src/SMESHDS/SMESHDS_Script.hxx index 808066bc3..8bd3fc579 100644 --- a/src/SMESHDS/SMESHDS_Script.hxx +++ b/src/SMESHDS/SMESHDS_Script.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_Script.hxx // Module : SMESH @@ -37,38 +38,45 @@ class SMESHDS_EXPORT SMESHDS_Script { public: - SMESHDS_Script(bool theIsEmbeddedMode); - ~SMESHDS_Script(); + SMESHDS_Script(bool theIsEmbeddedMode); + ~SMESHDS_Script(); void SetModified(bool theModified); bool IsModified(); - void AddNode(int NewNodeID, double x, double y, double z); - void AddEdge(int NewEdgeID, int idnode1, int idnode2); - void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3); - void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3, - int idnode4); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4, int idnode5); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4, int idnode5, int idnode6); - void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, - int idnode4, int idnode5, int idnode6, int idnode7, int idnode8); + void AddNode(int NewNodeID, double x, double y, double z); + void Add0DElement(int New0DElementID, int idnode); + void AddEdge(int NewEdgeID, int idnode1, int idnode2); + void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3); + void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3, + int idnode4); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6, int idnode7, int idnode8); + void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3, + int idnode4, int idnode5, int idnode6, int idnode7, int idnode8, + int idnode9, int idnode10, int idnode11, int idnode12); - void AddPolygonalFace (const int NewFaceID, - std::vector nodes_ids); - void AddPolyhedralVolume (const int NewVolID, - std::vector nodes_ids, - std::vector quantities); + void AddPolygonalFace (const int NewFaceID, + const std::vector& nodes_ids); + void AddPolyhedralVolume (const int NewVolID, + const std::vector& nodes_ids, + const std::vector& quantities); + void AddBall(int NewBallID, int node, double diameter); // special methods for quadratic elements - void AddEdge(int NewEdgeID, int n1, int n2, int n12); + void AddEdge(int NewEdgeID, int n1, int n2, int n12); void AddFace(int NewFaceID, int n1, int n2, int n3, int n12, int n23, int n31); void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, int n12, int n23, int n34, int n41); + void AddFace(int NewFaceID, int n1, int n2, int n3, int n4, + int n12, int n23, int n34, int n41, int nCenter); void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n12, int n23, int n31, int n14, int n24, int n34); void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5, @@ -84,22 +92,29 @@ class SMESHDS_EXPORT SMESHDS_Script int n12, int n23, int n34, int n41, int n56, int n67, int n78, int n85, int n15, int n26, int n37, int n48); + void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12, int n23, int n34, int n41, + int n56, int n67, int n78, int n85, + int n15, int n26, int n37, int n48, + int n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter); void MoveNode(int NewNodeID, double x, double y, double z); - void RemoveNode(int NodeID); - void RemoveElement(int ElementID); - void ChangeElementNodes(int ElementID, int nodes[], int nbnodes); - void ChangePolyhedronNodes(const int ElementID, - std::vector nodes_ids, - std::vector quantities); - void Renumber (const bool isNodes, const int startID, const int deltaID); - void ClearMesh(); - void Clear(); - const std::list & GetCommands(); + void RemoveNode(int NodeID); + void RemoveElement(int ElementID); + void ChangeElementNodes(int ElementID, int nodes[], int nbnodes); + void ChangePolyhedronNodes(const int ElementID, + const std::vector& nodes_ids, + const std::vector& quantities); + void Renumber (const bool isNodes, const int startID, const int deltaID); + void ClearMesh(); + void Clear(); + const std::list & GetCommands(); private: - SMESHDS_Command* getCommand(const SMESHDS_CommandType aType); + SMESHDS_Command* getCommand(const SMESHDS_CommandType aType); - std::list myCommands; + std::list myCommands; bool myIsEmbeddedMode; bool myIsModified; diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx index 127c5c2d9..32073bb50 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.cxx +++ b/src/SMESHDS/SMESHDS_SubMesh.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESH_SubMesh.cxx // Author : Yves FRICAUD, OCC @@ -26,31 +27,127 @@ // $Header: // #include "SMESHDS_SubMesh.hxx" +#include "SMESHDS_Mesh.hxx" #include "utilities.h" #include "SMDS_SetIterator.hxx" +#include +#include using namespace std; + +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + +SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index) +{ + myParent = parent; + myElements.clear(); + myNodes.clear(); + myIndex = index; + myUnusedIdNodes = 0; + myUnusedIdElements = 0; +} + +//================================================================================ +/*! + * \brief Destructor + */ +//================================================================================ + +SMESHDS_SubMesh::~SMESHDS_SubMesh() +{ +} + //======================================================================= //function : AddElement //purpose : //======================================================================= void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME) { - if ( !IsComplexSubmesh() ) - myElements.insert(ME); + if (!IsComplexSubmesh()) + { + if ( ME->GetType() == SMDSAbs_Node ) + { + AddNode( static_cast< const SMDS_MeshNode* >( ME )); + return; + } + //MESSAGE("in " << myIndex << " AddElement "<< ME->GetID()); + int oldShapeId = ME->getshapeId(); + if ( oldShapeId > 0 ) + { + if (oldShapeId != myIndex) + { + MESSAGE("add element in subshape already belonging to another subshape " + << ME->GetID() << " " << oldShapeId << " " << myIndex); + throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape")); + } + else + { + int idInSubShape = ME->getIdInShape(); + if (idInSubShape >= 0) + { + MESSAGE("add element in subshape already belonging to that subshape " + << ME->GetID() << " " << oldShapeId << " " << idInSubShape); + // check if ok: do nothing if ok + if (idInSubShape >= myElements.size()) + { + MESSAGE("out of bounds " << idInSubShape << " " << myElements.size()); + throw SALOME_Exception(LOCALIZED("out of bounds")); + } + if (ME != myElements[idInSubShape]) + { + MESSAGE("not the same element"); + throw SALOME_Exception(LOCALIZED("not the same element")); + } + MESSAGE("already done, OK, nothing to do"); + return; + } + } + } + + SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); + elem->setShapeId(myIndex); + elem->setIdInShape(myElements.size()); + myElements.push_back(ME); + } } //======================================================================= //function : RemoveElement //purpose : //======================================================================= -bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME) +bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted) { - if ( !IsComplexSubmesh() && NbElements() ) - return myElements.erase(ME); - + if (!ME) + { + MESSAGE("-----------------> Remove Null Element " << isElemDeleted); + return false; + } + //MESSAGE("-----------------> RemoveElement "<< ME->GetID() << " " << isElemDeleted); + if (!IsComplexSubmesh()) + { + if ( ME->getshapeId() != myIndex ) + return false; + int idInSubShape = ME->getIdInShape(); + //MESSAGE("in "<< myIndex << " RemoveElement " << ME->GetID() << " " << idInSubShape << " " << myUnusedIdElements); + SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); + elem->setShapeId(0); + elem->setIdInShape(-1); + if ((idInSubShape >= 0) && (idInSubShape < myElements.size())) + { + myElements[idInSubShape] = 0; // this vector entry is no more used + myUnusedIdElements++; + return true; + } + return false; + // } + } + MESSAGE("Try to remove an element from a complex submesh "); return false; } @@ -61,7 +158,22 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME) void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) { if ( !IsComplexSubmesh() ) - myNodes.insert(N); + { + int idInSubShape = N->getIdInShape(); + int shapeId = N->getshapeId(); + if ((shapeId > 0) && (idInSubShape >= 0)) + { +// MESSAGE("========== AddNode already belonging to other subShape " << N->GetID()); + // OK for vertex nodes + throw SALOME_Exception(LOCALIZED("add node in subshape already belonging to a subshape")); + } + SMDS_MeshNode* node = (SMDS_MeshNode*)(N); + node->setShapeId(myIndex); + node->setIdInShape(myNodes.size()); + myNodes.push_back(N); + //MESSAGE("in "<< myIndex << " AddNode " << node->GetID()); + } + //MESSAGE("try to add node in a complex submesh " << N->GetID()); } //======================================================================= @@ -69,11 +181,30 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N) //purpose : //======================================================================= -bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) +bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted) { - if ( !IsComplexSubmesh() && NbNodes() ) - return myNodes.erase(N); - + if (!IsComplexSubmesh()) + { + // if (!isNodeDeleted) // alive node has valid ID and can be found + // { + if ( N->getshapeId() != myIndex ) + return false; + int idInSubShape = N->getIdInShape(); + //int shapeId = N->getshapeId(); + //MESSAGE("in "<< myIndex << " RemoveNode " << shapeId << " " << idInSubShape << " " << N->GetID()); + SMDS_MeshNode* node = (SMDS_MeshNode*) (N); + node->setShapeId(0); + node->setIdInShape(-1); + if ((idInSubShape >= 0) && (idInSubShape < myNodes.size())) + { + myNodes[idInSubShape] = 0; // this vector entry is no more used + myUnusedIdNodes++; + return true; + } + return false; + // } + } + MESSAGE("Try to remove a node from a complex submesh"); return false; } @@ -83,15 +214,12 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N) //======================================================================= int SMESHDS_SubMesh::NbElements() const { + //MESSAGE(this << " NbElements " << IsComplexSubmesh() << " " << myElements.size() - myUnusedIdElements); if ( !IsComplexSubmesh() ) - return myElements.size(); + return myElements.size() - myUnusedIdElements; int nbElems = 0; -#ifndef WNT - set::iterator it = mySubMeshes.begin(); -#else set::const_iterator it = mySubMeshes.begin(); -#endif for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbElements(); @@ -105,46 +233,53 @@ int SMESHDS_SubMesh::NbElements() const int SMESHDS_SubMesh::NbNodes() const { - if ( !IsComplexSubmesh() ) - return myNodes.size(); + //MESSAGE(this << " NbNodes " << IsComplexSubmesh() << " " << myNodes.size() - myUnusedIdNodes); + if ( !IsComplexSubmesh() ) + return myNodes.size() - myUnusedIdNodes; int nbElems = 0; -#ifndef WNT - set::iterator it = mySubMeshes.begin(); -#else set::const_iterator it = mySubMeshes.begin(); -#endif for ( ; it != mySubMeshes.end(); it++ ) nbElems += (*it)->NbNodes(); return nbElems; } -// ===================== -// class MySetIterator -// ===================== - -template class MySetIterator:public SMDS_Iterator +/*! + * template class used for iteration on submesh elements. Interface of iterator remains + * unchanged after redesign of SMDS to avoid modification everywhere in SMESH. + * instances are stored in shared_ptr for automatic destruction. + * Container is copied for iteration, because original can be modified + * by addition of elements, for instance, and then reallocated (vector) + */ +template class MySetIterator : public SMDS_Iterator { - typedef const set TSet; - typename TSet::const_iterator myIt; - TSet& mySet; - - public: - MySetIterator(const set& s):mySet(s), myIt(s.begin()) - { - } - - bool more() - { - return myIt!=mySet.end(); - } - const T* next() - { - const T* t=*myIt; - myIt++; - return t; - } +protected: + typename TSET::const_iterator _it, _end; + TSET _table; +public: + MySetIterator(const TSET& table) + { + _table = table; + _it = _table.begin(); + _end = _table.end(); + while ((_it != _end) && (*_it == 0)) + _it++; + } + + virtual bool more() + { + while ((_it != _end) && (*_it == 0)) + _it++; + return (_it != _end); + } + + virtual ELEM next() + { + ELEM e = *_it; + _it++; + return e; + } }; // ===================== @@ -155,12 +290,11 @@ template class MyIterator : public SMDS_Iterator { public: MyIterator (const set& theSubMeshes) - : mySubMeshes( theSubMeshes ), mySubIt( theSubMeshes.begin() ), myMore(false) + : mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ), myMore(false) {} bool more() { - while (( !myElemIt.get() || !myElemIt->more() ) && - mySubIt != mySubMeshes.end()) + while (( !myElemIt.get() || !myElemIt->more() ) && mySubIt != mySubEnd) { myElemIt = getElements(*mySubIt); mySubIt++; @@ -181,8 +315,7 @@ template class MyIterator : public SMDS_Iterator private: bool myMore; - const set& mySubMeshes; - set::const_iterator mySubIt; + set::const_iterator mySubIt, mySubEnd; boost::shared_ptr< SMDS_Iterator > myElemIt; }; @@ -221,8 +354,7 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const { if ( IsComplexSubmesh() ) return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes )); - - return SMDS_ElemIteratorPtr(new MySetIterator(myElements)); + return SMDS_ElemIteratorPtr(new MySetIterator >(myElements)); } //======================================================================= @@ -235,7 +367,7 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const if ( IsComplexSubmesh() ) return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes )); - return SMDS_NodeIteratorPtr(new MySetIterator(myNodes)); + return SMDS_NodeIteratorPtr(new MySetIterator >(myNodes)); } //======================================================================= @@ -246,25 +378,34 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const { // DO NOT TRY TO FIND A REMOVED ELEMENT !! - if ( !ME ) - return false; - - if ( IsComplexSubmesh() ) - { - set::const_iterator aSubIt = mySubMeshes.begin(); - for ( ; aSubIt != mySubMeshes.end(); aSubIt++ ) - if ( (*aSubIt)->Contains( ME )) - return true; + //if ( IsComplexSubmesh() || !ME ) + if (!ME) return false; - } - if ( ME->GetType() == SMDSAbs_Node ) - { - const SMDS_MeshNode* n = static_cast( ME ); - return ( myNodes.find( n ) != myNodes.end() ); - } + if (IsComplexSubmesh()) + { + set::const_iterator aSubIt = mySubMeshes.begin(); + for (; aSubIt != mySubMeshes.end(); aSubIt++) + if ((*aSubIt)->Contains(ME)) + return true; + return false; + } - return ( myElements.find( ME ) != myElements.end() ); + if (ME->GetType() == SMDSAbs_Node) + { + int idInShape = ME->getIdInShape(); + if ((idInShape >= 0) && (idInShape < myNodes.size())) + if (myNodes[idInShape] == ME) + return true; + } + else + { + int idInShape = ME->getIdInShape(); + if ((idInShape >= 0) && (idInShape < myElements.size())) + if (myElements[idInShape] == ME) + return true; + } + return false; } //======================================================================= @@ -288,6 +429,16 @@ bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh ) return mySubMeshes.erase( theSubMesh ); } +//======================================================================= +//function : RemoveAllSubmeshes +//purpose : +//======================================================================= + +void SMESHDS_SubMesh::RemoveAllSubmeshes() +{ + mySubMeshes.clear(); +} + //======================================================================= //function : ContainsSubMesh //purpose : @@ -320,9 +471,66 @@ void SMESHDS_SubMesh::Clear() { myElements.clear(); myNodes.clear(); + myUnusedIdNodes = 0; + myUnusedIdElements = 0; SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator(); while ( sub->more() ) { if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next()) sm->Clear(); } } + +int SMESHDS_SubMesh::getSize() +{ + int c = NbNodes(); + int d = NbElements(); + //cerr << "SMESHDS_SubMesh::NbNodes " << c << endl; + //cerr << "SMESHDS_SubMesh::NbElements " << d << endl; + return c+d; +} + +void SMESHDS_SubMesh::compactList() +{ + //MESSAGE("compactList old: nodes " << myNodes.size() << " elements " << myElements.size()); + //stringstream a; + //stringstream b; + //stringstream c; + //stringstream d; + + std::vector newElems; + newElems.clear(); + for (int i = 0; i < myElements.size(); i++) + if (myElements[i]) + { + SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i]; + elem->setIdInShape(newElems.size()); + newElems.push_back(elem); + //a << elem->GetID() << " "; + //b << elem->GetID() << " "; + } + //else + // a << "_ "; + myElements.swap(newElems); + myUnusedIdElements = 0; + //MESSAGE("in " << myIndex << " oldElems " << a.str()); + //MESSAGE("in " << myIndex << " newElems " << b.str()); + + std::vector newNodes; + newNodes.clear(); + for (int i = 0; i < myNodes.size(); i++) + if (myNodes[i]) + { + SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i]; + node->setIdInShape(newNodes.size()); + newNodes.push_back(node); + //c << node->GetID() << " "; + //d << node->GetID() << " "; + } + //else + // c << "_ "; + myNodes.swap(newNodes); + myUnusedIdNodes = 0; + //MESSAGE("in " << myIndex << " oldNodes " << c.str()); + //MESSAGE("in " << myIndex << " newNodes " << d.str()); + //MESSAGE("compactList new: nodes " << myNodes.size() << " elements " << myElements.size()); +} diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx index 7b2eaa416..049c73e33 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.hxx +++ b/src/SMESHDS/SMESHDS_SubMesh.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHDS : management of mesh data and SMESH document // File : SMESHDS_SubMesh.hxx // Module : SMESH @@ -30,44 +31,59 @@ #include "SMDS_Mesh.hxx" #include +#include class SMESHDS_SubMesh; typedef SMDS_Iterator SMESHDS_SubMeshIterator; typedef boost::shared_ptr< SMESHDS_SubMeshIterator > SMESHDS_SubMeshIteratorPtr; +class SMESHDS_Mesh; + class SMESHDS_EXPORT SMESHDS_SubMesh { public: + SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index); + virtual ~SMESHDS_SubMesh(); - bool IsComplexSubmesh() const { return !mySubMeshes.empty(); } + virtual bool IsComplexSubmesh() const { return !mySubMeshes.empty(); } // if !IsComplexSubmesh() - void AddElement(const SMDS_MeshElement * ME); - bool RemoveElement(const SMDS_MeshElement * ME); // ret true if ME was in - void AddNode(const SMDS_MeshNode * ME); - bool RemoveNode(const SMDS_MeshNode * ME); // ret true if ME was in + virtual void AddElement(const SMDS_MeshElement * ME); + virtual bool RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted); // ret true if ME was in + virtual void AddNode(const SMDS_MeshNode * ME); + virtual bool RemoveNode(const SMDS_MeshNode * ME, bool isNodeDeleted); // ret true if ME was in // if IsComplexSubmesh() void AddSubMesh( const SMESHDS_SubMesh* theSubMesh ); bool RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh ); + void RemoveAllSubmeshes(); bool ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const; int NbSubMeshes() const { return mySubMeshes.size(); } SMESHDS_SubMeshIteratorPtr GetSubMeshIterator() const; // for both types - int NbElements() const; - SMDS_ElemIteratorPtr GetElements() const; - int NbNodes() const; - SMDS_NodeIteratorPtr GetNodes() const; - bool Contains(const SMDS_MeshElement * ME) const; // check if elem or node is in + virtual int NbElements() const; + virtual SMDS_ElemIteratorPtr GetElements() const; + virtual int NbNodes() const; + virtual SMDS_NodeIteratorPtr GetNodes() const; + virtual bool Contains(const SMDS_MeshElement * ME) const; // check if elem or node is in // clear the contents - void Clear(); + virtual void Clear(); + int getSize(); + void compactList(); + + inline SMESHDS_Mesh *getParent() {return myParent; }; private: - //const SMDS_Mesh * myMesh; - std::set myElements; - std::set myNodes; - std::set mySubMeshes; + SMESHDS_Mesh * myParent; + std::vector myElements; + std::vector myNodes; + + int myUnusedIdNodes; + int myUnusedIdElements; + int myIndex; + + std::set mySubMeshes; }; #endif diff --git a/src/SMESHDS/SMESH_Controls.hxx b/src/SMESHDS/SMESH_Controls.hxx new file mode 100644 index 000000000..49d6ab1d2 --- /dev/null +++ b/src/SMESHDS/SMESH_Controls.hxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _SMESH_CONTROLS_HXX_ +#define _SMESH_CONTROLS_HXX_ + +#include "SMDSAbs_ElementType.hxx" + +#include + +#ifdef WNT + #if defined SMESHCONTROLS_EXPORTS || defined SMESHControls_EXPORTS + #define SMESHCONTROLS_EXPORT __declspec( dllexport ) + #else + #define SMESHCONTROLS_EXPORT __declspec( dllimport ) + #endif +#else + #define SMESHCONTROLS_EXPORT +#endif + +class SMDS_Mesh; + +namespace SMESH{ + namespace Controls{ + + /* + Class : Functor + Description : Root of all Functors + */ + class SMESHCONTROLS_EXPORT Functor + { + public: + ~Functor(){} + virtual void SetMesh( const SMDS_Mesh* theMesh ) = 0; + virtual SMDSAbs_ElementType GetType() const = 0; + }; + typedef boost::shared_ptr FunctorPtr; + + + class NumericalFunctor; + typedef boost::shared_ptr NumericalFunctorPtr; + + /* + Class : Predicate + Description : Base class for all predicates + */ + class SMESHCONTROLS_EXPORT Predicate: public virtual Functor{ + public: + virtual bool IsSatisfy( long theElementId ) = 0; + virtual SMDSAbs_ElementType GetType() const = 0; + }; + typedef boost::shared_ptr PredicatePtr; + + } +} + +typedef SMESH::Controls::PredicatePtr SMESH_PredicatePtr; + + +#endif diff --git a/src/SMESHDS/SMESH_SMESHDS.hxx b/src/SMESHDS/SMESH_SMESHDS.hxx index 4e45bbfaa..cc22f1f6d 100755 --- a/src/SMESHDS/SMESH_SMESHDS.hxx +++ b/src/SMESHDS/SMESH_SMESHDS.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_SMESHDS.hxx // Author : Alexander A. BORODIN // Module : SMESH diff --git a/src/SMESHFiltersSelection/Makefile.am b/src/SMESHFiltersSelection/Makefile.am index 183083cc7..6b15a26b3 100644 --- a/src/SMESHFiltersSelection/Makefile.am +++ b/src/SMESHFiltersSelection/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESHFiltersSelection : filter selector for viewer # File : Makefile.in # Author : Patrick GOLDBRONN (CEA) @@ -57,12 +55,12 @@ libSMESHFiltersSelection_la_CPPFLAGS = \ $(BOOST_CPPFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix + -I$(top_builddir)/idl libSMESHFiltersSelection_la_LDFLAGS = \ ../../idl/libSalomeIDLSMESH.la \ $(KERNEL_LDFLAGS) -lSalomeDSClient -lSalomeDS \ - $(GUI_LDFLAGS) -lSalomeApp -lsuit \ - $(GEOM_LDFLAGS) -lGEOM \ - $(CAS_LDPATH) -lTKernel + $(GUI_LDFLAGS) -lSalomeApp -lsuit -lLightApp \ + $(GEOM_LDFLAGS) -lGEOM -lGEOMClient \ + $(CAS_LDPATH) -lTKernel -lTKMath -lTKBRep \ + $(QT_MT_LIBS) diff --git a/src/SMESHFiltersSelection/SMESH_LogicalFilter.cxx b/src/SMESHFiltersSelection/SMESH_LogicalFilter.cxx index f8f908f83..bcfa96bcb 100644 --- a/src/SMESHFiltersSelection/SMESH_LogicalFilter.cxx +++ b/src/SMESHFiltersSelection/SMESH_LogicalFilter.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_LogicalFilter.cxx // Module : SMESH // @@ -29,7 +30,9 @@ // Purpose : Constructor //======================================================================= SMESH_LogicalFilter::SMESH_LogicalFilter (const QList& theFilters, - const int theLogOp) + const int theLogOp, + bool takeOwnership) + : myOwnership( takeOwnership ) { setFilters(theFilters); setOperation(theLogOp); @@ -41,6 +44,7 @@ SMESH_LogicalFilter::SMESH_LogicalFilter (const QList& th //======================================================================= SMESH_LogicalFilter::~SMESH_LogicalFilter() { + deleteFilters(); } //======================================================================= @@ -69,6 +73,7 @@ bool SMESH_LogicalFilter::isOk (const SUIT_DataOwner* owner) const //======================================================================= void SMESH_LogicalFilter::setFilters (const QList& theFilters) { + deleteFilters(); myFilters = theFilters; } @@ -98,3 +103,18 @@ int SMESH_LogicalFilter::getOperation() const { return myOperation; } +//================================================================================ +/*! + * \brief Deletes filters if has an ownership + */ +//================================================================================ + +void SMESH_LogicalFilter::deleteFilters() +{ + if ( myOwnership ) + { + SUIT_SelectionFilter* filter; + foreach( filter, myFilters ) + delete filter; + } +} diff --git a/src/SMESHFiltersSelection/SMESH_LogicalFilter.hxx b/src/SMESHFiltersSelection/SMESH_LogicalFilter.hxx index 928313f80..3069fa890 100644 --- a/src/SMESHFiltersSelection/SMESH_LogicalFilter.hxx +++ b/src/SMESHFiltersSelection/SMESH_LogicalFilter.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_LogicalFilter.hxx // Module : SMESH // @@ -37,7 +38,7 @@ class SMESHFILTERSSELECTION_EXPORT SMESH_LogicalFilter : public SUIT_SelectionFi enum { LO_OR, LO_AND, LO_NOT, LO_UNDEFINED }; public: - SMESH_LogicalFilter( const QList&, const int ); + SMESH_LogicalFilter( const QList&, const int, bool takeOwnership=false ); virtual ~SMESH_LogicalFilter(); virtual bool isOk (const SUIT_DataOwner*) const; @@ -47,9 +48,13 @@ class SMESHFILTERSSELECTION_EXPORT SMESH_LogicalFilter : public SUIT_SelectionFi const QList getFilters() const; int getOperation() const; +private: + void deleteFilters(); + private: QList myFilters; int myOperation; + bool myOwnership; }; #endif diff --git a/src/SMESHFiltersSelection/SMESH_NumberFilter.cxx b/src/SMESHFiltersSelection/SMESH_NumberFilter.cxx index d8633f307..5699e263c 100644 --- a/src/SMESHFiltersSelection/SMESH_NumberFilter.cxx +++ b/src/SMESHFiltersSelection/SMESH_NumberFilter.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_NumberFilter.cxx // Module : SMESH // diff --git a/src/SMESHFiltersSelection/SMESH_NumberFilter.hxx b/src/SMESHFiltersSelection/SMESH_NumberFilter.hxx index 45724cfa1..6400d9b36 100644 --- a/src/SMESHFiltersSelection/SMESH_NumberFilter.hxx +++ b/src/SMESHFiltersSelection/SMESH_NumberFilter.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_NumberFilter.hxx // Module : SMESH // diff --git a/src/SMESHFiltersSelection/SMESH_Type.h b/src/SMESHFiltersSelection/SMESH_Type.h index 106110e09..e29c918a0 100644 --- a/src/SMESHFiltersSelection/SMESH_Type.h +++ b/src/SMESHFiltersSelection/SMESH_Type.h @@ -1,36 +1,36 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_Type.h // Created : Mon Jun 03 15:14:15 2002 // Author : Nicolas REJNERI // Project : SALOME // Module : SMESH -// $Header$ // #ifndef SMESH_TYPE_HEADER #define SMESH_TYPE_HEADER #ifdef WNT - #if defined SMESHFILTERSSELECTION_EXPORTS + #if defined SMESHFILTERSSELECTION_EXPORTS || defined SMESHFiltersSelection_EXPORTS #define SMESHFILTERSSELECTION_EXPORT __declspec( dllexport ) #else #define SMESHFILTERSSELECTION_EXPORT __declspec( dllimport ) @@ -51,7 +51,14 @@ enum MeshObjectType { SUBMESH_SOLID, SUBMESH_COMPOUND, GROUP, - COMPONENT + GROUP_NODE, + GROUP_EDGE, + GROUP_FACE, + GROUP_VOLUME, + GROUP_0D, + GROUP_BALL, + COMPONENT, + IDSOURCE }; #endif diff --git a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx index 509b87240..e9b83166c 100644 --- a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx +++ b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + #include "SMESH_TypeFilter.hxx" #include @@ -80,6 +81,7 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const // 4 | |- Applied algorithms ( selectable in Use Case Browser ) // 5 | |- Regular 1D // |- Group Of Nodes + // |- Group 1 if (aLevel <= 0) return false; @@ -87,90 +89,132 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const switch (myType) { case HYPOTHESIS: - { - if (aLevel == 2 && (objFather->Tag() == SMESH::Tag_HypothesisRoot)) + { + if (aLevel == 2 && (objFather->Tag() == SMESH::Tag_HypothesisRoot)) // hypo definition - Ok = true; - else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis)) + Ok = true; + else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis)) // applied global hypo - Ok = true; - else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis)) + Ok = true; + else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis)) // applied local hypo - Ok = true; - break; - } + Ok = true; + break; + } case ALGORITHM: - { - if (aLevel == 2 && (objFather->Tag() == SMESH::Tag_AlgorithmsRoot)) + { + if (aLevel == 2 && (objFather->Tag() == SMESH::Tag_AlgorithmsRoot)) // algo definition - Ok = true; - else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms)) + Ok = true; + else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms)) // applied global algo - Ok = true; - else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms)) + Ok = true; + else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms)) // applied local algo - Ok = true; - break; - } + Ok = true; + break; + } case MESH: - { - if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot)) - Ok = true; - break; - } + { + if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot)) + Ok = true; + break; + } case SUBMESH: - { - // see SMESH_Gen_i.cxx for tag numbers - if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstSubMesh && + { + // see SMESH_Gen_i.cxx for tag numbers + if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstSubMesh && objFather->Tag() <= SMESH::Tag_LastSubMesh)) - Ok = true; - break; - } + Ok = true; + break; + } case MESHorSUBMESH: - { - if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot)) - Ok = true; // mesh + { + if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot)) + Ok = true; // mesh else if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstSubMesh && objFather->Tag() <= SMESH::Tag_LastSubMesh)) - Ok = true; - break; - } + Ok = true; + break; + } case SUBMESH_VERTEX: // Label "SubMeshes on vertexes" - { - if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnVertex)) - Ok = true; - break; - } + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnVertex)) + Ok = true; + break; + } case SUBMESH_EDGE: - { - if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnEdge)) - Ok = true; - break; - } + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnEdge)) + Ok = true; + break; + } case SUBMESH_FACE: - { - if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnFace)) - Ok = true; - break; - } + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnFace)) + Ok = true; + break; + } case SUBMESH_SOLID: - { - if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnSolid)) - Ok = true; - break; - } + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnSolid)) + Ok = true; + break; + } case SUBMESH_COMPOUND: - { - if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnCompound)) - Ok = true; - break; - } + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnCompound)) + Ok = true; + break; + } case GROUP: - { - if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstGroup)) - Ok = true; - break; - } + { + if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstGroup)) + Ok = true; + break; + } + case GROUP_NODE: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_NodeGroups)) + Ok = true; + break; + } + case GROUP_EDGE: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_EdgeGroups)) + Ok = true; + break; + } + case GROUP_FACE: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_FaceGroups)) + Ok = true; + break; + } + case GROUP_VOLUME: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_VolumeGroups)) + Ok = true; + break; + } + case GROUP_0D: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_0DElementsGroups)) + Ok = true; + break; + } + case GROUP_BALL: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_BallElementsGroups)) + Ok = true; + break; + } + case IDSOURCE: + { + Ok = ( SMESH_TypeFilter(MESHorSUBMESH).isOk( theDataOwner ) || + SMESH_TypeFilter(GROUP) .isOk( theDataOwner )); + break; + } } } return Ok; diff --git a/src/SMESHFiltersSelection/SMESH_TypeFilter.hxx b/src/SMESHFiltersSelection/SMESH_TypeFilter.hxx index d966bfaa5..0821917d0 100644 --- a/src/SMESHFiltersSelection/SMESH_TypeFilter.hxx +++ b/src/SMESHFiltersSelection/SMESH_TypeFilter.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_TypeFilter.hxx // Module : SMESH // diff --git a/src/SMESHGUI/Makefile.am b/src/SMESHGUI/Makefile.am index db288673a..15925385f 100644 --- a/src/SMESHGUI/Makefile.am +++ b/src/SMESHGUI/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESHGUI : GUI for SMESH component # File : Makefile.am # Author : Alexander BORODIN, Open CASCADE S.A.S. @@ -49,12 +47,10 @@ salomeinclude_HEADERS = \ SMESHGUI_GroupDlg.h \ SMESHGUI_RemoveNodesDlg.h \ SMESHGUI_RemoveElementsDlg.h \ - SMESHGUI_MeshInfosDlg.h \ - SMESHGUI_StandardMeshInfosDlg.h \ - SMESHGUI_WhatIsDlg.h \ + SMESHGUI_MeshInfo.h \ + SMESHGUI_Measurements.h \ SMESHGUI_Preferences_ColorDlg.h \ SMESHGUI_Preferences_ScalarBarDlg.h \ - SMESHGUI_MoveNodesDlg.h \ SMESHGUI_AddMeshElementDlg.h \ SMESHGUI_XmlHandler.h \ SMESHGUI_Filter.h \ @@ -71,9 +67,11 @@ salomeinclude_HEADERS = \ SMESHGUI_RevolutionDlg.h \ SMESHGUI_RotationDlg.h \ SMESHGUI_TranslationDlg.h \ + SMESHGUI_ScaleDlg.h \ SMESHGUI_SymmetryDlg.h \ SMESHGUI_SewingDlg.h \ - SMESHGUI_EditMeshDlg.h \ + SMESHGUI_DuplicateNodesDlg.h \ + SMESHGUI_MergeDlg.h \ SMESHGUI_MeshUtils.h \ SMESHGUI_CreatePolyhedralVolumeDlg.h \ SMESHGUI_Operation.h \ @@ -90,6 +88,15 @@ salomeinclude_HEADERS = \ SMESHGUI_MakeNodeAtPointDlg.h \ SMESHGUI_MeshEditPreview.h \ SMESHGUI_IdValidator.h \ + SMESHGUI_MeshInfosBox.h \ + SMESHGUI_Make2DFrom3DOp.h \ + SMESHGUI_FindElemByPointDlg.h \ + SMESHGUI_MeshOrderDlg.h \ + SMESHGUI_MeshOrderOp.h \ + SMESHGUI_FileValidator.h \ + SMESHGUI_CopyMeshDlg.h \ + SMESHGUI_PreviewDlg.h \ + SMESHGUI_ReorientFacesDlg.h \ SMESH_SMESHGUI.hxx # Libraries targets @@ -106,12 +113,10 @@ dist_libSMESH_la_SOURCES = \ SMESHGUI_GroupDlg.cxx \ SMESHGUI_RemoveNodesDlg.cxx \ SMESHGUI_RemoveElementsDlg.cxx \ - SMESHGUI_MeshInfosDlg.cxx \ - SMESHGUI_StandardMeshInfosDlg.cxx \ - SMESHGUI_WhatIsDlg.cxx \ + SMESHGUI_MeshInfo.cxx \ + SMESHGUI_Measurements.cxx \ SMESHGUI_Preferences_ColorDlg.cxx \ SMESHGUI_Preferences_ScalarBarDlg.cxx \ - SMESHGUI_MoveNodesDlg.cxx \ SMESHGUI_AddMeshElementDlg.cxx \ SMESHGUI_XmlHandler.cxx \ SMESHGUI_Filter.cxx \ @@ -128,9 +133,11 @@ dist_libSMESH_la_SOURCES = \ SMESHGUI_RevolutionDlg.cxx \ SMESHGUI_RotationDlg.cxx \ SMESHGUI_TranslationDlg.cxx \ + SMESHGUI_ScaleDlg.cxx \ SMESHGUI_SymmetryDlg.cxx \ SMESHGUI_SewingDlg.cxx \ - SMESHGUI_EditMeshDlg.cxx \ + SMESHGUI_DuplicateNodesDlg.cxx \ + SMESHGUI_MergeDlg.cxx \ SMESHGUI_Utils.cxx \ SMESHGUI_GEOMGenUtils.cxx \ SMESHGUI_MeshUtils.cxx \ @@ -157,7 +164,16 @@ dist_libSMESH_la_SOURCES = \ SMESHGUI_MakeNodeAtPointDlg.cxx \ SMESHGUI_MeshEditPreview.cxx \ SMESHGUI_GroupOnShapeDlg.cxx \ - SMESHGUI_FileInfoDlg.cxx + SMESHGUI_FileInfoDlg.cxx \ + SMESHGUI_MeshInfosBox.cxx \ + SMESHGUI_Make2DFrom3DOp.cxx \ + SMESHGUI_FindElemByPointDlg.cxx \ + SMESHGUI_MeshOrderDlg.cxx \ + SMESHGUI_MeshOrderOp.cxx \ + SMESHGUI_CopyMeshDlg.cxx \ + SMESHGUI_FileValidator.cxx \ + SMESHGUI_PreviewDlg.cxx \ + SMESHGUI_ReorientFacesDlg.cxx MOC_FILES = \ SMESHGUI_moc.cxx \ @@ -171,12 +187,10 @@ MOC_FILES = \ SMESHGUI_GroupDlg_moc.cxx \ SMESHGUI_RemoveNodesDlg_moc.cxx \ SMESHGUI_RemoveElementsDlg_moc.cxx \ - SMESHGUI_MeshInfosDlg_moc.cxx \ - SMESHGUI_StandardMeshInfosDlg_moc.cxx \ - SMESHGUI_WhatIsDlg_moc.cxx \ + SMESHGUI_MeshInfo_moc.cxx \ + SMESHGUI_Measurements_moc.cxx \ SMESHGUI_Preferences_ColorDlg_moc.cxx \ SMESHGUI_Preferences_ScalarBarDlg_moc.cxx \ - SMESHGUI_MoveNodesDlg_moc.cxx \ SMESHGUI_AddMeshElementDlg_moc.cxx \ SMESHGUI_FilterDlg_moc.cxx \ SMESHGUI_FilterLibraryDlg_moc.cxx \ @@ -191,9 +205,11 @@ MOC_FILES = \ SMESHGUI_RevolutionDlg_moc.cxx \ SMESHGUI_RotationDlg_moc.cxx \ SMESHGUI_TranslationDlg_moc.cxx \ + SMESHGUI_ScaleDlg_moc.cxx \ SMESHGUI_SymmetryDlg_moc.cxx \ SMESHGUI_SewingDlg_moc.cxx \ - SMESHGUI_EditMeshDlg_moc.cxx \ + SMESHGUI_DuplicateNodesDlg_moc.cxx \ + SMESHGUI_MergeDlg_moc.cxx \ SMESHGUI_CreatePolyhedralVolumeDlg_moc.cxx \ SMESHGUI_Operation_moc.cxx \ SMESHGUI_SelectionOp_moc.cxx \ @@ -209,7 +225,15 @@ MOC_FILES = \ SMESHGUI_ComputeDlg_moc.cxx \ SMESHGUI_MakeNodeAtPointDlg_moc.cxx \ SMESHGUI_GroupOnShapeDlg_moc.cxx \ - SMESHGUI_FileInfoDlg_moc.cxx + SMESHGUI_FileInfoDlg_moc.cxx \ + SMESHGUI_MeshInfosBox_moc.cxx \ + SMESHGUI_Make2DFrom3DOp_moc.cxx \ + SMESHGUI_FindElemByPointDlg_moc.cxx \ + SMESHGUI_MeshOrderDlg_moc.cxx \ + SMESHGUI_CopyMeshDlg_moc.cxx \ + SMESHGUI_MeshOrderOp_moc.cxx \ + SMESHGUI_PreviewDlg_moc.cxx \ + SMESHGUI_ReorientFacesDlg_moc.cxx nodist_libSMESH_la_SOURCES= \ $(MOC_FILES) @@ -223,33 +247,38 @@ libSMESH_la_CPPFLAGS = \ $(PYTHON_INCLUDES) \ $(KERNEL_CXXFLAGS) \ $(GUI_CXXFLAGS) \ + $(QWT_INCLUDES) \ $(GEOM_CXXFLAGS) \ $(MED_CXXFLAGS) \ $(BOOST_CPPFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ - $(MED2_INCLUDES) \ + $(MED3_INCLUDES) \ $(HDF5_INCLUDES) \ -I$(srcdir)/../OBJECT \ -I$(srcdir)/../SMESHFiltersSelection \ -I$(srcdir)/../SMDS \ + -I$(srcdir)/../SMESHDS \ -I$(srcdir)/../SMESH \ + -I$(srcdir)/../SMESHUtils \ -I$(srcdir)/../SMESH_I \ -I$(srcdir)/../Controls \ -I$(srcdir)/../SMESHClient \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix - + -I$(top_builddir) \ + -I$(top_builddir)/idl libSMESH_la_LDFLAGS = \ ../SMESHFiltersSelection/libSMESHFiltersSelection.la \ ../SMDS/libSMDS.la \ ../Controls/libSMESHControls.la \ ../OBJECT/libSMESHObject.la \ - $(GEOM_LDFLAGS) \ - -lGEOMBase + $(CAS_LDFLAGS) -lTKV3d \ + $(GUI_LDFLAGS) -lSalomePrs -lsuit -lSUITApp -lCAM -lstd \ + $(GEOM_LDFLAGS) -lGEOMBase -lGEOMFiltersSelection -lGEOMObject \ + $(PYTHON_LIBS) # resources files nodist_salomeres_DATA= \ SMESH_images.qm \ - SMESH_msg_en.qm + SMESH_msg_en.qm \ + SMESH_msg_fr.qm diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 50f44fb18..52f3180ad 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -1,72 +1,82 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI.cxx -// Author : Nicolas REJNERI, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI.cxx +// Author : Nicolas REJNERI, Open CASCADE S.A.S. + +#include // E.A. must be included before Python.h to fix compilation on windows +#ifdef HAVE_FINITE +#undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined +#endif +#include "Python.h" +// SMESH includes #include "SMESHGUI.h" -#include "SMESHGUI_NodesDlg.h" -#include "SMESHGUI_TransparencyDlg.h" -#include "SMESHGUI_ClippingDlg.h" -#include "SMESHGUI_GroupDlg.h" -#include "SMESHGUI_RemoveNodesDlg.h" -#include "SMESHGUI_RemoveElementsDlg.h" -#include "SMESHGUI_MeshInfosDlg.h" -#include "SMESHGUI_StandardMeshInfosDlg.h" -#include "SMESHGUI_WhatIsDlg.h" -#include "SMESHGUI_Preferences_ColorDlg.h" -#include "SMESHGUI_Preferences_ScalarBarDlg.h" -#include "SMESHGUI_Hypotheses.h" -#include "SMESHGUI_MoveNodesDlg.h" #include "SMESHGUI_AddMeshElementDlg.h" #include "SMESHGUI_AddQuadraticElementDlg.h" +#include "SMESHGUI_BuildCompoundDlg.h" +#include "SMESHGUI_ClippingDlg.h" +#include "SMESHGUI_ComputeDlg.h" +#include "SMESHGUI_ConvToQuadOp.h" +#include "SMESHGUI_CreatePolyhedralVolumeDlg.h" +#include "SMESHGUI_DeleteGroupDlg.h" +#include "SMESHGUI_Displayer.h" +#include "SMESHGUI_MergeDlg.h" +#include "SMESHGUI_ExtrusionAlongPathDlg.h" +#include "SMESHGUI_ExtrusionDlg.h" +#include "SMESHGUI_FileInfoDlg.h" +#include "SMESHGUI_FileValidator.h" #include "SMESHGUI_FilterDlg.h" #include "SMESHGUI_FilterLibraryDlg.h" -#include "SMESHGUI_SingleEditDlg.h" -#include "SMESHGUI_MultiEditDlg.h" -#include "SMESHGUI_GroupOpDlg.h" +#include "SMESHGUI_FindElemByPointDlg.h" +#include "SMESHGUI_GroupDlg.h" #include "SMESHGUI_GroupOnShapeDlg.h" -#include "SMESHGUI_DeleteGroupDlg.h" -#include "SMESHGUI_SmoothingDlg.h" +#include "SMESHGUI_GroupOpDlg.h" +#include "SMESHGUI_Hypotheses.h" +#include "SMESHGUI_Make2DFrom3DOp.h" +#include "SMESHGUI_MakeNodeAtPointDlg.h" +#include "SMESHGUI_Measurements.h" +#include "SMESHGUI_MeshInfo.h" +#include "SMESHGUI_MeshOp.h" +#include "SMESHGUI_MeshOrderOp.h" +#include "SMESHGUI_MeshPatternDlg.h" +#include "SMESHGUI_MultiEditDlg.h" +#include "SMESHGUI_NodesDlg.h" +#include "SMESHGUI_Preferences_ColorDlg.h" +#include "SMESHGUI_Preferences_ScalarBarDlg.h" +#include "SMESHGUI_RemoveElementsDlg.h" +#include "SMESHGUI_RemoveNodesDlg.h" #include "SMESHGUI_RenumberingDlg.h" -#include "SMESHGUI_ExtrusionDlg.h" -#include "SMESHGUI_ExtrusionAlongPathDlg.h" #include "SMESHGUI_RevolutionDlg.h" -#include "SMESHGUI_TranslationDlg.h" #include "SMESHGUI_RotationDlg.h" -#include "SMESHGUI_SymmetryDlg.h" -#include "SMESHGUI_SewingDlg.h" -#include "SMESHGUI_EditMeshDlg.h" -#include "SMESHGUI_MeshPatternDlg.h" #include "SMESHGUI_Selection.h" -#include "SMESHGUI_CreatePolyhedralVolumeDlg.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_FileInfoDlg.h" +#include "SMESHGUI_SewingDlg.h" +#include "SMESHGUI_SingleEditDlg.h" +#include "SMESHGUI_SmoothingDlg.h" +#include "SMESHGUI_SymmetryDlg.h" +#include "SMESHGUI_TranslationDlg.h" +#include "SMESHGUI_ScaleDlg.h" +#include "SMESHGUI_TransparencyDlg.h" +#include "SMESHGUI_DuplicateNodesDlg.h" +#include "SMESHGUI_CopyMeshDlg.h" +#include "SMESHGUI_ReorientFacesDlg.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_MeshUtils.h" @@ -76,15 +86,21 @@ #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_HypothesesUtils.h" +#include + #include #include +#include +#include #include +#include "SMESH_ControlsDef.hxx" // SALOME GUI includes #include #include #include #include +#include #include #include @@ -96,6 +112,8 @@ #include #include +#include + #include #include #include @@ -109,23 +127,32 @@ #include #include +#ifndef DISABLE_PLOT2DVIEWER +#include +#include +#endif + // IDL includes #include #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes) #include CORBA_CLIENT_HEADER(SMESH_MeshEditor) +#include CORBA_CLIENT_HEADER(SMESH_Measurements) // Qt includes -// #define INCLUDE_MENUITEM_DEF // VSR commented ???????? +// #define INCLUDE_MENUITEM_DEF // VSR commented ???????? +#include #include +#include // BOOST includes #include // VTK includes -#include #include #include #include +#include +#include // SALOME KERNEL includes #include @@ -138,15 +165,19 @@ #include #include +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + //namespace{ // Declarations //============================================================= void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh, - int theCommandID); + int theCommandID); void ExportMeshToFile(int theCommandID); - void SetDisplayMode(int theCommandID); + void SetDisplayMode(int theCommandID, SMESHGUI_StudyId2MarkerMap& theMarkerMap); void SetDisplayEntity(int theCommandID); @@ -156,20 +187,30 @@ // Definitions //============================================================= void ImportMeshesFromFile( SMESH::SMESH_Gen_ptr theComponentMesh, - int theCommandID ) + int theCommandID ) { QStringList filter; std::string myExtension; if ( theCommandID == 113 ) { - filter.append( QObject::tr( "MED files (*.med)" ) ); - filter.append( QObject::tr( "All files (*)" ) ); + filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.med)" ); + filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" ); } else if ( theCommandID == 112 ) { - filter.append( QObject::tr( "IDEAS files (*.unv)" ) ); + filter.append( QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)" ); } else if ( theCommandID == 111 ) { - filter.append( QObject::tr( "DAT files (*.dat)" ) ); + filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" ); + } + else if ( theCommandID == 115 ) { + filter.append( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" ); + } + else if ( theCommandID == 116 ) { + filter.append( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" ); + } + else if ( theCommandID == 117 ) { + filter.append( QObject::tr( "SAUV files (*.sauv*)" ) ); + filter.append( QObject::tr( "All files (*)" ) ); } QString anInitialPath = ""; @@ -177,89 +218,143 @@ anInitialPath = QDir::currentPath(); QStringList filenames = SUIT_FileDlg::getOpenFileNames( SMESHGUI::desktop(), - anInitialPath, - filter, - QObject::tr( "SMESH_IMPORT_MESH" ) ); + anInitialPath, + filter, + QObject::tr( "SMESH_IMPORT_MESH" ) ); if ( filenames.count() > 0 ) { SUIT_OverrideCursor wc; _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); QStringList errors; + QStringList anEntryList; bool isEmpty = false; for ( QStringList::ConstIterator it = filenames.begin(); it != filenames.end(); ++it ) { - QString filename = *it; - SMESH::mesh_array_var aMeshes = new SMESH::mesh_array; - try { - switch ( theCommandID ) { - case 111: - { - // DAT format (currently unsupported) - errors.append( QString( "%1 :\n\t%2" ).arg( filename ). - arg( QObject::tr( "SMESH_ERR_NOT_SUPPORTED_FORMAT" ) ) ); - break; - } - case 112: - { - // UNV format - aMeshes->length( 1 ); - aMeshes[0] = theComponentMesh->CreateMeshesFromUNV( filename.toLatin1().constData() ); - if ( aMeshes[0]->_is_nil() ) - errors.append( QString( "%1 :\n\t%2" ).arg( filename ). - arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) ); - break; - } - case 113: - { - // MED format - SMESH::DriverMED_ReadStatus res; - aMeshes = theComponentMesh->CreateMeshesFromMED( filename.toLatin1().constData(), res ); - if ( res != SMESH::DRS_OK ) { - errors.append( QString( "%1 :\n\t%2" ).arg( filename ). - arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) ); - } - break; - } - } - } - catch ( const SALOME::SALOME_Exception& S_ex ) { - errors.append( QString( "%1 :\n\t%2" ).arg( filename ). - arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) ); - } - - for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ ) { - _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] ); - if ( aMeshSO ) { - _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); - _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" ); - aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); - if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import - SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() ); - } - else { - isEmpty = true; - } - } + QString filename = *it; + SMESH::mesh_array_var aMeshes = new SMESH::mesh_array; + try { + switch ( theCommandID ) { + case 111: + { + // DAT format (currently unsupported) + errors.append( QString( "%1 :\n\t%2" ).arg( filename ). + arg( QObject::tr( "SMESH_ERR_NOT_SUPPORTED_FORMAT" ) ) ); + break; + } + case 112: + { + // UNV format + aMeshes->length( 1 ); + aMeshes[0] = theComponentMesh->CreateMeshesFromUNV( filename.toLatin1().constData() ); + if ( aMeshes[0]->_is_nil() ) + errors.append( QString( "%1 :\n\t%2" ).arg( filename ). + arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) ); + break; + } + case 113: + { + // MED format + SMESH::DriverMED_ReadStatus res; + aMeshes = theComponentMesh->CreateMeshesFromMED( filename.toLatin1().constData(), res ); + if ( res != SMESH::DRS_OK ) { + errors.append( QString( "%1 :\n\t%2" ).arg( filename ). + arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) ); + } + break; + } + case 115: + { + // STL format + aMeshes->length( 1 ); + aMeshes[0] = theComponentMesh->CreateMeshesFromSTL( filename.toLatin1().constData() ); + if ( aMeshes[0]->_is_nil() ) { + errors.append( QString( "%1 :\n\t%2" ).arg( filename ). + arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) ); + } + break; + } + case 116: + { + // CGNS format + SMESH::DriverMED_ReadStatus res; + aMeshes = theComponentMesh->CreateMeshesFromCGNS( filename.toLatin1().constData(), res ); + if ( res != SMESH::DRS_OK ) { + errors.append( QString( "%1 :\n\t%2" ).arg( filename ). + arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) ); + } + break; + } + case 117: + { + // SAUV format + SMESH::DriverMED_ReadStatus res; + aMeshes = theComponentMesh->CreateMeshesFromSAUV( filename.toLatin1().constData(), res ); + if ( res != SMESH::DRS_OK ) { + errors.append( QString( "%1 :\n\t%2" ).arg( filename ). + arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) ); + } + break; + } + } + } + catch ( const SALOME::SALOME_Exception& S_ex ) { + errors.append( QString( "%1 :\n\t%2" ).arg( filename ). + arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) ); + } + + for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ ) { + _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] ); + if ( aMeshSO ) { + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" ); + aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); + if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import + SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() ); + + anEntryList.append( aMeshSO->GetID().c_str() ); + +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + aMeshes[i]->UnRegister(); +#endif + } + else { + isEmpty = true; + } + } } // update Object browser SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + // browse to the published meshes + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList ); + // show Error message box if there were errors if ( errors.count() > 0 ) { - SUIT_MessageBox::critical( SMESHGUI::desktop(), - QObject::tr( "SMESH_ERROR" ), - QObject::tr( "SMESH_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) ); + SUIT_MessageBox::critical( SMESHGUI::desktop(), + QObject::tr( "SMESH_ERROR" ), + QObject::tr( "SMESH_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) ); } // show warning message box, if some imported mesh is empty if ( isEmpty ) { - SUIT_MessageBox::warning( SMESHGUI::desktop(), - QObject::tr( "SMESH_WRN_WARNING" ), - QObject::tr( "SMESH_DRS_SOME_EMPTY" ) ); + SUIT_MessageBox::warning( SMESHGUI::desktop(), + QObject::tr( "SMESH_WRN_WARNING" ), + QObject::tr( "SMESH_DRS_SOME_EMPTY" ) ); } } } + //================================================================================ + /*! + * \brief Export selected meshes or groups into a file + */ + //================================================================================ + void ExportMeshToFile( int theCommandID ) { LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); @@ -267,132 +362,261 @@ if( aSel ) aSel->selectedObjects( selected ); - SMESH::SMESH_Mesh_var aMesh; - if(selected.Extent() == 1) - aMesh = SMESH::IObjectToInterface(selected.First()); - if ( aMesh->_is_nil() ) { - SUIT_MessageBox::warning( SMESHGUI::desktop(), - QObject::tr( "SMESH_WRN_WARNING" ), - QObject::tr( "SMESH_BAD_MESH_SELECTION" )); + const bool isMED = ( theCommandID == 122 || theCommandID == 125 ); + const bool isDAT = ( theCommandID == 121 || theCommandID == 124 ); + const bool isUNV = ( theCommandID == 123 || theCommandID == 126 ); + const bool isSTL = ( theCommandID == 140 || theCommandID == 141 ); + const bool isCGNS= ( theCommandID == 142 || theCommandID == 143 ); + const bool isSAUV= ( theCommandID == 144 || theCommandID == 145 ); + + // actually, the following condition can't be met (added for insurance) + if( selected.Extent() == 0 || + ( selected.Extent() > 1 && !isMED && !isSTL )) return; - } - Handle(SALOME_InteractiveObject) anIObject = selected.First(); - QString aFilter, aTitle = QObject::tr("Export mesh"); - QMap aFilterMap; - QMap aFilterMapSTL; - switch ( theCommandID ) { - case 125: - case 122: - { - if (aMesh->HasDuplicatedGroupNamesMED()) { - int aRet = SUIT_MessageBox::warning - (SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_EXPORT_MED_DUPLICATED_GRP").arg(anIObject->getName()), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes); - if (aRet != SUIT_MessageBox::Yes) - return; - } - // PAL18696 - QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2)); - QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2)); - aFilterMap.insert( QString("MED ") + v21 + " (*.med)", SMESH::MED_V2_1 ); - aFilterMap.insert( QString("MED ") + v22 + " (*.med)", SMESH::MED_V2_2 ); - } - break; - case 124: - case 121: - aFilter = QObject::tr("DAT files (*.dat)"); - break; - case 126: - case 123: - { - if (aMesh->NbPyramids()) { - int aRet = SUIT_MessageBox::warning - (SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_EXPORT_UNV").arg(anIObject->getName()), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes); - if (aRet != SUIT_MessageBox::Yes) - return; - } - aFilter = QObject::tr("IDEAS files (*.unv)"); + // get mesh object from selection and check duplication of their names + bool hasDuplicatedMeshNames = false; + QList< QPair< SMESH::SMESH_IDSource_var, QString > > aMeshList; + QList< QPair< SMESH::SMESH_IDSource_var, QString > >::iterator aMeshIter; + SALOME_ListIteratorOfListIO It( selected ); + for( ; It.More(); It.Next() ) + { + Handle(SALOME_InteractiveObject) anIObject = It.Value(); + SMESH::SMESH_IDSource_var aMeshItem = SMESH::IObjectToInterface(anIObject); + if ( aMeshItem->_is_nil() ) { + SUIT_MessageBox::warning( SMESHGUI::desktop(), + QObject::tr( "SMESH_WRN_WARNING" ), + QObject::tr( "SMESH_BAD_MESH_SELECTION" )); + return; } - break; - case 140: - case 141: - { - // export STL - /* - there must be check on others mesh elements not equal triangles - */ - if (aMesh->NbTriangles() < 1) { - SUIT_MessageBox::warning - (SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_EXPORT_STL1").arg(anIObject->getName())); - return; + + QString aMeshName = anIObject->getName(); + + // check for name duplications + if ( !hasDuplicatedMeshNames ) + for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) { + if( aMeshName == (*aMeshIter).second ) { + hasDuplicatedMeshNames = true; + break; + } } - if (!(aMesh->NbElements() - aMesh->NbTriangles())) { + + aMeshList.append( QPair< SMESH::SMESH_IDSource_var, QString >( aMeshItem, aMeshName ) ); + } + + if( hasDuplicatedMeshNames && isMED ) { + int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES"), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), 0, 1); + if (aRet != 0) + return; + } + + aMeshIter = aMeshList.begin(); + SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first; + SMESH::SMESH_Mesh_var aMesh = aMeshOrGroup->GetMesh(); + QString aMeshName = (*aMeshIter).second; + + if ( isMED || isCGNS || isSAUV ) + { + // check for equal group names within each mesh + for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) { + SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first ); + if ( !aMeshItem->_is_nil() && aMeshItem->HasDuplicatedGroupNamesMED()) { int aRet = SUIT_MessageBox::warning (SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_EXPORT_STL2").arg(anIObject->getName()), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes); - if (aRet != SUIT_MessageBox::Yes) + QObject::tr("SMESH_EXPORT_MED_DUPLICATED_GRP").arg((*aMeshIter).second), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), 0, 1); + if (aRet != 0) 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; + } + + // Warn the user about presence of not supported elements + QString format; + std::vector< SMESH::EntityType > notSupportedElemTypes, presentNotSupported; + if ( isDAT ) + { + format = "DAT"; + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Quadrangle ); + notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle ); + notSupportedElemTypes.push_back( SMESH::Entity_Polygon ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon ); + notSupportedElemTypes.push_back( SMESH::Entity_Tetra ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Tetra ); + notSupportedElemTypes.push_back( SMESH::Entity_Pyramid ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Hexa ); + notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa ); + notSupportedElemTypes.push_back( SMESH::Entity_Penta ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta ); + notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism ); + notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra ); + notSupportedElemTypes.push_back( SMESH::Entity_0D ); + notSupportedElemTypes.push_back( SMESH::Entity_Ball ); + } + else if ( isUNV ) + { + format = "UNV"; + notSupportedElemTypes.push_back( SMESH::Entity_Polygon ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon ); + notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra ); + notSupportedElemTypes.push_back( SMESH::Entity_Pyramid ); + notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism ); + notSupportedElemTypes.push_back( SMESH::Entity_0D ); + notSupportedElemTypes.push_back( SMESH::Entity_Ball ); + } + else if ( isSTL ) + { + format = "STL"; + notSupportedElemTypes.push_back( SMESH::Entity_Edge ); + notSupportedElemTypes.push_back( SMESH::Entity_Quad_Edge ); + notSupportedElemTypes.push_back( SMESH::Entity_0D ); + notSupportedElemTypes.push_back( SMESH::Entity_Ball ); + } + else if ( isCGNS ) + { + format = "CGNS"; + notSupportedElemTypes.push_back( SMESH::Entity_Ball ); + } + else if ( isSAUV ) + { + format = "SAUV"; + notSupportedElemTypes.push_back( SMESH::Entity_Ball ); + notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle ); + notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa ); + notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism ); + notSupportedElemTypes.push_back( SMESH::Entity_Polygon ); + notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra ); + } + if ( ! notSupportedElemTypes.empty() ) + { + SMESH::long_array_var nbElems = aMeshOrGroup->GetMeshInfo(); + for ( size_t iType = 0; iType < notSupportedElemTypes.size(); ++iType ) + if ( nbElems[ notSupportedElemTypes[ iType ]] > 0 ) + presentNotSupported.push_back( notSupportedElemTypes[ iType ]); + } + if ( !presentNotSupported.empty() ) + { + QString typeNames; + const char* typeMsg[SMESH::Entity_Last] = { "SMESH_NODES", + "SMESH_ELEMS0D","SMESH_EDGES","SMESH_QUADRATIC_EDGES","SMESH_TRIANGLES", + "SMESH_QUADRATIC_TRIANGLES","SMESH_QUADRANGLES","SMESH_QUADRATIC_QUADRANGLES", + "SMESH_BIQUADRATIC_QUADRANGLES","SMESH_POLYGONS","SMESH_QUADRATIC_POLYGONS", + "SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS", + "SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS", + "SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS", + "SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS" + }; + QString andStr = " " + QObject::tr("SMESH_AND") + " ", comma(", "); + for ( size_t iType = 0; iType < presentNotSupported.size(); ++iType ) { + typeNames += QObject::tr( typeMsg[ presentNotSupported[ iType ]]); + if ( iType != presentNotSupported.size() - 1 ) + typeNames += ( iType == presentNotSupported.size() - 2 ) ? andStr : comma; + } + int aRet = SUIT_MessageBox::warning + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("EXPORT_NOT_SUPPORTED").arg(aMeshName).arg(format).arg(typeNames), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), 0, 1); + if (aRet != 0) + return; } + // Get parameters of export operation + QString aFilename; SMESH::MED_VERSION aFormat; - // Init the parameter with the default value + // Init the parameters with the default values bool aIsASCII_STL = true; bool toCreateGroups = false; SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if ( resMgr ) toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false ); + bool toOverwrite = true; + QString aFilter, aTitle = QObject::tr("SMESH_EXPORT_MESH"); QString anInitialPath = ""; if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) anInitialPath = QDir::currentPath(); - if ( theCommandID != 122 && theCommandID != 125 && theCommandID != 140 && theCommandID != 141) { + if ( isUNV || isDAT ) + { + if ( isUNV ) + aFilter = QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)"; + else + aFilter = QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)"; if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath(); - aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), anInitialPath + QString("/") + anIObject->getName(), + aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), + anInitialPath + QString("/") + aMeshName, aFilter, aTitle, false); } - else if(theCommandID == 140 || theCommandID == 141) { // Export to STL + else if ( isCGNS )// Export to CGNS + { + SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); + fd->setWindowTitle( aTitle ); + fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" ); + if ( !anInitialPath.isEmpty() ) + fd->setDirectory( anInitialPath ); + fd->selectFile(aMeshName); + SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd ); + fd->setValidator( fv ); + + if ( fd->exec() ) + aFilename = fd->selectedFile(); + toOverwrite = fv->isOverwrite(); + + delete fd; + } + else if ( isSTL ) // Export to STL + { + QMap aFilterMap; + aFilterMap.insert( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)", 1 ); + aFilterMap.insert( QObject::tr( "STL_BIN_FILES_FILTER" ) + " (*.stl)", 0 ); + QStringList filters; - QMap::const_iterator it = aFilterMapSTL.begin(); - for ( ; it != aFilterMapSTL.end(); ++it ) + QMap::const_iterator it = aFilterMap.begin(); + for ( ; it != aFilterMap.end(); ++it ) filters.push_back( it.key() ); SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); fd->setWindowTitle( aTitle ); - fd->setFilters( filters ); - fd->selectFilter( QObject::tr("STL ASCII (*.stl)") ); + fd->setNameFilters( filters ); + fd->selectNameFilter( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" ); if ( !anInitialPath.isEmpty() ) fd->setDirectory( anInitialPath ); - fd->selectFile(anIObject->getName()); + fd->selectFile(aMeshName); bool is_ok = false; while (!is_ok) { if ( fd->exec() ) aFilename = fd->selectedFile(); - aIsASCII_STL = (aFilterMapSTL[fd->selectedFilter()]) == 1 ? true: false; + aIsASCII_STL = (aFilterMap[fd->selectedNameFilter()]) == 1 ? true: false; is_ok = true; } delete fd; } - else { // Export to MED + else if ( isMED || isSAUV ) // Export to MED or SAUV + { + QMap aFilterMap; + //QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2)); + if ( isMED ) { + QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2)); + //aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v21 ) + " (*.med)", SMESH::MED_V2_1 ); + aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v22 ) + " (*.med)", SMESH::MED_V2_2 ); + } + else { // isSAUV + aFilterMap.insert("All files (*)", SMESH::MED_V2_1 ); + aFilterMap.insert("SAUV files (*.sauv)", SMESH::MED_V2_2 ); + aFilterMap.insert("SAUV files (*.sauve)", SMESH::MED_V2_1 ); + } + QStringList filters; QString aDefaultFilter; QMap::const_iterator it = aFilterMap.begin(); @@ -402,76 +626,180 @@ aDefaultFilter = it.key(); } - //SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg ( SMESHGUI::desktop(), false, QObject::tr("SMESH_AUTO_GROUPS"), true, true ); fd->setWindowTitle( aTitle ); - fd->setFilters( filters ); - //fd->setSelectedFilter( QObject::tr("MED 2.2 (*.med)") ); - fd->selectFilter(aDefaultFilter); + fd->setNameFilters( filters ); + fd->selectNameFilter(aDefaultFilter); fd->SetChecked(toCreateGroups); if ( !anInitialPath.isEmpty() ) fd->setDirectory( anInitialPath ); - fd->selectFile(anIObject->getName()); + fd->selectFile(aMeshName); + + SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd ); + fd->setValidator( fv ); + bool is_ok = false; while (!is_ok) { if ( fd->exec() ) aFilename = fd->selectedFile(); - aFormat = aFilterMap[fd->selectedFilter()]; + else { + aFilename = QString::null; + break; + } + aFormat = aFilterMap[fd->selectedNameFilter()]; + toOverwrite = fv->isOverwrite(); is_ok = true; - if ( !aFilename.isEmpty() - && (aMesh->NbPolygons()>0 || aMesh->NbPolyhedrons()>0) - && aFormat==SMESH::MED_V2_1) { - int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_EXPORT_MED_V2_1").arg(anIObject->getName()), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes); - if (aRet != SUIT_MessageBox::Yes) { - is_ok = false; + if ( !aFilename.isEmpty() ) { + // med-2.1 does not support poly elements + if ( aFormat==SMESH::MED_V2_1 ) + for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) { + SMESH::SMESH_IDSource_var aMeshItem = (*aMeshIter).first; + SMESH::long_array_var nbElems = aMeshItem->GetMeshInfo(); + if ( nbElems[ SMESH::Entity_Polygon ] + nbElems[ SMESH::Entity_Quad_Polygon ] + + nbElems[ SMESH::Entity_Polyhedra ] + nbElems[ SMESH::Entity_Quad_Polyhedra ]) + { + int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_MED_V2_1").arg((*aMeshIter).second), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), 0, 1); + if (aRet != 0) { + is_ok = false; + break; + } + } + } + if( !toOverwrite ) { + // can't append to an existing using other format + SMESH::MED_VERSION aVersion = SMESH::MED_V2_1; + bool isVersionOk = SMESHGUI::GetSMESHGen()->GetMEDVersion( aFilename.toLatin1().constData(), aVersion ); + if( !isVersionOk || aVersion != aFormat ) { + int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_MED_VERSION_COLLISION").arg(aFilename), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), 0, 1); + if (aRet == 0) + toOverwrite = true; + else + is_ok = false; + } + + QStringList aMeshNamesCollisionList; + SMESH::string_array_var aMeshNames = SMESHGUI::GetSMESHGen()->GetMeshNames( aFilename.toLatin1().constData() ); + for( int i = 0, n = aMeshNames->length(); i < n; i++ ) { + QString anExistingMeshName( aMeshNames[ i ] ); + for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) { + QString anExportMeshName = (*aMeshIter).second; + if( anExportMeshName == anExistingMeshName ) { + aMeshNamesCollisionList.append( anExportMeshName ); + break; + } + } + } + if( !aMeshNamesCollisionList.isEmpty() ) { + QString aMeshNamesCollisionString = aMeshNamesCollisionList.join( ", " ); + int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_EXPORT_MED_MESH_NAMES_COLLISION").arg(aMeshNamesCollisionString), + QObject::tr("SMESH_BUT_YES"), + QObject::tr("SMESH_BUT_NO"), + QObject::tr("SMESH_BUT_CANCEL"), 0, 2); + if (aRet == 0) + toOverwrite = true; + else if (aRet == 2) + is_ok = false; + } } } } toCreateGroups = fd->IsChecked(); delete fd; } + else + { + return; + } + + // Perform export + if ( !aFilename.isEmpty() ) { // Check whether the file already exists and delete it if yes QFile aFile( aFilename ); - if ( aFile.exists() ) + if ( aFile.exists() && toOverwrite ) aFile.remove(); 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(); + // Renumbering is not needed since SMDS redesign in V6.2.0 (Nov 2010) +// bool Renumber = false; +// // PAL 14172 : Check of we have to renumber or not from the preferences before export +// if (resMgr) +// Renumber= resMgr->booleanValue("renumbering"); +// if (Renumber){ +// SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); +// aMeshEditor->RenumberNodes(); +// aMeshEditor->RenumberElements(); +// if ( SMESHGUI::automaticUpdate() ) +// SMESH::UpdateView(); +// } + if ( isMED ) + { + aMeshIter = aMeshList.begin(); + for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ ) + { + SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first; + SMESH::SMESH_Mesh_var aMeshItem = aMeshOrGroup->GetMesh(); + if ( aMeshOrGroup->_is_equivalent( aMeshItem )) + aMeshItem->ExportToMEDX( aFilename.toLatin1().data(), toCreateGroups, + aFormat, toOverwrite && aMeshIndex == 0 ); + else + aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toLatin1().data(), toCreateGroups, + aFormat, toOverwrite && aMeshIndex == 0 ); + } } - switch ( theCommandID ) { - case 125: - case 122: - aMesh->ExportToMED( aFilename.toLatin1().data(), toCreateGroups, aFormat ); - break; - case 124: - case 121: - aMesh->ExportDAT( aFilename.toLatin1().data() ); - break; - case 126: - case 123: - aMesh->ExportUNV( aFilename.toLatin1().data() ); - break; - case 140: - case 141: - aMesh->ExportSTL( aFilename.toLatin1().data(), aIsASCII_STL ); - break; - default: - break; + else if ( isSAUV ) + { + for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) + { + SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first ); + if( !aMeshItem->_is_nil() ) + aMeshItem->ExportSAUV( aFilename.toLatin1().data(), toCreateGroups ); + } + } + else if ( isDAT ) + { + if ( aMeshOrGroup->_is_equivalent( aMesh )) + aMesh->ExportDAT( aFilename.toLatin1().data() ); + else + aMesh->ExportPartToDAT( aMeshOrGroup, aFilename.toLatin1().data() ); + } + else if ( isUNV ) + { + if ( aMeshOrGroup->_is_equivalent( aMesh )) + aMesh->ExportUNV( aFilename.toLatin1().data() ); + else + aMesh->ExportPartToUNV( aMeshOrGroup, aFilename.toLatin1().data() ); + } + else if ( isSTL ) + { + if ( aMeshOrGroup->_is_equivalent( aMesh )) + aMesh->ExportSTL( aFilename.toLatin1().data(), aIsASCII_STL ); + else + aMesh->ExportPartToSTL( aMeshOrGroup, aFilename.toLatin1().data(), aIsASCII_STL ); + } + else if ( isCGNS ) + { + aMeshIter = aMeshList.begin(); + for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ ) + { + SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first; + SMESH::SMESH_Mesh_var aMeshItem = aMeshOrGroup->GetMesh(); + aMeshItem->ExportCGNS( aMeshOrGroup, + aFilename.toLatin1().data(), + toOverwrite && aMeshIndex == 0 ); + } } } catch (const SALOME::SALOME_Exception& S_ex){ @@ -485,7 +813,7 @@ } inline void InverseEntityMode(unsigned int& theOutputMode, - unsigned int theMode) + unsigned int theMode) { bool anIsNotPresent = ~theOutputMode & theMode; if(anIsNotPresent) @@ -503,28 +831,34 @@ if(selected.Extent() >= 1){ SALOME_ListIteratorOfListIO It( selected ); for( ; It.More(); It.Next()){ - Handle(SALOME_InteractiveObject) IObject = It.Value(); - if(IObject->hasEntry()){ - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ - unsigned int aMode = anActor->GetEntityMode(); - switch(theCommandID){ - case 217: - InverseEntityMode(aMode,SMESH_Actor::eEdges); - break; - case 218: - InverseEntityMode(aMode,SMESH_Actor::eFaces); - break; - case 219: - InverseEntityMode(aMode,SMESH_Actor::eVolumes); - break; - case 220: - aMode = SMESH_Actor::eAllEntity; - break; - } - if(aMode) - anActor->SetEntityMode(aMode); - } - } + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ + unsigned int aMode = anActor->GetEntityMode(); + switch(theCommandID){ + case 222: + InverseEntityMode(aMode,SMESH_Actor::eBallElem); + break; + case 216: + InverseEntityMode(aMode,SMESH_Actor::e0DElements); + break; + case 217: + InverseEntityMode(aMode,SMESH_Actor::eEdges); + break; + case 218: + InverseEntityMode(aMode,SMESH_Actor::eFaces); + break; + case 219: + InverseEntityMode(aMode,SMESH_Actor::eVolumes); + break; + case 220: + aMode = SMESH_Actor::eAllEntity; + break; + } + if(aMode) + anActor->SetEntityMode(aMode); + } + } } } } @@ -552,35 +886,231 @@ if( aMainObject->_is_nil() ) return; - aMainObject->SetAutoColor( true ); - - QList aReservedColors; + aMainObject->SetAutoColor( true ); // mesh groups are re-colored here SMESH::ListOfGroups aListOfGroups = *aMainObject->GetGroups(); for( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i]; - SALOMEDS::Color aCurrentColor = aGroupObject->GetColor(); - - SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors ); - aGroupObject->SetColor( aColor ); - aReservedColors.append( aColor ); - + SALOMEDS::Color aColor = aGroupObject->GetColor(); _PTR(SObject) aGroupSObject = SMESH::FindSObject(aGroupObject); - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str())) - { - if( aGroupObject->GetType() == SMESH::NODE ) - anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); - else if( aGroupObject->GetType() == SMESH::EDGE ) - anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); - else - anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B ); + if (aGroupSObject) { + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str())) { + switch ( aGroupObject->GetType ()) { + case SMESH::NODE: + anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break; + case SMESH::EDGE: + anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break; + case SMESH::ELEM0D: + anActor->Set0DColor( aColor.R, aColor.G, aColor.B ); break; + case SMESH::BALL: + anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break; + default: + QColor c; + int delta; + SMESH::GetColor("SMESH", "fill_color", c, delta, "0,170,255|-100"); + anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); + } + } } } SMESH::RepaintCurrentView(); } + QString functorToString( SMESH::Controls::FunctorPtr f ) + { + QString type = QObject::tr( "UNKNOWN_CONTROL" ); + if ( dynamic_cast< SMESH::Controls::Volume* >( f.get() ) ) + type = QObject::tr( "VOLUME_3D_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::MaxElementLength2D* >( f.get() ) ) + type = QObject::tr( "MAX_ELEMENT_LENGTH_2D" ); + else if ( dynamic_cast< SMESH::Controls::MaxElementLength3D* >( f.get() ) ) + type = QObject::tr( "MAX_ELEMENT_LENGTH_3D" ); + else if ( dynamic_cast< SMESH::Controls::MinimumAngle* >( f.get() ) ) + type = QObject::tr( "MINIMUMANGLE_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::AspectRatio* >( f.get() ) ) + type = QObject::tr( "ASPECTRATIO_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::AspectRatio3D* >( f.get() ) ) + type = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Warping* >( f.get() ) ) + type = QObject::tr( "WARP_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Taper* >( f.get() ) ) + type = QObject::tr( "TAPER_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Skew* >( f.get() ) ) + type = QObject::tr( "SKEW_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Area* >( f.get() ) ) + type = QObject::tr( "AREA_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Length* >( f.get() ) ) + type = QObject::tr( "LENGTH_EDGES" ); + else if ( dynamic_cast< SMESH::Controls::Length2D* >( f.get() ) ) + type = QObject::tr( "LENGTH2D_EDGES" ); + else if ( dynamic_cast< SMESH::Controls::MultiConnection* >( f.get() ) ) + type = QObject::tr( "MULTI_BORDERS" ); + else if ( dynamic_cast< SMESH::Controls::MultiConnection2D* >( f.get() ) ) + type = QObject::tr( "MULTI2D_BORDERS" ); + else if ( dynamic_cast< SMESH::Controls::FreeNodes* >( f.get() ) ) + type = QObject::tr( "FREE_NODES" ); + else if ( dynamic_cast< SMESH::Controls::FreeEdges* >( f.get() ) ) + type = QObject::tr( "FREE_EDGES" ); + else if ( dynamic_cast< SMESH::Controls::FreeBorders* >( f.get() ) ) + type = QObject::tr( "FREE_BORDERS" ); + else if ( dynamic_cast< SMESH::Controls::FreeFaces* >( f.get() ) ) + type = QObject::tr( "FREE_FACES" ); + else if ( dynamic_cast< SMESH::Controls::BareBorderVolume* >( f.get() ) ) + type = QObject::tr( "BARE_BORDER_VOLUME" ); + else if ( dynamic_cast< SMESH::Controls::BareBorderFace* >( f.get() ) ) + type = QObject::tr( "BARE_BORDER_FACE" ); + else if ( dynamic_cast< SMESH::Controls::OverConstrainedVolume* >( f.get() ) ) + type = QObject::tr( "OVER_CONSTRAINED_VOLUME" ); + else if ( dynamic_cast< SMESH::Controls::OverConstrainedFace* >( f.get() ) ) + type = QObject::tr( "OVER_CONSTRAINED_FACE" ); + else if ( dynamic_cast< SMESH::Controls::CoincidentNodes* >( f.get() ) ) + type = QObject::tr( "EQUAL_NODE" ); + else if ( dynamic_cast< SMESH::Controls::CoincidentElements1D* >( f.get() ) ) + type = QObject::tr( "EQUAL_EDGE" ); + else if ( dynamic_cast< SMESH::Controls::CoincidentElements2D* >( f.get() ) ) + type = QObject::tr( "EQUAL_FACE" ); + else if ( dynamic_cast< SMESH::Controls::CoincidentElements3D* >( f.get() ) ) + type = QObject::tr( "EQUAL_VOLUME" ); + return type; + } + + void SaveDistribution() + { + LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if ( aSel ) + aSel->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if ( anIO->hasEntry() ) { + SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ); + if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) { + SMESH_ScalarBarActor* aScalarBarActor = anActor->GetScalarBarActor(); + SMESH::Controls::FunctorPtr aFunctor = anActor->GetFunctor(); + if ( aScalarBarActor && aFunctor ) { + SMESH::Controls::NumericalFunctor* aNumFun = dynamic_cast( aFunctor.get() ); + if ( aNumFun ) { + std::vector elements; + SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface(anIO); + if ( mesh->_is_nil() ) { + SMESH::SMESH_IDSource_var idSource = + SMESH::IObjectToInterface(anIO); + if ( !idSource->_is_nil() ) + { + SMESH::long_array_var ids = idSource->GetIDs(); + elements.resize( ids->length() ); + for ( unsigned i = 0; i < elements.size(); ++i ) + elements[i] = ids[i]; + } + } + int nbIntervals = aScalarBarActor->GetMaximumNumberOfColors(); + vtkLookupTable* lookupTable = + static_cast(aScalarBarActor->GetLookupTable()); + double * minmax = lookupTable->GetRange(); + std::vector nbEvents; + std::vector funValues; + aNumFun->GetHistogram( nbIntervals, nbEvents, funValues, elements, minmax ); + QString anInitialPath = ""; + if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) + anInitialPath = QDir::currentPath(); + QString aMeshName = anIO->getName(); + QStringList filter; + filter.append( QObject::tr( "TEXT_FILES_FILTER" ) + " (*.txt)" ); + filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" ); + QString aFilename = anInitialPath + "/" + aMeshName + "_" + + functorToString( aFunctor ).toLower().simplified().replace( QRegExp( " |-" ), "_" ) + ".txt"; + aFilename = SUIT_FileDlg::getFileName( SMESHGUI::desktop(), + aFilename, + filter, + QObject::tr( "SMESH_SAVE_DISTRIBUTION" ), + false ); + if ( !aFilename.isEmpty() ) { + QFile f( aFilename ); + if ( f.open( QFile::WriteOnly | QFile::Truncate ) ) { + QTextStream out( &f ); + out << "# Mesh: " << aMeshName << endl; + out << "# Control: " << functorToString( aFunctor ) << endl; + out << "#" << endl; + out.setFieldWidth( 10 ); + for ( int i = 0; i < qMin( nbEvents.size(), funValues.size()-1 ); i++ ) + out << funValues[i] << "\t" << funValues[i+1] << "\t" << nbEvents[i] << endl; + f.close(); + } + } + } + } + } + } + } + } + + void ShowDistribution() { + LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if ( aSel ) + aSel->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if ( anIO->hasEntry() ) { + SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ); + if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) { + SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor(); + aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility()); + } + } + } + } + +#ifndef DISABLE_PLOT2DVIEWER + void PlotDistribution() { + SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); + if( !app ) + return; + + LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if ( aSel ) + aSel->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if ( anIO->hasEntry() ) { + //Find Actor by entry before getting Plot2d viewer, + //because after call getViewManager( Plot2d_Viewer::Type(), true ) active window is Plot2d Viewer + SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ); + + SUIT_ViewManager* aViewManager = app->getViewManager( Plot2d_Viewer::Type(), true ); // create if necessary + + if( !aViewManager ) + return; + + SPlot2d_Viewer* aView = dynamic_cast(aViewManager->getViewModel()); + if ( !aView ) + return; + + Plot2d_ViewFrame* aPlot = aView->getActiveViewFrame(); + if ( !aPlot ) + return; + + if ( anActor && anActor->GetControlMode() != SMESH_Actor::eNone ) { + SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram(); + QString functorName = functorToString( anActor->GetFunctor()); + QString aHistogramName("%1 : %2"); + aHistogramName = aHistogramName.arg(anIO->getName()).arg(functorName); + aHistogram->setName(aHistogramName); + aHistogram->setHorTitle(functorName); + aHistogram->setVerTitle(QObject::tr("DISTRIBUTION_NB_ENT")); + aPlot->displayObject(aHistogram, true); + } + } + } + } +#endif //DISABLE_PLOT2DVIEWER + void DisableAutoColor(){ LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); SALOME_ListIO selected; @@ -591,12 +1121,13 @@ Handle(SALOME_InteractiveObject) anIObject = selected.First(); SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface(anIObject); if ( !aMesh->_is_nil() ) { - aMesh->SetAutoColor( false ); + aMesh->SetAutoColor( false ); } } } - void SetDisplayMode(int theCommandID){ + void SetDisplayMode(int theCommandID, SMESHGUI_StudyId2MarkerMap& theMarkerMap) + { SALOME_ListIO selected; SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() ); if( !app ) @@ -607,131 +1138,302 @@ if( !aSel || !appStudy ) return; + if( theCommandID == 1134 ) { // Clipping dialog can be activated without selection + if( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) { + aModule->EmitSignalDeactivateDialog(); + if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) ) + (new SMESHGUI_ClippingDlg( aModule, aViewWindow ))->show(); + } + return; + } + _PTR(Study) aStudy = appStudy->studyDS(); aSel->selectedObjects( selected ); if(selected.Extent() >= 1){ switch(theCommandID){ - case 1134:{ - SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); - (new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI() ))->show(); - return; - } case 1133:{ - SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); - (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show(); - return; - }} + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); + (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show(); + return; + } + case 1132:{ + QColor c, e, b, n, c0D, cBall, o, outl, selection, preselection; + int delta; + int size0D = 0, ballSize = 0; + int Edgewidth = 0; + vtkFloatingPointType Shrink = 0.0; + vtkFloatingPointType faces_orientation_scale = 0.0; + bool faces_orientation_3dvectors = false; + + VTK::MarkerType aMarkerTypeCurrent = VTK::MT_NONE; + VTK::MarkerScale aMarkerScaleCurrent = VTK::MS_NONE; + int aMarkerTextureCurrent = 0; + + SALOME_ListIteratorOfListIO It( selected ); + for( ; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ + vtkFloatingPointType color[3]; + anActor->GetSufaceColor(color[0], color[1], color[2],delta); + int c0 = int (color[0] * 255); + int c1 = int (color[1] * 255); + int c2 = int (color[2] * 255); + c.setRgb(c0, c1, c2); + + vtkFloatingPointType edgecolor[3]; + anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]); + c0 = int (edgecolor[0] * 255); + c1 = int (edgecolor[1] * 255); + c2 = int (edgecolor[2] * 255); + e.setRgb(c0, c1, c2); + + vtkFloatingPointType nodecolor[3]; + anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]); + c0 = int (nodecolor[0] * 255); + c1 = int (nodecolor[1] * 255); + c2 = int (nodecolor[2] * 255); + n.setRgb(c0, c1, c2); + + vtkFloatingPointType color0D[3]; + anActor->Get0DColor(color0D[0], color0D[1], color0D[2]); + c0 = int (color0D[0] * 255); + c1 = int (color0D[1] * 255); + c2 = int (color0D[2] * 255); + c0D.setRgb(c0, c1, c2); + + vtkFloatingPointType ballcolor[3]; + anActor->GetBallColor(ballcolor[0], ballcolor[1], ballcolor[2]); + c0 = int (ballcolor[0] * 255); + c1 = int (ballcolor[1] * 255); + c2 = int (ballcolor[2] * 255); + cBall.setRgb(c0, c1, c2); + + vtkFloatingPointType outlineColor[3]; + anActor->GetOutlineColor(outlineColor[0], outlineColor[1], outlineColor[2]); + c0 = int (outlineColor[0] * 255); + c1 = int (outlineColor[1] * 255); + c2 = int (outlineColor[2] * 255); + outl.setRgb(c0, c1, c2); + + vtkFloatingPointType hColor[3]; + anActor->GetHighlightColor(hColor[0], hColor[1], hColor[2]); + c0 = int (hColor[0] * 255); + c1 = int (hColor[1] * 255); + c2 = int (hColor[2] * 255); + selection.setRgb(c0, c1, c2); + + vtkFloatingPointType phColor[3]; + anActor->GetPreHighlightColor(phColor[0], phColor[1], phColor[2]); + c0 = int (phColor[0] * 255); + c1 = int (phColor[1] * 255); + c2 = int (phColor[2] * 255); + preselection.setRgb(c0, c1, c2); + + size0D = (int)anActor->Get0DSize(); + if(size0D == 0) + size0D = 1; + ballSize = (int)anActor->GetBallSize(); + if(ballSize == 0) + ballSize = 1; + Edgewidth = (int)anActor->GetLineWidth(); + if(Edgewidth == 0) + Edgewidth = 1; + Shrink = anActor->GetShrinkFactor(); + + vtkFloatingPointType faces_orientation_color[3]; + anActor->GetFacesOrientationColor(faces_orientation_color); + c0 = int (faces_orientation_color[0] * 255); + c1 = int (faces_orientation_color[1] * 255); + c2 = int (faces_orientation_color[2] * 255); + o.setRgb(c0, c1, c2); + + faces_orientation_scale = anActor->GetFacesOrientationScale(); + faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors(); + + aMarkerTypeCurrent = anActor->GetMarkerType(); + aMarkerScaleCurrent = anActor->GetMarkerScale(); + aMarkerTextureCurrent = anActor->GetMarkerTexture(); + + // even if there are multiple objects in the selection, + // we need only the first one to get values for the dialog + break; + } + } + } + + SMESHGUI_Preferences_ColorDlg *aDlg = + new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() ); + aDlg->SetBooleanValue(1, faces_orientation_3dvectors); + aDlg->SetColor(1, c); + aDlg->SetColor(2, e); + aDlg->SetColor(3, n); + aDlg->SetColor(4, outl); + aDlg->SetColor(5, c0D); + aDlg->SetColor(6, cBall); + aDlg->SetColor(7, o); + aDlg->SetColor(8, selection); + aDlg->SetColor(9, preselection); + aDlg->SetDeltaBrightness(delta); + aDlg->SetDoubleValue(1, faces_orientation_scale); + aDlg->SetIntValue(1, Edgewidth); + aDlg->SetIntValue(2, int(Shrink*100.)); + aDlg->SetIntValue(3, size0D); + aDlg->SetIntValue(4, ballSize); + + aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] ); + + if( aMarkerTypeCurrent != VTK::MT_USER ) + aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent ); + else + aDlg->setCustomMarker( aMarkerTextureCurrent ); + + if(aDlg->exec()){ + QColor color = aDlg->GetColor(1); + QColor edgecolor = aDlg->GetColor(2); + QColor nodecolor = aDlg->GetColor(3); + QColor outlinecolor = aDlg->GetColor(4); + QColor color0D = aDlg->GetColor(5); + QColor ballcolor = aDlg->GetColor(6); + QColor faces_orientation_color = aDlg->GetColor(7); + QColor selectioncolor = aDlg->GetColor(8); + QColor preSelectioncolor = aDlg->GetColor(9); + int delta = aDlg->GetDeltaBrightness(); + + /* Point marker */ + theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap(); + + SALOME_ListIteratorOfListIO It( selected ); + for( ; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ + /* actor color and backface color */ + anActor->SetSufaceColor(vtkFloatingPointType (color.red()) / 255., + vtkFloatingPointType (color.green()) / 255., + vtkFloatingPointType (color.blue()) / 255., + delta); + /* edge color */ + anActor->SetEdgeColor(vtkFloatingPointType (edgecolor.red()) / 255., + vtkFloatingPointType (edgecolor.green()) / 255., + vtkFloatingPointType (edgecolor.blue()) / 255.); + /* edge outline */ + anActor->SetOutlineColor(vtkFloatingPointType (outlinecolor.red()) / 255., + vtkFloatingPointType (outlinecolor.green()) / 255., + vtkFloatingPointType (outlinecolor.blue()) / 255.); + + /* selection */ + anActor->SetHighlightColor(vtkFloatingPointType (selectioncolor.red()) / 255., + vtkFloatingPointType (selectioncolor.green()) / 255., + vtkFloatingPointType (selectioncolor.blue()) / 255.); + /* pre-selection */ + anActor->SetPreHighlightColor(vtkFloatingPointType (preSelectioncolor.red()) / 255., + vtkFloatingPointType (preSelectioncolor.green()) / 255., + vtkFloatingPointType (preSelectioncolor.blue()) / 255.); + + + /* Shrink factor and size edges */ + anActor->SetShrinkFactor(aDlg->GetIntValue(2) / 100.); + anActor->SetLineWidth(aDlg->GetIntValue(1)); + + /* Nodes color and size */ + anActor->SetNodeColor(vtkFloatingPointType (nodecolor.red()) / 255., + vtkFloatingPointType (nodecolor.green()) / 255., + vtkFloatingPointType (nodecolor.blue()) / 255.); + + /* 0D elements */ + anActor->Set0DColor(vtkFloatingPointType (color0D.red()) / 255., + vtkFloatingPointType (color0D.green()) / 255., + vtkFloatingPointType (color0D.blue()) / 255.); + anActor->Set0DSize(aDlg->GetIntValue(3)); + + /* Ball elements */ + anActor->SetBallColor(vtkFloatingPointType (ballcolor.red()) / 255., + vtkFloatingPointType (ballcolor.green()) / 255., + vtkFloatingPointType (ballcolor.blue()) / 255.); + anActor->SetBallSize(aDlg->GetIntValue(4)); + + /* Faces orientation */ + vtkFloatingPointType c[3] = {vtkFloatingPointType(faces_orientation_color.redF()), + vtkFloatingPointType(faces_orientation_color.greenF()), + vtkFloatingPointType(faces_orientation_color.blueF())}; + anActor->SetFacesOrientationColor(c); + anActor->SetFacesOrientationScale(aDlg->GetDoubleValue(1)); + anActor->SetFacesOrientation3DVectors(aDlg->GetBooleanValue(1)); + + VTK::MarkerType aMarkerTypeNew = aDlg->getMarkerType(); + VTK::MarkerScale aMarkerScaleNew = aDlg->getStandardMarkerScale(); + int aMarkerTextureNew = aDlg->getCustomMarkerID(); + if( aMarkerTypeNew != VTK::MT_USER ) + anActor->SetMarkerStd( aMarkerTypeNew, aMarkerScaleNew ); + else { + const VTK::MarkerMap& aMarkerMap = theMarkerMap[ aStudy->StudyId() ]; + VTK::MarkerMap::const_iterator anIter = aMarkerMap.find( aMarkerTextureNew ); + if( anIter != aMarkerMap.end() ) + anActor->SetMarkerTexture( aMarkerTextureNew, anIter->second.second ); + } + + SMESH::SMESH_GroupBase_var aGroupObject = SMESH::IObjectToInterface(IObject); + if( !aGroupObject->_is_nil() ) + { + SMESH::ElementType anElementType = aGroupObject->GetType(); + QColor aColor; + switch( anElementType ) + { + case SMESH::NODE: aColor = nodecolor; break; + case SMESH::EDGE: aColor = edgecolor; break; + default: aColor = color; break; + } + + SALOMEDS::Color aGroupColor; + aGroupColor.R = (float)aColor.red() / 255.0; + aGroupColor.G = (float)aColor.green() / 255.0; + aGroupColor.B = (float)aColor.blue() / 255.0; + aGroupObject->SetColor( aGroupColor ); + } + } + } + } + SMESH::RepaintCurrentView(); + } + delete aDlg; + return; + } + } SALOME_ListIteratorOfListIO It( selected ); for( ; It.More(); It.Next()){ - Handle(SALOME_InteractiveObject) IObject = It.Value(); - if(IObject->hasEntry()){ - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ - switch(theCommandID){ - case 211: - anActor->SetRepresentation(SMESH_Actor::eEdge); - break; - case 212: - anActor->SetRepresentation(SMESH_Actor::eSurface); - break; - case 213: - if(anActor->IsShrunk()) - anActor->UnShrink(); - else - anActor->SetShrink(); - break; - case 215: - anActor->SetRepresentation(SMESH_Actor::ePoint); - break; - case 1132:{ - vtkFloatingPointType color[3]; - anActor->GetSufaceColor(color[0], color[1], color[2]); - int c0 = int (color[0] * 255); - int c1 = int (color[1] * 255); - int c2 = int (color[2] * 255); - QColor c(c0, c1, c2); - - vtkFloatingPointType edgecolor[3]; - anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]); - c0 = int (edgecolor[0] * 255); - c1 = int (edgecolor[1] * 255); - c2 = int (edgecolor[2] * 255); - QColor e(c0, c1, c2); - - vtkFloatingPointType backfacecolor[3]; - anActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]); - c0 = int (backfacecolor[0] * 255); - c1 = int (backfacecolor[1] * 255); - c2 = int (backfacecolor[2] * 255); - QColor b(c0, c1, c2); - - vtkFloatingPointType nodecolor[3]; - anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]); - c0 = int (nodecolor[0] * 255); - c1 = int (nodecolor[1] * 255); - c2 = int (nodecolor[2] * 255); - QColor n(c0, c1, c2); - - int Edgewidth = (int)anActor->GetLineWidth(); - if(Edgewidth == 0) - Edgewidth = 1; - int intValue = int(anActor->GetNodeSize()); - vtkFloatingPointType Shrink = anActor->GetShrinkFactor(); - - SMESHGUI_Preferences_ColorDlg *aDlg = - new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() ); - aDlg->SetColor(1, c); - aDlg->SetColor(2, e); - aDlg->SetColor(3, n); - aDlg->SetColor(4, b); - aDlg->SetIntValue(1, Edgewidth); - aDlg->SetIntValue(2, intValue); - aDlg->SetIntValue(3, int(Shrink*100.)); - if(aDlg->exec()){ - QColor color = aDlg->GetColor(1); - QColor edgecolor = aDlg->GetColor(2); - QColor nodecolor = aDlg->GetColor(3); - QColor backfacecolor = aDlg->GetColor(4); - /* actor color and backface color */ - anActor->SetSufaceColor(vtkFloatingPointType (color.red()) / 255., - vtkFloatingPointType (color.green()) / 255., - vtkFloatingPointType (color.blue()) / 255.); - anActor->SetBackSufaceColor(vtkFloatingPointType (backfacecolor.red()) / 255., - vtkFloatingPointType (backfacecolor.green()) / 255., - vtkFloatingPointType (backfacecolor.blue()) / 255.); - - /* edge color */ - anActor->SetEdgeColor(vtkFloatingPointType (edgecolor.red()) / 255., - vtkFloatingPointType (edgecolor.green()) / 255., - vtkFloatingPointType (edgecolor.blue()) / 255.); - - /* Shrink factor and size edges */ - anActor->SetShrinkFactor(aDlg->GetIntValue(3) / 100.); - anActor->SetLineWidth(aDlg->GetIntValue(1)); - - /* Nodes color and size */ - anActor->SetNodeColor(vtkFloatingPointType (nodecolor.red()) / 255., - vtkFloatingPointType (nodecolor.green()) / 255., - vtkFloatingPointType (nodecolor.blue()) / 255.); - anActor->SetNodeSize(aDlg->GetIntValue(2)); - - SMESH::SMESH_GroupBase_var aGroupObject = SMESH::IObjectToInterface(IObject); - if( !aGroupObject->_is_nil() ) - { - SALOMEDS::Color aColor; - aColor.R = (float)color.red() / 255.0; - aColor.G = (float)color.green() / 255.0; - aColor.B = (float)color.blue() / 255.0; - aGroupObject->SetColor( aColor ); - } - - delete aDlg; - } - break; - }} - } - } + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ + switch(theCommandID){ + case 211: + anActor->SetRepresentation(SMESH_Actor::eEdge); + break; + case 212: + anActor->SetRepresentation(SMESH_Actor::eSurface); + break; + case 213: + if(anActor->IsShrunk()) + anActor->UnShrink(); + else + anActor->SetShrink(); + break; + case 215: + anActor->SetRepresentation(SMESH_Actor::ePoint); + break; + case 231: + if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines) + anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines); + break; + case 232: + if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs) + anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs); + break; + } + } + } } SMESH::RepaintCurrentView(); } @@ -747,88 +1449,113 @@ if( !selected.IsEmpty() ){ Handle(SALOME_InteractiveObject) anIO = selected.First(); if(!anIO.IsNull()){ - QString aTitle; - SMESH_Actor::eControl aControl = SMESH_Actor::eNone; - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())){ - switch ( theCommandID ){ - case 6001: - aTitle = QObject::tr( "LENGTH_EDGES" ); - aControl = SMESH_Actor::eLength; - break; - case 6018: - aTitle = QObject::tr( "LENGTH2D_EDGES" ); - aControl = SMESH_Actor::eLength2D; - break; - case 6002: - aTitle = QObject::tr( "FREE_EDGES" ); - aControl = SMESH_Actor::eFreeEdges; - break; - case 6003: - aTitle = QObject::tr( "FREE_BORDERS" ); - aControl = SMESH_Actor::eFreeBorders; - break; - case 6004: - aTitle = QObject::tr( "MULTI_BORDERS" ); - aControl = SMESH_Actor::eMultiConnection; - break; - case 6005: - aTitle = QObject::tr( "FREE_NODES" ); - aControl = SMESH_Actor::eFreeNodes; - break; - case 6019: - aTitle = QObject::tr( "MULTI2D_BORDERS" ); - aControl = SMESH_Actor::eMultiConnection2D; - break; - case 6011: - aTitle = QObject::tr( "AREA_ELEMENTS" ); - aControl = SMESH_Actor::eArea; - break; - case 6012: - aTitle = QObject::tr( "TAPER_ELEMENTS" ); - aControl = SMESH_Actor::eTaper; - break; - case 6013: - aTitle = QObject::tr( "ASPECTRATIO_ELEMENTS" ); - aControl = SMESH_Actor::eAspectRatio; - break; - case 6017: - aTitle = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" ); - aControl = SMESH_Actor::eAspectRatio3D; - break; - case 6014: - aTitle = QObject::tr( "MINIMUMANGLE_ELEMENTS" ); - aControl = SMESH_Actor::eMinimumAngle; - break; - case 6015: - aTitle = QObject::tr( "WARP_ELEMENTS" ); - aControl = SMESH_Actor::eWarping; - break; - case 6016: - aTitle = QObject::tr( "SKEW_ELEMENTS" ); - aControl = SMESH_Actor::eSkew; - break; - case 6009: - aTitle = QObject::tr( "SMESH_VOLUME" ); - aControl = SMESH_Actor::eVolume3D; - break; - case 6021: - aTitle = QObject::tr( "FREE_FACES" ); - aControl = SMESH_Actor::eFreeFaces; - break; - } - anActor->SetControlMode(aControl); - anActor->GetScalarBarActor()->SetTitle(aTitle.toLatin1().data()); - SMESH::RepaintCurrentView(); - } + SMESH_Actor::eControl aControl = SMESH_Actor::eNone; + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())) { + switch ( theCommandID ){ + case 6001: + aControl = SMESH_Actor::eLength; + break; + case 6018: + aControl = SMESH_Actor::eLength2D; + break; + case 6002: + aControl = SMESH_Actor::eFreeEdges; + break; + case 6003: + aControl = SMESH_Actor::eFreeBorders; + break; + case 6004: + aControl = SMESH_Actor::eMultiConnection; + break; + case 6005: + aControl = SMESH_Actor::eFreeNodes; + break; + case 6019: + aControl = SMESH_Actor::eMultiConnection2D; + break; + case 6011: + aControl = SMESH_Actor::eArea; + break; + case 6012: + aControl = SMESH_Actor::eTaper; + break; + case 6013: + aControl = SMESH_Actor::eAspectRatio; + break; + case 6017: + aControl = SMESH_Actor::eAspectRatio3D; + break; + case 6014: + aControl = SMESH_Actor::eMinimumAngle; + break; + case 6015: + aControl = SMESH_Actor::eWarping; + break; + case 6016: + aControl = SMESH_Actor::eSkew; + break; + case 6009: + aControl = SMESH_Actor::eVolume3D; + break; + case 6021: + aControl = SMESH_Actor::eFreeFaces; + break; + case 6022: + aControl = SMESH_Actor::eMaxElementLength2D; + break; + case 6023: + aControl = SMESH_Actor::eMaxElementLength3D; + break; + case 6024: + aControl = SMESH_Actor::eBareBorderVolume; + break; + case 6025: + aControl = SMESH_Actor::eBareBorderFace; + break; + case 6026: + aControl = SMESH_Actor::eOverConstrainedVolume; + break; + case 6027: + aControl = SMESH_Actor::eOverConstrainedFace; + break; + case 6028: + aControl = SMESH_Actor::eCoincidentNodes; + break; + case 6029: + aControl = SMESH_Actor::eCoincidentElems1D; + break; + case 6030: + aControl = SMESH_Actor:: eCoincidentElems2D; + break; + case 6031: + aControl = SMESH_Actor::eCoincidentElems3D; + break; + } + + anActor->SetControlMode(aControl); + anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() ); + SMESH::RepaintCurrentView(); +#ifndef DISABLE_PLOT2DVIEWER + if(anActor->GetPlot2Histogram()) { + SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram(); + QString functorName = functorToString( anActor->GetFunctor()); + QString aHistogramName("%1 : %2"); + aHistogramName = aHistogramName.arg(anIO->getName()).arg(functorName); + aHistogram->setName(aHistogramName); + aHistogram->setHorTitle(functorName); + SMESH::ProcessIn2DViewers(anActor); + } +#endif + } } } } bool CheckOIType(const Handle(SALOME_InteractiveObject) & theIO, - MeshObjectType theType, - const QString theInTypeName, - QString & theOutTypeName) + MeshObjectType theType, + const QString theInTypeName, + QString & theOutTypeName) { SMESH_TypeFilter aTypeFilter( theType ); QString entry; @@ -853,17 +1580,17 @@ _PTR(SComponent) aSComp = aSObj->GetFatherComponent(); CORBA::String_var anID = aSComp->GetID().c_str(); if (!strcmp(anID.in(),theIO->getEntry())) - return "Component"; + return "Component"; } QString aTypeName; if ( - CheckOIType ( theIO, HYPOTHESIS, "Hypothesis", aTypeName ) || - CheckOIType ( theIO, ALGORITHM, "Algorithm", aTypeName ) || - CheckOIType ( theIO, MESH, "Mesh", aTypeName ) || - CheckOIType ( theIO, SUBMESH, "SubMesh", aTypeName ) || - CheckOIType ( theIO, GROUP, "Group", aTypeName ) - ) + CheckOIType ( theIO, HYPOTHESIS, "Hypothesis", aTypeName ) || + CheckOIType ( theIO, ALGORITHM, "Algorithm", aTypeName ) || + CheckOIType ( theIO, MESH, "Mesh", aTypeName ) || + CheckOIType ( theIO, SUBMESH, "SubMesh", aTypeName ) || + CheckOIType ( theIO, GROUP, "Group", aTypeName ) + ) return aTypeName; return "NoType"; @@ -882,10 +1609,10 @@ SALOME_ListIteratorOfListIO It(selected); for ( ; It.More(); It.Next()) { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - QString Type = CheckTypeObject(IObject); - if (Type.compare(RefType) != 0) - return "Heterogeneous Selection"; + Handle(SALOME_InteractiveObject) IObject = It.Value(); + QString Type = CheckTypeObject(IObject); + if (Type.compare(RefType) != 0) + return "Heterogeneous Selection"; } return RefType; @@ -913,17 +1640,17 @@ QString cur = anIO->getComponentDataType(); _PTR(SObject) aSO = aStudy->FindObjectID(anIO->getEntry()); if (aSO) { - // check if object is reference - _PTR(SObject) aRefSObj; - aNameList.append("\n - "); - if ( aSO->ReferencedObject( aRefSObj ) ) { - QString aRefName = QString::fromStdString ( aRefSObj->GetName() ); - aNameList.append( aRefName ); - cur = QString::fromStdString ( aRefSObj->GetFatherComponent()->ComponentDataType() ); - } - else - aNameList.append(anIO->getName()); - objectCount++; + // check if object is reference + _PTR(SObject) aRefSObj; + aNameList.append("\n - "); + if ( aSO->ReferencedObject( aRefSObj ) ) { + QString aRefName = QString::fromStdString ( aRefSObj->GetName() ); + aNameList.append( aRefName ); + cur = QString::fromStdString ( aRefSObj->GetFatherComponent()->ComponentDataType() ); + } + else + aNameList.append(anIO->getName()); + objectCount++; } if( aParentComponent.isNull() ) @@ -937,46 +1664,42 @@ if ( aParentComponent != SMESHGUI::GetSMESHGUI()->name() ) { SUIT_MessageBox::warning( SMESHGUI::desktop(), - QObject::tr("ERR_ERROR"), - QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ) ); + QObject::tr("ERR_ERROR"), + QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ) ); return; } // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish if (SUIT_MessageBox::warning - (SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_REALLY_DELETE").arg( objectCount ).arg( aNameList ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::Yes) != SUIT_MessageBox::Yes) + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_REALLY_DELETE").arg( objectCount ).arg( aNameList ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes) != SUIT_MessageBox::Yes) return; SalomeApp_Application* anApp = dynamic_cast( SUIT_Session::session()->activeApplication() ); - SUIT_ViewManager* vm = anApp->activeViewManager(); - int nbSf = vm->getViewsCount(); + // Put the whole hierarchy of sub-objects of the selected SO's into a list and + // then treat them all starting from the deepest objects (at list back) + std::list< _PTR(SObject) > listSO; SALOME_ListIteratorOfListIO It(selected); - - aStudyBuilder->NewCommand(); // There is a transaction - for( ; It.More(); It.Next()){ // loop on selected IO's + for( ; It.More(); It.Next()) // loop on selected IO's + { Handle(SALOME_InteractiveObject) IObject = It.Value(); if(IObject->hasEntry()) { - _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry()); - - // disable removal of "SMESH" component object - if(aSO->FindAttribute(anAttr, "AttributeIOR")){ - anIOR = anAttr; - if ( engineIOR() == anIOR->Value().c_str() ) - continue; - } - //Check the referenced object - _PTR(SObject) aRefSObject; - if ( aSO && aSO->ReferencedObject( aRefSObject ) ) - aSO = aRefSObject; // Delete main Object instead of reference - - // put the whole hierarchy of sub-objects of the selected SO into a list and - // then treat them all starting from the deepest objects (at list back) - - std::list< _PTR(SObject) > listSO; + _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry()); + + // disable removal of "SMESH" component object + if(aSO->FindAttribute(anAttr, "AttributeIOR")){ + anIOR = anAttr; + if ( engineIOR() == anIOR->Value().c_str() ) + continue; + } + //Check the referenced object + _PTR(SObject) aRefSObject; + if ( aSO && aSO->ReferencedObject( aRefSObject ) ) + aSO = aRefSObject; // Delete main Object instead of reference + listSO.push_back( aSO ); std::list< _PTR(SObject) >::iterator itSO = listSO.begin(); for ( ; itSO != listSO.end(); ++itSO ) { @@ -984,60 +1707,87 @@ for (it->InitEx(false); it->More(); it->Next()) listSO.push_back( it->Value() ); } + } + } + // Check if none of objects to delete is referred from outside + std::list< _PTR(SObject) >::reverse_iterator ritSO; + for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO ) + { + _PTR(SObject) SO = *ritSO; + if ( !SO ) continue; + std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO ); + for (size_t i = 0; i < aReferences.size(); i++) { + _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent(); + std::string type = aComponent->ComponentDataType(); + if ( type != "SMESH" ) + { + SUIT_MessageBox::warning( anApp->desktop(), + QObject::tr("WRN_WARNING"), + QObject::tr("DEP_OBJECT") ); + return; // outside SMESH, there is an object depending on a SMESH object + } + } + } - // treat SO's in the list starting from the back - - std::list< _PTR(SObject) >::reverse_iterator ritSO = listSO.rbegin(); - for ( ; ritSO != listSO.rend(); ++ritSO ) { - _PTR(SObject) SO = *ritSO; - if ( !SO ) continue; - std::string anEntry = SO->GetID(); - - /** Erase graphical object **/ - if(SO->FindAttribute(anAttr, "AttributeIOR")){ - QVector aViews = vm->getViews(); - for(int i = 0; i < nbSf; i++){ - SUIT_ViewWindow *sf = aViews[i]; - if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){ - SMESH::RemoveActor(sf,anActor); - } - } - } - - /** Remove an object from data structures **/ - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO )); - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO )); - if ( !aGroup->_is_nil() ) { // DELETE GROUP - SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh(); - aMesh->RemoveGroup( aGroup ); + // Treat SO's in the list starting from the back + aStudyBuilder->NewCommand(); // There is a transaction + for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO ) + { + _PTR(SObject) SO = *ritSO; + if ( !SO ) continue; + std::string anEntry = SO->GetID(); + + /** Erase graphical object **/ + if(SO->FindAttribute(anAttr, "AttributeIOR")){ + ViewManagerList aViewMenegers = anApp->viewManagers(); + ViewManagerList::const_iterator it = aViewMenegers.begin(); + for( ; it != aViewMenegers.end(); it++) { + SUIT_ViewManager* vm = *it; + int nbSf = vm ? vm->getViewsCount() : 0; + if(vm) { + QVector aViews = vm->getViews(); + for(int i = 0; i < nbSf; i++){ + SUIT_ViewWindow *sf = aViews[i]; + if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){ + SMESH::RemoveActor(sf,anActor); + } + } } - else if ( !aSubMesh->_is_nil() ) { // DELETE SUBMESH - SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); - aMesh->RemoveSubMesh( aSubMesh ); + } + } + /** Remove an object from data structures **/ + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO )); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO )); + if ( !aGroup->_is_nil() ) { // DELETE GROUP + SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh(); + aMesh->RemoveGroup( aGroup ); + } + else if ( !aSubMesh->_is_nil() ) { // DELETE SUBMESH + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + aMesh->RemoveSubMesh( aSubMesh ); - _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh); - if (aMeshSO) - SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0); - } - else { - IObject = new SALOME_InteractiveObject - ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() ); - QString objType = CheckTypeObject(IObject); - if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS - SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject); - aStudyBuilder->RemoveObjectWithChildren( SO ); - } - else {// default action: remove SObject from the study + _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh); + if (aMeshSO) + SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0); + } + else { + Handle(SALOME_InteractiveObject) IObject = new SALOME_InteractiveObject + ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() ); + QString objType = CheckTypeObject(IObject); + if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS + SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject); + aStudyBuilder->RemoveObjectWithChildren( SO ); + } + else {// default action: remove SObject from the study // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy); //op->start(); - aStudyBuilder->RemoveObjectWithChildren( SO ); - //op->finish(); - } - } - } /* listSO back loop */ - } /* IObject->hasEntry() */ - } /* more/next */ + aStudyBuilder->RemoveObjectWithChildren( SO ); + //op->finish(); + } + } + } /* listSO back loop */ + aStudyBuilder->CommitCommand(); /* Clear any previous selection */ @@ -1046,13 +1796,17 @@ SMESHGUI::GetSMESHGUI()->updateObjBrowser(); } -//} +//} namespace extern "C" { SMESHGUI_EXPORT CAM_Module* createModule() { return new SMESHGUI(); } + + SMESHGUI_EXPORT char* getModuleVersion() { + return (char*)SMESH_VERSION_STR; + } } SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil(); @@ -1063,12 +1817,14 @@ SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil(); */ //============================================================================= SMESHGUI::SMESHGUI() : -SalomeApp_Module( "SMESH" ) +SalomeApp_Module( "SMESH" ), +LightApp_Module( "SMESH" ) { if ( CORBA::is_nil( myComponentSMESH ) ) { CORBA::Boolean anIsEmbeddedMode; myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode); + MESSAGE("-------------------------------> anIsEmbeddedMode=" << anIsEmbeddedMode); // 0019923: EDF 765 SMESH : default values of hypothesis SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this); @@ -1076,6 +1832,14 @@ SalomeApp_Module( "SMESH" ) myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg ); nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 ); myComponentSMESH->SetDefaultNbSegments( nbSeg ); + + const char* options[] = { "historical_python_dump", "forget_mesh_on_hyp_modif" }; + for ( size_t i = 0; i < sizeof(options)/sizeof(char*); ++i ) + if ( aResourceMgr->hasValue( "SMESH", options[i] )) + { + QString val = aResourceMgr->stringValue( "SMESH", options[i] ); + myComponentSMESH->SetOption( options[i], val.toLatin1().constData() ); + } } myActiveDialogBox = 0; @@ -1083,8 +1847,15 @@ SalomeApp_Module( "SMESH" ) myState = -1; myDisplayer = 0; + myEventCallbackCommand = vtkCallbackCommand::New(); + myEventCallbackCommand->Delete(); + myEventCallbackCommand->SetClientData( this ); + myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents ); + myPriority = 0.0; + SMESH::GetFilterManager(); SMESH::GetPattern(); + SMESH::GetMeasurements(); /* load resources for all available meshers */ SMESH::InitAvailableHypotheses(); @@ -1097,8 +1868,12 @@ SalomeApp_Module( "SMESH" ) //============================================================================= SMESHGUI::~SMESHGUI() { - SMESH::GetFilterManager()->Destroy(); +#ifdef WITHGENERICOBJ + SMESH::GetFilterManager()->UnRegister(); + SMESH::GetMeasurements()->UnRegister(); +#endif SMESH::GetFilterManager() = SMESH::FilterManager::_nil(); + SMESH::GetMeasurements() = SMESH::Measurements::_nil(); } //============================================================================= @@ -1115,13 +1890,22 @@ LightApp_SelectionMgr* SMESHGUI::selectionMgr() return 0; } -bool SMESHGUI::automaticUpdate() +//============================================================================= +/*! + * + */ +//============================================================================= +bool SMESHGUI::automaticUpdate(unsigned int requestedSize, bool* limitExceeded) { SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if ( !resMgr ) return false; - return resMgr->booleanValue( "SMESH", "auto_update", false ); + bool autoUpdate = resMgr->booleanValue( "SMESH", "auto_update", false ); + long updateLimit = resMgr->integerValue( "SMESH", "update_limit", 500000 ); + bool exceeded = updateLimit > 0 && requestedSize > updateLimit; + if ( limitExceeded ) *limitExceeded = autoUpdate && exceeded; + return autoUpdate && !exceeded; } //============================================================================= @@ -1156,7 +1940,7 @@ SMESHGUI* SMESHGUI::GetSMESHGUI() { _PTR(Study) aStudy = study->studyDS(); if ( aStudy ) - GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() ); + GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() ); } } @@ -1221,6 +2005,16 @@ void SMESHGUI::EmitSignalCloseAllDialogs() emit SignalCloseAllDialogs(); } +//============================================================================= +/*! + * + */ +//============================================================================= +void SMESHGUI::EmitSignalVisibilityChanged() +{ + emit SignalVisibilityChanged(); +} + //============================================================================= /*! * @@ -1275,9 +2069,15 @@ SalomeApp_Study* SMESHGUI::activeStudy() * */ //============================================================================= -char* SMESHGUI::JoinObjectParameters(const QStringList& theParametersList) +void SMESHGUI::Modified( bool theIsUpdateActions ) { - return theParametersList.join(":").toLatin1().data(); + if( SalomeApp_Application* app = dynamic_cast( SUIT_Session::session()->activeApplication() ) ) { + if( SalomeApp_Study* appStudy = dynamic_cast( app->activeStudy() ) ) { + appStudy->Modified(); + if( theIsUpdateActions ) + app->updateActions(); + } + } } //============================================================================= @@ -1308,8 +2108,8 @@ static int isStudyLocked(_PTR(Study) theStudy){ static bool checkLock(_PTR(Study) theStudy) { if (isStudyLocked(theStudy)) { SUIT_MessageBox::warning( SMESHGUI::desktop(), - QObject::tr("WRN_WARNING"), - QObject::tr("WRN_STUDY_LOCKED") ); + QObject::tr("WRN_WARNING"), + QObject::tr("WRN_STUDY_LOCKED") ); return true; } return false; @@ -1351,15 +2151,18 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) //QAction* act = action( theCommandID ); - switch (theCommandID) { - case 33: // DELETE + switch (theCommandID) { + case 33: // DELETE if(checkLock(aStudy)) break; OnEditDelete(); break; - case 113: // IMPORT + case 116: + case 115: + case 117: + case 113: case 112: - case 111: + case 111: // IMPORT { if(checkLock(aStudy)) break; ::ImportMeshesFromFile(GetSMESHGen(),theCommandID); @@ -1385,7 +2188,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } - case 122: // EXPORT MED + case 122: // EXPORT MED case 121: case 123: case 124: @@ -1393,12 +2196,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case 126: case 140: case 141: + case 142: + case 143: + case 144: + case 145: { ::ExportMeshToFile(theCommandID); break; } - case 200: // SCALAR BAR + case 200: // SCALAR BAR { LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); SALOME_ListIO selected; @@ -1406,12 +2213,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) aSel->selectedObjects( selected ); if( selected.Extent() ) { - Handle(SALOME_InteractiveObject) anIO = selected.First(); - if( anIO->hasEntry() ) { - if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) { - anActor->SetControlMode( SMESH_Actor::eNone ); - } - } + Handle(SALOME_InteractiveObject) anIO = selected.First(); + if( anIO->hasEntry() ) { + if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) { + anActor->SetControlMode( SMESH_Actor::eNone ); +#ifndef DISABLE_PLOT2DVIEWER + SMESH::ProcessIn2DViewers(anActor,SMESH::RemoveFrom2dViewer); +#endif + } + } } break; } @@ -1420,6 +2230,28 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this ); break; } + case 2021: + { + // dump control distribution data to the text file + ::SaveDistribution(); + break; + } + + case 2022: + { + // show/ distribution + ::ShowDistribution(); + break; + } + +#ifndef DISABLE_PLOT2DVIEWER + case 2023: + { + // plot distribution + ::PlotDistribution(); + break; + } +#endif // Auto-color case 1136: @@ -1432,21 +2264,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case 1134: // Clipping case 1133: // Tranparency - case 1132: // Colors / Size + case 1132: // Display preferences (colors, shrink size, line width, ...) // Display Mode case 215: // Nodes case 213: // Nodes case 212: // Nodes case 211: // Nodes - ::SetDisplayMode(theCommandID); + ::SetDisplayMode(theCommandID, myMarkerMap); break; - // Display Entity + //2D quadratic representation + case 231: + case 232: + ::SetDisplayMode(theCommandID, myMarkerMap); + break; + + // Display Entity + case 216: // 0D elements case 217: // Edges case 218: // Faces case 219: // Volumes case 220: // All Entity + case 222: // Balls ::SetDisplayEntity(theCommandID); break; @@ -1458,16 +2298,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SALOME_ListIteratorOfListIO it(selected); for( ; it.More(); it.Next()) { Handle(SALOME_InteractiveObject) anIObject = it.Value(); - if(anIObject->hasEntry()) { - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ - anActor->SetFacesOriented( !anActor->GetFacesOriented() ); - } - } + if(anIObject->hasEntry()) { + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ + anActor->SetFacesOriented( !anActor->GetFacesOriented() ); + } + } } break; } - case 214: // UPDATE + case 214: // UPDATE { if(checkLock(aStudy)) break; try { @@ -1490,15 +2330,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } - case 300: // ERASE - case 301: // DISPLAY - case 302: // DISPLAY ONLY + case 300: // ERASE + case 301: // DISPLAY + case 302: // DISPLAY ONLY { SMESH::EDisplaing anAction; switch (theCommandID) { - case 300: anAction = SMESH::eErase; break; - case 301: anAction = SMESH::eDisplay; break; - case 302: anAction = SMESH::eDisplayOnly; break; + case 300: anAction = SMESH::eErase; break; + case 301: anAction = SMESH::eDisplay; break; + case 302: anAction = SMESH::eDisplayOnly; break; } LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); @@ -1507,7 +2347,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) aSel->selectedObjects( sel_objects ); if( theCommandID==302 ) - startOperation( myEraseAll ); + { + MESSAGE("anAction = SMESH::eDisplayOnly"); + startOperation( myEraseAll ); + } extractContainers( sel_objects, to_process ); @@ -1518,19 +2361,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if (vtkwnd) { SALOME_ListIteratorOfListIO It( to_process ); for ( ; It.More(); It.Next()) { + MESSAGE("---"); Handle(SALOME_InteractiveObject) IOS = It.Value(); if (IOS->hasEntry()) { - if (!SMESH::UpdateView(anAction, IOS->getEntry())) + MESSAGE("---"); + if (!SMESH::UpdateView(anAction, IOS->getEntry())) { + SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged(); break; // PAL16774 (Crash after display of many groups) + } if (anAction == SMESH::eDisplayOnly) + { + MESSAGE("anAction = SMESH::eDisplayOnly"); anAction = SMESH::eDisplay; + } } } } // PAL13338 + PAL15161 --> - if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) + if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) { + MESSAGE("anAction = SMESH::eDisplayOnly"); SMESH::UpdateView(); + SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged(); + } // PAL13338 + PAL15161 <-- } catch (...) { // PAL16774 (Crash after display of many groups) @@ -1538,28 +2391,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } if (anAction == SMESH::eErase) { - SALOME_ListIO l1; - aSel->setSelectedObjects( l1 ); + MESSAGE("anAction == SMESH::eErase"); + SALOME_ListIO l1; + aSel->setSelectedObjects( l1 ); } else - aSel->setSelectedObjects( to_process ); + aSel->setSelectedObjects( to_process ); break; } - case 400: // NODES + case 4000: // NODES { if(checkLock(aStudy)) break; if ( vtkwnd ) { - EmitSignalDeactivateDialog(); + EmitSignalDeactivateDialog(); - ( new SMESHGUI_NodesDlg( this ) )->show(); + ( new SMESHGUI_NodesDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -1574,33 +2428,22 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } - case 406: // MOVE NODE - { - if ( !vtkwnd ) - { - SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); - break; - } - - if(checkLock(aStudy)) break; - ( new SMESHGUI_MoveNodesDlg( this ) )->show(); - break; - } - - case 701: // COMPUTE MESH - case 711: // PRECOMPUTE MESH - { - if (checkLock(aStudy)) break; - startOperation( theCommandID ); - } - break; - + case 701: // COMPUTE MESH + case 711: // PRECOMPUTE MESH + case 712: // EVALUATE MESH + case 713: // MESH ORDER case 702: // Create mesh case 703: // Create sub-mesh case 704: // Edit mesh/sub-mesh startOperation( theCommandID ); break; + case 705: // copy mesh + { + if (checkLock(aStudy)) break; + EmitSignalDeactivateDialog(); + ( new SMESHGUI_CopyMeshDlg( this ) )->show(); + } + break; case 710: // Build compound mesh { if (checkLock(aStudy)) break; @@ -1615,7 +2458,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1638,14 +2481,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) ( new SMESHGUI_UnionOfTwoTrianglesDlg( this ) )->show(); break; } - case 409: // Change orientation - case 410: // Union of triangles - case 411: // Cutting of quadrangles + case 409: // Change orientation + case 410: // Union of triangles + case 411: // Cutting of quadrangles + case 419: // Splitting volumes into tetrahedra { if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1658,6 +2502,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) aDlg = new SMESHGUI_ChangeOrientationDlg(this); else if ( theCommandID == 410 ) aDlg = new SMESHGUI_UnionOfTrianglesDlg(this); + else if ( theCommandID == 419 ) + aDlg = new SMESHGUI_CuttingIntoTetraDlg(this); else aDlg = new SMESHGUI_CuttingOfQuadsDlg(this); @@ -1668,12 +2514,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_SmoothingDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_SmoothingDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -1681,11 +2527,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if (checkLock(aStudy)) break; if (vtkwnd) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_ExtrusionDlg ( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_ExtrusionDlg ( this ) )->show(); } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -1693,12 +2539,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_RevolutionDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_RevolutionDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -1712,8 +2558,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) ( new SMESHGUI_MeshPatternDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -1721,30 +2567,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if (checkLock(aStudy)) break; if (vtkwnd) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show(); - } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); - } - break; - } - case 417: // Convert mesh to quadratic - { - startOperation( 417 ); - /* if (checkLock(aStudy)) break; - if (vtkwnd) { - EmitSignalDeactivateDialog(); - new SMESHGUI_ConvToQuadDlg(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); - }*/ + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } break; } - case 806: // CREATE GEO GROUP + case 417: // Convert mesh to quadratic + case 418: // create 2D mesh from 3D + case 420: // Reorient faces + case 806: // CREATE GEO GROUP { - startOperation( 806 ); + startOperation( theCommandID ); break; } case 801: // CREATE GROUP @@ -1752,7 +2588,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1767,7 +2603,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) int nbSel = selected.Extent(); if (nbSel == 1) { - // check if mesh is selected + // check if mesh is selected aMesh = SMESH::GetMeshByIO( selected.First() ); } SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aMesh); @@ -1780,7 +2616,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1794,52 +2630,61 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) int nbSel = selected.Extent(); if (nbSel == 1) { - // check if submesh is selected - Handle(SALOME_InteractiveObject) IObject = selected.First(); - if (IObject->hasEntry()) { - _PTR(SObject) aSObj = aStudy->FindObjectID(IObject->getEntry()); - if( aSObj ) { - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( aSObj ) ); - if (!aSubMesh->_is_nil()) { - try { - SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); - // get submesh elements list by types - SMESH::long_array_var aNodes = aSubMesh->GetElementsByType(SMESH::NODE); - SMESH::long_array_var aEdges = aSubMesh->GetElementsByType(SMESH::EDGE); - SMESH::long_array_var aFaces = aSubMesh->GetElementsByType(SMESH::FACE); - SMESH::long_array_var aVolumes = aSubMesh->GetElementsByType(SMESH::VOLUME); - // create group for each type o elements - QString aName = IObject->getName(); - if (aNodes->length() > 0) { - SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::NODE, aName + "_Nodes"); - aGroup->Add(aNodes.inout()); - } - if (aEdges->length() > 0) { - SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::EDGE, aName + "_Edges"); - aGroup->Add(aEdges.inout()); - } - if (aFaces->length() > 0) { - SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::FACE, aName + "_Faces"); - aGroup->Add(aFaces.inout()); - } - if (aVolumes->length() > 0) { - SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::VOLUME, aName + "_Volumes"); - aGroup->Add(aVolumes.inout()); - } - updateObjBrowser(); - - } + // check if submesh is selected + Handle(SALOME_InteractiveObject) IObject = selected.First(); + if (IObject->hasEntry()) { + _PTR(SObject) aSObj = aStudy->FindObjectID(IObject->getEntry()); + if( aSObj ) { + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( aSObj ) ); + if (!aSubMesh->_is_nil()) { + try { + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + // get submesh elements list by types + SMESH::long_array_var aNodes = aSubMesh->GetElementsByType(SMESH::NODE); + SMESH::long_array_var aEdges = aSubMesh->GetElementsByType(SMESH::EDGE); + SMESH::long_array_var aFaces = aSubMesh->GetElementsByType(SMESH::FACE); + SMESH::long_array_var aVolumes = aSubMesh->GetElementsByType(SMESH::VOLUME); + // create group for each type o elements + QString aName = IObject->getName(); + QStringList anEntryList; + if (aNodes->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::NODE, aName + "_Nodes"); + aGroup->Add(aNodes.inout()); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) ) + anEntryList.append( aSObject->GetID().c_str() ); + } + if (aEdges->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::EDGE, aName + "_Edges"); + aGroup->Add(aEdges.inout()); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) ) + anEntryList.append( aSObject->GetID().c_str() ); + } + if (aFaces->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::FACE, aName + "_Faces"); + aGroup->Add(aFaces.inout()); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) ) + anEntryList.append( aSObject->GetID().c_str() ); + } + if (aVolumes->length() > 0) { + SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::VOLUME, aName + "_Volumes"); + aGroup->Add(aVolumes.inout()); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) ) + anEntryList.append( aSObject->GetID().c_str() ); + } + updateObjBrowser(); + anApp->browseObjects( anEntryList ); + } catch(const SALOME::SALOME_Exception & S_ex){ - SalomeApp_Tools::QtCatchCorbaException(S_ex); - } - } - } - } + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + } + } + } } else if(nbSel==0) { SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_NO_AVAILABLE_DATA")); + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_NO_AVAILABLE_DATA")); } break; } @@ -1849,7 +2694,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1868,16 +2713,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface(It.Value()); if (!aGroup->_is_nil()) { - nbSelectedGroups++; + nbSelectedGroups++; SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup); aDlg->show(); - } + } } if (nbSelectedGroups == 0) - { - SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, SMESH::SMESH_GroupBase::_nil()); - aDlg->show(); - } + { + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, SMESH::SMESH_GroupBase::_nil()); + aDlg->show(); + } break; } @@ -1885,8 +2730,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if (myState == 800) { - SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox; - if (aDlg) aDlg->onAdd(); + SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox; + if (aDlg) aDlg->onAdd(); } break; } @@ -1895,8 +2740,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if (myState == 800) { - SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox; - if (aDlg) aDlg->onRemove(); + SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox; + if (aDlg) aDlg->onRemove(); } break; } @@ -1906,7 +2751,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1926,7 +2771,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if (!aGroup->_is_nil()) { SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup, true ); aDlg->show(); - } + } + else + { + SMESH::SMESH_GroupOnFilter_var aGroup = + SMESH::IObjectToInterface(It.Value()); + if (!aGroup->_is_nil()) { + SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup, true ); + aDlg->show(); + } + } } break; } @@ -1938,7 +2792,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1977,7 +2831,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if ( !vtkwnd ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "NOT_A_VTK_VIEWER" ) ); break; } @@ -1990,8 +2844,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } - case 900: // MESH INFOS + case 900: // MESH INFOS + case 903: // WHAT IS { + int page = theCommandID == 900 ? SMESHGUI_MeshInfoDlg::BaseInfo : SMESHGUI_MeshInfoDlg::ElemInfo; EmitSignalDeactivateDialog(); LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); SALOME_ListIO selected; @@ -1999,54 +2855,27 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) aSel->selectedObjects( selected ); if ( selected.Extent() > 1 ) { // a dlg for each IO - SALOME_ListIO IOs; - SALOME_ListIteratorOfListIO It (selected); + SALOME_ListIteratorOfListIO It( selected ); for ( ; It.More(); It.Next() ) { - IOs.Clear(); IOs.Append( It.Value() ); - aSel->setSelectedObjects( IOs ); - ( new SMESHGUI_MeshInfosDlg( this ) )->show(); + SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page ); + dlg->showInfo( It.Value() ); + dlg->show(); } - // restore selection - aSel->setSelectedObjects( selected ); } - else - ( new SMESHGUI_MeshInfosDlg( this ) )->show(); - break; - } - - case 902: // STANDARD MESH INFOS - { - EmitSignalDeactivateDialog(); - LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); - SALOME_ListIO selected; - if( aSel ) - aSel->selectedObjects( selected ); - - if ( selected.Extent() > 1 ) { // a dlg for each IO - SALOME_ListIO IOs; - SALOME_ListIteratorOfListIO It (selected); - for ( ; It.More(); It.Next() ) { - IOs.Clear(); - IOs.Append( It.Value() ); - aSel->setSelectedObjects( IOs ); - ( new SMESHGUI_StandardMeshInfosDlg( this ) )->show(); - } - // restore selection - aSel->setSelectedObjects( selected ); + else { + SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page ); + dlg->show(); } - else - ( new SMESHGUI_StandardMeshInfosDlg( this ) )->show(); break; } - case 903: // WHAT IS + case 904: // FIND ELEM { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_WhatIsDlg( this ) )->show(); + startOperation( theCommandID ); break; } - case 1100: // EDIT HYPOTHESIS + case 1100: // EDIT HYPOTHESIS { if(checkLock(aStudy)) break; @@ -2059,82 +2888,28 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if (nbSel == 1) { Handle(SALOME_InteractiveObject) anIObject = selected.First(); - SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::IObjectToInterface(anIObject); + SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::IObjectToInterface(anIObject); /* Look for all mesh objects that have this hypothesis affected in order to flag as ModifiedMesh */ /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects */ /* Warning : however by internal mechanism all subMeshes icons are changed ! */ if ( !aHypothesis->_is_nil() ) { + // BUG 0020378 + //SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypothesis->GetName()); SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypothesis->GetName()); - if (aCreator) - aCreator->edit( aHypothesis.in(), anIObject->getName(), desktop() ); + if (aCreator) { + aCreator->edit( aHypothesis.in(), anIObject->getName(), desktop(), this, SLOT( onHypothesisEdit( int ) ) ); + } else { // report error } } } - updateObjBrowser( true ); - break; - } - - case 1101: // RENAME - { - if ( checkLock( aStudy ) ) - break; - - LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); - SALOME_ListIO selected; - if( aSel ) - aSel->selectedObjects( selected ); - - bool isAny = false; // is there any appropriate object selected - - SALOME_ListIteratorOfListIO It( selected ); - for ( ; It.More(); It.Next() ) - { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - _PTR(SObject) obj = aStudy->FindObjectID( IObject->getEntry() ); - _PTR(GenericAttribute) anAttr; - _PTR(AttributeName) aName; - if ( obj ) - { - if ( obj->FindAttribute(anAttr, "AttributeName") ) - { - aName = anAttr; - QString newName = QString(aName->Value().c_str()); - - // check type to prevent renaming of inappropriate objects - int aType = SMESHGUI_Selection::type(IObject->getEntry(), aStudy); - if (aType == MESH || aType == GROUP || - aType == SUBMESH || aType == SUBMESH_COMPOUND || - aType == SUBMESH_SOLID || aType == SUBMESH_FACE || - aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX || - aType == HYPOTHESIS || aType == ALGORITHM) - { - isAny = true; - newName = LightApp_NameDlg::getName(desktop(), newName); - if ( !newName.isEmpty() ) - { - SMESHGUI::GetSMESHGen()->SetName(obj->GetIOR().c_str(), newName.toLatin1().data()); - - updateObjBrowser(); - } - } - } - } - } // for - - if (!isAny) { - SUIT_MessageBox::warning(desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_WRN_NO_APPROPRIATE_SELECTION")); - } break; } - - case 1102: // REMOVE HYPOTHESIS / ALGORITHMS + case 1102: // REMOVE HYPOTHESIS / ALGORITHMS { if(checkLock(aStudy)) break; SUIT_OverrideCursor wc; @@ -2146,8 +2921,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SALOME_ListIteratorOfListIO It(selected); for (int i = 0; It.More(); It.Next(), i++) { - Handle(SALOME_InteractiveObject) IObject = It.Value(); - SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject); + Handle(SALOME_InteractiveObject) IObject = It.Value(); + SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject); } SALOME_ListIO l1; aSel->setSelectedObjects( l1 ); @@ -2155,118 +2930,126 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } - case 401: // GEOM::EDGE - case 4021: // TRIANGLE - case 4022: // QUAD - case 4023: // POLYGON - case 4031: // TETRA - case 4032: // HEXA + case 4008: // BALL + case 4009: // ELEM0D + case 4010: // EDGE + case 4021: // TRIANGLE + case 4022: // QUAD + case 4023: // POLYGON + case 4031: // TETRA + case 4032: // HEXA + case 4133: // PENTA + case 4134: // PYRAMID + case 4135: // OCTA12 { if(checkLock(aStudy)) break; if ( vtkwnd ) { - EmitSignalDeactivateDialog(); - SMDSAbs_ElementType type = SMDSAbs_Edge; - int nbNodes = 2; + EmitSignalDeactivateDialog(); + SMDSAbs_EntityType type = SMDSEntity_Edge; switch (theCommandID) { - case 4021: // TRIANGLE - type = SMDSAbs_Face; nbNodes = 3; break; - case 4022: // QUAD - type = SMDSAbs_Face; nbNodes = 4; break; - case 4031: // TETRA - type = SMDSAbs_Volume; nbNodes = 4; break; - case 4023: // POLYGON - type = SMDSAbs_Face; nbNodes = 5; break; // 5 - identificator for POLYGON - case 4032: // HEXA - type = SMDSAbs_Volume; nbNodes = 8; break; - case 4033: // POLYHEDRE - type = SMDSAbs_Volume; nbNodes = 9; break; // 9 - identificator for POLYHEDRE + case 4008: type = SMDSEntity_Ball; break; + case 4009: type = SMDSEntity_0D; break; + case 4021: type = SMDSEntity_Triangle; break; + case 4022: type = SMDSEntity_Quadrangle; break; + case 4031: type = SMDSEntity_Tetra; break; + case 4023: type = SMDSEntity_Polygon; break; + case 4032: type = SMDSEntity_Hexa; break; + case 4133: type = SMDSEntity_Penta; break; + case 4134: type = SMDSEntity_Pyramid; break; + case 4135: type = SMDSEntity_Hexagonal_Prism; break; default:; } - ( new SMESHGUI_AddMeshElementDlg( this, type, nbNodes ) )->show(); + ( new SMESHGUI_AddMeshElementDlg( this, type ) )->show(); } else { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } - case 4033: // POLYHEDRON + case 4033: // POLYHEDRON { if(checkLock(aStudy)) break; if ( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_CreatePolyhedralVolumeDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_CreatePolyhedralVolumeDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } case 4034: // QUADRATIC EDGE case 4035: // QUADRATIC TRIANGLE case 4036: // QUADRATIC QUADRANGLE + case 4136: // BIQUADRATIC QUADRANGLE case 4037: // QUADRATIC TETRAHEDRON case 4038: // QUADRATIC PYRAMID case 4039: // QUADRATIC PENTAHEDRON case 4040: // QUADRATIC HEXAHEDRON + case 4140: // TRIQUADRATIC HEXAHEDRON { if(checkLock(aStudy)) break; if ( vtkwnd ) { - EmitSignalDeactivateDialog(); - int type; - - switch (theCommandID) { - case 4034: - type = QUAD_EDGE; break; - case 4035: - type = QUAD_TRIANGLE; break; - case 4036: - type = QUAD_QUADRANGLE; break; - case 4037: - type = QUAD_TETRAHEDRON; break; - case 4038: - type = QUAD_PYRAMID; break; - case 4039: - type = QUAD_PENTAHEDRON; break; - case 4040: - type = QUAD_HEXAHEDRON; - break; - default:; - } - ( new SMESHGUI_AddQuadraticElementDlg( this, type ) )->show(); + EmitSignalDeactivateDialog(); + SMDSAbs_EntityType type; + + switch (theCommandID) { + case 4034: + type = SMDSEntity_Quad_Edge; break; + case 4035: + type = SMDSEntity_Quad_Triangle; break; + case 4036: + type = SMDSEntity_Quad_Quadrangle; break; + case 4136: + type = SMDSEntity_BiQuad_Quadrangle; break; + case 4037: + type = SMDSEntity_Quad_Tetra; break; + case 4038: + type = SMDSEntity_Quad_Pyramid; break; + case 4039: + type = SMDSEntity_Quad_Penta; break; + case 4040: + type = SMDSEntity_Quad_Hexa; + case 4140: + type = SMDSEntity_TriQuad_Hexa; + break; + default:; + } + ( new SMESHGUI_AddQuadraticElementDlg( this, type ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } - case 4041: // REMOVES NODES + case 4041: // REMOVES NODES { if(checkLock(aStudy)) break; if ( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_RemoveNodesDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_RemoveNodesDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } - case 4042: // REMOVES ELEMENTS + case 4042: // REMOVES ELEMENTS { if(checkLock(aStudy)) break; if( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_RemoveElementsDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_RemoveElementsDlg( this ) )->show(); } else - { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); - } + { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } break; } case 4043: { // CLEAR_MESH @@ -2286,7 +3069,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SMESH::IObjectToInterface(IOS); if ( aMesh->_is_nil()) continue; try { - SMESH::UpdateView(SMESH::eErase, IOS->getEntry()); + SMESH::RemoveVisualObjectWithActors(IOS->getEntry(), true); aMesh->Clear(); _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh); SMESH::ModifiedMesh( aMeshSObj, false, true); @@ -2296,57 +3079,95 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) for ( anIter->InitEx(true); anIter->More(); anIter->Next() ) { _PTR(SObject) so = anIter->Value(); - SMESH::UpdateView(SMESH::eErase, so->GetID().c_str()); + SMESH::RemoveVisualObjectWithActors(so->GetID().c_str(), true); } } catch (const SALOME::SALOME_Exception& S_ex){ - wc.suspend(); - SalomeApp_Tools::QtCatchCorbaException(S_ex); - wc.resume(); + wc.suspend(); + SalomeApp_Tools::QtCatchCorbaException(S_ex); + wc.resume(); } } SMESH::UpdateView(); updateObjBrowser(); break; } - case 4051: // RENUMBERING NODES + case 4044: // REMOVE ORPHAN NODES + { + if(checkLock(aStudy)) break; + SALOME_ListIO selected; + if( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() ) + aSel->selectedObjects( selected ); + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) anIO = selected.First(); + SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO); + if ( !aMesh->_is_nil() ) { + bool confirm = SUIT_MessageBox::question( SMESHGUI::desktop(), + tr( "SMESH_WARNING" ), + tr( "REMOVE_ORPHAN_NODES_QUESTION"), + SUIT_MessageBox::Yes | + SUIT_MessageBox::No, + SUIT_MessageBox::No ) == SUIT_MessageBox::Yes; + if( confirm ) { + try { + SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); + int removed = aMeshEditor->RemoveOrphanNodes(); + SUIT_MessageBox::information(SMESHGUI::desktop(), + tr("SMESH_INFORMATION"), + tr("NB_NODES_REMOVED").arg(removed)); + if ( removed > 0 ) { + SMESH::UpdateView(); + SMESHGUI::Modified(); + } + } + catch (const SALOME::SALOME_Exception& S_ex) { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + catch (...) { + } + } + } + } + break; + } + case 4051: // RENUMBERING NODES { if(checkLock(aStudy)) break; if( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_RenumberingDlg( this, 0 ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_RenumberingDlg( this, 0 ) )->show(); } else - { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); - } + { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } break; } - case 4052: // RENUMBERING ELEMENTS + case 4052: // RENUMBERING ELEMENTS { if(checkLock(aStudy)) break; if ( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_RenumberingDlg( this, 1 ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_RenumberingDlg( this, 1 ) )->show(); } else - { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); - } + { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } break; } case 4061: // TRANSLATION { if(checkLock(aStudy)) break; if ( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_TranslationDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_TranslationDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -2354,12 +3175,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if( vtkwnd ) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_RotationDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_RotationDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -2367,12 +3188,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if(vtkwnd) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_SymmetryDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_SymmetryDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -2380,12 +3201,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if(vtkwnd) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_SewingDlg( this ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_SewingDlg( this ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -2393,12 +3214,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if(checkLock(aStudy)) break; if(vtkwnd) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_EditMeshDlg( this, 0 ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_MergeDlg( this, 0 ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -2406,11 +3227,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) { if (checkLock(aStudy)) break; if (vtkwnd) { - EmitSignalDeactivateDialog(); - ( new SMESHGUI_EditMeshDlg( this, 1 ) )->show(); + EmitSignalDeactivateDialog(); + ( new SMESHGUI_MergeDlg( this, 1 ) )->show(); } else { - SUIT_MessageBox::warning(SMESHGUI::desktop(), - tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); } break; } @@ -2419,6 +3240,34 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) startOperation( 4067 ); break; + case 4068: // SCALE + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + ( new SMESHGUI_ScaleDlg( this ) )->show(); + } + else { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } + break; + } + + case 4069: // DUPLICATE NODES + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + ( new SMESHGUI_DuplicateNodesDlg( this ) )->show(); + } + else { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } + break; + } + case 5105: // Library of selection filters { static QList aTypes; @@ -2437,7 +3286,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } break; - case 6017: // CONTROLS + case 6017: // CONTROLS case 6016: case 6015: case 6014: @@ -2453,33 +3302,43 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case 6005: case 6009: case 6021: + case 6022: + case 6023: + case 6024: + case 6025: + case 6026: + case 6027: + case 6028: + case 6029: + case 6030: + case 6031: if ( vtkwnd ) { LightApp_SelectionMgr* mgr = selectionMgr(); SALOME_ListIO selected; mgr->selectedObjects( selected ); if ( selected.Extent() == 1 && selected.First()->hasEntry() ) { - _PTR(SObject) SO = aStudy->FindObjectID( selected.First()->getEntry() ); - if ( SO ) { - CORBA::Object_var aObject = SMESH::SObjectToObject( SO ); - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( aObject ); - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject ); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( aObject ); - if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) { - ::Control( theCommandID ); - break; - } - } + _PTR(SObject) SO = aStudy->FindObjectID( selected.First()->getEntry() ); + if ( SO ) { + CORBA::Object_var aObject = SMESH::SObjectToObject( SO ); + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( aObject ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject ); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( aObject ); + if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) { + ::Control( theCommandID ); + break; + } + } } SUIT_MessageBox::warning(desktop(), - tr( "SMESH_WRN_WARNING" ), - tr( "SMESH_BAD_SELECTION" ) ); + tr( "SMESH_WRN_WARNING" ), + tr( "SMESH_BAD_SELECTION" ) ); break; } else { SUIT_MessageBox::warning(desktop(), - tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); + tr( "SMESH_WRN_WARNING" ), + tr( "NOT_A_VTK_VIEWER" ) ); } break; case 9010: @@ -2490,11 +3349,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SALOME_ListIteratorOfListIO it(selected); for( ; it.More(); it.Next()) { Handle(SALOME_InteractiveObject) anIObject = it.Value(); - if(anIObject->hasEntry()) { - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ - anActor->SetPointsLabeled( !anActor->GetPointsLabeled() ); - } - } + if(anIObject->hasEntry()) { + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ + anActor->SetPointsLabeled( !anActor->GetPointsLabeled() ); + } + } } break; } @@ -2503,15 +3362,25 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) LightApp_SelectionMgr* mgr = selectionMgr(); SALOME_ListIO selected; mgr->selectedObjects( selected ); - if (selected.Extent() == 1) { - Handle(SALOME_InteractiveObject) anIObject = selected.First(); - if(anIObject->hasEntry()) - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ - anActor->SetCellsLabeled( !anActor->GetCellsLabeled() ); - } + SALOME_ListIteratorOfListIO it(selected); + for( ; it.More(); it.Next()) { + Handle(SALOME_InteractiveObject) anIObject = it.Value(); + if(anIObject->hasEntry()) + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ + anActor->SetCellsLabeled( !anActor->GetCellsLabeled() ); + } } break; } + case 501: + case 502: + { + int page = theCommandID == 501 ? SMESHGUI_MeasureDlg::MinDistance : SMESHGUI_MeasureDlg::BoundingBox; + EmitSignalDeactivateDialog(); + SMESHGUI_MeasureDlg* dlg = new SMESHGUI_MeasureDlg( SMESHGUI::desktop(), page ); + dlg->show(); + break; + } } anApp->updateActions(); //SRN: To update a Save button in the toolbar @@ -2567,7 +3436,8 @@ void SMESHGUI::BuildPresentation( const Handle(SALOME_InteractiveObject) & theIO // function : createSMESHAction // purpose : //======================================================================= -void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle ) +void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, + const int key, const bool toggle, const QString& shortcutAction ) { QIcon icon; QWidget* parent = application()->desktop(); @@ -2584,7 +3454,8 @@ void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QStr menu = tr( QString( "MEN_%1" ).arg( po_id ).toLatin1().data() ), status_bar = tr( QString( "STB_%1" ).arg( po_id ).toLatin1().data() ); - createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() ) ); + createAction( id, tooltip, icon, menu, status_bar, key, parent, + toggle, this, SLOT( OnGUIEvent() ), shortcutAction ); } //======================================================================= @@ -2595,7 +3466,7 @@ void SMESHGUI::createPopupItem( const int id, const QString& clients, const QString& types, const QString& theRule, - const int pId ) + const int pId ) { int parentId = pId; if( pId!=-1 ) @@ -2638,18 +3509,25 @@ void SMESHGUI::initialize( CAM_Application* app ) // ----- create actions -------------- - createSMESHAction( 111, "DAT", "", (Qt::CTRL+Qt::Key_B) ); - createSMESHAction( 112, "UNV", "", (Qt::CTRL+Qt::Key_U) ); - createSMESHAction( 113, "MED", "", (Qt::CTRL+Qt::Key_M) ); + createSMESHAction( 111, "IMPORT_DAT", "", (Qt::CTRL+Qt::Key_B) ); + createSMESHAction( 112, "IMPORT_UNV", "", (Qt::CTRL+Qt::Key_U) ); + createSMESHAction( 113, "IMPORT_MED", "", (Qt::CTRL+Qt::Key_M) ); createSMESHAction( 114, "NUM" ); + createSMESHAction( 115, "IMPORT_STL" ); + createSMESHAction( 116, "IMPORT_CGNS" ); + createSMESHAction( 117, "IMPORT_SAUV" ); createSMESHAction( 121, "DAT" ); createSMESHAction( 122, "MED" ); createSMESHAction( 123, "UNV" ); createSMESHAction( 140, "STL" ); + createSMESHAction( 142, "CGNS" ); + createSMESHAction( 144, "SAUV" ); createSMESHAction( 124, "EXPORT_DAT" ); createSMESHAction( 125, "EXPORT_MED" ); createSMESHAction( 126, "EXPORT_UNV" ); createSMESHAction( 141, "EXPORT_STL" ); + createSMESHAction( 143, "EXPORT_CGNS" ); + createSMESHAction( 145, "EXPORT_SAUV" ); createSMESHAction( 150, "FILE_INFO" ); createSMESHAction( 33, "DELETE", "ICON_DELETE", Qt::Key_Delete ); createSMESHAction( 5105, "SEL_FILTER_LIB" ); @@ -2657,8 +3535,11 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 702, "CREATE_MESH", "ICON_DLG_INIT_MESH" ); createSMESHAction( 703, "CREATE_SUBMESH", "ICON_DLG_ADD_SUBMESH" ); createSMESHAction( 704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" ); + createSMESHAction( 705, "COPY_MESH", "ICON_COPY_MESH" ); createSMESHAction( 710, "BUILD_COMPOUND", "ICON_BUILD_COMPOUND" ); createSMESHAction( 711, "PRECOMPUTE", "ICON_PRECOMPUTE" ); + createSMESHAction( 712, "EVALUATE", "ICON_COMPUTE" ); + createSMESHAction( 713, "MESH_ORDER", "ICON_COMPUTE" ); createSMESHAction( 806, "CREATE_GEO_GROUP","ICON_CREATE_GEO_GROUP" ); createSMESHAction( 801, "CREATE_GROUP", "ICON_CREATE_GROUP" ); createSMESHAction( 802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" ); @@ -2672,11 +3553,22 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 814, "UNDERLYING_ELEMS","ICON_UNDERLYING_ELEMS" ); createSMESHAction( 813, "DEL_GROUP", "ICON_DEL_GROUP" ); createSMESHAction( 900, "ADV_INFO", "ICON_ADV_INFO" ); - createSMESHAction( 902, "STD_INFO", "ICON_STD_INFO" ); - createSMESHAction( 903, "WHAT_IS", "ICON_WHAT_IS" ); + //createSMESHAction( 902, "STD_INFO", "ICON_STD_INFO" ); + //createSMESHAction( 903, "WHAT_IS", "ICON_WHAT_IS" ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command) + createSMESHAction( 904, "FIND_ELEM", "ICON_FIND_ELEM" ); createSMESHAction( 6001, "LENGTH", "ICON_LENGTH", 0, true ); createSMESHAction( 6002, "FREE_EDGE", "ICON_FREE_EDGE", 0, true ); createSMESHAction( 6021, "FREE_FACES", "ICON_FREE_FACES", 0, true ); + createSMESHAction( 6022, "MAX_ELEMENT_LENGTH_2D", "ICON_MAX_ELEMENT_LENGTH_2D", 0, true ); + createSMESHAction( 6023, "MAX_ELEMENT_LENGTH_3D", "ICON_MAX_ELEMENT_LENGTH_3D", 0, true ); + createSMESHAction( 6024, "BARE_BORDER_VOLUME", "ICON_BARE_BORDER_VOLUME", 0, true ); + createSMESHAction( 6025, "BARE_BORDER_FACE", "ICON_BARE_BORDER_FACE", 0, true ); + createSMESHAction( 6026, "OVER_CONSTRAINED_VOLUME","ICON_OVER_CONSTRAINED_VOLUME", 0, true ); + createSMESHAction( 6027, "OVER_CONSTRAINED_FACE", "ICON_OVER_CONSTRAINED_FACE", 0, true ); + createSMESHAction( 6028, "EQUAL_NODE", "ICON_EQUAL_NODE", 0, true ); + createSMESHAction( 6029, "EQUAL_EDGE", "ICON_EQUAL_EDGE", 0, true ); + createSMESHAction( 6030, "EQUAL_FACE", "ICON_EQUAL_FACE", 0, true ); + createSMESHAction( 6031, "EQUAL_VOLUME", "ICON_EQUAL_VOLUME", 0, true ); createSMESHAction( 6003, "FREE_BORDER", "ICON_FREE_EDGE_2D", 0, true ); createSMESHAction( 6004, "CONNECTION", "ICON_CONNECTION", 0, true ); createSMESHAction( 6005, "FREE_NODE", "ICON_FREE_NODE", 0, true ); @@ -2690,15 +3582,31 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 6018, "LENGTH_2D", "ICON_LENGTH_2D", 0, true ); createSMESHAction( 6019, "CONNECTION_2D", "ICON_CONNECTION_2D", 0, true ); createSMESHAction( 6009, "VOLUME_3D", "ICON_VOLUME_3D", 0, true ); - createSMESHAction( 400, "NODE", "ICON_DLG_NODE" ); - createSMESHAction( 401, "EDGE", "ICON_DLG_EDGE" ); + createSMESHAction( 4000, "NODE", "ICON_DLG_NODE" ); + createSMESHAction( 4009, "ELEM0D", "ICON_DLG_ELEM0D" ); + createSMESHAction( 4008, "BALL", "ICON_DLG_BALL" ); + createSMESHAction( 4010, "EDGE", "ICON_DLG_EDGE" ); createSMESHAction( 4021, "TRIANGLE", "ICON_DLG_TRIANGLE" ); createSMESHAction( 4022, "QUAD", "ICON_DLG_QUADRANGLE" ); createSMESHAction( 4023, "POLYGON", "ICON_DLG_POLYGON" ); createSMESHAction( 4031, "TETRA", "ICON_DLG_TETRAS" ); createSMESHAction( 4032, "HEXA", "ICON_DLG_HEXAS" ); - createSMESHAction( 4041, "REMOVE_NODES", "ICON_DLG_REM_NODE" ); - createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" ); + createSMESHAction( 4133, "PENTA", "ICON_DLG_PENTA" ); + createSMESHAction( 4134, "PYRAMID", "ICON_DLG_PYRAMID" ); + createSMESHAction( 4135, "OCTA", "ICON_DLG_OCTA" ); + createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" ); + createSMESHAction( 4034, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" ); + createSMESHAction( 4035, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" ); + createSMESHAction( 4036, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" ); + createSMESHAction( 4136, "BIQUADRATIC_QUADRANGLE", "ICON_DLG_BIQUADRATIC_QUADRANGLE" ); + createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" ); + createSMESHAction( 4038, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" ); + createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" ); + createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" ); + createSMESHAction( 4140, "TRIQUADRATIC_HEXAHEDRON", "ICON_DLG_TRIQUADRATIC_HEXAHEDRON" ); + createSMESHAction( 4041, "REMOVE_NODES", "ICON_DLG_REM_NODE" ); + createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" ); + createSMESHAction( 4044, "REMOVE_ORPHAN_NODES", "ICON_DLG_REM_ORPHAN_NODES" ); createSMESHAction( 4043, "CLEAR_MESH" , "ICON_CLEAR_MESH" ); createSMESHAction( 4051, "RENUM_NODES", "ICON_DLG_RENUMBERING_NODES" ); createSMESHAction( 4052, "RENUM_ELEMENTS", "ICON_DLG_RENUMBERING_ELEMENTS" ); @@ -2708,8 +3616,9 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 4064, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" ); createSMESHAction( 4065, "MERGE", "ICON_SMESH_MERGE_NODES" ); createSMESHAction( 4066, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" ); - createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MESH_THROU_POINT" ); - createSMESHAction( 406, "MOVE", "ICON_DLG_MOVE_NODE" ); + createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" ); + createSMESHAction( 4068, "SCALE", "ICON_DLG_MESH_SCALE" ); + createSMESHAction( 4069, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" ); createSMESHAction( 407, "INV", "ICON_DLG_MESH_DIAGONAL" ); createSMESHAction( 408, "UNION2", "ICON_UNION2TRI" ); createSMESHAction( 409, "ORIENT", "ICON_DLG_MESH_ORIENTATION" ); @@ -2721,20 +3630,33 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 415, "MAP", "ICON_MAP" ); createSMESHAction( 416, "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" ); createSMESHAction( 417, "CONV_TO_QUAD", "ICON_CONV_TO_QUAD" ); + createSMESHAction( 418, "2D_FROM_3D", "ICON_2D_FROM_3D" ); + createSMESHAction( 419, "SPLIT_TO_TETRA", "ICON_SPLIT_TO_TETRA" ); + createSMESHAction( 420, "REORIENT_2D", "ICON_REORIENT_2D" ); createSMESHAction( 200, "RESET" ); createSMESHAction( 201, "SCALAR_BAR_PROP" ); + createSMESHAction( 2021, "SAVE_DISTRIBUTION" ); + createSMESHAction( 2022, "SHOW_DISTRIBUTION","",0, true ); +#ifndef DISABLE_PLOT2DVIEWER + createSMESHAction( 2023, "PLOT_DISTRIBUTION" ); +#endif createSMESHAction( 211, "WIRE", "ICON_WIRE", 0, true ); createSMESHAction( 212, "SHADE", "ICON_SHADE", 0, true ); createSMESHAction( 213, "SHRINK", "ICON_SHRINK", 0, true ); createSMESHAction( 214, "UPDATE", "ICON_UPDATE" ); createSMESHAction( 215, "NODES", "ICON_POINTS", 0, true ); + createSMESHAction( 222, "BALLS", "ICON_DLG_BALL", 0, true ); + createSMESHAction( 216, "ELEMS0D", "ICON_DLG_ELEM0D", 0, true ); createSMESHAction( 217, "EDGES", "ICON_DLG_EDGE", 0, true ); createSMESHAction( 218, "FACES", "ICON_DLG_TRIANGLE", 0, true ); createSMESHAction( 219, "VOLUMES", "ICON_DLG_TETRAS", 0, true ); createSMESHAction( 220, "ALL" ); createSMESHAction( 221, "FACE_ORIENTATION", "", 0, true ); + + createSMESHAction( 231, "LINE_REPRESENTATION", "", 0, true ); + createSMESHAction( 232, "ARC_REPRESENTATION", "", 0, true ); + createSMESHAction( 1100, "EDIT_HYPO" ); - createSMESHAction( 1101, "RENAME", "", Qt::Key_F2 ); createSMESHAction( 1102, "UNASSIGN" ); createSMESHAction( 9010, "NUM_NODES", "", 0, true ); createSMESHAction( 9011, "NUM_ELEMENTS", "", 0, true ); @@ -2747,31 +3669,31 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 1137, "DISABLE_AUTO_COLOR" ); createSMESHAction( 2000, "CTRL" ); - createSMESHAction( 300, "ERASE" ); - createSMESHAction( 301, "DISPLAY" ); + createSMESHAction( 501, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" ); + createSMESHAction( 502, "MEASURE_BND_BOX", "ICON_MEASURE_BND_BOX" ); + + createSMESHAction( 300, "HIDE" ); + createSMESHAction( 301, "SHOW" ); createSMESHAction( 302, "DISPLAY_ONLY" ); - createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" ); - createSMESHAction( 4034, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" ); - createSMESHAction( 4035, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" ); - createSMESHAction( 4036, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" ); - createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" ); - createSMESHAction( 4038, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" ); - createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" ); - createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" ); // ----- create menu -------------- - int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ), - editId = createMenu( tr( "MEN_EDIT" ), -1, 3 ), - toolsId = createMenu( tr( "MEN_TOOLS" ), -1, 5, 50 ), - meshId = createMenu( tr( "MEN_MESH" ), -1, 70, 10 ), - ctrlId = createMenu( tr( "MEN_CTRL" ), -1, 60, 10 ), - modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ), - viewId = createMenu( tr( "MEN_VIEW" ), -1, 2 ); + int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ), + editId = createMenu( tr( "MEN_EDIT" ), -1, 3 ), + toolsId = createMenu( tr( "MEN_TOOLS" ), -1, 5, 50 ), + meshId = createMenu( tr( "MEN_MESH" ), -1, 70, 10 ), + ctrlId = createMenu( tr( "MEN_CTRL" ), -1, 60, 10 ), + modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ), + measureId = createMenu( tr( "MEN_MEASURE" ), -1, 50, 10 ), + viewId = createMenu( tr( "MEN_VIEW" ), -1, 2 ); createMenu( separator(), fileId ); int importId = createMenu( tr( "MEN_IMPORT" ), fileId, -1, 10 ), exportId = createMenu( tr( "MEN_EXPORT" ), fileId, -1, 10 ), + nodeId = createMenu( tr( "MEN_NODE_CTRL" ), ctrlId, -1, 10 ), + edgeId = createMenu( tr( "MEN_EDGE_CTRL" ), ctrlId, -1, 10 ), + faceId = createMenu( tr( "MEN_FACE_CTRL" ), ctrlId, -1, 10 ), + volumeId = createMenu( tr( "MEN_VOLUME_CTRL" ), ctrlId, -1, 10 ), addId = createMenu( tr( "MEN_ADD" ), modifyId, 402 ), removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ), renumId = createMenu( tr( "MEN_RENUM" ), modifyId, 404 ), @@ -2780,12 +3702,19 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 111, importId, -1 ); createMenu( 112, importId, -1 ); createMenu( 113, importId, -1 ); - + createMenu( 115, importId, -1 ); +#ifdef WITH_CGNS + createMenu( 116, importId, -1 ); +#endif + createMenu( 117, importId, -1 ); createMenu( 121, exportId, -1 ); createMenu( 122, exportId, -1 ); createMenu( 123, exportId, -1 ); - createMenu( 140, exportId, -1 ); // export to stl STL - + createMenu( 140, exportId, -1 ); // export to STL +#ifdef WITH_CGNS + createMenu( 142, exportId, -1 ); // export to CGNS +#endif + createMenu( 144, exportId, -1 ); // export to SAUV createMenu( separator(), fileId, 10 ); createMenu( 33, editId, -1 ); @@ -2796,9 +3725,12 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 703, meshId, -1 ); createMenu( 704, meshId, -1 ); createMenu( 710, meshId, -1 ); + createMenu( 705, meshId, -1 ); createMenu( separator(), meshId, -1 ); createMenu( 701, meshId, -1 ); createMenu( 711, meshId, -1 ); + createMenu( 712, meshId, -1 ); + createMenu( 713, meshId, -1 ); createMenu( separator(), meshId, -1 ); createMenu( 801, meshId, -1 ); createMenu( 806, meshId, -1 ); @@ -2812,52 +3744,69 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( separator(), meshId, -1 ); createMenu( 814, meshId, -1 ); createMenu( separator(), meshId, -1 ); - createMenu( 813, meshId, -1 ); - createMenu( separator(), meshId, -1 ); createMenu( 900, meshId, -1 ); - createMenu( 902, meshId, -1 ); - createMenu( 903, meshId, -1 ); + //createMenu( 902, meshId, -1 ); + //createMenu( 903, meshId, -1 ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command) + createMenu( 904, meshId, -1 ); createMenu( separator(), meshId, -1 ); - createMenu( 6003, ctrlId, -1 ); - createMenu( 6001, ctrlId, -1 ); - createMenu( 6004, ctrlId, -1 ); - createMenu( separator(), ctrlId, -1 ); - createMenu( 6005, ctrlId, -1 ); - createMenu( 6002, ctrlId, -1 ); - createMenu( 6018, ctrlId, -1 ); - createMenu( 6019, ctrlId, -1 ); - createMenu( 6011, ctrlId, -1 ); - createMenu( 6012, ctrlId, -1 ); - createMenu( 6013, ctrlId, -1 ); - createMenu( 6014, ctrlId, -1 ); - createMenu( 6015, ctrlId, -1 ); - createMenu( 6016, ctrlId, -1 ); - createMenu( separator(), ctrlId, -1 ); - createMenu( 6017, ctrlId, -1 ); - createMenu( 6009, ctrlId, -1 ); - createMenu( 6021, ctrlId, -1 ); - createMenu( separator(), ctrlId, -1 ); - - createMenu( 400, addId, -1 ); - createMenu( 401, addId, -1 ); + createMenu( 6005, nodeId, -1 ); + createMenu( 6028, nodeId, -1 ); + createMenu( 6002, edgeId, -1 ); + createMenu( 6003, edgeId, -1 ); + createMenu( 6001, edgeId, -1 ); + createMenu( 6004, edgeId, -1 ); + createMenu( 6029, edgeId, -1 ); + createMenu( 6021, faceId, -1 ); + createMenu( 6025, faceId, -1 ); + createMenu( 6027, faceId, -1 ); + createMenu( 6018, faceId, -1 ); + createMenu( 6019, faceId, -1 ); + createMenu( 6011, faceId, -1 ); + createMenu( 6012, faceId, -1 ); + createMenu( 6013, faceId, -1 ); + createMenu( 6014, faceId, -1 ); + createMenu( 6015, faceId, -1 ); + createMenu( 6016, faceId, -1 ); + createMenu( 6022, faceId, -1 ); + createMenu( 6030, faceId, -1 ); + createMenu( 6017, volumeId, -1 ); + createMenu( 6009, volumeId, -1 ); + createMenu( 6023, volumeId, -1 ); + createMenu( 6024, volumeId, -1 ); + createMenu( 6026, volumeId, -1 ); + createMenu( 6031, volumeId, -1 ); + + createMenu( 4000, addId, -1 ); + createMenu( 4009, addId, -1 ); + createMenu( 4008, addId, -1 ); + createMenu( 4010, addId, -1 ); createMenu( 4021, addId, -1 ); createMenu( 4022, addId, -1 ); createMenu( 4023, addId, -1 ); createMenu( 4031, addId, -1 ); createMenu( 4032, addId, -1 ); + createMenu( 4133, addId, -1 ); + createMenu( 4134, addId, -1 ); + createMenu( 4135, addId, -1 ); createMenu( 4033, addId, -1 ); createMenu( separator(), addId, -1 ); createMenu( 4034, addId, -1 ); createMenu( 4035, addId, -1 ); createMenu( 4036, addId, -1 ); + createMenu( 4136, addId, -1 ); createMenu( 4037, addId, -1 ); createMenu( 4038, addId, -1 ); createMenu( 4039, addId, -1 ); createMenu( 4040, addId, -1 ); + createMenu( 4140, addId, -1 ); createMenu( 4041, removeId, -1 ); createMenu( 4042, removeId, -1 ); + createMenu( 4044, removeId, -1 ); + createMenu( separator(), removeId, -1 ); + createMenu( 813, removeId, -1 ); + createMenu( separator(), removeId, -1 ); createMenu( 4043, removeId, -1 ); createMenu( 4051, renumId, -1 ); @@ -2866,24 +3815,30 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 4061, transfId, -1 ); createMenu( 4062, transfId, -1 ); createMenu( 4063, transfId, -1 ); + createMenu( 4068, transfId, -1 ); createMenu( 4064, transfId, -1 ); createMenu( 4065, transfId, -1 ); createMenu( 4066, transfId, -1 ); + createMenu( 4069, transfId, -1 ); - createMenu( 406, modifyId, -1 ); createMenu( 4067,modifyId, -1 ); createMenu( 407, modifyId, -1 ); createMenu( 408, modifyId, -1 ); createMenu( 409, modifyId, -1 ); + createMenu( 420, modifyId, -1 ); createMenu( 410, modifyId, -1 ); createMenu( 411, modifyId, -1 ); + createMenu( 419, modifyId, -1 ); createMenu( 412, modifyId, -1 ); createMenu( 413, modifyId, -1 ); createMenu( 416, modifyId, -1 ); createMenu( 414, modifyId, -1 ); createMenu( 415, modifyId, -1 ); createMenu( 417, modifyId, -1 ); + createMenu( 418, modifyId, -1 ); + createMenu( 501, measureId, -1 ); + createMenu( 502, measureId, -1 ); createMenu( 214, viewId, -1 ); // ----- create toolbars -------------- @@ -2897,9 +3852,12 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 703, meshTb ); createTool( 704, meshTb ); createTool( 710, meshTb ); + createTool( 705, meshTb ); createTool( separator(), meshTb ); createTool( 701, meshTb ); createTool( 711, meshTb ); + createTool( 712, meshTb ); + createTool( 713, meshTb ); createTool( separator(), meshTb ); createTool( 801, meshTb ); createTool( 806, meshTb ); @@ -2908,16 +3866,23 @@ void SMESHGUI::initialize( CAM_Application* app ) //createTool( 815, meshTb ); createTool( separator(), meshTb ); createTool( 900, meshTb ); - createTool( 902, meshTb ); - createTool( 903, meshTb ); + //createTool( 902, meshTb ); + //createTool( 903, meshTb ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command) + createTool( 904, meshTb ); createTool( separator(), meshTb ); - createTool( 6001, ctrlTb ); + createTool( 6005, ctrlTb ); + createTool( 6028, ctrlTb ); + createTool( separator(), ctrlTb ); + createTool( 6002, ctrlTb ); createTool( 6003, ctrlTb ); + createTool( 6001, ctrlTb ); createTool( 6004, ctrlTb ); + createTool( 6029, ctrlTb ); createTool( separator(), ctrlTb ); - createTool( 6005, ctrlTb ); - createTool( 6002, ctrlTb ); + createTool( 6021, ctrlTb ); + createTool( 6025, ctrlTb ); + createTool( 6027, ctrlTb ); createTool( 6018, ctrlTb ); createTool( 6019, ctrlTb ); createTool( 6011, ctrlTb ); @@ -2926,31 +3891,44 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 6014, ctrlTb ); createTool( 6015, ctrlTb ); createTool( 6016, ctrlTb ); + createTool( 6022, ctrlTb ); + createTool( 6030, ctrlTb ); createTool( separator(), ctrlTb ); createTool( 6017, ctrlTb ); createTool( 6009, ctrlTb ); - createTool( 6021, ctrlTb ); + createTool( 6023, ctrlTb ); + createTool( 6024, ctrlTb ); + createTool( 6026, ctrlTb ); + createTool( 6031, ctrlTb ); createTool( separator(), ctrlTb ); - createTool( 400, addRemTb ); - createTool( 401, addRemTb ); + createTool( 4000, addRemTb ); + createTool( 4009, addRemTb ); + createTool( 4008, addRemTb ); + createTool( 4010, addRemTb ); createTool( 4021, addRemTb ); createTool( 4022, addRemTb ); createTool( 4023, addRemTb ); createTool( 4031, addRemTb ); createTool( 4032, addRemTb ); + createTool( 4133, addRemTb ); + createTool( 4134, addRemTb ); + createTool( 4135, addRemTb ); createTool( 4033, addRemTb ); createTool( separator(), addRemTb ); createTool( 4034, addRemTb ); createTool( 4035, addRemTb ); createTool( 4036, addRemTb ); + createTool( 4136, addRemTb ); createTool( 4037, addRemTb ); createTool( 4038, addRemTb ); createTool( 4039, addRemTb ); createTool( 4040, addRemTb ); + createTool( 4140, addRemTb ); createTool( separator(), addRemTb ); createTool( 4041, addRemTb ); createTool( 4042, addRemTb ); + createTool( 4044, addRemTb ); createTool( 4043, addRemTb ); createTool( separator(), addRemTb ); createTool( 4051, addRemTb ); @@ -2959,24 +3937,28 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 4061, addRemTb ); createTool( 4062, addRemTb ); createTool( 4063, addRemTb ); + createTool( 4068, addRemTb ); createTool( 4064, addRemTb ); createTool( 4065, addRemTb ); createTool( 4066, addRemTb ); + createTool( 4069, addRemTb ); createTool( separator(), addRemTb ); - createTool( 406, modifyTb ); createTool( 4067,modifyTb ); createTool( 407, modifyTb ); createTool( 408, modifyTb ); createTool( 409, modifyTb ); + createTool( 420, modifyTb ); createTool( 410, modifyTb ); createTool( 411, modifyTb ); + createTool( 419, modifyTb ); createTool( 412, modifyTb ); createTool( 413, modifyTb ); createTool( 416, modifyTb ); createTool( 414, modifyTb ); createTool( 415, modifyTb ); createTool( 417, modifyTb ); + createTool( 418, modifyTb ); createTool( 214, dispModeTb ); @@ -2985,59 +3967,83 @@ void SMESHGUI::initialize( CAM_Application* app ) myRules.clear(); QString OB = "'ObjectBrowser'", - View = "'" + SVTK_Viewer::Type() + "'", - pat = "'%1'", - mesh = pat.arg( SMESHGUI_Selection::typeName( MESH ) ), - group = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ), - hypo = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ), - algo = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ), - elems = QString( "'%1' '%2' '%3' '%4' '%5' '%6'" ). + View = "'" + SVTK_Viewer::Type() + "'", + pat = "'%1'", + mesh = pat.arg( SMESHGUI_Selection::typeName( MESH ) ), + group = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ), + hypo = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ), + algo = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ), + elems = QString( "'%1' '%2' '%3' '%4' '%5' '%6'" ). arg( SMESHGUI_Selection::typeName( SUBMESH_VERTEX ) ). - arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ). - arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ). - arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ). - arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ). - arg( SMESHGUI_Selection::typeName( SUBMESH ) ), + arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ). + arg( SMESHGUI_Selection::typeName( SUBMESH ) ), subMesh = elems, - mesh_group = mesh + " " + subMesh + " " + group, - hyp_alg = hypo + " " + algo; + mesh_part = mesh + " " + subMesh + " " + group, + mesh_group = mesh + " " + group, + hyp_alg = hypo + " " + algo; // popup for object browser + QString + isInvisible("not( isVisible )"), + isEmpty("numberOfNodes = 0"), + isNotEmpty("numberOfNodes <> 0"), + + // has nodes, edges, etc in VISIBLE! actor + hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"), + hasElems("(count( elemTypes ) > 0)"), + hasDifferentElems("(count( elemTypes ) > 1)"), + hasBalls("({'BallElem'} in elemTypes)"), + hasElems0d("({'Elem0d'} in elemTypes)"), + hasEdges("({'Edge'} in elemTypes)"), + hasFaces("({'Face'} in elemTypes)"), + hasVolumes("({'Volume'} in elemTypes)"); createPopupItem( 150, OB, mesh, "&& selcount=1 && isImported" ); // FILE INFORMATION createPopupItem( 703, OB, mesh, "&& isComputable"); // CREATE_SUBMESH - //createPopupItem( 703, OB, subMesh, "&& isComputable" ); // CREATE_SUBMESH createPopupItem( 704, OB, mesh, "&& isComputable"); // EDIT_MESHSUBMESH createPopupItem( 704, OB, subMesh, "&& isComputable" ); // EDIT_MESHSUBMESH createPopupItem( 803, OB, group ); // EDIT_GROUP - createPopupItem( 815, OB, group, "&& groupType = 'GroupOnGeom'" ); // EDIT_GROUP + createPopupItem( 815, OB, group, "&& groupType != 'Group'" ); // EDIT AS STANDALONE popupMgr()->insert( separator(), -1, 0 ); createPopupItem( 701, OB, mesh, "&& isComputable" ); // COMPUTE - createPopupItem( 711, OB, mesh, "&& isComputable" ); // PRECOMPUTE - createPopupItem( 214, OB, mesh_group ); // UPDATE - createPopupItem( 900, OB, mesh_group ); // ADV_INFO - createPopupItem( 902, OB, mesh ); // STD_INFO - createPopupItem( 903, OB, mesh_group ); // WHAT_IS + createPopupItem( 711, OB, mesh, "&& isComputable && isPreComputable" ); // PRECOMPUTE + createPopupItem( 712, OB, mesh, "&& isComputable" ); // EVALUATE + createPopupItem( 713, OB, mesh, "&& isComputable" ); // MESH ORDER + createPopupItem( 214, OB, mesh_part ); // UPDATE + createPopupItem( 900, OB, mesh_part ); // ADV_INFO + createPopupItem( 904, OB, mesh_group ); // FIND_ELEM popupMgr()->insert( separator(), -1, 0 ); createPopupItem( 801, OB, mesh ); // CREATE_GROUP createPopupItem( 806, OB, mesh ); // CREATE_GEO_GROUP createPopupItem( 802, OB, subMesh ); // CONSTRUCT_GROUP popupMgr()->insert( separator(), -1, 0 ); createPopupItem( 1100, OB, hypo); // EDIT HYPOTHESIS - createPopupItem( 1102, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS - createPopupItem( 1101, OB, mesh_group + " " + hyp_alg ); // RENAME + createPopupItem( 1102, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS popupMgr()->insert( separator(), -1, 0 ); createPopupItem( 4043, OB, mesh ); // CLEAR_MESH popupMgr()->insert( separator(), -1, 0 ); + createPopupItem( 417, OB, mesh + " " + subMesh ); // convert to quadratic + createPopupItem( 418, OB, mesh + " " + group, // create 2D mesh from 3D + "&& dim>=2"); + popupMgr()->insert( separator(), -1, 0 ); QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc ); - - 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 - createPopupItem( 33, OB, mesh_group + " " + hyp_alg ); // DELETE + QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc ); + QString only_one_2D = only_one_non_empty + " && dim>1"; + + createPopupItem( 125, OB, mesh_group, multiple_non_empty ); // EXPORT_MED + createPopupItem( 126, OB, mesh_group, only_one_non_empty ); // EXPORT_UNV + createPopupItem( 141, OB, mesh_group, only_one_2D ); // EXPORT_STL +#ifdef WITH_CGNS + createPopupItem( 143, OB, mesh_group, multiple_non_empty ); // EXPORT_CGNS +#endif + createPopupItem( 145, OB, mesh_group, multiple_non_empty ); // EXPORT_SAUV + createPopupItem( 33, OB, mesh_part + " " + hyp_alg ); // DELETE + createPopupItem( 813, OB, group ); // DEL_GROUP with contents popupMgr()->insert( separator(), -1, 0 ); // popup for viewer @@ -3046,10 +4052,9 @@ void SMESHGUI::initialize( CAM_Application* app ) createPopupItem( 805, View, elems ); // REMOVE popupMgr()->insert( separator(), -1, 0 ); - createPopupItem( 214, View, mesh_group ); // UPDATE - createPopupItem( 900, View, mesh_group ); // ADV_INFO - createPopupItem( 902, View, mesh ); // STD_INFO - createPopupItem( 903, View, mesh_group ); // WHAT_IS + createPopupItem( 214, View, mesh_part ); // UPDATE + createPopupItem( 900, View, mesh_part ); // ADV_INFO + createPopupItem( 904, View, mesh ); // FIND_ELEM popupMgr()->insert( separator(), -1, 0 ); createPopupItem( 1136, OB + " " + View, mesh, "&& (not isAutoColor)" ); // AUTO_COLOR @@ -3057,22 +4062,9 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), -1, 0 ); int anId; - QString - isInvisible("not( isVisible )"), - isEmpty("numberOfNodes = 0"), - isNotEmpty("numberOfNodes <> 0"), - - // has nodes, edges, etc in VISIBLE! actor - hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"), - hasElems("(count( elemTypes ) > 0)"), - hasDifferentElems("(count( elemTypes ) > 1)"), - hasEdges("({'Edge'} in elemTypes)"), - hasFaces("({'Face'} in elemTypes)"), - hasVolumes("({'Volume'} in elemTypes)"); - QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" ); QString aType = QString( "%1type in {%2}" ).arg( lc ); - aType = aType.arg( mesh_group ); + aType = aType.arg( mesh_part ); QString aMeshInVTK = aClient + "&&" + aType; aClient = "($client in {'VTKViewer' 'ObjectBrowser'})"; @@ -3124,6 +4116,10 @@ void SMESHGUI::initialize( CAM_Application* app ) anId = popupMgr()->insert( tr( "MEN_DISP_ENT" ), -1, -1 ); + popupMgr()->insert( action(216), anId, -1 ); // ELEMS 0D + popupMgr()->setRule(action(216), aDiffElemsInVTK + "&& isVisible &&" + hasElems0d, QtxPopupMgr::VisibleRule); + popupMgr()->setRule(action(216), "{'Elem0d'} in entityMode", QtxPopupMgr::ToggleRule); + popupMgr()->insert( action( 217 ), anId, -1 ); // EDGES popupMgr()->setRule( action( 217 ), aDiffElemsInVTK + "&& isVisible &&" + hasEdges, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 217 ), "{'Edge'} in entityMode", QtxPopupMgr::ToggleRule ); @@ -3136,11 +4132,28 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->setRule( action( 219 ), aDiffElemsInVTK + "&& isVisible &&" + hasVolumes, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 219 ), "{'Volume'} in entityMode", QtxPopupMgr::ToggleRule ); + popupMgr()->insert( action( 222 ), anId, -1 ); // BALLS + popupMgr()->setRule( action( 222 ), aDiffElemsInVTK + "&& isVisible &&" + hasBalls, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 222 ), "{'BallElem'} in entityMode", QtxPopupMgr::ToggleRule ); + popupMgr()->insert( separator(), anId, -1 ); popupMgr()->insert( action( 220 ), anId, -1 ); // ALL popupMgr()->setRule( action( 220 ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", QtxPopupMgr::VisibleRule ); + + //------------------------------------------------- + // Representation of the 2D Quadratic elements + //------------------------------------------------- + anId = popupMgr()->insert( tr( "MEN_QUADRATIC_REPRESENT" ), -1, -1 ); + popupMgr()->insert( action( 231 ), anId, -1 ); // LINE REPRESENTATION + popupMgr()->setRule( action( 231 ), aMeshInVTK + "and isVisible",QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 231 ), "quadratic2DMode = 'eLines'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert( action( 232 ), anId, -1 ); // ARC REPRESENTATION + popupMgr()->setRule( action( 232 ), aMeshInVTK + "and isVisible", QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 232 ), "quadratic2DMode = 'eArcs'", QtxPopupMgr::ToggleRule ); + //------------------------------------------------- // Orientation of faces //------------------------------------------------- @@ -3160,14 +4173,6 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( action( 1133 ), -1, -1 ); popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule ); - //------------------------------------------------- - // Clipping - //------------------------------------------------- - popupMgr()->insert( action( 1134 ), -1, -1 ); - popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& selcount=1 && isVisible", QtxPopupMgr::VisibleRule ); - - popupMgr()->insert( separator(), -1, -1 ); - //------------------------------------------------- // Controls //------------------------------------------------- @@ -3184,85 +4189,142 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), anId, -1 ); - popupMgr()->insert( action( 6003 ), anId, -1 ); // FREE_BORDER + int aSubId = popupMgr()->insert( tr( "MEN_NODE_CTRL" ), anId, -1 ); // NODE CONTROLS + + popupMgr()->insert( action( 6005 ), aSubId, -1 ); // FREE_NODE + popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert ( action( 6028 ), aSubId, -1 ); // EQUAL_NODE + popupMgr()->setRule( action( 6028 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6028 ), "controlMode = 'eCoincidentNodes'", QtxPopupMgr::ToggleRule); + + aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS + + popupMgr()->insert( action( 6002 ), aSubId, -1 ); // FREE_EDGE + popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert( action( 6003 ), aSubId, -1 ); // FREE_BORDER popupMgr()->setRule( action( 6003 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6003 ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6001 ), anId, -1 ); // LENGTH + popupMgr()->insert( action( 6001 ), aSubId, -1 ); // LENGTH popupMgr()->setRule( action( 6001 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6001 ), "controlMode = 'eLength'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6004 ), anId, -1 ); // CONNECTION + popupMgr()->insert( action( 6004 ), aSubId, -1 ); // CONNECTION popupMgr()->setRule( action( 6004 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6004 ), "controlMode = 'eMultiConnection'", QtxPopupMgr::ToggleRule ); + popupMgr()->insert ( action( 6029 ), aSubId, -1 ); // EQUAL_EDGE + popupMgr()->setRule( action( 6029 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6029 ), "controlMode = 'eCoincidentElems1D'", QtxPopupMgr::ToggleRule); - popupMgr()->insert( separator(), anId, -1 ); - - popupMgr()->insert( action( 6005 ), anId, -1 ); // FREE_NODE - popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule ); - popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule ); + aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS - popupMgr()->insert( action( 6002 ), anId, -1 ); // FREE_EDGE - popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); - popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule ); + popupMgr()->insert ( action( 6021 ), aSubId, -1 ); // FREE_FACE + popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/, + QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6018 ), anId, -1 ); // LENGTH_2D + popupMgr()->insert ( action( 6018 ), aSubId, -1 ); // LENGTH_2D popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6019 ), anId, -1 ); // CONNECTION_2D + popupMgr()->insert ( action( 6019 ), aSubId, -1 ); // CONNECTION_2D popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6011 ), anId, -1 ); // AREA + popupMgr()->insert ( action( 6011 ), aSubId, -1 ); // AREA popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6012 ), anId, -1 ); // TAPER + popupMgr()->insert ( action( 6012 ), aSubId, -1 ); // TAPER popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6013 ), anId, -1 ); // ASPECT + popupMgr()->insert ( action( 6013 ), aSubId, -1 ); // ASPECT popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6014 ), anId, -1 ); // MIN_ANG + popupMgr()->insert ( action( 6014 ), aSubId, -1 ); // MIN_ANG popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6015 ), anId, -1 ); // WARP + popupMgr()->insert ( action( 6015 ), aSubId, -1 ); // WARP popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6016 ), anId, -1 ); // SKEW + popupMgr()->insert ( action( 6016 ), aSubId, -1 ); // SKEW popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( separator(), anId, -1 ); + popupMgr()->insert ( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D + popupMgr()->setRule( action( 6022 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6022 ), "controlMode = 'eMaxElementLength2D'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert ( action( 6025 ), aSubId, -1 ); // BARE_BORDER_FACE + popupMgr()->setRule( action( 6025 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6025 ), "controlMode = 'eBareBorderFace'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6017 ), anId, -1 ); // ASPECT_3D + popupMgr()->insert ( action( 6027 ), aSubId, -1 ); // OVER_CONSTRAINED_FACE + popupMgr()->setRule( action( 6027 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6027 ), "controlMode = 'eOverConstrainedFace'", QtxPopupMgr::ToggleRule ); + popupMgr()->insert ( action( 6030 ), aSubId, -1 ); // EQUAL_FACE + popupMgr()->setRule( action( 6030 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6030 ), "controlMode = 'eCoincidentElems2D'", QtxPopupMgr::ToggleRule ); + + aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS + + popupMgr()->insert ( action( 6017 ), aSubId, -1 ); // ASPECT_3D popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert ( action( 6009 ), anId, -1 ); // VOLUME_3D + popupMgr()->insert ( action( 6009 ), aSubId, -1 ); // VOLUME_3D popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6021 ), anId, -1 ); // FREE_FACE - popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/, - QtxPopupMgr::VisibleRule ); - popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule ); + popupMgr()->insert ( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D + popupMgr()->setRule( action( 6023 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6023 ), "controlMode = 'eMaxElementLength3D'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert ( action( 6024 ), aSubId, -1 ); // BARE_BORDER_VOLUME + popupMgr()->setRule( action( 6024 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6024 ), "controlMode = 'eBareBorderVolume'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert ( action( 6026 ), aSubId, -1 ); // OVER_CONSTRAINED_VOLUME + popupMgr()->setRule( action( 6026 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6026 ), "controlMode = 'eOverConstrainedVolume'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert ( action( 6031 ), aSubId, -1 ); // EQUAL_VOLUME + popupMgr()->setRule( action( 6031 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6031 ), "controlMode = 'eCoincidentElems3D'", QtxPopupMgr::ToggleRule ); popupMgr()->insert( separator(), anId, -1 ); popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule ); - popupMgr()->insert( separator(), -1, -1 ); + popupMgr()->insert( separator(), anId, -1 ); + + aSubId = popupMgr()->insert( tr( "MEN_DISTRIBUTION_CTRL" ), anId, -1 ); // NODE CONTROLS + + popupMgr()->insert( action( 2021 ), aSubId, -1 ); // SAVE_DISTRIBUTION + popupMgr()->setRule( action( 2021 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule ); + + popupMgr()->insert( action( 2022 ), aSubId, -1 ); // SHOW_DISTRIBUTION + popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule); + +#ifndef DISABLE_PLOT2DVIEWER + popupMgr()->insert( action( 2023 ), aSubId, -1 ); // PLOT_DISTRIBUTION + popupMgr()->setRule( action( 2023 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule ); +#endif //------------------------------------------------- // Display / Erase //------------------------------------------------- + popupMgr()->insert( separator(), -1, -1 ); QString aRule = "$component={'SMESH'} and ( type='Component' or (" + aClient + " and " + aType + " and " + aSelCount + " and " + anActiveVTK + " and " + isNotEmpty + " %1 ) )"; popupMgr()->insert( action( 301 ), -1, -1 ); // DISPLAY @@ -3276,8 +4338,19 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), -1, -1 ); + //------------------------------------------------- + // Clipping + //------------------------------------------------- + popupMgr()->insert( action( 1134 ), -1, -1 ); + popupMgr()->setRule( action( 1134 ), "client='VTKViewer'", QtxPopupMgr::VisibleRule ); + + popupMgr()->insert( separator(), -1, -1 ); + connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ), - this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) ); + this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) ); + + connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ), + this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) ); } //================================================================================ @@ -3304,6 +4377,13 @@ bool SMESHGUI::isSelectionCompatible() return isCompatible; } + +bool SMESHGUI::reusableOperation( const int id ) +{ + // compute, evaluate and precompute are not reusable operations + return ( id == 701 || id == 711 || id == 712 ) ? false : SalomeApp_Module::reusableOperation( id ); +} + bool SMESHGUI::activateModule( SUIT_Study* study ) { bool res = SalomeApp_Module::activateModule( study ); @@ -3311,13 +4391,45 @@ bool SMESHGUI::activateModule( SUIT_Study* study ) setMenuShown( true ); setToolShown( true ); + // import Python module that manages SMESH plugins (need to be here because SalomePyQt API uses active module) + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* pluginsmanager=PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager"); + if(pluginsmanager==NULL) + PyErr_Print(); + else + { + PyObject* result=PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"smesh",tr("MEN_MESH").toStdString().c_str(),tr("SMESH_PLUGINS_OTHER").toStdString().c_str()); + if(result==NULL) + PyErr_Print(); + Py_XDECREF(result); + } + PyGILState_Release(gstate); + // end of GEOM plugins loading + // Reset actions accelerator keys action(111)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); // Import DAT action(112)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U)); // Import UNV action(113)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M)); // Import MED action( 33)->setEnabled(true); // Delete: Key_Delete - action(1101)->setEnabled(true); // Rename: Key_F2 + + // 0020210. Make SMESH_Gen update meshes at switching GEOM->SMESH + GetSMESHGen()->SetCurrentStudy(SALOMEDS::Study::_nil()); + if ( SalomeApp_Study* s = dynamic_cast( study )) + if ( _PTR(Study) aStudy = s->studyDS()) { + GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() ); + updateObjBrowser(); // objects can be removed + } + + // get all view currently opened in the study and connect their signals to + // the corresponding slots of the class. + SUIT_Desktop* aDesk = study->application()->desktop(); + if ( aDesk ) { + QList wndList = aDesk->windows(); + SUIT_ViewWindow* wnd; + foreach ( wnd, wndList ) + connectView( wnd ); + } return res; } @@ -3335,7 +4447,6 @@ bool SMESHGUI::deactivateModule( SUIT_Study* study ) action(113)->setShortcut(QKeySequence()); // Import MED action( 33)->setEnabled(false); // Delete: Key_Delete - action(1101)->setEnabled(false); // Rename: Key_F2 return SalomeApp_Module::deactivateModule( study ); } @@ -3391,7 +4502,7 @@ void SMESHGUI::contextMenuPopup( const QString& client, QMenu* menu, QString& ti if ( obj ) { QString aName = QString( obj->GetName().c_str() ); while ( aName.at( aName.length() - 1 ) == ' ' ) // Remove extraspaces in Name of Popup - aName.remove( (aName.length() - 1), 1 ); + aName.remove( (aName.length() - 1), 1 ); title = aName; } } @@ -3415,8 +4526,58 @@ void SMESHGUI::viewManagers( QStringList& list ) const void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr ) { - if ( dynamic_cast( mgr ) ) + if ( dynamic_cast( mgr ) ) { SMESH::UpdateSelectionProp( this ); + + QVector aViews = mgr->getViews(); + for(int i = 0; i < aViews.count() ; i++){ + SUIT_ViewWindow *sf = aViews[i]; + connectView( sf ); + } + } +} + +void SMESHGUI::onViewManagerRemoved( SUIT_ViewManager* theViewManager ) +{ + if( theViewManager && theViewManager->getType() == SVTK_Viewer::Type() ) + myClippingPlaneInfoMap.erase( theViewManager ); +} + +void SMESHGUI::addActorAsObserver( SMESH_Actor* theActor ) +{ + theActor->AddObserver( SMESH::DeleteActorEvent, + myEventCallbackCommand.GetPointer(), + myPriority ); +} + +void SMESHGUI::ProcessEvents( vtkObject* theObject, + unsigned long theEvent, + void* theClientData, + void* theCallData ) +{ + if( SMESHGUI* aSMESHGUI = reinterpret_cast( theClientData ) ) { + if( theObject && theEvent == SMESH::DeleteActorEvent ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) { + SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin(); + for( ; anIter1 != aClippingPlaneInfoMap.end(); anIter1++ ) { + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second; + SMESHGUI_ClippingPlaneInfoList::iterator anIter2 = aClippingPlaneInfoList.begin(); + for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) { + SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2; + std::list& anActorList = aClippingPlaneInfo.ActorList; + SMESH::TActorList::iterator anIter3 = anActorList.begin(); + for ( ; anIter3 != anActorList.end(); anIter3++ ) { + if( anActor == *anIter3 ) { + anActorList.erase( anIter3 ); + break; + } + } + } + } + } + } + } } void SMESHGUI::createPreferences() @@ -3424,8 +4585,12 @@ void SMESHGUI::createPreferences() // General tab ------------------------------------------------------------------------ int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) ); - int updateGroup = addPreference( tr( "PREF_GROUP_UPDATE" ), genTab ); - addPreference( tr( "PREF_AUTO_UPDATE" ), updateGroup, LightApp_Preferences::Bool, "SMESH", "auto_update" ); + int autoUpdate = addPreference( tr( "PREF_AUTO_UPDATE" ), genTab, LightApp_Preferences::Auto, "SMESH", "auto_update" ); + int lim = addPreference( tr( "PREF_UPDATE_LIMIT" ), autoUpdate, LightApp_Preferences::IntSpin, "SMESH", "update_limit" ); + setPreferenceProperty( lim, "min", 0 ); + setPreferenceProperty( lim, "max", 100000000 ); + setPreferenceProperty( lim, "step", 1000 ); + setPreferenceProperty( lim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) ); int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab ); setPreferenceProperty( qaGroup, "columns", 2 ); @@ -3434,15 +4599,20 @@ void SMESHGUI::createPreferences() int prec = addPreference( tr( "PREF_PRECISION_VALUE" ), qaGroup, LightApp_Preferences::IntSpin, "SMESH", "controls_precision" ); setPreferenceProperty( prec, "min", 0 ); setPreferenceProperty( prec, "max", 16 ); + int doubleNodesTol = addPreference( tr( "PREF_EQUAL_NODES_TOL" ), qaGroup, LightApp_Preferences::DblSpin, "SMESH", "equal_nodes_tolerance" ); + setPreferenceProperty( doubleNodesTol, "precision", 10 ); + setPreferenceProperty( doubleNodesTol, "min", 0.0000000001 ); + setPreferenceProperty( doubleNodesTol, "max", 1000000.0 ); + setPreferenceProperty( doubleNodesTol, "step", 0.0000001 ); int dispgroup = addPreference( tr( "PREF_DISPLAY_MODE" ), genTab ); setPreferenceProperty( dispgroup, "columns", 2 ); int dispmode = addPreference( tr( "PREF_DISPLAY_MODE" ), dispgroup, LightApp_Preferences::Selector, "SMESH", "display_mode" ); QStringList modes; - modes.append( "Wireframe" ); - modes.append( "Shading" ); - modes.append( "Nodes" ); - modes.append( "Shrink" ); + modes.append( tr("MEN_WIRE") ); + modes.append( tr("MEN_SHADE") ); + modes.append( tr("MEN_NODES") ); + modes.append( tr("MEN_SHRINK") ); QList indices; indices.append( 0 ); indices.append( 1 ); @@ -3451,6 +4621,25 @@ void SMESHGUI::createPreferences() setPreferenceProperty( dispmode, "strings", modes ); setPreferenceProperty( dispmode, "indexes", indices ); + int arcgroup = addPreference( tr( "QUADRATIC_REPRESENT_MODE" ), genTab ); + setPreferenceProperty( arcgroup, "columns", 2 ); + int quadraticmode = addPreference( tr( "QUADRATIC_REPRESENT_MODE" ), arcgroup, LightApp_Preferences::Selector, "SMESH", "quadratic_mode" ); + QStringList quadraticModes; + quadraticModes.append(tr("MEN_LINE_REPRESENTATION")); + quadraticModes.append(tr("MEN_ARC_REPRESENTATION")); + indices.clear(); + indices.append( 0 ); + indices.append( 1 ); + setPreferenceProperty( quadraticmode, "strings", quadraticModes ); + setPreferenceProperty( quadraticmode, "indexes", indices ); + + int maxAngle = addPreference( tr( "MAX_ARC_ANGLE" ), arcgroup, LightApp_Preferences::IntSpin, + "SMESH", "max_angle" ); + setPreferenceProperty( maxAngle, "min", 1 ); + setPreferenceProperty( maxAngle, "max", 90 ); + + + int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab ); setPreferenceProperty( exportgroup, "columns", 2 ); addPreference( tr( "PREF_AUTO_GROUPS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "auto_groups" ); @@ -3460,9 +4649,9 @@ void SMESHGUI::createPreferences() setPreferenceProperty( computeGroup, "columns", 2 ); int notifyMode = addPreference( tr( "PREF_NOTIFY_MODE" ), computeGroup, LightApp_Preferences::Selector, "SMESH", "show_result_notification" ); modes.clear(); - modes.append( "Never" ); - modes.append( "Errors only" ); - modes.append( "Always" ); + modes.append( tr( "PREF_NOTIFY_NEVER" ) ); + modes.append( tr( "PREF_NOTIFY_ERROR" ) ); + modes.append( tr( "PREF_NOTIFY_ALWAYS" ) ); indices.clear(); indices.append( 0 ); indices.append( 1 ); @@ -3470,6 +4659,23 @@ void SMESHGUI::createPreferences() setPreferenceProperty( notifyMode, "strings", modes ); setPreferenceProperty( notifyMode, "indexes", indices ); + int infoGroup = addPreference( tr( "PREF_GROUP_INFO" ), genTab ); + setPreferenceProperty( infoGroup, "columns", 4 ); + int elemInfo = addPreference( tr( "PREF_ELEM_INFO" ), infoGroup, LightApp_Preferences::Selector, "SMESH", "mesh_elem_info" ); + modes.clear(); + modes.append( tr( "PREF_ELEM_INFO_SIMPLE" ) ); + modes.append( tr( "PREF_ELEM_INFO_TREE" ) ); + indices.clear(); + indices.append( 0 ); + indices.append( 1 ); + setPreferenceProperty( elemInfo, "strings", modes ); + setPreferenceProperty( elemInfo, "indexes", indices ); + int nodesLim = addPreference( tr( "PREF_GPP_NODES_LIMIT" ), infoGroup, LightApp_Preferences::IntSpin, "SMESH", "info_groups_nodes_limit" ); + setPreferenceProperty( nodesLim, "min", 0 ); + setPreferenceProperty( nodesLim, "max", 10000000 ); + setPreferenceProperty( nodesLim, "step", 10000 ); + setPreferenceProperty( nodesLim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) ); + int segGroup = addPreference( tr( "PREF_GROUP_SEGMENT_LENGTH" ), genTab ); setPreferenceProperty( segGroup, "columns", 2 ); int segLen = addPreference( tr( "PREF_SEGMENT_LENGTH" ), segGroup, LightApp_Preferences::IntSpin, @@ -3481,30 +4687,109 @@ void SMESHGUI::createPreferences() setPreferenceProperty( nbSeg, "min", 1 ); setPreferenceProperty( nbSeg, "max", 10000000 ); + int loadGroup = addPreference( tr( "SMESH_PREF_MESH_LOADING" ), genTab ); + addPreference( tr( "PREF_FORGET_MESH_AT_HYP_MODIF" ), loadGroup, LightApp_Preferences::Bool, + "SMESH", "forget_mesh_on_hyp_modif" ); + + + // Quantities with individual precision settings + int precGroup = addPreference( tr( "SMESH_PREF_GROUP_PRECISION" ), genTab ); + setPreferenceProperty( precGroup, "columns", 2 ); + + const int nbQuantities = 6; + int precs[nbQuantities], ii = 0; + precs[ii++] = addPreference( tr( "SMESH_PREF_length_precision" ), precGroup, + LightApp_Preferences::IntSpin, "SMESH", "length_precision" ); + precs[ii++] = addPreference( tr( "SMESH_PREF_angle_precision" ), precGroup, + LightApp_Preferences::IntSpin, "SMESH", "angle_precision" ); + precs[ii++] = addPreference( tr( "SMESH_PREF_len_tol_precision" ), precGroup, + LightApp_Preferences::IntSpin, "SMESH", "len_tol_precision" ); + precs[ii++] = addPreference( tr( "SMESH_PREF_parametric_precision" ), precGroup, + LightApp_Preferences::IntSpin, "SMESH", "parametric_precision" ); + precs[ii++] = addPreference( tr( "SMESH_PREF_area_precision" ), precGroup, + LightApp_Preferences::IntSpin, "SMESH", "area_precision" ); + precs[ii ] = addPreference( tr( "SMESH_PREF_vol_precision" ), precGroup, + LightApp_Preferences::IntSpin, "SMESH", "vol_precision" ); + + // Set property for precision value for spinboxes + for ( ii = 0; ii < nbQuantities; ii++ ){ + setPreferenceProperty( precs[ii], "min", -14 ); + setPreferenceProperty( precs[ii], "max", 14 ); + setPreferenceProperty( precs[ii], "precision", 2 ); + } + + int previewGroup = addPreference( tr( "SMESH_PREF_GROUP_PREVIEW" ), genTab ); + setPreferenceProperty( previewGroup, "columns", 2 ); + int chunkSize = addPreference( tr( "PREF_PREVIEW_CHUNK_SIZE" ), previewGroup, LightApp_Preferences::IntSpin, "SMESH", "preview_actor_chunk_size" ); + setPreferenceProperty( chunkSize, "min", 0 ); + setPreferenceProperty( chunkSize, "max", 1000 ); + setPreferenceProperty( chunkSize, "step", 50 ); + + int pyDumpGroup = addPreference( tr( "PREF_PYTHON_DUMP" ), genTab ); + addPreference( tr( "PREF_HISTORICAL_PYTHON_DUMP" ), pyDumpGroup, LightApp_Preferences::Bool, "SMESH", "historical_python_dump" ); + // Mesh tab ------------------------------------------------------------------------ int meshTab = addPreference( tr( "PREF_TAB_MESH" ) ); int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab ); - setPreferenceProperty( nodeGroup, "columns", 2 ); + setPreferenceProperty( nodeGroup, "columns", 3 ); addPreference( tr( "PREF_COLOR" ), nodeGroup, LightApp_Preferences::Color, "SMESH", "node_color" ); - int nodeSz = addPreference( tr( "PREF_SIZE" ), nodeGroup, LightApp_Preferences::IntSpin, "SMESH", "node_size" ); - setPreferenceProperty( nodeSz, "min", 1 ); - setPreferenceProperty( nodeSz, "max", 5 ); + int typeOfMarker = addPreference( tr( "PREF_TYPE_OF_MARKER" ), nodeGroup, LightApp_Preferences::Selector, "SMESH", "type_of_marker" ); + + SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this); + QList aMarkerTypeIndicesList; + QList aMarkerTypeIconsList; + for ( int i = VTK::MT_POINT; i < VTK::MT_USER; i++ ) { + QString icoFile = QString( "ICON_VERTEX_MARKER_%1" ).arg( i ); + QPixmap pixmap = aResourceMgr->loadPixmap( "VTKViewer", tr( qPrintable( icoFile ) ) ); + aMarkerTypeIndicesList << i; + aMarkerTypeIconsList << pixmap; + } + setPreferenceProperty( typeOfMarker, "indexes", aMarkerTypeIndicesList ); + setPreferenceProperty( typeOfMarker, "icons", aMarkerTypeIconsList ); + + int markerScale = addPreference( tr( "PREF_MARKER_SCALE" ), nodeGroup, LightApp_Preferences::Selector, "SMESH", "marker_scale" ); + + QList aMarkerScaleIndicesList; + QStringList aMarkerScaleValuesList; + for ( int i = VTK::MS_10; i <= VTK::MS_70; i++ ) { + aMarkerScaleIndicesList << i; + aMarkerScaleValuesList << QString::number( (i-(int)VTK::MS_10)*0.5 + 1.0 ); + } + setPreferenceProperty( markerScale, "strings", aMarkerScaleValuesList ); + setPreferenceProperty( markerScale, "indexes", aMarkerScaleIndicesList ); int elemGroup = addPreference( tr( "PREF_GROUP_ELEMENTS" ), meshTab ); setPreferenceProperty( elemGroup, "columns", 2 ); - addPreference( tr( "PREF_FILL" ), elemGroup, LightApp_Preferences::Color, "SMESH", "fill_color" ); - addPreference( tr( "PREF_OUTLINE" ), elemGroup, LightApp_Preferences::Color, "SMESH", "outline_color" ); - addPreference( tr( "PREF_BACKFACE" ), elemGroup, LightApp_Preferences::Color, "SMESH", "backface_color" ); - int sp = addPreference( "", elemGroup, LightApp_Preferences::Space ); + int ColorId = addPreference( tr( "PREF_FILL" ), elemGroup, LightApp_Preferences::BiColor, "SMESH", "fill_color" ); + addPreference( tr( "PREF_COLOR_0D" ), elemGroup, LightApp_Preferences::Color, "SMESH", "elem0d_color" ); + addPreference( tr( "PREF_BALL_COLOR" ), elemGroup, LightApp_Preferences::Color, "SMESH", "ball_elem_color" ); + addPreference( tr( "PREF_OUTLINE" ), elemGroup, LightApp_Preferences::Color, "SMESH", "outline_color" ); + addPreference( tr( "PREF_WIREFRAME" ), elemGroup, LightApp_Preferences::Color, "SMESH", "wireframe_color" ); - setPreferenceProperty( sp, "hstretch", 0 ); - setPreferenceProperty( sp, "vstretch", 0 ); + setPreferenceProperty( ColorId, "text", tr("PREF_BACKFACE") ); - int elemW = addPreference( tr( "PREF_WIDTH" ), elemGroup, LightApp_Preferences::IntSpin, "SMESH", "element_width" ); - int shrink = addPreference( tr( "PREF_SHRINK_COEFF" ), elemGroup, LightApp_Preferences::IntSpin, "SMESH", "shrink_coeff" ); + int grpGroup = addPreference( tr( "PREF_GROUP_GROUPS" ), meshTab ); + setPreferenceProperty( grpGroup, "columns", 2 ); + + addPreference( tr( "PREF_GRP_NAMES" ), grpGroup, LightApp_Preferences::Color, "SMESH", "group_name_color" ); + + int size0d = addPreference(tr("PREF_SIZE_0D"), elemGroup, + LightApp_Preferences::IntSpin, "SMESH", "elem0d_size"); + int ballSize = addPreference(tr("PREF_BALL_SIZE"), elemGroup, + LightApp_Preferences::IntSpin, "SMESH", "ball_elem_size"); + int elemW = addPreference(tr("PREF_WIDTH"), elemGroup, + LightApp_Preferences::IntSpin, "SMESH", "element_width"); + int shrink = addPreference(tr("PREF_SHRINK_COEFF"), elemGroup, + LightApp_Preferences::IntSpin, "SMESH", "shrink_coeff"); + + setPreferenceProperty( size0d, "min", 1 ); + setPreferenceProperty( size0d, "max", 10 ); + + setPreferenceProperty( ballSize, "min", 1 ); + setPreferenceProperty( ballSize, "max", 10 ); setPreferenceProperty( elemW, "min", 1 ); setPreferenceProperty( elemW, "max", 5 ); @@ -3532,19 +4817,11 @@ void SMESHGUI::createPreferences() addPreference( tr( "PREF_OBJECT_COLOR" ), selGroup, LightApp_Preferences::Color, "SMESH", "selection_object_color" ); addPreference( tr( "PREF_ELEMENT_COLOR" ), selGroup, LightApp_Preferences::Color, "SMESH", "selection_element_color" ); - int selW = addPreference( tr( "PREF_WIDTH" ), selGroup, LightApp_Preferences::IntSpin, "SMESH", "selection_width" ); - - setPreferenceProperty( selW, "min", 1 ); - setPreferenceProperty( selW, "max", 5 ); int preGroup = addPreference( tr( "PREF_GROUP_PRESELECTION" ), selTab ); setPreferenceProperty( preGroup, "columns", 2 ); addPreference( tr( "PREF_HIGHLIGHT_COLOR" ), preGroup, LightApp_Preferences::Color, "SMESH", "highlight_color" ); - int preW = addPreference( tr( "PREF_WIDTH" ), preGroup, LightApp_Preferences::IntSpin, "SMESH", "highlight_width" ); - - setPreferenceProperty( preW, "min", 1 ); - setPreferenceProperty( preW, "max", 5 ); int precSelGroup = addPreference( tr( "PREF_GROUP_PRECISION" ), selTab ); setPreferenceProperty( precSelGroup, "columns", 2 ); @@ -3625,6 +4902,18 @@ void SMESHGUI::createPreferences() setPreferenceProperty( hh, "min", 0.0 ); setPreferenceProperty( hh, "max", 1.0 ); setPreferenceProperty( hh, "step", 0.1 ); + + int distributionGr = addPreference( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), sbarTab, LightApp_Preferences::Auto, "SMESH", "distribution_visibility" ); + int coloringType = addPreference( tr( "SMESH_DISTRIBUTION_COLORING_TYPE" ), distributionGr, LightApp_Preferences::Selector, "SMESH", "distribution_coloring_type" ); + setPreferenceProperty( distributionGr, "columns", 3 ); + QStringList types; + types.append( tr( "SMESH_MONOCOLOR" ) ); + types.append( tr( "SMESH_MULTICOLOR" ) ); + indices.clear(); indices.append( 0 ); indices.append( 1 ); + setPreferenceProperty( coloringType, "strings", types ); + setPreferenceProperty( coloringType, "indexes", indices ); + addPreference( tr( "SMESH_DISTRIBUTION_COLOR" ), distributionGr, LightApp_Preferences::Color, "SMESH", "distribution_color" ); + } void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) @@ -3635,50 +4924,50 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) std::string aWarning; SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this); if( name=="selection_object_color" || name=="selection_element_color" || - name=="selection_width" || name=="highlight_color" || name=="highlight_width" || + name=="highlight_color" || name=="selection_precision_node" || name=="selection_precision_element" || - name=="selection_precision_object") + name=="selection_precision_object") SMESH::UpdateSelectionProp( this ); else if (name == QString("scalar_bar_vertical_x") || name == QString("scalar_bar_vertical_width")){ 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"; - sbX1=0.01; - sbW=0.08; - aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1); - aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW); + aWarning = "Origin and Size Vertical: X+Width > 1\n"; + sbX1=0.01; + sbW=0.08; + aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1); + aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW); } } else if(name == QString("scalar_bar_vertical_y") || name == QString("scalar_bar_vertical_height")){ sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_y", sbY1); sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_height",sbH); if(sbY1+sbH > aTol){ - aWarning = "Origin and Size Vertical: Y+Height > 1\n"; - aResourceMgr->setValue("SMESH", "scalar_bar_vertical_y", sbY1); - aResourceMgr->setValue("SMESH", "scalar_bar_vertical_height",sbH); + aWarning = "Origin and Size Vertical: Y+Height > 1\n"; + aResourceMgr->setValue("SMESH", "scalar_bar_vertical_y", sbY1); + aResourceMgr->setValue("SMESH", "scalar_bar_vertical_height",sbH); } } else if(name == QString("scalar_bar_horizontal_x") || name == QString("scalar_bar_horizontal_width")){ sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_x", sbX1); sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_width", sbW); if(sbX1+sbW > aTol){ - aWarning = "Origin and Size Horizontal: X+Width > 1\n"; - sbX1=0.1; - sbW=0.08; - aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_x", sbX1); - aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_width", sbW); + aWarning = "Origin and Size Horizontal: X+Width > 1\n"; + sbX1=0.1; + sbW=0.08; + aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_x", sbX1); + aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_width", sbW); } } else if(name == QString("scalar_bar_horizontal_y") || name == QString("scalar_bar_horizontal_height")){ sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_y", sbY1); sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_height",sbH); if(sbY1+sbH > aTol){ - aWarning = "Origin and Size Horizontal: Y+Height > 1\n"; - sbY1=0.01; - sbH=0.08; - aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_y", sbY1); - aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH); + aWarning = "Origin and Size Horizontal: Y+Height > 1\n"; + sbY1=0.01; + sbH=0.08; + aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_y", sbY1); + aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH); } } else if ( name == "segmentation" ) { @@ -3689,12 +4978,17 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) int nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 ); myComponentSMESH->SetDefaultNbSegments( nbSeg ); } + else if ( name == "historical_python_dump" || + name == "forget_mesh_on_hyp_modif") { + QString val = aResourceMgr->stringValue( "SMESH", name ); + myComponentSMESH->SetOption( name.toLatin1().constData(), val.toLatin1().constData() ); + } if(aWarning.size() != 0){ aWarning += "The default values are applied instead."; SUIT_MessageBox::warning(SMESHGUI::desktop(), - QObject::tr("SMESH_ERR_SCALARBAR_PARAMS"), - QObject::tr(aWarning.c_str())); + QObject::tr("SMESH_ERR_SCALARBAR_PARAMS"), + QObject::tr(aWarning.c_str())); } } } @@ -3710,7 +5004,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) //================================================================================ void SMESHGUI::update( const int flags ) { - if ( flags & UF_Viewer | flags & UF_Forced ) + if ( (flags & UF_Viewer) | (flags & UF_Forced) ) SMESH::UpdateView(); else SalomeApp_Module::update( flags ); @@ -3762,6 +5056,15 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const // to do : create operation here switch( id ) { + case 417: //convert to quadratic + op = new SMESHGUI_ConvToQuadOp(); + break; + case 418: // create 2D mesh as boundary on 3D + op = new SMESHGUI_Make2DFrom3DOp(); + break; + case 420: // Reorient faces + op = new SMESHGUI_ReorientFacesOp(); + break; case 701: // Compute mesh op = new SMESHGUI_ComputeOp(); break; @@ -3777,12 +5080,18 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const case 711: // Precompute mesh op = new SMESHGUI_PrecomputeOp(); break; + case 712: // Evaluate mesh + op = new SMESHGUI_EvaluateOp(); + break; + case 713: // Evaluate mesh + op = new SMESHGUI_MeshOrderOp(); + break; case 806: // Create group on geom op = new SMESHGUI_GroupOnShapeOp(); break; - case 417: //convert to quadratic - op = new SMESHGUI_ConvToQuadOp(); - break; + case 904: // Find element + op = new SMESHGUI_FindElemByPointOp(); + break; case 4067: // make mesh pass through point op = new SMESHGUI_MakeNodeAtPointOp(); break; @@ -3830,14 +5139,11 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList& theReser { aTolerance /= 2; if( aTolerance < 1 ) - break; + break; } - //cout << "Iteration N" << anIterations << " (tolerance=" << aTolerance << ")"<< endl; aHue = (int)( 360.0 * rand() / RAND_MAX ); - //cout << "Hue = " << aHue << endl; - //cout << "Auto colors : "; bool ok = true; QList::const_iterator it = theReservedColors.constBegin(); QList::const_iterator itEnd = theReservedColors.constEnd(); @@ -3848,21 +5154,17 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList& theReser int h, s, v; aQColor.getHsv( &h, &s, &v ); - //cout << h << " "; if( abs( h - aHue ) < aTolerance ) { - ok = false; - //cout << "break (diff = " << abs( h - aHue ) << ")"; - break; + ok = false; + break; } } - //cout << endl; if( ok ) break; } - //cout << "Hue of the returned color = " << aHue << endl; QColor aColor; aColor.setHsv( aHue, 255, 255 ); @@ -3876,6 +5178,7 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList& theReser const char gSeparator = '_'; // character used to separate parameter names const char gDigitsSep = ':'; // character used to separate numeric parameter values (color = r:g:b) +const char gPathSep = '|'; // character used to separate paths /*! * \brief Store visual parameters @@ -3901,6 +5204,39 @@ void SMESHGUI::storeVisualParameters (int savePoint) savePoint); _PTR(IParameters) ip = ClientFactory::getIParameters(ap); + // store map of custom markers + const VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ]; + if( !aMarkerMap.empty() ) + { + VTK::MarkerMap::const_iterator anIter = aMarkerMap.begin(); + for( ; anIter != aMarkerMap.end(); anIter++ ) + { + int anId = anIter->first; + VTK::MarkerData aMarkerData = anIter->second; + std::string aMarkerFileName = aMarkerData.first; + VTK::MarkerTexture aMarkerTexture = aMarkerData.second; + if( aMarkerTexture.size() < 3 ) + continue; // should contain at least width, height and the first value + + QString aPropertyName( "texture" ); + aPropertyName += gSeparator; + aPropertyName += QString::number( anId ); + + QString aPropertyValue = aMarkerFileName.c_str(); + aPropertyValue += gPathSep; + + VTK::MarkerTexture::const_iterator aTextureIter = aMarkerTexture.begin(); + ushort aWidth = *aTextureIter++; + ushort aHeight = *aTextureIter++; + aPropertyValue += QString::number( aWidth ); aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aHeight ); aPropertyValue += gDigitsSep; + for( ; aTextureIter != aMarkerTexture.end(); aTextureIter++ ) + aPropertyValue += QString::number( *aTextureIter ); + + ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() ); + } + } + // viewers counters are used for storing view_numbers in IParameters int vtkViewers = 0; @@ -3916,21 +5252,53 @@ void SMESHGUI::storeVisualParameters (int savePoint) // saving VTK actors properties if (vType == SVTK_Viewer::Type()) { + // store the clipping planes attached to the view manager + SMESHGUI_ClippingPlaneInfoList aClippingPlaneInfoList; + SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter = myClippingPlaneInfoMap.find( vman ); + if( anIter != myClippingPlaneInfoMap.end() ) + aClippingPlaneInfoList = anIter->second; + + if( !aClippingPlaneInfoList.empty() ) { + SMESHGUI_ClippingPlaneInfoList::const_iterator anIter = aClippingPlaneInfoList.begin(); + for( int anId = 0; anIter != aClippingPlaneInfoList.end(); anIter++, anId++ ) + { + const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter; + SMESH::OrientedPlane* aPlane = aClippingPlaneInfo.Plane; + + QString aPropertyName( "ClippingPlane" ); + aPropertyName += gSeparator; + aPropertyName += QString::number( vtkViewers ); + aPropertyName += gSeparator; + aPropertyName += QString::number( anId ); + + QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData(); + + ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() ); + } + } + QVector views = vman->getViews(); for (int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++) { - if (SVTK_ViewWindow* vtkView = dynamic_cast(views[i])) + if (SVTK_ViewWindow* vtkView = dynamic_cast(views[i])) { - vtkActorCollection* allActors = vtkView->getRenderer()->GetActors(); - allActors->InitTraversal(); - while (vtkActor* actor = allActors->GetNextActor()) + VTK::ActorCollectionCopy aCopy(vtkView->getRenderer()->GetActors()); + vtkActorCollection* allActors = aCopy.GetActors(); + allActors->InitTraversal(); + while (vtkActor* actor = allActors->GetNextActor()) { - if (actor->GetVisibility()) // store only visible actors + if (actor->GetVisibility()) // store only visible actors { SMESH_Actor* aSmeshActor = 0; if (actor->IsA("SMESH_Actor")) aSmeshActor = SMESH_Actor::SafeDownCast(actor); - if (aSmeshActor && aSmeshActor->hasIO()) + if (aSmeshActor && aSmeshActor->hasIO()) { Handle(SALOME_InteractiveObject) io = aSmeshActor->getIO(); if (io->hasEntry()) @@ -3976,18 +5344,17 @@ void SMESHGUI::storeVisualParameters (int savePoint) // Colors (surface:edge:) vtkFloatingPointType r, g, b; + int delta; - aSmeshActor->GetSufaceColor(r, g, b); + aSmeshActor->GetSufaceColor(r, g, b, delta); QString colorStr ("surface"); colorStr += gDigitsSep; colorStr += QString::number(r); colorStr += gDigitsSep; colorStr += QString::number(g); colorStr += gDigitsSep; colorStr += QString::number(b); - aSmeshActor->GetBackSufaceColor(r, g, b); colorStr += gDigitsSep; colorStr += "backsurface"; - colorStr += gDigitsSep; colorStr += QString::number(r); - colorStr += gDigitsSep; colorStr += QString::number(g); - colorStr += gDigitsSep; colorStr += QString::number(b); + colorStr += gDigitsSep; colorStr += QString::number(delta); + aSmeshActor->GetEdgeColor(r, g, b); colorStr += gDigitsSep; colorStr += "edge"; @@ -4001,20 +5368,44 @@ void SMESHGUI::storeVisualParameters (int savePoint) colorStr += gDigitsSep; colorStr += QString::number(g); colorStr += gDigitsSep; colorStr += QString::number(b); + aSmeshActor->GetOutlineColor(r, g, b); + colorStr += gDigitsSep; colorStr += "outline"; + colorStr += gDigitsSep; colorStr += QString::number(r); + colorStr += gDigitsSep; colorStr += QString::number(g); + colorStr += gDigitsSep; colorStr += QString::number(b); + param = vtkParam + "Colors"; ip->setParameter(entry, param, colorStr.toLatin1().data()); // Sizes of lines and points QString sizeStr ("line"); sizeStr += gDigitsSep; sizeStr += QString::number((int)aSmeshActor->GetLineWidth()); - sizeStr += gDigitsSep; sizeStr += "node"; - sizeStr += gDigitsSep; sizeStr += QString::number((int)aSmeshActor->GetNodeSize()); sizeStr += gDigitsSep; sizeStr += "shrink"; sizeStr += gDigitsSep; sizeStr += QString::number(aSmeshActor->GetShrinkFactor()); param = vtkParam + "Sizes"; ip->setParameter(entry, param, sizeStr.toLatin1().data()); + // Point marker + QString markerStr; + + VTK::MarkerType aMarkerType = aSmeshActor->GetMarkerType(); + if( aMarkerType == VTK::MT_USER ) { + markerStr += "custom"; + markerStr += gDigitsSep; + markerStr += QString::number( aSmeshActor->GetMarkerTexture() ); + } + else { + markerStr += "std"; + markerStr += gDigitsSep; + markerStr += QString::number( (int)aMarkerType ); + markerStr += gDigitsSep; + markerStr += QString::number( (int)aSmeshActor->GetMarkerScale() ); + } + + param = vtkParam + "PointMarker"; + ip->setParameter(entry, param, markerStr.toLatin1().data()); + // Opacity param = vtkParam + "Opacity"; ip->setParameter(entry, param, @@ -4022,33 +5413,55 @@ void SMESHGUI::storeVisualParameters (int savePoint) // Clipping param = vtkParam + "ClippingPlane"; - int nPlanes = aSmeshActor->GetNumberOfClippingPlanes(); - if (!nPlanes) - ip->setParameter(entry, param, "Off"); - for (int ipl = 0; ipl < nPlanes; ipl++) { - //vtkPlane* plane = aSmeshActor->GetClippingPlane(ipl); - SMESH::Orientation anOrientation; - double aDistance; - vtkFloatingPointType anAngle[2]; - SMESHGUI_ClippingDlg::GetPlaneParam(aSmeshActor, ipl, anOrientation, aDistance, anAngle); - std::string planeValue = QString::number((int)anOrientation).toLatin1().data(); - planeValue += gDigitsSep; planeValue += QString::number(aDistance).toLatin1().data(); - planeValue += gDigitsSep; planeValue += QString::number(anAngle[0]).toLatin1().data(); - planeValue += gDigitsSep; planeValue += QString::number(anAngle[1]).toLatin1().data(); - - ip->setParameter(entry, param + QString::number(ipl+1).toLatin1().data(), planeValue); + int aPlaneId = 0; + if( !aClippingPlaneInfoList.empty() ) { + SMESHGUI_ClippingPlaneInfoList::const_iterator anIter1 = aClippingPlaneInfoList.begin(); + for( int anId = 0; anIter1 != aClippingPlaneInfoList.end(); anIter1++, anId++ ) + { + const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter1; + std::list anActorList = aClippingPlaneInfo.ActorList; + SMESH::TActorList::iterator anIter2 = anActorList.begin(); + for ( ; anIter2 != anActorList.end(); anIter2++ ) { + if( aSmeshActor == *anIter2 ) { + ip->setParameter( entry, param + QString::number( ++aPlaneId ).toLatin1().constData(), + QString::number( anId ).toLatin1().constData() ); + break; + } + } + } } + if( aPlaneId == 0 ) + ip->setParameter( entry, param, "Off" ); } // if (io->hasEntry()) - } // SMESH_Actor && hasIO - } // isVisible - } // while.. actors traversal - } // if (vtkView) + } // SMESH_Actor && hasIO + } // isVisible + } // while.. actors traversal + } // if (vtkView) } // for (views) vtkViewers++; } // if (SVTK view model) } // for (viewManagers) } +// data structures for clipping planes processing +typedef struct { + int Id; + vtkIdType Orientation; + vtkFloatingPointType Distance; + vtkFloatingPointType Angle[2]; +} TPlaneData; +typedef std::list TPlaneDataList; +typedef std::map TPlaneDataMap; + +typedef std::list TActorList; +typedef struct { + int PlaneId; + TActorList ActorList; + SUIT_ViewManager* ViewManager; +} TPlaneInfo; +typedef std::list TPlaneInfoList; +typedef std::map TPlaneInfoMap; + /*! * \brief Restore visual parameters * @@ -4073,6 +5486,115 @@ void SMESHGUI::restoreVisualParameters (int savePoint) savePoint); _PTR(IParameters) ip = ClientFactory::getIParameters(ap); + // restore map of custom markers and map of clipping planes + VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ]; + TPlaneDataMap aPlaneDataMap; + + std::vector properties = ip->getProperties(); + for (std::vector::iterator propIt = properties.begin(); propIt != properties.end(); ++propIt) + { + std::string property = *propIt; + QString aPropertyName( property.c_str() ); + QString aPropertyValue( ip->getProperty( property ).c_str() ); + + QStringList aPropertyNameList = aPropertyName.split( gSeparator, QString::SkipEmptyParts ); + if( aPropertyNameList.isEmpty() ) + continue; + + QString aPropertyType = aPropertyNameList[0]; + if( aPropertyType == "texture" ) + { + if( aPropertyNameList.size() != 2 ) + continue; + + bool ok = false; + int anId = aPropertyNameList[1].toInt( &ok ); + if( !ok || anId < 1 ) + continue; + + QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts ); + if( aPropertyValueList.size() != 2 ) + continue; + + std::string aMarkerFileName = aPropertyValueList[0].toStdString(); + QString aMarkerTextureString = aPropertyValueList[1]; + QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts ); + if( aMarkerTextureStringList.size() != 3 ) + continue; + + ok = false; + ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok ); + if( !ok ) + continue; + + ok = false; + ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok ); + if( !ok ) + continue; + + VTK::MarkerTexture aMarkerTexture; + aMarkerTexture.push_back( aWidth ); + aMarkerTexture.push_back( aHeight ); + + QString aMarkerTextureData = aMarkerTextureStringList[2]; + for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ ) + { + QChar aChar = aMarkerTextureData.at( i ); + if( aChar.isDigit() ) + aMarkerTexture.push_back( aChar.digitValue() ); + } + + aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture ); + } + else if( aPropertyType == "ClippingPlane" ) + { + if( aPropertyNameList.size() != 3 ) + continue; + + bool ok = false; + int aViewId = aPropertyNameList[1].toInt( &ok ); + if( !ok || aViewId < 0 ) + continue; + + ok = false; + int aClippingPlaneId = aPropertyNameList[2].toInt( &ok ); + if( !ok || aClippingPlaneId < 0 ) + continue; + + QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts ); + if( aPropertyValueList.size() != 4 ) + continue; + + TPlaneData aPlaneData; + aPlaneData.Id = aClippingPlaneId; + + ok = false; + aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok ); + if( !ok ) + continue; + + TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ]; + aPlaneDataList.push_back( aPlaneData ); + } + } + + TPlaneInfoMap aPlaneInfoMap; + std::vector entries = ip->getEntries(); for (std::vector::iterator entIt = entries.begin(); entIt != entries.end(); ++entIt) @@ -4110,7 +5632,7 @@ void SMESHGUI::restoreVisualParameters (int savePoint) bool ok; int viewIndex = viewIndexStr.toUInt(&ok); if (!ok) // bad conversion of view index to integer - continue; + continue; // viewers if (viewerTypStr == SVTK_Viewer::Type()) @@ -4119,48 +5641,50 @@ void SMESHGUI::restoreVisualParameters (int savePoint) if (vtkActors.IsBound(viewIndex)) aSmeshActor = vtkActors.Find(viewIndex); + QList lst; + getApp()->viewManagers(viewerTypStr, lst); + + // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager + SUIT_ViewManager* vman = NULL; + if (viewIndex >= 0 && viewIndex < lst.count()) + vman = lst.at(viewIndex); + if (paramNameStr == "Visibility") { - if (!aSmeshActor && displayer()) + if (!aSmeshActor && displayer() && vman) { - QList lst; - getApp()->viewManagers(viewerTypStr, lst); - - // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager - if (viewIndex >= 0 && viewIndex < lst.count()) { - SUIT_ViewManager* vman = lst.at(viewIndex); - SUIT_ViewModel* vmodel = vman->getViewModel(); - // SVTK view model can be casted to SALOME_View - displayer()->Display(entry, true, dynamic_cast(vmodel)); - - // store displayed actor in a temporary map for quicker - // access later when restoring other parameters - SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView(); - vtkRenderer* Renderer = vtkView->getRenderer(); - vtkActorCollection* theActors = Renderer->GetActors(); - theActors->InitTraversal(); - bool isFound = false; - vtkActor *ac = theActors->GetNextActor(); - for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) { - if (ac->IsA("SMESH_Actor")) { - SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac); - if (aGeomAc->hasIO()) { - Handle(SALOME_InteractiveObject) io = - Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO()); - if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) { - isFound = true; - vtkActors.Bind(viewIndex, aGeomAc); - } + SUIT_ViewModel* vmodel = vman->getViewModel(); + // SVTK view model can be casted to SALOME_View + displayer()->Display(entry, true, dynamic_cast(vmodel)); + + // store displayed actor in a temporary map for quicker + // access later when restoring other parameters + SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView(); + vtkRenderer* Renderer = vtkView->getRenderer(); + VTK::ActorCollectionCopy aCopy(Renderer->GetActors()); + vtkActorCollection* theActors = aCopy.GetActors(); + theActors->InitTraversal(); + bool isFound = false; + vtkActor *ac = theActors->GetNextActor(); + for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) { + if (ac->IsA("SMESH_Actor")) { + SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac); + if (aGeomAc->hasIO()) { + Handle(SALOME_InteractiveObject) io = + Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO()); + if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) { + isFound = true; + vtkActors.Bind(viewIndex, aGeomAc); } } } } } } // if (paramNameStr == "Visibility") - else + else { // the rest properties "work" with SMESH_Actor - if (aSmeshActor) + if (aSmeshActor) { QString val ((*valuesIt).c_str()); @@ -4201,49 +5725,115 @@ void SMESHGUI::restoreVisualParameters (int savePoint) // Colors else if (paramNameStr == "Colors") { QStringList colors = val.split(gDigitsSep, QString::SkipEmptyParts); - if (colors.count() == 16) { + if (colors.count() == 16 || colors.count() == 18 ) { if (colors[0] != "surface" || colors[4] != "backsurface" || - colors[8] != "edge" || colors[12] != "node") { + (colors[8] != "edge" && colors[6] != "edge" ) || (colors[12] != "node" && colors[10] != "node") || + (colors.count() == 18 && colors[14] != "outline")) { MESSAGE("Invalid order of data in Colors, must be: " - "surface:r:g:b:backsurface:r:g:b:edge:r:g:b:node:r:g:b"); + "surface:r:g:b:backsurface:r:g:b:edge:r:g:b:node:r:g:b or surface:r:g:b:backsurface:delta:edge:r:g:b:node:r:g:b:outline:r:g:b"); } else { - aSmeshActor->SetSufaceColor(colors[1].toFloat(), colors[2].toFloat(), colors[3].toFloat()); - aSmeshActor->SetBackSufaceColor(colors[5].toFloat(), colors[6].toFloat(), colors[7].toFloat()); - aSmeshActor->SetEdgeColor(colors[9].toFloat(), colors[10].toFloat(), colors[11].toFloat()); - aSmeshActor->SetNodeColor(colors[13].toFloat(), colors[14].toFloat(), colors[15].toFloat()); + int delta = 0; + float er,eg,eb; + float nr,ng,nb; + vtkFloatingPointType otr,otg,otb; + //Old case backsurface color is independent + if( colors.count() == 16 ) { + QColor ffc; + SMESH::GetColor( "SMESH", "fill_color", ffc, delta, "0,170,255|-100" ) ; + er = colors[9].toFloat(); + eg = colors[10].toFloat(); + eb = colors[11].toFloat(); + + nr = colors[13].toFloat(); + ng = colors[14].toFloat(); + nb = colors[15].toFloat(); + SMESH::GetColor("SMESH", "outline_color", otr, otg, otb, QColor( 0, 70, 0 ) ); + } else { + //New case backsurface color depends on surface color + delta = colors[5].toInt(); + + er = colors[7].toFloat(); + eg = colors[8].toFloat(); + eb = colors[9].toFloat(); + + nr = colors[11].toFloat(); + ng = colors[12].toFloat(); + nb = colors[13].toFloat(); + + otr = colors[15].toFloat(); + otg = colors[16].toFloat(); + otb = colors[17].toFloat(); + } + aSmeshActor->SetSufaceColor(colors[1].toFloat(), colors[2].toFloat(), colors[3].toFloat(), delta); + aSmeshActor->SetEdgeColor(er,eg,eb); + aSmeshActor->SetNodeColor(nr,ng,nb); + aSmeshActor->SetOutlineColor(otr,otg,otb); } } } // Sizes of lines and points else if (paramNameStr == "Sizes") { QStringList sizes = val.split(gDigitsSep, QString::SkipEmptyParts); - if (sizes.count() == 6) { + if (sizes.count() == 4) { + if (sizes[0] != "line" || sizes[2] != "shrink") { + MESSAGE("Invalid order of data in Sizes, must be: " + "line:int:shrink:float"); + } + else { + aSmeshActor->SetLineWidth(sizes[1].toInt()); + aSmeshActor->SetShrinkFactor(sizes[3].toFloat()); + } + } + else if (sizes.count() == 6) { // just to support old format if (sizes[0] != "line" || sizes[2] != "node" || sizes[4] != "shrink") { MESSAGE("Invalid order of data in Sizes, must be: " "line:int:node:int:shrink:float"); } else { aSmeshActor->SetLineWidth(sizes[1].toInt()); - aSmeshActor->SetNodeSize(sizes[3].toInt()); + //aSmeshActor->SetNodeSize(sizes[3].toInt()); // made obsolete aSmeshActor->SetShrinkFactor(sizes[5].toFloat()); } } } + // Point marker + else if (paramNameStr == "PointMarker") { + QStringList data = val.split(gDigitsSep, QString::SkipEmptyParts); + if( data.count() >= 2 ) { + bool ok = false; + int aParam1 = data[1].toInt( &ok ); + if( ok ) { + if( data[0] == "std" && data.count() == 3 ) { + int aParam2 = data[2].toInt( &ok ); + aSmeshActor->SetMarkerStd( (VTK::MarkerType)aParam1, (VTK::MarkerScale)aParam2 ); + } + else if( data[0] == "custom" ) { + VTK::MarkerMap::const_iterator markerIt = aMarkerMap.find( aParam1 ); + if( markerIt != aMarkerMap.end() ) { + VTK::MarkerData aMarkerData = markerIt->second; + aSmeshActor->SetMarkerTexture( aParam1, aMarkerData.second ); + } + } + } + } + } // Opacity else if (paramNameStr == "Opacity") { aSmeshActor->SetOpacity(val.toFloat()); } // Clipping else if (paramNameStr.startsWith("ClippingPlane")) { - cout << "$$$ ClippingPlane 1" << endl; - if (paramNameStr == "ClippingPlane1" || val == "Off") - aSmeshActor->RemoveAllClippingPlanes(); - if (val != "Off") { - cout << "$$$ ClippingPlane 2" << endl; - QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts); - if (vals.count() == 4) { // format check: 4 values - cout << "$$$ ClippingPlane 3" << endl; + QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts); + // old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles) + // new format - val looks like "Off" or "0" (plane id) + // (note: in new format "Off" value is used only for consistency, + // so it is processed together with values in old format) + bool anIsOldFormat = ( vals.count() == 4 || val == "Off" ); + if( anIsOldFormat ) { + if (paramNameStr == "ClippingPlane1" || val == "Off") + aSmeshActor->RemoveAllClippingPlanes(); + if (val != "Off") { SMESH::Orientation anOrientation = (SMESH::Orientation)vals[0].toInt(); double aDistance = vals[1].toFloat(); vtkFloatingPointType anAngle[2]; @@ -4256,18 +5846,156 @@ void SMESHGUI::restoreVisualParameters (int savePoint) if (viewIndex >= 0 && viewIndex < lst.count()) { SUIT_ViewManager* vman = lst.at(viewIndex); SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView(); - SMESHGUI_ClippingDlg::AddPlane(aSmeshActor, vtkView, - anOrientation, aDistance, anAngle); + + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ vman ]; + + SMESH::TActorList anActorList; + anActorList.push_back( aSmeshActor ); + SMESH::OrientedPlane* aPlane = + SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle); + if( aPlane ) { + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = aPlane; + aClippingPlaneInfo.ActorList = anActorList; + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + } + } + } + } + else { + bool ok = false; + int aPlaneId = val.toInt( &ok ); + if( ok && aPlaneId >= 0 ) { + bool anIsDefinedPlane = false; + TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ viewIndex ]; + TPlaneInfoList::iterator anIter = aPlaneInfoList.begin(); + for( ; anIter != aPlaneInfoList.end(); anIter++ ) { + TPlaneInfo& aPlaneInfo = *anIter; + if( aPlaneInfo.PlaneId == aPlaneId ) { + aPlaneInfo.ActorList.push_back( aSmeshActor ); + anIsDefinedPlane = true; + break; + } + } + if( !anIsDefinedPlane ) { + TPlaneInfo aPlaneInfo; + aPlaneInfo.PlaneId = aPlaneId; + aPlaneInfo.ActorList.push_back( aSmeshActor ); + aPlaneInfo.ViewManager = vman; + + // to make the list sorted by plane id + anIter = aPlaneInfoList.begin(); + for( ; anIter != aPlaneInfoList.end(); anIter++ ) { + const TPlaneInfo& aPlaneInfoRef = *anIter; + if( aPlaneInfoRef.PlaneId > aPlaneId ) + break; + } + aPlaneInfoList.insert( anIter, aPlaneInfo ); } } } } } // if (aSmeshActor) - } // other parameters than Visibility + } // other parameters than Visibility } } // for names/parameters iterator } // for entries iterator + // take into account planes with empty list of actors referred to them + QList aVMList; + getApp()->viewManagers(SVTK_Viewer::Type(), aVMList); + + TPlaneDataMap::const_iterator aPlaneDataIter = aPlaneDataMap.begin(); + for( ; aPlaneDataIter != aPlaneDataMap.end(); aPlaneDataIter++ ) { + int aViewId = aPlaneDataIter->first; + if( aViewId >= 0 && aViewId < aVMList.count() ) { + SUIT_ViewManager* aViewManager = aVMList.at( aViewId ); + + const TPlaneDataList& aPlaneDataList = aPlaneDataIter->second; + + TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ aViewId ]; + TPlaneDataList::const_iterator anIter2 = aPlaneDataList.begin(); + for( ; anIter2 != aPlaneDataList.end(); anIter2++ ) { + const TPlaneData& aPlaneData = *anIter2; + int aPlaneId = aPlaneData.Id; + + bool anIsFound = false; + TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin(); + for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) { + const TPlaneInfo& aPlaneInfo = *anIter3; + if( aPlaneInfo.PlaneId == aPlaneId ) { + anIsFound = true; + break; + } + } + + if( !anIsFound ) { + TPlaneInfo aPlaneInfo; // ActorList field is empty + aPlaneInfo.PlaneId = aPlaneId; + aPlaneInfo.ViewManager = aViewManager; + + // to make the list sorted by plane id + TPlaneInfoList::iterator anIter4 = aPlaneInfoList.begin(); + for( ; anIter4 != aPlaneInfoList.end(); anIter4++ ) { + const TPlaneInfo& aPlaneInfoRef = *anIter4; + if( aPlaneInfoRef.PlaneId > aPlaneId ) + break; + } + aPlaneInfoList.insert( anIter4, aPlaneInfo ); + } + } + } + } + + // add clipping planes to actors according to the restored parameters + // and update the clipping plane map + TPlaneInfoMap::const_iterator anIter1 = aPlaneInfoMap.begin(); + for( ; anIter1 != aPlaneInfoMap.end(); anIter1++ ) { + int aViewId = anIter1->first; + const TPlaneInfoList& aPlaneInfoList = anIter1->second; + + TPlaneDataMap::const_iterator anIter2 = aPlaneDataMap.find( aViewId ); + if( anIter2 == aPlaneDataMap.end() ) + continue; + const TPlaneDataList& aPlaneDataList = anIter2->second; + + TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin(); + for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) { + const TPlaneInfo& aPlaneInfo = *anIter3; + int aPlaneId = aPlaneInfo.PlaneId; + const TActorList& anActorList = aPlaneInfo.ActorList; + SUIT_ViewManager* aViewManager = aPlaneInfo.ViewManager; + if( !aViewManager ) + continue; + + SVTK_ViewWindow* aViewWindow = dynamic_cast( aViewManager->getActiveView() ); + if( !aViewWindow ) + continue; + + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ aViewManager ]; + + TPlaneDataList::const_iterator anIter4 = aPlaneDataList.begin(); + for( ; anIter4 != aPlaneDataList.end(); anIter4++ ) { + const TPlaneData& aPlaneData = *anIter4; + if( aPlaneData.Id == aPlaneId ) { + SMESH::OrientedPlane* aPlane = + SMESHGUI_ClippingDlg::AddPlane( anActorList, + aViewWindow, + (SMESH::Orientation)aPlaneData.Orientation, + aPlaneData.Distance, + aPlaneData.Angle ); + if( aPlane ) { + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = aPlane; + aClippingPlaneInfo.ActorList = anActorList; + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + } + break; + } + } + } + } + // update all VTK views QList lst; getApp()->viewManagers(lst); @@ -4290,8 +6018,8 @@ void SMESHGUI::restoreVisualParameters (int savePoint) */ int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString& param ) { - int tfont = addPreference( label, pId, LightApp_Preferences::Font, "VISU", param ); - + int tfont = addPreference( label, pId, LightApp_Preferences::Font, "SMESH", param ); + setPreferenceProperty( tfont, "mode", QtxFontEdit::Custom ); QStringList fam; @@ -4307,8 +6035,167 @@ int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString return tfont; } +/*! + \brief Actions after hypothesis edition + Updates object browser after hypothesis edition +*/ +void SMESHGUI::onHypothesisEdit( int result ) +{ + if( result == 1 ) + SMESHGUI::Modified(); + updateObjBrowser( true ); +} + + +/*! + \brief Signal handler closing(SUIT_ViewWindow*) of a view + \param pview view being closed +*/ +void SMESHGUI::onViewClosed( SUIT_ViewWindow* pview ) { +#ifndef DISABLE_PLOT2DVIEWER + //Crear all Plot2d Viewers if need. + SMESH::ClearPlot2Viewers(pview); +#endif +} + +void SMESHGUI::message( const QString& msg ) +{ + // dispatch message + QStringList data = msg.split("/"); + if ( data.count() > 0 ) { + if ( data.first() == "mesh_loading" ) { + // get mesh entry + QString entry = data.count() > 1 ? data[1] : QString(); + if ( entry.isEmpty() ) + return; + // get study + _PTR(Study) study = dynamic_cast( application()->activeStudy() )->studyDS(); + // get mesh name + _PTR(SObject) obj = study->FindObjectID( entry.toLatin1().constData() ); + QString name; + if ( obj ) + name = obj->GetName().c_str(); + if ( name.isEmpty() ) + return; + + if ( data.last() == "stop" ) + application()->putInfo( tr( "MESH_LOADING_MSG_FINISHED" ).arg( name ) ); + else + application()->putInfo( tr( "MESH_LOADING_MSG" ).arg( name ) ); + QApplication::processEvents(); + } + } +} + +/*! + \brief Connects or disconnects signals about activating and cloning view on the module slots + \param pview view which is connected/disconnected +*/ +void SMESHGUI::connectView( const SUIT_ViewWindow* pview ) { + if(!pview) + return; + + SUIT_ViewManager* viewMgr = pview->getViewManager(); + if ( viewMgr ) { + disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ), + this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) ); + + connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ), + this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) ); + } +} + +/*! + \brief Return \c true if object can be renamed +*/ +bool SMESHGUI::renameAllowed( const QString& entry) const { + SalomeApp_Application* anApp = dynamic_cast( application() ); + if( !anApp ) + return false; + + SalomeApp_Study* appStudy = dynamic_cast( anApp->activeStudy() ); + if( !appStudy ) + return false; + + SalomeApp_DataObject* obj = dynamic_cast(appStudy->findObjectByEntry(entry)); + + if(!obj) + return false; + + if(appStudy->isComponent(entry) || obj->isReference()) + return false; + + // check type to prevent renaming of inappropriate objects + int aType = SMESHGUI_Selection::type(qPrintable(entry), SMESH::GetActiveStudyDocument()); + if (aType == MESH || aType == GROUP || + aType == SUBMESH || aType == SUBMESH_COMPOUND || + aType == SUBMESH_SOLID || aType == SUBMESH_FACE || + aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX || + aType == HYPOTHESIS || aType == ALGORITHM) + return true; + + return false; +} +/*! + Rename object by entry. + \param entry entry of the object + \param name new name of the object + \brief Return \c true if rename operation finished successfully, \c false otherwise. +*/ +bool SMESHGUI::renameObject( const QString& entry, const QString& name) { + SalomeApp_Application* anApp = dynamic_cast( application() ); + if( !anApp ) + return false; + + SalomeApp_Study* appStudy = dynamic_cast( anApp->activeStudy() ); + if(!appStudy) + return false; + + _PTR(Study) aStudy = appStudy->studyDS(); + + if(!aStudy) + return false; + + bool aLocked = (_PTR(AttributeStudyProperties)(appStudy->studyDS()->GetProperties()))->IsLocked(); + if ( aLocked ) { + SUIT_MessageBox::warning ( anApp->desktop(), QObject::tr("WRN_WARNING"), QObject::tr("WRN_STUDY_LOCKED") ); + return false; + } + _PTR(SObject) obj = aStudy->FindObjectID( qPrintable(entry) ); + _PTR(GenericAttribute) anAttr; + _PTR(AttributeName) aName; + if ( obj ) { + if ( obj->FindAttribute(anAttr, "AttributeName") ) { + aName = anAttr; + // check type to prevent renaming of inappropriate objects + int aType = SMESHGUI_Selection::type( qPrintable(entry), SMESH::GetActiveStudyDocument() ); + if (aType == MESH || aType == GROUP || + aType == SUBMESH || aType == SUBMESH_COMPOUND || + aType == SUBMESH_SOLID || aType == SUBMESH_FACE || + aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX || + aType == HYPOTHESIS || aType == ALGORITHM) { + if ( !name.isEmpty() ) { + SMESHGUI::GetSMESHGen()->SetName(obj->GetIOR().c_str(), qPrintable(name) ); + + // update name of group object and its actor + Handle(SALOME_InteractiveObject) IObject = + new SALOME_InteractiveObject ( qPrintable(entry), "SMESH", qPrintable(name) ); + + SMESH::SMESH_GroupBase_var aGroupObject = SMESH::IObjectToInterface(IObject); + if( !aGroupObject->_is_nil() ) { + aGroupObject->SetName( qPrintable(name) ); + if ( SMESH_Actor *anActor = SMESH::FindActorByEntry( qPrintable(entry) ) ) + anActor->setName( qPrintable(name) ); + } + return true; + } + } + } + } + return false; +} diff --git a/src/SMESHGUI/SMESHGUI.h b/src/SMESHGUI/SMESHGUI.h index 230bc3162..6f5237ce3 100644 --- a/src/SMESHGUI/SMESHGUI.h +++ b/src/SMESHGUI/SMESHGUI.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -31,12 +32,21 @@ // SALOME GUI includes #include +#include #include // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Gen) +// VTK includes +#include +#include + +class vtkActor; +class vtkCallbackCommand; +class vtkObject; + class QDialog; class SUIT_Desktop; @@ -50,8 +60,24 @@ class SalomeApp_Study; class LightApp_Selection; class LightApp_SelectionMgr; +class SMESH_Actor; class SMESHGUI_FilterLibraryDlg; +typedef std::map SMESHGUI_StudyId2MarkerMap; + +namespace SMESH +{ + class OrientedPlane; + struct ClippingPlaneInfo + { + OrientedPlane* Plane; + std::list ActorList; + }; +} + +typedef std::list SMESHGUI_ClippingPlaneInfoList; +typedef std::map SMESHGUI_ClippingPlaneInfoMap; + //================================================================================= // class : SMESHGUI // purpose : @@ -70,11 +96,12 @@ public : static SUIT_ResourceMgr* resourceMgr(); static SUIT_Desktop* desktop(); static SalomeApp_Study* activeStudy(); - static char* JoinObjectParameters(const QStringList& theParametersList); bool isActiveStudyLocked(); - static bool automaticUpdate(); + static bool automaticUpdate(unsigned int requestedSize = 0, bool* limitExceeded = 0); + + static void Modified( bool = true ); virtual LightApp_Displayer* displayer(); virtual QString engineIOR() const; @@ -104,11 +131,14 @@ public : void EmitSignalDeactivateDialog(); void EmitSignalStudyFrameChanged(); void EmitSignalCloseAllDialogs(); + void EmitSignalVisibilityChanged(); virtual void contextMenuPopup( const QString&, QMenu*, QString& ); virtual void createPreferences(); virtual void preferencesChanged( const QString&, const QString& ); + virtual void message( const QString& ); + virtual void update( const int ); static SALOMEDS::Color getUniqueColor( const QList& ); @@ -116,29 +146,41 @@ public : virtual void storeVisualParameters (int savePoint); virtual void restoreVisualParameters(int savePoint); + virtual void addActorAsObserver( SMESH_Actor* theActor ); + + virtual bool renameAllowed( const QString& ) const; + virtual bool renameObject( const QString&, const QString& ); + + + SMESHGUI_ClippingPlaneInfoMap& getClippingPlaneInfoMap() { return myClippingPlaneInfoMap; } + public slots: virtual bool deactivateModule( SUIT_Study* ); virtual bool activateModule( SUIT_Study* ); virtual void studyClosed( SUIT_Study* ); + void onViewClosed( SUIT_ViewWindow* ); private slots: void OnGUIEvent(); void onViewManagerActivated( SUIT_ViewManager* ); + void onViewManagerRemoved( SUIT_ViewManager* ); void onOperationCommited( SUIT_Operation* ); void onOperationAborted( SUIT_Operation* ); - + void onHypothesisEdit( int result ); signals: void SignalDeactivateActiveDialog(); void SignalStudyFrameChanged(); void SignalCloseAllDialogs(); + void SignalVisibilityChanged(); protected: void createSMESHAction( const int, const QString&, const QString& = QString(), const int = 0, - const bool = false ); + const bool = false, + const QString& = QString() ); void createPopupItem( const int, const QString&, const QString&, @@ -149,12 +191,22 @@ protected: virtual bool isSelectionCompatible(); + virtual bool reusableOperation( const int id ); + + static void ProcessEvents( vtkObject* theObject, + unsigned long theEvent, + void* theClientData, + void* theCallData ); + private: void OnEditDelete(); int addVtkFontPref( const QString& label, const int pId, const QString& param ); + void connectView( const SUIT_ViewWindow* ); + + private : static SMESH::SMESH_Gen_var myComponentSMESH; QDialog* myActiveDialogBox; @@ -163,6 +215,12 @@ private : LightApp_Displayer* myDisplayer; SMESHGUI_FilterLibraryDlg* myFilterLibraryDlg; + + SMESHGUI_StudyId2MarkerMap myMarkerMap; + SMESHGUI_ClippingPlaneInfoMap myClippingPlaneInfoMap; + + vtkSmartPointer myEventCallbackCommand; + vtkFloatingPointType myPriority; }; #endif // SMESHGUI_H diff --git a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx index 97e393a24..2febf76f8 100644 --- a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_AddMeshElementDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -27,10 +28,12 @@ #include "SMESHGUI_AddMeshElementDlg.h" #include "SMESHGUI.h" +#include "SMESHGUI_GroupUtils.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_SpinBox.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" -#include "SMESHGUI_MeshUtils.h" -#include "SMESHGUI_IdValidator.h" #include #include @@ -64,6 +67,7 @@ #include // Qt includes +#include #include #include #include @@ -154,43 +158,19 @@ namespace SMESH typedef std::vector TVTKIds; void SetPosition (SMESH_Actor* theActor, - vtkIdType theType, - const TVTKIds& theIds) + vtkIdType theType, + TVTKIds& theIds) { vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid(); myGrid->SetPoints(aGrid->GetPoints()); + myGrid->Reset(); - const int* aConn = NULL; - switch (theType) { - case VTK_TETRA: - { - static int anIds[] = {0,2,1,3}; - aConn = anIds; - break; - } - case VTK_PYRAMID: - { - static int anIds[] = {0,3,2,1,4}; - aConn = anIds; - break; - } - case VTK_HEXAHEDRON: - { - static int anIds[] = {0,3,2,1,4,7,6,5}; - aConn = anIds; - break; - } - } + const std::vector& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( theType )); + SMDS_MeshCell::applyInterlace( interlace, theIds ); - myGrid->Reset(); vtkIdList *anIds = vtkIdList::New(); - - if(aConn) - for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) - anIds->InsertId(i,theIds[aConn[i]]); - else - for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) - anIds->InsertId(i,theIds[i]); + for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) + anIds->InsertId(i,theIds[i]); myGrid->InsertNextCell(theType,anIds); anIds->Delete(); @@ -212,8 +192,8 @@ namespace SMESH ~TElementSimulation() { if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) { - myVTKViewWindow->RemoveActor(myPreviewActor); - myVTKViewWindow->RemoveActor(myFaceOrientation); + myVTKViewWindow->RemoveActor(myPreviewActor); + myVTKViewWindow->RemoveActor(myFaceOrientation); } myPreviewActor->Delete(); myFaceOrientation->Delete(); @@ -235,12 +215,12 @@ namespace SMESH // function : SMESHGUI_AddMeshElementDlg() // purpose : constructor //================================================================================= -SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule, - SMDSAbs_ElementType ElementType, - int nbNodes ) +SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule, + SMDSAbs_EntityType ElementType) : QDialog( SMESH::GetDesktop( theModule ) ), mySMESHGUI( theModule ), - mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myBusy ( false ) { setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); @@ -250,55 +230,80 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule, myIsPoly = false; mySimulation = new SMESH::TElementSimulation (anApp); mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + myGeomType = ElementType; + myElementType = SMDSAbs_Volume; // verify nb nodes and type - myNbNodes = nbNodes; - myElementType = ElementType; - switch (ElementType) { - case SMDSAbs_Face: - // if (myNbNodes != 3 && myNbNodes != 4) - // myNbNodes = 3; - // break; - case SMDSAbs_Volume: - // if (myNbNodes != 4 && myNbNodes != 8) //(nbNodes < 4 || nbNodes > 8 || nbNodes == 7) - // myNbNodes = 4; + QString elemName; + switch ( myGeomType ) { + case SMDSEntity_0D: + myNbNodes = 1; + myElementType = SMDSAbs_0DElement; + elemName = "ELEM0D"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_0delems_anchor"; break; - default: - myElementType = SMDSAbs_Edge; + case SMDSEntity_Ball: + myNbNodes = 1; + myElementType = SMDSAbs_Ball; + elemName = "BALL"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_ball_anchor"; + break; + case SMDSEntity_Edge: myNbNodes = 2; - } - - QString elemName; - if (myNbNodes == 2) { + myElementType = SMDSAbs_Edge; elemName = "EDGE"; myHelpFileName = "adding_nodes_and_elements_page.html#adding_edges_anchor"; - } - else if (myNbNodes == 3) { + break; + case SMDSEntity_Triangle: + myNbNodes = 3; elemName = "TRIANGLE"; + myElementType = SMDSAbs_Face; myHelpFileName = "adding_nodes_and_elements_page.html#adding_triangles_anchor"; - } - else if (myNbNodes == 4) - if (myElementType == SMDSAbs_Face) { - elemName = "QUADRANGLE"; - myHelpFileName = "adding_nodes_and_elements_page.html#adding_quadrangles_anchor"; - } - else { - elemName = "TETRAS"; - myHelpFileName = "adding_nodes_and_elements_page.html#adding_tetrahedrons_anchor"; - } - else if (myNbNodes == 8) { - elemName = "HEXAS"; - myHelpFileName = "adding_nodes_and_elements_page.html#adding_hexahedrons_anchor"; - } - else if (myElementType == SMDSAbs_Face) { + break; + case SMDSEntity_Quadrangle: + myNbNodes = 4; + myElementType = SMDSAbs_Face; + elemName = "QUADRANGLE"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_quadrangles_anchor"; + break; + case SMDSEntity_Polygon: + myNbNodes = 0; + myElementType = SMDSAbs_Face; elemName = "POLYGON"; myIsPoly = true; myHelpFileName = "adding_nodes_and_elements_page.html#adding_polygons_anchor"; + break; + case SMDSEntity_Tetra: + myNbNodes = 4; + elemName = "TETRAS"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_tetrahedrons_anchor"; + break; + case SMDSEntity_Pyramid: + myNbNodes = 5; + elemName = "PYRAMID"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_pyramids_anchor"; + break; + case SMDSEntity_Hexa: + myNbNodes = 8; + elemName = "HEXAS"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_hexahedrons_anchor"; + break; + case SMDSEntity_Penta: + myNbNodes = 6; + elemName = "PENTA"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_pentahedrons_anchor"; + break; + case SMDSEntity_Hexagonal_Prism: + myNbNodes = 12; + elemName = "OCTA"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_octahedrons_anchor"; + break; + default: + myNbNodes = 2; + elemName = "EDGE"; + myHelpFileName = "adding_nodes_and_elements_page.html#adding_edges_anchor"; } - else if (myElementType == SMDSAbs_Volume) { - myHelpFileName = "adding_nodes_and_elements_page.html#adding_polyhedrons_anchor"; - } - + QString iconName = tr(QString("ICON_DLG_%1").arg(elemName).toLatin1().data()); QString buttonGrTitle = tr(QString("SMESH_%1").arg(elemName).toLatin1().data()); QString caption = tr(QString("SMESH_ADD_%1_TITLE").arg(elemName).toLatin1().data()); @@ -314,7 +319,7 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule, aTopLayout->setSpacing(SPACING); aTopLayout->setMargin(MARGIN); - /***************************************************************/ + /* Constructor *************************************************/ GroupConstructors = new QGroupBox(buttonGrTitle, this); QButtonGroup* ButtonGroup = new QButtonGroup(this); QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors); @@ -328,7 +333,7 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule, GroupConstructorsLayout->addWidget(Constructor1); ButtonGroup->addButton( Constructor1, 0 ); - /***************************************************************/ + /* Nodes & Reverse *********************************************/ GroupC1 = new QGroupBox(grBoxTitle, this); QGridLayout* GroupC1Layout = new QGridLayout(GroupC1); GroupC1Layout->setSpacing(SPACING); @@ -338,18 +343,42 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule, SelectButtonC1A1 = new QPushButton(GroupC1); SelectButtonC1A1->setIcon(image1); LineEditC1A1 = new QLineEdit(GroupC1); - // LineEditC1A1->setReadOnly(true); - if (!myIsPoly) - LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this, myNbNodes)); + LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this, myIsPoly ? 1000 : myNbNodes)); - Reverse = myElementType == SMDSAbs_Face ? new QCheckBox(tr("SMESH_REVERSE"), GroupC1) : 0; + Reverse = (myElementType == SMDSAbs_Face || myElementType == SMDSAbs_Volume ) ? new QCheckBox(tr("SMESH_REVERSE"), GroupC1) : 0; + + DiameterSpinBox = ( myGeomType == SMDSEntity_Ball ) ? new SMESHGUI_SpinBox(GroupC1) : 0; + QLabel* diameterLabel = DiameterSpinBox ? new QLabel( tr("BALL_DIAMETER"),GroupC1) : 0; GroupC1Layout->addWidget(TextLabelC1A1, 0, 0); GroupC1Layout->addWidget(SelectButtonC1A1, 0, 1); GroupC1Layout->addWidget(LineEditC1A1, 0, 2); - if ( Reverse ) GroupC1Layout->addWidget(Reverse, 1, 0, 1, 3); + if ( Reverse ) { + GroupC1Layout->addWidget(Reverse, 1, 0, 1, 3); + } + if ( DiameterSpinBox ) { + GroupC1Layout->addWidget(diameterLabel, 1, 0); + GroupC1Layout->addWidget(DiameterSpinBox, 1, 1, 1, 2); - /***************************************************************/ + DiameterSpinBox->RangeStepAndValidator( 1e-7, 1e+9, 0.1 ); + DiameterSpinBox->SetValue( 1. ); + } + /* Add to group ************************************************/ + GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this ); + GroupGroups->setCheckable( true ); + QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups); + GroupGroupsLayout->setSpacing(SPACING); + GroupGroupsLayout->setMargin(MARGIN); + + TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups ); + ComboBox_GroupName = new QComboBox( GroupGroups ); + ComboBox_GroupName->setEditable( true ); + ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert ); + + GroupGroupsLayout->addWidget( TextLabel_GroupName ); + GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 ); + + /* Apply etc ***************************************************/ GroupButtons = new QGroupBox(this); QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons); GroupButtonsLayout->setSpacing(SPACING); @@ -376,6 +405,7 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule, /***************************************************************/ aTopLayout->addWidget(GroupConstructors); aTopLayout->addWidget(GroupC1); + aTopLayout->addWidget(GroupGroups); aTopLayout->addWidget(GroupButtons); Init(); /* Initialisations */ @@ -401,6 +431,10 @@ void SMESHGUI_AddMeshElementDlg::Init() myEditCurrentArgument = LineEditC1A1; mySMESHGUI->SetActiveDialogBox((QDialog*)this); + /* reset "Add to group" control */ + GroupGroups->setChecked( false ); + //GroupGroups->setVisible( myElementType != SMDSAbs_0DElement ); + myNbOkNodes = 0; myActor = 0; @@ -416,6 +450,7 @@ void SMESHGUI_AddMeshElementDlg::Init() connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument())); /* to close dialog if study frame change */ connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel())); if (Reverse) connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int))); @@ -437,33 +472,99 @@ void SMESHGUI_AddMeshElementDlg::Init() //================================================================================= void SMESHGUI_AddMeshElementDlg::ClickOnApply() { + if( !isValid() ) + return; + if (myNbOkNodes && !mySMESHGUI->isActiveStudyLocked()) { myBusy = true; - SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; - anArrayOfIdeces->length(myNbNodes); - bool reverse = (Reverse && Reverse->isChecked()); + SMESH::long_array_var anArrayOfIndices = new SMESH::long_array; + anArrayOfIndices->length(myNbNodes); QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts); - for (int i = 0; i < aListId.count(); i++) - if (reverse) - anArrayOfIdeces[i] = aListId[ myNbNodes - i - 1 ].toInt(); - else - anArrayOfIdeces[i] = aListId[ i ].toInt(); + const std::vector& revIndex = SMDS_MeshCell::reverseSmdsOrder( myGeomType ); + if ( Reverse && Reverse->isChecked() && !revIndex.empty() ) + for (int i = 0; i < aListId.count(); i++) + anArrayOfIndices[i] = aListId[ revIndex[i] ].toInt(); + else if ( Reverse && Reverse->isChecked() && revIndex.empty() ) // polygon + for (int i = 0; i < aListId.count(); i++) + anArrayOfIndices[i] = aListId[ aListId.count()-1 - i ].toInt(); + else + for (int i = 0; i < aListId.count(); i++) + anArrayOfIndices[i] = aListId[ i ].toInt(); + + bool addToGroup = GroupGroups->isChecked(); + QString aGroupName; + + SMESH::SMESH_GroupBase_var aGroup; + int idx = 0; + if( addToGroup ) { + aGroupName = ComboBox_GroupName->currentText(); + for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { + QString aName = ComboBox_GroupName->itemText( i ); + if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) + idx = i; + } + if ( idx > 0 && idx < myGroups.count() ) { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); + if ( !aGeomGroup->_is_nil() ) { + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return; + } + aGroup = myGroups[idx-1]; + } + } + long anElemId = -1; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); switch (myElementType) { + case SMDSAbs_0DElement: + anElemId = aMeshEditor->Add0DElement(anArrayOfIndices[0]); break; + case SMDSAbs_Ball: + if ( myGeomType == SMDSEntity_Ball ) + anElemId = aMeshEditor->AddBall(anArrayOfIndices[0], + DiameterSpinBox->GetValue()); break; case SMDSAbs_Edge: - aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break; - case SMDSAbs_Face:{ - if(myIsPoly) - aMeshEditor->AddPolygonalFace(anArrayOfIdeces.inout()); + anElemId = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break; + case SMDSAbs_Face: + if ( myIsPoly ) + anElemId = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout()); else - aMeshEditor->AddFace(anArrayOfIdeces.inout()); + anElemId = aMeshEditor->AddFace(anArrayOfIndices.inout()); break; - + default: + anElemId = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break; } - case SMDSAbs_Volume: - aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break; - default:; + + if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) { + SMESH::SMESH_Group_var aGroupUsed; + if ( aGroup->_is_nil() ) { + // create new group + aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName ); + if ( !aGroupUsed->_is_nil() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + else { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); + if ( !aGeomGroup->_is_nil() ) { + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } + } + else + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + } + + if ( !aGroupUsed->_is_nil() ) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length( 1 ); + anIdList[0] = anElemId; + aGroupUsed->Add( anIdList.inout() ); + } } SALOME_ListIO aList; aList.Append( myActor->getIO() ); @@ -479,6 +580,8 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply() myEditCurrentArgument->setText(""); myBusy = false; + + SMESHGUI::Modified(); } } @@ -515,8 +618,9 @@ void SMESHGUI_AddMeshElementDlg::ClickOnCancel() void SMESHGUI_AddMeshElementDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) - app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), + myHelpFileName); else { QString platform; #ifdef WIN32 @@ -525,10 +629,10 @@ void SMESHGUI_AddMeshElementDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -555,40 +659,40 @@ void SMESHGUI_AddMeshElementDlg::onTextChange (const QString& theNewText) if (aMesh) { TColStd_MapOfInteger newIndices; - + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); bool allOk = true; for (int i = 0; i < aListId.count(); i++) { if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) ) - { - newIndices.Add( n->GetID() ); - myNbOkNodes++; - } + { + newIndices.Add( n->GetID() ); + myNbOkNodes++; + } else - allOk = false; + allOk = false; } - + mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->highlight( myActor->getIO(), true, true ); - + myNbOkNodes = ( allOk && myNbNodes == aListId.count() ); - + if (myIsPoly) { - if ( !allOk || myElementType != SMDSAbs_Face || aListId.count() < 3 ) - myNbOkNodes = 0; - else - myNbOkNodes = aListId.count(); + if ( !allOk || myElementType != SMDSAbs_Face || aListId.count() < 3 ) + myNbOkNodes = 0; + else + myNbOkNodes = aListId.count(); } } - + if(myNbOkNodes) { buttonOk->setEnabled(true); buttonApply->setEnabled(true); displaySimulation(); } - + myBusy = false; } @@ -617,6 +721,8 @@ void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument() mySimulation->SetVisibility(false); // SMESH::SetPointRepresentation(true); + QString aCurrentEntry = myEntry; + // get selected mesh SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); @@ -625,10 +731,29 @@ void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument() return; Handle(SALOME_InteractiveObject) anIO = aList.First(); + myEntry = anIO->getEntry(); myMesh = SMESH::GetMeshByIO(anIO); if (myMesh->_is_nil()) return; + // process groups + if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) { + myGroups.clear(); + ComboBox_GroupName->clear(); + ComboBox_GroupName->addItem( QString() ); + SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups(); + for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; + if ( !aGroup->_is_nil() && aGroup->GetType() == (SMESH::ElementType)myElementType ) { + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + } + } + myActor = SMESH::FindActorByEntry(anIO->getEntry()); if (!myActor) return; @@ -667,24 +792,15 @@ void SMESHGUI_AddMeshElementDlg::displaySimulation() anIds.push_back(myActor->GetObject()->GetNodeVTKId(aListId[ i ].toInt())); if (Reverse && Reverse->isChecked()) - reverse(anIds.begin(),anIds.end()); - - vtkIdType aType = 0; - if (myIsPoly) - switch ( myElementType ) { - case SMDSAbs_Face : aType = VTK_POLYGON; break; - default: return; - } - else { - switch (myNbNodes) { - case 2: aType = VTK_LINE; break; - case 3: aType = VTK_TRIANGLE; break; - case 4: aType = myElementType == SMDSAbs_Face ? VTK_QUAD : VTK_TETRA; break; - case 8: aType = VTK_HEXAHEDRON; break; - default: return; - } + { + const std::vector& i = SMDS_MeshCell::reverseSmdsOrder( myGeomType ); + if ( i.empty() ) // polygon + std::reverse( anIds.begin(), anIds.end() ); + else + SMDS_MeshCell::applyInterlace( i, anIds ); } + vtkIdType aType = SMDS_MeshCell::toVtkType( myGeomType ); mySimulation->SetPosition(myActor,aType,anIds); SMESH::UpdateView(); } @@ -795,9 +911,22 @@ void SMESHGUI_AddMeshElementDlg::keyPressEvent( QKeyEvent* e ) QDialog::keyPressEvent( e ); if ( e->isAccepted() ) return; - + if ( e->key() == Qt::Key_F1 ) { e->accept(); ClickOnHelp(); } } + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool SMESHGUI_AddMeshElementDlg::isValid() +{ + if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) { + SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) ); + return false; + } + return true; +} diff --git a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.h b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.h index ee10b312f..72ad06d93 100644 --- a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.h +++ b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_AddMeshElementDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -38,6 +39,7 @@ #include #include CORBA_SERVER_HEADER(SMESH_Mesh) +class QComboBox; class QGroupBox; class QLabel; class QLineEdit; @@ -48,6 +50,7 @@ class SMESHGUI; class SMESH_Actor; class SVTK_Selector; class LightApp_SelectionMgr; +class SMESHGUI_SpinBox; namespace SMESH { @@ -63,7 +66,7 @@ class SMESHGUI_EXPORT SMESHGUI_AddMeshElementDlg : public QDialog Q_OBJECT public: - SMESHGUI_AddMeshElementDlg( SMESHGUI*, SMDSAbs_ElementType = SMDSAbs_Edge, int = 2 ); + SMESHGUI_AddMeshElementDlg( SMESHGUI*, SMDSAbs_EntityType = SMDSEntity_Edge ); ~SMESHGUI_AddMeshElementDlg(); private: @@ -74,6 +77,10 @@ private: void keyPressEvent( QKeyEvent* ); void displaySimulation(); + bool isValid(); + + typedef QList GrpList; + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ int myNbOkNodes; /* to check when arguments is defined */ @@ -82,6 +89,7 @@ private: QLineEdit* myEditCurrentArgument; /* Current LineEdit */ + SMDSAbs_EntityType myGeomType; int myElementType; int myNbNodes; bool myIsPoly; @@ -89,9 +97,14 @@ private: SMESH::SMESH_Mesh_var myMesh; SMESH_Actor* myActor; SMESH::TElementSimulation* mySimulation; + QString myEntry; + GrpList myGroups; QGroupBox* GroupConstructors; QRadioButton* Constructor1; + QGroupBox* GroupGroups; + QLabel* TextLabel_GroupName; + QComboBox* ComboBox_GroupName; QGroupBox* GroupButtons; QPushButton* buttonOk; QPushButton* buttonCancel; @@ -102,6 +115,7 @@ private: QPushButton* SelectButtonC1A1; QLineEdit* LineEditC1A1; QCheckBox* Reverse; + SMESHGUI_SpinBox* DiameterSpinBox; QString myHelpFileName; diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx index 1c3106e73..0472de715 100644 --- a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_AddMeshElementDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -30,6 +31,7 @@ #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_GroupUtils.h" #include "SMESHGUI_IdValidator.h" #include @@ -69,6 +71,7 @@ #include // Qt includes +#include #include #include #include @@ -88,63 +91,26 @@ #define SPACING 6 #define MARGIN 11 -namespace SMESH +namespace { - void ReverseConnectivity( std::vector & ids, int type ) + void ReverseConnectivity( std::vector & ids, SMDSAbs_EntityType type, + bool toReverse, // inverse element + bool toVtkOrder ) // smds connectivity to vtk one { - // for reverse connectivity of other types keeping the first id, see - // void SMESH_VisualObjDef::buildElemPrs() in SMESH_Object.cxx:900 - const int* conn = 0; - - switch ( type ) { - case QUAD_TETRAHEDRON: { - static int aConn[] = {0,2,1,3,6,5,4,7,9,8}; - conn = aConn; - break; - } - case QUAD_PYRAMID: { - static int aConn[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; - conn = aConn; - break; - } - case QUAD_PENTAHEDRON: { - static int aConn[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; - conn = aConn; - break; - } - case QUAD_HEXAHEDRON: { - static int aConn[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; - conn = aConn; - break; - } - case QUAD_EDGE: { - static int aConn[] = {1,0,2}; - conn = aConn; - break; - } - case QUAD_TRIANGLE: { - static int aConn[] = {0,2,1,5,4,3}; - conn = aConn; - break; - } - case QUAD_QUADRANGLE: { - static int aConn[] = {0,3,2,1,7,6,5,4}; - conn = aConn; - break; - } - default:; - } - if ( !conn ) { - reverse( ids.begin(), ids.end() ); + if ( toReverse ) // first reverse smds order + { + const std::vector& index = SMDS_MeshCell::reverseSmdsOrder(type); + SMDS_MeshCell::applyInterlace( index, ids ); } - else { - std::vector aRevIds( ids.size() ); - for ( int i = 0; i < ids.size(); i++) - aRevIds[ i ] = ids[ conn[ i ]]; - ids = aRevIds; + if ( toVtkOrder ) // from smds to vtk connectivity + { + const std::vector& index = SMDS_MeshCell::toVtkOrder(type); + SMDS_MeshCell::applyInterlace( index, ids ); } } - +} +namespace SMESH +{ class TElementSimulation { SalomeApp_Application* myApplication; SUIT_ViewWindow* myViewWindow; @@ -218,85 +184,36 @@ namespace SMESH } typedef std::vector TVTKIds; - void SetPosition (SMESH_Actor* theActor, - const int theType, - TVTKIds& theIds, - const int theMode, - const bool theReverse) + void SetPosition (SMESH_Actor* theActor, + SMDSAbs_EntityType theType, + TVTKIds& theIds, + const int theMode, + const bool theReverse) { vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid(); myGrid->SetPoints(aGrid->GetPoints()); //add points - vtkIdType aType = 0; + ReverseConnectivity( theIds, theType, theReverse, /*toVtkOrder=*/true); - switch (theType) { - case QUAD_EDGE: - aType = VTK_QUADRATIC_EDGE; - break; - case QUAD_TRIANGLE: - aType = VTK_QUADRATIC_TRIANGLE; - break; - case QUAD_QUADRANGLE: - aType = VTK_QUADRATIC_QUAD; - break; - case QUAD_TETRAHEDRON: - aType = VTK_QUADRATIC_TETRA; - break; - case QUAD_PYRAMID: - //aType = VTK_QUADRATIC_PYRAMID; // NOT SUPPORTED IN VTK4.2 - aType = VTK_CONVEX_POINT_SET; - break; - case QUAD_PENTAHEDRON: - aType = VTK_QUADRATIC_WEDGE; - //aType = VTK_CONVEX_POINT_SET; - break; - case QUAD_HEXAHEDRON: - aType = VTK_QUADRATIC_HEXAHEDRON; - break; - } - - // take care of orientation - if ( aType == VTK_CONVEX_POINT_SET ) { - if ( theReverse && theMode == VTK_SURFACE ) { - //myPreviewActor->GetProperty()->SetColor( myBackRGB[0], myBackRGB[1], myBackRGB[2] ); - } - } - else { - // VTK cell connectivity opposites the MED one for volumic elements - if( aType != VTK_QUADRATIC_WEDGE) { - if ( theIds.size() > 8 ? !theReverse : theReverse ) { - ReverseConnectivity( theIds, theType ); - } - } - else if(theReverse) - ReverseConnectivity( theIds, theType ); - } - myGrid->Reset(); vtkIdList *anIds = vtkIdList::New(); - + for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) { anIds->InsertId(i,theIds[i]); //std::cout << i<< ": " << theIds[i] << std::endl; } - + + vtkIdType aType = SMDS_MeshCell::toVtkType(theType); myGrid->InsertNextCell(aType,anIds); anIds->Delete(); - + myGrid->Modified(); myPreviewActor->GetMapper()->Update(); myPreviewActor->SetRepresentation( theMode ); SetVisibility(true, theActor->GetFacesOriented()); - - // restore normal orientation - if ( aType == VTK_CONVEX_POINT_SET ) { - if ( theReverse && theMode == VTK_SURFACE ) { - //myPreviewActor->GetProperty()->SetColor( myRGB[0], myRGB[1], myRGB[2] ); - } - } } @@ -311,8 +228,8 @@ namespace SMESH ~TElementSimulation() { if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) { - myVTKViewWindow->RemoveActor(myPreviewActor); - myVTKViewWindow->RemoveActor(myFaceOrientation); + myVTKViewWindow->RemoveActor(myPreviewActor); + myVTKViewWindow->RemoveActor(myFaceOrientation); } myPreviewActor->Delete(); myFaceOrientation->Delete(); @@ -356,8 +273,6 @@ static int LastPentahedronIds[] = {1,2,0,4,5,3,3,4,5}; static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3}; static int LastHexahedronIds[] = {1,2,3,0,5,6,7,4,4,5,6,7}; - - /*! \class BusyLocker \brief Simple 'busy state' flag locker. @@ -411,11 +326,12 @@ QWidget* IdEditItem::createEditor() const // purpose : constructor //================================================================================= SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule, - const int theType ) + const SMDSAbs_EntityType theType ) : QDialog( SMESH::GetDesktop( theModule ) ), mySMESHGUI( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), - myType( theType ), + myGeomType( theType ), + //myType( theType ), myBusy( false ) { setModal( false ); @@ -423,36 +339,42 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM SalomeApp_Application* anApp = dynamic_cast (SUIT_Session::session()->activeApplication()); - + mySimulation = new SMESH::TElementSimulation (anApp); mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); QString anElementName; - switch ( myType ) { - case QUAD_EDGE: + switch ( myGeomType ) { + case SMDSEntity_Quad_Edge: anElementName = QString("QUADRATIC_EDGE"); break; - case QUAD_TRIANGLE: + case SMDSEntity_Quad_Triangle: anElementName = QString("QUADRATIC_TRIANGLE"); - break; - case QUAD_QUADRANGLE: + break; + case SMDSEntity_Quad_Quadrangle: anElementName = QString("QUADRATIC_QUADRANGLE"); break; - case QUAD_TETRAHEDRON: + case SMDSEntity_BiQuad_Quadrangle: + anElementName = QString("BIQUADRATIC_QUADRANGLE"); + break; + case SMDSEntity_Quad_Tetra: anElementName = QString("QUADRATIC_TETRAHEDRON"); break; - case QUAD_PYRAMID: + case SMDSEntity_Quad_Pyramid: anElementName = QString("QUADRATIC_PYRAMID"); break; - case QUAD_PENTAHEDRON: + case SMDSEntity_Quad_Penta: anElementName = QString("QUADRATIC_PENTAHEDRON"); break; - case QUAD_HEXAHEDRON: + case SMDSEntity_Quad_Hexa: anElementName = QString("QUADRATIC_HEXAHEDRON"); break; + case SMDSEntity_TriQuad_Hexa: + anElementName = QString("TRIQUADRATIC_HEXAHEDRON"); + break; default: - myType = QUAD_EDGE; + myGeomType = SMDSEntity_Quad_Edge; anElementName = QString("QUADRATIC_EDGE"); } @@ -460,12 +382,12 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM QString caption = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data()); QString argumentsGrTitle = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data()); QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data()); - + QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName)); QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); setWindowTitle(caption); - + setSizeGripEnabled(true); QVBoxLayout* aDialogLayout = new QVBoxLayout(this); @@ -490,21 +412,58 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM aGroupArgumentsLayout->setSpacing(SPACING); aGroupArgumentsLayout->setMargin(MARGIN); + // Corner nodes QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments); - mySelectButton = new QPushButton(GroupArguments); - mySelectButton->setIcon(image1); + myCornerSelectButton = new QPushButton(GroupArguments); + myCornerSelectButton->setIcon(image1); myCornerNodes = new QLineEdit(GroupArguments); + // Mid-edge nodes myTable = new QTableWidget(GroupArguments); + // Mid-face nodes + myMidFaceLabel = new QLabel(tr("SMESH_MIDFACE_NODES"), GroupArguments); + myMidFaceSelectButton = new QPushButton(GroupArguments); + myMidFaceSelectButton->setIcon(image1); + myMidFaceNodes = new QLineEdit(GroupArguments); + myMidFaceNodes->setValidator(new SMESHGUI_IdValidator(this, 6)); + + // Central node + myCenterLabel = new QLabel(tr("SMESH_CENTER_NODE"), GroupArguments); + myCenterSelectButton = new QPushButton(GroupArguments); + myCenterSelectButton->setIcon(image1); + myCenterNode = new QLineEdit(GroupArguments); + myCenterNode->setValidator(new SMESHGUI_IdValidator(this, 1)); + myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments); - aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0); - aGroupArgumentsLayout->addWidget(mySelectButton, 0, 1); - aGroupArgumentsLayout->addWidget(myCornerNodes, 0, 2); - aGroupArgumentsLayout->addWidget(myTable, 1, 0, 1, 3); - aGroupArgumentsLayout->addWidget(myReverseCB, 2, 0, 1, 3); - + aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0); + aGroupArgumentsLayout->addWidget(myCornerSelectButton, 0, 1); + aGroupArgumentsLayout->addWidget(myCornerNodes, 0, 2); + aGroupArgumentsLayout->addWidget(myTable, 1, 0, 1, 3); + aGroupArgumentsLayout->addWidget(myMidFaceLabel, 2, 0); + aGroupArgumentsLayout->addWidget(myMidFaceSelectButton, 2, 1); + aGroupArgumentsLayout->addWidget(myMidFaceNodes, 2, 2); + aGroupArgumentsLayout->addWidget(myCenterLabel, 3, 0); + aGroupArgumentsLayout->addWidget(myCenterSelectButton, 3, 1); + aGroupArgumentsLayout->addWidget(myCenterNode, 3, 2); + aGroupArgumentsLayout->addWidget(myReverseCB, 4, 0, 1, 3); + + /***************************************************************/ + GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this ); + GroupGroups->setCheckable( true ); + QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups); + GroupGroupsLayout->setSpacing(SPACING); + GroupGroupsLayout->setMargin(MARGIN); + + TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups ); + ComboBox_GroupName = new QComboBox( GroupGroups ); + ComboBox_GroupName->setEditable( true ); + ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert ); + + GroupGroupsLayout->addWidget( TextLabel_GroupName ); + GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 ); + /***************************************************************/ GroupButtons = new QGroupBox(this); QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons); @@ -532,6 +491,7 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM /***************************************************************/ aDialogLayout->addWidget(GroupConstructors); aDialogLayout->addWidget(GroupArguments); + aDialogLayout->addWidget(GroupGroups); aDialogLayout->addWidget(GroupButtons); Init(); /* Initialisations */ @@ -554,49 +514,74 @@ void SMESHGUI_AddQuadraticElementDlg::Init() { myRadioButton1->setChecked(true); mySMESHGUI->SetActiveDialogBox((QDialog*)this); - + + /* reset "Add to group" control */ + GroupGroups->setChecked( false ); + myActor = 0; + myNbMidFaceNodes = 0; + myNbCenterNodes = 0; int aNumRows; - switch (myType) { - case QUAD_EDGE: + switch (myGeomType) { + case SMDSEntity_Quad_Edge: aNumRows = 1; myNbCorners = 2; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_edges break; - case QUAD_TRIANGLE: + case SMDSEntity_Quad_Triangle: aNumRows = 3; myNbCorners = 3; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles break; - case QUAD_QUADRANGLE: + case SMDSEntity_Quad_Quadrangle: + aNumRows = 4; + myNbCorners = 4; + myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles + break; + case SMDSEntity_BiQuad_Quadrangle: aNumRows = 4; myNbCorners = 4; + myNbCenterNodes = 1; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles break; - case QUAD_TETRAHEDRON: + case SMDSEntity_Quad_Tetra: aNumRows = 6; myNbCorners = 4; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_tetrahedrons break; - case QUAD_PYRAMID: + case SMDSEntity_Quad_Pyramid: aNumRows = 8; myNbCorners = 5; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pyramids break; - case QUAD_PENTAHEDRON: + case SMDSEntity_Quad_Penta: aNumRows = 9; myNbCorners = 6; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons - break; - case QUAD_HEXAHEDRON: + break; + case SMDSEntity_Quad_Hexa: + aNumRows = 12; + myNbCorners = 8; + myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons + break; + case SMDSEntity_TriQuad_Hexa: aNumRows = 12; myNbCorners = 8; + myNbMidFaceNodes = 6; + myNbCenterNodes = 1; myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons break; } - + + myMidFaceLabel ->setVisible( myNbMidFaceNodes ); + myMidFaceSelectButton->setVisible( myNbMidFaceNodes ); + myMidFaceNodes ->setVisible( myNbMidFaceNodes ); + myCenterLabel ->setVisible( myNbCenterNodes ); + myCenterSelectButton ->setVisible( myNbCenterNodes ); + myCenterNode ->setVisible( myNbCenterNodes ); + myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners)); /* initialize table */ @@ -608,7 +593,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init() aColLabels.append(tr("SMESH_MIDDLE")); aColLabels.append(tr("SMESH_LAST")); myTable->setHorizontalHeaderLabels(aColLabels); - + for ( int col = 0; col < myTable->columnCount(); col++ ) myTable->setColumnWidth(col, 80); @@ -616,7 +601,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init() //myTable->setColumnReadOnly(2, true); // VSR: TODO myTable->setEnabled( false ); - + for ( int row = 0; row < myTable->rowCount(); row++ ) { myTable->setItem( row, 0, new QTableWidgetItem( "" ) ); @@ -629,13 +614,17 @@ void SMESHGUI_AddQuadraticElementDlg::Init() myTable->setItem( row, 2, new QTableWidgetItem( "" ) ); myTable->item( row, 2 )->setFlags(0); } - + /* signals and slots connections */ - connect(mySelectButton, SIGNAL(clicked()), SLOT(SetEditCorners())); + connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection())); + connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection())); + connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection())); connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument())); connect(myTable, SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int))); connect(myTable, SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int))); connect(myCornerNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); + connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); + connect(myCenterNode, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(myReverseCB, SIGNAL(stateChanged(int)), SLOT(onReverse(int))); connect(buttonOk, SIGNAL(clicked()), SLOT(ClickOnOk())); @@ -645,6 +634,9 @@ void SMESHGUI_AddQuadraticElementDlg::Init() connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog())); connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel())); + + myCurrentLineEdit = myCornerNodes; // set selection mode SMESH::SetPointRepresentation(true); @@ -652,7 +644,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init() if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->SetSelectionMode( NodeSelection ); - SetEditCorners(); + SelectionIntoArgument(); } //================================================================================= @@ -661,6 +653,9 @@ void SMESHGUI_AddQuadraticElementDlg::Init() //================================================================================= void SMESHGUI_AddQuadraticElementDlg::ClickOnApply() { + if( !isValid() ) + return; + if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() ) return; @@ -668,59 +663,137 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnApply() std::vector anIds; - switch (myType) { - case QUAD_EDGE: + switch (myGeomType) { + case SMDSEntity_Quad_Edge: anIds.push_back(myTable->item(0, 0)->text().toInt()); anIds.push_back(myTable->item(0, 2)->text().toInt()); anIds.push_back(myTable->item(0, 1)->text().toInt()); break; - case QUAD_TRIANGLE: - case QUAD_QUADRANGLE: - case QUAD_TETRAHEDRON: - case QUAD_PYRAMID: - case QUAD_PENTAHEDRON: - case QUAD_HEXAHEDRON: + case SMDSEntity_Quad_Triangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + case SMDSEntity_Quad_Tetra: + case SMDSEntity_Quad_Pyramid: + case SMDSEntity_Quad_Penta: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: for ( int row = 0; row < myNbCorners; row++ ) anIds.push_back(myTable->item(row, 0)->text().toInt()); for ( int row = 0; row < myTable->rowCount(); row++ ) anIds.push_back(myTable->item(row, 1)->text().toInt()); + if ( myNbMidFaceNodes ) + { + QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts); + for (int i = 0; i < aListId.count(); i++) + anIds.push_back( aListId[ i ].toInt() ); + } + if ( myNbCenterNodes ) + { + QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts); + anIds.push_back( aListId[ 0 ].toInt() ); + } break; } if ( myReverseCB->isChecked()) - SMESH::ReverseConnectivity( anIds, myType ); - + ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false ); + int aNumberOfIds = anIds.size(); SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; anArrayOfIdeces->length( aNumberOfIds ); - + for (int i = 0; i < aNumberOfIds; i++) anArrayOfIdeces[i] = anIds[ i ]; + bool addToGroup = GroupGroups->isChecked(); + QString aGroupName; + + SMESH::SMESH_GroupBase_var aGroup; + int idx = 0; + if( addToGroup ) { + aGroupName = ComboBox_GroupName->currentText(); + for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { + QString aName = ComboBox_GroupName->itemText( i ); + if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) + idx = i; + } + if ( idx > 0 && idx < myGroups.count() ) { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); + if ( !aGeomGroup->_is_nil() ) { + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return; + } + aGroup = myGroups[idx-1]; + } + } + + SMESH::ElementType anElementType; + long anElemId = -1; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - switch (myType) { - case QUAD_EDGE: - aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break; - case QUAD_TRIANGLE: - case QUAD_QUADRANGLE: - aMeshEditor->AddFace(anArrayOfIdeces.inout()); break; - case QUAD_TETRAHEDRON: - case QUAD_PYRAMID: - case QUAD_PENTAHEDRON: - case QUAD_HEXAHEDRON: - aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break; + switch (myGeomType) { + case SMDSEntity_Quad_Edge: + anElementType = SMESH::EDGE; + anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break; + case SMDSEntity_Quad_Triangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + anElementType = SMESH::FACE; + anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break; + case SMDSEntity_Quad_Tetra: + case SMDSEntity_Quad_Pyramid: + case SMDSEntity_Quad_Penta: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + anElementType = SMESH::VOLUME; + anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break; + default: break; + } + + if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) { + SMESH::SMESH_Group_var aGroupUsed; + if ( aGroup->_is_nil() ) { + // create new group + aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName ); + if ( !aGroupUsed->_is_nil() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + else { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); + if ( !aGeomGroup->_is_nil() ) { + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } + } + else + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + } + + if ( !aGroupUsed->_is_nil() ) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length( 1 ); + anIdList[0] = anElemId; + aGroupUsed->Add( anIdList.inout() ); + } } - + SALOME_ListIO aList; aList.Append( myActor->getIO() ); mySelector->ClearIndex(); mySelectionMgr->setSelectedObjects( aList, false ); mySimulation->SetVisibility(false); SMESH::UpdateView(); - + UpdateTable(); - SetEditCorners(); + SetCurrentSelection(); updateButtons(); + + SMESHGUI::Modified(); } //================================================================================= @@ -756,7 +829,7 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel() void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -766,10 +839,10 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -781,7 +854,7 @@ void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText) { if (myBusy) return; BusyLocker lock( myBusy ); - + mySimulation->SetVisibility(false); // hilight entered nodes @@ -789,31 +862,37 @@ void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText) if (myActor) aMesh = myActor->GetObject()->GetMesh(); + QLineEdit* send = (QLineEdit*)sender(); + if (send == myCornerNodes || + send == myMidFaceNodes || + send == myCenterNode) + myCurrentLineEdit = send; + if (aMesh) { TColStd_MapOfInteger newIndices; - + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); bool allOk = true; for (int i = 0; i < aListId.count(); i++) { if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) ) { - newIndices.Add( n->GetID() ); + newIndices.Add( n->GetID() ); } else { - allOk = false; - break; + allOk = false; + break; } } - + mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->highlight( myActor->getIO(), true, true ); - - if ( sender() == myCornerNodes ) + + if ( myCurrentLineEdit == myCornerNodes ) UpdateTable( allOk ); } - + updateButtons(); displaySimulation(); } @@ -826,55 +905,93 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument() { if (myBusy) return; BusyLocker lock( myBusy ); - - if ( myIsEditCorners ) + + QString aCurrentEntry = myEntry; + + if ( myCurrentLineEdit ) { // clear myActor = 0; - - myCornerNodes->setText(""); - + + myCurrentLineEdit->setText(""); + if (!GroupButtons->isEnabled()) // inactive return; - + mySimulation->SetVisibility(false); - + // get selected mesh SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); - + if (aList.Extent() != 1) { UpdateTable(); updateButtons(); return; } - + Handle(SALOME_InteractiveObject) anIO = aList.First(); + myEntry = anIO->getEntry(); myMesh = SMESH::GetMeshByIO(anIO); if (myMesh->_is_nil()) { updateButtons(); return; } - + myActor = SMESH::FindActorByEntry(anIO->getEntry()); - + } - + + // process groups + if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) { + SMESH::ElementType anElementType; + switch ( myGeomType ) { + case SMDSEntity_Quad_Edge: + anElementType = SMESH::EDGE; break; + case SMDSEntity_Quad_Triangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + anElementType = SMESH::FACE; break; + case SMDSEntity_Quad_Tetra: + case SMDSEntity_Quad_Pyramid: + case SMDSEntity_Quad_Penta: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + anElementType = SMESH::VOLUME; break; + } + myGroups.clear(); + ComboBox_GroupName->clear(); + ComboBox_GroupName->addItem( QString() ); + SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups(); + for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; + if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) { + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + } + } + if (!myActor) { updateButtons(); return; } - + // get selected nodes QString aString = ""; int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString); - - if ( myIsEditCorners ) + + if ( myCurrentLineEdit ) { - myCornerNodes->setText(aString); - - UpdateTable(); + if ( myCurrentLineEdit != myCenterNode || nbNodes == 1 ) + myCurrentLineEdit->setText(aString); + + if ( myCurrentLineEdit == myCornerNodes ) + UpdateTable(); } else if ( myTable->isEnabled() && nbNodes == 1 ) { @@ -882,7 +999,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument() if ( theCol == 1 ) myTable->item(theRow, 1)->setText(aString); } - + updateButtons(); displaySimulation(); } @@ -896,13 +1013,13 @@ void SMESHGUI_AddQuadraticElementDlg::displaySimulation() if ( IsValid() ) { SMESH::TElementSimulation::TVTKIds anIds; - + // Collect ids from the dialog int anID; bool ok; int aDisplayMode = VTK_SURFACE; - - if ( myType == QUAD_EDGE ) + + if ( myGeomType == SMDSEntity_Quad_Edge ) { anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) ); anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) ); @@ -914,20 +1031,31 @@ void SMESHGUI_AddQuadraticElementDlg::displaySimulation() else { for ( int row = 0; row < myNbCorners; row++ ) - anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) ); - + anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) ); + for ( int row = 0; row < myTable->rowCount(); row++ ) { - anID = myTable->item(row, 1)->text().toInt(&ok); - if (!ok) { - anID = myTable->item(row, 0)->text().toInt(); - aDisplayMode = VTK_WIREFRAME; - } - anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) ); + anID = myTable->item(row, 1)->text().toInt(&ok); + if (!ok) { + anID = myTable->item(row, 0)->text().toInt(); + aDisplayMode = VTK_WIREFRAME; + } + anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) ); + } + if ( myNbMidFaceNodes ) + { + QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts); + for (int i = 0; i < aListId.count(); i++) + anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() )); + } + if ( myNbCenterNodes ) + { + QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts); + anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() )); } } - - mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked()); + + mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked()); } else { @@ -937,15 +1065,26 @@ void SMESHGUI_AddQuadraticElementDlg::displaySimulation() } //================================================================================= -// function : SetEditCorners() +// function : SetCurrentSelection() // purpose : //================================================================================= -void SMESHGUI_AddQuadraticElementDlg::SetEditCorners() +void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection() { - myCornerNodes->setFocus(); - myIsEditCorners = true; - SelectionIntoArgument(); - updateButtons(); + QPushButton* send = (QPushButton*)sender(); + myCurrentLineEdit = 0; + + if (send == myCornerSelectButton) + myCurrentLineEdit = myCornerNodes; + else if ( send == myMidFaceSelectButton ) + myCurrentLineEdit = myMidFaceNodes; + else if ( send == myCenterSelectButton ) + myCurrentLineEdit = myCenterNode; + + if ( myCurrentLineEdit ) + { + myCurrentLineEdit->setFocus(); + SelectionIntoArgument(); + } } //================================================================================= @@ -1040,19 +1179,37 @@ bool SMESHGUI_AddQuadraticElementDlg::IsValid() return false; bool ok; - + std::set< int > okIDs; for ( int row = 0; row < myTable->rowCount(); row++ ) { int anID = myTable->item(row, 1)->text().toInt(&ok); if ( !ok ) return false; - + const SMDS_MeshNode * aNode = aMesh->FindNode(anID); if ( !aNode ) return false; + okIDs.insert( anID ); } - - return true; + + QStringList aListId; + if ( myNbMidFaceNodes ) + aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts); + if ( myNbCenterNodes ) + aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts); + + for (int i = 0; i < aListId.count(); i++) + { + int anID = aListId[ i ].toInt(&ok); + if ( !ok ) + return false; + + if ( !aMesh->FindNode(anID) ) + return false; + okIDs.insert( anID ); + } + + return okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes; } //================================================================================= @@ -1062,53 +1219,55 @@ bool SMESHGUI_AddQuadraticElementDlg::IsValid() void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity ) { QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts); - + if ( aListCorners.count() == myNbCorners && theConersValidity ) { myTable->setEnabled( true ); - - // clear the Middle column + + // clear the Middle column for ( int row = 0; row < myTable->rowCount(); row++ ) myTable->item( row, 1 )->setText(""); - + int* aFirstColIds; int* aLastColIds; - - switch (myType) { - case QUAD_EDGE: + + switch (myGeomType) { + case SMDSEntity_Quad_Edge: aFirstColIds = FirstEdgeIds; aLastColIds = LastEdgeIds; break; - case QUAD_TRIANGLE: + case SMDSEntity_Quad_Triangle: aFirstColIds = FirstTriangleIds; aLastColIds = LastTriangleIds; break; - case QUAD_QUADRANGLE: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: aFirstColIds = FirstQuadrangleIds; aLastColIds = LastQuadrangleIds; break; - case QUAD_TETRAHEDRON: + case SMDSEntity_Quad_Tetra: aFirstColIds = FirstTetrahedronIds; aLastColIds = LastTetrahedronIds; break; - case QUAD_PYRAMID: + case SMDSEntity_Quad_Pyramid: aFirstColIds = FirstPyramidIds; aLastColIds = LastPyramidIds; break; - case QUAD_PENTAHEDRON: + case SMDSEntity_Quad_Penta: aFirstColIds = FirstPentahedronIds; aLastColIds = LastPentahedronIds; - break; - case QUAD_HEXAHEDRON: + break; + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: aFirstColIds = FirstHexahedronIds; aLastColIds = LastHexahedronIds; break; } - + // fill the First and the Last columns for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++) myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] ); - + for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++) myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] ); } @@ -1117,8 +1276,8 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity ) // clear table for ( int row = 0; row < myTable->rowCount(); row++ ) for ( int col = 0; col < myTable->columnCount(); col++ ) - if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText(""); - + if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText(""); + myTable->setEnabled( false ); } } @@ -1130,7 +1289,7 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity ) //================================================================================= void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol ) { - myIsEditCorners = false; + myCurrentLineEdit = 0; displaySimulation(); updateButtons(); } @@ -1142,7 +1301,7 @@ void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCo //================================================================================= void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol) { - myIsEditCorners = false; + myCurrentLineEdit = 0; displaySimulation(); updateButtons(); } @@ -1169,3 +1328,16 @@ void SMESHGUI_AddQuadraticElementDlg::updateButtons() buttonOk->setEnabled( valid ); buttonApply->setEnabled( valid ); } + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool SMESHGUI_AddQuadraticElementDlg::isValid() +{ + if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) { + SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) ); + return false; + } + return true; +} diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h index a048a6760..3b2c360b2 100644 --- a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_AddMeshElementDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -28,6 +29,7 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" +#include "SMDSAbs_ElementType.hxx" // Qt includes #include @@ -36,7 +38,10 @@ #include #include CORBA_SERVER_HEADER(SMESH_Mesh) +class QComboBox; +class QFrame; class QGroupBox; +class QLabel; class QLineEdit; class QPushButton; class QRadioButton; @@ -52,9 +57,6 @@ namespace SMESH struct TElementSimulation; } -enum { QUAD_EDGE, QUAD_TRIANGLE, QUAD_QUADRANGLE, QUAD_TETRAHEDRON, - QUAD_PYRAMID, QUAD_PENTAHEDRON, QUAD_HEXAHEDRON }; - //================================================================================= // class : SMESHGUI_AddQuadraticElementDlg // purpose : @@ -64,10 +66,12 @@ class SMESHGUI_EXPORT SMESHGUI_AddQuadraticElementDlg : public QDialog Q_OBJECT public: - SMESHGUI_AddQuadraticElementDlg( SMESHGUI*, const int ); + SMESHGUI_AddQuadraticElementDlg( SMESHGUI*, const SMDSAbs_EntityType ); ~SMESHGUI_AddQuadraticElementDlg(); private: + typedef QList GrpList; + void Init(); void closeEvent( QCloseEvent* ); void hideEvent( QHideEvent* ); /* ESC key */ @@ -78,28 +82,44 @@ private: bool IsValid(); void updateButtons(); + bool isValid(); + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ int myNbCorners; /* The required number of corners */ + int myNbMidFaceNodes; + int myNbCenterNodes; bool myBusy; SVTK_Selector* mySelector; SMESH::SMESH_Mesh_var myMesh; SMESH_Actor* myActor; SMESH::TElementSimulation* mySimulation; + QString myEntry; + GrpList myGroups; - int myType; - bool myIsEditCorners; + SMDSAbs_EntityType myGeomType; + QLineEdit* myCurrentLineEdit; QGroupBox* GroupConstructors; QRadioButton* myRadioButton1; QGroupBox* GroupArguments; + QPushButton* myCornerSelectButton; QLineEdit* myCornerNodes; - QPushButton* mySelectButton; + QLabel* myMidFaceLabel; + QPushButton* myMidFaceSelectButton; + QLineEdit* myMidFaceNodes; + QLabel* myCenterLabel; + QPushButton* myCenterSelectButton; + QLineEdit* myCenterNode; QTableWidget* myTable; QCheckBox* myReverseCB; + QGroupBox* GroupGroups; + QLabel* TextLabel_GroupName; + QComboBox* ComboBox_GroupName; + QGroupBox* GroupButtons; QPushButton* buttonOk; QPushButton* buttonCancel; @@ -118,7 +138,7 @@ private slots: void ClickOnCancel(); void ClickOnApply(); void ClickOnHelp(); - void SetEditCorners(); + void SetCurrentSelection(); void SelectionIntoArgument(); void DeactivateActiveDialog(); void ActivateThisDialog(); diff --git a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx index 2d6b7435b..edee4cecb 100644 --- a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_BuildCompoundDlg.cxx -// Author : Alexander KOVALEV, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI_BuildCompoundDlg.cxx +// Author : Alexander KOVALEV, Open CASCADE S.A.S. +// SMESH includes + #include "SMESHGUI_BuildCompoundDlg.h" #include "SMESHGUI.h" @@ -66,6 +65,10 @@ #define SPACING 6 #define MARGIN 11 +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + //================================================================================= // name : SMESHGUI_BuildCompoundDlg // Purpose : @@ -73,7 +76,8 @@ SMESHGUI_BuildCompoundDlg::SMESHGUI_BuildCompoundDlg( SMESHGUI* theModule ) : QDialog(SMESH::GetDesktop(theModule)), mySMESHGUI(theModule), - mySelectionMgr(SMESH::GetSelectionMgr(theModule)) + mySelectionMgr(SMESH::GetSelectionMgr(theModule)), + myIsApplyAndClose( false ) { setModal(false); setAttribute(Qt::WA_DeleteOnClose, true); @@ -137,12 +141,12 @@ SMESHGUI_BuildCompoundDlg::SMESHGUI_BuildCompoundDlg( SMESHGUI* theModule ) TextLabelTol = new QLabel(tr("SMESH_TOLERANCE"), GroupArgs); TextLabelTol->setAlignment(Qt::AlignCenter); SpinBoxTol = new SMESHGUI_SpinBox(GroupArgs); - SpinBoxTol->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, 6); + SpinBoxTol->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision" ); GroupArgsLayout->addWidget(TextLabelMeshes, 0, 0); GroupArgsLayout->addWidget(SelectButton, 0, 1); GroupArgsLayout->addWidget(LineEditMeshes, 0, 2, 1, 2); - GroupArgsLayout->addWidget(TextLabelUnion, 1, 0, 1, 3); + GroupArgsLayout->addWidget(TextLabelUnion, 1, 0, 1, 3); GroupArgsLayout->addWidget(ComboBoxUnion, 1, 3); GroupArgsLayout->addWidget(CheckBoxCommon, 2, 0, 1, 4); GroupArgsLayout->addWidget(CheckBoxMerge, 3, 0, 1, 4); @@ -289,29 +293,37 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply() if (!isValid()) return false; - if (!myMesh->_is_nil()) { + SMESH::SMESH_Mesh_var aCompoundMesh; + + if (!myMesh->_is_nil()) + { QStringList aParameters; aParameters << (CheckBoxMerge->isChecked() ? SpinBoxTol->text() : QString(" ")); - try { + + QStringList anEntryList; + try { SUIT_OverrideCursor aWaitCursor; + myMeshArray[0]->SetParameters( aParameters.join(":").toLatin1().constData() ); + SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen(); // concatenate meshes - SMESH::SMESH_Mesh_var aCompoundMesh; if(CheckBoxCommon->isChecked()) - aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray, - !(ComboBoxUnion->currentIndex()), - CheckBoxMerge->isChecked(), - SpinBoxTol->GetValue()); + aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray, + !(ComboBoxUnion->currentIndex()), + CheckBoxMerge->isChecked(), + SpinBoxTol->GetValue()); else - aCompoundMesh = aSMESHGen->Concatenate(myMeshArray, - !(ComboBoxUnion->currentIndex()), - CheckBoxMerge->isChecked(), - SpinBoxTol->GetValue()); - - aCompoundMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); - - SMESH::SetName( SMESH::FindSObject( aCompoundMesh ), LineEditName->text() ); + aCompoundMesh = aSMESHGen->Concatenate(myMeshArray, + !(ComboBoxUnion->currentIndex()), + CheckBoxMerge->isChecked(), + SpinBoxTol->GetValue()); + + _PTR(SObject) aSO = SMESH::FindSObject( aCompoundMesh ); + if( aSO ) { + SMESH::SetName( aSO, LineEditName->text() ); + anEntryList.append( aSO->GetID().c_str() ); + } mySMESHGUI->updateObjBrowser(); } catch(...) { return false; @@ -319,8 +331,30 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply() LineEditName->setText(GetDefaultName(tr("COMPOUND_MESH"))); - //mySelectionMgr->clearSelected(); - SMESH::UpdateView(); + // IPAL21468 Compound is hidden after creation. + if ( SMESHGUI::automaticUpdate() ) { + mySelectionMgr->clearSelected(); + SMESH::UpdateView(); + + _PTR(SObject) aSO = SMESH::FindSObject(aCompoundMesh.in()); + if ( SMESH_Actor* anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()) ) + SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor); + }// end IPAL21468 + + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); + + SMESHGUI::Modified(); + +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + if (!CORBA::is_nil(aCompoundMesh)) + aCompoundMesh->UnRegister(); +#endif + return true; } return false; @@ -332,6 +366,7 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply() //================================================================================= void SMESHGUI_BuildCompoundDlg::ClickOnOk() { + setIsApplyAndClose( true ); if (ClickOnApply()) ClickOnCancel(); } @@ -356,14 +391,14 @@ void SMESHGUI_BuildCompoundDlg::ClickOnCancel() void SMESHGUI_BuildCompoundDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - "application")). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + "application")). + arg(myHelpFileName)); } } @@ -491,7 +526,6 @@ void SMESHGUI_BuildCompoundDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_BuildCompoundDlg::onSelectMerge(bool toMerge) { - TextLabelTol->setEnabled(toMerge); SpinBoxTol->setEnabled(toMerge); if(!toMerge) @@ -518,3 +552,23 @@ bool SMESHGUI_BuildCompoundDlg::isValid() } return true; } + +//================================================================ +// function : setIsApplyAndClose +// Purpose : Set value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +void SMESHGUI_BuildCompoundDlg::setIsApplyAndClose( const bool theFlag ) +{ + myIsApplyAndClose = theFlag; +} + +//================================================================ +// function : isApplyAndClose +// Purpose : Get value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +bool SMESHGUI_BuildCompoundDlg::isApplyAndClose() const +{ + return myIsApplyAndClose; +} diff --git a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h index c1085739d..6230022e8 100644 --- a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h +++ b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_BuildCompoundDlg.h // Author : Alexander KOVALEV, Open CASCADE S.A.S. @@ -73,6 +74,9 @@ private: void keyPressEvent( QKeyEvent* ); bool isValid(); + + void setIsApplyAndClose( const bool theFlag ); + bool isApplyAndClose() const; private: SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ @@ -109,6 +113,8 @@ private: QString myHelpFileName; + bool myIsApplyAndClose; + private slots: void ClickOnOk(); void ClickOnCancel(); diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx index 6f2d9293e..3143626c6 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ClippingDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -40,11 +41,15 @@ #include #include #include +#include #include +#include + #include -#include + +#include #include @@ -58,138 +63,139 @@ #include #include #include +#include // VTK includes #include -#include #include #include #include #include +#include #define SPACING 6 #define MARGIN 11 -class OrientedPlane: public vtkPlane +//================================================================================= +// class : OrientedPlane +// purpose : +//================================================================================= +SMESH::OrientedPlane* SMESH::OrientedPlane::New() { - SVTK_ViewWindow* myViewWindow; - - vtkDataSetMapper* myMapper; - -public: - static OrientedPlane *New() - { - return new OrientedPlane(); - } - static OrientedPlane *New(SVTK_ViewWindow* theViewWindow) - { - return new OrientedPlane(theViewWindow); - } - vtkTypeMacro (OrientedPlane, vtkPlane); - - SMESH::Orientation myOrientation; - float myDistance; - double myAngle[2]; - - vtkPlaneSource* myPlaneSource; - SALOME_Actor *myActor; - - void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; } - SMESH::Orientation GetOrientation() { return myOrientation; } + return new OrientedPlane(); +} - void SetDistance (float theDistance) { myDistance = theDistance; } - float GetDistance() { return myDistance; } +SMESH::OrientedPlane* SMESH::OrientedPlane::New(SVTK_ViewWindow* theViewWindow) +{ + return new OrientedPlane(theViewWindow); +} - void ShallowCopy (OrientedPlane* theOrientedPlane) - { - SetNormal(theOrientedPlane->GetNormal()); - SetOrigin(theOrientedPlane->GetOrigin()); +void SMESH::OrientedPlane::ShallowCopy(SMESH::OrientedPlane* theOrientedPlane) +{ + SetNormal(theOrientedPlane->GetNormal()); + SetOrigin(theOrientedPlane->GetOrigin()); - myOrientation = theOrientedPlane->GetOrientation(); - myDistance = theOrientedPlane->GetDistance(); + myOrientation = theOrientedPlane->GetOrientation(); + myDistance = theOrientedPlane->GetDistance(); - myAngle[0] = theOrientedPlane->myAngle[0]; - myAngle[1] = theOrientedPlane->myAngle[1]; + myAngle[0] = theOrientedPlane->myAngle[0]; + myAngle[1] = theOrientedPlane->myAngle[1]; - myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal()); - myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin()); - myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1()); - myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2()); - } + myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal()); + myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin()); + myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1()); + myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2()); +} -protected: - OrientedPlane(SVTK_ViewWindow* theViewWindow): - myViewWindow(theViewWindow), - myOrientation(SMESH::XY), - myDistance(0.5) - { - Init(); - myViewWindow->AddActor(myActor); - } +SMESH::OrientedPlane::OrientedPlane(SVTK_ViewWindow* theViewWindow): + myViewWindow(theViewWindow), + myOrientation(SMESH::XY), + myDistance(0.5) +{ + Init(); + myViewWindow->AddActor(myActor, false, false); // don't adjust actors +} - OrientedPlane(): - myOrientation(SMESH::XY), - myViewWindow(NULL), - myDistance(0.5) - { - Init(); - } +SMESH::OrientedPlane::OrientedPlane(): + myOrientation(SMESH::XY), + myViewWindow(NULL), + myDistance(0.5) +{ + Init(); +} - void Init() - { - myPlaneSource = vtkPlaneSource::New(); - - myAngle[0] = myAngle[1] = 0.0; - - // Create and display actor - myMapper = vtkDataSetMapper::New(); - myMapper->SetInput(myPlaneSource->GetOutput()); - - myActor = SALOME_Actor::New(); - myActor->VisibilityOff(); - myActor->PickableOff(); - myActor->SetInfinitive(true); - myActor->SetMapper(myMapper); - - vtkFloatingPointType anRGB[3]; - vtkProperty* aProp = vtkProperty::New(); - SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); - aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); - aProp->SetOpacity(0.75); - myActor->SetProperty(aProp); - aProp->Delete(); - - vtkProperty* aBackProp = vtkProperty::New(); - SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) ); - aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); - aBackProp->SetOpacity(0.75); - myActor->SetBackfaceProperty(aBackProp); - aBackProp->Delete(); - } +void SMESH::OrientedPlane::Init() +{ + myPlaneSource = vtkPlaneSource::New(); + + myAngle[0] = myAngle[1] = 0.0; + + // Create and display actor + myMapper = vtkDataSetMapper::New(); + myMapper->SetInput(myPlaneSource->GetOutput()); + + myActor = SALOME_Actor::New(); + myActor->VisibilityOff(); + myActor->PickableOff(); + myActor->SetInfinitive(true); + myActor->SetMapper(myMapper); + + vtkFloatingPointType anRGB[3]; + vtkProperty* aProp = vtkProperty::New(); + SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); + aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + aProp->SetOpacity(0.75); + myActor->SetProperty(aProp); + aProp->Delete(); + + vtkProperty* aBackProp = vtkProperty::New(); + SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) ); + aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + aBackProp->SetOpacity(0.75); + myActor->SetBackfaceProperty(aBackProp); + aBackProp->Delete(); +} - ~OrientedPlane(){ +SMESH::OrientedPlane::~OrientedPlane() +{ + if (myViewWindow) myViewWindow->RemoveActor(myActor); - myActor->Delete(); + myActor->Delete(); - myMapper->RemoveAllInputs(); - myMapper->Delete(); + myMapper->RemoveAllInputs(); + myMapper->Delete(); - // commented: porting to vtk 5.0 - // myPlaneSource->UnRegisterAllOutputs(); - myPlaneSource->Delete(); - }; + // commented: porting to vtk 5.0 + // myPlaneSource->UnRegisterAllOutputs(); + myPlaneSource->Delete(); +} -private: - // Not implemented. - OrientedPlane (const OrientedPlane&); - void operator= (const OrientedPlane&); +//================================================================================= +// class : ActorItem +// purpose : +//================================================================================= +class ActorItem : public QListWidgetItem +{ +public: + ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) : + QListWidgetItem( theName, theListWidget ), + myActor( theActor ) {} + + SMESH_Actor* getActor() const { return myActor; } +private: + SMESH_Actor* myActor; }; -struct TSetVisiblity { - TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){} - void operator()(SMESH::TVTKPlane& theOrientedPlane){ - theOrientedPlane->myActor->SetVisibility(myIsVisible); +//================================================================================= +// class : TSetVisibility +// purpose : +//================================================================================= +struct TSetVisibility { + TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){} + void operator()(SMESH::TPlaneData& thePlaneData){ + bool anIsEmpty = thePlaneData.ActorList.empty(); + thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible && !anIsEmpty); } int myIsVisible; }; @@ -198,13 +204,13 @@ struct TSetVisiblity { // used in SMESHGUI::restoreVisualParameters() to avoid // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx //================================================================================= -void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor* theActor, - SVTK_ViewWindow* theViewWindow, - SMESH::Orientation theOrientation, - double theDistance, - vtkFloatingPointType theAngle[2]) +SMESH::OrientedPlane* SMESHGUI_ClippingDlg::AddPlane (SMESH::TActorList theActorList, + SVTK_ViewWindow* theViewWindow, + SMESH::Orientation theOrientation, + double theDistance, + const vtkFloatingPointType theAngle[2]) { - OrientedPlane* aPlane = OrientedPlane::New(theViewWindow); + SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(theViewWindow); aPlane->myAngle[0] = theAngle[0]; aPlane->myAngle[1] = theAngle[1]; @@ -254,41 +260,64 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor* theActor, vtkMath::Cross(aNormal,aDir[1],aDir[0]); } - // ??? - theActor->SetPlaneParam(aNormal, theDistance, aPlane); - - vtkDataSet* aDataSet = theActor->GetInput(); - vtkFloatingPointType *aPnt = aDataSet->GetCenter(); - - vtkFloatingPointType* anOrigin = aPlane->GetOrigin(); - vtkFloatingPointType aDel = aDataSet->GetLength()/2.0; + vtkFloatingPointType aBounds[6]; + vtkFloatingPointType anOrigin[3]; + + bool anIsOk = false; + if( theActorList.empty() ) { + // to support planes with empty actor list we should create + // a nullified plane that will be initialized later + anOrigin[0] = anOrigin[1] = anOrigin[2] = 0; + aBounds[0] = aBounds[2] = aBounds[4] = 0; + aBounds[1] = aBounds[3] = aBounds[5] = 0; + anIsOk = true; + } + else + anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList, + aNormal, + theDistance, + aBounds, + anOrigin ); + if( !anIsOk ) + return NULL; + + aPlane->SetNormal( aNormal ); + aPlane->SetOrigin( anOrigin ); + + vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., + ( aBounds[2] + aBounds[3] ) / 2., + ( aBounds[4] + aBounds[5] ) / 2. }; + + vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + + pow( aBounds[3] - aBounds[2], 2 ) + + pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, - {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; + {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3]; vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], - aPnt[1] - aDelta[0][1] - aDelta[1][1], - aPnt[2] - aDelta[0][2] - aDelta[1][2]}; + aPnt[1] - aDelta[0][1] - aDelta[1][1], + aPnt[2] - aDelta[0][2] - aDelta[1][2]}; vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0], - aPnt01[1] + aNormal[1], - aPnt01[2] + aNormal[2]}; + aPnt01[1] + aNormal[1], + aPnt01[2] + aNormal[2]}; vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], - aPnt[1] - aDelta[0][1] + aDelta[1][1], - aPnt[2] - aDelta[0][2] + aDelta[1][2]}; + aPnt[1] - aDelta[0][1] + aDelta[1][1], + aPnt[2] - aDelta[0][2] + aDelta[1][2]}; vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0], - aPnt11[1] + aNormal[1], - aPnt11[2] + aNormal[2]}; + aPnt11[1] + aNormal[1], + aPnt11[2] + aNormal[2]}; vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], - aPnt[1] + aDelta[0][1] - aDelta[1][1], - aPnt[2] + aDelta[0][2] - aDelta[1][2]}; + aPnt[1] + aDelta[0][1] - aDelta[1][1], + aPnt[2] + aDelta[0][2] - aDelta[1][2]}; vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0], - aPnt21[1] + aNormal[1], - aPnt21[2] + aNormal[2]}; + aPnt21[1] + aNormal[1], + aPnt21[2] + aNormal[2]}; vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; @@ -297,28 +326,13 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor* theActor, aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); - theActor->AddClippingPlane(aPlane); - aPlane->Delete(); -} + SMESH::TActorList::iterator anIter = theActorList.begin(); + for ( ; anIter != theActorList.end(); anIter++ ) + if( vtkActor* aVTKActor = *anIter ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->AddClippingPlane( aPlane ); -//================================================================================= -// used in SMESHGUI::restoreVisualParameters() to avoid -// declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx -//================================================================================= -void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor* theActor, - int thePlaneIndex, - SMESH::Orientation& theOrientation, - double& theDistance, - vtkFloatingPointType* theAngle) -{ - if (vtkPlane* aPln = theActor->GetClippingPlane(thePlaneIndex)) { - if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aPln)) { - theOrientation = aPlane->GetOrientation(); - theDistance = aPlane->GetDistance(); - theAngle[0] = aPlane->myAngle[0]; - theAngle[1] = aPlane->myAngle[1]; - } - } + return aPlane; } //================================================================================= @@ -326,11 +340,10 @@ void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor* theActor, // purpose : // //================================================================================= -SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): +SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow* theViewWindow ): QDialog( SMESH::GetDesktop(theModule) ), - mySelector(SMESH::GetViewWindow(theModule)->GetSelector()), - mySelectionMgr(SMESH::GetSelectionMgr(theModule)), - mySMESHGUI(theModule) + mySMESHGUI(theModule), + myViewWindow(theViewWindow) { setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); @@ -342,8 +355,8 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): SMESHGUI_ClippingDlgLayout->setMargin(MARGIN); // Controls for selecting, creating, deleting planes - QGroupBox* GroupPlanes = new QGroupBox(tr("Clipping planes"), this); - QHBoxLayout* GroupPlanesLayout = new QHBoxLayout(GroupPlanes); + QGroupBox* GroupPlanes = new QGroupBox(tr("CLIP_PLANES"), this); + QGridLayout* GroupPlanesLayout = new QGridLayout(GroupPlanes); GroupPlanesLayout->setSpacing(SPACING); GroupPlanesLayout->setMargin(MARGIN); @@ -353,10 +366,21 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): buttonDelete = new QPushButton(tr("SMESH_BUT_DELETE"), GroupPlanes); - GroupPlanesLayout->addWidget(ComboBoxPlanes); - GroupPlanesLayout->addStretch(); - GroupPlanesLayout->addWidget(buttonNew); - GroupPlanesLayout->addWidget(buttonDelete); + QLabel* aLabel = new QLabel(tr("MESHES_SUBMESHES_GROUPS"), GroupPlanes); + + ActorList = new QListWidget(GroupPlanes); + ActorList->setSelectionMode(QAbstractItemView::SingleSelection); + + SelectAllCheckBox = new QCheckBox(tr("SELECT_ALL"), GroupPlanes); + + GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0); + GroupPlanesLayout->addWidget(new QWidget(), 0, 1); + GroupPlanesLayout->addWidget(buttonNew, 0, 2); + GroupPlanesLayout->addWidget(buttonDelete, 0, 3); + GroupPlanesLayout->addWidget(aLabel, 1, 0, 1, 4); + GroupPlanesLayout->addWidget(ActorList, 2, 0, 1, 4); + GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 4); + GroupPlanesLayout->setColumnStretch( 1, 1 ); // Controls for defining plane parameters QGroupBox* GroupParameters = new QGroupBox(tr("SMESH_PARAMETERS"), this); @@ -372,18 +396,18 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): SpinBoxDistance = new SMESHGUI_SpinBox(GroupParameters); - TextLabelRot1 = new QLabel(tr("Rotation around X (Y to Z):"), GroupParameters); + TextLabelRot1 = new QLabel(tr("ROTATION_AROUND_X_Y2Z"), GroupParameters); SpinBoxRot1 = new SMESHGUI_SpinBox(GroupParameters); - TextLabelRot2 = new QLabel(tr("Rotation around Y (X to Z):"), GroupParameters); + TextLabelRot2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters); SpinBoxRot2 = new SMESHGUI_SpinBox(GroupParameters); - PreviewCheckBox = new QCheckBox(tr("Show preview"), GroupParameters); + PreviewCheckBox = new QCheckBox(tr("SHOW_PREVIEW"), GroupParameters); PreviewCheckBox->setChecked(true); - AutoApplyCheckBox = new QCheckBox(tr("Auto Apply"), GroupParameters); + AutoApplyCheckBox = new QCheckBox(tr("AUTO_APPLY"), GroupParameters); AutoApplyCheckBox->setChecked(false); GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0); @@ -425,19 +449,20 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): SMESHGUI_ClippingDlgLayout->addWidget(GroupButtons); // Initial state - SpinBoxDistance->RangeStepAndValidator(0.0, 1.0, 0.01, 3); - SpinBoxRot1->RangeStepAndValidator(-180.0, 180.0, 1, 3); - SpinBoxRot2->RangeStepAndValidator(-180.0, 180.0, 1, 3); + SpinBoxDistance->RangeStepAndValidator(0.0, 1.0, 0.01, "length_precision" ); + SpinBoxRot1->RangeStepAndValidator(-180.0, 180.0, 1, "angle_precision" ); + SpinBoxRot2->RangeStepAndValidator(-180.0, 180.0, 1, "angle_precision" ); - ComboBoxOrientation->addItem(tr("|| X-Y")); - ComboBoxOrientation->addItem(tr("|| Y-Z")); - ComboBoxOrientation->addItem(tr("|| Z-X")); + ComboBoxOrientation->addItem(tr("ALONG_XY")); + ComboBoxOrientation->addItem(tr("ALONG_YZ")); + ComboBoxOrientation->addItem(tr("ALONG_ZX")); SpinBoxDistance->SetValue(0.5); - myActor = 0; myIsSelectPlane = false; - onSelectionChanged(); + + initializePlaneData(); + synchronize(); myHelpFileName = "clipping_page.html"; @@ -445,6 +470,8 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): connect(ComboBoxPlanes, SIGNAL(activated(int)), this, SLOT(onSelectPlane(int))); connect(buttonNew, SIGNAL(clicked()), this, SLOT(ClickOnNew())); connect(buttonDelete, SIGNAL(clicked()), this, SLOT(ClickOnDelete())); + connect(ActorList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onActorItemChanged(QListWidgetItem*))); + connect(SelectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAll(int))); connect(ComboBoxOrientation, SIGNAL(activated(int)), this, SLOT(onSelectOrientation(int))); connect(SpinBoxDistance, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam())); connect(SpinBoxRot1, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam())); @@ -456,7 +483,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); /* to close dialog if study frame change */ connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(ClickOnCancel())); @@ -470,10 +496,9 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg() { // no need to delete child widgets, Qt does it all for us - std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false)); - if (mySMESHGUI) - if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) - SMESH::RenderViewWindow(aViewWindow); + std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(false)); + if (myViewWindow) + SMESH::RenderViewWindow(myViewWindow); } double SMESHGUI_ClippingDlg::getDistance() const @@ -502,27 +527,58 @@ double SMESHGUI_ClippingDlg::getRotation2() const //======================================================================= void SMESHGUI_ClippingDlg::ClickOnApply() { - if (!myActor) - return; - - if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) { + if (myViewWindow) { SUIT_OverrideCursor wc; QWidget *aCurrWid = this->focusWidget(); aCurrWid->clearFocus(); aCurrWid->setFocus(); - myActor->RemoveAllClippingPlanes(); + SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ]; + + // clean memory allocated for planes + SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin(); + for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ ) + if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane ) + aPlane->Delete(); + + aClippingPlaneInfoList.clear(); + + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->RemoveAllClippingPlanes(); + + SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin(); + for( ; anIter2 != myPlanes.end(); anIter2++ ) { + SMESH::TPlaneData aPlaneData = *anIter2; + SMESH::TPlane aPlane = aPlaneData.Plane; + SMESH::TActorList anActorList = aPlaneData.ActorList; + + // the check is disabled to support planes with empty actor list + //if( anActorList.empty() ) + // continue; - SMESH::TPlanes::iterator anIter = myPlanes.begin(); - for ( ; anIter != myPlanes.end(); anIter++) { - OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow); - anOrientedPlane->ShallowCopy(anIter->GetPointer()); - myActor->AddClippingPlane(anOrientedPlane); - anOrientedPlane->Delete(); + SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow); + anOrientedPlane->ShallowCopy(aPlane.GetPointer()); + + SMESH::TActorList::iterator anIter3 = anActorList.begin(); + for( ; anIter3 != anActorList.end(); anIter3++ ) + if( vtkActor* aVTKActor = *anIter3 ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->AddClippingPlane(anOrientedPlane); + + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = anOrientedPlane; + aClippingPlaneInfo.ActorList = anActorList; + + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); } - SMESH::RenderViewWindow(aViewWindow); + SMESH::RenderViewWindow( myViewWindow ); } } @@ -555,67 +611,31 @@ void SMESHGUI_ClippingDlg::ClickOnHelp() if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { - QString platform; + QString platform; #ifdef WIN32 - platform = "winapplication"; + platform = "winapplication"; #else - platform = "application"; + platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } -//================================================================================= -// function : onSelectionChanged() -// purpose : Called when selection is changed -//================================================================================= -void SMESHGUI_ClippingDlg::onSelectionChanged() -{ - if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) { - const SALOME_ListIO& aList = mySelector->StoredIObjects(); - if (aList.Extent() > 0) { - Handle(SALOME_InteractiveObject) IOS = aList.First(); - myActor = SMESH::FindActorByEntry(IOS->getEntry()); - if (myActor) { - std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false)); - myPlanes.clear(); - - vtkIdType anId = 0, anEnd = myActor->GetNumberOfClippingPlanes(); - for ( ; anId < anEnd; anId++) { - if (vtkImplicitFunction* aFunction = myActor->GetClippingPlane(anId)) { - if(OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)){ - OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow); - SMESH::TVTKPlane aTVTKPlane(anOrientedPlane); - anOrientedPlane->Delete(); - aTVTKPlane->ShallowCopy(aPlane); - myPlanes.push_back(aTVTKPlane); - } - } - } - - std::for_each(myPlanes.begin(),myPlanes.end(), - TSetVisiblity(PreviewCheckBox->isChecked())); - } - } - SMESH::RenderViewWindow(aViewWindow); - } - Sinchronize(); -} - //======================================================================= // function : onSelectPlane() // purpose : //======================================================================= void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex) { - if (!myActor || myPlanes.empty()) + if (myPlanes.empty()) return; - OrientedPlane* aPlane = myPlanes[theIndex].GetPointer(); + SMESH::TPlaneData aPlaneData = myPlanes[theIndex]; + SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); // Orientation SMESH::Orientation anOrientation = aPlane->GetOrientation(); @@ -642,6 +662,11 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex) break; } myIsSelectPlane = false; + + // Actors + bool anIsBlocked = ActorList->blockSignals( true ); + updateActorList(); + ActorList->blockSignals( anIsBlocked ); } //======================================================================= @@ -650,19 +675,31 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex) //======================================================================= void SMESHGUI_ClippingDlg::ClickOnNew() { - if (!myActor) - return; + if(myViewWindow){ + SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow); + SMESH::TPlane aTPlane(aPlane); + + SMESH::TActorList anActorList; + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActorList.push_back( anActor ); - if(SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)){ - OrientedPlane* aPlane = OrientedPlane::New(aViewWindow); - SMESH::TVTKPlane aTVTKPlane(aPlane); - myPlanes.push_back(aTVTKPlane); + SMESH::TPlaneData aPlaneData(aTPlane, anActorList); + + myPlanes.push_back(aPlaneData); if (PreviewCheckBox->isChecked()) - aTVTKPlane->myActor->VisibilityOn(); - - Sinchronize(); + aTPlane->myActor->VisibilityOn(); + + bool anIsBlocked = ActorList->blockSignals( true ); + + synchronize(); SetCurrentPlaneParam(); + + ActorList->blockSignals( anIsBlocked ); } } @@ -672,20 +709,105 @@ void SMESHGUI_ClippingDlg::ClickOnNew() //======================================================================= void SMESHGUI_ClippingDlg::ClickOnDelete() { - if (!myActor || myPlanes.empty()) + if (myPlanes.empty()) return; int aPlaneIndex = ComboBoxPlanes->currentIndex(); - SMESH::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex; - anIter->GetPointer()->myActor->SetVisibility(false); + SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex; + SMESH::TPlaneData aPlaneData = *anIter; + aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false); myPlanes.erase(anIter); if(AutoApplyCheckBox->isChecked()) ClickOnApply(); - Sinchronize(); - SMESH::RenderViewWindow(SMESH::GetCurrentVtkView()); + synchronize(); + SMESH::RenderViewWindow( myViewWindow ); +} + +//======================================================================= +// function : updateActorItem() +// purpose : +//======================================================================= +void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem, + bool theUpdateSelectAll, + bool theUpdateClippingPlaneMap ) +{ + // update Select All check box + if( theUpdateSelectAll ) { + int aNbItems = ActorList->count(), aNbChecked = 0; + for( int i = 0; i < aNbItems; i++ ) + if( QListWidgetItem* anItem = ActorList->item( i ) ) + if( anItem->checkState() == Qt::Checked ) + aNbChecked++; + + Qt::CheckState aCheckState = Qt::Unchecked; + if( aNbChecked == aNbItems ) + aCheckState = Qt::Checked; + else if( aNbChecked > 0 ) + aCheckState = Qt::PartiallyChecked; + + bool anIsBlocked = SelectAllCheckBox->blockSignals( true ); + SelectAllCheckBox->setCheckState( aCheckState ); + SelectAllCheckBox->blockSignals( anIsBlocked ); + } + + // update clipping plane map + if( theUpdateClippingPlaneMap ) { + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + if( ActorItem* anItem = dynamic_cast( theItem ) ) { + if( SMESH_Actor* anActor = anItem->getActor() ) { + SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; + SMESH::TActorList& anActorList = aPlaneData.ActorList; + bool anIsPushed = false; + SMESH::TActorList::iterator anIter = anActorList.begin(); + for ( ; anIter != anActorList.end(); anIter++ ) { + if( anActor == *anIter ) { + anIsPushed = true; + break; + } + } + if( theItem->checkState() == Qt::Checked && !anIsPushed ) + anActorList.push_back( anActor ); + else if( theItem->checkState() == Qt::Unchecked && anIsPushed ) + anActorList.remove( anActor ); + } + } + } +} + +//======================================================================= +// function : onActorItemChanged() +// purpose : +//======================================================================= +void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem ) +{ + updateActorItem( theItem, true, true ); + SetCurrentPlaneParam(); +} + +//======================================================================= +// function : onSelectAll() +// purpose : +//======================================================================= +void SMESHGUI_ClippingDlg::onSelectAll( int theState ) +{ + if( theState == Qt::PartiallyChecked ) { + SelectAllCheckBox->setCheckState( Qt::Checked ); + return; + } + + bool anIsBlocked = ActorList->blockSignals( true ); + for( int i = 0, n = ActorList->count(); i < n; i++ ) { + if( QListWidgetItem* anItem = ActorList->item( i ) ) { + anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked ); + updateActorItem( anItem, false, true ); + } + } + SelectAllCheckBox->setTristate( false ); + ActorList->blockSignals( anIsBlocked ); + SetCurrentPlaneParam(); } //======================================================================= @@ -698,16 +820,16 @@ void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem) return; if (theItem == 0) { - TextLabelRot1->setText(tr("Rotation around X (Y to Z):")); - TextLabelRot2->setText(tr("Rotation around Y (X to Z):")); + TextLabelRot1->setText(tr("ROTATION_AROUND_X_Y2Z")); + TextLabelRot2->setText(tr("ROTATION_AROUND_Y_X2Z")); } else if (theItem == 1) { - TextLabelRot1->setText(tr("Rotation around Y (Z to X):")); - TextLabelRot2->setText(tr("Rotation around Z (Y to X):")); + TextLabelRot1->setText(tr("ROTATION_AROUND_Y_Z2X")); + TextLabelRot2->setText(tr("ROTATION_AROUND_Z_Y2X")); } else if (theItem == 2) { - TextLabelRot1->setText(tr("Rotation around Z (X to Y):")); - TextLabelRot2->setText(tr("Rotation around X (Z to Y):")); + TextLabelRot1->setText(tr("ROTATION_AROUND_Z_X2Y")); + TextLabelRot2->setText(tr("ROTATION_AROUND_X_Z2Y")); } if((QComboBox*)sender() == ComboBoxOrientation) @@ -715,17 +837,17 @@ void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem) } //======================================================================= -// function : Sinchronize() +// function : synchronize() // purpose : //======================================================================= -void SMESHGUI_ClippingDlg::Sinchronize() +void SMESHGUI_ClippingDlg::synchronize() { int aNbPlanes = myPlanes.size(); ComboBoxPlanes->clear(); QString aName; for(int i = 1; i<=aNbPlanes; i++) { - aName = QString(tr("Plane# %1")).arg(i); + aName = QString(tr("PLANE_NUM")).arg(i); ComboBoxPlanes->addItem(aName); } @@ -735,17 +857,22 @@ void SMESHGUI_ClippingDlg::Sinchronize() bool anIsControlsEnable = (aPos >= 0); if (anIsControlsEnable) { onSelectPlane(aPos); + updateActorList(); } else { - ComboBoxPlanes->addItem(tr("No planes")); + ComboBoxPlanes->addItem(tr("NO_PLANES")); + ActorList->clear(); SpinBoxRot1->SetValue(0.0); SpinBoxRot2->SetValue(0.0); SpinBoxDistance->SetValue(0.5); } + ActorList->setEnabled(anIsControlsEnable); + SelectAllCheckBox->setEnabled(anIsControlsEnable); buttonDelete->setEnabled(anIsControlsEnable); - buttonApply->setEnabled(anIsControlsEnable); - PreviewCheckBox->setEnabled(anIsControlsEnable); - AutoApplyCheckBox->setEnabled(anIsControlsEnable); + // the following 3 controls should be enabled + //buttonApply->setEnabled(anIsControlsEnable); + //PreviewCheckBox->setEnabled(anIsControlsEnable); + //AutoApplyCheckBox->setEnabled(anIsControlsEnable); ComboBoxOrientation->setEnabled(anIsControlsEnable); SpinBoxDistance->setEnabled(anIsControlsEnable); SpinBoxRot1->setEnabled(anIsControlsEnable); @@ -773,7 +900,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer(); + SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); vtkFloatingPointType aNormal[3]; SMESH::Orientation anOrientation; @@ -831,52 +959,69 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() aPlane->SetOrientation(anOrientation); aPlane->SetDistance(getDistance()); - myActor->SetPlaneParam(aNormal, getDistance(), aPlane); - - vtkDataSet* aDataSet = myActor->GetInput(); - vtkFloatingPointType *aPnt = aDataSet->GetCenter(); - - vtkFloatingPointType* anOrigin = aPlane->GetOrigin(); - vtkFloatingPointType aDel = aDataSet->GetLength()/2.0; - - vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, - {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; - vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3]; - - vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], - aPnt[1] - aDelta[0][1] - aDelta[1][1], - aPnt[2] - aDelta[0][2] - aDelta[1][2]}; - vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0], - aPnt01[1] + aNormal[1], - aPnt01[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); - - vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], - aPnt[1] - aDelta[0][1] + aDelta[1][1], - aPnt[2] - aDelta[0][2] + aDelta[1][2]}; - vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0], - aPnt11[1] + aNormal[1], - aPnt11[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); - - vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], - aPnt[1] + aDelta[0][1] - aDelta[1][1], - aPnt[2] + aDelta[0][2] - aDelta[1][2]}; - vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0], - aPnt21[1] + aNormal[1], - aPnt21[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); - - vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; - aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]); - aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]); - aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); - aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); + SMESH::TActorList anActorList = aPlaneData.ActorList; + + vtkFloatingPointType aBounds[6]; + vtkFloatingPointType anOrigin[3]; + bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList, + aNormal, + getDistance(), + aBounds, + anOrigin ); + + aPlane->myActor->SetVisibility( anIsOk && PreviewCheckBox->isChecked() ); + + if( anIsOk ) { + aPlane->SetNormal( aNormal ); + aPlane->SetOrigin( anOrigin ); + + vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., + ( aBounds[2] + aBounds[3] ) / 2., + ( aBounds[4] + aBounds[5] ) / 2. }; + + vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + + pow( aBounds[3] - aBounds[2], 2 ) + + pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); + + vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, + {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; + vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3]; + + vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], + aPnt[1] - aDelta[0][1] - aDelta[1][1], + aPnt[2] - aDelta[0][2] - aDelta[1][2]}; + vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0], + aPnt01[1] + aNormal[1], + aPnt01[2] + aNormal[2]}; + vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); + + vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], + aPnt[1] - aDelta[0][1] + aDelta[1][1], + aPnt[2] - aDelta[0][2] + aDelta[1][2]}; + vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0], + aPnt11[1] + aNormal[1], + aPnt11[2] + aNormal[2]}; + vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); + + vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], + aPnt[1] + aDelta[0][1] - aDelta[1][1], + aPnt[2] + aDelta[0][2] - aDelta[1][2]}; + vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0], + aPnt21[1] + aNormal[1], + aPnt21[2] + aNormal[2]}; + vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); + + vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; + aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]); + aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]); + aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); + aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); + } if(AutoApplyCheckBox->isChecked()) ClickOnApply(); - SMESH::RenderViewWindow(SMESH::GetCurrentVtkView()); + SMESH::RenderViewWindow( myViewWindow ); } //======================================================================= @@ -885,8 +1030,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() //======================================================================= void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled) { - std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled)); - SMESH::RenderViewWindow(SMESH::GetCurrentVtkView()); + std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(theIsToggled)); + SMESH::RenderViewWindow( myViewWindow ); } //================================================================================= @@ -904,3 +1049,124 @@ void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e ) ClickOnHelp(); } } + +//================================================================================= +// function : initializePlaneData() +// purpose : +//================================================================================= +void SMESHGUI_ClippingDlg::initializePlaneData() +{ + const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() ); + if( anIter1 != aClippingPlaneInfoMap.end() ) { + const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second; + SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin(); + for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) { + const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2; + SMESH::TPlane aTPlane( aClippingPlaneInfo.Plane ); + SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList ); + myPlanes.push_back( aPlaneData ); + } + } + std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) ); +} + +//================================================================================= +// function : updateActorList() +// purpose : +//================================================================================= +void SMESHGUI_ClippingDlg::updateActorList() +{ + ActorList->clear(); + + SalomeApp_Study* anAppStudy = SMESHGUI::activeStudy(); + if( !anAppStudy ) + return; + + _PTR(Study) aStudy = anAppStudy->studyDS(); + if( !aStudy ) + return; + + if( !myViewWindow ) + return; + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; + const SMESH::TActorList& anActorList = aPlaneData.ActorList; + + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) { + if( anActor->hasIO() ) { + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if( _PTR(SObject) aSObj = aStudy->FindObjectID( anIO->getEntry() ) ) { + bool anIsChecked = false; + SMESH::TActorList::const_iterator anIter = anActorList.begin(); + for ( ; anIter != anActorList.end(); anIter++ ) { + if( vtkActor* aVTKActorRef = *anIter ) { + if( SMESH_Actor* anActorRef = SMESH_Actor::SafeDownCast( aVTKActorRef ) ) { + if( anActorRef == anActor ) { + anIsChecked = true; + break; + } + } + } + } + QString aName = QString( aSObj->GetName().c_str() ); + QListWidgetItem* anItem = new ActorItem( anActor, aName, ActorList ); + anItem->setCheckState( anIsChecked ? Qt::Checked : Qt::Unchecked ); + updateActorItem( anItem, true, false ); + } + } + } + } +} + +//================================================================================= +// function : getCurrentActors() +// purpose : +//================================================================================= +SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors() +{ + SMESH::TActorList anActorList; + for( int i = 0, n = ActorList->count(); i < n; i++ ) + if( ActorItem* anItem = dynamic_cast( ActorList->item( i ) ) ) + if( anItem->checkState() == Qt::Checked ) + if( SMESH_Actor* anActor = anItem->getActor() ) + anActorList.push_back( anActor ); + return anActorList; +} + +//================================================================================= +// function : dumpPlaneData() +// purpose : +//================================================================================= +void SMESHGUI_ClippingDlg::dumpPlaneData() const +{ + printf( "----------- Plane Data -----------\n" ); + int anId = 1; + SMESH::TPlaneDataVector::const_iterator anIter1 = myPlanes.begin(); + for ( ; anIter1 != myPlanes.end(); anIter1++, anId++ ) { + SMESH::TPlaneData aPlaneData = *anIter1; + SMESH::TPlane aPlane = aPlaneData.Plane; + vtkFloatingPointType* aNormal = aPlane->GetNormal(); + vtkFloatingPointType* anOrigin = aPlane->GetOrigin(); + printf( "Plane N%d:\n", anId ); + printf( " Normal = ( %f, %f, %f )\n", aNormal[0], aNormal[1], aNormal[2] ); + printf( " Origin = ( %f, %f, %f )\n", anOrigin[0], anOrigin[1], anOrigin[2] ); + + SMESH::TActorList anActorList = aPlaneData.ActorList; + SMESH::TActorList::const_iterator anIter2 = anActorList.begin(); + for ( ; anIter2 != anActorList.end(); anIter2++ ) { + if( vtkActor* aVTKActor = *anIter2 ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + printf( " - Actor: '%s'\n", anActor->getName() ); + } + else + printf( " - Actor: NULL\n"); + } + } + printf( "----------------------------------\n" ); +} diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.h b/src/SMESHGUI/SMESHGUI_ClippingDlg.h index af9829762..70bd03b89 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.h +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ClippingDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -34,31 +35,91 @@ // Qt includes #include +#include // VTK includes +#include #include // STL includes +#include +#include #include class QLabel; class QPushButton; class QCheckBox; class QComboBox; -class LightApp_SelectionMgr; -class SVTK_Selector; +class QListWidget; +class QListWidgetItem; +class SALOME_Actor; class SMESHGUI; class SMESH_Actor; -class OrientedPlane; class SMESHGUI_SpinBox; +class vtkActor; +class vtkDataSetMapper; +class vtkPlaneSource; namespace SMESH { - typedef vtkSmartPointer TVTKPlane; - typedef std::vector TPlanes; enum Orientation { XY, YZ, ZX }; -}; + class OrientedPlane: public vtkPlane + { + QPointer myViewWindow; + vtkDataSetMapper* myMapper; + + public: + static OrientedPlane *New(); + static OrientedPlane *New(SVTK_ViewWindow* theViewWindow); + vtkTypeMacro (OrientedPlane, vtkPlane); + + SMESH::Orientation myOrientation; + float myDistance; + double myAngle[2]; + + vtkPlaneSource* myPlaneSource; + SALOME_Actor *myActor; + + void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; } + SMESH::Orientation GetOrientation() { return myOrientation; } + + void SetDistance (float theDistance) { myDistance = theDistance; } + float GetDistance() { return myDistance; } + + void ShallowCopy (OrientedPlane* theOrientedPlane); + + protected: + OrientedPlane(SVTK_ViewWindow* theViewWindow); + OrientedPlane(); + + void Init(); + + ~OrientedPlane(); + private: + // Not implemented. + OrientedPlane (const OrientedPlane&); + void operator= (const OrientedPlane&); + }; + + typedef vtkSmartPointer TPlane; + typedef std::list TActorList; + + struct TPlaneData + { + TPlaneData( TPlane thePlane, + TActorList theActorList ) + { + Plane = thePlane; + ActorList = theActorList; + } + TPlane Plane; + TActorList ActorList; + }; + + typedef std::vector TPlaneVector; + typedef std::vector TPlaneDataVector; +}; //================================================================================= // class : SMESHGUI_ClippingDlg @@ -69,7 +130,7 @@ class SMESHGUI_EXPORT SMESHGUI_ClippingDlg : public QDialog Q_OBJECT public: - SMESHGUI_ClippingDlg( SMESHGUI* ); + SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* ); ~SMESHGUI_ClippingDlg(); double getDistance() const; @@ -77,35 +138,42 @@ public: double getRotation1() const; double getRotation2() const; void setRotation( const double, const double ); - void Sinchronize(); // used in SMESHGUI::restoreVisualParameters() to avoid // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx - static void AddPlane (SMESH_Actor* theActor, - SVTK_ViewWindow* theViewWindow, - SMESH::Orientation theOrientation, - double theDistance, - vtkFloatingPointType theAngle[2]); - - static void GetPlaneParam (SMESH_Actor* theActor, - int thePlaneIndex, - SMESH::Orientation& theOrientation, - double& theDistance, - vtkFloatingPointType* theAngle); + static SMESH::OrientedPlane* AddPlane (SMESH::TActorList theActorList, + SVTK_ViewWindow* theViewWindow, + SMESH::Orientation theOrientation, + double theDistance, + const vtkFloatingPointType theAngle[2]); protected: void keyPressEvent( QKeyEvent* ); private: - LightApp_SelectionMgr* mySelectionMgr; - SVTK_Selector* mySelector; + void initializePlaneData(); + + void synchronize(); + + void updateActorList(); + SMESH::TActorList getCurrentActors(); + + void updateActorItem( QListWidgetItem* theItem, + bool theUpdateSelectAll, + bool theUpdateClippingPlaneMap ); + + void dumpPlaneData() const; + +private: SMESHGUI* mySMESHGUI; - SMESH_Actor* myActor; - SMESH::TPlanes myPlanes; + SVTK_ViewWindow* myViewWindow; + SMESH::TPlaneDataVector myPlanes; QComboBox* ComboBoxPlanes; QPushButton* buttonNew; QPushButton* buttonDelete; + QListWidget* ActorList; + QCheckBox* SelectAllCheckBox; QLabel* TextLabelOrientation; QComboBox* ComboBoxOrientation; QLabel* TextLabelDistance; @@ -128,9 +196,10 @@ public slots: void onSelectPlane( int ); void ClickOnNew(); void ClickOnDelete(); + void onActorItemChanged( QListWidgetItem* ); + void onSelectAll( int ); void onSelectOrientation( int ); void SetCurrentPlaneParam(); - void onSelectionChanged(); void OnPreviewToggle( bool ); void ClickOnOk(); void ClickOnCancel(); diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index 147a6a464..0bb2fa5ef 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_ComputeDlg.cxx // Author : Edward AGAPOV, Open CASCADE S.A.S. // SMESH includes @@ -29,8 +27,12 @@ #include "SMESHGUI_GEOMGenUtils.h" #include "SMESHGUI_MeshUtils.h" #include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshInfosBox.h" #include "SMESHGUI_HypothesesUtils.h" #include "SMESHGUI_MeshEditPreview.h" +#include "SMESHGUI_MeshOrderOp.h" +#include "SMESHGUI_MeshOrderDlg.h" + #include "SMESH_ActorUtils.h" #include @@ -83,6 +85,8 @@ #include #include #include +#include +#include // VTK includes #include @@ -96,6 +100,7 @@ #define COLONIZE(str) (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" ) +/* OBSOLETE static void addSeparator( QWidget* parent ) { QGridLayout* l = qobject_cast( parent->layout() ); @@ -107,6 +112,7 @@ static void addSeparator( QWidget* parent ) l->addWidget( hline, row, i ); } } +*/ enum TCol { COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS @@ -339,10 +345,13 @@ namespace SMESH CASE2TEXT( COMPERR_EXCEPTION ); CASE2TEXT( COMPERR_MEMORY_PB ); CASE2TEXT( COMPERR_BAD_SHAPE ); + CASE2TEXT( COMPERR_CANCELED ); case SMESH::COMPERR_ALGO_FAILED: if ( strlen(comment) == 0 ) text = QObject::tr("COMPERR_ALGO_FAILED"); break; + case SMESH::COMPERR_WARNING: + return comment ? QString(comment) : QObject::tr("COMPERR_UNKNOWN"); default: text = QString("#%1").arg( -errCode ); } @@ -351,7 +360,7 @@ namespace SMESH } // ----------------------------------------------------------------------- /*! - * \brief Return SO of a subshape + * \brief Return SO of a sub-shape */ _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape) { @@ -376,7 +385,7 @@ namespace SMESH } // ----------------------------------------------------------------------- /*! - * \brief Return subshape by ID + * \brief Return sub-shape by ID */ GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape) { @@ -414,7 +423,7 @@ namespace SMESH } // ----------------------------------------------------------------------- /*! - * \brief Return text describing a subshape + * \brief Return text describing a sub-shape */ QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape ) { @@ -452,351 +461,20 @@ namespace SMESH } // namespace SMESH -// ========================================================================================= -/*! - * \brief Box showing mesh info - */ -// ========================================================================================= - -SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent) - : QGroupBox( tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full ) -{ - QGridLayout* l = new QGridLayout(this); - l->setMargin( MARGIN ); - l->setSpacing( SPACING ); - - QFont italic = font(); italic.setItalic(true); - QFont bold = font(); bold.setBold(true); - - QLabel* lab; - int row = 0; - - // title - lab = new QLabel( this ); - lab->setMinimumWidth(100); lab->setFont( italic ); - l->addWidget( lab, row, 0 ); - // -- - lab = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this ); - lab->setMinimumWidth(100); lab->setFont( italic ); - l->addWidget( lab, row, 1 ); - // -- - lab = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this ); - lab->setMinimumWidth(100); lab->setFont( italic ); - l->addWidget( lab, row, 2 ); - // -- - lab = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this ); - lab->setMinimumWidth(100); lab->setFont( italic ); - l->addWidget( lab, row, 3 ); - - if ( myFull ) - { - // nodes - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ); - lab->setFont( bold ); - l->addWidget( lab, row, 0 ); - // -- - myNbNode = new QLabel( this ); - l->addWidget( myNbNode, row, 1 ); - - addSeparator(this); // add separator - - // edges - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ); - lab->setFont( bold ); - l->addWidget( lab, row, 0 ); - // -- - myNbEdge = new QLabel( this ); - l->addWidget( myNbEdge, row, 1 ); - // -- - myNbLinEdge = new QLabel( this ); - l->addWidget( myNbLinEdge, row, 2 ); - // -- - myNbQuadEdge = new QLabel( this ); - l->addWidget( myNbQuadEdge, row, 3 ); - - addSeparator(this); // add separator - - // faces - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this); - lab->setFont( bold ); - l->addWidget( lab, row, 0 ); - // -- - myNbFace = new QLabel( this ); - l->addWidget( myNbFace, row, 1 ); - // -- - myNbLinFace = new QLabel( this ); - l->addWidget( myNbLinFace, row, 2 ); - // -- - myNbQuadFace = new QLabel( this ); - l->addWidget( myNbQuadFace, row, 3 ); - // -- - row++; // increment row count - // ... triangles - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbTrai = new QLabel( this ); - l->addWidget( myNbTrai, row, 1 ); - // -- - myNbLinTrai = new QLabel( this ); - l->addWidget( myNbLinTrai, row, 2 ); - // -- - myNbQuadTrai = new QLabel( this ); - l->addWidget( myNbQuadTrai, row, 3 ); - // -- - row++; // increment row count - // ... quadrangles - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbQuad = new QLabel( this ); - l->addWidget( myNbQuad, row, 1 ); - // -- - myNbLinQuad = new QLabel( this ); - l->addWidget( myNbLinQuad, row, 2 ); - // -- - myNbQuadQuad = new QLabel( this ); - l->addWidget( myNbQuadQuad, row, 3 ); - // -- - row++; // increment row count - // ... poligones - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this ); - l->addWidget( lab, row, 0 ); - myNbPolyg = new QLabel( this ); - l->addWidget( myNbPolyg, row, 1 ); - - addSeparator(this); // add separator - - // volumes - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this); - lab->setFont( bold ); - l->addWidget( lab, row, 0 ); - // -- - myNbVolum = new QLabel( this ); - l->addWidget( myNbVolum, row, 1 ); - // -- - myNbLinVolum = new QLabel( this ); - l->addWidget( myNbLinVolum, row, 2 ); - // -- - myNbQuadVolum = new QLabel( this ); - l->addWidget( myNbQuadVolum, row, 3 ); - // -- - row++; // increment row count - // ... tetras - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbTetra = new QLabel( this ); - l->addWidget( myNbTetra, row, 1 ); - // -- - myNbLinTetra = new QLabel( this ); - l->addWidget( myNbLinTetra, row, 2 ); - // -- - myNbQuadTetra = new QLabel( this ); - l->addWidget( myNbQuadTetra, row, 3 ); - // -- - row++; // increment row count - // ... hexas - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbHexa = new QLabel( this ); - l->addWidget( myNbHexa, row, 1 ); - // -- - myNbLinHexa = new QLabel( this ); - l->addWidget( myNbLinHexa, row, 2 ); - // -- - myNbQuadHexa = new QLabel( this ); - l->addWidget( myNbQuadHexa, row, 3 ); - // -- - row++; // increment row count - // ... pyras - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbPyra = new QLabel( this ); - l->addWidget( myNbPyra, row, 1 ); - // -- - myNbLinPyra = new QLabel( this ); - l->addWidget( myNbLinPyra, row, 2 ); - // -- - myNbQuadPyra = new QLabel( this ); - l->addWidget( myNbQuadPyra, row, 3 ); - // -- - row++; // increment row count - // ... prisms - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbPrism = new QLabel( this ); - l->addWidget( myNbPrism, row, 1 ); - // -- - myNbLinPrism = new QLabel( this ); - l->addWidget( myNbLinPrism, row, 2 ); - // -- - myNbQuadPrism = new QLabel( this ); - l->addWidget( myNbQuadPrism, row, 3 ); - // -- - row++; // increment row count - // ... polyedres - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbPolyh = new QLabel( this ); - l->addWidget( myNbPolyh, row, 1 ); - } - else - { - // nodes - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbNode = new QLabel( this ); - l->addWidget( myNbNode, row, 1 ); - - // edges - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ); - l->addWidget( lab, row, 0 ); - // -- - myNbEdge = new QLabel( this ); - l->addWidget( myNbEdge, row, 1 ); - // -- - myNbLinEdge = new QLabel( this ); - l->addWidget( myNbLinEdge, row, 2 ); - // -- - myNbQuadEdge = new QLabel( this ); - l->addWidget( myNbQuadEdge, row, 3 ); - - // faces - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this); - l->addWidget( lab, row, 0 ); - // -- - myNbFace = new QLabel( this ); - l->addWidget( myNbFace, row, 1 ); - // -- - myNbLinFace = new QLabel( this ); - l->addWidget( myNbLinFace, row, 2 ); - // -- - myNbQuadFace = new QLabel( this ); - l->addWidget( myNbQuadFace, row, 3 ); - - // volumes - row = l->rowCount(); // retrieve current row count - // -- - lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this); - l->addWidget( lab, row, 0 ); - // -- - myNbVolum = new QLabel( this ); - l->addWidget( myNbVolum, row, 1 ); - // -- - myNbLinVolum = new QLabel( this ); - l->addWidget( myNbLinVolum, row, 2 ); - // -- - myNbQuadVolum = new QLabel( this ); - l->addWidget( myNbQuadVolum, row, 3 ); - } -} - -// ========================================================================================= -/*! - * \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( QWidget* parent ) +SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval ) : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ ) { QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); aDlgLay->setMargin( 0 ); aDlgLay->setSpacing( SPACING ); - QFrame* aMainFrame = createMainFrame (mainFrame()); + QFrame* aMainFrame = createMainFrame(mainFrame(),ForEval); aDlgLay->addWidget(aMainFrame); @@ -818,7 +496,7 @@ SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg() // purpose : Create frame containing dialog's fields //======================================================================= -QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) +QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval) { QFrame* aFrame = new QFrame(theParent); @@ -827,7 +505,13 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) // constructor - QGroupBox* aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame); + QGroupBox* aPixGrp; + if(ForEval) { + aPixGrp = new QGroupBox(tr("EVAL_DLG"), aFrame); + } + else { + aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame); + } QButtonGroup* aBtnGrp = new QButtonGroup(this); QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp); aPixGrpLayout->setMargin(MARGIN); aPixGrpLayout->setSpacing(SPACING); @@ -854,10 +538,11 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) // Computation errors myCompErrorGroup = new QGroupBox(tr("ERRORS"), aFrame); - myTable = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup); - myShowBtn = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup); - myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup); - myBadMeshBtn = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup); + myWarningLabel = new QLabel(QString("%1").arg(tr("COMPUTE_WARNING")), myCompErrorGroup); + myTable = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup); + myShowBtn = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup); + myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup); + myBadMeshBtn = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup); //myTable->setReadOnly( true ); // VSR: check myTable->setEditTriggers( QAbstractItemView::NoEditTriggers ); @@ -879,11 +564,12 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) QGridLayout* grpLayout = new QGridLayout(myCompErrorGroup); grpLayout->setSpacing(SPACING); grpLayout->setMargin(MARGIN); - grpLayout->addWidget( myTable, 0, 0, 4, 1 ); - grpLayout->addWidget( myShowBtn, 0, 1 ); - grpLayout->addWidget( myPublishBtn, 1, 1 ); - grpLayout->addWidget( myBadMeshBtn, 2, 1 ); - grpLayout->setRowStretch( 3, 1 ); + grpLayout->addWidget( myWarningLabel, 0, 0 ); + grpLayout->addWidget( myTable, 1, 0, 4, 1 ); + grpLayout->addWidget( myShowBtn, 1, 1 ); + grpLayout->addWidget( myPublishBtn, 2, 1 ); + grpLayout->addWidget( myBadMeshBtn, 3, 1 ); + grpLayout->setRowStretch( 4, 1 ); // Hypothesis definition errors @@ -931,8 +617,7 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) //================================================================================ SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp() - : SMESHGUI_Operation(), - myCompDlg( 0 ) + : SMESHGUI_Operation(), myCompDlg( 0 ) { myTShapeDisplayer = new SMESH::TShapeDisplayer(); myBadMeshDisplayer = 0; @@ -941,6 +626,15 @@ SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp() myHelpFileName = "about_meshes_page.html"; // V4 } +SMESH::SMESH_Mesh_ptr SMESHGUI_BaseComputeOp::getMesh() +{ + LightApp_SelectionMgr* Sel = selectionMgr(); + SALOME_ListIO selected; Sel->selectedObjects( selected ); + Handle(SALOME_InteractiveObject) anIO = selected.First(); + SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO); + return myMesh->_is_nil() ? aMesh._retn() : SMESH::SMESH_Mesh::_duplicate( myMesh ); +} + //================================================================================ /*! * \brief Start operation @@ -963,8 +657,8 @@ void SMESHGUI_BaseComputeOp::startOperation() int nbSel = selected.Extent(); if (nbSel != 1) { SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_NO_AVAILABLE_DATA")); + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_NO_AVAILABLE_DATA")); onCancel(); return; } @@ -973,16 +667,97 @@ void SMESHGUI_BaseComputeOp::startOperation() myMesh = SMESH::GetMeshByIO(myIObject); if (myMesh->_is_nil()) { SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_NO_AVAILABLE_DATA")); + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_NO_AVAILABLE_DATA")); onCancel(); - + return; } myMainShape = myMesh->GetShapeToMesh(); SMESHGUI_Operation::startOperation(); } +//================================================================================ +//================================================================================ + +SMESHGUI_ComputeDlg_QThread::SMESHGUI_ComputeDlg_QThread(SMESH::SMESH_Gen_var gen, + SMESH::SMESH_Mesh_var mesh, + GEOM::GEOM_Object_var mainShape) +{ + myResult = false; + myGen = gen; + myMesh = mesh; + myMainShape = mainShape; +} + +void SMESHGUI_ComputeDlg_QThread::run() +{ + myResult = myGen->Compute(myMesh, myMainShape); +} + +bool SMESHGUI_ComputeDlg_QThread::result() +{ + return myResult; +} + +void SMESHGUI_ComputeDlg_QThread::cancel() +{ + myGen->CancelCompute(myMesh, myMainShape); +} + +//================================================================================ +//================================================================================ + +SMESHGUI_ComputeDlg_QThreadQDialog::SMESHGUI_ComputeDlg_QThreadQDialog(QWidget *parent, + SMESH::SMESH_Gen_var gen, + SMESH::SMESH_Mesh_var mesh, + GEOM::GEOM_Object_var mainShape) + : QDialog(parent), + qthread(gen, mesh, mainShape) +{ + // -- + setWindowTitle(tr("Compute")); + cancelButton = new QPushButton(tr("Cancel")); + cancelButton->setDefault(true); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(onCancel())); + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(cancelButton); + setLayout(layout); + resize(200, 50); + // -- + startTimer(30); // 30 millisecs + qthread.start(); +} + +bool SMESHGUI_ComputeDlg_QThreadQDialog::result() +{ + return qthread.result(); +} + +void SMESHGUI_ComputeDlg_QThreadQDialog::onCancel() +{ + qthread.cancel(); +} + +void SMESHGUI_ComputeDlg_QThreadQDialog::timerEvent(QTimerEvent *event) +{ + if(qthread.isFinished()) + { + close(); + } + event->accept(); +} + +void SMESHGUI_ComputeDlg_QThreadQDialog::closeEvent(QCloseEvent *event) +{ + if(qthread.isRunning()) + { + event->ignore(); + return; + } + event->accept(); +} + //================================================================================ /*! * \brief computeMesh() @@ -1001,9 +776,11 @@ void SMESHGUI_BaseComputeOp::computeMesh() bool computeFailed = true, memoryLack = false; _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh); + if ( !aMeshSObj ) // IPAL 21340 + return; bool hasShape = myMesh->HasShapeToMesh(); bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape; - if ( shapeOK && aMeshSObj ) + if ( shapeOK ) { myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); @@ -1011,12 +788,26 @@ void SMESHGUI_BaseComputeOp::computeMesh() if ( errors->length() > 0 ) { aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() ); } + if ( myMesh->HasModificationsToDiscard() && // issue 0020693 + SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ), + tr( "FULL_RECOMPUTE_QUESTION" ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 1, 0 ) == 0 ) + myMesh->Clear(); SUIT_OverrideCursor aWaitCursor; try { #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif - if (gen->Compute(myMesh, myMainShape)) + //SMESH::UpdateNulData(myIObject, true); + bool res; +#ifdef WITH_SMESH_CANCEL_COMPUTE + SMESHGUI_ComputeDlg_QThreadQDialog qthreaddialog(desktop(), gen, myMesh, myMainShape); + qthreaddialog.exec(); + res = qthreaddialog.result(); +#else + res = gen->Compute(myMesh, myMainShape); +#endif + if (res) computeFailed = false; } catch(const SALOME::SALOME_Exception & S_ex){ @@ -1035,6 +826,10 @@ void SMESHGUI_BaseComputeOp::computeMesh() memoryLack = true; } + if ( !memoryLack && !SMDS_Mesh::CheckMemory(true) ) { // has memory to show dialog boxes? + memoryLack = true; + } + // NPAL16631: if ( !memoryLack ) { SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0); @@ -1042,32 +837,45 @@ void SMESHGUI_BaseComputeOp::computeMesh() // SHOW MESH // NPAL16631: if ( getSMESHGUI()->automaticUpdate() ) - if ( !memoryLack && getSMESHGUI()->automaticUpdate() ) + SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() ); + long newSize = myMesh->NbElements(); + bool limitExceeded; + if ( !memoryLack ) { - try { + if ( getSMESHGUI()->automaticUpdate( newSize, &limitExceeded ) ) + { + try { #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 - OCC_CATCH_SIGNALS; + OCC_CATCH_SIGNALS; #endif - SMESH::Update(myIObject, true); - } - catch (...) { + SMESH::Update(myIObject, true); + } + catch (...) { #ifdef _DEBUG_ - MESSAGE ( "Exception thrown during mesh visualization" ); + MESSAGE ( "Exception thrown during mesh visualization" ); #endif - if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning? - SMESH::OnVisuException(); - } - else { - memoryLack = true; + if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning? + SMESH::OnVisuException(); + } + else { + memoryLack = true; + } } } + else if ( limitExceeded ) + { + long limitSize = resMgr->integerValue( "SMESH", "update_limit", 500000 ); + SUIT_MessageBox::warning( desktop(), + tr( "SMESH_WRN_WARNING" ), + tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( newSize ).arg( limitSize ) ); + } } LightApp_SelectionMgr *Sel = selectionMgr(); if ( Sel ) { - SALOME_ListIO selected; - selected.Append( myIObject ); - Sel->setSelectedObjects( selected ); + SALOME_ListIO selected; + selected.Append( myIObject ); + Sel->setSelectedObjects( selected ); } } } @@ -1110,10 +918,10 @@ void SMESHGUI_BaseComputeOp::computeMesh() } void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, - const bool theNoCompError, - SMESH::compute_error_array_var& theCompErrors, - const bool theNoHypoError, - const QString& theHypErrors ) + const bool theNoCompError, + SMESH::compute_error_array_var& theCompErrors, + const bool theNoHypoError, + const QString& theHypErrors ) { bool hasShape = myMesh->HasShapeToMesh(); SMESHGUI_ComputeDlg* aCompDlg = computeDlg(); @@ -1129,7 +937,8 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, } else if ( theNoCompError && theNoHypoError ) { - aCompDlg->myFullInfo->SetInfoByMesh( myMesh ); + SMESH::long_array_var aRes = myMesh->GetMeshInfo(); + aCompDlg->myFullInfo->SetMeshInfo( aRes ); aCompDlg->myFullInfo->show(); aCompDlg->myBriefInfo->hide(); aCompDlg->myHypErrorGroup->hide(); @@ -1137,25 +946,44 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, } else { - QTableWidget* tbl = aCompDlg->myTable; - aCompDlg->myBriefInfo->SetInfoByMesh( myMesh ); - aCompDlg->myBriefInfo->show(); - aCompDlg->myFullInfo->hide(); + bool onlyWarnings = !theNoCompError; // == valid mesh computed but there are errors reported + for ( int i = 0; i < theCompErrors->length() && onlyWarnings; ++i ) + onlyWarnings = ( theCompErrors[ i ].code == SMESH::COMPERR_WARNING ); + + // full or brief mesh info + SMESH::long_array_var aRes = myMesh->GetMeshInfo(); + if ( onlyWarnings ) { + aCompDlg->myFullInfo->SetMeshInfo( aRes ); + aCompDlg->myFullInfo->show(); + aCompDlg->myBriefInfo->hide(); + } else { + aCompDlg->myBriefInfo->SetMeshInfo( aRes ); + aCompDlg->myBriefInfo->show(); + aCompDlg->myFullInfo->hide(); + } + // pbs of hypo dfinitions if ( theNoHypoError ) { aCompDlg->myHypErrorGroup->hide(); - } - else { + } else { aCompDlg->myHypErrorGroup->show(); aCompDlg->myHypErrorLabel->setText( theHypErrors ); } - if ( theNoCompError ) { + // table of errors + if ( theNoCompError ) + { aCompDlg->myCompErrorGroup->hide(); } - else { + else + { aCompDlg->myCompErrorGroup->show(); + if ( onlyWarnings ) + aCompDlg->myWarningLabel->show(); + else + aCompDlg->myWarningLabel->hide(); + if ( !hasShape ) { aCompDlg->myPublishBtn->hide(); aCompDlg->myShowBtn->hide(); @@ -1166,6 +994,7 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, } // fill table of errors + QTableWidget* tbl = aCompDlg->myTable; tbl->setRowCount( theCompErrors->length() ); if ( !hasShape ) tbl->hideColumn( COL_SHAPE ); else tbl->showColumn( COL_SHAPE ); @@ -1176,29 +1005,29 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, { SMESH::ComputeError & err = theCompErrors[ row ]; - QString text = err.algoName.in(); - if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) ); - else tbl->item( row, COL_ALGO )->setText( text ); + QString text = err.algoName.in(); + if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_ALGO )->setText( text ); - text = SMESH::errorText( err.code, err.comment.in() ); - if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) ); - else tbl->item( row, COL_ERROR )->setText( text ); + text = SMESH::errorText( err.code, err.comment.in() ); + if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_ERROR )->setText( text ); - text = QString("%1").arg( err.subShapeID ); - if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) ); - else tbl->item( row, COL_SHAPEID )->setText( text ); + text = QString("%1").arg( err.subShapeID ); + if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_SHAPEID )->setText( text ); text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString(""); - if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) ); - else tbl->item( row, COL_SHAPE )->setText( text ); + if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_SHAPE )->setText( text ); text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : ""; - if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) ); - else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled + if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled text = err.hasBadMesh ? "hasBadMesh" : ""; - if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) ); - else tbl->item( row, COL_BAD_MESH )->setText( text ); + if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_BAD_MESH )->setText( text ); if ( err.hasBadMesh ) hasBadMesh = true; //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ??? @@ -1244,7 +1073,7 @@ void SMESHGUI_BaseComputeOp::stopOperation() //================================================================================ /*! - * \brief publish selected subshape + * \brief publish selected sub-shape */ //================================================================================ @@ -1420,7 +1249,7 @@ SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const if ( !myCompDlg ) { SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this; - me->myCompDlg = new SMESHGUI_ComputeDlg( desktop() ); + me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), false ); // connect signals and slots connect(myCompDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape())); connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape())); @@ -1433,6 +1262,17 @@ SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const return myCompDlg; } +//================================================================================ +/*! + * \brief returns from compute mesh result dialog + */ +//================================================================================ + +bool SMESHGUI_BaseComputeOp::onApply() +{ + return true; +} + //================================================================================ /*! * \brief Return a table @@ -1476,18 +1316,26 @@ SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp() void SMESHGUI_ComputeOp::startOperation() { SMESHGUI_BaseComputeOp::startOperation(); + if (myMesh->_is_nil()) + return; computeMesh(); } //================================================================================ /*! - * \brief perform it's intention action: compute mesh + * \brief check the same operations on the same mesh */ //================================================================================ -bool SMESHGUI_ComputeOp::onApply() +bool SMESHGUI_BaseComputeOp::isValid( SUIT_Operation* theOp ) const { - return true; + SMESHGUI_BaseComputeOp* baseOp = dynamic_cast( theOp ); + bool ret = true; + if ( !myMesh->_is_nil() && baseOp ) { + SMESH::SMESH_Mesh_var aMesh = baseOp->getMesh(); + if ( !aMesh->_is_nil() && aMesh->GetId() == myMesh->GetId() ) ret = false; + } + return ret; } //================================================================================ @@ -1511,10 +1359,11 @@ LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp() : SMESHGUI_BaseComputeOp(), myDlg( 0 ), + myOrderMgr( 0 ), myActiveDlg( 0 ), myPreviewDisplayer( 0 ) { - myHelpFileName = "preview_meshes_page.html"; // V4 + myHelpFileName = "constructing_meshes_page.html#preview_mesh_anchor"; } //================================================================================ @@ -1527,6 +1376,8 @@ SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp() { delete myDlg; myDlg = 0; + delete myOrderMgr; + myOrderMgr = 0; myActiveDlg = 0; if ( myPreviewDisplayer ) delete myPreviewDisplayer; @@ -1559,6 +1410,8 @@ void SMESHGUI_PrecomputeOp::startOperation() // connect signals connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) ); + connect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onCompute() ) ); + connect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onCompute() ) ); } myActiveDlg = myDlg; @@ -1587,6 +1440,22 @@ void SMESHGUI_PrecomputeOp::startOperation() } SMESHGUI_BaseComputeOp::startOperation(); + if (myMesh->_is_nil()) + return; + + if (myDlg->getPreviewMode() == -1) + { + // nothing to preview + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_NOTHING_PREVIEW")); + onCancel(); + return; + } + + // disconnect slot from preview dialog to have Apply from results of compute operation only + disconnect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) ); + disconnect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) ); myDlg->show(); } @@ -1611,7 +1480,7 @@ void SMESHGUI_PrecomputeOp::stopOperation() //================================================================================ /*! - * \brief perform it's intention action: reinitialise dialog + * \brief reinitialize dialog after operaiton become active again */ //================================================================================ @@ -1622,16 +1491,57 @@ void SMESHGUI_PrecomputeOp::resumeOperation() SMESHGUI_BaseComputeOp::resumeOperation(); } +//================================================================================ +/*! + * \brief perform it's intention action: reinitialise dialog + */ +//================================================================================ + void SMESHGUI_PrecomputeOp::initDialog() { QList modes; + QMap modeMap; + _PTR(SObject) pMesh = studyDS()->FindObjectID( myIObject->getEntry() ); + getAssignedAlgos( pMesh, modeMap ); + if ( modeMap.contains( SMESH::DIM_3D ) ) + { + if ( modeMap.contains( SMESH::DIM_2D ) ) + modes.append( SMESH::DIM_2D ); + if ( modeMap.contains( SMESH::DIM_1D ) ) + modes.append( SMESH::DIM_1D ); + } + else if ( modeMap.contains( SMESH::DIM_2D ) ) + { + if ( modeMap.contains( SMESH::DIM_1D ) ) + modes.append( SMESH::DIM_1D ); + } + + myOrderMgr = new SMESHGUI_MeshOrderMgr( myDlg->getMeshOrderBox() ); + myOrderMgr->SetMesh( myMesh ); + bool isOrder = myOrderMgr->GetMeshOrder(myPrevOrder); + myDlg->getMeshOrderBox()->setShown(isOrder); + if ( !isOrder ) { + delete myOrderMgr; + myOrderMgr = 0; + } + + myDlg->setPreviewModes( modes ); +} + +//================================================================================ +/*! + * \brief detect asigned mesh algorithms + */ +//================================================================================ + +void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh, + QMap& theModeMap) +{ _PTR(SObject) aHypRoot; _PTR(GenericAttribute) anAttr; int aPart = SMESH::Tag_RefOnAppliedAlgorithms; - - _PTR(SObject) pMesh = studyDS()->FindObjectID( myIObject->getEntry() ); - if ( pMesh && pMesh->FindSubObject( aPart, aHypRoot ) ) + if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) ) { _PTR(ChildIterator) anIter = SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot ); @@ -1649,50 +1559,38 @@ void SMESHGUI_PrecomputeOp::initDialog() CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject(); if ( CORBA::is_nil( aVar ) ) continue; - - SMESH::SMESH_Algo_var algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); - if ( !algo->_is_nil() ) - { - modeMap[ SMESH::DIM_1D ] = 0; - modeMap[ SMESH::DIM_2D ] = 0; - } - else + + for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ ) { - algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); + SMESH::SMESH_Algo_var algo; + switch(dim) { + case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break; + case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break; + case SMESH::DIM_3D: algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); break; + default: break; + } if ( !algo->_is_nil() ) - modeMap[ SMESH::DIM_2D ] = 0; + theModeMap[ dim ] = 0; } } } } - if ( modeMap.contains( SMESH::DIM_1D ) ) - modes.append( SMESH::DIM_1D ); - if ( modeMap.contains( SMESH::DIM_2D ) ) - modes.append( SMESH::DIM_2D ); - - myDlg->setPreviewModes( modes ); } //================================================================================ /*! - * \brief perform it's intention action: + * \brief perform it's intention action: compute mesh */ //================================================================================ -bool SMESHGUI_PrecomputeOp::onApply() +void SMESHGUI_PrecomputeOp::onCompute() { - QObject* obj = sender(); - if ( obj != myDlg && myActiveDlg == myDlg ) - return true; // just return from error messages - if ( myActiveDlg == myDlg ) - { - myDlg->hide(); - myMapShapeId.clear(); - myActiveDlg = computeDlg(); - computeMesh(); - } - - return true; + myDlg->hide(); + if (myOrderMgr && myOrderMgr->IsOrderChanged()) + myOrderMgr->SetMeshOrder(); + myMapShapeId.clear(); + myActiveDlg = computeDlg(); + computeMesh(); } //================================================================================ @@ -1704,14 +1602,14 @@ bool SMESHGUI_PrecomputeOp::onApply() void SMESHGUI_PrecomputeOp::onCancel() { QObject* curDlg = sender(); - if ( curDlg == computeDlg() ) + if ( curDlg == computeDlg() && myActiveDlg == myDlg ) { - if ( myActiveDlg == myDlg ) // return from error messages - myDlg->show(); - + // return from error messages + myDlg->show(); return; } + bool isRestoreOrder = false; if ( myActiveDlg == myDlg && !myMesh->_is_nil() && myMapShapeId.count() ) { // ask to remove already computed mesh elements @@ -1723,8 +1621,24 @@ void SMESHGUI_PrecomputeOp::onCancel() QMap::const_iterator it = myMapShapeId.constBegin(); for ( ; it != myMapShapeId.constEnd(); ++it ) myMesh->ClearSubMesh( *it ); + isRestoreOrder = true; } } + + // return previous mesh order + if (myOrderMgr && myOrderMgr->IsOrderChanged()) { + if (!isRestoreOrder) + isRestoreOrder = + (SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ), + tr( "SMESH_REJECT_MESH_ORDER" ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0); + if (isRestoreOrder) + myOrderMgr->SetMeshOrder(myPrevOrder); + } + + delete myOrderMgr; + myOrderMgr = 0; + myMapShapeId.clear(); SMESHGUI_BaseComputeOp::onCancel(); } @@ -1743,6 +1657,11 @@ void SMESHGUI_PrecomputeOp::onPreview() _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh); if ( !aMeshSObj ) return; + + // set modified submesh priority if any + if (myOrderMgr && myOrderMgr->IsOrderChanged()) + myOrderMgr->SetMeshOrder(); + // Compute preview of mesh, // i.e. compute mesh till indicated dimension int dim = myDlg->getPreviewMode(); @@ -1778,6 +1697,7 @@ void SMESHGUI_PrecomputeOp::onPreview() SMESH::MeshPreviewStruct_var previewData = gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId); + SMESH::MeshPreviewStruct* previewRes = previewData._retn(); if ( previewRes && previewRes->nodesXYZ.length() > 0 ) { @@ -1785,7 +1705,7 @@ void SMESHGUI_PrecomputeOp::onPreview() myPreviewDisplayer->SetData( previewRes ); // append shape indeces with computed mesh entities for ( int i = 0, n = aShapesId->length(); i < n; i++ ) - myMapShapeId[ aShapesId[ i ] ] = 0; + myMapShapeId[ aShapesId[ i ] ] = 0; } else myPreviewDisplayer->SetVisibility(false); @@ -1847,7 +1767,8 @@ void SMESHGUI_PrecomputeOp::onPreview() //================================================================================ SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent ) - : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help ) + : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help ), + myOrderBox(0) { setWindowTitle( tr( "CAPTION" ) ); @@ -1856,6 +1777,9 @@ SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent ) QVBoxLayout* layout = new QVBoxLayout( main ); + myOrderBox = new SMESHGUI_MeshOrderBox( main ); + layout->addWidget(myOrderBox); + QFrame* frame = new QFrame( main ); layout->setMargin(0); layout->setSpacing(0); layout->addWidget( frame ); @@ -1911,3 +1835,292 @@ int SMESHGUI_PrecomputeDlg::getPreviewMode() const { return myPreviewMode->currentId(); } + +//================================================================================ +/*! + * \brief Returns current preview mesh mode +*/ +//================================================================================ + +SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const +{ + return myOrderBox; +} + + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp() + : SMESHGUI_BaseComputeOp() +{ +} + + +//================================================================================ +/*! + * \brief Desctructor +*/ +//================================================================================ + +SMESHGUI_EvaluateOp::~SMESHGUI_EvaluateOp() +{ +} + +//================================================================================ +/*! + * \brief perform it's intention action: compute mesh + */ +//================================================================================ + +void SMESHGUI_EvaluateOp::startOperation() +{ + SMESHGUI_BaseComputeOp::evaluateDlg(); + SMESHGUI_BaseComputeOp::startOperation(); + if (myMesh->_is_nil()) + return; + evaluateMesh(); +} + +//================================================================================ +/*! + * \brief Gets dialog of this operation + * \retval LightApp_Dialog* - pointer to dialog of this operation + */ +//================================================================================ + +LightApp_Dialog* SMESHGUI_EvaluateOp::dlg() const +{ + return evaluateDlg(); +} + +//================================================================================ +/*! + * \brief evaluateMesh() +*/ +//================================================================================ + +void SMESHGUI_BaseComputeOp::evaluateMesh() +{ + // EVALUATE MESH + + SMESH::MemoryReserve aMemoryReserve; + + SMESH::compute_error_array_var aCompErrors; + QString aHypErrors; + + bool evaluateFailed = true, memoryLack = false; + SMESH::long_array_var aRes; + + _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh); + if ( !aMeshSObj ) // IPAL21340 + return; + + bool hasShape = myMesh->HasShapeToMesh(); + bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape; + if ( shapeOK ) + { + myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() ); + SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); + SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape); + if ( errors->length() > 0 ) { + aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() ); + } + SUIT_OverrideCursor aWaitCursor; + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + aRes = gen->Evaluate(myMesh, myMainShape); + } + catch(const SALOME::SALOME_Exception & S_ex){ + memoryLack = true; + } + + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + aCompErrors = gen->GetComputeErrors( myMesh, myMainShape ); + } + catch(const SALOME::SALOME_Exception & S_ex){ + memoryLack = true; + } + } + + if ( memoryLack ) + aMemoryReserve.release(); + + evaluateFailed = ( aCompErrors->length() > 0 ); + myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_EVALUATE_FAILED" : "SMESH_EVALUATE_SUCCEED")); + + // SHOW ERRORS + + bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 ); + bool noHypoError = ( aHypErrors.isEmpty() ); + + //SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() ); + //int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" ); + + bool isShowResultDlg = true; + //if( noHypoError ) + //switch( aNotifyMode ) { + //case 0: // show the mesh computation result dialog NEVER + //isShowResultDlg = false; + //commit(); + //break; + //case 1: // show the mesh computation result dialog if there are some errors + //if ( memoryLack || !noHypoError ) + // isShowResultDlg = true; + //else + //{ + // isShowResultDlg = false; + // commit(); + //} + //break; + //default: // show the result dialog after each mesh computation + //isShowResultDlg = true; + //} + + // SHOW RESULTS + if ( isShowResultDlg ) + showEvaluateResult( aRes, memoryLack, noCompError, aCompErrors, + noHypoError, aHypErrors); +} + + +void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes, + const bool theMemoryLack, + const bool theNoCompError, + SMESH::compute_error_array_var& theCompErrors, + const bool theNoHypoError, + const QString& theHypErrors) +{ + bool hasShape = myMesh->HasShapeToMesh(); + SMESHGUI_ComputeDlg* aCompDlg = evaluateDlg(); + aCompDlg->myMemoryLackGroup->hide(); + + if ( theMemoryLack ) + { + aCompDlg->myMemoryLackGroup->show(); + aCompDlg->myFullInfo->hide(); + aCompDlg->myBriefInfo->hide(); + aCompDlg->myHypErrorGroup->hide(); + aCompDlg->myCompErrorGroup->hide(); + } + else if ( theNoCompError && theNoHypoError ) + { + aCompDlg->myFullInfo->SetMeshInfo( theRes ); + aCompDlg->myFullInfo->show(); + aCompDlg->myBriefInfo->hide(); + aCompDlg->myHypErrorGroup->hide(); + aCompDlg->myCompErrorGroup->hide(); + } + else + { + QTableWidget* tbl = aCompDlg->myTable; + aCompDlg->myBriefInfo->SetMeshInfo( theRes ); + aCompDlg->myBriefInfo->show(); + aCompDlg->myFullInfo->hide(); + + if ( theNoHypoError ) { + aCompDlg->myHypErrorGroup->hide(); + } + else { + aCompDlg->myHypErrorGroup->show(); + aCompDlg->myHypErrorLabel->setText( theHypErrors ); + } + + if ( theNoCompError ) { + aCompDlg->myCompErrorGroup->hide(); + } + else { + aCompDlg->myCompErrorGroup->show(); + + aCompDlg->myPublishBtn->hide(); + aCompDlg->myShowBtn->hide(); + + // fill table of errors + tbl->setRowCount( theCompErrors->length() ); + if ( !hasShape ) tbl->hideColumn( COL_SHAPE ); + else tbl->showColumn( COL_SHAPE ); + tbl->setColumnWidth( COL_ERROR, 200 ); + + bool hasBadMesh = false; + for ( int row = 0; row < theCompErrors->length(); ++row ) + { + SMESH::ComputeError & err = theCompErrors[ row ]; + + QString text = err.algoName.in(); + if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_ALGO )->setText( text ); + + text = SMESH::errorText( err.code, err.comment.in() ); + if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_ERROR )->setText( text ); + + text = QString("%1").arg( err.subShapeID ); + if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_SHAPEID )->setText( text ); + + text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString(""); + if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_SHAPE )->setText( text ); + + text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : ""; + if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled + + text = err.hasBadMesh ? "hasBadMesh" : ""; + if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) ); + else tbl->item( row, COL_BAD_MESH )->setText( text ); + if ( err.hasBadMesh ) hasBadMesh = true; + + //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ??? + tbl->resizeRowToContents( row ); + } + tbl->resizeColumnToContents( COL_ALGO ); + tbl->resizeColumnToContents( COL_SHAPE ); + + if ( hasBadMesh ) + aCompDlg->myBadMeshBtn->show(); + else + aCompDlg->myBadMeshBtn->hide(); + + tbl->setCurrentCell(0,0); + currentCellChanged(); // to update buttons + } + } + // show dialog and wait, becase Compute can be invoked from Preview operation + //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer + aCompDlg->show(); +} + + +//================================================================================ +/*! + * \brief Gets dialog of evaluate operation + * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation + */ +//================================================================================ + +SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::evaluateDlg() const +{ + if ( !myCompDlg ) + { + SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this; + me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), true ); + // connect signals and slots + connect(myCompDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape())); + connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape())); + connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh())); + QTableWidget* aTable = me->table(); + connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged())); + connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged())); + } + return myCompDlg; +} + diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.h b/src/SMESHGUI/SMESHGUI_ComputeDlg.h index 5ec969cc7..49aa2477c 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.h +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.h @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_ComputeDlg.h // Author : Edward AGAPOV, Open CASCADE S.A.S. // @@ -36,8 +34,10 @@ // Qt includes #include +#include #include #include +#include // IDL includes #include @@ -50,11 +50,10 @@ class QTableWidget; class QLabel; class QtxComboBox; class SMESHGUI_ComputeDlg; +class SMESHGUI_MeshInfosBox; class SMESHGUI_PrecomputeDlg; class SMESHGUI_MeshEditPreview; -class SMESH::compute_error_array; - namespace SMESH { class TShapeDisplayer; @@ -71,6 +70,8 @@ public: SMESHGUI_BaseComputeOp(); virtual ~SMESHGUI_BaseComputeOp(); + SMESH::SMESH_Mesh_ptr getMesh(); + protected: virtual void startOperation(); virtual void stopOperation(); @@ -78,12 +79,23 @@ protected: SMESHGUI_ComputeDlg* computeDlg() const; void computeMesh(); void showComputeResult( const bool, - const bool, - SMESH::compute_error_array_var&, - const bool, - const QString& ); + const bool, + SMESH::compute_error_array_var&, + const bool, + const QString& ); + SMESHGUI_ComputeDlg* evaluateDlg() const; + void evaluateMesh(); + void showEvaluateResult(const SMESH::long_array& theRes, + const bool, + const bool, + SMESH::compute_error_array_var&, + const bool, + const QString&); + + virtual bool isValid( SUIT_Operation* theOp ) const; protected slots: + virtual bool onApply(); void onPreviewShape(); void onPublishShape(); void onShowBadMesh(); @@ -120,9 +132,10 @@ protected: virtual void startOperation(); protected slots: - virtual bool onApply(); }; +class SMESHGUI_MeshOrderMgr; + /*! * \brief Operation to preview and compute a mesh and show computation errors */ @@ -136,6 +149,12 @@ public: virtual LightApp_Dialog* dlg() const; + /** + * \brief returns map of assigned algorithms modes + */ + static void getAssignedAlgos(_PTR(SObject) theMesh, + QMap& theModeMap); + protected: virtual void startOperation(); virtual void stopOperation(); @@ -144,64 +163,42 @@ protected: virtual void initDialog(); protected slots: - virtual bool onApply(); virtual void onCancel(); private slots: void onPreview(); + void onCompute(); private: + //! private fields QMap< int, int > myMapShapeId; QPointer myActiveDlg; QPointer myDlg; SMESHGUI_MeshEditPreview* myPreviewDisplayer; + //! fields for mesh order + typedef QList TListOfInt; + typedef QList TListOfListOfInt; + TListOfListOfInt myPrevOrder; + SMESHGUI_MeshOrderMgr* myOrderMgr; }; /*! - * \brief Box showing mesh info + * \brief Operation to evaluate a mesh and show result */ - -class SMESHGUI_EXPORT SMESHGUI_MeshInfosBox : public QGroupBox +class SMESHGUI_EXPORT SMESHGUI_EvaluateOp: public SMESHGUI_BaseComputeOp { Q_OBJECT public: - SMESHGUI_MeshInfosBox( const bool, QWidget* ); + SMESHGUI_EvaluateOp(); + virtual ~SMESHGUI_EvaluateOp(); - void SetInfoByMesh( SMESH::SMESH_Mesh_var ); + virtual LightApp_Dialog* dlg() const; -private: - bool myFull; - QLabel* myNbNode; - QLabel* myNbEdge; - QLabel* myNbLinEdge; - QLabel* myNbQuadEdge; - QLabel* myNbTrai; - QLabel* myNbLinTrai; - QLabel* myNbQuadTrai; - QLabel* myNbQuad; - QLabel* myNbLinQuad; - QLabel* myNbQuadQuad; - QLabel* myNbFace; - QLabel* myNbLinFace; - QLabel* myNbQuadFace; - QLabel* myNbPolyg; - QLabel* myNbHexa; - QLabel* myNbLinHexa; - QLabel* myNbQuadHexa; - QLabel* myNbTetra; - QLabel* myNbLinTetra; - QLabel* myNbQuadTetra; - QLabel* myNbPyra; - QLabel* myNbLinPyra; - QLabel* myNbQuadPyra; - QLabel* myNbPrism; - QLabel* myNbLinPrism; - QLabel* myNbQuadPrism; - QLabel* myNbVolum; - QLabel* myNbLinVolum; - QLabel* myNbQuadVolum; - QLabel* myNbPolyh; +protected: + virtual void startOperation(); + +protected slots: }; /*! @@ -213,17 +210,18 @@ class SMESHGUI_EXPORT SMESHGUI_ComputeDlg : public SMESHGUI_Dialog Q_OBJECT public: - SMESHGUI_ComputeDlg( QWidget* ); + SMESHGUI_ComputeDlg( QWidget*, bool ); virtual ~SMESHGUI_ComputeDlg(); protected: - QFrame* createMainFrame( QWidget* ); + QFrame* createMainFrame( QWidget*, bool ); QLabel* myMeshName; QGroupBox* myMemoryLackGroup; QGroupBox* myCompErrorGroup; QGroupBox* myHypErrorGroup; QLabel* myHypErrorLabel; + QLabel* myWarningLabel; QTableWidget* myTable; QPushButton* myShowBtn; QPushButton* myPublishBtn; @@ -236,6 +234,8 @@ protected: friend class SMESHGUI_PrecomputeOp; }; +class SMESHGUI_MeshOrderBox; + /*! * \brief Dialog to preview and compute a mesh and show computation errors */ @@ -250,14 +250,69 @@ public: void setPreviewModes( const QList& ); int getPreviewMode() const; + + SMESHGUI_MeshOrderBox* getMeshOrderBox() const; signals: void preview(); private: + SMESHGUI_MeshOrderBox* myOrderBox; QPushButton* myPreviewBtn; QtxComboBox* myPreviewMode; }; +/*! + * \brief Thread to launch computation + */ + +class SMESHGUI_EXPORT SMESHGUI_ComputeDlg_QThread : public QThread +{ + Q_OBJECT + +public: + SMESHGUI_ComputeDlg_QThread(SMESH::SMESH_Gen_var gen, + SMESH::SMESH_Mesh_var mesh, + GEOM::GEOM_Object_var mainShape); + bool result(); + void cancel(); + +protected: + void run(); + +private: + SMESH::SMESH_Gen_var myGen; + SMESH::SMESH_Mesh_var myMesh; + GEOM::GEOM_Object_var myMainShape; + bool myResult; +}; + +/*! + * \brief Dialog to display Cancel button + */ + +class SMESHGUI_EXPORT SMESHGUI_ComputeDlg_QThreadQDialog : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_ComputeDlg_QThreadQDialog(QWidget *parent, + SMESH::SMESH_Gen_var gen, + SMESH::SMESH_Mesh_var mesh, + GEOM::GEOM_Object_var mainShape); + bool result(); + +protected: + void timerEvent(QTimerEvent *timer); + void closeEvent(QCloseEvent *event); + +private slots: + void onCancel(); + +private: + SMESHGUI_ComputeDlg_QThread qthread; + QPushButton *cancelButton; + +}; #endif // SMESHGUI_COMPUTEDLG_H diff --git a/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.cxx b/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.cxx index 5db422cdd..b42d728ae 100644 --- a/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ConvToQuadDlg.cxx // Author : Open CASCADE S.A.S. @@ -35,6 +36,7 @@ #include #include #include +#include #define SPACING 6 #define MARGIN 11 @@ -69,6 +71,8 @@ SMESHGUI_ConvToQuadDlg::SMESHGUI_ConvToQuadDlg() myBG->addButton(myRB2, 1); myRB1->setChecked( true ); + myWarning = new QLabel(QString("%1").arg(tr("NON_CONFORM_WARNING")), mainFrame()); + // Fill layout QGridLayout* aLay = new QGridLayout( mainFrame() ); aLay->setMargin( 5 ); @@ -79,6 +83,7 @@ SMESHGUI_ConvToQuadDlg::SMESHGUI_ConvToQuadDlg() aLay->addWidget( objectWg( 0, Control ), 0, 2 ); aLay->addWidget( myMedNdsOnGeom, 1, 0, 1, 3 ); aLay->addWidget( myBGBox, 2, 0, 1, 3 ); + aLay->addWidget( myWarning, 3, 0, 1, 3 ); connect(myBG, SIGNAL( buttonClicked( int ) ), this, SIGNAL( onClicked( int ) ) ); } @@ -112,11 +117,26 @@ int SMESHGUI_ConvToQuadDlg::CurrentRB( ) return myBG->checkedId(); } +void SMESHGUI_ConvToQuadDlg::ShowWarning(bool toShow) +{ + if ( toShow ) + myWarning->show(); + else + myWarning->hide(); +} + +bool SMESHGUI_ConvToQuadDlg::isWarningShown() +{ + return myWarning->isVisible(); +} + void SMESHGUI_ConvToQuadDlg::SetEnabledControls( const bool theCheck ) { - myBGBox->setEnabled( theCheck ); + //myBGBox->setEnabled( theCheck ); + myRB1->setEnabled( theCheck ); + myRB2->setEnabled( theCheck ); myMedNdsOnGeom->setEnabled( theCheck ); - setButtonEnabled( theCheck, QtxDialog::OK | QtxDialog::Apply ); + //setButtonEnabled( theCheck, QtxDialog::OK | QtxDialog::Apply ); } void SMESHGUI_ConvToQuadDlg::SetEnabledRB( const int idx, const bool theCheck ) diff --git a/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.h b/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.h index 53240eae6..660dbc731 100644 --- a/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.h +++ b/src/SMESHGUI/SMESHGUI_ConvToQuadDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ConvToQuadDlg.h // Author : Open CASCADE S.A.S. @@ -35,6 +36,7 @@ class QCheckBox; class QRadioButton; class QButtonGroup; class QGroupBox; +class QLabel; class SMESHGUI_EXPORT SMESHGUI_ConvToQuadDlg : public SMESHGUI_Dialog { @@ -52,6 +54,8 @@ public: void SetEnabledControls( const bool ); void SetEnabledRB( const int, const bool ); int CurrentRB(); //returns the ID of the selected toggle button + void ShowWarning(bool); + bool isWarningShown(); signals: void onClicked( int ); @@ -62,6 +66,7 @@ private: QButtonGroup* myBG; QRadioButton* myRB1; QRadioButton* myRB2; + QLabel* myWarning; }; #endif // SMESHGUI_CONVTOQUADDLG_H diff --git a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx index 962b11abd..a62d0b949 100644 --- a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx +++ b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ConvToQuadOp.cxx // Author : Open CASCADE S.A.S. @@ -26,15 +27,18 @@ // #include "SMESHGUI_ConvToQuadOp.h" +#include "SMESHGUI.h" #include "SMESHGUI_ConvToQuadDlg.h" #include "SMESHGUI_Utils.h" +#include "SMDSAbs_ElementType.hxx" -#include +#include "SMESH_TypeFilter.hxx" // SALOME GUI includes -#include -#include #include +#include +#include +#include // IDL includes #include @@ -97,6 +101,7 @@ void SMESHGUI_ConvToQuadOp::startOperation() myDlg->SetMediumNdsOnGeom( false ); myDlg->activateObject( 0 ); + myDlg->ShowWarning( false ); myDlg->show(); selectionDone(); @@ -117,22 +122,26 @@ void SMESHGUI_ConvToQuadOp::selectionDone() SMESHGUI_SelectionOp::selectionDone(); try { - QString anMeshEntry = myDlg->selectedObject( 0 ); - _PTR(SObject) pMesh = studyDS()->FindObjectID( anMeshEntry.toLatin1().data() ); - if ( !pMesh ) return; + QString anObjEntry = myDlg->selectedObject( 0 ); + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); + if ( !pObj ) return; - SMESH::SMESH_Mesh_var mesh = - SMESH::SObjectToInterface( pMesh ); + SMESH::SMESH_IDSource_var idSource = + SMESH::SObjectToInterface( pObj ); - if( mesh->_is_nil() ) + myDlg->setButtonEnabled( true, QtxDialog::OK | QtxDialog::Apply ); + if( idSource->_is_nil() ) { myDlg->SetEnabledControls( false ); + myDlg->setButtonEnabled( false, QtxDialog::OK | QtxDialog::Apply ); + return; } - else if( ConsistMesh( mesh ) == SMESHGUI_ConvToQuadOp::Quadratic ) + MeshType meshType = ConsistMesh( idSource ); + if( meshType == SMESHGUI_ConvToQuadOp::Quadratic ) { myDlg->SetEnabledRB( 0, false ); } - else if( ConsistMesh( mesh ) == SMESHGUI_ConvToQuadOp::Linear ) + else if( meshType == SMESHGUI_ConvToQuadOp::Linear ) { myDlg->SetEnabledRB( 1, false ); } @@ -140,6 +149,22 @@ void SMESHGUI_ConvToQuadOp::selectionDone() { myDlg->SetEnabledControls( true ); } + + // show warning on non-conformal result mesh + if ( ! idSource->_is_nil() ) + { + SMESH::SMESH_subMesh_var subMesh = + SMESH::SObjectToInterface( pObj ); + bool toShow = false; + if ( !subMesh->_is_nil() ) + { + SMESH::SMESH_Mesh_var mesh = idSource->GetMesh(); + idSource = SMESH::SMESH_IDSource::_narrow( mesh ); + MeshType fullMeshType = ConsistMesh( idSource ); + toShow = ( fullMeshType != Comp ); + } + myDlg->ShowWarning( toShow ); + } } catch ( const SALOME::SALOME_Exception& S_ex ) { @@ -162,7 +187,7 @@ void SMESHGUI_ConvToQuadOp::selectionDone() SUIT_SelectionFilter* SMESHGUI_ConvToQuadOp::createFilter( const int theId ) const { if ( theId == 0 ) - return new SMESH_TypeFilter( MESH ); + return new SMESH_TypeFilter( MESHorSUBMESH ); else return 0; } @@ -176,48 +201,57 @@ SUIT_SelectionFilter* SMESHGUI_ConvToQuadOp::createFilter( const int theId ) con //================================================================================ bool SMESHGUI_ConvToQuadOp::onApply() { + SUIT_OverrideCursor aWaitCursor; QString aMess; - QString anMeshEntry = myDlg->selectedObject( 0 ); - _PTR(SObject) pMesh = studyDS()->FindObjectID( anMeshEntry.toLatin1().data() ); - if ( !pMesh ) + QString anObjEntry = myDlg->selectedObject( 0 ); + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); + if ( !pObj ) { dlg()->show(); SUIT_MessageBox::warning( myDlg, - tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") ); - + tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") ); return false; } - SMESH::SMESH_Mesh_var mesh = - SMESH::SObjectToInterface( pMesh ); + SMESH::SMESH_Mesh_var mesh; + SMESH::SMESH_IDSource_var idSource = + SMESH::SObjectToInterface( pObj ); + if( !CORBA::is_nil(idSource) ) + mesh = idSource->GetMesh(); if( CORBA::is_nil(mesh) ) { SUIT_MessageBox::warning( myDlg, - tr( "SMESH_WRN_WARNING" ), tr("REF_IS_NULL") ); - + tr( "SMESH_WRN_WARNING" ), tr("REF_IS_NULL") ); return false; - } + } bool aResult = false; try { SMESH::SMESH_MeshEditor_var aEditor = mesh->GetMeshEditor(); + aResult = true; + SMESH::SMESH_Mesh_var sourceMesh = SMESH::SObjectToInterface( pObj ); if( !myDlg->CurrentRB() ) { bool aParam = true; if( myDlg->IsEnabledCheck() ) - aParam = myDlg->IsMediumNdsOnGeom(); + aParam = myDlg->IsMediumNdsOnGeom(); - aEditor->ConvertToQuadratic( aParam ); - aResult = true; + if ( sourceMesh->_is_nil() ) + aEditor->ConvertToQuadraticObject( aParam, idSource ); + else + aEditor->ConvertToQuadratic( aParam ); } else { - aResult = aEditor->ConvertFromQuadratic(); + if ( sourceMesh->_is_nil() ) + aEditor->ConvertFromQuadraticObject( idSource ); + else + aEditor->ConvertFromQuadratic(); } } catch ( const SALOME::SALOME_Exception& S_ex ) @@ -231,6 +265,7 @@ bool SMESHGUI_ConvToQuadOp::onApply() } if( aResult ) { + SMESHGUI::Modified(); update( UF_ObjBrowser | UF_Model | UF_Viewer ); selectionDone(); } @@ -242,42 +277,43 @@ bool SMESHGUI_ConvToQuadOp::onApply() * Determines, what elements this mesh contains. */ //================================================================================ -SMESHGUI_ConvToQuadOp::MeshType SMESHGUI_ConvToQuadOp::ConsistMesh( const SMESH::SMESH_Mesh_var& mesh) const +SMESHGUI_ConvToQuadOp::MeshType SMESHGUI_ConvToQuadOp::ConsistMesh( const SMESH::SMESH_IDSource_var& idSource) const { - int nbAllElem = 0, nbQEdges =0, nbQFaces =0, nbQVolum = 0; - int nbEdges = 0, nbFaces = 0, nbVolum = 0; - - nbAllElem = (int)mesh->NbElements(); - nbQEdges = (int)mesh->NbEdgesOfOrder(SMESH::ORDER_QUADRATIC); - nbQFaces = (int)mesh->NbFacesOfOrder(SMESH::ORDER_QUADRATIC); - nbQVolum = (int)mesh->NbVolumesOfOrder(SMESH::ORDER_QUADRATIC); - - nbEdges = (int)mesh->NbEdgesOfOrder(SMESH::ORDER_LINEAR); - nbFaces = (int)mesh->NbFacesOfOrder(SMESH::ORDER_LINEAR); - nbVolum = (int)mesh->NbVolumesOfOrder(SMESH::ORDER_LINEAR); - - if( nbAllElem == (nbQEdges+nbQFaces+nbQVolum) ) - return SMESHGUI_ConvToQuadOp::Quadratic; - else if ( nbAllElem == (nbEdges+nbFaces+nbVolum) ) - return SMESHGUI_ConvToQuadOp::Linear; - else - return SMESHGUI_ConvToQuadOp::Comp; + SMESH::long_array_var nbElemOfType = idSource->GetMeshInfo(); + bool hasQuad = ( nbElemOfType[SMDSEntity_Quad_Edge ] || + nbElemOfType[SMDSEntity_Quad_Triangle ] || + nbElemOfType[SMDSEntity_Quad_Quadrangle] || + nbElemOfType[SMDSEntity_Quad_Tetra ] || + nbElemOfType[SMDSEntity_Quad_Hexa ] || + nbElemOfType[SMDSEntity_Quad_Pyramid ] || + nbElemOfType[SMDSEntity_Quad_Penta ] ); + + bool hasLin = ( nbElemOfType[SMDSEntity_Edge ] || + nbElemOfType[SMDSEntity_Triangle ] || + nbElemOfType[SMDSEntity_Quadrangle] || + nbElemOfType[SMDSEntity_Tetra ] || + nbElemOfType[SMDSEntity_Hexa ] || + nbElemOfType[SMDSEntity_Pyramid ] || + nbElemOfType[SMDSEntity_Penta ] ); + + if ( hasQuad && hasLin ) + return Comp; + return hasQuad ? Quadratic : Linear; } - void SMESHGUI_ConvToQuadOp::ConnectRadioButtons( int id ) { - QString anMeshEntry = myDlg->selectedObject( 0 ); - _PTR(SObject) pMesh = studyDS()->FindObjectID( anMeshEntry.toLatin1().data() ); - if ( !pMesh ) return; + QString anObjEntry = myDlg->selectedObject( 0 ); + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); + if ( !pObj ) return; - SMESH::SMESH_Mesh_var mesh = - SMESH::SObjectToInterface( pMesh ); + SMESH::SMESH_IDSource_var idSource = + SMESH::SObjectToInterface( pObj ); + SMESH::SMESH_Mesh_var mesh = idSource->GetMesh(); - GEOM::GEOM_Object_var mainGeom; - mainGeom = mesh->GetShapeToMesh(); + bool hasGeom = mesh->HasShapeToMesh(); - if( id || mainGeom->_is_nil() ) + if( id || !hasGeom ) myDlg->SetEnabledCheck( false ); else myDlg->SetEnabledCheck( true ); diff --git a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.h b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.h index ad60ea5ea..9e2cbb129 100644 --- a/src/SMESHGUI/SMESHGUI_ConvToQuadOp.h +++ b/src/SMESHGUI/SMESHGUI_ConvToQuadOp.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ConvToQuadOp.h // Author : Open CASCADE S.A.S. @@ -54,7 +55,7 @@ protected: virtual void startOperation(); virtual void selectionDone(); virtual SUIT_SelectionFilter* createFilter( const int ) const; - MeshType ConsistMesh( const SMESH::SMESH_Mesh_var& ) const; + MeshType ConsistMesh( const SMESH::SMESH_IDSource_var& ) const; protected slots: virtual bool onApply(); diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx new file mode 100644 index 000000000..7c3d1d62c --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx @@ -0,0 +1,697 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_CopyMeshDlg.cxx + +#include "SMESHGUI_CopyMeshDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_SpinBox.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_FilterDlg.h" + +#include +#include +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +// SALOME KERNEL includes +#include + +// OCCT includes +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +/*! + \class BusyLocker + \brief Simple 'busy state' flag locker. + \internal +*/ + +namespace +{ + class BusyLocker + { + public: + //! Constructor. Sets passed boolean flag to \c true. + BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; } + //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false. + ~BusyLocker() { myBusy = false; } + private: + bool& myBusy; //! External 'busy state' boolean flag + }; +} + +#define SPACING 6 +#define MARGIN 11 + +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + + +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + +SMESHGUI_CopyMeshDlg::SMESHGUI_CopyMeshDlg( SMESHGUI* theModule ) + : QDialog( SMESH::GetDesktop( theModule ) ), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myFilterDlg(0), + mySelectedObject(SMESH::SMESH_IDSource::_nil()), + myIsApplyAndClose( false ) +{ + QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_COPY_MESH"))); + + setModal(false); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(tr("SMESH_COPY_MESH_TITLE")); + setSizeGripEnabled(true); + + QVBoxLayout* SMESHGUI_CopyMeshDlgLayout = new QVBoxLayout(this); + SMESHGUI_CopyMeshDlgLayout->setSpacing(SPACING); + SMESHGUI_CopyMeshDlgLayout->setMargin(MARGIN); + + /***************************************************************/ + ConstructorsBox = new QGroupBox(tr("SMESH_COPY_MESH_TITLE"), this); + QButtonGroup* GroupConstructors = new QButtonGroup(this); + QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox); + ConstructorsBoxLayout->setSpacing(SPACING); + ConstructorsBoxLayout->setMargin(MARGIN); + + QRadioButton* RadioButton1= new QRadioButton(ConstructorsBox); + RadioButton1->setIcon(image); + GroupConstructors->addButton(RadioButton1, 0); + + ConstructorsBoxLayout->addWidget(RadioButton1); + RadioButton1->setChecked(true); + GroupConstructors->addButton(RadioButton1, 0); + + /***************************************************************/ + GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this); + QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments); + GroupArgumentsLayout->setSpacing(SPACING); + GroupArgumentsLayout->setMargin(MARGIN); + + myIdValidator = new SMESHGUI_IdValidator(this); + + // Controls for idSource/elements selection + myTextLabelElements = new QLabel(tr("OBJECT_NAME"), GroupArguments); + myLineEditElements = new QLineEdit(GroupArguments); + myLineEditElements->setValidator(myIdValidator); + myLineEditElements->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + + // Control for the mesh objects selection + myIdSourceCheck = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); + + // Name of a mesh to create + QLabel* meshNameLabel = new QLabel(tr("NEW_NAME"), GroupArguments); + myMeshNameEdit = new QLineEdit(GroupArguments); + + // CheckBox for copying groups + myCopyGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments); + myCopyGroupsCheck->setChecked(false); + + // CheckBox for keeping ids + myKeepIdsCheck = new QCheckBox(tr("SMESH_KEEP_IDS"), GroupArguments); + myKeepIdsCheck->setChecked(true); + + // layout + GroupArgumentsLayout->addWidget(myTextLabelElements, 0, 0); + GroupArgumentsLayout->addWidget(myLineEditElements, 0, 1, 1, 5); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 6); + GroupArgumentsLayout->addWidget(myIdSourceCheck, 1, 0, 1, 6); + GroupArgumentsLayout->addWidget(meshNameLabel, 2, 0); + GroupArgumentsLayout->addWidget(myMeshNameEdit, 2, 1, 1, 5); + GroupArgumentsLayout->addWidget(myCopyGroupsCheck, 3, 0, 1, 6); + GroupArgumentsLayout->addWidget(myKeepIdsCheck, 4, 0, 1, 6); + + /***************************************************************/ + GroupButtons = new QGroupBox(this); + QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons); + GroupButtonsLayout->setSpacing(SPACING); + GroupButtonsLayout->setMargin(MARGIN); + + buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons); + buttonOk->setAutoDefault(true); + buttonOk->setDefault(true); + buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); + buttonApply->setAutoDefault(true); + buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons); + buttonCancel->setAutoDefault(true); + buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons); + buttonHelp->setAutoDefault(true); + + GroupButtonsLayout->addWidget(buttonOk); + GroupButtonsLayout->addSpacing(10); + GroupButtonsLayout->addWidget(buttonApply); + GroupButtonsLayout->addSpacing(10); + GroupButtonsLayout->addStretch(); + GroupButtonsLayout->addWidget(buttonCancel); + GroupButtonsLayout->addWidget(buttonHelp); + + /***************************************************************/ + SMESHGUI_CopyMeshDlgLayout->addWidget(ConstructorsBox); + SMESHGUI_CopyMeshDlgLayout->addWidget(GroupArguments); + SMESHGUI_CopyMeshDlgLayout->addWidget(GroupButtons); + + /* Initialisations */ + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // Selection filter + myIdSourceFilter = new SMESH_TypeFilter( IDSOURCE ); + + myHelpFileName = "copy_mesh_page.html"; + + Init(); + + /* signals and slots connections */ + connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel())); + connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); + + connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), + this, SLOT (DeactivateActiveDialog())); + connect(mySelectionMgr, SIGNAL (currentSelectionChanged()), + this, SLOT (SelectionIntoArgument())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()),/* to close dialog if study change */ + this, SLOT (ClickOnCancel())); + + connect(myLineEditElements, SIGNAL(textChanged(const QString&)), + this, SLOT (onTextChange(const QString&))); + connect(myIdSourceCheck, SIGNAL(toggled(bool)), + this, SLOT (onSelectIdSource(bool))); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : ~SMESHGUI_CopyMeshDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= + +SMESHGUI_CopyMeshDlg::~SMESHGUI_CopyMeshDlg() +{ + if ( myFilterDlg ) + { + myFilterDlg->setParent( 0 ); + delete myFilterDlg; myFilterDlg = 0; + } + if ( myIdSourceFilter ) + { + if ( mySelectionMgr ) + mySelectionMgr->removeFilter( myIdSourceFilter ); + delete myIdSourceFilter; myIdSourceFilter=0; + } +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::Init (bool ResetControls) +{ + myBusy = false; + + myMeshNameEdit->setText( SMESH::UniqueMeshName("Mesh")); + if ( ResetControls ) + { + myLineEditElements->clear(); + //myElementsId = ""; + myNbOkElements = 0; + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + myActor = 0; + myMesh = SMESH::SMESH_Mesh::_nil(); + + myIdSourceCheck->setChecked(true); + myCopyGroupsCheck->setChecked(false); + myKeepIdsCheck->setChecked(false); + + onSelectIdSource( myIdSourceCheck->isChecked() ); + } +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= + +bool SMESHGUI_CopyMeshDlg::ClickOnApply() +{ + if (mySMESHGUI->isActiveStudyLocked()) + return false; + + if( !isValid() ) + return false; + + QStringList anEntryList; + try + { + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_IDSource_var aPartToCopy; + if ( myIdSourceCheck->isChecked()) + { + aPartToCopy = mySelectedObject; + } + else + { + QStringList aListElementsId = myLineEditElements->text().split(" ", QString::SkipEmptyParts); + SMESH::long_array_var anElementsId = new SMESH::long_array; + anElementsId->length(aListElementsId.count()); + for (int i = 0; i < aListElementsId.count(); i++) + anElementsId[i] = aListElementsId[i].toInt(); + + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + aPartToCopy = aMeshEditor->MakeIDSource( anElementsId, SMESH::ALL ); + } + QByteArray meshName = myMeshNameEdit->text().toLatin1(); + bool toCopyGroups = ( myCopyGroupsCheck->isChecked() ); + bool toKeepIDs = ( myKeepIdsCheck->isChecked() ); + + SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGen(); + SMESH::SMESH_Mesh_var newMesh = + gen->CopyMesh(aPartToCopy, meshName.constData(), toCopyGroups, toKeepIDs); + if( !newMesh->_is_nil() ) + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) ) + anEntryList.append( aSObject->GetID().c_str() ); +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + newMesh->UnRegister(); +#endif + } catch (...) { + } + + mySMESHGUI->updateObjBrowser(true); + SMESHGUI::Modified(); + + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); + + Init(false); + mySelectedObject = SMESH::SMESH_IDSource::_nil(); + SelectionIntoArgument(); + + return true; +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::ClickOnOk() +{ + setIsApplyAndClose( true ); + if( ClickOnApply() ) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::ClickOnCancel() +{ + disconnect(mySelectionMgr, 0, this, 0); + if ( mySelectionMgr ) + mySelectionMgr->removeFilter( myIdSourceFilter ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + mySMESHGUI->ResetState(); + reject(); +} + +//================================================================================= +// function : ClickOnHelp() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::ClickOnHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} + +//======================================================================= +// function : onTextChange() +// purpose : +//======================================================================= + +void SMESHGUI_CopyMeshDlg::onTextChange (const QString& theNewText) +{ + QLineEdit* send = (QLineEdit*)sender(); + + if (myBusy) return; + BusyLocker lock( myBusy ); + + //if (send == myLineEditElements) + myNbOkElements = 0; + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + // hilight entered elements + SMDS_Mesh* aMesh = 0; + if (myActor) + aMesh = myActor->GetObject()->GetMesh(); + + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); + if (myActor && aMesh) + { + TColStd_MapOfInteger newIndices; + if (send == myLineEditElements) { + for (int i = 0; i < aListId.count(); i++) + if ( const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt())) + { + newIndices.Add(e->GetID()); + } + } + myNbOkElements = newIndices.Extent(); + + Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); + mySelector->AddOrRemoveIndex( anIO, newIndices, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( anIO, true, true ); + } + else + { + myNbOkElements = aListId.count(); + } + + if (myNbOkElements) { + buttonOk->setEnabled(true); + buttonApply->setEnabled(true); + } +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= + +void SMESHGUI_CopyMeshDlg::SelectionIntoArgument() +{ + if (myBusy) return; + BusyLocker lock( myBusy ); + + // clear + myActor = 0; + QString aString = ""; + + myLineEditElements->setText(aString); + myNbOkElements = 0; + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + myFilterBtn->setEnabled(false); + + // get selected mesh + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); + int nbSel = aList.Extent(); + if (nbSel != 1) + return; + + Handle(SALOME_InteractiveObject) IO = aList.First(); + mySelectedObject = SMESH::IObjectToInterface( IO ); + if ( mySelectedObject->_is_nil() ) + return; + + myMesh = SMESH::GetMeshByIO(IO); + if (myMesh->_is_nil()) + return; + + myActor = SMESH::FindActorByEntry(IO->getEntry()); + if (!myActor) + myActor = SMESH::FindActorByObject(myMesh); + + if (myIdSourceCheck->isChecked()) + { + SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString ); + if ( aString.isEmpty() ) aString = " "; + else aString = aString.trimmed(); // issue 0021327 + } + else + { + SMESH::GetNameOfSelectedElements( mySelector, IO, aString ); + myNbOkElements = aString.size(); + myFilterBtn->setEnabled(true); + } + myLineEditElements->setText( aString ); + bool ok = !aString.isEmpty(); + + buttonOk->setEnabled(ok); + buttonApply->setEnabled(ok); +} + +//======================================================================= +//function : onSelectIdSource +//purpose : +//======================================================================= +void SMESHGUI_CopyMeshDlg::onSelectIdSource (bool toSelectMesh) +{ + if (toSelectMesh) + myTextLabelElements->setText(tr("OBJECT_NAME")); + else + myTextLabelElements->setText(tr("ELEM_IDS")); + + if (toSelectMesh) { + myLineEditElements->clear(); + } + + mySelectionMgr->clearFilters(); + mySelectionMgr->installFilter(myIdSourceFilter); + SMESH::SetPointRepresentation(false); + + if (toSelectMesh) { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + myLineEditElements->setReadOnly(true); + myLineEditElements->setValidator(0); + } + else + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( CellSelection ); + myLineEditElements->setReadOnly(false); + myLineEditElements->setValidator(myIdValidator); + onTextChange(myLineEditElements->text()); + } + + SelectionIntoArgument(); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= + +bool SMESHGUI_CopyMeshDlg::isValid() +{ + if ( myIdSourceCheck->isChecked() ) + return !mySelectedObject->_is_nil(); + + return myNbOkElements > 0; +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::DeactivateActiveDialog() +{ + if (ConstructorsBox->isEnabled()) { + ConstructorsBox->setEnabled(false); + GroupArguments->setEnabled(false); + GroupButtons->setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + if ( mySelectionMgr ) + mySelectionMgr->removeFilter( myIdSourceFilter ); + } +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + mySMESHGUI->EmitSignalDeactivateDialog(); + ConstructorsBox->setEnabled(true); + GroupArguments->setEnabled(true); + GroupButtons->setEnabled(true); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + onSelectIdSource( myIdSourceCheck->isChecked() ); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::enterEvent (QEvent*) +{ + if (!ConstructorsBox->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::closeEvent (QCloseEvent*) +{ + /* same than click on cancel button */ + ClickOnCancel(); +} + +//======================================================================= +//function : hideEvent +//purpose : caused by ESC key +//======================================================================= +void SMESHGUI_CopyMeshDlg::hideEvent (QHideEvent*) +{ + if (!isMinimized()) + ClickOnCancel(); +} + +//================================================================================= +// function : keyPressEvent() +// purpose : +//================================================================================= +void SMESHGUI_CopyMeshDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + ClickOnHelp(); + } +} + +//================================================================================= +// function : setFilters() +// purpose : SLOT. Called when "Filter" button pressed. +//================================================================================= +void SMESHGUI_CopyMeshDlg::setFilters() +{ + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } + if ( !myFilterDlg ) + myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL ); + + myFilterDlg->SetSelection(); + myFilterDlg->SetMesh( myMesh ); + myFilterDlg->SetSourceWg( myLineEditElements ); + + myFilterDlg->show(); +} + +//================================================================ +// function : setIsApplyAndClose +// Purpose : Set value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +void SMESHGUI_CopyMeshDlg::setIsApplyAndClose( const bool theFlag ) +{ + myIsApplyAndClose = theFlag; +} + +//================================================================ +// function : isApplyAndClose +// Purpose : Get value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +bool SMESHGUI_CopyMeshDlg::isApplyAndClose() const +{ + return myIsApplyAndClose; +} diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h new file mode 100644 index 000000000..b0c3b9338 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h @@ -0,0 +1,130 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_CopyMeshDlg.h +// +#ifndef SMESHGUI_CopyMeshDLG_H +#define SMESHGUI_CopyMeshDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QCheckBox; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; + +class SMESHGUI; +class SMESHGUI_IdValidator; +class SMESHGUI_FilterDlg; +class SMESH_Actor; +class SVTK_Selector; +class LightApp_SelectionMgr; +class SUIT_SelectionFilter; + +//================================================================================= +// class : SMESHGUI_CopyMeshDlg +// purpose : copy some elements or a mesh object into a new mesh +//================================================================================= + +class SMESHGUI_EXPORT SMESHGUI_CopyMeshDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_CopyMeshDlg( SMESHGUI* ); + ~SMESHGUI_CopyMeshDlg(); + +private: + void Init( bool = true ); + void closeEvent( QCloseEvent* ); + void enterEvent( QEvent* ); /* mouse enter the QWidget */ + void hideEvent( QHideEvent* ); /* ESC key */ + void keyPressEvent( QKeyEvent* ); + int GetConstructorId(); + void setNewMeshName(); + + bool isValid(); + + void setIsApplyAndClose( const bool theFlag ); + bool isApplyAndClose() const; + + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + SMESHGUI_IdValidator* myIdValidator; + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + int myNbOkElements; /* to check when elements are defined */ + + SVTK_Selector* mySelector; + + bool myBusy; + SMESH::SMESH_Mesh_var myMesh; + SMESH_Actor* myActor; + SUIT_SelectionFilter* myIdSourceFilter; + + SMESH::SMESH_IDSource_var mySelectedObject; + + QGroupBox* ConstructorsBox; + QGroupBox* GroupArguments; + QGroupBox* GroupButtons; + + QPushButton* buttonOk; + QPushButton* buttonCancel; + QPushButton* buttonApply; + QPushButton* buttonHelp; + + QLabel* myTextLabelElements; + QLineEdit* myLineEditElements; + QLineEdit* myMeshNameEdit; + QCheckBox* myIdSourceCheck; + QCheckBox* myCopyGroupsCheck; + QCheckBox* myKeepIdsCheck; + + QPushButton* myFilterBtn; + SMESHGUI_FilterDlg* myFilterDlg; + + QString myHelpFileName; + + bool myIsApplyAndClose; + +private slots: + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void ClickOnHelp(); + void SelectionIntoArgument(); + void DeactivateActiveDialog(); + void ActivateThisDialog(); + void onTextChange( const QString& ); + void onSelectIdSource( bool ); + void setFilters(); +}; + +#endif // SMESHGUI_CopyMeshDLG_H diff --git a/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx b/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx index ef7f198ee..ac3c71931 100755 --- a/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_CreatePatternDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. // SMESH includes @@ -193,11 +194,11 @@ QWidget* SMESHGUI_CreatePatternDlg::createMainFrame( QWidget* theParent ) // Connect signals and slots connect( myTypeGrp, SIGNAL( buttonClicked( int ) ), - this, SLOT( onTypeChanged( int ) ) ); + this, SLOT( onTypeChanged( int ) ) ); connect( myProjectChk, SIGNAL( toggled( bool ) ), - this, SLOT( onProject( bool ) ) ); + this, SLOT( onProject( bool ) ) ); connect( aSelBtn, SIGNAL( clicked() ), - this, SLOT( onSelBtnClicked() ) ); + this, SLOT( onSelBtnClicked() ) ); return aMainGrp; } @@ -274,11 +275,11 @@ void SMESHGUI_CreatePatternDlg::Init( const int theType ) // selection and SMESHGUI connect( mySelectionMgr, SIGNAL( currentSelectionChanged() ), - this, SLOT( onSelectionDone() ) ); + this, SLOT( onSelectionDone() ) ); connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), - this, SLOT( onDeactivate() ) ); + this, SLOT( onDeactivate() ) ); connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), - this, SLOT( onClose() ) ); + this, SLOT( onClose() ) ); mySwitch2d->setEnabled( theType == Type_2d ); mySwitch3d->setEnabled( theType == Type_3d ); @@ -291,7 +292,7 @@ void SMESHGUI_CreatePatternDlg::Init( const int theType ) QApplication::instance()->processEvents(); updateGeometry(); - resize( minimumSize() ); + resize(100,100); activateSelection(); onSelectionDone(); @@ -342,8 +343,8 @@ bool SMESHGUI_CreatePatternDlg::isValid() { if ( myGeomObj->_is_nil() ) { SUIT_MessageBox::information( this, - tr( "SMESH_INSUFFICIENT_DATA" ), - tr( "SMESHGUI_INVALID_PARAMETERS" ) ); + tr( "SMESH_INSUFFICIENT_DATA" ), + tr( "SMESHGUI_INVALID_PARAMETERS" ) ); return false; } return true; @@ -406,13 +407,13 @@ void SMESHGUI_CreatePatternDlg::onSave() if ( aWritten != aLen ) { SUIT_MessageBox::information( this, - tr( "SMESH_ERROR" ), - tr( "ERROR_OF_SAVING" ) ); + tr( "SMESH_ERROR" ), + tr( "ERROR_OF_SAVING" ) ); } else { //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) ) - aViewWindow->SetSelectionMode( ActorSelection ); + aViewWindow->SetSelectionMode( ActorSelection ); disconnect( mySelectionMgr, 0, this, 0 ); disconnect( mySMESHGUI, 0, this, 0 ); mySMESHGUI->ResetState(); @@ -465,7 +466,7 @@ void SMESHGUI_CreatePatternDlg::onOk() else { //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) ) - aViewWindow->SetSelectionMode( ActorSelection ); + aViewWindow->SetSelectionMode( ActorSelection ); disconnect( mySelectionMgr, 0, this, 0 ); disconnect( mySMESHGUI, 0, this, 0 ); mySMESHGUI->ResetState(); @@ -512,11 +513,11 @@ void SMESHGUI_CreatePatternDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning( this, - tr( "WRN_WARNING" ), - tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ). - arg( app->resourceMgr()->stringValue( "ExternalBrowser", - platform ) ). - arg( myHelpFileName ) ); + tr( "WRN_WARNING" ), + tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ). + arg( app->resourceMgr()->stringValue( "ExternalBrowser", + platform ) ). + arg( myHelpFileName ) ); } } @@ -532,7 +533,7 @@ bool SMESHGUI_CreatePatternDlg::loadFromObject( const bool theMess ) if ( myPattern->_is_nil() ) myPattern = SMESH::GetPattern(); - if ( myMesh->_is_nil() && mySubMesh->_is_nil() || myGeomObj->_is_nil() ) + if ( (myMesh->_is_nil() && mySubMesh->_is_nil()) || myGeomObj->_is_nil() ) return false; SMESH::SMESH_Mesh_ptr aMesh = mySubMesh->_is_nil() ? myMesh.in() : mySubMesh->GetFather(); @@ -754,20 +755,20 @@ void SMESHGUI_CreatePatternDlg::activateSelection() if ( myType == Type_2d ) { mySelectionMgr->installFilter( new SMESH_NumberFilter( "SMESH", - TopAbs_SHAPE, - -1, - TopAbs_FACE ) ); + TopAbs_SHAPE, + -1, + TopAbs_FACE ) ); } else { TColStd_MapOfInteger aTypes; aTypes.Add( TopAbs_SHELL ); aTypes.Add( TopAbs_SOLID ); mySelectionMgr->installFilter( new SMESH_NumberFilter( "SMESH", - TopAbs_FACE, - 6, - aTypes, - GEOM::GEOM_Object::_nil(), - true ) ); + TopAbs_FACE, + 6, + aTypes, + GEOM::GEOM_Object::_nil(), + true ) ); } } diff --git a/src/SMESHGUI/SMESHGUI_CreatePatternDlg.h b/src/SMESHGUI/SMESHGUI_CreatePatternDlg.h index 838b609d4..0a03e1061 100755 --- a/src/SMESHGUI/SMESHGUI_CreatePatternDlg.h +++ b/src/SMESHGUI/SMESHGUI_CreatePatternDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_CreatePatternDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. // diff --git a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx index db615c8c4..ffc22ecdb 100644 --- a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_CreatePolyhedralVolumeDlg.cxx // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -30,6 +31,7 @@ #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_GroupUtils.h" #include "SMESHGUI_IdValidator.h" #include @@ -63,6 +65,7 @@ // Qt includes #include #include +#include #include #include #include @@ -129,9 +132,9 @@ namespace SMESH typedef std::vector TVTKIds; void SetPosition(SMESH_Actor* theActor, - vtkIdType theType, - const TVTKIds& theIds, - bool theReset=true) + vtkIdType theType, + const TVTKIds& theIds, + bool theReset=true) { vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid(); myGrid->SetPoints(aGrid->GetPoints()); @@ -141,14 +144,14 @@ namespace SMESH vtkIdList *anIds = vtkIdList::New(); for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) - anIds->InsertId(i,theIds[i]); + anIds->InsertId(i,theIds[i]); myGrid->InsertNextCell(theType,anIds); if(theIds.size()!=0){ - myGrid->InsertNextCell(theType,anIds); - myGrid->Modified(); + myGrid->InsertNextCell(theType,anIds); + myGrid->Modified(); } - + anIds->Delete(); SetVisibility(true); @@ -167,7 +170,7 @@ namespace SMESH ~TPolySimulation(){ if( myViewWindow ) - myViewWindow->RemoveActor(myPreviewActor); + myViewWindow->RemoveActor(myPreviewActor); myPreviewActor->Delete(); @@ -246,6 +249,21 @@ SMESHGUI_CreatePolyhedralVolumeDlg::SMESHGUI_CreatePolyhedralVolumeDlg( SMESHGUI GroupContentLayout->addWidget( RemoveButton, 3, 3 ); GroupContentLayout->addWidget( Preview, 5, 0, 1, 4 ); + /***************************************************************/ + GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this ); + GroupGroups->setCheckable( true ); + QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups); + GroupGroupsLayout->setSpacing(SPACING); + GroupGroupsLayout->setMargin(MARGIN); + + TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups ); + ComboBox_GroupName = new QComboBox( GroupGroups ); + ComboBox_GroupName->setEditable( true ); + ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert ); + + GroupGroupsLayout->addWidget( TextLabel_GroupName ); + GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 ); + /***************************************************************/ GroupButtons = new QGroupBox( this ); QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons ); @@ -273,6 +291,7 @@ SMESHGUI_CreatePolyhedralVolumeDlg::SMESHGUI_CreatePolyhedralVolumeDlg( SMESHGUI /***************************************************************/ topLayout->addWidget( ConstructorsBox ); topLayout->addWidget( GroupContent ); + topLayout->addWidget( GroupGroups ); topLayout->addWidget( GroupButtons ); mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); @@ -306,6 +325,9 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::Init() myEditCurrentArgument = LineEditElements; mySMESHGUI->SetActiveDialogBox( (QDialog*)this ); + /* reset "Add to group" control */ + GroupGroups->setChecked( false ); + myNbOkElements = 0; myActor = 0; @@ -321,7 +343,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::Init() connect(SelectElementsButton, SIGNAL( clicked() ), SLOT( SetEditCurrentArgument() ) ); connect(LineEditElements, SIGNAL( textChanged(const QString&) ), SLOT(onTextChange(const QString&))); - connect(myFacesByNodes, SIGNAL(selectionChanged()), this, SLOT(onListSelectionChanged())); + connect(myFacesByNodes, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); connect(AddButton, SIGNAL(clicked()), this, SLOT(onAdd())); connect(RemoveButton, SIGNAL(clicked()), this, SLOT(onRemove())); @@ -358,42 +380,42 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ConstructorsClicked(int constructorId) { case 0 : { - if ( myActor ){ + if ( myActor ){ myActor->SetPointRepresentation(true); - } + } else SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - - AddButton->setEnabled(false); - RemoveButton->setEnabled(false); - TextLabelIds->setText( tr( "SMESH_ID_NODES" ) ); - myFacesByNodesLabel->show(); - myFacesByNodes->clear(); - myFacesByNodes->show(); - AddButton->show(); - RemoveButton->show(); - Preview->show(); - break; + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + + AddButton->setEnabled(false); + RemoveButton->setEnabled(false); + TextLabelIds->setText( tr( "SMESH_ID_NODES" ) ); + myFacesByNodesLabel->show(); + myFacesByNodes->clear(); + myFacesByNodes->show(); + AddButton->show(); + RemoveButton->show(); + Preview->show(); + break; } case 1 : { - if( myActor ){ - myActor->SetPointRepresentation(false); - } else { - SMESH::SetPointRepresentation(false); - } - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - - TextLabelIds->setText( tr( "SMESH_ID_FACES" ) ); - myFacesByNodesLabel->hide(); - myFacesByNodes->hide(); - AddButton->hide(); - RemoveButton->hide(); - Preview->show(); - break; + if( myActor ){ + myActor->SetPointRepresentation(false); + } else { + SMESH::SetPointRepresentation(false); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + + TextLabelIds->setText( tr( "SMESH_ID_FACES" ) ); + myFacesByNodesLabel->hide(); + myFacesByNodes->hide(); + AddButton->hide(); + RemoveButton->hide(); + Preview->show(); + break; } } @@ -402,7 +424,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ConstructorsClicked(int constructorId) QApplication::instance()->processEvents(); updateGeometry(); - resize( minimumSize() ); + resize(100,100); } //================================================================================= @@ -420,80 +442,143 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnPreview(bool theToggled){ //================================================================================= void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply() { + if( !isValid() ) + return; + if ( myNbOkElements>0 && !mySMESHGUI->isActiveStudyLocked()) { if(checkEditLine(false) == -1) {return;} busy = true; + long anElemId = -1; + + bool addToGroup = GroupGroups->isChecked(); + QString aGroupName; + + SMESH::SMESH_GroupBase_var aGroup; + int idx = 0; + if( addToGroup ) { + aGroupName = ComboBox_GroupName->currentText(); + for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { + QString aName = ComboBox_GroupName->itemText( i ); + if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) + idx = i; + } + if ( idx > 0 && idx < myGroups.count() ) { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); + if ( !aGeomGroup->_is_nil() ) { + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return; + } + aGroup = myGroups[idx-1]; + } + } + if (GetConstructorId() == 0) - { - SMESH::long_array_var anIdsOfNodes = new SMESH::long_array; - SMESH::long_array_var aQuantities = new SMESH::long_array; - - aQuantities->length( myFacesByNodes->count() ); - - TColStd_ListOfInteger aNodesIds; - - int aNbQuantities = 0; - for (int i = 0; i < myFacesByNodes->count(); i++ ) { - QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts ); - for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it) - aNodesIds.Append( (*it).toInt() ); - - aQuantities[aNbQuantities++] = anIds.count(); - } - - anIdsOfNodes->length(aNodesIds.Extent()); - - int aNbIdsOfNodes = 0; - TColStd_ListIteratorOfListOfInteger It; - It.Initialize(aNodesIds); - for( ;It.More();It.Next()) - anIdsOfNodes[aNbIdsOfNodes++] = It.Value(); - - try{ - SUIT_OverrideCursor aWaitCursor; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - aMeshEditor->AddPolyhedralVolume(anIdsOfNodes, aQuantities); - }catch(SALOME::SALOME_Exception& exc){ - INFOS("Follow exception was cought:\n\t"<length( myFacesByNodes->count() ); + + TColStd_ListOfInteger aNodesIds; + + int aNbQuantities = 0; + for (int i = 0; i < myFacesByNodes->count(); i++ ) { + QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts ); + for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it) + aNodesIds.Append( (*it).toInt() ); + + aQuantities[aNbQuantities++] = anIds.count(); + } + + anIdsOfNodes->length(aNodesIds.Extent()); + + int aNbIdsOfNodes = 0; + TColStd_ListIteratorOfListOfInteger It; + It.Initialize(aNodesIds); + for( ;It.More();It.Next()) + anIdsOfNodes[aNbIdsOfNodes++] = It.Value(); + + try{ + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + anElemId = aMeshEditor->AddPolyhedralVolume(anIdsOfNodes, aQuantities); + }catch(SALOME::SALOME_Exception& exc){ + INFOS("Follow exception was cought:\n\t"<text().split( " ", QString::SkipEmptyParts ); - anIdsOfFaces->length(aListId.count()); - for ( int i = 0; i < aListId.count(); i++ ) - anIdsOfFaces[i] = aListId[i].toInt(); - - try{ - SUIT_OverrideCursor aWaitCursor; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - aMeshEditor->AddPolyhedralVolumeByFaces(anIdsOfFaces); - }catch(SALOME::SALOME_Exception& exc){ - INFOS("Follow exception was cought:\n\t"<text().split( " ", QString::SkipEmptyParts ); + anIdsOfFaces->length(aListId.count()); + for ( int i = 0; i < aListId.count(); i++ ) + anIdsOfFaces[i] = aListId[i].toInt(); + + try{ + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + anElemId = aMeshEditor->AddPolyhedralVolumeByFaces(anIdsOfFaces); + }catch(SALOME::SALOME_Exception& exc){ + INFOS("Follow exception was cought:\n\t"<_is_nil() ) { + // create new group + aGroupUsed = SMESH::AddGroup( myMesh, SMESH::VOLUME, aGroupName ); + if ( !aGroupUsed->_is_nil() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + else { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); + if ( !aGeomGroup->_is_nil() ) { + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } + } + else + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + } + + if ( !aGroupUsed->_is_nil() ) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length( 1 ); + anIdList[0] = anElemId; + aGroupUsed->Add( anIdList.inout() ); + } + } + //SALOME_ListIO aList; //mySelectionMgr->setSelectedObjects( aList ); SMESH::UpdateView(); if( myActor ){ - unsigned int anEntityMode = myActor->GetEntityMode(); - myActor->SetEntityMode(SMESH_Actor::eVolumes | anEntityMode); + unsigned int anEntityMode = myActor->GetEntityMode(); + myActor->SetEntityMode(SMESH_Actor::eVolumes | anEntityMode); } //ConstructorsClicked( GetConstructorId() ); busy = false; + + SMESHGUI::Modified(); } + myFacesByNodes->clear(); } //================================================================================= @@ -507,7 +592,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnOk() ClickOnCancel(); } - + //================================================================================= // function : ClickOnCancel() // purpose : @@ -543,10 +628,10 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -570,67 +655,67 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::onTextChange(const QString& theNewText) if (GetConstructorId() == 0) { if ( aMesh ) { - TColStd_MapOfInteger newIndices; + TColStd_MapOfInteger newIndices; - QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts ); - for ( int i = 0; i < aListId.count(); i++ ) { - const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ); - if ( n ) { - newIndices.Add(n->GetID()); - myNbOkElements++; - } - } + QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts ); + for ( int i = 0; i < aListId.count(); i++ ) { + const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ); + if ( n ) { + newIndices.Add(n->GetID()); + myNbOkElements++; + } + } - mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false ); + mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( myActor->getIO(), true, true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( myActor->getIO(), true, true ); - if ( myNbOkElements>0 && aListId.count()>=3) - AddButton->setEnabled(true); - else - AddButton->setEnabled(false); + if ( myNbOkElements>0 && aListId.count()>=3) + AddButton->setEnabled(true); + else + AddButton->setEnabled(false); - displaySimulation(); + displaySimulation(); } } else if (GetConstructorId() == 1) { - myNbOkElements = 0; - buttonOk->setEnabled( false ); - buttonApply->setEnabled( false ); + myNbOkElements = 0; + buttonOk->setEnabled( false ); + buttonApply->setEnabled( false ); - // check entered ids of faces and hilight them - QStringList aListId; - if ( aMesh ) { - TColStd_MapOfInteger newIndices; + // check entered ids of faces and hilight them + QStringList aListId; + if ( aMesh ) { + TColStd_MapOfInteger newIndices; - aListId = theNewText.split( " ", QString::SkipEmptyParts ); - - for ( int i = 0; i < aListId.count(); i++ ) { - const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() ); - if ( e ) { - newIndices.Add(e->GetID()); - myNbOkElements++; - } - } - - mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( myActor->getIO(), true, true ); + aListId = theNewText.split( " ", QString::SkipEmptyParts ); + + for ( int i = 0; i < aListId.count(); i++ ) { + const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() ); + if ( e ) { + newIndices.Add(e->GetID()); + myNbOkElements++; + } + } + + mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( myActor->getIO(), true, true ); - if ( myNbOkElements ) { - if (aListId.count()>1){ - buttonOk->setEnabled( true ); - buttonApply->setEnabled( true ); - } - else{ - buttonOk->setEnabled( false ); - buttonApply->setEnabled( false ); - } - if(aListId.count()>1) - displaySimulation(); - } - } + if ( myNbOkElements ) { + if (aListId.count()>1){ + buttonOk->setEnabled( true ); + buttonApply->setEnabled( true ); + } + else{ + buttonOk->setEnabled( false ); + buttonApply->setEnabled( false ); + } + if(aListId.count()>1) + displaySimulation(); + } + } } busy = false; } @@ -663,6 +748,8 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument() mySimulation->SetVisibility(false); + QString aCurrentEntry = myEntry; + // get selected mesh SALOME_ListIO selected; @@ -672,10 +759,29 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument() return; } + myEntry = selected.First()->getEntry(); myMesh = SMESH::GetMeshByIO( selected.First() ); if ( myMesh->_is_nil() ) return; + // process groups + if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) { + myGroups.clear(); + ComboBox_GroupName->clear(); + ComboBox_GroupName->addItem( QString() ); + SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups(); + for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; + if ( !aGroup->_is_nil() && aGroup->GetType() == SMESH::VOLUME ) { + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + } + } + myActor = SMESH::FindActorByObject(myMesh); if ( !myActor ) return; @@ -749,13 +855,13 @@ int SMESHGUI_CreatePolyhedralVolumeDlg::checkEditLine(bool checkLast) case 0:{ // nodes const SMDS_MeshNode * aNode = aMesh->FindNode( aListId[ i ].toInt() ); if( !aNode ){ - SUIT_MessageBox::warning(this, - tr("SMESH_POLYEDRE_CREATE_ERROR"), - tr("The incorrect indices of nodes!")); - - myEditCurrentArgument->clear(); - myEditCurrentArgument->setText( aString ); - return -1; + SUIT_MessageBox::warning(this, + tr("SMESH_POLYEDRE_CREATE_ERROR"), + tr("The incorrect indices of nodes!")); + + myEditCurrentArgument->clear(); + myEditCurrentArgument->setText( aString ); + return -1; } break; @@ -764,24 +870,24 @@ int SMESHGUI_CreatePolyhedralVolumeDlg::checkEditLine(bool checkLast) bool aElemIsOK = true; const SMDS_MeshElement * aElem = aMesh->FindElement( aListId[ i ].toInt() ); if (!aElem) - { - aElemIsOK = false; - } + { + aElemIsOK = false; + } else - { - SMDSAbs_ElementType aType = aMesh->GetElementType( aElem->GetID(),true ); - if (aType != SMDSAbs_Face){ - aElemIsOK = false; - } - } + { + SMDSAbs_ElementType aType = aMesh->GetElementType( aElem->GetID(),true ); + if (aType != SMDSAbs_Face){ + aElemIsOK = false; + } + } if (!aElemIsOK){ - SUIT_MessageBox::warning(this, - tr("SMESH_POLYEDRE_CREATE_ERROR"), - tr("The incorrect indices of faces!")); - - myEditCurrentArgument->clear(); - myEditCurrentArgument->setText( aString ); - return -1; + SUIT_MessageBox::warning(this, + tr("SMESH_POLYEDRE_CREATE_ERROR"), + tr("The incorrect indices of faces!")); + + myEditCurrentArgument->clear(); + myEditCurrentArgument->setText( aString ); + return -1; } break; } @@ -804,66 +910,66 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::displaySimulation() vtkIdType aType = VTK_CONVEX_POINT_SET; SMDS_Mesh* aMesh = 0; if ( myActor ){ - aMesh = myActor->GetObject()->GetMesh(); + aMesh = myActor->GetObject()->GetMesh(); } if (GetConstructorId() == 0 && aMesh){ - if (!AddButton->isEnabled()){ - mySimulation->ResetGrid(true); - for (int i = 0; i < myFacesByNodes->count(); i++) { - QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts ); - SMESH::TPolySimulation::TVTKIds aVTKIds_faces; - for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it){ - const SMDS_MeshNode* aNode = aMesh->FindNode( (*it).toInt() ); - if (!aNode) continue; - vtkIdType aId = myActor->GetObject()->GetNodeVTKId( (*it).toInt() ); - aVTKIds.push_back(aId); - aVTKIds_faces.push_back(aId); - } - if(!Preview->isChecked()){ - aType = VTK_POLYGON; - mySimulation->SetPosition(myActor, aType, aVTKIds_faces,false); - } - } - if(myFacesByNodes->count() == 0){ - mySimulation->SetVisibility(false); - } else { - mySimulation->SetVisibility(true); - } - if(Preview->isChecked()){ - mySimulation->SetPosition(myActor, aType, aVTKIds); - } - } else { - // add ids from edit line - QStringList anEditIds = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts ); - for ( int i = 0; i < anEditIds.count(); i++ ) - aVTKIds.push_back( myActor->GetObject()->GetNodeVTKId( anEditIds[ i ].toInt() )); - aType = VTK_POLYGON; - mySimulation->SetPosition(myActor, aType, aVTKIds); - } + if (!AddButton->isEnabled()){ + mySimulation->ResetGrid(true); + for (int i = 0; i < myFacesByNodes->count(); i++) { + QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts ); + SMESH::TPolySimulation::TVTKIds aVTKIds_faces; + for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it){ + const SMDS_MeshNode* aNode = aMesh->FindNode( (*it).toInt() ); + if (!aNode) continue; + vtkIdType aId = myActor->GetObject()->GetNodeVTKId( (*it).toInt() ); + aVTKIds.push_back(aId); + aVTKIds_faces.push_back(aId); + } + if(!Preview->isChecked()){ + aType = VTK_POLYGON; + mySimulation->SetPosition(myActor, aType, aVTKIds_faces,false); + } + } + if(myFacesByNodes->count() == 0){ + mySimulation->SetVisibility(false); + } else { + mySimulation->SetVisibility(true); + } + if(Preview->isChecked()){ + mySimulation->SetPosition(myActor, aType, aVTKIds); + } + } else { + // add ids from edit line + QStringList anEditIds = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts ); + for ( int i = 0; i < anEditIds.count(); i++ ) + aVTKIds.push_back( myActor->GetObject()->GetNodeVTKId( anEditIds[ i ].toInt() )); + aType = VTK_POLYGON; + mySimulation->SetPosition(myActor, aType, aVTKIds); + } }else if(GetConstructorId() == 1 && aMesh){ - QStringList aListId = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts ); - for ( int i = 0; i < aListId.count(); i++ ) - { - const SMDS_MeshElement * anElem = aMesh->FindElement( aListId[ i ].toInt() ); - if ( !anElem ) continue; - SMDSAbs_ElementType aFaceType = aMesh->GetElementType( anElem->GetID(),true ); - if (aFaceType != SMDSAbs_Face) continue; - - SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); - SMESH::TPolySimulation::TVTKIds aVTKIds_faces; - while( anIter->more() ) - if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() ){ - vtkIdType aId = myActor->GetObject()->GetNodeVTKId( aNode->GetID() ); - aVTKIds.push_back(aId); - aVTKIds_faces.push_back(aId); - } - if(!Preview->isChecked()){ - aType = VTK_POLYGON; - mySimulation->SetPosition(myActor, aType, aVTKIds_faces); - } - } - if(Preview->isChecked()) - mySimulation->SetPosition(myActor, aType, aVTKIds); + QStringList aListId = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts ); + for ( int i = 0; i < aListId.count(); i++ ) + { + const SMDS_MeshElement * anElem = aMesh->FindElement( aListId[ i ].toInt() ); + if ( !anElem ) continue; + SMDSAbs_ElementType aFaceType = aMesh->GetElementType( anElem->GetID(),true ); + if (aFaceType != SMDSAbs_Face) continue; + + SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); + SMESH::TPolySimulation::TVTKIds aVTKIds_faces; + while( anIter->more() ) + if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() ){ + vtkIdType aId = myActor->GetObject()->GetNodeVTKId( aNode->GetID() ); + aVTKIds.push_back(aId); + aVTKIds_faces.push_back(aId); + } + if(!Preview->isChecked()){ + aType = VTK_POLYGON; + mySimulation->SetPosition(myActor, aType, aVTKIds_faces); + } + } + if(Preview->isChecked()) + mySimulation->SetPosition(myActor, aType, aVTKIds); } SMESH::UpdateView(); } @@ -985,8 +1091,8 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::onAdd() myNbOkElements = 1; myEditCurrentArgument->clear(); AddButton->setEnabled(false); - buttonOk->setEnabled( true ); - if(myFacesByNodes->count()>1) buttonApply->setEnabled( true ); + buttonApply->setEnabled( myFacesByNodes->count() > 1 ); + buttonOk->setEnabled( myFacesByNodes->count() > 1 ); } busy = false; onListSelectionChanged(); @@ -1062,3 +1168,16 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::keyPressEvent( QKeyEvent* e ) ClickOnHelp(); } } + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool SMESHGUI_CreatePolyhedralVolumeDlg::isValid() +{ + if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) { + SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) ); + return false; + } + return true; +} diff --git a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h index b46d0c35b..44dd3ab5d 100644 --- a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h +++ b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_CreatePolyhedralVolumeDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -37,6 +38,7 @@ #include CORBA_SERVER_HEADER(SMESH_Mesh) class QButtonGroup; +class QComboBox; class QGroupBox; class QListWidget; class QLabel; @@ -67,6 +69,8 @@ public: ~SMESHGUI_CreatePolyhedralVolumeDlg(); private: + typedef QList GrpList; + void Init(); void closeEvent( QCloseEvent* ); void enterEvent( QEvent* ); /* mouse enter the QWidget */ @@ -75,6 +79,8 @@ private: int GetConstructorId(); void displaySimulation(); + bool isValid(); + int checkEditLine( bool = true ); /*! Checking for indices, return 1 if all ok, esle -1*/ SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ @@ -88,12 +94,17 @@ private: SMESH::SMESH_Mesh_var myMesh; SMESH_Actor* myActor; SMESH::TPolySimulation* mySimulation; + QString myEntry; + GrpList myGroups; QGroupBox* ConstructorsBox; QButtonGroup* GroupConstructors; QRadioButton* RadioButton1; QRadioButton* RadioButton2; QCheckBox* Preview; + QGroupBox* GroupGroups; + QLabel* TextLabel_GroupName; + QComboBox* ComboBox_GroupName; QGroupBox* GroupButtons; QPushButton* buttonOk; QPushButton* buttonCancel; diff --git a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx index 6e2a106a2..ac5a1c686 100644 --- a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_DeleteGroupDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. // SMESH includes @@ -189,7 +190,7 @@ bool SMESHGUI_DeleteGroupDlg::isValid() { if (myListBox->count() == 0) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("NO_SELECTED_GROUPS")); + tr("NO_SELECTED_GROUPS")); return false; } @@ -218,6 +219,7 @@ bool SMESHGUI_DeleteGroupDlg::onApply() myListGrp.clear(); mySelectionMgr->clearSelected(); SMESH::UpdateView(); + SMESHGUI::Modified(); mySMESHGUI->updateObjBrowser(true); myBlockSelection = false; @@ -266,10 +268,10 @@ void SMESHGUI_DeleteGroupDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } diff --git a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.h b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.h index c9d6bd029..48e418417 100644 --- a/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.h +++ b/src/SMESHGUI/SMESHGUI_DeleteGroupDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_DeleteGroupDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. // diff --git a/src/SMESHGUI/SMESHGUI_Dialog.cxx b/src/SMESHGUI/SMESHGUI_Dialog.cxx index 754221521..958f609ff 100644 --- a/src/SMESHGUI/SMESHGUI_Dialog.cxx +++ b/src/SMESHGUI/SMESHGUI_Dialog.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Dialog.cxx // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_Dialog.h b/src/SMESHGUI/SMESHGUI_Dialog.h index 7da64f71e..374cbe72b 100644 --- a/src/SMESHGUI/SMESHGUI_Dialog.h +++ b/src/SMESHGUI/SMESHGUI_Dialog.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Dialog.h // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. @@ -44,8 +45,8 @@ class SMESHGUI_EXPORT SMESHGUI_Dialog : public LightApp_Dialog Q_OBJECT public: - SMESHGUI_Dialog( QWidget* = 0, const bool = false, const bool = false, - const int = OK | Close | Apply | Help ); + SMESHGUI_Dialog( QWidget* = 0, const bool modal = false, const bool allowResize = false, + const int = OK | Close | Apply | Help ); virtual ~SMESHGUI_Dialog(); virtual void show(); diff --git a/src/SMESHGUI/SMESHGUI_Displayer.cxx b/src/SMESHGUI/SMESHGUI_Displayer.cxx index 613fbb9e4..153c34825 100644 --- a/src/SMESHGUI/SMESHGUI_Displayer.cxx +++ b/src/SMESHGUI/SMESHGUI_Displayer.cxx @@ -1,32 +1,34 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : Displayer for SMESH module // File : SMESHGUI_Displayer.cxx // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. // SMESH includes // -#include "SMESHGUI_Displayer.h" +#include "SMESHGUI_Displayer.h" #include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_Utils.h" // SALOME GUI includes #include @@ -35,6 +37,13 @@ #include #include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + + SMESHGUI_Displayer::SMESHGUI_Displayer( SalomeApp_Application* app ) : LightApp_Displayer(), myApp( app ) @@ -59,16 +68,16 @@ SALOME_Prs* SMESHGUI_Displayer::buildPresentation( const QString& entry, SALOME_ SUIT_ViewWindow* wnd = vtk_viewer->getViewManager()->getActiveView(); SMESH_Actor* anActor = SMESH::FindActorByEntry( wnd, entry.toLatin1().data() ); if( !anActor ) - anActor = SMESH::CreateActor( study()->studyDS(), entry.toLatin1().data(), true ); + anActor = SMESH::CreateActor( study()->studyDS(), entry.toLatin1().data(), true ); if( anActor ) { - SMESH::DisplayActor( wnd, anActor ); + SMESH::DisplayActor( wnd, anActor ); prs = LightApp_Displayer::buildPresentation( entry.toLatin1().data(), aViewFrame ); } if( prs ) - UpdatePrs( prs ); + UpdatePrs( prs ); else if( anActor ) - SMESH::RemoveActor( vtk_viewer->getViewManager()->getActiveView(), anActor ); + SMESH::RemoveActor( vtk_viewer->getViewManager()->getActiveView(), anActor ); } } @@ -80,7 +89,38 @@ SalomeApp_Study* SMESHGUI_Displayer::study() const return dynamic_cast( myApp->activeStudy() ); } -bool SMESHGUI_Displayer::canBeDisplayed( const QString& /*entry*/, const QString& viewer_type ) const -{ - return viewer_type==SVTK_Viewer::Type(); +bool SMESHGUI_Displayer::canBeDisplayed( const QString& entry, const QString& viewer_type ) const { + bool res = false; + if(viewer_type != SVTK_Viewer::Type()) + return res; + + SalomeApp_Study* study = dynamic_cast( myApp->activeStudy() ); + if( !study ) + return res; + + + _PTR(SObject) obj = study->studyDS()->FindObjectID( (const char*)entry.toLatin1() ); + CORBA::Object_var anObj = SMESH::SObjectToObject( obj ); + + /* + if( !CORBA::is_nil( anObj ) ) { + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( anObj ); + if ( ! mesh->_is_nil() ) + res = (mesh->NbNodes() > 0); + + SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( anObj ); + if ( !aSubMeshObj->_is_nil() ) + res = (aSubMeshObj->GetNumberOfNodes(true) > 0); + + SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( anObj ); + if ( !aGroupObj->_is_nil() ) + res = !aGroupObj->IsEmpty(); + }*/ + if( !CORBA::is_nil( anObj ) ) { + if(!SMESH::SMESH_Mesh::_narrow( anObj )->_is_nil() || + !SMESH::SMESH_subMesh::_narrow( anObj )->_is_nil() || + !SMESH::SMESH_GroupBase::_narrow( anObj )->_is_nil()) + res = true; + } + return res; } diff --git a/src/SMESHGUI/SMESHGUI_Displayer.h b/src/SMESHGUI/SMESHGUI_Displayer.h index 61288ee13..6a0920b4a 100644 --- a/src/SMESHGUI/SMESHGUI_Displayer.h +++ b/src/SMESHGUI/SMESHGUI_Displayer.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : Displayer for SMESH module // File : SMESHGUI_Displayer.h // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx new file mode 100644 index 000000000..e49250afe --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx @@ -0,0 +1,624 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_DuplicateNodesDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. + +// SMESH includes +#include "SMESHGUI_DuplicateNodesDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" + +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +#define SPACING 6 +#define MARGIN 11 + +/*! + \class BusyLocker + \brief Simple 'busy state' flag locker. + \internal +*/ + +class BusyLocker +{ +public: + //! Constructor. Sets passed boolean flag to \c true. + BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; } + //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false. + ~BusyLocker() { myBusy = false; } +private: + bool& myBusy; //! External 'busy state' boolean flag +}; + +/*! + \brief Constructor + \param theModule Mesh module instance +*/ +SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule ) + : QDialog( SMESH::GetDesktop( theModule ) ), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) +{ + // Dialog attributes + setModal(false); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(tr("SMESH_DUPLICATE_TITLE")); + setSizeGripEnabled(true); + + // Icons for the dialog operation modes and selection button + SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI ); + QPixmap iconWithoutElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES"))); + QPixmap iconWithElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES_WITH_ELEM"))); + QPixmap iconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); + + // Main layout + QVBoxLayout* aMainLayout = new QVBoxLayout(this); + aMainLayout->setSpacing(SPACING); + aMainLayout->setMargin(MARGIN); + + // Operation modes selector + QGroupBox* aConstructorsBox = new QGroupBox(tr("DUPLICATION_MODE"), this); + myGroupConstructors = new QButtonGroup(this); + QHBoxLayout* aConstructorsBoxLayout = new QHBoxLayout(aConstructorsBox); + aConstructorsBoxLayout->setSpacing(SPACING); + aConstructorsBoxLayout->setMargin(MARGIN); + + QRadioButton* aRadioButton1 = new QRadioButton(aConstructorsBox); + aRadioButton1->setIcon(iconWithoutElem); + QRadioButton* aRadioButton2 = new QRadioButton(aConstructorsBox); + aRadioButton2->setIcon(iconWithElem); + + aConstructorsBoxLayout->addWidget(aRadioButton1); + aConstructorsBoxLayout->addWidget(aRadioButton2); + myGroupConstructors->addButton(aRadioButton1, 0); + myGroupConstructors->addButton(aRadioButton2, 1); + + // Arguments + myGroupArguments = new QGroupBox(this); + QGridLayout* aGroupArgumentsLayout = new QGridLayout(myGroupArguments); + aGroupArgumentsLayout->setSpacing(SPACING); + aGroupArgumentsLayout->setMargin(MARGIN); + + myTextLabel1 = new QLabel(myGroupArguments); + mySelectButton1 = new QPushButton(myGroupArguments); + mySelectButton1->setIcon(iconSelect); + myLineEdit1 = new QLineEdit(myGroupArguments); + myLineEdit1->setReadOnly(true); + + myTextLabel2 = new QLabel(myGroupArguments); + mySelectButton2 = new QPushButton(myGroupArguments); + mySelectButton2->setIcon(iconSelect); + myLineEdit2 = new QLineEdit(myGroupArguments); + myLineEdit2->setReadOnly(true); + + myTextLabel3 = new QLabel(myGroupArguments); + mySelectButton3 = new QPushButton(myGroupArguments); + mySelectButton3->setIcon(iconSelect); + myLineEdit3 = new QLineEdit(myGroupArguments); + myLineEdit3->setReadOnly(true); + + myCheckBoxNewElemGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_ELEMENTS"), myGroupArguments); + myCheckBoxNewNodeGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments); + + aGroupArgumentsLayout->addWidget(myTextLabel1, 0, 0); + aGroupArgumentsLayout->addWidget(mySelectButton1, 0, 1); + aGroupArgumentsLayout->addWidget(myLineEdit1, 0, 2); + aGroupArgumentsLayout->addWidget(myTextLabel2, 1, 0); + aGroupArgumentsLayout->addWidget(mySelectButton2, 1, 1); + aGroupArgumentsLayout->addWidget(myLineEdit2, 1, 2); + aGroupArgumentsLayout->addWidget(myTextLabel3, 2, 0); + aGroupArgumentsLayout->addWidget(mySelectButton3, 2, 1); + aGroupArgumentsLayout->addWidget(myLineEdit3, 2, 2); + aGroupArgumentsLayout->addWidget(myCheckBoxNewElemGroup, 3, 0); + aGroupArgumentsLayout->addWidget(myCheckBoxNewNodeGroup, 4, 0); + aGroupArgumentsLayout->setRowStretch(5, 1); + + // Buttons + QGroupBox* aGroupButtons = new QGroupBox(this); + QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(aGroupButtons); + aGroupButtonsLayout->setSpacing(SPACING); + aGroupButtonsLayout->setMargin(MARGIN); + + myButtonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGroupButtons); + myButtonOk->setAutoDefault(true); + myButtonOk->setDefault(true); + myButtonApply = new QPushButton(tr("SMESH_BUT_APPLY"), aGroupButtons); + myButtonApply->setAutoDefault(true); + myButtonClose = new QPushButton(tr("SMESH_BUT_CLOSE"), aGroupButtons); + myButtonClose->setAutoDefault(true); + myButtonHelp = new QPushButton(tr("SMESH_BUT_HELP"), aGroupButtons); + myButtonHelp->setAutoDefault(true); + + aGroupButtonsLayout->addWidget(myButtonOk); + aGroupButtonsLayout->addSpacing(10); + aGroupButtonsLayout->addWidget(myButtonApply); + aGroupButtonsLayout->addSpacing(10); + aGroupButtonsLayout->addStretch(); + aGroupButtonsLayout->addWidget(myButtonClose); + aGroupButtonsLayout->addWidget(myButtonHelp); + + // Add mode selector, arguments and buttons to the main layout + aMainLayout->addWidget(aConstructorsBox); + aMainLayout->addWidget(myGroupArguments); + aMainLayout->addWidget(aGroupButtons); + + // Initialize the dialog + Init(); + + // Help file name + myHelpFileName = "double_nodes_page.html"; + + // Signals and slots connections + connect(myGroupConstructors, SIGNAL(buttonClicked(int)), SLOT(onConstructorsClicked(int))); + + connect(mySelectButton1, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + connect(mySelectButton2, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + connect(mySelectButton3, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + + connect(myButtonOk, SIGNAL(clicked()), this, SLOT(onOk())); + connect(myButtonClose, SIGNAL(clicked()), this, SLOT(onClose())); + connect(myButtonApply, SIGNAL(clicked()), this, SLOT(onApply())); + connect(myButtonHelp, SIGNAL(clicked()), this, SLOT(onHelp())); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionChanged())); + + connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(onDeactivate())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(onClose())); +} + +/*! + \brief Destructor +*/ +SMESHGUI_DuplicateNodesDlg::~SMESHGUI_DuplicateNodesDlg() +{ +} + +/*! + \brief Destructor +*/ +void SMESHGUI_DuplicateNodesDlg::Init() +{ + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + myCheckBoxNewElemGroup->setChecked(true); + myCheckBoxNewNodeGroup->setChecked(true); + + // Set initial parameters + myBusy = false; + myCurrentLineEdit = myLineEdit1; + + myGroups1.clear(); + myGroups2.clear(); + myGroups3.clear(); + + // Set selection mode + mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP)); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + + // Set construction mode + int operationMode = myGroupConstructors->checkedId(); + if (operationMode < 0) { + // The dialog has been just displayed + operationMode = 0; + myGroupConstructors->button(0)->setChecked(true); + } + onConstructorsClicked(operationMode); +} + +/*! + \brief SLOT called to change the dialog operation mode. + \param constructorId id of the radio button in mode selector button group +*/ +void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId) +{ + // Clear all fields + myLineEdit1->clear(); + myLineEdit2->clear(); + myLineEdit3->clear(); + + myGroups1.clear(); + myGroups2.clear(); + myGroups3.clear(); + + // Set the first field as current + myCurrentLineEdit = myLineEdit1; + myCurrentLineEdit->setFocus(); + + switch (constructorId) { + case 0: + { + // Set text to the group of arguments and to the first two labels + myGroupArguments->setTitle(tr("DUPLICATION_WITHOUT_ELEMS")); + myTextLabel1->setText(tr("GROUP_NODES_TO_DUPLICATE")); + myTextLabel2->setText(tr("GROUP_NODES_TO_REPLACE")); + + myCheckBoxNewElemGroup->hide(); + myCheckBoxNewNodeGroup->show(); + + // Hide the third field + myTextLabel3->hide(); + mySelectButton3->hide(); + myLineEdit3->hide(); + + break; + } + case 1: + { + // Set text to the group of arguments and to all the labels + myGroupArguments->setTitle(tr("DUPLICATION_WITH_ELEMS")); + myTextLabel1->setText(tr("GROUP_ELEMS_TO_DUPLICATE")); + myTextLabel2->setText(tr("GROUP_NODES_NOT_DUPLICATE")); + myTextLabel3->setText(tr("GROUP_ELEMS_TO_REPLACE")); + + myCheckBoxNewElemGroup->show(); + myCheckBoxNewNodeGroup->show(); + + // Show the third field + myTextLabel3->show(); + mySelectButton3->show(); + myLineEdit3->show(); + + break; + } + } + + // Process selection + onSelectionChanged(); +} + +/*! + \brief SLOT called to apply changes. +*/ +bool SMESHGUI_DuplicateNodesDlg::onApply() +{ + if ( mySMESHGUI->isActiveStudyLocked() || !isValid() ) + return false; + + BusyLocker lock( myBusy ); + + bool toCreateElemGroup = myCheckBoxNewElemGroup->isChecked(); + bool toCreateNodeGroup = myCheckBoxNewNodeGroup->isChecked(); + int operationMode = myGroupConstructors->checkedId(); + + // Apply changes + bool result = false; + SUIT_OverrideCursor aWaitCursor; + + try { + SMESH::SMESH_Mesh_var aMesh = myGroups1[0]->GetMesh(); + SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); + + if ( operationMode == 0 ) { + SMESH::ListOfGroups_var g1 = new SMESH::ListOfGroups(); + g1->length( myGroups1.count() ); + for ( int i = 0; i < myGroups1.count(); i++ ) + g1[i] = myGroups1[i]; + SMESH::ListOfGroups_var g2 = new SMESH::ListOfGroups(); + g2->length( myGroups2.count() ); + for ( int i = 0; i < myGroups2.count(); i++ ) + g2[i] = myGroups2[i]; + + if ( toCreateNodeGroup ) { + SMESH::SMESH_GroupBase_var aNewGroup = + aMeshEditor->DoubleNodeGroupsNew( g1.in(), g2.in() ); + result = !CORBA::is_nil( aNewGroup ); + } + else { + result = aMeshEditor->DoubleNodeGroups( g1.in(), g2.in() ); + } + } + else { + SMESH::ListOfGroups_var g1 = new SMESH::ListOfGroups(); + g1->length( myGroups1.count() ); + for ( int i = 0; i < myGroups1.count(); i++ ) + g1[i] = myGroups1[i]; + SMESH::ListOfGroups_var g2 = new SMESH::ListOfGroups(); + g2->length( myGroups2.count() ); + for ( int i = 0; i < myGroups2.count(); i++ ) + g2[i] = myGroups2[i]; + SMESH::ListOfGroups_var g3 = new SMESH::ListOfGroups(); + g3->length( myGroups3.count() ); + + for ( int i = 0; i < myGroups3.count(); i++ ) + g3[i] = myGroups3[i]; + if ( toCreateElemGroup || toCreateNodeGroup ) { + SMESH::ListOfGroups_var aNewGroups = + aMeshEditor->DoubleNodeElemGroups2New( g1.in(), g2.in(), g3.in(), + toCreateElemGroup, toCreateNodeGroup ); + result = ( aNewGroups[ !toCreateElemGroup ].in() ); + } + else { + result = aMeshEditor->DoubleNodeElemGroups( g1.in(), g2.in(), g3.in() ); + } + } + } + catch (const SALOME::SALOME_Exception& S_ex) { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + catch ( const std::exception& exc ) { + INFOS( "Follow exception was cought:\n\t" << exc.what() ); + } + catch (...){ + INFOS( "Unknown exception was cought !!!" ); + } + + if (!result) { + SUIT_MessageBox::warning(this, + tr("SMESH_WRN_WARNING"), + tr("SMESH_OPERATION_FAILED")); + return false; + } + + // Update GUI + mySelectionMgr->clearSelected(); + SMESH::UpdateView(); + SMESHGUI::Modified(); + mySMESHGUI->updateObjBrowser(true); + + // Reinitialize the dialog + Init(); + + return true; +} + +/*! + \brief SLOT called to apply changes and close the dialog. +*/ +void SMESHGUI_DuplicateNodesDlg::onOk() +{ + if (onApply()) + onClose(); +} + +/*! + \brief SLOT called to close the dialog. +*/ +void SMESHGUI_DuplicateNodesDlg::onClose() +{ + disconnect(mySelectionMgr, 0, this, 0); + disconnect(mySMESHGUI, 0, this, 0); + mySMESHGUI->ResetState(); + mySelectionMgr->clearFilters(); + reject(); +} + +/*! + \brief SLOT called when selection changed. +*/ +void SMESHGUI_DuplicateNodesDlg::onSelectionChanged() +{ + if ( myBusy || !isEnabled() ) return; + + int operationMode = myGroupConstructors->checkedId(); + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + //int aNbSel = aList.Extent(); + + QList aGroups; + + SALOME_ListIteratorOfListIO anIter ( aList ); + bool ok = true; + for ( ; anIter.More() && ok; anIter.Next()) { + SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface( anIter.Value() ); + // check group is selected + ok = !CORBA::is_nil( aGroup ); + // check groups of the same mesh are selected + if ( ok ) { + SMESH::SMESH_Mesh_var aMesh1; + if ( !aGroups.isEmpty() ) aMesh1 = aGroups[0]->GetMesh(); + SMESH::SMESH_Mesh_var aMesh2 = aGroup->GetMesh(); + ok = CORBA::is_nil( aMesh1 ) || aMesh1->_is_equivalent( aMesh2 ); + } + // check group of proper type is selected + if ( ok ) { + SMESH::ElementType aGroupType = aGroup->GetType(); + if ( operationMode == 0 ) { + ok = ( myCurrentLineEdit == myLineEdit1 && aGroupType == SMESH::NODE ) || + ( myCurrentLineEdit == myLineEdit2 && aGroupType != SMESH::NODE ); + } + else { + ok = ( myCurrentLineEdit == myLineEdit1 && ( aGroupType == SMESH::EDGE || + aGroupType == SMESH::FACE ) ) || + ( myCurrentLineEdit == myLineEdit2 && aGroupType == SMESH::NODE ) || + ( myCurrentLineEdit == myLineEdit3 && aGroupType != SMESH::NODE ); + } + } + if ( ok ) aGroups << aGroup; + } + + // Clear current field + myCurrentLineEdit->clear(); + + if ( ok && !aGroups.isEmpty() ) { + if ( myCurrentLineEdit == myLineEdit1 ) myGroups1 = aGroups; + else if ( myCurrentLineEdit == myLineEdit2 ) myGroups2 = aGroups; + else if ( myCurrentLineEdit == myLineEdit3 ) myGroups3 = aGroups; + CORBA::String_var name = aGroups[0]->GetName(); + myCurrentLineEdit->setText( aGroups.count() == 1 ? QString(name).trimmed() : + QObject::tr( "SMESH_OBJECTS_SELECTED" ).arg( aGroups.count() ) ); + } + else { + if ( myCurrentLineEdit == myLineEdit1 ) myGroups1.clear(); + else if ( myCurrentLineEdit == myLineEdit2 ) myGroups2.clear(); + else if ( myCurrentLineEdit == myLineEdit3 ) myGroups3.clear(); + myCurrentLineEdit->clear(); + } + + // Enable/disable "Apply and Close" and "Apply" buttons + bool isDataValid = isValid(); + myButtonOk->setEnabled( isDataValid ); + myButtonApply->setEnabled( isDataValid ); +} + +/*! + \brief SLOT called when selection button clicked. +*/ +void SMESHGUI_DuplicateNodesDlg::onEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + // Set current field for edition + if (send == mySelectButton1) { + myCurrentLineEdit = myLineEdit1; + } + else if (send == mySelectButton2) { + myCurrentLineEdit = myLineEdit2; + } + else if (send == mySelectButton3) { + myCurrentLineEdit = myLineEdit3; + } + + myCurrentLineEdit->setFocus(); + onSelectionChanged(); +} + +/*! + \brief Check if the input data is valid. + \return \c true id the data is valid +*/ +bool SMESHGUI_DuplicateNodesDlg::isValid() +{ + return myGroupConstructors->checkedId() == 1 ? + ( !myGroups1.isEmpty() && !myGroups3.isEmpty() ) : + ( !myGroups1.isEmpty() ); +} + + +/*! + \brief SLOT called when dialog shoud be deativated. +*/ +void SMESHGUI_DuplicateNodesDlg::onDeactivate() +{ + if (isEnabled()) { + mySelectionMgr->clearFilters(); + setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } +} + +/*! + \brief Receive dialog enter events. + Activates the dialog when the mouse cursor enters. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::enterEvent (QEvent*) +{ + if ( !isEnabled() ) { + mySMESHGUI->EmitSignalDeactivateDialog(); + setEnabled(true); + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // Set selection mode + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP)); + } +} + +/*! + \brief Receive close events. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::closeEvent (QCloseEvent*) +{ + onClose(); +} + +/*! + \brief Receive key press events. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + onHelp(); + } +} + +/*! + \brief Show the dialog help page. +*/ +void SMESHGUI_DuplicateNodesDlg::onHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h new file mode 100644 index 000000000..2714ba093 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h @@ -0,0 +1,120 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_DuplicateNodesDlg.h +// Author : Michael ZORIN, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_DUPLICATENODESDLG_H +#define SMESHGUI_DUPLICATENODESDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) + +class QButtonGroup; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QCheckBox; + +class LightApp_SelectionMgr; + +class SMESHGUI; + +/*! + \class SMESHGUI_DuplicateNodesDlg + \brief Dialog for duplication of nodes. +*/ +class SMESHGUI_EXPORT SMESHGUI_DuplicateNodesDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_DuplicateNodesDlg( SMESHGUI* ); + ~SMESHGUI_DuplicateNodesDlg(); + +private: + void Init(); + + bool isValid(); + + void closeEvent( QCloseEvent* ); + void enterEvent( QEvent* ); + void keyPressEvent( QKeyEvent* ); + +private slots: + void onConstructorsClicked( int ); + + void onOk(); + void onClose(); + bool onApply(); + void onHelp(); + + void onEditCurrentArgument(); + void onSelectionChanged(); + + void onDeactivate(); + +private: + QLineEdit* myCurrentLineEdit; + + QButtonGroup* myGroupConstructors; + + QGroupBox* myGroupArguments; + QLabel* myTextLabel1; + QLabel* myTextLabel2; + QLabel* myTextLabel3; + QPushButton* mySelectButton1; + QPushButton* mySelectButton2; + QPushButton* mySelectButton3; + QLineEdit* myLineEdit1; + QLineEdit* myLineEdit2; + QLineEdit* myLineEdit3; + QCheckBox* myCheckBoxNewElemGroup; + QCheckBox* myCheckBoxNewNodeGroup; + + QPushButton* myButtonOk; + QPushButton* myButtonApply; + QPushButton* myButtonClose; + QPushButton* myButtonHelp; + + SMESHGUI* mySMESHGUI; + LightApp_SelectionMgr* mySelectionMgr; + + QList myGroups1; + QList myGroups2; + QList myGroups3; + + bool myBusy; + + QString myHelpFileName; +}; + +#endif // SMESHGUI_DUPLICATENODESDLG_H diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx deleted file mode 100644 index c8aa3710d..000000000 --- a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx +++ /dev/null @@ -1,1138 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_EditMeshDlg.cxx -// Author : Open CASCADE S.A.S. -// SMESH includes -// -#include "SMESHGUI_EditMeshDlg.h" - -#include "SMESHGUI.h" -#include "SMESHGUI_Utils.h" -#include "SMESHGUI_VTKUtils.h" -#include "SMESHGUI_MeshUtils.h" -#include "SMESHGUI_SpinBox.h" - -#include -#include -#include -#include - -// SALOME GUI includes -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -// OCCT includes -#include -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Group) -#include CORBA_SERVER_HEADER(SMESH_MeshEditor) - -// VTK includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SPACING 6 -#define MARGIN 11 - -namespace SMESH -{ - class TIdPreview - { // to display in the viewer IDs of the selected elements - SVTK_ViewWindow* myViewWindow; - - vtkUnstructuredGrid* myIdGrid; - SALOME_Actor* myIdActor; - - vtkUnstructuredGrid* myPointsNumDataSet; - vtkMaskPoints* myPtsMaskPoints; - vtkSelectVisiblePoints* myPtsSelectVisiblePoints; - vtkLabeledDataMapper* myPtsLabeledDataMapper; - vtkTextProperty* aPtsTextProp; - bool myIsPointsLabeled; - vtkActor2D* myPointLabels; - - std::vector myIDs; - - public: - TIdPreview(SVTK_ViewWindow* theViewWindow): - myViewWindow(theViewWindow) - { - myIdGrid = vtkUnstructuredGrid::New(); - - // Create and display actor - vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); - aMapper->SetInput( myIdGrid ); - - myIdActor = SALOME_Actor::New(); - myIdActor->SetInfinitive(true); - myIdActor->VisibilityOff(); - myIdActor->PickableOff(); - - myIdActor->SetMapper( aMapper ); - aMapper->Delete(); - - myViewWindow->AddActor(myIdActor); - - //Definition of points numbering pipeline - myPointsNumDataSet = vtkUnstructuredGrid::New(); - - myPtsMaskPoints = vtkMaskPoints::New(); - myPtsMaskPoints->SetInput(myPointsNumDataSet); - myPtsMaskPoints->SetOnRatio(1); - - myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New(); - myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput()); - myPtsSelectVisiblePoints->SelectInvisibleOff(); - myPtsSelectVisiblePoints->SetTolerance(0.1); - - myPtsLabeledDataMapper = vtkLabeledDataMapper::New(); - myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput()); - 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, - std::list & aGrCentersXYZ ) - { - vtkPoints* aPoints = vtkPoints::New(); - aPoints->SetNumberOfPoints(theElemsIdMap.Extent()); - myIDs.clear(); - - TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); - for( ; idIter.More(); idIter.Next() ) { - myIDs.push_back(idIter.Key()); - } - - gp_XYZ aXYZ; - std::list::iterator coordIt = aGrCentersXYZ.begin(); - for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) { - aXYZ = *coordIt; - aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() ); - } - myIdGrid->SetPoints(aPoints); - aPoints->Delete(); - - myIdActor->GetMapper()->Update(); - } - - void AddToRender(vtkRenderer* theRenderer) - { - myIdActor->AddToRender(theRenderer); - - myPtsSelectVisiblePoints->SetRenderer(theRenderer); - theRenderer->AddActor2D(myPointLabels); - } - - void RemoveFromRender(vtkRenderer* theRenderer) - { - myIdActor->RemoveFromRender(theRenderer); - - myPtsSelectVisiblePoints->SetRenderer(theRenderer); - theRenderer->RemoveActor(myPointLabels); - } - - void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true ) - { - myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints(); - - if ( myIsPointsLabeled ) { - myPointsNumDataSet->ShallowCopy(myIdGrid); - vtkDataSet *aDataSet = myPointsNumDataSet; - int aNbElem = myIDs.size(); - vtkIntArray *anArray = vtkIntArray::New(); - anArray->SetNumberOfValues( aNbElem ); - for ( int i = 0; i < aNbElem; i++ ) - anArray->SetValue( i, myIDs[i] ); - aDataSet->GetPointData()->SetScalars( anArray ); - anArray->Delete(); - myPtsMaskPoints->SetInput( aDataSet ); - myPointLabels->SetVisibility( theIsActorVisible ); - } - else { - myPointLabels->SetVisibility( false ); - } - } - - ~TIdPreview() - { - RemoveFromRender(myViewWindow->getRenderer()); - - myIdGrid->Delete(); - - myViewWindow->RemoveActor(myIdActor); - myIdActor->Delete(); - - //Deleting of points numbering pipeline - //--------------------------------------- - myPointsNumDataSet->Delete(); - - //myPtsLabeledDataMapper->RemoveAllInputs(); //vtk 5.0 porting - myPtsLabeledDataMapper->Delete(); - - //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting - myPtsSelectVisiblePoints->Delete(); - - //myPtsMaskPoints->UnRegisterAllOutputs(); //vtk 5.0 porting - myPtsMaskPoints->Delete(); - - myPointLabels->Delete(); - -// myTimeStamp->Delete(); - } - }; -} - -static const char * IconFirst[] = { -"18 10 2 1", -" g None", -". g #000000", -" . . ", -" .. .. .. ", -" .. ... ... ", -" .. .... .... ", -" .. ..... ..... ", -" .. ..... ..... ", -" .. .... .... ", -" .. ... ... ", -" .. .. .. ", -" . . "}; - -//================================================================================= -// class : SMESHGUI_EditMeshDlg() -// purpose : -//================================================================================= -SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule, - int theAction) - : QDialog(SMESH::GetDesktop(theModule)), - mySMESHGUI(theModule), - mySelectionMgr(SMESH::GetSelectionMgr(theModule)), - myAction(theAction) -{ - setModal(false); - setAttribute(Qt::WA_DeleteOnClose, true); - setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES")); - - myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI )); - - SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI ); - QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES"))); - QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS"))); - QPixmap IconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); - QPixmap IconAdd (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND"))); - QPixmap IconRemove (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE"))); - - setSizeGripEnabled(true); - - QVBoxLayout* DlgLayout = new QVBoxLayout(this); - DlgLayout->setSpacing(SPACING); - DlgLayout->setMargin(MARGIN); - - /***************************************************************/ - GroupConstructors = new QGroupBox(myAction == 1 ? - tr("SMESH_MERGE_ELEMENTS") : - tr("SMESH_MERGE_NODES"), - this); - - QButtonGroup* ButtonGroup = new QButtonGroup(this); - QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors); - GroupConstructorsLayout->setSpacing(SPACING); - GroupConstructorsLayout->setMargin(MARGIN); - - RadioButton = new QRadioButton(GroupConstructors); - RadioButton->setIcon(myAction == 1 ? IconMergeElems : IconMergeNodes); - RadioButton->setChecked(true); - GroupConstructorsLayout->addWidget(RadioButton); - ButtonGroup->addButton(RadioButton, 0); - - /***************************************************************/ - // Controls for mesh defining - GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this); - QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh); - GroupMeshLayout->setSpacing(SPACING); - GroupMeshLayout->setMargin(MARGIN); - - TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh); - SelectMeshButton = new QPushButton(GroupMesh); - SelectMeshButton->setIcon(IconSelect); - LineEditMesh = new QLineEdit(GroupMesh); - LineEditMesh->setReadOnly(true); - - GroupMeshLayout->addWidget(TextLabelName); - GroupMeshLayout->addWidget(SelectMeshButton); - GroupMeshLayout->addWidget(LineEditMesh); - - /***************************************************************/ - // Controls for coincident elements detecting - GroupCoincident = new QGroupBox(myAction == 1 ? - tr("COINCIDENT_ELEMENTS") : - tr("COINCIDENT_NODES"), - this); - - QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincident); - GroupCoincidentLayout->setSpacing(SPACING); - GroupCoincidentLayout->setMargin(MARGIN); - - if (myAction == 0) { // case merge nodes - TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), GroupCoincident); - SpinBoxTolerance = new SMESHGUI_SpinBox(GroupCoincident); - SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - - GroupCoincidentLayout->addWidget(TextLabelTolerance, 0, 0); - GroupCoincidentLayout->addWidget(SpinBoxTolerance, 0, 1); - } - else { - TextLabelTolerance = 0; - SpinBoxTolerance = 0; - } - - int row = GroupCoincidentLayout->rowCount(); - - ListCoincident = new QListWidget(GroupCoincident); - ListCoincident->setSelectionMode(QListWidget::ExtendedSelection); - - DetectButton = new QPushButton(tr("DETECT"), GroupCoincident); - AddGroupButton = new QPushButton(tr("SMESH_BUT_ADD"), GroupCoincident); - RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincident); - - SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincident); - - GroupCoincidentLayout->addWidget(ListCoincident, row, 0, 4, 2); - GroupCoincidentLayout->addWidget(DetectButton, row, 2); - GroupCoincidentLayout->addWidget(AddGroupButton, row+2, 2); - GroupCoincidentLayout->addWidget(RemoveGroupButton, row+3, 2); - GroupCoincidentLayout->addWidget(SelectAllCB, row+4, 0, 1, 3); - GroupCoincidentLayout->setRowMinimumHeight(row+1, 10); - GroupCoincidentLayout->setRowStretch(row+1, 5); - - /***************************************************************/ - // Controls for editing the selected group - GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this); - QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit); - GroupEditLayout->setSpacing(SPACING); - GroupEditLayout->setMargin(MARGIN); - - ListEdit = new QListWidget(GroupEdit); - //ListEdit->setRowMode(QListBox::FixedNumber); - //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn); - //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff); - ListEdit->setFlow( QListView::LeftToRight ); - ListEdit->setSelectionMode(QListWidget::ExtendedSelection); - - AddElemButton = new QPushButton(GroupEdit); - AddElemButton->setIcon(IconAdd); - RemoveElemButton = new QPushButton(GroupEdit); - RemoveElemButton->setIcon(IconRemove); - SetFirstButton = new QPushButton(GroupEdit); - SetFirstButton->setIcon(QPixmap(IconFirst)); - - GroupEditLayout->addWidget(ListEdit, 0, 0, 2, 1); - GroupEditLayout->addWidget(AddElemButton, 0, 1); - GroupEditLayout->addWidget(RemoveElemButton, 0, 2); - GroupEditLayout->addWidget(SetFirstButton, 1, 1, 1, 2); - - /***************************************************************/ - GroupButtons = new QGroupBox(this); - QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons); - GroupButtonsLayout->setSpacing(SPACING); - GroupButtonsLayout->setMargin(MARGIN); - - buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons); - buttonOk->setAutoDefault(true); - buttonOk->setDefault(true); - buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); - buttonApply->setAutoDefault(true); - buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons); - buttonCancel->setAutoDefault(true); - buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons); - buttonHelp->setAutoDefault(true); - - GroupButtonsLayout->addWidget(buttonOk); - GroupButtonsLayout->addSpacing(10); - GroupButtonsLayout->addWidget(buttonApply); - GroupButtonsLayout->addSpacing(10); - GroupButtonsLayout->addStretch(); - GroupButtonsLayout->addWidget(buttonCancel); - GroupButtonsLayout->addWidget(buttonHelp); - - /***************************************************************/ - DlgLayout->addWidget(GroupConstructors); - DlgLayout->addWidget(GroupMesh); - DlgLayout->addWidget(GroupCoincident); - DlgLayout->addWidget(GroupEdit); - DlgLayout->addWidget(GroupButtons); - - Init(); // Initialisations -} - -//================================================================================= -// function : ~SMESHGUI_EditMeshDlg() -// purpose : Destroys the object and frees any allocated resources -//================================================================================= -SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg() -{ - delete myIdPreview; -} - -//================================================================================= -// function : Init() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::Init() -{ - if (myAction == 0) { - SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, 5); - SpinBoxTolerance->SetValue(1e-05); - } - - RadioButton->setChecked(true); - - myEditCurrentArgument = (QWidget*)LineEditMesh; - - myActor = 0; - mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil(); - - 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); - - QList aListOfFilters; - if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); - if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); - - 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(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); - - connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); - connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect())); - connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup())); - connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup())); - connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup())); - connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool))); - connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup())); - connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement())); - connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement())); - connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) ); - - connect(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())); - - SetFirstButton->setEnabled(false); - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - - // Init Mesh field from selection - SelectionIntoArgument(); - - myHelpFileName = "merging_elements_page.html"; -} - -//================================================================================= -// function : FindGravityCenter() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, - std::list< gp_XYZ > & theGrCentersXYZ) -{ - if (!myActor) - return; - - SMDS_Mesh* aMesh = 0; - aMesh = myActor->GetObject()->GetMesh(); - if (!aMesh) - return; - - int nbNodes; - - TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); - for( ; idIter.More(); idIter.Next() ) { - const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key()); - if ( !anElem ) - continue; - - gp_XYZ anXYZ(0., 0., 0.); - SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator(); - for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) ); - } - anXYZ.Divide( nbNodes ); - - theGrCentersXYZ.push_back( anXYZ ); - } -} - -//================================================================================= -// function : ClickOnApply() -// purpose : -//================================================================================= -bool SMESHGUI_EditMeshDlg::ClickOnApply() -{ - if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil()) - return false; - - try { - SUIT_OverrideCursor aWaitCursor; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - - SMESH::long_array_var anIds = new SMESH::long_array; - SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array; - - aGroupsOfElements->length(ListCoincident->count()); - - int anArrayNum = 0; - for (int i = 0; i < ListCoincident->count(); i++) { - QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts); - - anIds->length(aListIds.count()); - for (int i = 0; i < aListIds.count(); i++) - anIds[i] = aListIds[i].toInt(); - - aGroupsOfElements[anArrayNum++] = anIds.inout(); - } - - if( myAction == 0 ) - aMeshEditor->MergeNodes (aGroupsOfElements.inout()); - else - aMeshEditor->MergeElements (aGroupsOfElements.inout()); - - } catch(...) { - } - - SMESH::UpdateView(); - - onDetect(); - return true; -} - -//================================================================================= -// function : ClickOnOk() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::ClickOnOk() -{ - if (ClickOnApply()) - ClickOnCancel(); -} - -//================================================================================= -// function : ClickOnCancel() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::ClickOnCancel() -{ - 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 : ClickOnHelp() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::ClickOnHelp() -{ - LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) - app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); - else { - QString platform; -#ifdef WIN32 - platform = "winapplication"; -#else - platform = "application"; -#endif - SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); - } -} - -//================================================================================= -// function : onEditGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onEditGroup() -{ - QList selItems = ListCoincident->selectedItems(); - if ( selItems.count() != 1 ) { - ListEdit->clear(); - return; - } - - QStringList aNewIds; - - for (int i = 0; i < ListEdit->count(); i++ ) - aNewIds.append(ListEdit->item(i)->text()); - - ListCoincident->clearSelection(); - selItems.first()->setText(aNewIds.join(" ")); - selItems.first()->setSelected(true); -} - -//================================================================================= -// function : updateControls() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::updateControls() -{ - if (ListEdit->count() == 0) - SetFirstButton->setEnabled(false); - bool enable = !(myMesh->_is_nil()) && ListCoincident->count(); - buttonOk->setEnabled(enable); - buttonApply->setEnabled(enable); -} - -//================================================================================= -// function : onDetect() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onDetect() -{ - if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) - return; - - try { - SUIT_OverrideCursor aWaitCursor; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - - ListCoincident->clear(); - ListEdit->clear(); - - SMESH::array_of_long_array_var aGroupsArray; - - switch (myAction) { - case 0 : - if(!mySubMeshOrGroup->_is_nil()) - aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aGroupsArray); - else - aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aGroupsArray); - break; - case 1 : - if(!mySubMeshOrGroup->_is_nil()) - aMeshEditor->FindEqualElements(mySubMeshOrGroup, aGroupsArray); - else - aMeshEditor->FindEqualElements(myMesh, aGroupsArray); - break; - } - - for (int i = 0; i < aGroupsArray->length(); i++) { - SMESH::long_array& aGroup = aGroupsArray[i]; - - QStringList anIDs; - for (int j = 0; j < aGroup.length(); j++) - anIDs.append(QString::number(aGroup[j])); - - ListCoincident->addItem(anIDs.join(" ")); - } - } catch(...) { - } - - ListCoincident->selectAll(); - updateControls(); -} - -//================================================================================= -// function : onSelectGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSelectGroup() -{ - if (myIsBusy || !myActor) - return; - myEditCurrentArgument = (QWidget*)ListCoincident; - - ListEdit->clear(); - - TColStd_MapOfInteger anIndices; - QList selItems = ListCoincident->selectedItems(); - QListWidgetItem* anItem; - QStringList aListIds; - - ListEdit->clear(); - - foreach(anItem, selItems) { - aListIds = anItem->text().split(" ", QString::SkipEmptyParts); - for (int i = 0; i < aListIds.count(); i++) - anIndices.Add(aListIds[i].toInt()); - } - - if (selItems.count() == 1) { - ListEdit->addItems(aListIds); - ListEdit->selectAll(); - } - - mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); - SALOME_ListIO aList; - aList.Append(myActor->getIO()); - mySelectionMgr->setSelectedObjects(aList,false); - - if (myAction == 0) { - myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } - else { - std::list< gp_XYZ > aGrCentersXYZ; - FindGravityCenter(anIndices, aGrCentersXYZ); - myIdPreview->SetElemsData( anIndices, aGrCentersXYZ); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } - - updateControls(); -} - -//================================================================================= -// function : onSelectAll() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSelectAll (bool isToggled) -{ - if ( isToggled ) - ListCoincident->selectAll(); - else - ListCoincident->clearSelection(); -} - -//================================================================================= -// function : onSelectElementFromGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSelectElementFromGroup() -{ - if (myIsBusy || !myActor) - return; - - TColStd_MapOfInteger anIndices; - QList selItems = ListEdit->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) - anIndices.Add(anItem->text().toInt()); - - SetFirstButton->setEnabled(selItems.count() == 1); - - mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); - SALOME_ListIO aList; - aList.Append(myActor->getIO()); - mySelectionMgr->setSelectedObjects(aList); - - if (myAction == 0) { - myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } - else { - std::list< gp_XYZ > aGrCentersXYZ; - FindGravityCenter(anIndices, aGrCentersXYZ); - myIdPreview->SetElemsData(anIndices, aGrCentersXYZ); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } -} - -//================================================================================= -// function : onAddGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onAddGroup() -{ - if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) - return; - - QString anIDs = ""; - SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs); - - ListCoincident->clearSelection(); - ListCoincident->addItem(anIDs); - int nbGroups = ListCoincident->count(); - if (nbGroups) { - ListCoincident->setCurrentRow(nbGroups-1); - ListCoincident->item(nbGroups-1)->setSelected(true); - } - else { - // VSR ? this code seems to be never executed!!! - ListCoincident->setCurrentRow(0); - //ListCoincident->setSelected(0, true); // VSR: no items - no selection - } - - updateControls(); -} - -//================================================================================= -// function : onRemoveGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onRemoveGroup() -{ - if (myEditCurrentArgument != (QWidget*)ListCoincident) - return; - myIsBusy = true; - - QList selItems = ListCoincident->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) - delete anItem; - - ListEdit->clear(); - updateControls(); - - myIsBusy = false; -} - -//================================================================================= -// function : onAddElement() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onAddElement() -{ - if (!myActor) - return; - myIsBusy = true; - - QString aListStr = ""; - int aNbNnodes = 0; - - aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); - if (aNbNnodes < 1) - return; - - QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts); - - for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) { - QList found = ListEdit->findItems(*it, Qt::MatchExactly); - if ( found.count() == 0 ) { - QListWidgetItem* anItem = new QListWidgetItem(*it); - ListEdit->addItem(anItem); - anItem->setSelected(true); - } - else { - QListWidgetItem* anItem; - foreach(anItem, found) anItem->setSelected(true); - } - } - - myIsBusy = false; - onEditGroup(); -} - -//================================================================================= -// function : onRemoveElement() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onRemoveElement() -{ - if (myEditCurrentArgument != (QWidget*)ListCoincident) - return; - myIsBusy = true; - - QList selItems = ListEdit->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) - delete anItem; - - myIsBusy = false; - onEditGroup(); -} - -//================================================================================= -// function : onSetFirst() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSetFirst() -{ - if (myEditCurrentArgument != (QWidget*)ListCoincident) - return; - myIsBusy = true; - - QList selItems = ListEdit->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) { - ListEdit->takeItem(ListEdit->row(anItem)); - ListEdit->insertItem(0, anItem); - } - - myIsBusy = false; - onEditGroup(); -} - -//================================================================================= -// function : SetEditCurrentArgument() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::SetEditCurrentArgument() -{ - QPushButton* send = (QPushButton*)sender(); - - disconnect(mySelectionMgr, 0, this, 0); - mySelectionMgr->clearSelected(); - mySelectionMgr->clearFilters(); - - if (send == SelectMeshButton) { - myEditCurrentArgument = (QWidget*)LineEditMesh; - SMESH::SetPointRepresentation(false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); - } - - myEditCurrentArgument->setFocus(); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - SelectionIntoArgument(); -} - -//================================================================================= -// function : SelectionIntoArgument() -// purpose : Called when selection as changed or other case -//================================================================================= -void SMESHGUI_EditMeshDlg::SelectionIntoArgument() -{ - if (myEditCurrentArgument == (QWidget*)LineEditMesh) { - QString aString = ""; - LineEditMesh->setText(aString); - - ListCoincident->clear(); - ListEdit->clear(); - myActor = 0; - - int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); - if (nbSel != 1) - 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(IO)->_is_nil() || //SUBMESH OR GROUP - !SMESH::IObjectToInterface(IO)->_is_nil()) && - !SMESH::IObjectToInterface(IO)->_is_nil()) - mySubMeshOrGroup = SMESH::IObjectToInterface(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); - } -} - -//================================================================================= -// function : DeactivateActiveDialog() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::DeactivateActiveDialog() -{ - if (GroupConstructors->isEnabled()) { - GroupConstructors->setEnabled(false); - GroupMesh->setEnabled(false); - GroupCoincident->setEnabled(false); - GroupEdit->setEnabled(false); - GroupButtons->setEnabled(false); - mySMESHGUI->ResetState(); - mySMESHGUI->SetActiveDialogBox(0); - } - - mySelectionMgr->clearSelected(); - disconnect(mySelectionMgr, 0, this, 0); -} - -//================================================================================= -// function : ActivateThisDialog() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::ActivateThisDialog() -{ - /* Emit a signal to deactivate the active dialog */ - mySMESHGUI->EmitSignalDeactivateDialog(); - GroupConstructors->setEnabled(true); - GroupMesh->setEnabled(true); - GroupCoincident->setEnabled(true); - GroupEdit->setEnabled(true); - GroupButtons->setEnabled(true); - - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - mySMESHGUI->SetActiveDialogBox((QDialog*)this); - SelectionIntoArgument(); -} - -//================================================================================= -// function : enterEvent() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::enterEvent(QEvent*) -{ - if (!GroupConstructors->isEnabled()) - ActivateThisDialog(); -} - -//================================================================================= -// function : closeEvent() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent*) -{ - /* same than click on cancel button */ - ClickOnCancel(); -} - -//======================================================================= -//function : hideEvent -//purpose : caused by ESC key -//======================================================================= -void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent *) -{ - if (!isMinimized()) - ClickOnCancel(); -} - -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e) -{ - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; - - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - ClickOnHelp(); - } -} diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.h b/src/SMESHGUI/SMESHGUI_EditMeshDlg.h deleted file mode 100644 index 3b96bede4..000000000 --- a/src/SMESHGUI/SMESHGUI_EditMeshDlg.h +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_EditMeshDlg.h -// Author : Open CASCADE S.A.S. -// -#ifndef SMESHGUI_EDITMESHDLG_H -#define SMESHGUI_EDITMESHDLG_H - -// SMESH includes -#include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include - -// OCCT includes -#include - -// STL includes -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Mesh) - -class QGroupBox; -class QLabel; -class QLineEdit; -class QPushButton; -class QRadioButton; -class QCheckBox; -class QListWidget; -class SMESHGUI; -class SMESHGUI_SpinBox; -class SMESH_Actor; -class SVTK_Selector; -class LightApp_SelectionMgr; -class SUIT_SelectionFilter; -class TColStd_MapOfInteger; - -namespace SMESH -{ - struct TIdPreview; -} - -//================================================================================= -// class : SMESHGUI_EditMeshDlg -// purpose : -//================================================================================= -class SMESHGUI_EXPORT SMESHGUI_EditMeshDlg : public QDialog -{ - Q_OBJECT; - -public: - SMESHGUI_EditMeshDlg( SMESHGUI*, int ); - ~SMESHGUI_EditMeshDlg(); - -private: - void Init(); - void closeEvent( QCloseEvent* ); - void enterEvent( QEvent* ); /* mouse enter the QWidget */ - void hideEvent( QHideEvent* ); /* ESC key */ - void keyPressEvent( QKeyEvent* ); - void onEditGroup(); - - void FindGravityCenter( TColStd_MapOfInteger&, - std::list& ); - // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list - -private: - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ - LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ - SVTK_Selector* mySelector; - - QWidget* myEditCurrentArgument; - - SMESH::SMESH_Mesh_var myMesh; - SMESH::SMESH_IDSource_var mySubMeshOrGroup; - SMESH_Actor* myActor; - SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter; - - SMESH::TIdPreview* myIdPreview; - - int myAction; - bool myIsBusy; - - // Widgets - QGroupBox* GroupConstructors; - QRadioButton* RadioButton; - - QGroupBox* GroupButtons; - QPushButton* buttonOk; - QPushButton* buttonCancel; - QPushButton* buttonApply; - QPushButton* buttonHelp; - - QGroupBox* GroupMesh; - QLabel* TextLabelName; - QPushButton* SelectMeshButton; - QLineEdit* LineEditMesh; - - QGroupBox* GroupCoincident; - QLabel* TextLabelTolerance; - SMESHGUI_SpinBox* SpinBoxTolerance; - QPushButton* DetectButton; - QListWidget* ListCoincident; - QPushButton* AddGroupButton; - QPushButton* RemoveGroupButton; - QCheckBox* SelectAllCB; - - QGroupBox* GroupEdit; - QListWidget* ListEdit; - QPushButton* AddElemButton; - QPushButton* RemoveElemButton; - QPushButton* SetFirstButton; - - QString myHelpFileName; - - private slots: - void ClickOnOk(); - void ClickOnCancel(); - bool ClickOnApply(); - void ClickOnHelp(); - void updateControls(); - void onDetect(); - void onAddGroup(); - void onRemoveGroup(); - void onSelectGroup(); - void onSelectAll( bool ); - void onSelectElementFromGroup(); - void onAddElement(); - void onRemoveElement(); - void onSetFirst(); - void SetEditCurrentArgument(); - void SelectionIntoArgument(); - void DeactivateActiveDialog(); - void ActivateThisDialog(); -}; - -#endif // SMESHGUI_EDITMESHDLG_H diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx index a8cffc9e3..4ec84dce9 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ExtrusionAlongPathDlg.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. // SMESH includes -// + #include "SMESHGUI_ExtrusionAlongPathDlg.h" #include "SMESHGUI.h" @@ -33,6 +34,7 @@ #include "SMESHGUI_SpinBox.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_MeshEditPreview.h" #include #include @@ -108,8 +110,7 @@ private: // purpose : constructor //================================================================================= SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theModule ) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), + : SMESHGUI_PreviewDlg( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), myFilterDlg( 0 ) { @@ -166,8 +167,9 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod ElementsLineEdit = new QLineEdit(GroupArguments); ElementsLineEdit->setValidator(myIdValidator); - QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); - connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + ElementsLineEdit->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); // Controls for the whole mesh selection MeshCheck = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); @@ -186,15 +188,6 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod PathMeshLineEdit = new QLineEdit(PathGrp); PathMeshLineEdit->setReadOnly(true); - // Controls for path shape selection - QLabel* PathShapeLab = new QLabel(tr("SMESH_PATH_SHAPE"), PathGrp); - - SelectPathShapeButton = new QToolButton(PathGrp); - SelectPathShapeButton->setIcon(selectImage); - - PathShapeLineEdit = new QLineEdit(PathGrp); - PathShapeLineEdit->setReadOnly(true); - // Controls for path starting point selection QLabel* StartPointLab = new QLabel(tr("SMESH_PATH_START"), PathGrp); @@ -208,12 +201,9 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod PathGrpLayout->addWidget(PathMeshLab, 0, 0); PathGrpLayout->addWidget(SelectPathMeshButton, 0, 1); PathGrpLayout->addWidget(PathMeshLineEdit, 0, 2); - PathGrpLayout->addWidget(PathShapeLab, 1, 0); - PathGrpLayout->addWidget(SelectPathShapeButton, 1, 1); - PathGrpLayout->addWidget(PathShapeLineEdit, 1, 2); - PathGrpLayout->addWidget(StartPointLab, 2, 0); - PathGrpLayout->addWidget(SelectStartPointButton, 2, 1); - PathGrpLayout->addWidget(StartPointLineEdit, 2, 2); + PathGrpLayout->addWidget(StartPointLab, 1, 0); + PathGrpLayout->addWidget(SelectStartPointButton, 1, 1); + PathGrpLayout->addWidget(StartPointLineEdit, 1, 2); BasePointGrp = new QGroupBox(tr("SMESH_BASE_POINT"), GroupArguments); BasePointGrp->setCheckable(true); @@ -272,16 +262,20 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments); MakeGroupsCheck->setChecked(true); + //Preview check box + myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); + // layouting GroupArgumentsLayout->addWidget(ElementsLab, 0, 0); GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); GroupArgumentsLayout->addWidget(ElementsLineEdit, 0, 2); - GroupArgumentsLayout->addWidget(filterBtn, 0, 3); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 3); GroupArgumentsLayout->addWidget(MeshCheck, 1, 0, 1, 4); GroupArgumentsLayout->addWidget(PathGrp, 2, 0, 1, 4); GroupArgumentsLayout->addWidget(BasePointGrp, 3, 0, 1, 4); GroupArgumentsLayout->addWidget(AnglesGrp, 4, 0, 1, 4); - GroupArgumentsLayout->addWidget(MakeGroupsCheck, 5, 0, 1, 4); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 5, 0, 1, 4); + GroupArgumentsLayout->addWidget(MakeGroupsCheck, 6, 0, 1, 4); /***************************************************************/ // common buttons group box @@ -319,10 +313,10 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod /***************************************************************/ // Initialisations - XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - AngleSpin->RangeStepAndValidator(-180.0, 180.0, 5.0, 3); + XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + AngleSpin->RangeStepAndValidator(-180.0, 180.0, 5.0, "angle_precision"); mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); @@ -337,7 +331,8 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); myElementsFilter = new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR); - myPathMeshFilter = new SMESH_TypeFilter (MESH); + //myPathMeshFilter = new SMESH_TypeFilter (MESH); + myPathMeshFilter = new SMESH_TypeFilter(MESHorSUBMESH); myHelpFileName = "extrusion_along_path_page.html"; @@ -357,7 +352,6 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod connect(SelectElementsButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(SelectPathMeshButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); - connect(SelectPathShapeButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(SelectStartPointButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); connect(SelectBasePointButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument())); @@ -366,12 +360,23 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(reject())); connect(ElementsLineEdit, SIGNAL(textChanged(const QString&)), - SLOT(onTextChange(const QString&))); + SLOT(onTextChange(const QString&))); connect(StartPointLineEdit, SIGNAL(textChanged(const QString&)), - SLOT(onTextChange(const QString&))); + SLOT(onTextChange(const QString&))); connect(MeshCheck, SIGNAL(toggled(bool)), SLOT(onSelectMesh())); + connect(XSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(YSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(ZSpin, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(AddAngleButton, SIGNAL(clicked()), this, SLOT(toDisplaySimulation())); + connect(RemoveAngleButton, SIGNAL(clicked()), this, SLOT(toDisplaySimulation())); + connect(LinearAnglesCheck, SIGNAL(toggled(bool)), SLOT(onSelectMesh())); + + + //To Connect preview check box + connectPreviewControl(); + AnglesList->installEventFilter(this); ElementsLineEdit->installEventFilter(this); StartPointLineEdit->installEventFilter(this); @@ -405,12 +410,10 @@ void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls) myMesh = SMESH::SMESH_Mesh::_nil(); myIDSource = SMESH::SMESH_IDSource::_nil(); myMeshActor = 0; - myPathMesh = SMESH::SMESH_Mesh::_nil(); - myPathShape = GEOM::GEOM_Object::_nil(); + myPath = SMESH::SMESH_IDSource::_nil(); ElementsLineEdit->clear(); PathMeshLineEdit->clear(); - PathShapeLineEdit->clear(); StartPointLineEdit->clear(); if (ResetControls) { @@ -422,6 +425,8 @@ void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls) MeshCheck->setChecked(false); ConstructorsClicked(0); onSelectMesh(); + myPreviewCheckBox->setChecked(false); + onDisplaySimulation(false); } SetEditCurrentArgument(0); } @@ -436,6 +441,8 @@ void SMESHGUI_ExtrusionAlongPathDlg::ConstructorsClicked (int type) disconnect(mySelectionMgr, 0, this, 0); + hidePreview(); + if (type == 0) GroupArguments->setTitle(tr("EXTRUSION_1D")); else if (type == 1) @@ -454,19 +461,19 @@ void SMESHGUI_ExtrusionAlongPathDlg::ConstructorsClicked (int type) SMESH::SetPointRepresentation(false); if (MeshCheck->isChecked()) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); + aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->installFilter(myElementsFilter); } else { if (type == 0) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - } + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); + } if (type == 1) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - } + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + } } } connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); @@ -483,50 +490,21 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply() if (mySMESHGUI->isActiveStudyLocked()) return false; - if (myMesh->_is_nil() || MeshCheck->isChecked() && myIDSource->_is_nil() || - !myMeshActor || myPathMesh->_is_nil() || myPathShape->_is_nil()) + //if (myMesh->_is_nil() || MeshCheck->isChecked() && myIDSource->_is_nil() || + // !myMeshActor || myPathMesh->_is_nil() || myPathShape->_is_nil()) + if ( myMesh->_is_nil() || (MeshCheck->isChecked() && myIDSource->_is_nil()) || + /*!myMeshActor ||*/ myPath->_is_nil() ) return false; if (!isValid()) return false; - SMESH::long_array_var anElementsId = new SMESH::long_array; - - if (!MeshCheck->isChecked()) { - // If "Select whole mesh, submesh or group" check box is off -> - // use only elements of given type selected by user - - SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh(); - if (aMesh) { - QStringList aListElementsId = ElementsLineEdit->text().split(" ", QString::SkipEmptyParts); - anElementsId = new SMESH::long_array; - anElementsId->length(aListElementsId.count()); - bool bOk; - int j = 0; - for (int i = 0; i < aListElementsId.count(); i++) { - long ind = aListElementsId[ i ].toLong(&bOk); - if (bOk) { - const SMDS_MeshElement* e = aMesh->FindElement(ind); - if (e) { - bool typeMatch = Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge || - Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face; - if (typeMatch) - anElementsId[ j++ ] = ind; - } - } - } - anElementsId->length(j); - } - - if (anElementsId->length() <= 0) { - return false; - } - } + SMESH::long_array_var anElementsId = getSelectedElements(); if (StartPointLineEdit->text().trimmed().isEmpty()) { return false; } - + bool bOk; long aNodeStart = StartPointLineEdit->text().toLong(&bOk); if (!bOk) { @@ -534,19 +512,13 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply() } QStringList aParameters; + + //get angles + SMESH::double_array_var anAngles = getAngles(); + + for (int i = 0; i < myAnglesList.count(); i++) + aParameters << AnglesList->item(i)->text(); - // get angles - SMESH::double_array_var anAngles = new SMESH::double_array; - if (AnglesGrp->isChecked()) { - anAngles->length(myAnglesList.count()); - int j = 0; - for (int i = 0; i < myAnglesList.count(); i++) { - double angle = myAnglesList[i]; - anAngles[ j++ ] = angle*PI/180; - aParameters << AnglesList->item(i)->text(); - } - anAngles->length(j); - } // get base point SMESH::PointStruct aBasePoint; @@ -562,88 +534,63 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply() try { SUIT_OverrideCursor wc; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - if ( LinearAnglesCheck->isChecked() ) - anAngles = aMeshEditor->LinearAnglesVariation( myPathMesh, myPathShape, anAngles ); + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); SMESH::SMESH_MeshEditor::Extrusion_Error retVal; - if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) { - if( MeshCheck->isChecked() ) { - if( GetConstructorId() == 0 ) - SMESH::ListOfGroups_var groups = - aMeshEditor->ExtrusionAlongPathObject1DMakeGroups(myIDSource, myPathMesh, - myPathShape, aNodeStart, - AnglesGrp->isChecked(), anAngles, - BasePointGrp->isChecked(), aBasePoint, retVal); - else - SMESH::ListOfGroups_var groups = - aMeshEditor->ExtrusionAlongPathObject2DMakeGroups(myIDSource, myPathMesh, - myPathShape, aNodeStart, - AnglesGrp->isChecked(), anAngles, - BasePointGrp->isChecked(), aBasePoint, retVal); - } - else - SMESH::ListOfGroups_var groups = - aMeshEditor->ExtrusionAlongPathMakeGroups(anElementsId, myPathMesh, - myPathShape, aNodeStart, - AnglesGrp->isChecked(), anAngles, - BasePointGrp->isChecked(), aBasePoint, retVal); + + myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + + bool NeedGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ); + SMESH::ElementType ElemType = SMESH::FACE; + if( GetConstructorId() == 0 ) + ElemType = SMESH::EDGE; + if( !MeshCheck->isChecked() ) { + SMESH::ListOfGroups_var groups = + aMeshEditor->ExtrusionAlongPathX(anElementsId, myPath, aNodeStart, AnglesGrp->isChecked(), + anAngles, LinearAnglesCheck->isChecked(), + BasePointGrp->isChecked(), aBasePoint, + NeedGroups, ElemType, retVal); } else { - if( MeshCheck->isChecked() ) { - if( GetConstructorId() == 0 ) - retVal = aMeshEditor->ExtrusionAlongPathObject1D(myIDSource, myPathMesh, - myPathShape, aNodeStart, - AnglesGrp->isChecked(), anAngles, - BasePointGrp->isChecked(), aBasePoint); - else - retVal = aMeshEditor->ExtrusionAlongPathObject2D(myIDSource, myPathMesh, - myPathShape, aNodeStart, - AnglesGrp->isChecked(), anAngles, - BasePointGrp->isChecked(), aBasePoint); - } - else - retVal = aMeshEditor->ExtrusionAlongPath(anElementsId, myPathMesh, - myPathShape, aNodeStart, - AnglesGrp->isChecked(), anAngles, - BasePointGrp->isChecked(), aBasePoint); + SMESH::ListOfGroups_var groups = + aMeshEditor->ExtrusionAlongPathObjX(myIDSource, myPath, aNodeStart, AnglesGrp->isChecked(), + anAngles, LinearAnglesCheck->isChecked(), + BasePointGrp->isChecked(), aBasePoint, + NeedGroups, ElemType, retVal); } - if( retVal == SMESH::SMESH_MeshEditor::EXTR_OK ) - myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); - //wc.stop(); wc.suspend(); switch (retVal) { case SMESH::SMESH_MeshEditor::EXTR_NO_ELEMENTS: SUIT_MessageBox::warning(this, - tr("SMESH_ERROR"), - tr("NO_ELEMENTS_SELECTED")); + tr("SMESH_ERROR"), + tr("NO_ELEMENTS_SELECTED")); return false; break; case SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE: SUIT_MessageBox::warning(this, - tr("SMESH_ERROR"), - tr("SELECTED_PATH_IS_NOT_EDGE")); + tr("SMESH_ERROR"), + tr("SELECTED_PATH_IS_NOT_EDGE")); return false; break; case SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE: SUIT_MessageBox::warning(this, - tr("SMESH_ERROR"), - tr("BAD_SHAPE_TYPE")); + tr("SMESH_ERROR"), + tr("BAD_SHAPE_TYPE")); return false; break; case SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE: SUIT_MessageBox::warning(this, - tr("SMESH_ERROR"), - tr("EXTR_BAD_STARTING_NODE")); + tr("SMESH_ERROR"), + tr("EXTR_BAD_STARTING_NODE")); return false; break; case SMESH::SMESH_MeshEditor::EXTR_BAD_ANGLES_NUMBER: SUIT_MessageBox::warning(this, - tr("SMESH_ERROR"), - tr("WRONG_ANGLES_NUMBER")); + tr("SMESH_ERROR"), + tr("WRONG_ANGLES_NUMBER")); return false; break; case SMESH::SMESH_MeshEditor::EXTR_CANT_GET_TANGENT: SUIT_MessageBox::warning(this, - tr("SMESH_ERROR"), - tr("CANT_GET_TANGENT")); + tr("SMESH_ERROR"), + tr("CANT_GET_TANGENT")); return false; break; case SMESH::SMESH_MeshEditor::EXTR_OK: break; @@ -653,7 +600,11 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply() } //mySelectionMgr->clearSelected(); - SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() ); + if ( myMeshActor ) + SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() ); + + SMESHGUI::Modified(); + if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) mySMESHGUI->updateObjBrowser(true); // new groups may appear //SMESH::UpdateView(); @@ -689,10 +640,10 @@ void SMESHGUI_ExtrusionAlongPathDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -751,49 +702,50 @@ void SMESHGUI_ExtrusionAlongPathDlg::onTextChange (const QString& theNewText) const Handle(SALOME_InteractiveObject)& anIO = myMeshActor->getIO(); TColStd_MapOfInteger newIndices; for (int i = 0; i < aListId.count(); i++) { - long ind = aListId[ i ].toLong(&bOk); - if (bOk) { - const SMDS_MeshElement* e = aMesh->FindElement(ind); - if (e) { - // check also type of element - bool typeMatch = Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge || - Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face; - if (typeMatch) - newIndices.Add(e->GetID()); - } - } + long ind = aListId[ i ].toLong(&bOk); + if (bOk) { + const SMDS_MeshElement* e = aMesh->FindElement(ind); + if (e) { + // check also type of element + bool typeMatch = (Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge) || + (Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face); + if (typeMatch) + newIndices.Add(e->GetID()); + } + } } mySelector->AddOrRemoveIndex(anIO, newIndices, false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( anIO, true, true ); + aViewWindow->highlight( anIO, true, true ); } - } else if (send == StartPointLineEdit && + } + else if (send == StartPointLineEdit && myEditCurrentArgument == StartPointLineEdit) { - if (!myPathMesh->_is_nil()) { - SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh); + if (!myPath->_is_nil()) { + SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath); SMDS_Mesh* aMesh = 0; if (aPathActor) - aMesh = aPathActor->GetObject()->GetMesh(); + aMesh = aPathActor->GetObject()->GetMesh(); if (aMesh) { - //mySelectionMgr->clearSelected(); - //mySelectionMgr->AddIObject(aPathActor->getIO()); + //mySelectionMgr->clearSelected(); + //mySelectionMgr->AddIObject(aPathActor->getIO()); SALOME_ListIO aList; aList.Append(aPathActor->getIO()); mySelectionMgr->setSelectedObjects(aList, false); - bool bOk; - long ind = theNewText.toLong(&bOk); - if (bOk) { - const SMDS_MeshNode* n = aMesh->FindNode(ind); - if (n) { - //if (!mySelectionMgr->IsIndexSelected(aPathActor->getIO(), n->GetID())) { + bool bOk; + long ind = theNewText.toLong(&bOk); + if (bOk) { + const SMDS_MeshNode* n = aMesh->FindNode(ind); + if (n) { + //if (!mySelectionMgr->IsIndexSelected(aPathActor->getIO(), n->GetID())) { TColStd_MapOfInteger newIndices; - newIndices.Add(n->GetID()); - mySelector->AddOrRemoveIndex( aPathActor->getIO(), newIndices, false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( aPathActor->getIO(), true, true ); - } - } + newIndices.Add(n->GetID()); + mySelector->AddOrRemoveIndex( aPathActor->getIO(), newIndices, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( aPathActor->getIO(), true, true ); + } + } } } } @@ -843,7 +795,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument() } // find actor myMeshActor = SMESH::FindActorByObject(myMesh); - if (!myMeshActor) + if (!myMeshActor && !MeshCheck->isChecked()) return; if (MeshCheck->isChecked()) { @@ -862,57 +814,37 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument() SMESH::GetNameOfSelectedElements(mySelector, IO, aString); ElementsLineEdit->setText(aString); } - } else if (myEditCurrentArgument == PathMeshLineEdit) { + } + else if (myEditCurrentArgument == PathMeshLineEdit) { // we are now selecting path mesh // reset PathMeshLineEdit->clear(); - myPathMesh = SMESH::SMESH_Mesh::_nil(); - PathShapeLineEdit->clear(); - myPathShape = GEOM::GEOM_Object::_nil(); + myPath = SMESH::SMESH_IDSource::_nil(); StartPointLineEdit->clear(); - + // try to get mesh from selection Handle(SALOME_InteractiveObject) IO = aList.First(); - myPathMesh = SMESH::IObjectToInterface(IO); - if(myPathMesh->_is_nil()) + myPath = SMESH::IObjectToInterface(IO); + if( myPath->_is_nil() ) return; - + QString aString; SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); PathMeshLineEdit->setText(aString); - } else if (myEditCurrentArgument == PathShapeLineEdit) { - // we are now selecting path mesh - // reset - PathShapeLineEdit->clear(); - myPathShape = GEOM::GEOM_Object::_nil(); - StartPointLineEdit->clear(); - - // return if path mesh is not yet selected - if (myPathMesh->_is_nil()) - return; - - // try to get shape from selection - Handle(SALOME_InteractiveObject) IO = aList.First(); - myPathShape = SMESH::IObjectToInterface(IO); - if (myPathShape->_is_nil()) - return; - - QString aString; - SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); - PathShapeLineEdit->setText(aString); - } else if (myEditCurrentArgument == StartPointLineEdit) { + } + else if (myEditCurrentArgument == StartPointLineEdit) { // we are now selecting start point of path // reset StartPointLineEdit->clear(); // return if path mesh or path shape is not yet selected - if (myPathMesh->_is_nil() || myPathShape->_is_nil()) + if( myPath->_is_nil() ) return; // try to get shape from selection Handle(SALOME_InteractiveObject) IO = aList.First(); - SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh); + SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath); if ( !aPathActor ) return; @@ -937,10 +869,10 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument() TopoDS_Vertex aVertex; if (!aGeomObj->_is_nil()) { if (aGeomObj->IsShape() && GEOMBase::GetShape(aGeomObj, aVertex) && !aVertex.IsNull()) { - gp_Pnt aPnt = BRep_Tool::Pnt(aVertex); - XSpin->SetValue(aPnt.X()); - YSpin->SetValue(aPnt.Y()); - ZSpin->SetValue(aPnt.Z()); + gp_Pnt aPnt = BRep_Tool::Pnt(aVertex); + XSpin->SetValue(aPnt.X()); + YSpin->SetValue(aPnt.Y()); + ZSpin->SetValue(aPnt.Z()); } return; } @@ -972,6 +904,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument() YSpin->SetValue(n->Y()); ZSpin->SetValue(n->Z()); } + onDisplaySimulation(true); } //================================================================================= @@ -983,7 +916,6 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument() QToolButton* send = (QToolButton*)sender(); if (send != SelectElementsButton && send != SelectPathMeshButton && - send != SelectPathShapeButton && send != SelectStartPointButton && send != SelectBasePointButton) return; @@ -997,7 +929,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument() void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button) { disconnect(mySelectionMgr, 0, this, 0); - mySelectionMgr->clearSelected(); + // mySelectionMgr->clearSelected(); mySelectionMgr->clearFilters(); SMESH::SetPickable(); @@ -1006,19 +938,19 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button SMESH::SetPointRepresentation(false); if (MeshCheck->isChecked()) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); + aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->installFilter(myElementsFilter); } else { if (Elements1dRB->isChecked()) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - } + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); + } else if (Elements2dRB->isChecked()) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - } + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + } } } else if (button == SelectPathMeshButton) { myEditCurrentArgument = PathMeshLineEdit; @@ -1027,31 +959,16 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->installFilter(myPathMeshFilter); } - else if (button == SelectPathShapeButton) { - myEditCurrentArgument = PathShapeLineEdit; - SMESH::SetPointRepresentation(false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - - if (!myPathMesh->_is_nil()) { - GEOM::GEOM_Object_var aMainShape = myPathMesh->GetShapeToMesh(); - SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh); - - if (!aMainShape->_is_nil() && aPathActor) - mySelectionMgr->installFilter(new SMESH_NumberFilter ("GEOM", TopAbs_SHAPE, -1, - TopAbs_EDGE, aMainShape)); - //SMESH::SetPickable(aPathActor); - } - } else if (button == SelectStartPointButton) { myEditCurrentArgument = StartPointLineEdit; - if (!myPathMesh->_is_nil()) { - SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh); + //if (!myPathMesh->_is_nil()) { + if (!myPath->_is_nil()) { + SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath); if (aPathActor) { - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - SMESH::SetPickable(aPathActor); + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + SMESH::SetPickable(aPathActor); } } } @@ -1136,6 +1053,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::onSelectMesh() ElementsLineEdit->setValidator(toSelectMesh ? 0 : myIdValidator); ElementsLab->setText(toSelectMesh ? tr("SMESH_NAME") : tr("SMESH_ID_ELEMENTS")); ElementsLineEdit->clear(); + myFilterBtn->setEnabled(!toSelectMesh); SetEditCurrentArgument(SelectElementsButton); } @@ -1195,21 +1113,21 @@ bool SMESHGUI_ExtrusionAlongPathDlg::eventFilter (QObject* object, QEvent* event QKeyEvent* ke = (QKeyEvent*)event; if (object == AnglesList) { if (ke->key() == Qt::Key_Delete) - OnAngleRemoved(); + OnAngleRemoved(); } } else if (event->type() == QEvent::FocusIn) { if (object == ElementsLineEdit) { if (myEditCurrentArgument != ElementsLineEdit) - SetEditCurrentArgument(SelectElementsButton); + SetEditCurrentArgument(SelectElementsButton); } else if (object == StartPointLineEdit) { if (myEditCurrentArgument != StartPointLineEdit) - SetEditCurrentArgument(SelectStartPointButton); + SetEditCurrentArgument(SelectStartPointButton); } else if (object == XSpin->editor() || object == YSpin->editor() || object == ZSpin->editor()) { if (myEditCurrentArgument != XSpin) - SetEditCurrentArgument(SelectBasePointButton); + SetEditCurrentArgument(SelectBasePointButton); } } return QDialog::eventFilter(object, event); @@ -1237,6 +1155,12 @@ void SMESHGUI_ExtrusionAlongPathDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_ExtrusionAlongPathDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) { QList types; @@ -1287,10 +1211,162 @@ void SMESHGUI_ExtrusionAlongPathDlg::updateLinearAngles() enableLinear = false; anItem->text().toDouble(&enableLinear); if( !enableLinear ) - break; + break; } } if( !enableLinear ) LinearAnglesCheck->setChecked( false ); LinearAnglesCheck->setEnabled( enableLinear ); } + +//================================================================================= +// function : isValuesValid() +// purpose : Return true in case if values entered into dialog are valid +//================================================================================= +bool SMESHGUI_ExtrusionAlongPathDlg::isValuesValid() { + + if ( (MeshCheck->isChecked() && myIDSource->_is_nil()) || + myMesh->_is_nil() || + myPath->_is_nil() ) + return false; + + if(!MeshCheck->isChecked()) { + QStringList aListElementsId = ElementsLineEdit->text().split(" ", QString::SkipEmptyParts); + if(aListElementsId.count() <= 0) + return false; + } + + bool bOk; + StartPointLineEdit->text().toLong(&bOk); + if (!bOk) { + return false; + } + + return true; +} + + +//================================================================================= +// function : onDisplaySimulation +// purpose : Show/Hide preview +//================================================================================= +void SMESHGUI_ExtrusionAlongPathDlg::onDisplaySimulation( bool toDisplayPreview ) { + if (myPreviewCheckBox->isChecked() && toDisplayPreview) { + if(isValid() && isValuesValid()) { + + //Get selected elements: + SMESH::long_array_var anElementsId = getSelectedElements(); + + // get angles + SMESH::double_array_var anAngles = getAngles(); + + // get base point + SMESH::PointStruct aBasePoint; + if (BasePointGrp->isChecked()) { + aBasePoint.x = XSpin->GetValue(); + aBasePoint.y = YSpin->GetValue(); + aBasePoint.z = ZSpin->GetValue(); + } + bool bOk; + long aNodeStart = StartPointLineEdit->text().toLong(&bOk); + if (bOk) { + + try { + SUIT_OverrideCursor wc; + + SMESH::SMESH_MeshEditor::Extrusion_Error retVal; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); + bool NeedGroups = false; + SMESH::ElementType ElemType = SMESH::FACE; + if( GetConstructorId() == 0 ) + ElemType = SMESH::EDGE; + if( !MeshCheck->isChecked() ) { + aMeshEditor->ExtrusionAlongPathX(anElementsId, myPath, aNodeStart, AnglesGrp->isChecked(), + anAngles, LinearAnglesCheck->isChecked(), + BasePointGrp->isChecked(), aBasePoint, + NeedGroups, ElemType, retVal); + } + else { + SMESH::ListOfGroups_var groups = + aMeshEditor->ExtrusionAlongPathObjX(myIDSource, myPath, aNodeStart, AnglesGrp->isChecked(), + anAngles, LinearAnglesCheck->isChecked(), + BasePointGrp->isChecked(), aBasePoint, + NeedGroups, ElemType, retVal); + } + + wc.suspend(); + if( retVal == SMESH::SMESH_MeshEditor::EXTR_OK ) { + SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); + mySimulation->SetData(aMeshPreviewStruct._retn()); + } else { + hidePreview(); + } + + } catch (...) { + hidePreview(); + } + } else { + hidePreview(); + } + + } else { + hidePreview(); + } + } else { + hidePreview(); + } +} + + +//================================================================================= +// function : getSelectedElements +// purpose : return list of the selected elements +//================================================================================= +SMESH::long_array_var SMESHGUI_ExtrusionAlongPathDlg::getSelectedElements() { + + // If "Select whole mesh, submesh or group" check box is off -> + // use only elements of given type selected by user + SMESH::long_array_var anElementsId = new SMESH::long_array; + if (!MeshCheck->isChecked()) { + + SMDS_Mesh* aMesh; + if ( myMeshActor ) + aMesh = myMeshActor->GetObject()->GetMesh(); + + if (aMesh) { + QStringList aListElementsId = ElementsLineEdit->text().split(" ", QString::SkipEmptyParts); + anElementsId = new SMESH::long_array; + anElementsId->length(aListElementsId.count()); + bool bOk; + int j = 0; + for (int i = 0; i < aListElementsId.count(); i++) { + long ind = aListElementsId[ i ].toLong(&bOk); + if (bOk) { + const SMDS_MeshElement* e = aMesh->FindElement(ind); + if (e) { + bool typeMatch = (Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge) || + (Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face); + if (typeMatch) + anElementsId[ j++ ] = ind; + } + } + } + anElementsId->length(j); + } + } + return anElementsId; +} + +SMESH::double_array_var SMESHGUI_ExtrusionAlongPathDlg::getAngles() { + SMESH::double_array_var anAngles = new SMESH::double_array; + if (AnglesGrp->isChecked()) { + anAngles->length(myAnglesList.count()); + int j = 0; + for (int i = 0; i < myAnglesList.count(); i++) { + double angle = myAnglesList[i]; + anAngles[ j++ ] = angle*M_PI/180.; + } + anAngles->length(j); + } + return anAngles; +} diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h index 4e1cbcb9c..b02aeb7a2 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h +++ b/src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ExtrusionAlongPathDlg.h // Author : Vadim SANDLER, Open CASCADE S.A.S. @@ -28,9 +29,7 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include +#include "SMESHGUI_PreviewDlg.h" // IDL includes #include @@ -59,7 +58,7 @@ class SUIT_SelectionFilter; // class : SMESHGUI_ExtrusionAlongPathDlg // purpose : //================================================================================= -class SMESHGUI_EXPORT SMESHGUI_ExtrusionAlongPathDlg : public QDialog +class SMESHGUI_EXPORT SMESHGUI_ExtrusionAlongPathDlg : public SMESHGUI_PreviewDlg { Q_OBJECT @@ -80,10 +79,13 @@ private: void SetEditCurrentArgument( QToolButton* ); bool isValid(); + bool isValuesValid(); + + SMESH::long_array_var getSelectedElements(); + SMESH::double_array_var getAngles(); void updateLinearAngles(); - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ SMESHGUI_IdValidator* myIdValidator; LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ SVTK_Selector* mySelector; @@ -94,8 +96,9 @@ private: SMESH::SMESH_Mesh_var myMesh; SMESH_Actor* myMeshActor; SMESH::SMESH_IDSource_var myIDSource; - SMESH::SMESH_Mesh_var myPathMesh; - GEOM::GEOM_Object_var myPathShape; + //SMESH::SMESH_Mesh_var myPathMesh; + SMESH::SMESH_IDSource_var myPath; + //GEOM::GEOM_Object_var myPathShape; SUIT_SelectionFilter* myElementsFilter; SUIT_SelectionFilter* myPathMeshFilter; int myType; @@ -115,8 +118,8 @@ private: QGroupBox* PathGrp; QToolButton* SelectPathMeshButton; QLineEdit* PathMeshLineEdit; - QToolButton* SelectPathShapeButton; - QLineEdit* PathShapeLineEdit; + //QToolButton* SelectPathShapeButton; + //QLineEdit* PathShapeLineEdit; QToolButton* SelectStartPointButton; QLineEdit* StartPointLineEdit; QCheckBox* LinearAnglesCheck; @@ -140,10 +143,12 @@ private: QString myHelpFileName; + QPushButton* myFilterBtn; SMESHGUI_FilterDlg* myFilterDlg; protected slots: void reject(); + virtual void onDisplaySimulation( bool ); private slots: void ConstructorsClicked( int ); diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx index 0626e4575..c75af4f45 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ExtrusionDlg.cxx // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -33,6 +34,7 @@ #include "SMESHGUI_SpinBox.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_MeshEditPreview.h" #include #include @@ -87,8 +89,7 @@ // purpose : constructor //================================================================================= SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), + : SMESHGUI_PreviewDlg( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), myFilterDlg( 0 ), mySelectedObject(SMESH::SMESH_IDSource::_nil()) @@ -96,6 +97,7 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_EDGE"))); QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_TRIANGLE"))); QPixmap image2 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); + QPixmap image3 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_NODE"))); setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); @@ -113,16 +115,20 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) ConstructorsBoxLayout->setSpacing(SPACING); ConstructorsBoxLayout->setMargin(MARGIN); + RadioButton0= new QRadioButton(ConstructorsBox); + RadioButton0->setIcon(image3); RadioButton1= new QRadioButton(ConstructorsBox); RadioButton1->setIcon(image0); RadioButton2= new QRadioButton(ConstructorsBox); RadioButton2->setIcon(image1); + ConstructorsBoxLayout->addWidget(RadioButton0); ConstructorsBoxLayout->addWidget(RadioButton1); ConstructorsBoxLayout->addWidget(RadioButton2); - GroupConstructors->addButton(RadioButton1, 0); - GroupConstructors->addButton(RadioButton2, 1); + GroupConstructors->addButton(RadioButton0, 0); + GroupConstructors->addButton(RadioButton1, 1); + GroupConstructors->addButton(RadioButton2, 2); /***************************************************************/ GroupButtons = new QGroupBox(this); @@ -149,7 +155,7 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) GroupButtonsLayout->addWidget(buttonHelp); /***************************************************************/ - GroupArguments = new QGroupBox(tr("EXTRUSION_1D"), this); + GroupArguments = new QGroupBox(tr("EXTRUSION_0D"), this); QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments); GroupArgumentsLayout->setSpacing(SPACING); GroupArgumentsLayout->setMargin(MARGIN); @@ -164,16 +170,21 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); - QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); - connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + LineEditElements->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); // Control for the whole mesh selection CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); + RadioButton3 = new QRadioButton(GroupArguments); + RadioButton3->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") ); + RadioButton4 = new QRadioButton(GroupArguments); + RadioButton4->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") ); + //Control for the Distance selection TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments); - TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments); TextLabelDx = new QLabel(tr("SMESH_X"), GroupArguments); SpinBox_Dx = new SMESHGUI_SpinBox(GroupArguments); @@ -185,6 +196,8 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) // Controls for vector selection + TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments); + SelectVectorButton = new QPushButton(GroupArguments); SelectVectorButton->setIcon(image2); @@ -197,6 +210,9 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) TextLabelVz = new QLabel(tr("SMESH_DZ"), GroupArguments); SpinBox_Vz = new SMESHGUI_SpinBox(GroupArguments); + TextLabelDist = new QLabel(tr("SMESH_DISTANCE"), GroupArguments); + SpinBox_VDist = new SMESHGUI_SpinBox(GroupArguments); + // Controls for nb. steps defining TextLabelNbSteps = new QLabel(tr("SMESH_NUMBEROFSTEPS"), GroupArguments); SpinBox_NbSteps = new SalomeApp_IntSpinBox(GroupArguments); @@ -204,29 +220,39 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) // CheckBox for groups generation MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments); + //Preview check box + myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); + GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5); - GroupArgumentsLayout->addWidget(filterBtn, 0, 7); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 7); GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8); - GroupArgumentsLayout->addWidget(TextLabelDistance, 2, 0); - GroupArgumentsLayout->addWidget(TextLabelDx, 2, 2); - GroupArgumentsLayout->addWidget(SpinBox_Dx, 2, 3); - GroupArgumentsLayout->addWidget(TextLabelDy, 2, 4); - GroupArgumentsLayout->addWidget(SpinBox_Dy, 2, 5); - GroupArgumentsLayout->addWidget(TextLabelDz, 2, 6); - GroupArgumentsLayout->addWidget(SpinBox_Dz, 2, 7); - GroupArgumentsLayout->addWidget(TextLabelVector, 3, 0); - GroupArgumentsLayout->addWidget(SelectVectorButton, 3, 1); - GroupArgumentsLayout->addWidget(TextLabelVx, 3, 2); - GroupArgumentsLayout->addWidget(SpinBox_Vx, 3, 3); - GroupArgumentsLayout->addWidget(TextLabelVy, 3, 4); - GroupArgumentsLayout->addWidget(SpinBox_Vy, 3, 5); - GroupArgumentsLayout->addWidget(TextLabelVz, 3, 6); - GroupArgumentsLayout->addWidget(SpinBox_Vz, 3, 7); - GroupArgumentsLayout->addWidget(TextLabelNbSteps, 4, 0); - GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 4, 2, 1, 6); - GroupArgumentsLayout->addWidget(MakeGroupsCheck, 5, 0, 1, 8); + GroupArgumentsLayout->addWidget(RadioButton3, 2, 1, 1, 3); + GroupArgumentsLayout->addWidget(RadioButton4, 2, 5, 1, 3); + GroupArgumentsLayout->addWidget(TextLabelDistance, 3, 0); + GroupArgumentsLayout->addWidget(TextLabelDx, 3, 2); + GroupArgumentsLayout->addWidget(SpinBox_Dx, 3, 3); + GroupArgumentsLayout->addWidget(TextLabelDy, 3, 4); + GroupArgumentsLayout->addWidget(SpinBox_Dy, 3, 5); + GroupArgumentsLayout->addWidget(TextLabelDz, 3, 6); + GroupArgumentsLayout->addWidget(SpinBox_Dz, 3, 7); + GroupArgumentsLayout->addWidget(TextLabelVector, 4, 0); + GroupArgumentsLayout->addWidget(SelectVectorButton, 4, 1); + GroupArgumentsLayout->addWidget(TextLabelVx, 4, 2); + GroupArgumentsLayout->addWidget(SpinBox_Vx, 4, 3); + GroupArgumentsLayout->addWidget(TextLabelVy, 4, 4); + GroupArgumentsLayout->addWidget(SpinBox_Vy, 4, 5); + GroupArgumentsLayout->addWidget(TextLabelVz, 4, 6); + GroupArgumentsLayout->addWidget(SpinBox_Vz, 4, 7); + GroupArgumentsLayout->addWidget(TextLabelDist, 5, 0); + GroupArgumentsLayout->addWidget(SpinBox_VDist, 5, 3); + GroupArgumentsLayout->addWidget(TextLabelNbSteps, 6, 0, 1, 3); + GroupArgumentsLayout->addWidget(SpinBox_NbSteps, 6, 3); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 7, 0, 1, 8); + GroupArgumentsLayout->addWidget(MakeGroupsCheck, 8, 0, 1, 8); + GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 8, 0); + /***************************************************************/ SMESHGUI_ExtrusionDlgLayout->addWidget(ConstructorsBox); @@ -234,17 +260,19 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons); /* Initialisations */ - SpinBox_Vx->RangeStepAndValidator(-1, 1, 0.01, 3); - SpinBox_Vy->RangeStepAndValidator(-1, 1, 0.01, 3); - SpinBox_Vz->RangeStepAndValidator(-1, 1, 0.01, 3); + SpinBox_Vx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision"); + SpinBox_Vy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision"); + SpinBox_Vz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision"); - SpinBox_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Dy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); + SpinBox_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Dy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); SpinBox_NbSteps->setRange(1, 999999); + SpinBox_VDist->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); - RadioButton1->setChecked(true); + RadioButton0->setChecked(true); + RadioButton3->setChecked(true); MakeGroupsCheck->setChecked(true); mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); @@ -273,6 +301,9 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); + connect(RadioButton3, SIGNAL(clicked()), this, SLOT(ClickOnRadio())); + connect(RadioButton4, SIGNAL(clicked()), this, SLOT(ClickOnRadio())); + // to update state of the Ok & Apply buttons connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable())); connect(SpinBox_Vy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable())); @@ -291,9 +322,22 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule) connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); + connect(SpinBox_Dx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Dy, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Dz, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Vx, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Vy, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Vz, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_VDist, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_NbSteps, SIGNAL(valueChanged(int)), this, SLOT(toDisplaySimulation())); + + //To Connect preview check box + connectPreviewControl(); + /***************************************************************/ ConstructorsClicked(0); + ClickOnRadio(); SelectionIntoArgument(); } @@ -316,6 +360,7 @@ SMESHGUI_ExtrusionDlg::~SMESHGUI_ExtrusionDlg() void SMESHGUI_ExtrusionDlg::Init (bool ResetControls) { myBusy = false; + myIDs.clear(); LineEditElements->clear(); myNbOkElements = 0; @@ -325,6 +370,7 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls) if (ResetControls) { SpinBox_NbSteps->setValue(1); + SpinBox_VDist->setValue(10); SpinBox_Dx->SetValue(0); SpinBox_Dy->SetValue(0); SpinBox_Dz->SetValue(0); @@ -334,6 +380,8 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls) CheckBoxMesh->setChecked(false); onSelectMesh(false); + myPreviewCheckBox->setChecked(false); + onDisplaySimulation(false); } CheckIsEnable(); @@ -344,19 +392,33 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls) // purpose : Check whether the Ok and Apply buttons should be enabled or not //================================================================================= void SMESHGUI_ExtrusionDlg::CheckIsEnable() -{ - - double aX = SpinBox_Vx->GetValue()*SpinBox_Dx->GetValue(); - double aY = SpinBox_Vy->GetValue()*SpinBox_Dy->GetValue(); - double aZ = SpinBox_Vz->GetValue()*SpinBox_Dz->GetValue(); - double aModule = sqrt(aX*aX + aY*aY + aZ*aZ); - - bool anIsEnable = myNbOkElements > 0 && aModule > 1.0E-38; +{ + bool anIsEnable = myNbOkElements > 0 && isValuesValid(); buttonOk->setEnabled(anIsEnable); buttonApply->setEnabled(anIsEnable); } +//================================================================================= +// function : isValuesValid() +// purpose : Return true in case if values entered into dialog are valid +//================================================================================= +bool SMESHGUI_ExtrusionDlg::isValuesValid() { + double aX, aY, aZ, aModule = 0; + if ( RadioButton3->isChecked() ) { + aX = SpinBox_Dx->GetValue(); + aY = SpinBox_Dy->GetValue(); + aZ = SpinBox_Dz->GetValue(); + aModule = sqrt(aX*aX + aY*aY + aZ*aZ); + } else if ( RadioButton4->isChecked() ) { + aX = SpinBox_Vx->GetValue(); + aY = SpinBox_Vy->GetValue(); + aZ = SpinBox_Vz->GetValue(); + aModule = sqrt(aX*aX + aY*aY + aZ*aZ); + } + return aModule > 1.0E-38; +} + //================================================================================= // function : ConstructorsClicked() // purpose : Radio button management @@ -365,25 +427,45 @@ void SMESHGUI_ExtrusionDlg::ConstructorsClicked (int constructorId) { disconnect(mySelectionMgr, 0, this, 0); + hidePreview(); + + TextLabelElements->setText(tr( constructorId ? "SMESH_ID_ELEMENTS" : "SMESH_ID_NODES")); + switch (constructorId) { case 0: { - GroupArguments->setTitle(tr("EXTRUSION_1D")); + GroupArguments->setTitle(tr("EXTRUSION_0D")); if (!CheckBoxMesh->isChecked()) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - } + { + LineEditElements->clear(); + myIDs.clear(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + } break; } case 1: + { + GroupArguments->setTitle(tr("EXTRUSION_1D")); + if (!CheckBoxMesh->isChecked()) + { + LineEditElements->clear(); + myIDs.clear(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); + } + break; + } + case 2: { GroupArguments->setTitle(tr("EXTRUSION_2D")); if (!CheckBoxMesh->isChecked()) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - } + { + LineEditElements->clear(); + myIDs.clear(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + } break; } } @@ -397,6 +479,58 @@ void SMESHGUI_ExtrusionDlg::ConstructorsClicked (int constructorId) connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); } +//================================================================================= +// function : ConstructorsClicked() +// purpose : Radio button management +//================================================================================= +void SMESHGUI_ExtrusionDlg::ClickOnRadio() +{ + if ( RadioButton3->isChecked() ) { + TextLabelDistance->show(); + TextLabelDx->show(); + SpinBox_Dx->show(); + TextLabelDy->show(); + SpinBox_Dy->show(); + TextLabelDz->show(); + SpinBox_Dz->show(); + + TextLabelVector->hide(); + TextLabelVx->hide(); + SpinBox_Vx->hide(); + TextLabelVy->hide(); + SpinBox_Vy->hide(); + TextLabelVz->hide(); + SpinBox_Vz->hide(); + TextLabelDist->hide(); + SpinBox_VDist->hide(); + SelectVectorButton->hide(); + } else if ( RadioButton4->isChecked() ) { + TextLabelDistance->hide(); + TextLabelDx->hide(); + SpinBox_Dx->hide(); + TextLabelDy->hide(); + SpinBox_Dy->hide(); + TextLabelDz->hide(); + SpinBox_Dz->hide(); + + TextLabelVector->show(); + TextLabelVx->show(); + SpinBox_Vx->show(); + TextLabelVy->show(); + SpinBox_Vy->show(); + TextLabelVz->show(); + SpinBox_Vz->show(); + TextLabelDist->show(); + SpinBox_VDist->show(); + SelectVectorButton->show(); + } + onDisplaySimulation(true); + // AdjustSize + qApp->processEvents(); + updateGeometry(); + resize( minimumSizeHint() ); +} + //================================================================================= // function : ClickOnApply() // purpose : Called when user presses button @@ -410,66 +544,104 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply() return false; if (myNbOkElements) { - - gp_XYZ aNormale(SpinBox_Vx->GetValue(), - SpinBox_Vy->GetValue(), - SpinBox_Vz->GetValue()); - - aNormale /= aNormale.Modulus(); - + SMESH::DirStruct aVector; - aVector.PS.x = SpinBox_Dx->GetValue()*aNormale.X(); - aVector.PS.y = SpinBox_Dy->GetValue()*aNormale.Y(); - aVector.PS.z = SpinBox_Dz->GetValue()*aNormale.Z(); + getExtrusionVector(aVector); + + QStringList aParameters; + if ( RadioButton3->isChecked() ) { + aParameters << SpinBox_Dx->text(); + aParameters << SpinBox_Dy->text(); + aParameters << SpinBox_Dz->text(); + } else if ( RadioButton4->isChecked() ) { + // only 3 coords in a python dump command :( + // aParameters << SpinBox_Vx->text(); + // aParameters << SpinBox_Vy->text(); + // aParameters << SpinBox_Vz->text(); + // aParameters << SpinBox_VDist->text(); + } long aNbSteps = (long)SpinBox_NbSteps->value(); - QStringList aParameters; - aParameters << SpinBox_Dx->text(); - aParameters << SpinBox_Dy->text(); - aParameters << SpinBox_Dz->text(); aParameters << SpinBox_NbSteps->text(); try { SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) { - if( CheckBoxMesh->isChecked() ) { - if( GetConstructorId() == 0 ) - SMESH::ListOfGroups_var groups = - aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector, aNbSteps); - else - SMESH::ListOfGroups_var groups = - aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector, aNbSteps); - } - else - SMESH::ListOfGroups_var groups = - aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector, aNbSteps); + if( CheckBoxMesh->isChecked() ) + switch (GetConstructorId() ) { + case 0: + { + SMESH::ListOfGroups_var groups = + aMeshEditor->ExtrusionSweepObject0DMakeGroups(mySelectedObject, aVector, aNbSteps); + break; + } + case 1: + { + SMESH::ListOfGroups_var groups = + aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector, aNbSteps); + break; + } + case 2: + { + SMESH::ListOfGroups_var groups = + aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector, aNbSteps); + break; + } + } + else + { + SMESH::ListOfGroups_var groups; + if (GetConstructorId() == 0) + groups = aMeshEditor->ExtrusionSweepMakeGroups0D(myElementsId.inout(), aVector, aNbSteps); + else + groups = aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector, aNbSteps); + } + } else { - if( CheckBoxMesh->isChecked() ) { - if( GetConstructorId() == 0 ) - aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps); - else - aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps); - } - else - aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps); + if( CheckBoxMesh->isChecked() ) + switch( GetConstructorId() ) { + case 0: + { + aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps); + break; + } + case 1: + { + aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps); + break; + } + case 2: + { + aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps); + break; + } + } + else + if (GetConstructorId() == 0) + aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps); + else + aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps); } - myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); - } catch (...) { } - SMESH::UpdateView(); + SMESH::Update(myIO, SMESH::eDisplay); if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) mySMESHGUI->updateObjBrowser(true); // new groups may appear Init(false); ConstructorsClicked(GetConstructorId()); + mySelectionMgr->clearSelected(); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; } @@ -490,17 +662,6 @@ void SMESHGUI_ExtrusionDlg::ClickOnOk() //================================================================================= void SMESHGUI_ExtrusionDlg::ClickOnCancel() { - disconnect(mySelectionMgr, 0, this, 0); - mySelectionMgr->clearFilters(); - //mySelectionMgr->clearSelected(); - if (SMESH::GetCurrentVtkView()) { - SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters - SMESH::SetPointRepresentation(false); - SMESH::SetPickable(); - } - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - mySMESHGUI->ResetState(); reject(); } @@ -521,10 +682,10 @@ void SMESHGUI_ExtrusionDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -553,9 +714,28 @@ void SMESHGUI_ExtrusionDlg::onTextChange (const QString& theNewText) if (send == LineEditElements) { SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0; - SMESH::ElementType SMESHType = GetConstructorId() ? SMESH::FACE : SMESH::EDGE; - SMDSAbs_ElementType SMDSType = GetConstructorId() ? SMDSAbs_Face: SMDSAbs_Edge; - + SMESH::ElementType SMESHType; + SMDSAbs_ElementType SMDSType; + switch (GetConstructorId()) { + case 0: + { + SMESHType = SMESH::NODE; + SMDSType = SMDSAbs_Node; + break; + } + case 1: + { + SMESHType = SMESH::EDGE; + SMDSType = SMDSAbs_Edge; + break; + } + case 2: + { + SMESHType = SMESH::FACE; + SMDSType = SMDSAbs_Face; + break; + } + } myElementsId = new SMESH::long_array; myElementsId->length( aListId.count() ); TColStd_MapOfInteger newIndices; @@ -564,7 +744,11 @@ void SMESHGUI_ExtrusionDlg::onTextChange (const QString& theNewText) bool validId = false; if ( id > 0 ) { if ( aMesh ) { - const SMDS_MeshElement * e = aMesh->FindElement( id ); + const SMDS_MeshElement * e; + if (SMDSType == SMDSAbs_Node) + e = aMesh->FindNode( id ); + else + e = aMesh->FindElement( id ); validId = ( e && e->GetType() == SMDSType ); } else { validId = ( myMesh->GetElementType( id, true ) == SMESHType ); @@ -576,12 +760,14 @@ void SMESHGUI_ExtrusionDlg::onTextChange (const QString& theNewText) myElementsId->length( myNbOkElements = newIndices.Extent() ); mySelector->AddOrRemoveIndex(myIO, newIndices, false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( myIO, true, true ); + aViewWindow->highlight( myIO, true, true ); } } CheckIsEnable(); + onDisplaySimulation(true); + myBusy = false; } @@ -598,8 +784,11 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() return; // clear - myActor = 0; - myIO.Nullify(); + if(myEditCurrentArgument != (QWidget*)SpinBox_Vx) { + myActor = 0; + Handle(SALOME_InteractiveObject) resIO = myIO; + myIO.Nullify(); + } QString aString = ""; // set busy flag @@ -617,11 +806,14 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() return; Handle(SALOME_InteractiveObject) IO = aList.First(); - myMesh = SMESH::GetMeshByIO(IO); - if (myMesh->_is_nil()) - return; - myIO = IO; - myActor = SMESH::FindActorByObject(myMesh); + + if(myEditCurrentArgument != (QWidget*)SpinBox_Vx) { + myMesh = SMESH::GetMeshByIO(IO); + if (myMesh->_is_nil()) + return; + myIO = IO; + myActor = SMESH::FindActorByObject(myMesh); + } if (myEditCurrentArgument == (QWidget*)LineEditElements) { int aNbElements = 0; @@ -648,7 +840,7 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() aNbElements = aMapIndex.Extent(); if (aNbElements < 1) - return; + return; myElementsId = new SMESH::long_array; myElementsId->length( aNbElements ); @@ -667,7 +859,9 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() TColStd_IndexedMapOfInteger aMapIndex; mySelector->GetIndex(IO,aMapIndex); int aNbElements = aMapIndex.Extent(); - SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0; + SMESH::SMESH_Mesh_var aMesh_var = SMESH::GetMeshByIO(IO); + SMESH_Actor* anActor = SMESH::FindActorByObject(aMesh_var); + SMDS_Mesh* aMesh = anActor ? anActor->GetObject()->GetMesh() : 0; if(aNbElements != 1 || !aMesh) return; @@ -684,6 +878,8 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument() } + onDisplaySimulation(true); + // OK CheckIsEnable(); } @@ -704,20 +900,30 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument() myEditCurrentArgument = (QWidget*)LineEditElements; if (CheckBoxMesh->isChecked()) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); + aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); } else { int aConstructorId = GetConstructorId(); - if (aConstructorId == 0) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - } - else if (aConstructorId == 1) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - } + switch(aConstructorId) { + case 0: + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + break; + } + case 1: + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); + break; + } + case 2: + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + break; + } + } } } else if (send == SelectVectorButton){ @@ -774,17 +980,47 @@ void SMESHGUI_ExtrusionDlg::enterEvent (QEvent*) ActivateThisDialog(); } +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_ExtrusionDlg::closeEvent( QCloseEvent* ) +{ + /* same than click on cancel button */ + disconnect(mySelectionMgr, 0, this, 0); + mySelectionMgr->clearFilters(); + //mySelectionMgr->clearSelected(); + if (SMESH::GetCurrentVtkView()) { + SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters + SMESH::SetPointRepresentation(false); + SMESH::SetPickable(); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySMESHGUI->ResetState(); +} + +void SMESHGUI_ExtrusionDlg::reject() +{ + QDialog::reject(); + close(); +} + //================================================================================= // function : onSelectMesh() // purpose : //================================================================================= void SMESHGUI_ExtrusionDlg::onSelectMesh (bool toSelectMesh) { - if (toSelectMesh) + if (toSelectMesh) { + myIDs = LineEditElements->text(); TextLabelElements->setText(tr("SMESH_NAME")); + } else TextLabelElements->setText(tr("SMESH_ID_ELEMENTS")); + myFilterBtn->setEnabled(!toSelectMesh); + if (myEditCurrentArgument != LineEditElements) { LineEditElements->clear(); return; @@ -800,23 +1036,35 @@ void SMESHGUI_ExtrusionDlg::onSelectMesh (bool toSelectMesh) LineEditElements->setValidator(0); } else { int aConstructorId = GetConstructorId(); - if (aConstructorId == 0) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - } - else if (aConstructorId == 0) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - } - + switch(aConstructorId) { + case 0: + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + break; + } + case 1: + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); + break; + } + case 2: + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + break; + } + } LineEditElements->setReadOnly(false); LineEditElements->setValidator(myIdValidator); onTextChange(LineEditElements->text()); } SelectionIntoArgument(); + + if (!toSelectMesh) + LineEditElements->setText( myIDs ); } //================================================================================= @@ -850,14 +1098,38 @@ void SMESHGUI_ExtrusionDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_ExtrusionDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) { QList types; + types.append( SMESH::NODE ); types.append( SMESH::EDGE ); types.append( SMESH::FACE ); myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types ); } - myFilterDlg->Init( GetConstructorId() ? SMESH::FACE : SMESH::EDGE ); + switch( GetConstructorId() ){ + case 0: + { + myFilterDlg->Init( SMESH::NODE ); + break; + } + case 1: + { + myFilterDlg->Init( SMESH::EDGE ); + break; + } + case 2: + { + myFilterDlg->Init( SMESH::FACE ); + break; + } + } + myFilterDlg->SetSelection(); myFilterDlg->SetMesh( myMesh ); @@ -874,9 +1146,16 @@ bool SMESHGUI_ExtrusionDlg::isValid() { QString msg; bool ok = true; - ok = SpinBox_Dx->isValid( msg, true ) && ok; - ok = SpinBox_Dy->isValid( msg, true ) && ok; - ok = SpinBox_Dz->isValid( msg, true ) && ok; + if ( RadioButton3->isChecked() ) { + ok = SpinBox_Dx->isValid( msg, true ) && ok; + ok = SpinBox_Dy->isValid( msg, true ) && ok; + ok = SpinBox_Dz->isValid( msg, true ) && ok; + } else if ( RadioButton4->isChecked() ) { + ok = SpinBox_Vx->isValid( msg, true ) && ok; + ok = SpinBox_Vy->isValid( msg, true ) && ok; + ok = SpinBox_Vz->isValid( msg, true ) && ok; + ok = SpinBox_VDist->isValid( msg, true ) && ok; + } ok = SpinBox_NbSteps->isValid( msg, true ) && ok; if( !ok ) { @@ -888,3 +1167,82 @@ bool SMESHGUI_ExtrusionDlg::isValid() } return true; } + +//================================================================================= +// function : onDisplaySimulation +// purpose : Show/Hide preview +//================================================================================= +void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) { + if (myPreviewCheckBox->isChecked() && toDisplayPreview) { + if (myNbOkElements && isValid() && isValuesValid()) { + //Get input vector + SMESH::DirStruct aVector; + getExtrusionVector(aVector); + + //Get Number of the steps + long aNbSteps = (long)SpinBox_NbSteps->value(); + + try { + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); + if( CheckBoxMesh->isChecked() ) { + switch (GetConstructorId()) { + case 0: + { + aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps); + break; + } + case 1: + { + aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps); + break; + } + case 2: + { + aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps); + break; + } + } + } + else + if(GetConstructorId() == 0) + aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps); + else + aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps); + + SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); + mySimulation->SetData(aMeshPreviewStruct._retn()); + } catch (...) { + hidePreview(); + } + } else { + hidePreview(); + } + } else { + hidePreview(); + } +} + +//================================================================================= +// function : getExtrusionVector() +// purpose : get direction of the extrusion +//================================================================================= +void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector) { + if ( RadioButton3->isChecked() ) { + aVector.PS.x = SpinBox_Dx->GetValue(); + aVector.PS.y = SpinBox_Dy->GetValue(); + aVector.PS.z = SpinBox_Dz->GetValue(); + } else if ( RadioButton4->isChecked() ) { + gp_XYZ aNormale(SpinBox_Vx->GetValue(), + SpinBox_Vy->GetValue(), + SpinBox_Vz->GetValue()); + + + aNormale /= aNormale.Modulus(); + double aVDist = (double)SpinBox_VDist->value(); + + aVector.PS.x = aNormale.X()*aVDist; + aVector.PS.y = aNormale.Y()*aVDist; + aVector.PS.z = aNormale.Z()*aVDist; + } +} diff --git a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h index 99468eaa7..dd0b741a0 100644 --- a/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h +++ b/src/SMESHGUI/SMESHGUI_ExtrusionDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_ExtrusionDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -28,13 +29,11 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" +#include "SMESHGUI_PreviewDlg.h" // SALOME GUI includes #include -// Qt includes -#include - // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Mesh) @@ -61,7 +60,7 @@ class SalomeApp_IntSpinBox; // class : SMESHGUI_ExtrusionDlg // purpose : //================================================================================= -class SMESHGUI_EXPORT SMESHGUI_ExtrusionDlg : public QDialog +class SMESHGUI_EXPORT SMESHGUI_ExtrusionDlg : public SMESHGUI_PreviewDlg { Q_OBJECT @@ -69,15 +68,19 @@ public: SMESHGUI_ExtrusionDlg( SMESHGUI* ); ~SMESHGUI_ExtrusionDlg(); + void reject(); + private: void Init( bool = true ); void enterEvent( QEvent* ); /* mouse enter the QWidget */ + void closeEvent( QCloseEvent* ); void keyPressEvent( QKeyEvent* ); int GetConstructorId(); - + void getExtrusionVector(SMESH::DirStruct& aVector); + bool isValid(); + bool isValuesValid(); - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ SMESHGUI_IdValidator* myIdValidator; LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ QWidget* myEditCurrentArgument; /* Current argument editor */ @@ -96,10 +99,14 @@ private: // widgets QGroupBox* ConstructorsBox; QButtonGroup* GroupConstructors; + QRadioButton* RadioButton0; QRadioButton* RadioButton1; QRadioButton* RadioButton2; + QRadioButton* RadioButton3; + QRadioButton* RadioButton4; QGroupBox* GroupArguments; + QGroupBox* GroupDimensions; QLabel* TextLabelElements; QPushButton* SelectElementsButton; QLineEdit* LineEditElements; @@ -119,6 +126,8 @@ private: SMESHGUI_SpinBox* SpinBox_Vy; QLabel* TextLabelVz; SMESHGUI_SpinBox* SpinBox_Vz; + QLabel* TextLabelDist; + SMESHGUI_SpinBox* SpinBox_VDist; QLabel* TextLabelNbSteps; SalomeApp_IntSpinBox* SpinBox_NbSteps; QCheckBox* MakeGroupsCheck; @@ -130,8 +139,13 @@ private: QPushButton* buttonHelp; QString myHelpFileName; + QString myIDs; + QPushButton* myFilterBtn; SMESHGUI_FilterDlg* myFilterDlg; + +protected slots: + virtual void onDisplaySimulation( bool ); private slots: void ConstructorsClicked( int ); @@ -140,6 +154,7 @@ private slots: bool ClickOnApply(); void ClickOnCancel(); void ClickOnHelp(); + void ClickOnRadio(); void SetEditCurrentArgument(); void SelectionIntoArgument(); void DeactivateActiveDialog(); diff --git a/src/SMESHGUI/SMESHGUI_FileInfoDlg.cxx b/src/SMESHGUI/SMESHGUI_FileInfoDlg.cxx index b6f6f0e48..78446f12b 100644 --- a/src/SMESHGUI/SMESHGUI_FileInfoDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FileInfoDlg.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FileInfoDlg.cxx // Author : Alexandre SOLOVYOV, Open CASCADE S.A.S. (alexander.solovyov@opencascade.com) diff --git a/src/SMESHGUI/SMESHGUI_FileInfoDlg.h b/src/SMESHGUI/SMESHGUI_FileInfoDlg.h index 0303acb61..dee3e0764 100644 --- a/src/SMESHGUI/SMESHGUI_FileInfoDlg.h +++ b/src/SMESHGUI/SMESHGUI_FileInfoDlg.h @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FileInfoDlg.h // Author : Alexandre SOLOVYOV, Open CASCADE S.A.S. (alexander.solovyov@opencascade.com) diff --git a/src/SMESHGUI/SMESHGUI_FileValidator.cxx b/src/SMESHGUI/SMESHGUI_FileValidator.cxx new file mode 100755 index 000000000..e56a4951e --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FileValidator.cxx @@ -0,0 +1,74 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_FileValidator.cxx +// Author : Oleg UVAROV +// SMESH includes +// +#include "SMESHGUI_FileValidator.h" + +// SALOME GUI includes +#include +#include + +// Qt includes +#include + +//======================================================================= +//function : SMESHGUI_FileValidator +//purpose : +//======================================================================= +SMESHGUI_FileValidator::SMESHGUI_FileValidator( QWidget* parent ) +: SUIT_FileValidator( parent ), + myIsOverwrite( true ) +{ +} + +//======================================================================= +//function : canSave +//purpose : +//======================================================================= +bool SMESHGUI_FileValidator::canSave( const QString& fileName, bool checkPermission ) +{ + if ( QFile::exists( fileName ) ) { + if ( parent() ) { + int anAnswer = SUIT_MessageBox::question( parent(), QObject::tr( "SMESH_WRN_WARNING" ), + QObject::tr( "SMESH_FILE_EXISTS" ).arg( fileName ), + QObject::tr( "SMESH_BUT_OVERWRITE" ), + QObject::tr( "SMESH_BUT_ADD" ), + QObject::tr( "SMESH_BUT_CANCEL" ), 0, 2 ); + if( anAnswer == 2 ) + return false; + myIsOverwrite = anAnswer == 0; + } + + // copied from SUIT_FileValidator + if ( checkPermission && !QFileInfo( fileName ).isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "SMESH_ERROR" ), + QObject::tr( "NO_PERMISSION" ).arg( fileName ) ); + return false; + } + } + else { + return SUIT_FileValidator::canSave( fileName, checkPermission ); + } + return true; +} diff --git a/src/SMESHGUI/SMESHGUI_FileValidator.h b/src/SMESHGUI/SMESHGUI_FileValidator.h new file mode 100755 index 000000000..0f6f0129e --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FileValidator.h @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_FileValidator.h +// Author : Oleg UVAROV +// +#ifndef SMESHGUI_FILEVALIDATOR_H +#define SMESHGUI_FILEVALIDATOR_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// SALOME GUI includes +#include + +class SMESHGUI_EXPORT SMESHGUI_FileValidator : public SUIT_FileValidator +{ +public: + SMESHGUI_FileValidator( QWidget* = 0 ); + + virtual bool canSave( const QString&, bool = true ); + + bool isOverwrite() const { return myIsOverwrite; } + +private: + bool myIsOverwrite; +}; + +#endif // SMESHGUI_FILEVALIDATOR_H diff --git a/src/SMESHGUI/SMESHGUI_Filter.cxx b/src/SMESHGUI/SMESHGUI_Filter.cxx index e6d12feec..c011b9606 100755 --- a/src/SMESHGUI/SMESHGUI_Filter.cxx +++ b/src/SMESHGUI/SMESHGUI_Filter.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESHGUI_Filter : Filters for VTK viewer // File : SMESHGUI_Filter.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -106,8 +107,8 @@ bool SMESHGUI_PredicateFilter::IsObjValid( const int theObjId ) const if ( myActor == 0 || myPred->_is_nil() ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -210,8 +211,8 @@ bool SMESHGUI_QuadrangleFilter::IsValid( const int theCellId ) const if ( myActor == 0 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -230,8 +231,8 @@ bool SMESHGUI_QuadrangleFilter::IsObjValid( const int theObjId ) const if ( myActor == 0 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -289,8 +290,8 @@ bool SMESHGUI_TriangleFilter::IsValid( const int theCellId ) const if ( myActor == 0 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -309,8 +310,8 @@ bool SMESHGUI_TriangleFilter::IsObjValid( const int theObjId ) const if ( myActor == 0 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -367,8 +368,8 @@ bool SMESHGUI_FacesFilter::IsValid( const int theCellId ) const if ( myActor == 0 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -386,8 +387,8 @@ bool SMESHGUI_FacesFilter::IsObjValid( const int theObjId ) const if ( myActor == 0 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -441,11 +442,11 @@ SMESHGUI_VolumesFilter::~SMESHGUI_VolumesFilter() //======================================================================= bool SMESHGUI_VolumesFilter::IsValid( const int theCellId ) const { - if ( myActor == 0 ) + if ( myActor == 0 || theCellId < 1 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); @@ -463,8 +464,8 @@ bool SMESHGUI_VolumesFilter::IsObjValid( const int theObjId ) const if ( myActor == 0 ) return false; - SMESH_Actor* anActor = ( SMESH_Actor* )myActor; - if ( anActor->GetObject() == 0 ) + SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor ); + if ( !anActor || anActor->GetObject() == 0 ) return false; SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); diff --git a/src/SMESHGUI/SMESHGUI_Filter.h b/src/SMESHGUI/SMESHGUI_Filter.h index 6da648be9..ed048df67 100755 --- a/src/SMESHGUI/SMESHGUI_Filter.h +++ b/src/SMESHGUI/SMESHGUI_Filter.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESHGUI_Filter : Filters for VTK viewer // File : SMESHGUI_Filter.h // Author : Sergey LITONIN, Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index 0b55d8b71..ac756a16c 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -1,29 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FilterDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. -// SMESH includes // + +// SMESH includes #include "SMESHGUI_FilterDlg.h" #include "SMESHGUI.h" @@ -32,6 +34,7 @@ #include "SMESHGUI_Filter.h" #include "SMESHGUI_FilterUtils.h" #include "SMESHGUI_FilterLibraryDlg.h" +#include "SMESHGUI_SpinBox.h" #include #include @@ -53,6 +56,8 @@ #include #include #include +#include +#include #include #include @@ -159,30 +164,32 @@ public: virtual void SetString(const int, const QString&); void SetEditable(const int, const bool); void SetEditable(const bool); + void SetPrecision(const int, const char* = 0); private: - QMap< int, QLineEdit* > myLineEdits; + QMap< int, QWidget* > myWidgets; }; SMESHGUI_FilterTable::AdditionalWidget::AdditionalWidget (QWidget* theParent) : QWidget(theParent) { QLabel* aLabel = new QLabel(tr("SMESH_TOLERANCE"), this); - myLineEdits[ Tolerance ] = new QLineEdit(this); - QDoubleValidator* aValidator = new QDoubleValidator(myLineEdits[ Tolerance ]); - aValidator->setBottom(0); - myLineEdits[ Tolerance ]->setValidator(aValidator); + + SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox(this); + sb->setAcceptNames( false ); // No Notebook variables allowed + sb->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + sb->RangeStepAndValidator( 0., 1.e20, 0.1, "len_tol_precision" ); + myWidgets[ Tolerance ] = sb; QHBoxLayout* aLay = new QHBoxLayout(this); aLay->setSpacing(SPACING); aLay->setMargin(0); aLay->addWidget(aLabel); - aLay->addWidget(myLineEdits[ Tolerance ]); + aLay->addWidget(myWidgets[ Tolerance ]); aLay->addStretch(); - QString aText = QString("%1").arg(Precision::Confusion()); - myLineEdits[ Tolerance ]->setText(aText); + SetDouble( Tolerance, Precision::Confusion() ); } SMESHGUI_FilterTable::AdditionalWidget::~AdditionalWidget() @@ -204,13 +211,18 @@ bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const QList aParams = GetParameters(); QList::const_iterator anIter; for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter) { - const QLineEdit* aWg = myLineEdits[ *anIter ]; - int p = 0; - QString aText = aWg->text(); - if (aWg->isEnabled() && aWg->validator()->validate(aText, p) != QValidator::Acceptable) { - if (theMsg) - SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("SMESHGUI_INVALID_PARAMETERS")); + if ( !myWidgets.contains( *anIter ) ) continue; + bool valid = true; + if ( qobject_cast( myWidgets[ *anIter ] ) ) { + valid = qobject_cast( myWidgets[ *anIter ] )->hasAcceptableInput(); + } + else if ( qobject_cast( myWidgets[ *anIter ] ) ) { + QString foo; + valid = qobject_cast( myWidgets[ *anIter ] )->isValid( foo, false ); + } + if (!valid && theMsg) { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("SMESHGUI_INVALID_PARAMETERS")); return false; } } @@ -220,41 +232,78 @@ bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const double SMESHGUI_FilterTable::AdditionalWidget::GetDouble (const int theId) const { - return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toDouble() : 0; + double retval = 0; + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->text().toDouble(); + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->GetValue(); + } + return retval; } int SMESHGUI_FilterTable::AdditionalWidget::GetInteger (const int theId) const { - return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toInt() : 0; + int retval = 0; + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->text().toInt(); + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = (int)( qobject_cast( myWidgets[ theId ] )->GetValue() ); + } + return retval; } QString SMESHGUI_FilterTable::AdditionalWidget::GetString (const int theId) const { - return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text() : QString(""); + QString retval = ""; + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->text(); + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = QString::number( qobject_cast( myWidgets[ theId ] )->GetValue() ); + } + return retval; } void SMESHGUI_FilterTable::AdditionalWidget::SetDouble (const int theId, const double theVal) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setText(QString("%1").arg(theVal)); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setText( QString::number( theVal ) ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->SetValue( theVal ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetInteger (const int theId, const int theVal) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setText(QString("%1").arg(theVal)); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setText( QString::number( theVal ) ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->SetValue( (double)theVal ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetString (const int theId, const QString& theVal) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setText(theVal); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setText( theVal ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->SetValue( theVal.toDouble() ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const int theId, const bool isEditable) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setReadOnly(!isEditable); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setReadOnly( !isEditable ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setReadOnly( !isEditable ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable) @@ -265,6 +314,19 @@ void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable) SetEditable( *anIter, isEditable ); } +void SMESHGUI_FilterTable::AdditionalWidget::SetPrecision(const int theId, const char* precision) +{ + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) { + SMESHGUI_SpinBox* sb = qobject_cast( myWidgets[ theId ] ); + double val = sb->GetValue(); + double min = pow(10.0, -(sb->decimals())); + sb->RangeStepAndValidator( 0., 1.e20, 0.1, precision ? precision : "len_tol_precision" ); + sb->SetValue( qMax( val, min ) ); + } + } +} + /* Class : SMESHGUI_FilterTable::ComboItem Description : Combo table item. Identificator corresponding to string may be assigned @@ -411,6 +473,115 @@ bool SMESHGUI_FilterTable::CheckItem::checked() const return checkState() == Qt::Checked; } +/* + Class : SMESHGUI_FilterTable::IntSpinItem + Description : Integer spin table item. +*/ + +class SMESHGUI_FilterTable::IntSpinItem : public QTableWidgetItem +{ +public: + static int Type(); + + IntSpinItem( const int theValue ); + + int value() const; + void setValue( const int theValue ); + + void clear(); +}; + +int SMESHGUI_FilterTable::IntSpinItem::Type() +{ + return QTableWidgetItem::UserType + 3; +} + +SMESHGUI_FilterTable::IntSpinItem::IntSpinItem( const int theValue ) + : QTableWidgetItem( Type() ) +{ + setValue( theValue ); +} + +int SMESHGUI_FilterTable::IntSpinItem::value() const +{ + bool ok = false; + int value = data( Qt::UserRole ).toInt( &ok ); + return ok ? value : 0; +} + +void SMESHGUI_FilterTable::IntSpinItem::setValue( const int theValue ) +{ + setData( Qt::UserRole, theValue ); + setText( QString::number( theValue ) ); +} + +void SMESHGUI_FilterTable::IntSpinItem::clear() +{ + setText( "" ); +} + +/* + Class : SMESHGUI_FilterTable::DoubleSpinItem + Description : Double spin table item. +*/ + +class SMESHGUI_FilterTable::DoubleSpinItem : public QTableWidgetItem +{ +public: + static int Type(); + + DoubleSpinItem( const double theValue ); + + double value() const; + void setValue( const double theValue ); + + int precision() const; + void setPrecision( const int thePrecision ); + + void clear(); +}; + +int SMESHGUI_FilterTable::DoubleSpinItem::Type() +{ + return QTableWidgetItem::UserType + 4; +} + +SMESHGUI_FilterTable::DoubleSpinItem::DoubleSpinItem( const double theValue ) + : QTableWidgetItem( Type() ) +{ + setValue( theValue ); +} + +double SMESHGUI_FilterTable::DoubleSpinItem::value() const +{ + bool ok = false; + double value = data( Qt::UserRole ).toDouble( &ok ); + return ok ? value : 0; +} + +void SMESHGUI_FilterTable::DoubleSpinItem::setValue( const double theValue ) +{ + setData( Qt::UserRole, theValue ); + setText( QString::number( theValue ) ); +} + +int SMESHGUI_FilterTable::DoubleSpinItem::precision() const +{ + bool ok = false; + int precision = data( Qt::UserRole + 1 ).toInt( &ok ); + return ok ? precision : 0; +} + +void SMESHGUI_FilterTable::DoubleSpinItem::setPrecision( const int thePrecision ) +{ + setData( Qt::UserRole + 1, thePrecision ); +} + +void SMESHGUI_FilterTable::DoubleSpinItem::clear() +{ + setText( "" ); +} + /* Class : SMESHGUI_FilterTable::ComboDelegate Description : Table used by this widget @@ -423,13 +594,13 @@ public: ~ComboDelegate(); QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, - const QModelIndex& ) const; + const QModelIndex& ) const; void setEditorData( QWidget*, const QModelIndex& ) const; void setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const; void updateEditorGeometry( QWidget*, const QStyleOptionViewItem&, - const QModelIndex& ) const; + const QModelIndex& ) const; private: QTableWidget* myTable; }; @@ -445,47 +616,86 @@ SMESHGUI_FilterTable::ComboDelegate::~ComboDelegate() } QWidget* SMESHGUI_FilterTable::ComboDelegate::createEditor( QWidget* parent, - const QStyleOptionViewItem& option, - const QModelIndex& index ) const -{ - QStringList l = index.data( Qt::UserRole ).toStringList(); - if ( !l.isEmpty() ) { - QComboBox* cb = new QComboBox( parent ); - cb->setFrame( false ); - cb->addItems( l ); - return cb; + const QStyleOptionViewItem& option, + const QModelIndex& index ) const +{ + QVariant aData = index.data( Qt::UserRole ); + QVariant::Type aDataType = aData.type(); + if( aDataType == QVariant::StringList ) { + QStringList l = aData.toStringList(); + if ( !l.isEmpty() ) { + QComboBox* cb = new QComboBox( parent ); + cb->setFrame( false ); + cb->addItems( l ); + return cb; + } + } + else if( aDataType == QVariant::Int ) { + bool ok = false; + int aValue = aData.toInt( &ok ); + if ( ok ) { + SalomeApp_IntSpinBox* intSpin = new SalomeApp_IntSpinBox( 0, 1000, 1, parent, false, true ); + intSpin->setFrame( false ); + intSpin->setValue( aValue ); + return intSpin; + } + } + else if( aDataType == QVariant::Double ) { + bool ok = false; + double aValue = aData.toDouble( &ok ); + if ( ok ) { + int aPrecision = index.data( Qt::UserRole + 1 ).toInt( &ok ); + if ( !ok ) + aPrecision = 0; + + SalomeApp_DoubleSpinBox* dblSpin = new SalomeApp_DoubleSpinBox( -1.e20, 1.e20, 1, aPrecision, 20, parent, false, true ); + dblSpin->setFrame( false ); + dblSpin->setValue( aValue ); + return dblSpin; + } } return QItemDelegate::createEditor( parent, option, index ); } void SMESHGUI_FilterTable::ComboDelegate::setEditorData( QWidget* editor, - const QModelIndex& index ) const + const QModelIndex& index ) const { - QString value = index.model()->data( index, Qt::DisplayRole ).toString(); - QComboBox* cb = dynamic_cast( editor ); + QVariant data = index.model()->data( index, Qt::DisplayRole ); + QString value = data.toString(); bool bOk = false; - if ( cb ) { + if ( QComboBox* cb = dynamic_cast( editor ) ) { int i = cb->findText( value ); if ( i >= 0 ) { cb->setCurrentIndex( i ); bOk = true; } } + else if ( SalomeApp_DoubleSpinBox* dblSpin = dynamic_cast( editor ) ) { + if( data.type() == QVariant::Double ) { + double valueDouble = data.toDouble( &bOk ); + if( bOk ) + dblSpin->setValue( valueDouble ); + } + } if ( !bOk ) QItemDelegate::setEditorData( editor, index ); } void SMESHGUI_FilterTable::ComboDelegate::setModelData( QWidget* editor, - QAbstractItemModel* model, - const QModelIndex& index) const -{ - QComboBox* cb = dynamic_cast( editor ); - if ( cb ) model->setData( index, cb->currentText(), Qt::DisplayRole ); + QAbstractItemModel* model, + const QModelIndex& index) const +{ + if( QComboBox* cb = dynamic_cast( editor ) ) + model->setData( index, cb->currentText(), Qt::DisplayRole ); + else if( SalomeApp_IntSpinBox* intSpin = dynamic_cast( editor ) ) + model->setData( index, intSpin->value(), Qt::DisplayRole ); + else if( SalomeApp_DoubleSpinBox* dblSpin = dynamic_cast( editor ) ) + model->setData( index, dblSpin->value(), Qt::DisplayRole ); else QItemDelegate::setModelData( editor, model, index ); } void SMESHGUI_FilterTable::ComboDelegate::updateEditorGeometry( QWidget* editor, - const QStyleOptionViewItem& option, - const QModelIndex& index ) const + const QStyleOptionViewItem& option, + const QModelIndex& index ) const { editor->setGeometry( option.rect ); } @@ -597,8 +807,8 @@ bool SMESHGUI_FilterTable::Table::isEditable (int row, int col) const void SMESHGUI_FilterTable::Table::setReadOnly( bool on ) { setEditTriggers( on ? - QAbstractItemView::NoEditTriggers : - QAbstractItemView::AllEditTriggers ); + QAbstractItemView::NoEditTriggers : + QAbstractItemView::AllEditTriggers ); } bool SMESHGUI_FilterTable::Table::isReadOnly() const @@ -909,13 +1119,16 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) QtxColorButton* clrBtn = qobject_cast(aTable->cellWidget(i, 2)); if (clrBtn && !clrBtn->color().isValid()) errMsg = tr( "GROUPCOLOR_ERROR" ); - } else if (aCriterion == SMESH::FT_RangeOfIds || - aCriterion == SMESH::FT_BelongToGeom || - aCriterion == SMESH::FT_BelongToPlane || - aCriterion == SMESH::FT_BelongToCylinder || - aCriterion == SMESH::FT_BelongToGenSurface || - aCriterion == SMESH::FT_ElemGeomType || - aCriterion == SMESH::FT_LyingOnGeom) { + } + else if (aCriterion == SMESH::FT_RangeOfIds || + aCriterion == SMESH::FT_BelongToGeom || + aCriterion == SMESH::FT_BelongToPlane || + aCriterion == SMESH::FT_BelongToCylinder || + aCriterion == SMESH::FT_BelongToGenSurface || + aCriterion == SMESH::FT_ElemGeomType || + aCriterion == SMESH::FT_CoplanarFaces || + aCriterion == SMESH::FT_LyingOnGeom) + { if (aTable->text(i, 2).isEmpty()) errMsg = tr( "ERROR" ); } @@ -929,8 +1142,8 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) if (!aRes && aTable->isEditable(i, 2)) errMsg = tr( "ERROR" ); else if (aType == SMESH::EDGE && - GetCriterionType(i, aType) == SMESH::FT_MultiConnection && - aThreshold == 1) + GetCriterionType(i, aType) == SMESH::FT_MultiConnection && + aThreshold == 1) errMsg = tr( "MULTIEDGES_ERROR" ); } @@ -1029,12 +1242,14 @@ void SMESHGUI_FilterTable::GetCriterion (const int theRow, } else if ( aCriterionType == SMESH::FT_ElemGeomType ) theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value(); + else if ( aCriterionType == SMESH::FT_CoplanarFaces ) + theCriterion.ThresholdID = aTable->text(theRow, 2).toLatin1().constData(); else if ( aCriterionType != SMESH::FT_RangeOfIds && aCriterionType != SMESH::FT_BelongToGeom && - aCriterionType != SMESH::FT_BelongToPlane && - aCriterionType != SMESH::FT_BelongToCylinder && - aCriterionType != SMESH::FT_BelongToGenSurface && - aCriterionType != SMESH::FT_LyingOnGeom) + aCriterionType != SMESH::FT_BelongToPlane && + aCriterionType != SMESH::FT_BelongToCylinder && + aCriterionType != SMESH::FT_BelongToGenSurface && + aCriterionType != SMESH::FT_LyingOnGeom ) { theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value(); theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble(); @@ -1068,7 +1283,10 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow, ((ComboItem*)aTable->item(theRow, 0))->setValue(theCriterion.Type); onCriterionChanged(theRow, 0, aType); - ((ComboItem*)aTable->item(theRow, 1))->setValue(theCriterion.Compare); + if ( theCriterion.Compare == SMESH::FT_Undefined ) + ((ComboItem*)aTable->item(theRow, 1))->setValue( SMESH::FT_EqualTo ); + else + ((ComboItem*)aTable->item(theRow, 1))->setValue(theCriterion.Compare); ((CheckItem*)aTable->item(theRow, 3))->setChecked(theCriterion.UnaryOp == SMESH::FT_LogicalNOT); if (theCriterion.BinaryOp != SMESH::FT_Undefined) @@ -1100,19 +1318,30 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow, ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2); typeBox->setValue( (int)(theCriterion.Threshold + 0.5) ); } + else if (theCriterion.Type == SMESH::FT_CoplanarFaces ) + { + aTable->item( theRow, 2 )->setText( QString( theCriterion.ThresholdID ) ); + } else if (theCriterion.Type != SMESH::FT_RangeOfIds && - theCriterion.Type != SMESH::FT_BelongToGeom && - theCriterion.Type != SMESH::FT_BelongToPlane && - theCriterion.Type != SMESH::FT_BelongToCylinder && - theCriterion.Type != SMESH::FT_BelongToGenSurface && - theCriterion.Type != SMESH::FT_LyingOnGeom && - theCriterion.Type != SMESH::FT_FreeBorders && - theCriterion.Type != SMESH::FT_FreeEdges && - theCriterion.Type != SMESH::FT_FreeNodes && - theCriterion.Type != SMESH::FT_FreeFaces && - theCriterion.Type != SMESH::FT_BadOrientedVolume && - theCriterion.Type != SMESH::FT_LinearOrQuadratic) + theCriterion.Type != SMESH::FT_BelongToGeom && + theCriterion.Type != SMESH::FT_BelongToPlane && + theCriterion.Type != SMESH::FT_BelongToCylinder && + theCriterion.Type != SMESH::FT_BelongToGenSurface && + theCriterion.Type != SMESH::FT_LyingOnGeom && + theCriterion.Type != SMESH::FT_CoplanarFaces && + theCriterion.Type != SMESH::FT_FreeBorders && + theCriterion.Type != SMESH::FT_FreeEdges && + theCriterion.Type != SMESH::FT_FreeNodes && + theCriterion.Type != SMESH::FT_FreeFaces && + theCriterion.Type != SMESH::FT_BadOrientedVolume && + theCriterion.Type != SMESH::FT_BareBorderFace && + theCriterion.Type != SMESH::FT_BareBorderVolume && + theCriterion.Type != SMESH::FT_OverConstrainedFace && + theCriterion.Type != SMESH::FT_OverConstrainedVolume && + theCriterion.Type != SMESH::FT_LinearOrQuadratic) + { aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15)); + } else { aTable->item( theRow, 2 )->setText(QString(theCriterion.ThresholdStr)); @@ -1121,21 +1350,25 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow, } if (theCriterion.Compare == SMESH::FT_EqualTo || - theCriterion.Type == SMESH::FT_BelongToPlane || - theCriterion.Type == SMESH::FT_BelongToCylinder || - theCriterion.Type == SMESH::FT_BelongToGenSurface) + theCriterion.Type == SMESH::FT_BelongToPlane || + theCriterion.Type == SMESH::FT_BelongToCylinder || + theCriterion.Type == SMESH::FT_BelongToGenSurface || + theCriterion.Type == SMESH::FT_BelongToGeom || + theCriterion.Type == SMESH::FT_LyingOnGeom || + theCriterion.Type == SMESH::FT_CoplanarFaces || + theCriterion.Type == SMESH::FT_EqualNodes) { QTableWidgetItem* anItem = aTable->item(theRow, 0); if (!myAddWidgets.contains(anItem)) { myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack); + myAddWidgets[ anItem ]->SetPrecision( AdditionalWidget::Tolerance, getPrecision( theCriterion.Type ) ); myWgStack->addWidget(myAddWidgets[ anItem ]); } myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance); } emit CriterionChanged(theRow, aType); - } //======================================================================= @@ -1263,14 +1496,18 @@ void SMESHGUI_FilterTable::updateAdditionalWidget() ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0)); int aCriterion = GetCriterionType(aRow); - bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo && - aCriterion != SMESH::FT_BelongToGeom && - aCriterion != SMESH::FT_LyingOnGeom && - aCriterion != SMESH::FT_RangeOfIds && - aCriterion != SMESH::FT_FreeEdges && - aCriterion != SMESH::FT_FreeFaces && - aCriterion != SMESH::FT_BadOrientedVolume; - + bool toEnable = ((((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo && + aCriterion != SMESH::FT_RangeOfIds && + aCriterion != SMESH::FT_FreeEdges && + aCriterion != SMESH::FT_FreeFaces && + aCriterion != SMESH::FT_BadOrientedVolume && + aCriterion != SMESH::FT_BareBorderFace && + aCriterion != SMESH::FT_BareBorderVolume && + aCriterion != SMESH::FT_OverConstrainedFace && + aCriterion != SMESH::FT_OverConstrainedVolume) + || + aCriterion == SMESH::FT_CoplanarFaces); + if (!myAddWidgets.contains(anItem)) { myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack); @@ -1278,9 +1515,45 @@ void SMESHGUI_FilterTable::updateAdditionalWidget() } myWgStack->setCurrentWidget(myAddWidgets[ anItem ]); + myAddWidgets[ anItem ]->SetPrecision( AdditionalWidget::Tolerance, getPrecision( aCriterion ) ); myWgStack->setEnabled(toEnable); } +const char* SMESHGUI_FilterTable::getPrecision( const int aType ) +{ + const char* retval = 0; + switch ( aType ) { + case SMESH::FT_AspectRatio: + case SMESH::FT_AspectRatio3D: + case SMESH::FT_Taper: + retval = "parametric_precision"; break; + case SMESH::FT_Warping: + case SMESH::FT_MinimumAngle: + case SMESH::FT_Skew: + case SMESH::FT_CoplanarFaces: + retval = "angle_precision"; break; + case SMESH::FT_Area: + retval = "area_precision"; break; + case SMESH::FT_BelongToGeom: + case SMESH::FT_BelongToPlane: + case SMESH::FT_BelongToCylinder: + case SMESH::FT_BelongToGenSurface: + case SMESH::FT_LyingOnGeom: + case SMESH::FT_EqualNodes: + retval = "len_tol_precision"; break; + case SMESH::FT_Length: + case SMESH::FT_Length2D: + case SMESH::FT_MaxElementLength2D: + case SMESH::FT_MaxElementLength3D: + retval = "length_precision"; break; + case SMESH::FT_Volume3D: + retval = "vol_precision"; break; + default: + break; + } + return retval; +} + //======================================================================= // name : SMESHGUI_FilterTable::removeAdditionalWidget // Purpose : Remove widgets containing additional parameters from widget @@ -1353,8 +1626,17 @@ static QList geomTypes( const int theType ) typeIds.append( SMESH::Geom_PYRAMID ); typeIds.append( SMESH::Geom_HEXA ); typeIds.append( SMESH::Geom_PENTA ); + typeIds.append( SMESH::Geom_HEXAGONAL_PRISM ); typeIds.append( SMESH::Geom_POLYHEDRA ); } + if ( theType == SMESH::ALL || theType == SMESH::ELEM0D ) + { + typeIds.append( SMESH::Geom_POINT ); + } + if ( theType == SMESH::ALL || theType == SMESH::BALL ) + { + typeIds.append( SMESH::Geom_BALL ); + } return typeIds; } @@ -1370,10 +1652,56 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con int aCriterionType = GetCriterionType(row); QtxColorButton* clrBtn = qobject_cast(aTable->cellWidget(row, 2)); - bool isComboItem = aTable->item(row, 2)->type() == ComboItem::Type(); + int aComboType = ComboItem::Type(); + int aIntSpinType = IntSpinItem::Type(); + int aDoubleSpinType = DoubleSpinItem::Type(); + QTableWidgetItem* aTableItem = aTable->item(row, 2); + bool isComboItem = false; + bool isIntSpinItem = false; + bool isDoubleSpinItem = false; + if (aTableItem) { + int aTableType = aTable->item(row, 2)->type(); + isComboItem = ( aTableType == aComboType ); + isIntSpinItem = ( aTableType == aIntSpinType ); + isDoubleSpinItem = ( aTableType == aDoubleSpinType ); + } + bool anIsDoubleCriterion = + aCriterionType == SMESH::FT_AspectRatio || + aCriterionType == SMESH::FT_AspectRatio3D || + aCriterionType == SMESH::FT_Taper || + aCriterionType == SMESH::FT_Warping || + aCriterionType == SMESH::FT_MinimumAngle || + aCriterionType == SMESH::FT_Skew || + aCriterionType == SMESH::FT_Area || + aCriterionType == SMESH::FT_Length || + aCriterionType == SMESH::FT_Length2D || + aCriterionType == SMESH::FT_MaxElementLength2D || + aCriterionType == SMESH::FT_MaxElementLength3D || + aCriterionType == SMESH::FT_Volume3D; + + int aPrecision = 0; + if ( anIsDoubleCriterion ) { + const char* aPrecisionType = getPrecision( aCriterionType ); + SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr( mySMESHGUI ); + if( aPrecisionType && aResourceMgr ) + aPrecision = aResourceMgr->integerValue( "SMESH", aPrecisionType, aPrecision ); + } + + // if the precision is to be changed we should remove the existing + // spin item and create another one with new precision + bool anIsPrecisionChanged = false; + if ( anIsDoubleCriterion && isDoubleSpinItem ) { + if ( DoubleSpinItem* aDoubleSpinItem = dynamic_cast( aTable->item( row, 2 ) ) ) { + anIsPrecisionChanged = aDoubleSpinItem->precision() != aPrecision; + } + } + if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) || - (aCriterionType != SMESH::FT_ElemGeomType && isComboItem) ) + (aCriterionType != SMESH::FT_ElemGeomType && isComboItem) || + (aCriterionType != SMESH::FT_MultiConnection && isIntSpinItem) || + (!anIsDoubleCriterion && isDoubleSpinItem) || + anIsPrecisionChanged ) { bool isSignalsBlocked = aTable->signalsBlocked(); aTable->blockSignals( true ); @@ -1382,13 +1710,16 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con aTable->blockSignals( isSignalsBlocked ); } if ( (aCriterionType == SMESH::FT_GroupColor && !clrBtn) || - (aCriterionType == SMESH::FT_ElemGeomType && !isComboItem) ) + (aCriterionType == SMESH::FT_ElemGeomType && !isComboItem) || + (aCriterionType == SMESH::FT_MultiConnection && !isIntSpinItem) || + (anIsDoubleCriterion && !isDoubleSpinItem) || + anIsPrecisionChanged ) { bool isSignalsBlocked = aTable->signalsBlocked(); aTable->blockSignals( true ); if ( aCriterionType == SMESH::FT_GroupColor ) aTable->setCellWidget( row, 2, new QtxColorButton( aTable ) ); - else { + else if ( aCriterionType == SMESH::FT_ElemGeomType ) { QList typeIds = geomTypes( aType ); QMap typeNames; QList::const_iterator anIter = typeIds.begin(); @@ -1400,17 +1731,36 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con ComboItem* typeBox = new ComboItem( typeNames ); aTable->setItem( row, 2, typeBox ); } + else if ( aCriterionType == SMESH::FT_MultiConnection ) { + IntSpinItem* intSpin = new IntSpinItem( 0 ); + aTable->setItem( row, 2, intSpin ); + } + else if ( anIsDoubleCriterion ) { + DoubleSpinItem* dblSpin = new DoubleSpinItem( 0 ); + dblSpin->setPrecision( aPrecision ); + aTable->setItem( row, 2, dblSpin ); + } aTable->blockSignals( isSignalsBlocked ); } - if (aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes || - aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders || - aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges || - aCriterionType == SMESH::FT_FreeFaces) || - aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume || + if ((aType == SMESH::NODE && (aCriterionType == SMESH::FT_FreeNodes || + aCriterionType == SMESH::FT_EqualNodes )) || + (aType == SMESH::EDGE && (aCriterionType == SMESH::FT_FreeBorders || + aCriterionType == SMESH::FT_EqualEdges )) || + (aType == SMESH::FACE && (aCriterionType == SMESH::FT_BareBorderFace || + aCriterionType == SMESH::FT_OverConstrainedFace || + aCriterionType == SMESH::FT_FreeEdges || + aCriterionType == SMESH::FT_FreeFaces || + aCriterionType == SMESH::FT_EqualFaces)) || + (aType == SMESH::VOLUME && (aCriterionType == SMESH::FT_BadOrientedVolume || + aCriterionType == SMESH::FT_OverConstrainedVolume || + aCriterionType == SMESH::FT_BareBorderVolume || + aCriterionType == SMESH::FT_EqualVolumes )) || aCriterionType == SMESH::FT_LinearOrQuadratic || aCriterionType == SMESH::FT_GroupColor || - aCriterionType == SMESH::FT_ElemGeomType) + aCriterionType == SMESH::FT_ElemGeomType || + aCriterionType == SMESH::FT_CoplanarFaces + ) { bool isSignalsBlocked = aTable->signalsBlocked(); aTable->blockSignals( true ); @@ -1418,8 +1768,10 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con if (aCompareItem->count() > 0) aCompareItem->clear(); aTable->setEditable(false, row, 1); + aTable->item(row, 2)->setText( QString("") ); aTable->setEditable(aCriterionType == SMESH::FT_GroupColor || - aCriterionType == SMESH::FT_ElemGeomType, row, 2); + aCriterionType == SMESH::FT_ElemGeomType || + aCriterionType == SMESH::FT_CoplanarFaces, row, 2); aTable->blockSignals( isSignalsBlocked ); } else if (aCriterionType == SMESH::FT_RangeOfIds || @@ -1445,19 +1797,21 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con } else { - if (aCompareItem->count() != 3) + if (aCompareItem && aCompareItem->count() != 3) { aCompareItem->setItems(getCompare()); } - QString aText = aTable->text(row, 2); - bool isOk = false; - aText.toDouble(&isOk); - aTable->item( row, 2 )->setText(isOk ? aText : QString("")); - if (!aTable->isEditable(row, 1)) - aTable->setEditable(true, row, 1); - if (!aTable->isEditable(row, 2)) - aTable->setEditable(true, row, 2); + if (aTable->item( row, 2 )) { + QString aText = aTable->text(row, 2); + bool isOk = false; + aText.toDouble(&isOk); + aTable->item( row, 2 )->setText(isOk ? aText : QString("")); + if (!aTable->isEditable(row, 1)) + aTable->setEditable(true, row, 1); + if (!aTable->isEditable(row, 2)) + aTable->setEditable(true, row, 2); + } } updateAdditionalWidget(); @@ -1472,7 +1826,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con //======================================================================= void SMESHGUI_FilterTable::onCriterionChanged (int row, int col) { - onCriterionChanged(row, col, -1); + if( col == 0 ) + onCriterionChanged(row, col, -1); } //======================================================================= @@ -1615,6 +1970,7 @@ const QMap& SMESHGUI_FilterTable::getSupportedTypes() const if (aTypes.isEmpty()) { aTypes[ SMESH::NODE ] = tr("NODES"); + aTypes[ SMESH::BALL ] = tr("BALLS"); aTypes[ SMESH::EDGE ] = tr("EDGES"); aTypes[ SMESH::FACE ] = tr("FACES"); aTypes[ SMESH::VOLUME ] = tr("VOLUMES"); @@ -1643,6 +1999,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); aCriteria[ SMESH::FT_FreeNodes ] = tr("FREE_NODES"); aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); + aCriteria[ SMESH::FT_EqualNodes ] = tr("EQUAL_NODE"); } return aCriteria; } @@ -1663,6 +2020,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR"); aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE"); + aCriteria[ SMESH::FT_EqualEdges ] = tr("EQUAL_EDGE"); } return aCriteria; } @@ -1677,6 +2035,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_Taper ] = tr("TAPER"); aCriteria[ SMESH::FT_Skew ] = tr("SKEW"); aCriteria[ SMESH::FT_Area ] = tr("AREA"); + aCriteria[ SMESH::FT_MaxElementLength2D ] = tr("MAX_ELEMENT_LENGTH_2D"); aCriteria[ SMESH::FT_FreeEdges ] = tr("FREE_EDGES"); aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); @@ -1687,9 +2046,13 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_Length2D ] = tr("LENGTH2D"); aCriteria[ SMESH::FT_MultiConnection2D ] = tr("MULTI2D_BORDERS"); aCriteria[ SMESH::FT_FreeFaces ] = tr("FREE_FACES"); + aCriteria[ SMESH::FT_BareBorderFace ] = tr("BARE_BORDER_FACE"); + aCriteria[ SMESH::FT_OverConstrainedFace] = tr("OVER_CONSTRAINED_FACE"); aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR"); aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE"); + aCriteria[ SMESH::FT_CoplanarFaces ] = tr("COPLANAR_FACES"); + aCriteria[ SMESH::FT_EqualFaces ] = tr("EQUAL_FACE"); } return aCriteria; } @@ -1698,15 +2061,48 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) static QMap aCriteria; if (aCriteria.isEmpty()) { - aCriteria[ SMESH::FT_AspectRatio3D ] = tr("ASPECT_RATIO_3D"); - aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); - aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); - aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); - aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME"); - aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D"); - aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR"); - aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); - aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE"); + aCriteria[ SMESH::FT_AspectRatio3D ] = tr("ASPECT_RATIO_3D"); + aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); + aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); + aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); + aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME"); + aCriteria[ SMESH::FT_BareBorderVolume ] = tr("BARE_BORDER_VOLUME"); + aCriteria[ SMESH::FT_OverConstrainedVolume] = tr("OVER_CONSTRAINED_VOLUME"); + aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D"); + aCriteria[ SMESH::FT_MaxElementLength3D ] = tr("MAX_ELEMENT_LENGTH_3D"); + aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR"); + aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); + aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE"); + aCriteria[ SMESH::FT_EqualVolumes ] = tr("EQUAL_VOLUME"); + } + return aCriteria; + } + else if (theType == SMESH::ELEM0D) + { + static QMap aCriteria; + if (aCriteria.isEmpty()) + { + aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); + 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_GroupColor ] = tr("GROUP_COLOR"); + } + return aCriteria; + } + else if (theType == SMESH::BALL) + { + static QMap aCriteria; + if (aCriteria.isEmpty()) + { + aCriteria[ SMESH::FT_BallDiameter ] = tr("BALL_DIAMETER"); + aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); + 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_GroupColor ] = tr("GROUP_COLOR"); } return aCriteria; } @@ -1773,7 +2169,7 @@ SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable (QWidget* thePar } static int aLenCr = qAbs( aMaxLenCr - - aMetrics.width(tr("CRITERION"))) / aMetrics.width(' ') + 5; + aMetrics.width(tr("CRITERION"))) / aMetrics.width(' ') + 5; QString aCrStr; aCrStr.fill(' ', aLenCr); @@ -1803,10 +2199,10 @@ SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable (QWidget* thePar aTable->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); connect(aTable, SIGNAL(cellChanged(int, int)), - this, SLOT(onCriterionChanged(int, int))); + this, SLOT(onCriterionChanged(int, int))); connect(aTable, SIGNAL(currentCellChanged(int, int, int, int)), - this, SLOT(onCurrentChanged(int, int))); + this, SLOT(onCurrentChanged(int, int))); return aTable; } @@ -1836,15 +2232,15 @@ void SMESHGUI_FilterTable::SetEditable (const bool isEditable) Table* aTable = anIter.value(); for (int i = 0, n = aTable->rowCount(); i < n; i++) for (int j = 0, m = aTable->columnCount(); j < m; j++) - { - QTableWidgetItem* anItem = aTable->item(i, j); - if ( dynamic_cast( anItem ) ) { - Qt::ItemFlags f = anItem->flags(); - if (!isEditable) f = f & ~Qt::ItemIsUserCheckable; - else f = f | Qt::ItemIsUserCheckable; - anItem->setFlags( f ); - } - } + { + QTableWidgetItem* anItem = aTable->item(i, j); + if ( dynamic_cast( anItem ) ) { + Qt::ItemFlags f = anItem->flags(); + if (!isEditable) f = f & ~Qt::ItemIsUserCheckable; + else f = f | Qt::ItemIsUserCheckable; + anItem->setFlags( f ); + } + } //end of IPAL19974 if (isEditable) @@ -2017,8 +2413,8 @@ bool SMESHGUI_FilterTable::GetThreshold (const int theRow, // Purpose : Set text and internal value in cell of ID value //======================================================================= void SMESHGUI_FilterTable::SetID( const int theRow, - const QString& theText, - const int theEntityType ) + const QString& theText, + const int theEntityType ) { Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ]; aTable->item( theRow, 5 )->setText( theText ); @@ -2029,8 +2425,8 @@ void SMESHGUI_FilterTable::SetID( const int theRow, // Purpose : Get text and internal value from cell of ID value //======================================================================= bool SMESHGUI_FilterTable::GetID( const int theRow, - QString& theText, - const int theEntityType ) + QString& theText, + const int theEntityType ) { Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ]; QTableWidgetItem* anItem = aTable->item( theRow, 5 ); @@ -2057,7 +2453,8 @@ SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI* theModule, const QList& theTypes ) : QDialog( SMESH::GetDesktop( theModule ) ), mySMESHGUI( theModule ), - mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myInitSourceWgOnApply( true ) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) mySelector = aViewWindow->GetSelector(); @@ -2073,7 +2470,8 @@ SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI* theModule, const int theType ) : QDialog( SMESH::GetDesktop( theModule ) ), mySMESHGUI( theModule ), - mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myInitSourceWgOnApply( true ) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) mySelector = aViewWindow->GetSelector(); @@ -2180,7 +2578,7 @@ QWidget* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent) mySourceGrp->addButton(aSelBtn, Selection); mySourceGrp->addButton(aDlgBtn, Dialog); - aSelBtn->setChecked(true); + aMeshBtn->setChecked(true); return aBox; } @@ -2191,19 +2589,15 @@ QWidget* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent) //======================================================================= void SMESHGUI_FilterDlg::updateMainButtons() { + myButtons[ BTN_Close ]->show(); if (myTypes.count() == 1) { - myButtons[ BTN_Cancel ]->show(); myButtons[ BTN_Apply ]->hide(); - myButtons[ BTN_Close ]->hide(); } else { - myButtons[ BTN_Cancel ]->hide(); myButtons[ BTN_Apply ]->show(); - myButtons[ BTN_Close ]->show(); } - // updateGeometry(); } @@ -2220,7 +2614,6 @@ QWidget* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent) myButtons[ BTN_OK ] = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGrp); myButtons[ BTN_Apply ] = new QPushButton(tr("SMESH_BUT_APPLY"), aGrp); - myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"), aGrp); myButtons[ BTN_Close ] = new QPushButton(tr("SMESH_BUT_CLOSE"), aGrp); myButtons[ BTN_Help ] = new QPushButton(tr("SMESH_BUT_HELP"), aGrp); @@ -2229,12 +2622,10 @@ QWidget* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent) aLay->addWidget(myButtons[ BTN_Apply ]); aLay->addSpacing(10); aLay->addStretch(); - aLay->addWidget(myButtons[ BTN_Cancel ]); aLay->addWidget(myButtons[ BTN_Close ]); aLay->addWidget(myButtons[ BTN_Help ]); connect(myButtons[ BTN_OK ], SIGNAL(clicked()), SLOT(onOk())); - connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose())); connect(myButtons[ BTN_Close ], SIGNAL(clicked()), SLOT(onClose())); connect(myButtons[ BTN_Apply ], SIGNAL(clicked()), SLOT(onApply())); connect(myButtons[ BTN_Help ], SIGNAL(clicked()), SLOT(onHelp())); @@ -2325,8 +2716,8 @@ void SMESHGUI_FilterDlg::Init (const QList& theTypes) mySetInViewer->setChecked(true); mySourceGrp->button(myApplyToState.contains(theTypes.first()) ? - myApplyToState[ theTypes.first() ] : - Selection)->setChecked(true); + myApplyToState[ theTypes.first() ] : + Mesh)->setChecked(true); } //======================================================================= @@ -2400,10 +2791,10 @@ void SMESHGUI_FilterDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -2506,31 +2897,18 @@ void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QList& theIds) if (theWg == 0) return; + QStringList aStrList; + foreach(int id, theIds) + aStrList << QString::number(id); + if (theWg->inherits("QListWidget")) { - QListWidget* aListBox = qobject_cast( theWg ); - aListBox->clear(); - - QStringList aStrList; - QList::const_iterator anIter; - for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) - aStrList.append(QString("%1").arg(*anIter)); - - aListBox->addItems(aStrList); + qobject_cast(theWg)->clear(); + qobject_cast(theWg)->addItems(aStrList); } else if (theWg->inherits("QLineEdit")) { - QLineEdit* aLineEdit = qobject_cast( theWg ); - QString aStr; - QList::const_iterator anIter; - - for (anIter = theIds.begin(); anIter != theIds.end(); ++ anIter) - aStr += QString("%1 ").arg(*anIter); - - if (!aStr.isEmpty()) - aStr.remove(aStr.length() - 1, 1); - - aLineEdit->setText(aStr); + qobject_cast( theWg )->setText(aStrList.join(" ")); } } @@ -2550,7 +2928,8 @@ bool SMESHGUI_FilterDlg::isValid() const aType == SMESH::FT_BelongToPlane || aType == SMESH::FT_BelongToCylinder || aType == SMESH::FT_BelongToGenSurface || - aType == SMESH::FT_LyingOnGeom) { + aType == SMESH::FT_LyingOnGeom) + { QString aName; myTable->GetThreshold(i, aName); @@ -2558,7 +2937,7 @@ bool SMESHGUI_FilterDlg::isValid() const SMESH::GetActiveStudyDocument()->FindObjectByName(aName.toLatin1().constData(), "GEOM"); if (aList.size() == 0) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("BAD_SHAPE_NAME").arg(aName)); + tr("BAD_SHAPE_NAME").arg(aName)); return false; } @@ -2574,31 +2953,54 @@ bool SMESHGUI_FilterDlg::isValid() const aFace.IsNull() || aFace.ShapeType() != TopAbs_FACE) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("SHAPE_IS_NOT_A_FACE").arg(aName)); + tr("SHAPE_IS_NOT_A_FACE").arg(aName)); return false; } Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace)); if (aSurf.IsNull()) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("SHAPE_IS_NOT_A_FACE").arg(aName)); + tr("SHAPE_IS_NOT_A_FACE").arg(aName)); return false; } if (aType == SMESH::FT_BelongToPlane && !aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("SHAPE_IS_NOT_A_PLANE").arg(aName)); + tr("SHAPE_IS_NOT_A_PLANE").arg(aName)); return false; } if (aType == SMESH::FT_BelongToCylinder && !aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName)); + tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName)); return false; } } } } + else if (aType == SMESH::FT_CoplanarFaces) + { + QString faceID; + myTable->GetThreshold(i, faceID); + if ( faceID.isEmpty() ) + { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("FACE_ID_NOT_SELECTED")); + return false; + } + if ( myMesh->_is_nil() ) + { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("MESH_IS_NOT_SELECTED")); + return false; + } + if ( myMesh->GetElementType( faceID.toLong(), /*iselem=*/true) != SMESH::FACE ) + { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("NOT_FACE_ID").arg(faceID)); + return false; + } + } } return true; @@ -2609,18 +3011,24 @@ bool SMESHGUI_FilterDlg::isValid() const // Purpose : Set widget of parent dialog containing idsto be filtered if // user select corresponding source radio button //======================================================================= -void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg) +void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg, + const bool initOnApply) { mySourceWg = theWg; + myInitSourceWgOnApply = initOnApply; } //======================================================================= -// name : SMESHGUI_FilterDlg::SetGroupIds +// name : SMESHGUI_FilterDlg::SetMesh // Purpose : Set mesh //======================================================================= void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh) { - myMesh = theMesh; + if ( !theMesh->_is_nil() ) { + myMesh = theMesh; + if ( !myFilter[ myTable->GetType() ]->_is_nil()) + myFilter[ myTable->GetType() ]->SetMesh( theMesh ); + } const bool isEnable = !(myMesh->_is_nil()); myButtons[BTN_OK]->setEnabled(isEnable); myButtons[BTN_Apply]->setEnabled(isEnable); @@ -2637,7 +3045,7 @@ void SMESHGUI_FilterDlg::SetSelection() if (mySelectionMgr) { myIObjects.Clear(); - const SALOME_ListIO& anObjs = mySelector->StoredIObjects(); + const SALOME_ListIO& anObjs = mySelector->StoredIObjects(); SALOME_ListIteratorOfListIO anIter (anObjs); for ( ; anIter.More(); anIter.Next()) { TColStd_IndexedMapOfInteger aMap; @@ -2674,9 +3082,11 @@ bool SMESHGUI_FilterDlg::onApply() if (!myFilter[ aCurrType ]->GetPredicate()->_is_nil()) { QList aResultIds; filterSource(aCurrType, aResultIds); + // select in viewer selectInViewer(aCurrType, aResultIds); } + myInsertState[ aCurrType ] = mySetInViewer->isChecked(); myApplyToState[ aCurrType ] = mySourceGrp->checkedId(); } @@ -2725,6 +3135,36 @@ bool SMESHGUI_FilterDlg::createFilter (const int theType) return true; } +//================================================================================ +/*! + * \brief Return the current filter + */ +//================================================================================ + +SMESH::Filter_var SMESHGUI_FilterDlg::GetFilter() const +{ + SMESH::Filter_var filter; + try { + int aCurrType = myTable->GetType(); + filter = myFilter[ aCurrType ]; + } + catch(...) + { + } + return filter._retn(); +} + +//================================================================================ +/*! + * \brief Sets a filter to the table + */ +//================================================================================ + +void SMESHGUI_FilterDlg::SetFilter(SMESH::Filter_var filter, int type) +{ + myFilter[ type ] = filter; +} + //======================================================================= // name : SMESHGUI_FilterDlg::insertFilterInViewer // Purpose : Insert filter in viewer @@ -2787,15 +3227,15 @@ void SMESHGUI_FilterDlg::filterSource (const int theType, // filter ids SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate(); - aPred->SetMesh(myMesh); + myFilter[ theType ]->SetMesh(myMesh); QList::const_iterator anIter; for (anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter) if (aPred->IsSatisfy(*anIter)) theResIds.append(*anIter); - - // set ids to the dialog - setIdsToWg(mySourceWg, theResIds); } + // set ids to the dialog + if (myInitSourceWgOnApply || aSourceId == Dialog) + setIdsToWg(mySourceWg, theResIds); } //======================================================================= @@ -2860,7 +3300,7 @@ void SMESHGUI_FilterDlg::filterSelectionSource (const int theType, // Filter entities SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate(); - aPred->SetMesh(myMesh); + myFilter[ theType ]->SetMesh(myMesh); TColStd_MapIteratorOfMapOfInteger aResIter(aToBeFiltered); for ( ; aResIter.More(); aResIter.Next()) if (aPred->IsSatisfy(aResIter.Key())) @@ -2966,24 +3406,33 @@ void SMESHGUI_FilterDlg::onSelectionDone() } } - int aCriterionType = myTable->GetCriterionType(aRow); - if (aList.Extent() != 1 || - !myTable->CurrentCell(aRow, aCol) || - aCriterionType != SMESH::FT_BelongToGeom && - aCriterionType != SMESH::FT_BelongToPlane && - aCriterionType != SMESH::FT_BelongToCylinder && - aCriterionType != SMESH::FT_BelongToGenSurface && - aCriterionType != SMESH::FT_LyingOnGeom) + QList types; + types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane + << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface + << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces; + if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) || + !types.contains(myTable->GetCriterionType(aRow))) return; - Handle(SALOME_InteractiveObject) anIO = aList.First(); - GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface(anIO); - if (!anObj->_is_nil()) + if ( myTable->GetCriterionType(aRow) == SMESH::FT_CoplanarFaces ) + { + QString aString; + int nbElems = SMESH::GetNameOfSelectedElements(mySelector,//myViewWindow->GetSelector(), + aList.First(), aString); + if (nbElems == 1) + myTable->SetThreshold(aRow, aString); + } + else + { + Handle(SALOME_InteractiveObject) anIO = aList.First(); + GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface(anIO); + if (!anObj->_is_nil()) { myTable->SetThreshold(aRow, GEOMBase::GetName(anObj)); //myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj)); myTable->SetID(aRow, anIO->getEntry()); } + } } @@ -3014,9 +3463,9 @@ void SMESHGUI_FilterDlg::updateSelection() if (mySelectionMgr == 0) return; - TColStd_MapOfInteger allTypes; - for( int i=0; i<10; i++ ) - allTypes.Add( i ); +// TColStd_MapOfInteger allTypes; +// for( int i=0; i<10; i++ ) +// allTypes.Add( i ); SalomeApp_Study* aStudy = dynamic_cast( mySMESHGUI->application()->activeStudy() ); if( !aStudy ) return; @@ -3025,15 +3474,16 @@ void SMESHGUI_FilterDlg::updateSelection() mySelectionMgr->clearFilters(); int aRow, aCol; - + + bool isCurrentCell = myTable->CurrentCell(aRow, aCol); int aCriterionType = myTable->GetCriterionType(aRow); - if (myTable->CurrentCell(aRow, aCol) && + if ( isCurrentCell && (aCriterionType == SMESH::FT_BelongToGeom || aCriterionType == SMESH::FT_BelongToPlane || aCriterionType == SMESH::FT_BelongToCylinder || aCriterionType == SMESH::FT_BelongToGenSurface || - aCriterionType == SMESH::FT_LyingOnGeom)) { - + aCriterionType == SMESH::FT_LyingOnGeom)) + { if (aCriterionType == SMESH::FT_BelongToGeom || aCriterionType == SMESH::FT_BelongToGenSurface || aCriterionType == SMESH::FT_LyingOnGeom) { @@ -3048,9 +3498,12 @@ void SMESHGUI_FilterDlg::updateSelection() } myIsSelectionChanged = true; - } else { + } + else + { if (myIsSelectionChanged) { - mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection + // mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection + // Impossible to select any object in the OB on the second opening of FilterDlg } } } diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.h b/src/SMESHGUI/SMESHGUI_FilterDlg.h index ed1c95e9d..ace63067b 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.h +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FilterDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -71,6 +72,8 @@ class SMESHGUI_EXPORT SMESHGUI_FilterTable : public QWidget class Table; class ComboItem; + class IntSpinItem; + class DoubleSpinItem; class CheckItem; class AdditionalWidget; class ComboDelegate; @@ -123,12 +126,12 @@ public: const int = -1 ); void SetID( const int, - const QString&, - const int = -1 ); + const QString&, + const int = -1 ); bool GetID( const int, - QString&, - const int = -1 ); + QString&, + const int = -1 ); void Update(); @@ -167,6 +170,7 @@ private: void updateBtnState(); void removeAdditionalWidget( QTableWidget*, const int ); void updateAdditionalWidget(); + const char* getPrecision( const int ); const QMap& getSupportedTypes() const; @@ -211,7 +215,7 @@ class SMESHGUI_FilterDlg : public QDialog enum { Mesh, Selection, Dialog, None }; // Buttons - enum { BTN_OK, BTN_Cancel, BTN_Apply, BTN_Close, BTN_Help }; + enum { BTN_OK, BTN_Apply, BTN_Close, BTN_Help }; public: SMESHGUI_FilterDlg( SMESHGUI*, const QList& ); @@ -223,10 +227,13 @@ public: void SetSelection(); void SetMesh (SMESH::SMESH_Mesh_var); - void SetSourceWg( QWidget* ); + void SetSourceWg( QWidget*, const bool initOnApply = true ); static SMESH::Filter::Criterion createCriterion(); + SMESH::Filter_var GetFilter() const; + void SetFilter(SMESH::Filter_var filter, int type); + signals: void Accepted(); @@ -285,6 +292,7 @@ private: LightApp_SelectionMgr* mySelectionMgr; SVTK_Selector* mySelector; SMESH::SMESH_Mesh_var myMesh; + bool myInitSourceWgOnApply; QWidget* mySourceWg; SALOME_DataMapOfIOMapOfInteger myIObjects; diff --git a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx index 47c9e912c..c17dde1fa 100644 --- a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FilterLibraryDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -226,7 +227,7 @@ QWidget* SMESHGUI_FilterLibraryDlg::createMainFrame (QWidget* theParent) connect(myOpenBtn, SIGNAL(clicked()), this, SLOT(onBrowse())); connect(myListBox, SIGNAL(itemSelectionChanged()), - this, SLOT(onFilterChanged())); + this, SLOT(onFilterChanged())); connect(myAddBtn, SIGNAL(clicked()), this, SLOT(onAddBtnPressed())); connect(myDeleteBtn, SIGNAL(clicked()), this, SLOT(onDeleteBtnPressed())); @@ -256,7 +257,6 @@ QWidget* SMESHGUI_FilterLibraryDlg::createButtonFrame (QWidget* theParent) myButtons[ BTN_OK ] = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGrp); myButtons[ BTN_Apply ] = new QPushButton(tr("SMESH_BUT_APPLY"), aGrp); - myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"), aGrp); myButtons[ BTN_Close ] = new QPushButton(tr("SMESH_BUT_CLOSE"), aGrp); myButtons[ BTN_Help ] = new QPushButton(tr("SMESH_BUT_HELP"), aGrp); @@ -265,12 +265,10 @@ QWidget* SMESHGUI_FilterLibraryDlg::createButtonFrame (QWidget* theParent) aLay->addWidget(myButtons[ BTN_Apply ]); aLay->addSpacing(10); aLay->addStretch(); - aLay->addWidget(myButtons[ BTN_Cancel ]); aLay->addWidget(myButtons[ BTN_Close ]); aLay->addWidget(myButtons[ BTN_Help ]); connect(myButtons[ BTN_OK ], SIGNAL(clicked()), SLOT(onOk())); - connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose())); connect(myButtons[ BTN_Close ], SIGNAL(clicked()), SLOT(onClose())); connect(myButtons[ BTN_Apply ], SIGNAL(clicked()), SLOT(onApply())); connect(myButtons[ BTN_Help ], SIGNAL(clicked()), SLOT(onHelp())); @@ -290,14 +288,11 @@ QWidget* SMESHGUI_FilterLibraryDlg::createButtonFrame (QWidget* theParent) //======================================================================= void SMESHGUI_FilterLibraryDlg::updateMainButtons() { + myButtons[ BTN_Close ]->show(); if (myTypes.count() == 1) { - myButtons[ BTN_Cancel ]->show(); myButtons[ BTN_Apply ]->hide(); - myButtons[ BTN_Close ]->hide(); } else { - myButtons[ BTN_Cancel ]->hide(); myButtons[ BTN_Apply ]->show(); - myButtons[ BTN_Close ]->show(); } } @@ -423,7 +418,7 @@ bool SMESHGUI_FilterLibraryDlg::onApply() if (myLibrary->_is_nil()) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"), - tr("LIBRARY_IS_NOT_LOADED")); + tr("LIBRARY_IS_NOT_LOADED")); return false; } @@ -437,11 +432,11 @@ bool SMESHGUI_FilterLibraryDlg::onApply() } else if (myMode == EDIT || myMode == ADD_TO) { SMESH::Filter_var aFilter = createFilter(); if (!myListBox->selectedItems().empty() && - !myLibrary->Replace(myCurrFilterName.toLatin1().constData(), - myName->text().toLatin1().constData(), - aFilter.in())) { + !myLibrary->Replace(myCurrFilterName.toLatin1().constData(), + myName->text().toLatin1().constData(), + aFilter.in())) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"), - tr("ERROR_OF_EDITING")); + tr("ERROR_OF_EDITING")); aResult = false; } else @@ -457,7 +452,7 @@ bool SMESHGUI_FilterLibraryDlg::onApply() delete aFileName; } else if (myMode != COPY_FROM) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"), - tr("ERROR_OF_SAVING")); + tr("ERROR_OF_SAVING")); } else { } @@ -507,10 +502,10 @@ void SMESHGUI_FilterLibraryDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -674,7 +669,7 @@ void SMESHGUI_FilterLibraryDlg::processNewLibrary() if (myLibrary->_is_nil()) { if (myMode == COPY_FROM) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"), - tr("ERROR_LOAD")); + tr("ERROR_LOAD")); return; } else { myLibrary = aFilterMgr->CreateLibrary(); @@ -730,7 +725,7 @@ bool SMESHGUI_FilterLibraryDlg::isNameValid(const bool theMess) const if (aCurrName.isEmpty()) { if (theMess) SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("EMPTY_FILTER_NAME")); + tr("EMPTY_FILTER_NAME")); return false; } @@ -739,7 +734,7 @@ bool SMESHGUI_FilterLibraryDlg::isNameValid(const bool theMess) const if (aNames[ f ] == aCurrName && aNames[ f ] != myCurrFilterName) { if (theMess) SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("ERROR_FILTER_NAME")); + tr("ERROR_FILTER_NAME")); return false; } } @@ -787,7 +782,7 @@ bool SMESHGUI_FilterLibraryDlg::isPermissionValid(const bool theIsExistingOnly) if (!isWritable) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"), - tr("NO_PERMISSION")); + tr("NO_PERMISSION")); return false; } @@ -831,8 +826,8 @@ void SMESHGUI_FilterLibraryDlg::onFilterChanged() SMESH::Filter_var aFilter = createFilter(); myLibrary->Replace(myCurrFilterName.toLatin1().constData(), - myName->text().toLatin1().constData(), - aFilter); + myName->text().toLatin1().constData(), + aFilter); } // Fill table with filter parameters @@ -938,8 +933,8 @@ void SMESHGUI_FilterLibraryDlg::onAddBtnPressed() SMESH::Filter_var aFilter = createFilter(); myLibrary->Replace(myCurrFilterName.toLatin1().constData(), - myName->text().toLatin1().constData(), - aFilter); + myName->text().toLatin1().constData(), + aFilter); } myTable->Clear(myTable->GetType()); @@ -955,7 +950,7 @@ void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName) { if (myLibrary->_is_nil()) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"), - tr("LIBRARY_IS_NOT_LOADED")); + tr("LIBRARY_IS_NOT_LOADED")); return; } @@ -979,7 +974,7 @@ void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName) if (!aResult) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"), - tr("ERROR_OF_ADDING")); + tr("ERROR_OF_ADDING")); } updateList(); @@ -989,7 +984,7 @@ void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName) if (theName != aName) SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WARNING"), - tr("ASSIGN_NEW_NAME").arg(theName).arg(aName)); + tr("ASSIGN_NEW_NAME").arg(theName).arg(aName)); } //======================================================================= @@ -1089,7 +1084,7 @@ void SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed() { if (myLibrary->_is_nil()) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"), - tr("LIBRARY_IS_NOT_LOADED")); + tr("LIBRARY_IS_NOT_LOADED")); return; } @@ -1097,7 +1092,7 @@ void SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed() if (anIndex == -1 || !myLibrary->Delete(myCurrFilterName.toLatin1().constData())) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"), - tr("ERROR_OF_DELETING")); + tr("ERROR_OF_DELETING")); } else { myCurrFilterName = ""; myCurrFilter = -1; @@ -1188,8 +1183,8 @@ void SMESHGUI_FilterLibraryDlg::onNeedValidation() { SMESH::Filter_var aFilter = createFilter(myTable->GetType()); myLibrary->Replace(myCurrFilterName.toLatin1().constData(), - myName->text().toLatin1().constData(), - aFilter); + myName->text().toLatin1().constData(), + aFilter); } } } diff --git a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.h b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.h index eb9fe6134..5b5af4fd0 100644 --- a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.h +++ b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FilterLibraryDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -55,7 +56,7 @@ class SMESHGUI_EXPORT SMESHGUI_FilterLibraryDlg : public QDialog Q_OBJECT // Buttons - enum { BTN_OK, BTN_Cancel, BTN_Apply, BTN_Close, BTN_Help }; + enum { BTN_OK, BTN_Apply, BTN_Close, BTN_Help }; class Dialog; diff --git a/src/SMESHGUI/SMESHGUI_FilterUtils.cxx b/src/SMESHGUI/SMESHGUI_FilterUtils.cxx index d7ce02e58..44ca767f1 100644 --- a/src/SMESHGUI/SMESHGUI_FilterUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FilterUtils.cxx // Author : Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_FilterUtils.h b/src/SMESHGUI/SMESHGUI_FilterUtils.h index aa4cfd0be..dd3103d35 100644 --- a/src/SMESHGUI/SMESHGUI_FilterUtils.h +++ b/src/SMESHGUI/SMESHGUI_FilterUtils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_FilterUtils.h // Author : Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx new file mode 100644 index 000000000..89515cad6 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx @@ -0,0 +1,553 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_FindElemByPointDlg.cxx +// Author : Edward AGAPOV, Open CASCADE S.A.S. +// + +// SMESH includes +#include "SMESHGUI_FindElemByPointDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_SpinBox.h" +#include "SMESHGUI_MeshEditPreview.h" + +#include "SMESH_Actor.h" +#include "SMESH_ActorUtils.h" +#include "SMESH_TypeFilter.hxx" +#include "SMESH_LogicalFilter.hxx" + +// SALOME GUI includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// VTK includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +#define SPACING 6 +#define MARGIN 11 + +//======================================================================= +/*! + * \brief Dialog to find elements by a point coordinates + */ +//======================================================================= + +SMESHGUI_FindElemByPointDlg::SMESHGUI_FindElemByPointDlg() + : SMESHGUI_Dialog( 0, false, true, OK | Help ) +{ + setWindowTitle(tr("CAPTION")); + + QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); + aDlgLay->setMargin(0); + aDlgLay->setSpacing(SPACING); + + QWidget* aMainFrame = createMainFrame (mainFrame()); + + aDlgLay->addWidget(aMainFrame); + aDlgLay->setStretchFactor(aMainFrame, 1); +} + +//================================================================================ +/*! + * \brief Set types of elements available for search + */ +//================================================================================ + +void SMESHGUI_FindElemByPointDlg::setTypes(SMESH::array_of_ElementType_var & types) +{ + myElemTypeCombo->blockSignals(true); + myElemTypeCombo->clear(); + int nbTypes = 0, hasNodes = 0; + for ( int i = 0; i < types->length(); ++i ) + { + switch ( types[i] ) { + case SMESH::NODE: + myElemTypeCombo->addItem( tr( "MEN_NODE" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::NODE )); + hasNodes = 1; + break; + case SMESH::EDGE: + myElemTypeCombo->addItem( tr( "MEN_EDGE" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::EDGE )); + break; + case SMESH::FACE: + myElemTypeCombo->addItem( tr( "MEN_FACE" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::FACE )); + break; + case SMESH::VOLUME: + myElemTypeCombo->addItem( tr( "MEN_VOLUME_3D" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::VOLUME )); + break; + case SMESH::ELEM0D: + myElemTypeCombo->addItem( tr( "MEN_ELEM0D" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::ELEM0D )); + break; + case SMESH::BALL: + myElemTypeCombo->addItem( tr( "MEN_BALL" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::BALL )); + break; + default:; + } + } + if ( nbTypes - hasNodes > 1 ) + { + myElemTypeCombo->addItem( tr( "MEN_ALL" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::ALL )); + } + if ( !hasNodes && nbTypes > 0 ) + { + myElemTypeCombo->addItem( tr( "MEN_NODE" )); + myElemTypeCombo->setId( nbTypes++, int( SMESH::NODE )); + } + myElemTypeCombo->blockSignals(false); +} + +//======================================================================= +// function : createMainFrame() +// purpose : Create frame containing dialog's input fields +//======================================================================= +QWidget* SMESHGUI_FindElemByPointDlg::createMainFrame (QWidget* theParent) +{ + QWidget* aFrame = new QWidget(theParent); + + //mesh name + + QGroupBox* aMeshGrp = new QGroupBox(tr("MESH_GROUP"), aFrame); + QHBoxLayout* aMeshGrpLayout = new QHBoxLayout(aMeshGrp); + aMeshGrpLayout->setMargin(MARGIN); + aMeshGrpLayout->setSpacing(SPACING); + + myMeshName = new QLineEdit(aMeshGrp); + aMeshGrpLayout->addWidget(myMeshName); + + // coordinates + + QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame); + QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp); + aCoordGrpLayout->setMargin(MARGIN); + aCoordGrpLayout->setSpacing(SPACING); + + QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp); + myX = new SMESHGUI_SpinBox(aCoordGrp); + + QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp); + myY = new SMESHGUI_SpinBox(aCoordGrp); + + QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp); + myZ = new SMESHGUI_SpinBox(aCoordGrp); + + myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myX->SetValue(0); + myY->SetValue(0); + myZ->SetValue(0); + + aCoordGrpLayout->addWidget(aXLabel); + aCoordGrpLayout->addWidget(myX); + aCoordGrpLayout->addWidget(aYLabel); + aCoordGrpLayout->addWidget(myY); + aCoordGrpLayout->addWidget(aZLabel); + aCoordGrpLayout->addWidget(myZ); + + // Elements + + QGroupBox* elementGrp = new QGroupBox(tr("Elements"), aFrame); + QGridLayout* elementGrpLayout = new QGridLayout(elementGrp); + elementGrpLayout->setSpacing(SPACING); + elementGrpLayout->setMargin(MARGIN); + + + myFindBtn = new QPushButton(elementGrp); + myFindBtn->setText(tr("Find")); + //myFindBtn->setCheckable(false); + + myElemTypeCombo = new QtxComboBox(elementGrp); + + myFoundList = new QListWidget(elementGrp); + + elementGrpLayout->addWidget( myFindBtn, 0, 0 ); + elementGrpLayout->addWidget( myElemTypeCombo, 0, 1 ); + elementGrpLayout->addWidget( myFoundList, 1, 0, 2, 2 ); + + + QVBoxLayout* aLay = new QVBoxLayout(aFrame); + aLay->setMargin( 0 ); + aLay->setSpacing( SPACING ); + aLay->addWidget(aMeshGrp); + aLay->addWidget(aCoordGrp); + aLay->addWidget(elementGrp); + + // OK instead of "Apply and Close" + if ( QAbstractButton* but = button(OK) ) + but->setText( tr("SMESH_BUT_OK")); + + return aFrame; +} + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_FindElemByPointOp::SMESHGUI_FindElemByPointOp() + :SMESHGUI_SelectionOp() +{ + mySimulation = 0; + myDlg = new SMESHGUI_FindElemByPointDlg; + myHelpFileName = "find_element_by_point_page.html"; + + QList filters; + filters.append( new SMESH_TypeFilter( MESH ) ); + filters.append( new SMESH_TypeFilter( GROUP ) ); + myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + + myPreview = new SMESH::MeshPreviewStruct(); + + myPreview->nodesXYZ.length(1); + myPreview->nodesXYZ[0].x = myDlg->myX->GetValue(); + myPreview->nodesXYZ[0].y = myDlg->myY->GetValue(); + myPreview->nodesXYZ[0].z = myDlg->myZ->GetValue(); + + myPreview->elementTypes.length(1); + myPreview->elementTypes[0].SMDS_ElementType = SMESH::NODE; + myPreview->elementTypes[0].isPoly = false; + myPreview->elementTypes[0].nbNodesInElement = 1; + + myPreview->elementConnectivities.length(1); + myPreview->elementConnectivities[0] = 0; + + // connect signals and slots + connect(myDlg->myFindBtn, SIGNAL(clicked()), this, SLOT(onFind())); + 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->myFoundList, SIGNAL(itemSelectionChanged()), this, SLOT(onElemSelected())); + connect(myDlg->myElemTypeCombo,SIGNAL(currentIndexChanged(int)),this, SLOT(onElemTypeChange(int))); + connect(myDlg, SIGNAL(rejectedDlg()), this, SLOT(onRejectedDlg())); +} + +//======================================================================= +// function : startOperation() +// purpose : Init dialog fields, connect signals and slots, show dialog +//======================================================================= +void SMESHGUI_FindElemByPointOp::startOperation() +{ + // 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(); + myDlg->show(); + redisplayPreview(); + + onSelectionDone(); // init myMeshOrPart +} + +//================================================================================ +/*! + * \brief Stops operation + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::stopOperation() +{ + if ( mySimulation ) + { + mySimulation->SetVisibility(false); + delete mySimulation; + mySimulation = 0; + } + selectionMgr()->removeFilter( myFilter ); + SMESHGUI_SelectionOp::stopOperation(); +} + +//================================================================================ +/*! + * \brief hilight found selected elements + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::onElemSelected() +{ + if ( !myMeshIO.IsNull() ) + { + Selection_Mode selMode = + myDlg->myElemTypeCombo->currentId() == int(SMESH::NODE) ? NodeSelection : CellSelection; + if ( selectionMode() != selMode ) + setSelectionMode( selMode ); + + QList ids = myDlg->myFoundList->selectedItems(); + QList::iterator id = ids.begin(); + TColStd_MapOfInteger idMap; + for ( ; id != ids.end(); ++id ) + idMap.Add( (*id)->text().toInt() ); + + addOrRemoveIndex( myMeshIO, idMap, false ); + + SALOME_ListIO aList; + aList.Append(myMeshIO); + selectionMgr()->setSelectedObjects(aList,false); + } +} + +//================================================================================ +/*! + * \brief Set selection mode according to element type + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::onElemTypeChange(int index) +{ + Selection_Mode newMode = (index == 1) ? NodeSelection : CellSelection; + if ( selectionMode() != newMode ) + { + selectionMgr()->clearFilters(); + setSelectionMode( newMode ); + } + myDlg->myFoundList->clear(); +} + +//================================================================================ +/*! + * \brief Method needed for internal cuisine + */ +//================================================================================ + +void SMESHGUI_FindElemByPointDlg::reject() +{ + emit rejectedDlg(); + QtxDialog::reject(); +} + +//================================================================================ +/*! + * \brief Method needed for internal cuisine + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::onRejectedDlg() +{ + myMeshIO.Nullify(); +} + +//================================================================================ +/*! + * \brief perform it's intention action: find elements + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::onFind() +{ + if ( myMeshOrPart->_is_nil() ) + return; + + try { + SUIT_OverrideCursor wc; + + SMESH::SMESH_Mesh_var aMesh = myMeshOrPart->GetMesh(); + if ( aMesh->_is_nil() ) + return; + SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); + if (aMeshEditor->_is_nil()) + return; + + SMESH::long_array_var foundIds; + if ( aMesh->_is_equivalent( myMeshOrPart ) ) + foundIds = + aMeshEditor->FindElementsByPoint( myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue(), + SMESH::ElementType( myDlg->myElemTypeCombo->currentId())); + else + foundIds = + aMeshEditor->FindAmongElementsByPoint( myMeshOrPart, + myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue(), + SMESH::ElementType( myDlg->myElemTypeCombo->currentId())); + myDlg->myFoundList->clear(); + for ( int i = 0; i < foundIds->length(); ++i ) + myDlg->myFoundList->addItem( QString::number( foundIds[i] )); + + if ( foundIds->length() > 0 ) + myDlg->myFoundList->setCurrentRow(0); + } + catch (const SALOME::SALOME_Exception& S_ex) { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + catch (...) { + } +} + +//================================================================================ +/*! + * \brief Method needed for internal cuisine + */ +//================================================================================ + +bool SMESHGUI_FindElemByPointOp::onApply() +{ + onRejectedDlg(); + return true; +} + +//================================================================================ +/*! + * \brief SLOT called when selection changed + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::onSelectionDone() +{ + if ( !myDlg->isVisible() || !myDlg->isEnabled() ) + return; + + QString oldMeshEntry, newMeshEntry; + if ( !myMeshIO.IsNull() && myMeshIO->hasEntry() ) + oldMeshEntry = myMeshIO->getEntry(); + + try { + SALOME_ListIO aList; + selectionMgr()->selectedObjects(aList, SVTK_Viewer::Type()); + if (aList.Extent() == 1 && aList.First()->hasEntry()) + { + Handle(SALOME_InteractiveObject) anIO = aList.First(); + _PTR(SObject) pObj = studyDS()->FindObjectID(anIO->getEntry()); + CORBA::Object_var anObj = SMESH::IObjectToObject( anIO ); + newMeshEntry = anIO->getEntry(); + SMESH::SMESH_IDSource_var aMeshOrPart = SMESH::SMESH_IDSource::_narrow(anObj); + if ( pObj && !aMeshOrPart->_is_nil() && oldMeshEntry != newMeshEntry ) + { + myMeshOrPart = aMeshOrPart; + myMeshIO.Nullify(); + myMeshIO = anIO; + std::string name = pObj->GetName(); + myDlg->myMeshName->setText(""); + myDlg->myMeshName->setText( QString( name.c_str() ).trimmed() ); + SMESH::array_of_ElementType_var types = myMeshOrPart->GetTypes(); + myDlg->setTypes( types ); + } + } + } + catch (...) { + } + + if ( oldMeshEntry != newMeshEntry || newMeshEntry.isEmpty() ) + myDlg->myFoundList->clear(); + + myDlg->myFindBtn->setEnabled( !myMeshIO.IsNull() ); +} + +//================================================================================ +/*! + * \brief show point by coordinates + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::redisplayPreview() +{ + myDlg->myFoundList->clear(); + + myPreview->nodesXYZ[0].x = myDlg->myX->GetValue(); + myPreview->nodesXYZ[0].y = myDlg->myY->GetValue(); + myPreview->nodesXYZ[0].z = myDlg->myZ->GetValue(); + + mySimulation->SetData(&myPreview.in()); +} + +//================================================================================ +/*! + * \brief install filter on meshes + */ +//================================================================================ + +void SMESHGUI_FindElemByPointOp::activateSelection() +{ + selectionMgr()->clearFilters(); + selectionMgr()->installFilter( myFilter ); +} + +//================================================================================ +/*! + * \brief Destructor +*/ +//================================================================================ + +SMESHGUI_FindElemByPointOp::~SMESHGUI_FindElemByPointOp() +{ + if ( myDlg ) { delete myDlg; myDlg = 0; } + if ( mySimulation ) { delete mySimulation; mySimulation = 0; } + if ( myFilter ) + { + QList sub = ((SMESH_LogicalFilter*)myFilter)->getFilters(); + delete sub.front(); + delete sub.back(); + delete myFilter; + myFilter = 0; + } +} + +//================================================================================ +/*! + * \brief Gets dialog of this operation + * \retval LightApp_Dialog* - pointer to dialog of this operation + */ +//================================================================================ + +LightApp_Dialog* SMESHGUI_FindElemByPointOp::dlg() const +{ + return myDlg; +} + diff --git a/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.h b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.h new file mode 100644 index 000000000..09990407e --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.h @@ -0,0 +1,120 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef SMESHGUI_FindElemByPointDLG_H +#define SMESHGUI_FindElemByPointDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +#include "SMESHGUI_Dialog.h" +#include "SMESHGUI_SelectionOp.h" + +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QLineEdit; +class QPushButton; +class QListWidget; +class QtxComboBox; +class SMESHGUI_SpinBox; +class SMESHGUI_MeshEditPreview; +class SMESHGUI_FindElemByPointDlg; + +/*! + * \brief Operation to find elements by a point coordinates + */ +class SMESHGUI_EXPORT SMESHGUI_FindElemByPointOp: public SMESHGUI_SelectionOp +{ + Q_OBJECT + +public: + SMESHGUI_FindElemByPointOp(); + virtual ~SMESHGUI_FindElemByPointOp(); + + virtual LightApp_Dialog* dlg() const; + +protected: + + virtual void startOperation(); + virtual void stopOperation(); + + virtual void activateSelection(); + +protected slots: + + virtual void onFind(); + virtual bool onApply(); + +private slots: + + void onRejectedDlg(); + void onSelectionDone(); + void onElemSelected(); + void onElemTypeChange(int); + void redisplayPreview(); + +private: + SMESHGUI_FindElemByPointDlg* myDlg; + + SUIT_SelectionFilter* myFilter; + SMESHGUI_MeshEditPreview* mySimulation; // to show point coordinates + SMESH::SMESH_IDSource_var myMeshOrPart; + SMESH::MeshPreviewStruct_var myPreview; + Handle(SALOME_InteractiveObject) myMeshIO; +}; + +/*! + * \brief Dialog to find elements by a point coordinates + */ + +class SMESHGUI_EXPORT SMESHGUI_FindElemByPointDlg : public SMESHGUI_Dialog +{ + Q_OBJECT + +public: + SMESHGUI_FindElemByPointDlg(); + + void setTypes(SMESH::array_of_ElementType_var & types); + +private: + QWidget* createMainFrame( QWidget* ); + + QLineEdit* myMeshName; + SMESHGUI_SpinBox* myX; + SMESHGUI_SpinBox* myY; + SMESHGUI_SpinBox* myZ; + QtxComboBox* myElemTypeCombo; + QPushButton* myFindBtn; + QListWidget* myFoundList; + + QString myHelpFileName; + + friend class SMESHGUI_FindElemByPointOp; + +signals: + void rejectedDlg(); + +protected slots: + virtual void reject(); + +private slots: +//void ButtonToggled( bool ); +}; + +#endif // SMESHGUI_FindElemByPointDLG_H diff --git a/src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx b/src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx index 33907aec0..ead9da3c0 100644 --- a/src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GEOMGenUtils.cxx // Author : Open CASCADE S.A.S. @@ -51,7 +52,8 @@ namespace SMESH return aGEOMGen; } - GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh(_PTR(SObject) theMeshOrSubmesh) + GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh(_PTR(SObject) theMeshOrSubmesh, + bool* isMesh) { SALOMEDS_SObject* aMeshOrSubmesh = _CAST(SObject,theMeshOrSubmesh); if(aMeshOrSubmesh) { @@ -60,11 +62,17 @@ namespace SMESH SMESH::SMESH_Mesh_var aMesh = SObjectToInterface( theMeshOrSubmesh ); if ( !aMesh->_is_nil() ) + { + if ( isMesh ) *isMesh = true; return aMesh->GetShapeToMesh(); + } SMESH::SMESH_subMesh_var aSubmesh = SObjectToInterface( theMeshOrSubmesh ); if ( !aSubmesh->_is_nil() ) - return aSubmesh->GetSubShape(); + { + if ( isMesh ) *isMesh = false; + return aSubmesh->GetSubShape(); + } } } return GEOM::GEOM_Object::_nil(); @@ -89,7 +97,7 @@ namespace SMESH SALOMEDS_SObject* aRefSO = _CAST(SObject,aRefSOClient); aMeshShape = GEOM::GEOM_Object::_narrow(aRefSO->GetObject()); } else { - SALOMEDS_SObject* aSO = _CAST(SObject,aSObject); + SALOMEDS_SObject* aSO = _CAST(SObject,aSObject); aMeshShape = GEOM::GEOM_Object::_narrow(aSO->GetObject()); } diff --git a/src/SMESHGUI/SMESHGUI_GEOMGenUtils.h b/src/SMESHGUI/SMESHGUI_GEOMGenUtils.h index 8461a6432..807c2576a 100644 --- a/src/SMESHGUI/SMESHGUI_GEOMGenUtils.h +++ b/src/SMESHGUI/SMESHGUI_GEOMGenUtils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GEOMGenUtils.h // Author : Open CASCADE S.A.S. @@ -42,7 +43,7 @@ namespace SMESH { SMESHGUI_EXPORT GEOM::GEOM_Gen_var GetGEOMGen(); - SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh( _PTR(SObject) ); + SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh( _PTR(SObject), bool* isMesh=0 ); SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetGeom( _PTR(SObject) ); diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index 352215c95..10995de19 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_GroupDlg.cxx -// Author : Natalia KOPNOVA, Open CASCADE S.A.S. -// SMESH includes + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_GroupDlg.cxx +// Author : Natalia KOPNOVA, Open CASCADE S.A.S. +// SMESH includes // #include "SMESHGUI_GroupDlg.h" @@ -38,6 +39,7 @@ #include #include #include +#include // SALOME GEOM includes #include @@ -61,6 +63,8 @@ #include +#include + // SALOME KERNEL includes #include @@ -96,19 +100,34 @@ #define SPACING 6 #define MARGIN 11 +enum grpSelectionMode { + grpNoSelection = -1, + grpNodeSelection = 0, + grpBallSelection = 1, + grpEdgeSelection = 2, + grpFaceSelection = 3, + grpVolumeSelection = 4, + grpSubMeshSelection = 5, + grpGroupSelection = 6, + grpMeshSelection = 7, + grpGeomSelection = 8, + grpAllSelection = 9, +}; + //================================================================================= // function : SMESHGUI_GroupDlg() // purpose : //================================================================================= SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, - SMESH::SMESH_Mesh_ptr theMesh ) + SMESH::SMESH_Mesh_ptr theMesh ) : QDialog( SMESH::GetDesktop( theModule ) ), mySMESHGUI( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ), myIsBusy( false ), myNameChanged( false ), - myActor( 0 ) + myIsApplyAndClose( false ), + myNbChangesOfContents(0) { initDialog( true ); if ( !theMesh->_is_nil() ) @@ -127,14 +146,15 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, // purpose : //================================================================================= SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, - SMESH::SMESH_GroupBase_ptr theGroup, + SMESH::SMESH_GroupBase_ptr theGroup, const bool theIsConvert ) : QDialog( SMESH::GetDesktop( theModule ) ), mySMESHGUI( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ), myIsBusy( false ), - myNameChanged( false ) + myNameChanged( false ), + myNbChangesOfContents(0) // just not to use uninitialized variable { initDialog( false ); if ( !theGroup->_is_nil() ) @@ -145,7 +165,7 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, mySelectGroup->setEnabled( false ); myCurrentLineEdit = myMeshGroupLine; - setSelectionMode( 5 ); + setSelectionMode( grpGroupSelection ); } } @@ -194,6 +214,7 @@ void SMESHGUI_GroupDlg::initDialog( bool create) QStringList types; types.append( tr( "MESH_NODE" ) ); + types.append( tr( "SMESH_BALL_ELEM" ) ); types.append( tr( "SMESH_EDGE" ) ); types.append( tr( "SMESH_FACE" ) ); types.append( tr( "SMESH_VOLUME" ) ); @@ -221,10 +242,13 @@ void SMESHGUI_GroupDlg::initDialog( bool create) QRadioButton* rb1 = new QRadioButton( tr( "SMESH_GROUP_STANDALONE" ), aGrpTypeBox ); QRadioButton* rb2 = new QRadioButton( tr( "SMESH_GROUP_GEOMETRY" ), aGrpTypeBox ); + QRadioButton* rb3 = new QRadioButton( tr( "SMESH_GROUP_FILTER" ), aGrpTypeBox ); myGrpTypeGroup->addButton( rb1, 0 ); myGrpTypeGroup->addButton( rb2, 1 ); + myGrpTypeGroup->addButton( rb3, 2 ); aGrpTypeBoxLayout->addWidget( rb1 ); aGrpTypeBoxLayout->addWidget( rb2 ); + aGrpTypeBoxLayout->addWidget( rb3 ); aGrpTypeBox->setEnabled( create ); myGrpTypeId = -1; @@ -232,66 +256,72 @@ void SMESHGUI_GroupDlg::initDialog( bool create) myWGStack = new QStackedWidget( this ); QWidget* wg1 = new QWidget( myWGStack ); QWidget* wg2 = new QWidget( myWGStack ); + QWidget* wg3 = new QWidget( myWGStack ); /***************************************************************/ - QGroupBox* aContentBox = new QGroupBox( tr( "SMESH_CONTENT" ), wg1 ); + QGroupBox* aContentBox = new QGroupBox( tr( "SMESH_CONTENT" ), wg1 ); QGridLayout* aContentBoxLayout = new QGridLayout( aContentBox ); aContentBoxLayout->setMargin( MARGIN ); aContentBoxLayout->setSpacing( SPACING ); - QLabel* aLabel = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox ); - myElements = new QListWidget( aContentBox ); + mySelectAll = new QCheckBox( tr( "SELECT_ALL" ), aContentBox ); + myAllowElemsModif = new QCheckBox( tr( "ALLOW_ELEM_LIST_MODIF" ), aContentBox ); + + myElementsLab = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox ); + myElements = new QListWidget( aContentBox ); myElements->setSelectionMode( QListWidget::ExtendedSelection ); - myFilter = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox ); - QPushButton* aAddBtn = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox ); - QPushButton* aRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox ); - QPushButton* aSortBtn = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox ); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox ); + myAddBtn = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox ); + myRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox ); + mySortBtn = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox ); - aContentBoxLayout->addWidget( aLabel, 0, 0 ); - aContentBoxLayout->addWidget( myElements, 1, 0, 6, 1 ); - aContentBoxLayout->addWidget( myFilter, 1, 1 ); - aContentBoxLayout->addWidget( aAddBtn, 3, 1 ); - aContentBoxLayout->addWidget( aRemoveBtn, 4, 1 ); - aContentBoxLayout->addWidget( aSortBtn, 6, 1 ); + aContentBoxLayout->addWidget( mySelectAll, 0, 0 ); + aContentBoxLayout->addWidget( myAllowElemsModif, 1, 0 ); + aContentBoxLayout->addWidget( myFilterBtn, 1, 1 ); + aContentBoxLayout->addWidget( myElementsLab, 2, 0 ); + aContentBoxLayout->addWidget( myElements, 3, 0, 6, 1 ); + aContentBoxLayout->addWidget( myAddBtn, 3, 1 ); + aContentBoxLayout->addWidget( myRemoveBtn, 4, 1 ); + aContentBoxLayout->addWidget( mySortBtn, 8, 1 ); aContentBoxLayout->setColumnStretch( 0, 1 ); - aContentBoxLayout->setRowStretch( 2, 1 ); - aContentBoxLayout->setRowStretch( 5, 1 ); + aContentBoxLayout->setRowStretch( 3, 1 ); + aContentBoxLayout->setRowStretch( 6, 1 ); /***************************************************************/ - QGroupBox* aSelectBox = new QGroupBox( tr( "SMESH_SELECT_FROM" ), wg1 ); - QGridLayout* aSelectBoxLayout = new QGridLayout( aSelectBox ); - aSelectBoxLayout->setMargin( MARGIN ); - aSelectBoxLayout->setSpacing( SPACING ); + mySelectBox = new QGroupBox( tr( "SMESH_SELECT_FROM" ), wg1 ); + QGridLayout* mySelectBoxLayout = new QGridLayout( mySelectBox ); + mySelectBoxLayout->setMargin( MARGIN ); + mySelectBoxLayout->setSpacing( SPACING ); - mySelectSubMesh = new QCheckBox( tr( "SMESH_SUBMESH" ), aSelectBox ); - mySubMeshBtn = new QPushButton( aSelectBox ); + mySelectSubMesh = new QCheckBox( tr( "SMESH_SUBMESH" ), mySelectBox ); + mySubMeshBtn = new QPushButton( mySelectBox ); mySubMeshBtn->setIcon( image0 ); - mySubMeshLine = new QLineEdit( aSelectBox ); + mySubMeshLine = new QLineEdit( mySelectBox ); mySubMeshLine->setReadOnly( true ); onSelectSubMesh( false ); - mySelectGroup = new QCheckBox( tr( "SMESH_GROUP" ), aSelectBox ); - myGroupBtn = new QPushButton( aSelectBox ); + mySelectGroup = new QCheckBox( tr( "SMESH_GROUP" ), mySelectBox ); + myGroupBtn = new QPushButton( mySelectBox ); myGroupBtn->setIcon( image0 ); - myGroupLine = new QLineEdit( aSelectBox ); + myGroupLine = new QLineEdit( mySelectBox ); myGroupLine->setReadOnly( true ); onSelectGroup( false ); - aSelectBoxLayout->addWidget( mySelectSubMesh, 0, 0 ); - aSelectBoxLayout->addWidget( mySubMeshBtn, 0, 1 ); - aSelectBoxLayout->addWidget( mySubMeshLine, 0, 2 ); - aSelectBoxLayout->addWidget( mySelectGroup, 1, 0 ); - aSelectBoxLayout->addWidget( myGroupBtn, 1, 1 ); - aSelectBoxLayout->addWidget( myGroupLine, 1, 2 ); + mySelectBoxLayout->addWidget( mySelectSubMesh, 0, 0 ); + mySelectBoxLayout->addWidget( mySubMeshBtn, 0, 1 ); + mySelectBoxLayout->addWidget( mySubMeshLine, 0, 2 ); + mySelectBoxLayout->addWidget( mySelectGroup, 1, 0 ); + mySelectBoxLayout->addWidget( myGroupBtn, 1, 1 ); + mySelectBoxLayout->addWidget( myGroupLine, 1, 2 ); /***************************************************************/ QVBoxLayout* wg1Layout = new QVBoxLayout( wg1 ); wg1Layout->setMargin( 0 ); wg1Layout->setSpacing( SPACING ); wg1Layout->addWidget( aContentBox ); - wg1Layout->addWidget( aSelectBox ); + wg1Layout->addWidget( mySelectBox ); wg1Layout->setStretchFactor( aContentBox, 10 ); /***************************************************************/ @@ -309,15 +339,24 @@ void SMESHGUI_GroupDlg::initDialog( bool create) /***************************************************************/ QGridLayout* wg2Layout = new QGridLayout( wg2 ); wg2Layout->setMargin( 0 ); - wg1Layout->setSpacing( SPACING ); + wg2Layout->setSpacing( SPACING ); wg2Layout->addWidget( geomObject, 0, 0 ); wg2Layout->addWidget( myGeomGroupBtn, 0, 1 ); wg2Layout->addWidget( myGeomGroupLine,0, 2 ); wg2Layout->setRowStretch( 1, 5 ); + /***************************************************************/ + QPushButton * aFilter2 = new QPushButton( tr( "SMESH_BUT_FILTER" ), wg3 ); + QGridLayout* wg3Layout = new QGridLayout( wg3 ); + wg3Layout->setMargin( 0 ); + wg3Layout->setSpacing( SPACING ); + wg3Layout->addWidget( aFilter2, 0, 0 ); + wg3Layout->setRowStretch( 1, 5 ); + /***************************************************************/ myWGStack->insertWidget( 0, wg1 ); myWGStack->insertWidget( 1, wg2 ); + myWGStack->insertWidget( 2, wg3 ); /***************************************************************/ QGroupBox* aColorBox = new QGroupBox(tr( "SMESH_SET_COLOR" ), this); @@ -328,7 +367,7 @@ void SMESHGUI_GroupDlg::initDialog( bool create) QLabel* aColorLab = new QLabel(tr( "SMESH_CHECK_COLOR" ), aColorBox ); myColorBtn = new QtxColorButton(aColorBox); myColorBtn->setSizePolicy( QSizePolicy::MinimumExpanding, - myColorBtn->sizePolicy().verticalPolicy() ); + myColorBtn->sizePolicy().verticalPolicy() ); aColorBoxLayout->addWidget(aColorLab); aColorBoxLayout->addWidget(myColorBtn); @@ -372,45 +411,53 @@ void SMESHGUI_GroupDlg::initDialog( bool create) aMainLayout->addWidget(aButtons, 6, 0, 1, 3); /* signals and slots connections */ - connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); - connect(myGrpTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onGrpTypeChanged(int))); - connect(myTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); + connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(myGrpTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onGrpTypeChanged(int))); + connect(myTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); - connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&))); - connect(myElements, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); + connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&))); + connect(myElements, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); - connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters())); - connect(aAddBtn, SIGNAL(clicked()), this, SLOT(onAdd())); - connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove())); - connect(aSortBtn, SIGNAL(clicked()), this, SLOT(onSort())); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + connect(aFilter2, SIGNAL(clicked()), this, SLOT(setFilters())); + connect(mySelectAll, SIGNAL(toggled(bool)), this, SLOT(onSelectAll())); + connect(myAllowElemsModif,SIGNAL(toggled(bool)), this, SLOT(onSelectAll())); + connect(myAddBtn, SIGNAL(clicked()), this, SLOT(onAdd())); + connect(myRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove())); + connect(mySortBtn, SIGNAL(clicked()), this, SLOT(onSort())); connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool))); connect(mySelectGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool))); - connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); - connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); connect(myGeomGroupBtn, SIGNAL(toggled(bool)), this, SLOT(onGeomSelectionButton(bool))); - connect(myColorBtn, SIGNAL(changed( QColor )), this, SLOT(onColorChanged( QColor ))); + connect(myColorBtn, SIGNAL(changed( QColor )), this, SLOT(onColorChanged( QColor ))); - connect(myOKBtn, SIGNAL(clicked()), this, SLOT(onOK())); - connect(myApplyBtn, SIGNAL(clicked()), this, SLOT(onApply())); - connect(myCloseBtn, SIGNAL(clicked()), this, SLOT(onClose())); - connect(myHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp())); + connect(myOKBtn, SIGNAL(clicked()), this, SLOT(onOK())); + connect(myApplyBtn, SIGNAL(clicked()), this, SLOT(onApply())); + connect(myCloseBtn, SIGNAL(clicked()), this, SLOT(onClose())); + connect(myHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp())); /* Init selection */ mySMESHGUI->SetActiveDialogBox(this); mySMESHGUI->SetState(800); - mySelectionMode = -1; + mySelectionMode = grpNoSelection; myMeshFilter = new SMESH_TypeFilter(MESH); - mySubMeshFilter = new SMESH_TypeFilter(SUBMESH); - myGroupFilter = new SMESH_TypeFilter(GROUP); + mySubMeshFilter = new SMESH_LogicalFilter(QList(), + SMESH_LogicalFilter::LO_OR, + /*takeOwnership=*/true); + myGroupFilter = new SMESH_LogicalFilter(QList(), + SMESH_LogicalFilter::LO_OR, + /*takeOwnership=*/true); SalomeApp_Study* aStudy = dynamic_cast( mySMESHGUI->application()->activeStudy() ); myGeomFilter = new GEOM_SelectionFilter( aStudy, true ); connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onDeactivate())); connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(onClose())); connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onObjectSelectionChanged())); + connect(mySMESHGUI, SIGNAL(SignalVisibilityChanged()), this, SLOT(onVisibilityChanged())); rb1->setChecked(true); // VSR !!! onGrpTypeChanged(0); // VSR!!! @@ -418,8 +465,7 @@ void SMESHGUI_GroupDlg::initDialog( bool create) if (myMesh->_is_nil() ) myTypeGroup->button(0)->setChecked(true); - updateButtons(); - //myName->setText(GetDefaultName(tr( "SMESH_GROUP" ))); + onSelectAll(); //updateButtons(); } //================================================================================= @@ -433,6 +479,10 @@ SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg() myFilterDlg->setParent( 0 ); delete myFilterDlg; } + if ( myMeshFilter ) delete myMeshFilter; + if ( mySubMeshFilter ) delete mySubMeshFilter; + if ( myGroupFilter ) delete myGroupFilter; + if ( myGeomFilter ) delete myGeomFilter; } //================================================================================= @@ -485,6 +535,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh) setShowEntityMode(); myGroup = SMESH::SMESH_Group::_nil(); myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); + myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil(); // NPAL19389: create a group with a selection in another group // set actor of myMesh, if it is visible, else try @@ -513,7 +564,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh) // purpose : //================================================================================= void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup, - const bool theIsConvert) + const bool theIsConvert) { restoreShowEntityMode(); myMesh = theGroup->GetMesh(); @@ -532,17 +583,20 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup, int aType = 0; switch(theGroup->GetType()) { - case SMESH::NODE: aType= 0; break; - case SMESH::EDGE: aType = 1; break; - case SMESH::FACE: aType = 2; break; - case SMESH::VOLUME: aType = 3; break; + case SMESH::NODE: aType = 0; break; + case SMESH::BALL: aType = 1; break; + case SMESH::EDGE: aType = 2; break; + case SMESH::FACE: aType = 3; break; + case SMESH::VOLUME: aType = 4; break; } myTypeGroup->button(aType)->setChecked(true); - myGroup = SMESH::SMESH_Group::_narrow( theGroup ); - myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup ); + myGroup = SMESH::SMESH_Group::_narrow( theGroup ); + myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup ); + myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_narrow( theGroup ); + myFilter = SMESH::Filter::_nil(); - if (myGroup->_is_nil() && myGroupOnGeom->_is_nil()) + if (myGroup->_is_nil() && myGroupOnGeom->_is_nil() && myGroupOnFilter->_is_nil() ) return; // NPAL19389: create a group with a selection in another group @@ -550,21 +604,24 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup, // actor of theGroup, if it is visible, else try // any visible actor of group or submesh of myMesh // commented, because an attempt to set selection on not displayed cells leads to error - //SetAppropriateActor(); - myActor = SMESH::FindActorByObject(myMesh); - if ( !myActor ) - myActor = SMESH::FindActorByObject(theGroup); - SMESH::SetPickable(myActor); + SetAppropriateActor(); - int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : 1)); + /* SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh); + if ( !anActor ) + anActor = SMESH::FindActorByObject(theGroup); + SMESH::SetPickable(anActor);*/ + + int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : myGroupOnGeom->_is_nil() ? 2 : 1)); myGrpTypeGroup->button(grpType)->setChecked(true); onGrpTypeChanged(grpType); - if ( grpType == 0 ) { + myTypeId = aType; + if ( grpType == 0 ) { // standalone group myCurrentLineEdit = 0; myElements->clear(); + myAllowElemsModif->setChecked( true ); + setSelectionMode(aType); - myTypeId = aType; setShowEntityMode(); // depends on myTypeId @@ -579,7 +636,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup, myElements->selectAll(); } } - else + else if ( grpType == 1 ) // group on geom { QString aShapeName( "" ); _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); @@ -587,15 +644,30 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup, if (!aGroupShape->_is_nil()) { _PTR(SObject) aGroupShapeSO = aStudy->FindObjectID(aGroupShape->GetStudyEntry()); - aShapeName = aGroupShapeSO->GetName().c_str(); + if ( aGroupShapeSO ) + aShapeName = aGroupShapeSO->GetName().c_str(); } myGeomGroupLine->setText( aShapeName ); + } + else // group on filter + { + myFilter = myGroupOnFilter->GetFilter(); + if ( !myFilter->_is_nil() ) { + SMESH::Predicate_var perdicate = myFilter->GetPredicate(); + if ( perdicate->_is_nil() ) + myFilter = SMESH::Filter::_nil(); + } + } + + if ( grpType != 0 ) + { myNameChanged = true; myName->blockSignals(true); - myName->setText( "Group On " + aShapeName); + myName->setText(theGroup->GetName()); myName->blockSignals(false); } - updateButtons(); + + onSelectAll(); //updateButtons(); } //================================================================================= @@ -605,14 +677,33 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup, void SMESHGUI_GroupDlg::updateButtons() { bool enable = !myName->text().trimmed().isEmpty(); - - 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(); + if ( enable ) + { + if (myGrpTypeId == 0) { // standalone + if ( !mySelectAll->isChecked() ) + { + if ( myAllowElemsModif->isChecked() ) + { + enable = ( myElements->count() > 0 ); + } + else if ((enable = !myFilter->_is_nil() )) + { + SMESH::array_of_ElementType_var types = myFilter->GetTypes(); + enable = types->length(); + } + } + enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil()); + } + else if (myGrpTypeId == 1) // on geom + { + if (CORBA::is_nil(myGroupOnGeom)) // creation mode + enable = ( myGeomObjects->length() > 0 && !myMesh->_is_nil() ); + } + else if (myGrpTypeId == 2) // on filter + { + if (( enable = !myFilter->_is_nil() )) + if (CORBA::is_nil(myGroupOnFilter) ) // creation mode + enable = !myMesh->_is_nil(); } } @@ -639,9 +730,13 @@ void SMESHGUI_GroupDlg::onTypeChanged (int id) { if (myTypeId != id) { myElements->clear(); - if (myCurrentLineEdit == 0) - setSelectionMode(id); myTypeId = id; + if ( myGrpTypeId == 0 && myCurrentLineEdit == 0) + setSelectionMode(id); + else + setSelectionMode( mySelectionMode++ ); // update according to mySelectionMode + + onObjectSelectionChanged(); setShowEntityMode(); } } @@ -653,13 +748,14 @@ void SMESHGUI_GroupDlg::onTypeChanged (int id) void SMESHGUI_GroupDlg::onGrpTypeChanged (int id) { if (myGrpTypeId != id) { + myGrpTypeId = id; myWGStack->setCurrentIndex( id ); myName->blockSignals(true); myName->setText(myOldName); myName->blockSignals(false); - onSelectGeomGroup(id == 1); + onSelectGeomGroup(id != 0); } - myGrpTypeId = id; + updateButtons(); } //================================================================================= @@ -680,48 +776,95 @@ void SMESHGUI_GroupDlg::setSelectionMode (int theMode) // PAL7314 if (myMesh->_is_nil()) return; + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ); + bool isSelectAll = mySelectAll->isChecked() || !myAllowElemsModif->isChecked() || myGrpTypeId != 0; if (mySelectionMode != theMode) { // [PAL10408] mySelectionMgr->clearSelected(); mySelectionMgr->clearFilters(); - if (myActor) - myActor->SetPointRepresentation(false); + SMESH::RemoveFilters(); + + if (myActorsList.count() > 0) + for (QListIterator it( myActorsList ); it.hasNext(); ) + it.next()->SetPointRepresentation(false); else SMESH::SetPointRepresentation(false); - if (theMode < 4) { - switch (theMode) { - case 0: - if (myActor) - myActor->SetPointRepresentation(true); - else - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - break; - case 1: - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - break; - case 2: - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - break; - default: - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(VolumeSelection); + + switch (theMode) { + case grpNodeSelection: + if ( myGrpTypeId == 0 ) // standalone + { + if (myActorsList.count() > 0) + for (QListIterator it( myActorsList ); it.hasNext(); ) + it.next()->SetPointRepresentation(true); + else + SMESH::SetPointRepresentation(true); + } + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : NodeSelection); + break; + case grpEdgeSelection: + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : EdgeSelection); + break; + case grpBallSelection: + //if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : BallSelection); + break; + case grpFaceSelection: + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : FaceSelection); + break; + case grpVolumeSelection: + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : VolumeSelection); + break; + case grpSubMeshSelection: { + + SMESH_TypeFilter* f = 0; + switch (myTypeId) { + case grpNodeSelection: f = new SMESH_TypeFilter(SUBMESH); break; + case grpEdgeSelection: f = new SMESH_TypeFilter(SUBMESH_EDGE); break; + case grpFaceSelection: f = new SMESH_TypeFilter(SUBMESH_FACE); break; + case grpVolumeSelection: f = new SMESH_TypeFilter(SUBMESH_SOLID); break; + default: f = new SMESH_TypeFilter(SUBMESH); + } + QList filtList; + filtList.append( f ); + filtList.append( new SMESH_TypeFilter(SUBMESH_COMPOUND)); + mySubMeshFilter->setFilters( filtList ); + + mySelectionMgr->installFilter( mySubMeshFilter ); + + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + } + case grpGroupSelection: { + + SMESH_TypeFilter* f = 0; + switch (myTypeId) { + case grpNodeSelection: f = new SMESH_TypeFilter(GROUP_NODE); break; + case grpBallSelection: f = new SMESH_TypeFilter(GROUP_BALL); break; + case grpEdgeSelection: f = new SMESH_TypeFilter(GROUP_EDGE); break; + case grpFaceSelection: f = new SMESH_TypeFilter(GROUP_FACE); break; + case grpVolumeSelection: f = new SMESH_TypeFilter(GROUP_VOLUME); break; + default: f = new SMESH_TypeFilter(GROUP); } - } else { - if (theMode == 4) - mySelectionMgr->installFilter(mySubMeshFilter); - else if (theMode == 5) - mySelectionMgr->installFilter(myGroupFilter); - else if (theMode == 6) - mySelectionMgr->installFilter(myMeshFilter); - else if (theMode == 7) - mySelectionMgr->installFilter(myGeomFilter); - - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); + QList filtList; + filtList.append( f ); + myGroupFilter->setFilters( filtList ); + + mySelectionMgr->installFilter(myGroupFilter); + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + } + case grpMeshSelection: + mySelectionMgr->installFilter(myMeshFilter); + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + case grpGeomSelection: + mySelectionMgr->installFilter(myGeomFilter); + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + default: + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; } + if ( aViewWindow ) aViewWindow->Repaint(); mySelectionMode = theMode; } } @@ -738,20 +881,40 @@ bool SMESHGUI_GroupDlg::onApply() if (myName->text().trimmed().isEmpty()) return false; - if (myGrpTypeId == 0) { // on mesh elements - if (!myElements->count()) + SMESH::ElementType aType = SMESH::ALL; + switch (myTypeId) { + case grpNodeSelection: aType = SMESH::NODE; break; + case grpBallSelection: aType = SMESH::BALL; break; + case grpEdgeSelection: aType = SMESH::EDGE; break; + case grpFaceSelection: aType = SMESH::FACE; break; + case grpVolumeSelection: aType = SMESH::VOLUME; break; + } + + bool anIsOk = false; + QStringList anEntryList; + + SMESH::SMESH_GroupBase_var resultGroup; + bool isCreation; + + if (myGrpTypeId == 0) // standalone + { + if (!mySelectAll->isChecked() && !myElements->count() && myAllowElemsModif->isChecked()) return false; mySelectionMgr->clearSelected(); if (myGroup->_is_nil()) { // creation or conversion // check if group on geometry is not null - if (!CORBA::is_nil(myGroupOnGeom)) { + if (!myGroupOnGeom->_is_nil() || !myGroupOnFilter->_is_nil()) { if (myMesh->_is_nil()) return false; - myGroup = myMesh->ConvertToStandalone( myGroupOnGeom ); - // nullify pointer, because object become dead + if ( myGroupOnGeom->_is_nil() ) + myGroup = myMesh->ConvertToStandalone( myGroupOnFilter ); + else + myGroup = myMesh->ConvertToStandalone( myGroupOnGeom ); + myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); + myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil(); } } @@ -759,107 +922,98 @@ bool SMESHGUI_GroupDlg::onApply() if (myMesh->_is_nil()) return false; - SMESH::ElementType aType = SMESH::ALL; - 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); - for (i = 0; i < k; i++) { - anIdList[i] = myElements->item(i)->text().toInt(); - } - myGroup = SMESH::AddGroup(myMesh, aType, myName->text()); - myGroup->Add(anIdList.inout()); - SALOMEDS::Color aColor = getGroupColor(); - myGroup->SetColor(aColor); + resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup ); + isCreation = true; - _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup); + if ( mySelectAll->isChecked() ) { + // select all + myGroup->AddFrom(myMesh.in()); + } + else { + // select manually - //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) ); - SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" ); + if ( !myFilter->_is_nil() && + ( myNbChangesOfContents == 1 || !myAllowElemsModif->isChecked())) + { + myGroup->AddFrom( myFilter ); + } + else + { + SMESH::long_array_var anIdList = new SMESH::long_array; + int i, k = myElements->count(); + anIdList->length(k); + for (i = 0; i < k; i++) { + anIdList[i] = myElements->item(i)->text().toInt(); + } + myGroup->Add(anIdList.inout()); + } + } - /* init for next operation */ - myName->setText( "" ); - myElements->clear(); - myGroup = SMESH::SMESH_Group::_nil(); } else { // edition - myGroup->SetName(myName->text().toLatin1().data()); - - SALOMEDS::Color aColor = getGroupColor(); - myGroup->SetColor(aColor); - - _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup); - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) - anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B ); - QList aAddList; + resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup ); + isCreation = false; - int i, total = myElements->count(); - for (i = 0; i < total; i++) { - int anId = myElements->item(i)->text().toInt(); - int idx = myIdList.indexOf(anId); - if ( idx == -1 ) - aAddList.append(anId); - else - myIdList.removeAt(idx); + if ( mySelectAll->isChecked() ) { + // select all + myGroup->Clear(); + myGroup->AddFrom(myMesh.in()); } - if (!aAddList.empty()) { - SMESH::long_array_var anIdList = new SMESH::long_array; - int added = aAddList.count(); - anIdList->length(added); - for (i = 0; i < added; i++) - anIdList[i] = aAddList[i]; - myGroup->Add(anIdList.inout()); - } - if (!myIdList.empty()) { - SMESH::long_array_var anIdList = new SMESH::long_array; - int removed = myIdList.count(); - anIdList->length(removed); - for (i = 0; i < removed; i++) - anIdList[i] = myIdList[i]; - myGroup->Remove(anIdList.inout()); - } - /* init for next operation */ - myIdList.clear(); - for (i = 0; i < total; i++) { - myIdList.append(myElements->item(i)->text().toInt()); + else { + QList aAddList; + + int i, total = myElements->count(); + for (i = 0; i < total; i++) { + int anId = myElements->item(i)->text().toInt(); + int idx = myIdList.indexOf(anId); + if ( idx == -1 ) + aAddList.append(anId); + else + myIdList.removeAt(idx); + } + if (!aAddList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + int added = aAddList.count(); + anIdList->length(added); + for (i = 0; i < added; i++) + anIdList[i] = aAddList[i]; + myGroup->Add(anIdList.inout()); + } + if (!myIdList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + int removed = myIdList.count(); + anIdList->length(removed); + for (i = 0; i < removed; i++) + anIdList[i] = myIdList[i]; + myGroup->Remove(anIdList.inout()); + } + /* init for next operation */ + myIdList.clear(); + for (i = 0; i < total; i++) { + myIdList.append(myElements->item(i)->text().toInt()); + } } } - mySMESHGUI->updateObjBrowser(true); - SMESH::UpdateView(); // asv: fix of BUG PAL5515 - mySelectionMgr->clearSelected(); - return true; + anIsOk = true; } - else if (myGrpTypeId == 1) { // on geom object + 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 1: aType = SMESH::EDGE; 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()); + SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId()); if (myGeomObjects->length() == 1) { - myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, - myName->text().toLatin1().data(), - myGeomObjects[0]); + myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, + myName->text().toLatin1().data(), + myGeomObjects[0]); } else { SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen(); @@ -901,43 +1055,101 @@ bool SMESHGUI_GroupDlg::onApply() aNewGeomGroupName += myName->text(); SALOMEDS::SObject_var aNewGroupSO = geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar, - aNewGeomGroupName.toLatin1().data(), aMeshShape); + aNewGeomGroupName.toLatin1().data(), aMeshShape); } myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, - myName->text().toLatin1().data(), - aGroupVar); + myName->text().toLatin1().data(), + aGroupVar); } + resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom ); + isCreation = true; + + } + else { // edition + + resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom ); + isCreation = false; + } + anIsOk = true; + } + if (myGrpTypeId == 2) // group on filter + { + if ( myFilter->_is_nil() ) return false; - SALOMEDS::Color aColor = getGroupColor(); - myGroupOnGeom->SetColor(aColor); + if (CORBA::is_nil(myGroupOnFilter)) { // creation + if (myMesh->_is_nil()) + return false; - _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom); + myGroupOnFilter = myMesh->CreateGroupFromFilter(aType, + myName->text().toLatin1().data(), + myFilter); - //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) ); - SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" ); + resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter ); + isCreation = true; + } + else + { + myGroupOnFilter->SetFilter( myFilter ); - /* init for next operation */ - myName->setText( "" ); - myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); + resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter ); + isCreation = false; } - else { // edition - myGroupOnGeom->SetName(myName->text().toLatin1().data()); + anIsOk = true; + } + + if( anIsOk ) + { + SALOMEDS::Color aColor = getGroupColor(); + resultGroup->SetColor(aColor); - SALOMEDS::Color aColor = getGroupColor(); - myGroupOnGeom->SetColor(aColor); + _PTR(SObject) aMeshGroupSO = SMESH::FindSObject( resultGroup ); + if( aMeshGroupSO ) + anEntryList.append( aMeshGroupSO->GetID().c_str() ); - _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom); - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) - anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B ); - } + if ( isCreation ) + { + SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" ); + /* init for the next operation */ + myName->setText( "" ); + myElements->clear(); + myGroup = SMESH::SMESH_Group::_nil(); + myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); + myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil(); + myFilter = SMESH::Filter::_nil(); + } + else + { + resultGroup->SetName(myName->text().toLatin1().data()); + + if ( aMeshGroupSO ) + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) { + anActor->setName(myName->text().toLatin1().data()); + switch ( myTypeId ) { + case grpNodeSelection: anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break; + case grpBallSelection: anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break; + case grpEdgeSelection: anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break; + case grpFaceSelection: + case grpVolumeSelection: + default: + QColor c; + int delta; + SMESH::GetColor("SMESH", "fill_color", c , delta, "0,170,255|-100"); + anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); break; + } + } + } + SMESHGUI::Modified(); mySMESHGUI->updateObjBrowser(true); + SMESH::UpdateView(); // asv: fix of BUG PAL5515 mySelectionMgr->clearSelected(); - return true; - } - return false; + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() ); + } + return anIsOk; } //================================================================================= @@ -946,8 +1158,10 @@ bool SMESHGUI_GroupDlg::onApply() //================================================================================= void SMESHGUI_GroupDlg::onOK() { + setIsApplyAndClose( true ); if ( onApply() ) onClose(); + setIsApplyAndClose( false ); } //================================================================================= @@ -956,9 +1170,9 @@ void SMESHGUI_GroupDlg::onOK() //================================================================================= void SMESHGUI_GroupDlg::onListSelectionChanged() { - // MESSAGE( "SMESHGUI_GroupDlg::onListSelectionChanged(); myActor = " << myActor); - if( myIsBusy || !myActor) return; - myIsBusy = true; + //MESSAGE( "SMESHGUI_GroupDlg::onListSelectionChanged(); myActorsList.count() = " << myActorsList.count()); + if( myIsBusy || myActorsList.count() == 0 ) return; + myIsBusy = true; if (myCurrentLineEdit == 0) { mySelectionMgr->clearSelected(); @@ -966,9 +1180,9 @@ void SMESHGUI_GroupDlg::onListSelectionChanged() QList selItems = myElements->selectedItems(); QListWidgetItem* anItem; foreach(anItem, selItems) aIndexes.Add(anItem->text().toInt()); - mySelector->AddOrRemoveIndex(myActor->getIO(), aIndexes, false); + mySelector->AddOrRemoveIndex(myActorsList.first()->getIO(), aIndexes, false); SALOME_ListIO aList; - aList.Append(myActor->getIO()); + aList.Append(myActorsList.first()->getIO()); mySelectionMgr->setSelectedObjects(aList,false); } myIsBusy = false; @@ -1010,7 +1224,7 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() myGeomObjects->length(0); if (myGeomGroupBtn->isChecked()) - myGeomGroupBtn->setChecked(false); + myGeomGroupBtn->setChecked(false); if (!myCreate) myName->setText( "" ); @@ -1029,16 +1243,20 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() Handle(SALOME_InteractiveObject) IO = aList.First(); if (myCreate) { - restoreShowEntityMode(); - myMesh = SMESH::IObjectToInterface(IO); + restoreShowEntityMode(); + myMesh = SMESH::IObjectToInterface(IO); setShowEntityMode(); updateGeomPopup(); if (myMesh->_is_nil()) - { + { updateButtons(); - myIsBusy = false; - return; - } + myIsBusy = false; + return; + } + + if ( myFilterDlg && !myMesh->_is_nil()){ + myFilterDlg->SetMesh( myMesh ); + } myGroup = SMESH::SMESH_Group::_nil(); // NPAL19389: create a group with a selection in another group @@ -1059,15 +1277,14 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() else { SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface(IO); if (aGroup->_is_nil()) - { - myIsBusy = false; + { + myIsBusy = false; return; - } + } myIsBusy = false; - myCurrentLineEdit = 0; - myGroup = SMESH::SMESH_Group::_nil(); - myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); + myGroup = SMESH::SMESH_Group::_nil(); + myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); init(aGroup); myIsBusy = true; @@ -1081,13 +1298,13 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() if (myGrpTypeId == 0) { - if (myTypeId == -1) - onTypeChanged(0); - else - { - myElements->clear(); - setSelectionMode(myTypeId); - } + if (myTypeId == -1) + onTypeChanged(0); + else + { + myElements->clear(); + setSelectionMode(myTypeId); + } } myIsBusy = false; @@ -1103,26 +1320,24 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() if (aNbSel == 0 || !aMeshSO) { - myGeomObjects->length(0); - updateButtons(); - myIsBusy = false; - return; + myGeomObjects->length(0); + updateButtons(); + myIsBusy = false; + return; } myGeomObjects->length(aNbSel); GEOM::GEOM_Object_var aGeomGroup; - Standard_Boolean testResult; int i = 0; SALOME_ListIteratorOfListIO anIt (aList); for (; anIt.More(); anIt.Next()) { - testResult = Standard_False; - aGeomGroup = GEOMBase::ConvertIOinGEOMObject(anIt.Value(), testResult); + aGeomGroup = GEOMBase::ConvertIOinGEOMObject(anIt.Value()); // Check if the object is a geometry group - if (!testResult || CORBA::is_nil(aGeomGroup)) + if (CORBA::is_nil(aGeomGroup)) continue; // Check if group constructed on the same shape as a mesh or on its child @@ -1137,21 +1352,17 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() else aGroupMainShape = GEOM::GEOM_Object::_duplicate(aGeomGroup); _PTR(SObject) aGroupMainShapeSO = - //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(aGroupMainShape)); aStudy->FindObjectID(aGroupMainShape->GetStudyEntry()); _PTR(SObject) anObj, aRef; bool isRefOrSubShape = false; if (aMeshSO->FindSubObject(1, anObj) && anObj->ReferencedObject(aRef)) { - //if (strcmp(aRef->GetID(), aGroupMainShapeSO->GetID()) == 0) { if (aRef->GetID() == aGroupMainShapeSO->GetID()) { isRefOrSubShape = true; } else { _PTR(SObject) aFather = aGroupMainShapeSO->GetFather(); _PTR(SComponent) aComponent = aGroupMainShapeSO->GetFatherComponent(); - //while (!isRefOrSubShape && strcmp(aFather->GetID(), aComponent->GetID()) != 0) { while (!isRefOrSubShape && aFather->GetID() != aComponent->GetID()) { - //if (strcmp(aRef->GetID(), aFather->GetID()) == 0) if (aRef->GetID() == aFather->GetID()) isRefOrSubShape = true; else @@ -1165,10 +1376,10 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() myGeomObjects->length(i); if ( i == 0 ) - { - myIsBusy = false; - return; - } + { + myIsBusy = false; + return; + } aNbSel = i; } @@ -1202,13 +1413,12 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() } else // !myCurrentLineEdit: local selection of nodes or elements { - if (aNbSel == 1 && myActor && myActor->hasIO()) + if (aNbSel == 1 && myActorsList.count() > 0 ) { -#ifdef ENABLE_SWITCH_ACTOR_DURING_ELEMENTS_SELECTION // NPAL19389: create a group with a selection in another group // Switch myActor to the newly selected one, if the last // is visible and belongs to group or submesh of myMesh - Handle(SALOME_InteractiveObject) curIO = myActor->getIO(); + /* Handle(SALOME_InteractiveObject) curIO = myActor->getIO(); Handle(SALOME_InteractiveObject) selIO = aList.First(); if (curIO->hasEntry() && selIO->hasEntry()) { const char* selEntry = selIO->getEntry(); @@ -1235,54 +1445,101 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() } } } - } + }*/ // NPAL19389 END -#endif // ENABLE_SWITCH_ACTOR_DURING_ELEMENTS_SELECTION QString aListStr = ""; int aNbItems = 0; if (myTypeId == 0) { - aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); + QListIterator it( myActorsList ); + while ( it.hasNext() ) { + QString tmpStr; + aNbItems += SMESH::GetNameOfSelectedNodes(mySelector, it.next()->getIO(), tmpStr); + aListStr += tmpStr; + } } else { - aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr); + QListIterator it( myActorsList ); + while ( it.hasNext() ) { + QString tmpStr; + aNbItems += SMESH::GetNameOfSelectedElements(mySelector, it.next()->getIO(), tmpStr); + aListStr += tmpStr; + } } if (aNbItems > 0) { - QListWidgetItem* anItem; - QList listItemsToSel; - QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts); - for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { - QList found = myElements->findItems(*it, Qt::MatchExactly); - foreach(anItem, found) - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } - bool blocked = myElements->signalsBlocked(); - myElements->blockSignals(true); - foreach(anItem, listItemsToSel) anItem->setSelected(true); - myElements->blockSignals(blocked); - onListSelectionChanged(); - listItemsToSel.clear(); + QListWidgetItem* anItem; + QList listItemsToSel; + QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts); + for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { + QList found = myElements->findItems(*it, Qt::MatchExactly); + foreach(anItem, found) + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } + bool blocked = myElements->signalsBlocked(); + myElements->blockSignals(true); + foreach(anItem, listItemsToSel) anItem->setSelected(true); + myElements->blockSignals(blocked); + onListSelectionChanged(); + listItemsToSel.clear(); } } } - - if (!myActor) { - if (!myGroup->_is_nil()) - myActor = SMESH::FindActorByObject(myGroup); - else if(!myGroupOnGeom->_is_nil()) - myActor = SMESH::FindActorByObject(myGroupOnGeom); - else - myActor = SMESH::FindActorByObject(myMesh); + + if (myActorsList.count() == 0) { + if (!myGroup->_is_nil()) { + SMESH_Actor* anActor = SMESH::FindActorByObject(myGroup); + if ( anActor ) + myActorsList.append( anActor ); + } + else if(!myGroupOnGeom->_is_nil()) { + SMESH_Actor* anActor = SMESH::FindActorByObject(myGroupOnGeom); + if ( anActor ) + myActorsList.append( anActor ); + } + else { + SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh ); + if ( anActor ) + myActorsList.append( anActor ); + } } // somehow, if we display the mesh, while selecting from another actor, // the mesh becomes pickable, and there is no way to select any element - if (myActor) - SMESH::SetPickable(myActor); + if (myActorsList.count() > 0) { + QListIterator it( myActorsList ); + while ( it.hasNext() ) { + SMESH_Actor* anActor = it.next(); + if ( IsActorVisible(anActor) ) + anActor->SetPickable(true); + } + } myIsBusy = false; } +//================================================================================= +// function : onSelectAll() +// purpose : Called when "Select all" is checked +//================================================================================= +void SMESHGUI_GroupDlg::onSelectAll() +{ + bool noElemsModif = ( mySelectAll->isChecked() || !myAllowElemsModif->isChecked() ); + + myElementsLab->setEnabled( !noElemsModif ); + myElements->setEnabled ( !noElemsModif ); + myFilterBtn->setEnabled ( !mySelectAll->isChecked() ); + myAddBtn->setEnabled ( !noElemsModif ); + myRemoveBtn->setEnabled ( !noElemsModif ); + mySortBtn->setEnabled ( !noElemsModif ); + mySelectBox->setEnabled ( !noElemsModif ); + myAllowElemsModif->setEnabled( !mySelectAll->isChecked() ); + + int selMode = mySelectionMode; + mySelectionMode = grpNoSelection; + setSelectionMode( selMode ); + updateButtons(); +} + //================================================================================= // function : onSelectSubMesh() // purpose : Called when selection in 3D view or ObjectBrowser is changed @@ -1297,7 +1554,7 @@ void SMESHGUI_GroupDlg::onSelectSubMesh(bool on) //VSR: mySelectGeomGroup->setChecked(false); //VSR: } myCurrentLineEdit = mySubMeshLine; - setSelectionMode(4); + setSelectionMode(grpSubMeshSelection); } else { mySubMeshLine->setText( "" ); @@ -1321,7 +1578,7 @@ void SMESHGUI_GroupDlg::onSelectGroup(bool on) mySelectSubMesh->setChecked(false); } myCurrentLineEdit = myGroupLine; - setSelectionMode(5); + setSelectionMode(grpGroupSelection); } else { myGroupLine->setText( "" ); @@ -1336,7 +1593,7 @@ void SMESHGUI_GroupDlg::onSelectGroup(bool on) //================================================================================= // function : (onSelectGeomGroup) -// purpose : Called when selection in 3D view or ObjectBrowser is changed +// purpose : Called when group type changed. on == "on group" or "on filter" //================================================================================= void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on) { @@ -1347,9 +1604,14 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on) else if (mySelectGroup->isChecked()) { mySelectGroup->setChecked(false); } - myCurrentLineEdit = myGeomGroupLine; - updateGeomPopup(); - setSelectionMode(8); + if ( myGrpTypeId == 1 ) { // on group + myCurrentLineEdit = myGeomGroupLine; + updateGeomPopup(); + } + else { // on filter + myCurrentLineEdit = 0; + } + setSelectionMode(grpAllSelection); } else { myGeomGroupBtn->setChecked(false); @@ -1357,11 +1619,10 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on) myGeomGroupLine->setText( "" ); myCurrentLineEdit = 0; if (myTypeId != -1) - setSelectionMode(myTypeId); + setSelectionMode( myTypeId ); } } - //================================================================================= // function : setCurrentSelection() // purpose : @@ -1371,11 +1632,14 @@ void SMESHGUI_GroupDlg::setCurrentSelection() QPushButton* send = (QPushButton*)sender(); myCurrentLineEdit = 0; if (send == myMeshGroupBtn) { - myCurrentLineEdit = myMeshGroupLine; + disconnect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + mySelectionMgr->clearSelected(); if (myCreate) - setSelectionMode(6); + setSelectionMode(grpMeshSelection); else - setSelectionMode(5); + setSelectionMode(grpGroupSelection); + connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + myCurrentLineEdit = myMeshGroupLine; onObjectSelectionChanged(); } else if (send == mySubMeshBtn) { @@ -1395,14 +1659,22 @@ void SMESHGUI_GroupDlg::setCurrentSelection() //================================================================================= void SMESHGUI_GroupDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } + SMESH::ElementType aType = SMESH::ALL; 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; - default: return; + case grpNodeSelection: aType = SMESH::NODE; break; + case grpBallSelection: aType = SMESH::BALL; break; + case grpEdgeSelection: aType = SMESH::EDGE; break; + case grpFaceSelection: aType = SMESH::FACE; break; + case grpVolumeSelection: aType = SMESH::VOLUME; break; + default: return; } if ( myFilterDlg == 0 ) @@ -1413,9 +1685,15 @@ void SMESHGUI_GroupDlg::setFilters() else myFilterDlg->Init( aType ); + if ( !myGroupOnFilter->_is_nil() ) + { + myFilterDlg->SetFilter( myFilter, aType ); + myFilterDlg->Init( aType ); + } + myFilterDlg->SetSelection(); myFilterDlg->SetMesh( myMesh ); - myFilterDlg->SetSourceWg( myElements ); + myFilterDlg->SetSourceWg( myElements, false ); myFilterDlg->show(); } @@ -1433,6 +1711,28 @@ void SMESHGUI_GroupDlg::onFilterAccepted() mySelectSubMesh->setChecked( false ); mySelectGroup->setChecked( false ); } + // get a filter from myFilterDlg + myFilter = myFilterDlg->GetFilter(); + if ( !myFilter->_is_nil() ) { + SMESH::Predicate_var perdicate = myFilter->GetPredicate(); + if ( perdicate->_is_nil() ) + myFilter = SMESH::Filter::_nil(); + } + // set mesh to myFilter + if ( !myFilter->_is_nil() ) { + SMESH::SMESH_Mesh_var mesh = myMesh; + if ( mesh->_is_nil() ) { + if ( !myGroup->_is_nil() ) + mesh = myGroup->GetMesh(); + else if ( !myGroupOnGeom->_is_nil() ) + mesh = myGroupOnGeom->GetMesh(); + else if ( !myGroupOnFilter->_is_nil() ) + mesh = myGroupOnFilter->GetMesh(); + } + myFilter->SetMesh( mesh ); + } + + updateButtons(); } //================================================================================= @@ -1446,25 +1746,30 @@ void SMESHGUI_GroupDlg::onAdd() int aNbSel = aList.Extent(); - if (aNbSel == 0 || !myActor || myMesh->_is_nil()) return; + if (aNbSel == 0 || myActorsList.count() == 0 || myMesh->_is_nil()) return; myIsBusy = true; + int sizeBefore = myElements->count(); SMESH::ElementType aType = SMESH::ALL; switch(myTypeId) { - case 0: + case grpNodeSelection: aType = SMESH::NODE; mySelector->SetSelectionMode(NodeSelection); break; - case 1: + case grpBallSelection: + aType = SMESH::BALL; + //mySelector->SetSelectionMode(BallSelection); + break; + case grpEdgeSelection: aType = SMESH::EDGE; mySelector->SetSelectionMode(EdgeSelection); break; - case 2: + case grpFaceSelection: aType = SMESH::FACE; mySelector->SetSelectionMode(FaceSelection); break; - case 3: + case grpVolumeSelection: aType = SMESH::VOLUME; mySelector->SetSelectionMode(VolumeSelection); break; @@ -1480,26 +1785,36 @@ void SMESHGUI_GroupDlg::onAdd() QString aListStr = ""; int aNbItems = 0; if (myTypeId == 0) { - aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); + QListIterator it( myActorsList ); + while ( it.hasNext() ) { + QString tmpStr; + aNbItems += SMESH::GetNameOfSelectedNodes(mySelector, it.next()->getIO(), tmpStr); + aListStr += tmpStr; + } } else { - aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr); + QListIterator it( myActorsList ); + while ( it.hasNext() ) { + QString tmpStr; + aNbItems += SMESH::GetNameOfSelectedElements(mySelector, it.next()->getIO(), tmpStr); + aListStr += tmpStr; + } } if (aNbItems > 0) { QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts); for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { - QList found = myElements->findItems(*it, Qt::MatchExactly); - if (found.count() == 0) { - anItem = new QListWidgetItem(*it); - myElements->addItem(anItem); - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } - else { - foreach(anItem, found) - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } + QList found = myElements->findItems(*it, Qt::MatchExactly); + if (found.count() == 0) { + anItem = new QListWidgetItem(*it); + myElements->addItem(anItem); + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } + else { + foreach(anItem, found) + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } } bool blocked = myElements->signalsBlocked(); myElements->blockSignals(true); @@ -1519,8 +1834,8 @@ void SMESHGUI_GroupDlg::onAdd() SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(anIt.Value()); if (!aSubMesh->_is_nil()) { - // check if mesh is the same - if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { + // check if mesh is the same + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { try { SMESH::long_array_var anElements = aSubMesh->GetElementsByType(aType); int k = anElements->length(); @@ -1530,21 +1845,21 @@ void SMESHGUI_GroupDlg::onAdd() if (found.count() == 0) { anItem = new QListWidgetItem(aText); myElements->addItem(anItem); - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } + else { + foreach(anItem, found) + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); } - else { - foreach(anItem, found) - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } } - bool blocked = myElements->signalsBlocked(); - myElements->blockSignals(true); - foreach(anItem, listItemsToSel) anItem->setSelected(true); - myElements->blockSignals(blocked); - onListSelectionChanged(); - listItemsToSel.clear(); + bool blocked = myElements->signalsBlocked(); + myElements->blockSignals(true); + foreach(anItem, listItemsToSel) anItem->setSelected(true); + myElements->blockSignals(blocked); + onListSelectionChanged(); + listItemsToSel.clear(); } catch (const SALOME::SALOME_Exception& ex) { SalomeApp_Tools::QtCatchCorbaException(ex); @@ -1566,32 +1881,32 @@ void SMESHGUI_GroupDlg::onAdd() SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface(anIt.Value()); if (!aGroup->_is_nil()) { - // check if mesh is the same - if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { - SMESH::long_array_var anElements = aGroup->GetListOfID(); - int k = anElements->length(); - for (int i = 0; i < k; i++) { - QString aText = QString::number(anElements[i]); - QList found = myElements->findItems(aText, Qt::MatchExactly); - if (found.count() == 0) { - anItem = new QListWidgetItem(aText); - myElements->addItem(anItem); - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } - else { - foreach(anItem, found) - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } - } - bool blocked = myElements->signalsBlocked(); - myElements->blockSignals(true); - foreach(anItem, listItemsToSel) anItem->setSelected(true); - myElements->blockSignals(blocked); - onListSelectionChanged(); - listItemsToSel.clear(); - } + // check if mesh is the same + if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anElements = aGroup->GetListOfID(); + int k = anElements->length(); + for (int i = 0; i < k; i++) { + QString aText = QString::number(anElements[i]); + QList found = myElements->findItems(aText, Qt::MatchExactly); + if (found.count() == 0) { + anItem = new QListWidgetItem(aText); + myElements->addItem(anItem); + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } + else { + foreach(anItem, found) + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } + } + bool blocked = myElements->signalsBlocked(); + myElements->blockSignals(true); + foreach(anItem, listItemsToSel) anItem->setSelected(true); + myElements->blockSignals(blocked); + onListSelectionChanged(); + listItemsToSel.clear(); + } } } mySelectGroup->setChecked(false); @@ -1605,10 +1920,10 @@ void SMESHGUI_GroupDlg::onAdd() SMESH::ElementType aGroupType = SMESH::ALL; switch(aGroupOp->GetType(myGeomObjects[0])) { - case 7: aGroupType = SMESH::NODE; break; - case 6: aGroupType = SMESH::EDGE; break; - case 4: aGroupType = SMESH::FACE; break; - case 2: aGroupType = SMESH::VOLUME; break; + case TopAbs_VERTEX: aGroupType = SMESH::NODE; break; + case TopAbs_EDGE: aGroupType = SMESH::EDGE; break; + case TopAbs_FACE: aGroupType = SMESH::FACE; break; + case TopAbs_SOLID: aGroupType = SMESH::VOLUME; break; default: myIsBusy = false; return; } @@ -1619,7 +1934,7 @@ void SMESHGUI_GroupDlg::onAdd() // Construct filter SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); SMESH::Filter_var aFilter = aFilterMgr->CreateFilter(); - SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();; + SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom(); aBelongToGeom->SetGeom(myGeomObjects[0]); aBelongToGeom->SetShapeName(aGroupSO->GetName().c_str()); aBelongToGeom->SetElementType(aType); @@ -1629,19 +1944,19 @@ void SMESHGUI_GroupDlg::onAdd() int k = anElements->length(); for (int i = 0; i < k; i++) { - QString aText = QString::number(anElements[i]); - QList found = myElements->findItems(aText, Qt::MatchExactly); - if (found.count() == 0) { - anItem = new QListWidgetItem(aText); - myElements->addItem(anItem); - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } - else { - foreach(anItem, found) - if (!anItem->isSelected()) - listItemsToSel.push_back(anItem); - } + QString aText = QString::number(anElements[i]); + QList found = myElements->findItems(aText, Qt::MatchExactly); + if (found.count() == 0) { + anItem = new QListWidgetItem(aText); + myElements->addItem(anItem); + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } + else { + foreach(anItem, found) + if (!anItem->isSelected()) + listItemsToSel.push_back(anItem); + } } bool blocked = myElements->signalsBlocked(); myElements->blockSignals(true); @@ -1656,6 +1971,8 @@ void SMESHGUI_GroupDlg::onAdd() onListSelectionChanged(); } myIsBusy = false; + if ( sizeBefore < myElements->count() ) + ++myNbChangesOfContents; // mySelectionMgr->clearSelected(); updateButtons(); } @@ -1667,6 +1984,8 @@ void SMESHGUI_GroupDlg::onAdd() void SMESHGUI_GroupDlg::onRemove() { myIsBusy = true; + int sizeBefore = myElements->count(); + if (myCurrentLineEdit == 0) { QList selItems = myElements->selectedItems(); QListWidgetItem* item; @@ -1681,10 +2000,11 @@ void SMESHGUI_GroupDlg::onRemove() SMESH::ElementType aType = SMESH::ALL; 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; + case grpNodeSelection: aType = SMESH::NODE; break; + case grpBallSelection: aType = SMESH::BALL; break; + case grpEdgeSelection: aType = SMESH::EDGE; break; + case grpFaceSelection: aType = SMESH::FACE; break; + case grpVolumeSelection: aType = SMESH::VOLUME; break; } if (myCurrentLineEdit == mySubMeshLine) { @@ -1694,42 +2014,42 @@ void SMESHGUI_GroupDlg::onRemove() SALOME_ListIteratorOfListIO anIt (aList); for ( ; anIt.More(); anIt.Next()) { - SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(anIt.Value()); - if (!aSubMesh->_is_nil()) { - // check if mesh is the same - if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { - if (aType == SMESH::NODE) { - try { - SMESH::long_array_var anElements = aSubMesh->GetNodesId(); - int k = anElements->length(); - for (int i = 0; i < k; i++) { - QList found = - myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly); - QListWidgetItem* anItem; - foreach(anItem, found) delete anItem; - } - } - catch (const SALOME::SALOME_Exception& ex) { - SalomeApp_Tools::QtCatchCorbaException(ex); - } - } - else { - try { - SMESH::long_array_var anElements = aSubMesh->GetElementsId(); - int k = anElements->length(); - for (int i = 0; i < k; i++) { - QList found = - myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly); - QListWidgetItem* anItem; - foreach(anItem, found) delete anItem; - } - } - catch (const SALOME::SALOME_Exception& ex) { - SalomeApp_Tools::QtCatchCorbaException(ex); - } - } - } - } + SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(anIt.Value()); + if (!aSubMesh->_is_nil()) { + // check if mesh is the same + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { + if (aType == SMESH::NODE) { + try { + SMESH::long_array_var anElements = aSubMesh->GetNodesId(); + int k = anElements->length(); + for (int i = 0; i < k; i++) { + QList found = + myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly); + QListWidgetItem* anItem; + foreach(anItem, found) delete anItem; + } + } + catch (const SALOME::SALOME_Exception& ex) { + SalomeApp_Tools::QtCatchCorbaException(ex); + } + } + else { + try { + SMESH::long_array_var anElements = aSubMesh->GetElementsId(); + int k = anElements->length(); + for (int i = 0; i < k; i++) { + QList found = + myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly); + QListWidgetItem* anItem; + foreach(anItem, found) delete anItem; + } + } + catch (const SALOME::SALOME_Exception& ex) { + SalomeApp_Tools::QtCatchCorbaException(ex); + } + } + } + } } } else if (myCurrentLineEdit == myGroupLine) { @@ -1740,24 +2060,26 @@ void SMESHGUI_GroupDlg::onRemove() SALOME_ListIteratorOfListIO anIt (aList); for ( ; anIt.More(); anIt.Next()) { - SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface(anIt.Value()); - if (aRes && !aGroup->_is_nil()) { - // check if mesh is the same - if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { - SMESH::long_array_var anElements = aGroup->GetListOfID(); - int k = anElements->length(); - for (int i = 0; i < k; i++) { - QList found = - myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly); - QListWidgetItem* anItem; - foreach(anItem, found) delete anItem; - } - } - } + SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface(anIt.Value()); + if (aRes && !aGroup->_is_nil()) { + // check if mesh is the same + if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { + SMESH::long_array_var anElements = aGroup->GetListOfID(); + int k = anElements->length(); + for (int i = 0; i < k; i++) { + QList found = + myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly); + QListWidgetItem* anItem; + foreach(anItem, found) delete anItem; + } + } + } } } } myIsBusy = false; + if ( sizeBefore > myElements->count() ) + myNbChangesOfContents += 2; // it's used to detect that "Add" was only once updateButtons(); } @@ -1781,7 +2103,7 @@ void SMESHGUI_GroupDlg::onSort() int id = myElements->item(i)->text().toInt(); anArray[i] = id; if (myElements->item(i)->isSelected()) - aSelected.append(id); + aSelected.append(id); } // sort & update list std::sort(anArray.begin(), anArray.end()); @@ -1793,7 +2115,7 @@ void SMESHGUI_GroupDlg::onSort() anItem = new QListWidgetItem(QString::number(anArray[i])); myElements->addItem(anItem); if (aSelected.contains(anArray[i])) - listItemsToSel.push_back(anItem); + listItemsToSel.push_back(anItem); } bool blocked = myElements->signalsBlocked(); myElements->blockSignals(true); @@ -1813,6 +2135,15 @@ void SMESHGUI_GroupDlg::closeEvent (QCloseEvent*) onClose(); } +//================================================================================= +// function : onVisibilityChanged() +// purpose : +//================================================================================= +void SMESHGUI_GroupDlg::onVisibilityChanged() +{ + SetAppropriateActor(); +} + //================================================================================= // function : SMESHGUI_GroupDlg::onClose // purpose : SLOT called when "Close" button pressed. Close dialog @@ -1826,7 +2157,13 @@ void SMESHGUI_GroupDlg::onClose() restoreShowEntityMode(); } - mySelectionMgr->clearSelected(); + if( isApplyAndClose() && !myObjectToSelect.isEmpty() ) { + SUIT_DataOwnerPtrList aList; + aList.append( new LightApp_DataOwner( myObjectToSelect ) ); + mySelectionMgr->setSelected( aList ); + } + else + mySelectionMgr->clearSelected(); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->clearFilters(); @@ -1852,10 +2189,10 @@ void SMESHGUI_GroupDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr( "WRN_WARNING" ), - tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ). - arg(app->resourceMgr()->stringValue( "ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ). + arg(app->resourceMgr()->stringValue( "ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -1878,7 +2215,7 @@ void SMESHGUI_GroupDlg::enterEvent (QEvent*) if (!isEnabled()) { mySMESHGUI->EmitSignalDeactivateDialog(); setEnabled(true); - mySelectionMode = -1; + mySelectionMode = grpNoSelection; setSelectionMode(myTypeId); //mySMESHGUI->SetActiveDialogBox((QDialog*)this); mySMESHGUI->SetActiveDialogBox(this); @@ -1956,12 +2293,12 @@ void SMESHGUI_GroupDlg::onGeomSelectionButton(bool isBtnOn) myCurrentLineEdit = myGeomGroupLine; QAction* a = myGeomPopup->exec( QCursor::pos() ); if (!a || myActions[a] == DIRECT_GEOM_INDEX) - setSelectionMode(7); + setSelectionMode(grpGeomSelection); } else if (!isBtnOn) { myCurrentLineEdit = 0; - setSelectionMode(8); + setSelectionMode(grpAllSelection); } } @@ -1974,19 +2311,19 @@ void SMESHGUI_GroupDlg::onGeomPopup( QAction* a ) int index = myActions[a]; if ( index == GEOM_BY_MESH_INDEX ) { - mySelectionMode = -1; + mySelectionMode = grpNoSelection; if ( !myShapeByMeshOp ) { - myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp(true); - connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)), - SLOT(onPublishShapeByMeshDlg(SUIT_Operation*))); - connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)), - SLOT(onCloseShapeByMeshDlg(SUIT_Operation*))); + myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp(true); + connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)), + SLOT(onPublishShapeByMeshDlg(SUIT_Operation*))); + connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)), + SLOT(onCloseShapeByMeshDlg(SUIT_Operation*))); } // set mesh object to SMESHGUI_ShapeByMeshOp and start it if ( !myMesh->_is_nil() ) { - myIsBusy = true; + myIsBusy = true; hide(); // stop processing selection - myIsBusy = false; + myIsBusy = false; myShapeByMeshOp->setModule( mySMESHGUI ); myShapeByMeshOp->setStudy( 0 ); // it's really necessary myShapeByMeshOp->SetMesh( myMesh ); @@ -2013,12 +2350,12 @@ void SMESHGUI_GroupDlg::onPublishShapeByMeshDlg(SUIT_Operation* op) QString ID = aGeomVar->GetStudyEntry(); _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); if ( _PTR(SObject) aGeomSO = aStudy->FindObjectID( ID.toLatin1().data() )) { - SALOME_ListIO anIOList; - Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject - ( aGeomSO->GetID().c_str(), "SMESH", aGeomSO->GetName().c_str() ); - anIOList.Append( anIO ); - mySelectionMgr->setSelectedObjects( anIOList, false ); - onObjectSelectionChanged(); + SALOME_ListIO anIOList; + Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject + ( aGeomSO->GetID().c_str(), "SMESH", aGeomSO->GetName().c_str() ); + anIOList.Append( anIO ); + mySelectionMgr->setSelectedObjects( anIOList, false ); + onObjectSelectionChanged(); } } } @@ -2035,7 +2372,7 @@ void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op) if ( myShapeByMeshOp == op ) { show(); - setSelectionMode(7); + setSelectionMode(grpGeomSelection); } } @@ -2046,8 +2383,8 @@ void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op) void SMESHGUI_GroupDlg::setGroupColor( const SALOMEDS::Color& theColor ) { QColor aQColor( (int)( theColor.R * 255.0 ), - (int)( theColor.G * 255.0 ), - (int)( theColor.B * 255.0 ) ); + (int)( theColor.G * 255.0 ), + (int)( theColor.B * 255.0 ) ); setGroupQColor( aQColor ); } @@ -2118,8 +2455,8 @@ void SMESHGUI_GroupDlg::setDefaultGroupColor() SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors ); aQColor.setRgb( (int)( aColor.R * 255.0 ), - (int)( aColor.G * 255.0 ), - (int)( aColor.B * 255.0 ) ); + (int)( aColor.G * 255.0 ), + (int)( aColor.B * 255.0 ) ); } @@ -2135,82 +2472,84 @@ void SMESHGUI_GroupDlg::setDefaultGroupColor() bool SMESHGUI_GroupDlg::SetAppropriateActor() { bool isActor = false; + myActorsList.clear(); if (myMesh->_is_nil()) return false; SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView(); - // try mesh actor - myActor = SMESH::FindActorByObject(myMesh); - if (myActor && myActor->hasIO()) - { - isActor = true; - if (aViewWindow && !aViewWindow->isVisible(myActor->getIO())) - isActor = false; - } - - // try current group actor - if (!isActor) { - if (!myGroup->_is_nil()) { - myActor = SMESH::FindActorByObject(myGroup); - if (myActor && myActor->hasIO()) - { - isActor = true; - if (aViewWindow && !aViewWindow->isVisible(myActor->getIO())) - isActor = false; + if (myGeomGroupBtn->isChecked()) { // try current group on geometry actor + if (!isActor) { + if (!myGroupOnGeom->_is_nil()) { + SMESH_Actor* anActor = SMESH::FindActorByObject(myGroupOnGeom); + if (anActor && anActor->hasIO()) + { + isActor = true; + if (aViewWindow && !aViewWindow->isVisible(anActor->getIO())) + isActor = false; + else + myActorsList.append(anActor); + } } } - } - - // try current group on geometry actor - if (!isActor) { - if (!myGroupOnGeom->_is_nil()) { - myActor = SMESH::FindActorByObject(myGroupOnGeom); - if (myActor && myActor->hasIO()) - { - isActor = true; - if (aViewWindow && !aViewWindow->isVisible(myActor->getIO())) - isActor = false; - } + } else { + // try mesh actor + SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh); + if (anActor && anActor->hasIO()) { + isActor = true; + if (aViewWindow && !aViewWindow->isVisible(anActor->getIO())) + isActor = false; + else + myActorsList.append(anActor); } - } - - // try any visible actor of group or submesh of current mesh - if (!isActor && aViewWindow) { - // mesh entry - _PTR(SObject) aSObject = SMESH::FindSObject(myMesh); - if (aSObject) { - CORBA::String_var meshEntry = aSObject->GetID().c_str(); - int len = strlen(meshEntry); - - // iterate on all actors in current view window, search for - // any visible actor, that belongs to group or submesh of current mesh - vtkActorCollection *aCollection = aViewWindow->getRenderer()->GetActors(); - aCollection->InitTraversal(); - for (vtkActor *anAct = aCollection->GetNextActor(); - anAct && !isActor; - anAct = aCollection->GetNextActor()) - { - SMESH_Actor *anActor = dynamic_cast(anAct); - if (anActor && anActor->hasIO()) { - Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); - if (aViewWindow->isVisible(anIO)) { - if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0) { - myActor = anActor; - isActor = true; + + // try group actor + if (!isActor && !myGroup->_is_nil()) { + SMESH_Actor* anActor = SMESH::FindActorByObject(myGroup); + if (anActor && anActor->hasIO()) + myActorsList.append(anActor); + } + + // try any visible actor of group or submesh of current mesh + if (aViewWindow) { + // mesh entry + _PTR(SObject) aSObject = SMESH::FindSObject(myMesh); + if (aSObject) { + CORBA::String_var meshEntry = aSObject->GetID().c_str(); + int len = strlen(meshEntry); + + // iterate on all actors in current view window, search for + // any visible actor, that belongs to group or submesh of current mesh + VTK::ActorCollectionCopy aCopy(aViewWindow->getRenderer()->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); + int nbItems = aCollection->GetNumberOfItems(); + for (int i=0; i(aCollection->GetItemAsObject(i)); + if (anActor && anActor->hasIO()) { + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if (aViewWindow->isVisible(anIO)) { + if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0 && !myActorsList.contains(anActor) ) + myActorsList.append(anActor); + } } } - } } } } - - if (isActor) - SMESH::SetPickable(myActor); - - return isActor; + + if (myActorsList.count() > 0) { + QListIterator it( myActorsList ); + while ( it.hasNext() ) { + SMESH_Actor* anActor = it.next(); + if ( IsActorVisible(anActor) ) + anActor->SetPickable(true); + } + } + + return ( isActor || (myActorsList.count() > 0) ); } - + //======================================================================= //function : setShowEntityMode //purpose : make shown only entity corresponding to my type @@ -2222,10 +2561,11 @@ void SMESHGUI_GroupDlg::setShowEntityMode() if (!myStoredShownEntity) myStoredShownEntity = actor->GetEntityMode(); switch ( myTypeId ) { - case 0: restoreShowEntityMode(); break; - case 1: actor->SetEntityMode( SMESH_Actor::eEdges ); break; - case 2: actor->SetEntityMode( SMESH_Actor::eFaces ); break; - case 3: actor->SetEntityMode( SMESH_Actor::eVolumes ); break; + case grpNodeSelection: restoreShowEntityMode(); break; + case grpBallSelection: actor->SetEntityMode( SMESH_Actor::eBallElem ); break; + case grpEdgeSelection: actor->SetEntityMode( SMESH_Actor::eEdges ); break; + case grpFaceSelection: actor->SetEntityMode( SMESH_Actor::eFaces ); break; + case grpVolumeSelection: actor->SetEntityMode( SMESH_Actor::eVolumes ); break; } } } @@ -2244,3 +2584,35 @@ void SMESHGUI_GroupDlg::restoreShowEntityMode() } myStoredShownEntity = 0; } + +//======================================================================= +//function : IsActorVisible +//purpose : return visibility of the actor +//======================================================================= +bool SMESHGUI_GroupDlg::IsActorVisible( SMESH_Actor* theActor ) +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView(); + if (theActor && aViewWindow) + return aViewWindow->isVisible(theActor->getIO()); + return false; +} + +//================================================================ +//function : setIsApplyAndClose +//purpose : Set value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +void SMESHGUI_GroupDlg::setIsApplyAndClose( const bool theFlag ) +{ + myIsApplyAndClose = theFlag; +} + +//================================================================ +//function : isApplyAndClose +//purpose : Get value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +bool SMESHGUI_GroupDlg::isApplyAndClose() const +{ + return myIsApplyAndClose; +} diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.h b/src/SMESHGUI/SMESHGUI_GroupDlg.h index 39a417887..2592f4dc4 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.h +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GroupDlg.h // Author : Natalia KOPNOVA, Open CASCADE S.A.S. @@ -38,7 +39,10 @@ #include #include CORBA_SERVER_HEADER(SMESH_Mesh) #include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Filter) +class QGroupBox; +class QLabel; class QLineEdit; class QButtonGroup; class QListWidget; @@ -57,6 +61,7 @@ class SUIT_Operation; class SVTK_Selector; class SUIT_SelectionFilter; class LightApp_SelectionMgr; +class SMESH_LogicalFilter; //================================================================================= // class : SMESHGUI_GroupDlg @@ -68,9 +73,9 @@ class SMESHGUI_EXPORT SMESHGUI_GroupDlg : public QDialog public: SMESHGUI_GroupDlg( SMESHGUI*, - SMESH::SMESH_Mesh_ptr = SMESH::SMESH_Mesh::_nil() ); + SMESH::SMESH_Mesh_ptr = SMESH::SMESH_Mesh::_nil() ); SMESHGUI_GroupDlg( SMESHGUI*, - SMESH::SMESH_GroupBase_ptr, + SMESH::SMESH_GroupBase_ptr, const bool theIsConvert = false ); ~SMESHGUI_GroupDlg(); @@ -90,10 +95,12 @@ private slots: bool onApply(); void onHelp(); void onDeactivate(); + void onVisibilityChanged(); void onListSelectionChanged(); void onObjectSelectionChanged(); + void onSelectAll(); void onSelectSubMesh( bool ); void onSelectGroup( bool ); void onSelectGeomGroup( bool ); @@ -126,6 +133,8 @@ private: bool SetAppropriateActor(); void setShowEntityMode(); void restoreShowEntityMode(); + + bool IsActorVisible( SMESH_Actor* ); void setGroupColor( const SALOMEDS::Color& ); SALOMEDS::Color getGroupColor() const; @@ -134,10 +143,14 @@ private: QColor getGroupQColor() const; void setDefaultGroupColor(); - + + void setIsApplyAndClose( const bool theFlag ); + bool isApplyAndClose() const; + + private: + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ - SMESH_Actor* myActor; /* Current mesh actor */ int myGrpTypeId; /* Current group type id : standalone or group on geometry */ int myTypeId; /* Current type id = radio button id */ int myStoredShownEntity; /* Store ShowEntity mode of myMesh */ @@ -154,13 +167,19 @@ private: QButtonGroup* myGrpTypeGroup; QStackedWidget* myWGStack; + QCheckBox* mySelectAll; + QCheckBox* myAllowElemsModif; + QLabel* myElementsLab; QListWidget* myElements; - QPushButton* myFilter; + QPushButton* myFilterBtn; + QPushButton* myAddBtn; + QPushButton* myRemoveBtn; + QPushButton* mySortBtn; + QGroupBox* mySelectBox; QCheckBox* mySelectSubMesh; QPushButton* mySubMeshBtn; QLineEdit* mySubMeshLine; - QCheckBox* mySelectGroup; QPushButton* myGroupBtn; QLineEdit* myGroupLine; @@ -180,8 +199,11 @@ private: SMESHGUI_ShapeByMeshOp* myShapeByMeshOp; SMESH::SMESH_Mesh_var myMesh; + QList myActorsList; SMESH::SMESH_Group_var myGroup; SMESH::SMESH_GroupOnGeom_var myGroupOnGeom; + SMESH::SMESH_GroupOnFilter_var myGroupOnFilter; + SMESH::Filter_var myFilter; QList myIdList; GEOM::ListOfGO_var myGeomObjects; @@ -190,8 +212,8 @@ private: //Handle(SMESH_TypeFilter) mySubMeshFilter; //Handle(SMESH_TypeFilter) myGroupFilter; SUIT_SelectionFilter* myMeshFilter; - SUIT_SelectionFilter* mySubMeshFilter; - SUIT_SelectionFilter* myGroupFilter; + SMESH_LogicalFilter* mySubMeshFilter; + SMESH_LogicalFilter* myGroupFilter; SUIT_SelectionFilter* myGeomFilter; SMESHGUI_FilterDlg* myFilterDlg; @@ -203,6 +225,10 @@ private: QMap myActions; bool myNameChanged; //added by skl for IPAL19574 + int myNbChangesOfContents; // nb add's and remove's + + QString myObjectToSelect; + bool myIsApplyAndClose; }; #endif // SMESHGUI_GROUPDLG_H diff --git a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx index c85a269df..2bfdd1bc9 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GroupOnShapeDlg.cxx // Created : Wed Sep 17 18:36:51 2008 @@ -29,6 +27,7 @@ #include "SMESHGUI_GroupOnShapeDlg.h" #include "SMESH_TypeFilter.hxx" +#include "SMESHGUI.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_GEOMGenUtils.h" @@ -37,6 +36,7 @@ #include #include +#include #include #include @@ -178,7 +178,7 @@ SMESHGUI_GroupOnShapeOp::SMESHGUI_GroupOnShapeOp() : SMESHGUI_SelectionOp(ActorSelection), myDlg( 0 ) { - myHelpFileName = "creating_groups_page.html"; + myHelpFileName = "create_groups_from_geometry_page.html"; } SMESHGUI_GroupOnShapeOp::~SMESHGUI_GroupOnShapeOp() @@ -302,7 +302,7 @@ bool SMESHGUI_GroupOnShapeOp::onApply() if ( !aStudy ) return false; // mesh - _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() ); + _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() ); SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface( meshSO ); if ( mesh->_is_nil() ) return false; @@ -319,6 +319,7 @@ bool SMESHGUI_GroupOnShapeOp::onApply() // create groups SMESH::SMESH_GroupOnGeom_var group; + QStringList anEntryList; for ( int isNode = 0; isNode < 2; ++isNode ) // elems and then nodes { QStringList::iterator geomID = isNode ? myNodeGeoIDs.begin() : myElemGeoIDs.begin(); @@ -347,11 +348,30 @@ bool SMESHGUI_GroupOnShapeOp::onApply() //printf( "apply() %s %s\n", (*geomID).latin1(), name.latin1() ); group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom ); + if( !group->_is_nil() ) + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( group ) ) + anEntryList.append( aSObject->GetID().c_str() ); } } update( UF_ObjBrowser | UF_Model ); - init(); + SMESHGUI::Modified(); + + // Re-init controls to create the next group + myElemGeoIDs.clear(); + myNodeGeoIDs.clear(); + removeCustomFilters(); + myDlg->myNodeGeomList->clear(); + myDlg->myElemGeomList->clear(); + myDlg->myElemGeomBtn->setChecked(false); + myDlg->myNodeGeomBtn->setChecked(false); + myDlg->updateButtons(); + + update( UF_ObjBrowser | UF_Model ); + + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); return !group->_is_nil(); } @@ -431,6 +451,7 @@ void SMESHGUI_GroupOnShapeOp::selectionDone() myDlg->myElemGeomBtn->setEnabled( nbSelected == 1 ); myDlg->myNodeGeomList->clear(); myDlg->myNodeGeomBtn->setEnabled( nbSelected == 1 ); + myDlg->myElemGeomBtn->click(); return; } diff --git a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.h b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.h index 0009e5996..8e5478974 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.h +++ b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.h @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GroupOnShapeDlg.h // Author : Edard AGAPOV diff --git a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx index 44cdfdf94..8588a3c56 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GroupOpDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -44,6 +45,9 @@ #include #include +// SALOME KERNEL includes +#include + // Qt includes #include #include @@ -74,7 +78,8 @@ SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg( SMESHGUI* theModule ) : QDialog( SMESH::GetDesktop( theModule ) ), mySMESHGUI( theModule ), - mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myIsApplyAndClose( false ) { setModal(false); @@ -131,7 +136,7 @@ QWidget* SMESHGUI_GroupOpDlg::createMainFrame( QWidget* theParent ) QLabel* aColorLab = new QLabel(tr( "SMESH_CHECK_COLOR" ), aColorBox ); myColorBtn = new QtxColorButton(aColorBox); myColorBtn->setSizePolicy( QSizePolicy::MinimumExpanding, - myColorBtn->sizePolicy().verticalPolicy() ); + myColorBtn->sizePolicy().verticalPolicy() ); aColorBoxLayout->addWidget(aColorLab); aColorBoxLayout->addWidget(myColorBtn); @@ -242,7 +247,7 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList& theL if ( theListGrp.isEmpty() ) { SUIT_MessageBox::information( this, tr("SMESH_INSUFFICIENT_DATA"), - tr("INCORRECT_ARGUMENTS") ); + tr("INCORRECT_ARGUMENTS") ); return false; } @@ -289,14 +294,14 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList& theL if ( aMeshId == -1 ) { SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"), - tr("DIFF_MESHES")); + tr("DIFF_MESHES")); return false; } if ( aGrpType == -1 ) { SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"), - tr("DIFF_TYPES")); + tr("DIFF_TYPES")); return false; } @@ -308,8 +313,10 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList& theL */ void SMESHGUI_GroupOpDlg::onOk() { + setIsApplyAndClose( true ); if ( onApply() ) onClose(); + setIsApplyAndClose( false ); } /*! @@ -343,10 +350,10 @@ void SMESHGUI_GroupOpDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -524,6 +531,28 @@ bool SMESHGUI_GroupOpDlg::onApply() return false; } +/*! + \brief Set value of the flag indicating that the dialog is + accepted by Apply & Close button + \param theFlag value of the flag + \sa isApplyAndClose() +*/ +void SMESHGUI_GroupOpDlg::setIsApplyAndClose( const bool theFlag ) +{ + myIsApplyAndClose = theFlag; +} + +/*! + \brief Get value of the flag indicating that the dialog is + accepted by Apply & Close button + \return value of the flag + \sa setApplyAndClose() +*/ +bool SMESHGUI_GroupOpDlg::isApplyAndClose() const +{ + return myIsApplyAndClose; +} + // === === === === === === === === === === === === === === === === === === === === === /*! @@ -585,6 +614,7 @@ bool SMESHGUI_UnionGroupsDlg::onApply() QString aName = getName(); bool aRes = false; + QStringList anEntryList; try { SMESH::ListOfGroups_var aList = convert( myGroups ); @@ -593,6 +623,8 @@ bool SMESHGUI_UnionGroupsDlg::onApply() if ( !CORBA::is_nil( aNewGrp ) ) { aNewGrp->SetColor( getColor() ); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) ) + anEntryList.append( aSObject->GetID().c_str() ); aRes = true; } } @@ -603,14 +635,18 @@ bool SMESHGUI_UnionGroupsDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); return true; } else { SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), - tr("SMESH_OPERATION_FAILED")); + tr("SMESH_OPERATION_FAILED")); return false; } } @@ -687,6 +723,7 @@ bool SMESHGUI_IntersectGroupsDlg::onApply() QString aName = getName(); bool aRes = false; + QStringList anEntryList; try { SMESH::ListOfGroups_var aList = convert( myGroups ); @@ -695,6 +732,8 @@ bool SMESHGUI_IntersectGroupsDlg::onApply() if ( !CORBA::is_nil( aNewGrp ) ) { aNewGrp->SetColor( getColor() ); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) ) + anEntryList.append( aSObject->GetID().c_str() ); aRes = true; } } @@ -705,14 +744,18 @@ bool SMESHGUI_IntersectGroupsDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); return true; } else { SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), - tr("SMESH_OPERATION_FAILED")); + tr("SMESH_OPERATION_FAILED")); return false; } } @@ -852,6 +895,7 @@ bool SMESHGUI_CutGroupsDlg::onApply() QString aName = getName(); bool aRes = false; + QStringList anEntryList; try { SMESH::ListOfGroups_var aList1 = convert( myGroups1 ); @@ -861,6 +905,8 @@ bool SMESHGUI_CutGroupsDlg::onApply() if ( !CORBA::is_nil( aNewGrp ) ) { aNewGrp->SetColor( getColor() ); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) ) + anEntryList.append( aSObject->GetID().c_str() ); aRes = true; } } @@ -871,14 +917,18 @@ bool SMESHGUI_CutGroupsDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); return true; } else { SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), - tr("SMESH_OPERATION_FAILED")); + tr("SMESH_OPERATION_FAILED")); return false; } } @@ -913,7 +963,7 @@ SMESHGUI_DimGroupDlg::SMESHGUI_DimGroupDlg( SMESHGUI* theModule ) : SMESHGUI_GroupOpDlg( theModule ) { setWindowTitle( tr( "CREATE_GROUP_OF_UNDERLYING_ELEMS" ) ); - setHelpFileName( "creating_groups_page.html#gui_create_dim_group" ); + setHelpFileName( "group_of_underlying_elements_page.html" ); QGroupBox* anArgGrp = getArgGrp(); @@ -1003,6 +1053,7 @@ bool SMESHGUI_DimGroupDlg::onApply() QString aName = getName(); bool aRes = false; + QStringList anEntryList; try { SMESH::ListOfGroups_var aList = convert( myGroups ); @@ -1012,6 +1063,8 @@ bool SMESHGUI_DimGroupDlg::onApply() if ( !CORBA::is_nil( aNewGrp ) ) { aNewGrp->SetColor( getColor() ); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) ) + anEntryList.append( aSObject->GetID().c_str() ); aRes = true; } } @@ -1022,14 +1075,18 @@ bool SMESHGUI_DimGroupDlg::onApply() if ( aRes ) { + SMESHGUI::Modified(); getSMESHGUI()->updateObjBrowser(true); reset(); + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); return true; } else { SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), - tr("SMESH_OPERATION_FAILED")); + tr("SMESH_OPERATION_FAILED")); return false; } } diff --git a/src/SMESHGUI/SMESHGUI_GroupOpDlg.h b/src/SMESHGUI/SMESHGUI_GroupOpDlg.h index fda94dd01..ec3b4c2f5 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOpDlg.h +++ b/src/SMESHGUI/SMESHGUI_GroupOpDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GroupOpDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -87,6 +88,9 @@ protected: SALOMEDS::Color getColor() const; + void setIsApplyAndClose( const bool theFlag ); + bool isApplyAndClose() const; + private: void closeEvent( QCloseEvent* ); void enterEvent( QEvent* ); @@ -118,6 +122,8 @@ private: SVTK_Selector* mySelector; QString myHelpFileName; + + bool myIsApplyAndClose; }; /* diff --git a/src/SMESHGUI/SMESHGUI_GroupUtils.cxx b/src/SMESHGUI/SMESHGUI_GroupUtils.cxx index e645257e2..093426cfd 100644 --- a/src/SMESHGUI/SMESHGUI_GroupUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GroupUtils.cxx // Author : Open CASCADE S.A.S. @@ -35,13 +36,13 @@ namespace SMESH { SMESH::SMESH_Group_var AddGroup( SMESH::SMESH_Mesh_ptr theMesh, - SMESH::ElementType theType, - const QString& theGroupName ) + SMESH::ElementType theType, + const QString& theGroupName ) { SMESH::SMESH_Group_var aGroup; try { if ( !theMesh->_is_nil() ) - aGroup = theMesh->CreateGroup( theType, theGroupName.toLatin1().data() ); + aGroup = theMesh->CreateGroup( theType, theGroupName.toLatin1().data() ); } catch( const SALOME::SALOME_Exception& S_ex ) { SalomeApp_Tools::QtCatchCorbaException( S_ex ); diff --git a/src/SMESHGUI/SMESHGUI_GroupUtils.h b/src/SMESHGUI/SMESHGUI_GroupUtils.h index e0673a783..1ede5161b 100644 --- a/src/SMESHGUI/SMESHGUI_GroupUtils.h +++ b/src/SMESHGUI/SMESHGUI_GroupUtils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_GroupUtils.h // Author : Open CASCADE S.A.S. @@ -40,8 +41,8 @@ namespace SMESH { SMESHGUI_EXPORT SMESH::SMESH_Group_var AddGroup( SMESH::SMESH_Mesh_ptr, - SMESH::ElementType, - const QString& ); + SMESH::ElementType, + const QString& ); } #endif // SMESHGUI_GROUPUTILS_H diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx index 8ca61f49f..3d0baf890 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_Hypotheses.cxx -// Author : Julia DOROVSKIKH, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI_Hypotheses.cxx +// Author : Julia DOROVSKIKH, Open CASCADE S.A.S. +// SMESH includes + #include "SMESHGUI_Hypotheses.h" #include "SMESHGUI.h" @@ -48,13 +47,16 @@ #include #include #include -#include #define SPACING 6 #define MARGIN 11 +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + SMESHGUI_GenericHypothesisCreator::SMESHGUI_GenericHypothesisCreator( const QString& theHypType ) - : myHypType( theHypType ), myIsCreate( false ), myDlg( 0 ), myEventLoop( 0 ) + : myHypType( theHypType ), myIsCreate( false ), myDlg( 0 ) { } @@ -69,46 +71,45 @@ void SMESHGUI_GenericHypothesisCreator::setInitParamsHypothesis(SMESH::SMESH_Hyp } void SMESHGUI_GenericHypothesisCreator::create( SMESH::SMESH_Hypothesis_ptr initParamsHyp, - const QString& theHypName, - QWidget* parent) + const QString& theHypName, + QWidget* parent, QObject* obj, const QString& slot ) { MESSAGE( "Creation of hypothesis with initial params" ); setInitParamsHypothesis( initParamsHyp ); - create( false, theHypName, parent ); + create( false, theHypName, parent, obj, slot ); } void SMESHGUI_GenericHypothesisCreator::create( bool isAlgo, - const QString& theHypName, - QWidget* theParent ) + const QString& theHypName, + QWidget* theParent, QObject* obj, const QString& slot ) { MESSAGE( "Creation of hypothesis" ); myIsCreate = true; // Create hypothesis/algorithm - if (isAlgo) - SMESH::CreateHypothesis( hypType(), theHypName, isAlgo ); - else - { - SMESH::SMESH_Hypothesis_var aHypothesis = + if (isAlgo) { + SMESH::SMESH_Hypothesis_var anAlgo = + SMESH::CreateHypothesis( hypType(), theHypName, isAlgo ); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(anAlgo)) + anAlgo->UnRegister(); +#endif + } + else { + SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::CreateHypothesis( hypType(), theHypName, false ); - if( !editHypothesis( aHypothesis.in(), theHypName, theParent ) ) - { //remove just created hypothesis - _PTR(SObject) aHypSObject = SMESH::FindSObject( aHypothesis.in() ); - _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); - if( aStudy && !aStudy->GetProperties()->IsLocked() ) - { - _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); - aBuilder->RemoveObjectWithChildren( aHypSObject ); - } - } + editHypothesis( aHypothesis.in(), theHypName, theParent, obj, slot ); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHypothesis)) + aHypothesis->UnRegister(); +#endif } - SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); } void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr theHypothesis, - const QString& theHypName, - QWidget* theParent ) + const QString& theHypName, + QWidget* theParent, QObject* obj, const QString& slot ) { if( CORBA::is_nil( theHypothesis ) ) return; @@ -117,37 +118,25 @@ void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr theHyp myIsCreate = false; - if( !editHypothesis( theHypothesis, theHypName, theParent ) ) - return; - - SMESH::SObjectList listSOmesh = SMESH::GetMeshesUsingAlgoOrHypothesis( theHypothesis ); - if( listSOmesh.size() > 0 ) - for( int i = 0; i < listSOmesh.size(); i++ ) - { - _PTR(SObject) submSO = listSOmesh[i]; - SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface( submSO ); - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface( submSO ); - if( !aSubMesh->_is_nil() ) - aMesh = aSubMesh->GetFather(); - _PTR(SObject) meshSO = SMESH::FindSObject( aMesh ); - SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0); - } - SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); + editHypothesis( theHypothesis, theHypName, theParent, obj, slot ); } -bool SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, - const QString& theHypName, - QWidget* theParent ) +void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, + const QString& theHypName, + QWidget* theParent, + QObject* obj, const QString& slot ) { - if( CORBA::is_nil( h ) ) - return false; - - bool res = true; myHypName = theHypName; myHypo = SMESH::SMESH_Hypothesis::_duplicate( h ); +#ifdef WITHGENERICOBJ + myHypo->Register(); +#endif SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent ); connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) ); + connect( this, SIGNAL( finished( int ) ), obj, slot.toLatin1().constData() ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), Dlg, SLOT( reject() )); + myDlg = Dlg; QFrame* fr = buildFrame(); if( fr ) @@ -159,25 +148,14 @@ bool SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ Dlg->setType( type() ); retrieveParams(); Dlg->show(); - if ( !myEventLoop ) - myEventLoop = new QEventLoop( this ); - myEventLoop->exec(); // make myDlg not modal - res = myDlg->result(); - if( res ) { - QString paramValues = storeParams(); - if ( !paramValues.isEmpty() ) { - if ( _PTR(SObject) SHyp = SMESH::FindSObject( myHypo )) - SMESH::SetValue( SHyp, paramValues ); - } - } + Dlg->resize( Dlg->minimumSizeHint() ); + } + else { + emit finished( QDialog::Accepted ); + delete myDlg; } - delete Dlg; myDlg = 0; - changeWidgets().clear(); - myHypo = SMESH::SMESH_Hypothesis::_nil(); - myInitParamsHypo = SMESH::SMESH_Hypothesis::_nil(); - return res; } - + QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() { if( CORBA::is_nil( hypothesis() ) ) @@ -206,13 +184,13 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() GroupC1Layout->addWidget( lab, i, 0 ); QWidget* w = getCustomWidget( *anIt, GroupC1, i ); - if ( !w ) + if ( !w ) switch( (*anIt).myValue.type() ) { case QVariant::Int: { SalomeApp_IntSpinBox* sb = new SalomeApp_IntSpinBox( GroupC1 ); - sb->setObjectName( (*anIt).myName ); + sb->setObjectName( (*anIt).myName ); attuneStdWidget( sb, i ); sb->setValue( (*anIt).myValue.toInt() ); connect( sb, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) ); @@ -222,7 +200,7 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() case QVariant::Double: { SalomeApp_DoubleSpinBox* sb = new SMESHGUI_SpinBox( GroupC1 ); - sb->setObjectName( (*anIt).myName ); + sb->setObjectName( (*anIt).myName ); attuneStdWidget( sb, i ); sb->setValue( (*anIt).myValue.toDouble() ); connect( sb, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); @@ -243,7 +221,7 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() w = sb; } else if(aStudy->IsReal(aVar.toLatin1().constData())){ - SalomeApp_DoubleSpinBox* sb = new SalomeApp_DoubleSpinBox( GroupC1 ); + SalomeApp_DoubleSpinBox* sb = new SMESHGUI_SpinBox( GroupC1 ); sb->setObjectName( (*anIt).myName ); attuneStdWidget( sb, i ); sb->setText( aVar ); @@ -282,10 +260,59 @@ void SMESHGUI_GenericHypothesisCreator::valueChanged( QWidget* ) { } -void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int /*result*/ ) +void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result ) { - if ( myEventLoop ) - myEventLoop->exit(); + bool res = result==QDialog::Accepted; + if( res ) + { + /*QString paramValues = */storeParams(); + // No longer needed since NoteBook appears and "Value" OB field shows names of variable +// if ( !paramValues.isEmpty() ) { +// if ( _PTR(SObject) SHyp = SMESH::FindSObject( myHypo )) +// SMESH::SetValue( SHyp, paramValues ); +// } + } + + changeWidgets().clear(); + + if( myIsCreate && !res ) + { + //remove just created hypothesis + _PTR(SObject) aHypSObject = SMESH::FindSObject( myHypo ); + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + if( aStudy && !aStudy->GetProperties()->IsLocked() ) + { + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + aBuilder->RemoveObjectWithChildren( aHypSObject ); + } + } + else if( !myIsCreate && res ) + { + SMESH::SObjectList listSOmesh = SMESH::GetMeshesUsingAlgoOrHypothesis( myHypo ); + if( listSOmesh.size() > 0 ) + for( int i = 0; i < listSOmesh.size(); i++ ) + { + _PTR(SObject) submSO = listSOmesh[i]; + SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface( submSO ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface( submSO ); + if( !aSubMesh->_is_nil() ) + aMesh = aSubMesh->GetFather(); + _PTR(SObject) meshSO = SMESH::FindSObject( aMesh ); + SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0); + } + } + SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); +#ifdef WITHGENERICOBJ + myHypo->UnRegister(); +#endif + myHypo = SMESH::SMESH_Hypothesis::_nil(); + myInitParamsHypo = SMESH::SMESH_Hypothesis::_nil(); + + disconnect( myDlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) ); + myDlg->close(); + //delete myDlg; since WA_DeleteOnClose==true + myDlg = 0; + emit finished( result ); } bool SMESHGUI_GenericHypothesisCreator::stdParams( ListOfStdParams& ) const @@ -305,48 +332,52 @@ bool SMESHGUI_GenericHypothesisCreator::getStdParamFromDlg( ListOfStdParams& par { SalomeApp_IntSpinBox* sb = ( SalomeApp_IntSpinBox* )( *anIt ); item.myValue = sb->value(); + item.myText = sb->text(); params.append( item ); } - else if( (*anIt)->inherits( "SalomeApp_DoubleSpinBox" ) ) { SalomeApp_DoubleSpinBox* sb = ( SalomeApp_DoubleSpinBox* )( *anIt ); item.myValue = sb->value(); + item.myText = sb->text(); params.append( item ); } - else if( (*anIt)->inherits( "QLineEdit" ) ) { QLineEdit* line = ( QLineEdit* )( *anIt ); - item.myValue = line->text(); + item.myValue = item.myText = line->text(); params.append( item ); } - else if ( getParamFromCustomWidget( item, *anIt )) { params.append( item ); } - else res = false; } return res; } +QString SMESHGUI_GenericHypothesisCreator::getVariableName(const char* methodName) const +{ + SMESH::SMESH_Hypothesis_var h = hypothesis(); + if ( !h->_is_nil() ) + { + CORBA::String_var aVaribaleName = h->GetVarParameter( methodName ); + return QString( aVaribaleName.in() ); + } + return QString(); +} QStringList SMESHGUI_GenericHypothesisCreator::getVariablesFromDlg() const { QStringList aResult; ListOfWidgets::const_iterator anIt = widgets().begin(), aLast = widgets().end(); for( ; anIt!=aLast; anIt++ ) { - if( (*anIt)->inherits( "SalomeApp_IntSpinBox" ) ) { - SalomeApp_IntSpinBox* sb = ( SalomeApp_IntSpinBox* )( *anIt ); + if( (*anIt)->inherits( "QAbstractSpinBox" ) ) { + QAbstractSpinBox* sb = ( QAbstractSpinBox* )( *anIt ); aResult.append(sb->text()); - } - else if( (*anIt)->inherits( "QtxDoubleSpinBox" ) ) { - QtxDoubleSpinBox* sb = ( QtxDoubleSpinBox* )( *anIt ); - aResult.append(sb->text()); - } + } } return aResult; } @@ -386,6 +417,11 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_GenericHypothesisCreator::hypothesis() cons return myHypo; } +void SMESHGUI_GenericHypothesisCreator::setShapeEntry( const QString& theEntry ) +{ + myShapeEntry = theEntry; +} + //================================================================================ /*! * \brief Return hypothesis containing initial parameters @@ -430,7 +466,7 @@ SMESHGUI_GenericHypothesisCreator::ListOfWidgets& SMESHGUI_GenericHypothesisCrea } QtxDialog* SMESHGUI_GenericHypothesisCreator:: dlg() const -{ +{ return myDlg; } @@ -495,11 +531,15 @@ void SMESHGUI_GenericHypothesisCreator::onReject() QString SMESHGUI_GenericHypothesisCreator::helpPage() const { QString aHypType = hypType(); - QString aHelpFileName; + QString aHelpFileName = ""; if ( aHypType == "LocalLength" ) aHelpFileName = "a1d_meshing_hypo_page.html#average_length_anchor"; + else if ( aHypType == "MaxLength" ) + aHelpFileName = "a1d_meshing_hypo_page.html#max_length_anchor"; else if ( aHypType == "Arithmetic1D") aHelpFileName = "a1d_meshing_hypo_page.html#arithmetic_1d_anchor"; + else if ( aHypType == "FixedPoints1D") + aHelpFileName = "a1d_meshing_hypo_page.html#fixed_points_1d_anchor"; else if ( aHypType == "MaxElementArea") aHelpFileName = "a2d_meshing_hypo_page.html#max_element_area_anchor"; else if ( aHypType == "MaxElementVolume") @@ -520,23 +560,29 @@ QString SMESHGUI_GenericHypothesisCreator::helpPage() const aHelpFileName = "projection_algos_page.html"; else if ( aHypType == "NumberOfLayers") aHelpFileName = "radial_prism_algo_page.html"; + else if ( aHypType == "NumberOfLayers2D") + aHelpFileName = "radial_quadrangle_1D2D_algo_page.html"; else if ( aHypType == "LayerDistribution") aHelpFileName = "radial_prism_algo_page.html"; + else if ( aHypType == "LayerDistribution2D") + aHelpFileName = "radial_quadrangle_1D2D_algo_page.html"; else if ( aHypType == "SegmentLengthAroundVertex") - aHelpFileName = "segments_around_vertex_algo.html"; - else - aHelpFileName = ""; + aHelpFileName = "segments_around_vertex_algo_page.html"; + else if ( aHypType == "QuadrangleParams") + aHelpFileName = "a2d_meshing_hypo_page.html#hypo_quad_params_anchor"; + else if ( aHypType == "ViscousLayers") + aHelpFileName = "additional_hypo_page.html#viscous_layers_anchor"; + else if ( aHypType == "ImportSource1D" || aHypType == "ImportSource2D") + aHelpFileName = "import_algos_page.html"; return aHelpFileName; } - - - SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreator* creator, QWidget* parent ) : QtxDialog( parent, false, true ), myCreator( creator ) { - setMinimumSize( 300, height() ); + setAttribute(Qt::WA_DeleteOnClose, true); + // setMinimumSize( 300, height() ); // setFixedSize( 300, height() ); QVBoxLayout* topLayout = new QVBoxLayout( mainFrame() ); topLayout->setMargin( 0 ); @@ -546,7 +592,7 @@ SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreato QHBoxLayout* titLay = new QHBoxLayout( titFrame ); titLay->setMargin( 0 ); titLay->setSpacing( SPACING ); - + myIconLabel = new QLabel( titFrame ); myIconLabel->setScaledContents( false ); myIconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); @@ -567,6 +613,7 @@ SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreato SMESHGUI_HypothesisDlg::~SMESHGUI_HypothesisDlg() { + delete myCreator; } void SMESHGUI_HypothesisDlg::setCustomFrame( QFrame* f ) @@ -602,8 +649,17 @@ void SMESHGUI_HypothesisDlg::onHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); if (app) { - SMESHGUI* aSMESHGUI = dynamic_cast( app->activeModule() ); - app->onHelpContextModule(aSMESHGUI ? app->moduleName(aSMESHGUI->moduleName()) : QString(""), myHelpFileName); + QString name = "SMESH"; + if(myCreator) { + QVariant pluginName = myCreator->property( PLUGIN_NAME ); + if( pluginName.isValid() ) { + QString rootDir = pluginName.toString() + "PLUGIN_ROOT_DIR"; + QString varValue = QString( getenv(rootDir.toLatin1().constData())); + if(!varValue.isEmpty()) + name = pluginName.toString() + "PLUGIN"; + } + } + app->onHelpContextModule(name, myHelpFileName); } else { QString platform; @@ -613,16 +669,16 @@ void SMESHGUI_HypothesisDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } void SMESHGUI_HypothesisDlg::setHIcon( const QPixmap& p ) { - myIconLabel->setPixmap( p ); + myIconLabel->setPixmap( p ); } void SMESHGUI_HypothesisDlg::setType( const QString& t ) @@ -631,18 +687,18 @@ void SMESHGUI_HypothesisDlg::setType( const QString& t ) } HypothesisData::HypothesisData( const QString& theTypeName, - const QString& thePluginName, - const QString& theServerLibName, - const QString& theClientLibName, - const QString& theLabel, - const QString& theIconId, - const QList& theDim, - const bool theIsAux, - const QStringList& theNeededHypos, - const QStringList& theOptionalHypos, - const QStringList& theInputTypes, - const QStringList& theOutputTypes, - const bool theIsNeedGeometry, + const QString& thePluginName, + const QString& theServerLibName, + const QString& theClientLibName, + const QString& theLabel, + const QString& theIconId, + const QList& theDim, + const bool theIsAux, + const QStringList& theNeededHypos, + const QStringList& theOptionalHypos, + const QStringList& theInputTypes, + const QStringList& theOutputTypes, + const bool theIsNeedGeometry, const bool supportSub) : TypeName( theTypeName ), PluginName( thePluginName ), @@ -652,7 +708,7 @@ HypothesisData::HypothesisData( const QString& theTypeName, IconId( theIconId ), Dim( theDim ), IsAux( theIsAux ), - NeededHypos( theNeededHypos ), + NeededHypos( theNeededHypos ), OptionalHypos( theOptionalHypos ), InputTypes( theInputTypes ), OutputTypes( theOutputTypes ), @@ -661,16 +717,96 @@ HypothesisData::HypothesisData( const QString& theTypeName, { } -HypothesesSet::HypothesesSet( const QString& theSetName ) - : HypoSetName( theSetName ) +HypothesesSet::HypothesesSet( const QString& theSetName ) + : myHypoSetName( theSetName ), + myIsAlgo( false ), + myIsCustom( false ) { } HypothesesSet::HypothesesSet( const QString& theSetName, - const QStringList& theHypoList, - const QStringList& theAlgoList ) - : HypoSetName( theSetName ), - HypoList( theHypoList ), - AlgoList( theAlgoList ) + const QStringList& theHypoList, + const QStringList& theAlgoList ) + : myHypoSetName( theSetName ), + myHypoList( theHypoList ), + myAlgoList( theAlgoList ), + myIsAlgo( false ), + myIsCustom( false ) +{ +} + +QStringList* HypothesesSet::list(bool is_algo) const +{ + return const_cast( &( is_algo ? myAlgoList : myHypoList ) ); +} + +QStringList* HypothesesSet::list() const +{ + return list( myIsAlgo ); +} + +QString HypothesesSet::name() const +{ + return myHypoSetName; +} + +void HypothesesSet::set( bool isAlgo, const QStringList& lst ) +{ + *list(isAlgo) = lst; +} + +int HypothesesSet::count( bool isAlgo ) const +{ + return list(isAlgo)->count(); +} + +bool HypothesesSet::isAlgo() const +{ + return myIsAlgo; +} + +void HypothesesSet::init( bool isAlgo ) { + myIsAlgo = isAlgo; + myIndex = -1; +} + +bool HypothesesSet::more() const +{ + return myIndex < list()->count(); +} + +void HypothesesSet::next() +{ + myIndex++; +} + +QString HypothesesSet::current() const +{ + return list()->at(myIndex); +} + +void HypothesesSet::setIsCustom( bool isCustom ) +{ + myIsCustom = isCustom; +} + +bool HypothesesSet::getIsCustom() const +{ + return myIsCustom; +} + +int HypothesesSet::maxDim() const +{ + HypothesesSet * thisSet = (HypothesesSet*) this; + int dim = -1; + for ( int isAlgo = 0; isAlgo < 2; ++isAlgo ) + { + thisSet->init( isAlgo ); + while ( thisSet->next(), thisSet->more() ) + if ( HypothesisData* hypData = SMESH::GetHypothesisData( thisSet->current() )) + for ( int i = 0; i < hypData->Dim.count(); ++i ) + dim = qMax( dim, hypData->Dim[i] ); + } + return dim; } diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.h b/src/SMESHGUI/SMESHGUI_Hypotheses.h index 6cf6c524d..c15484b84 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.h +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Hypotheses.h // Author : Julia DOROVSKIKH, Open CASCADE S.A.S. @@ -28,6 +29,7 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" +#include "SMESHGUI_HypothesesUtils.h" // Qt includes #include @@ -51,10 +53,9 @@ public: virtual ~SMESHGUI_GenericHypothesisCreator(); void create( SMESH::SMESH_Hypothesis_ptr, - const QString&, QWidget* ); - void create( bool, const QString&, QWidget* ); - void edit( SMESH::SMESH_Hypothesis_ptr, - const QString&, QWidget* ); + const QString&, QWidget*, QObject*, const QString& ); + void create( bool, const QString&, QWidget*, QObject*, const QString& ); + void edit( SMESH::SMESH_Hypothesis_ptr, const QString&, QWidget*, QObject*, const QString& ); void setInitParamsHypothesis(SMESH::SMESH_Hypothesis_ptr); virtual bool checkParams( QString& ) const; @@ -64,6 +65,15 @@ public: QString hypType() const; QString hypName() const; bool isCreation() const; + + QString getShapeEntry() const { return myShapeEntry; } + void setShapeEntry( const QString& theEntry ); + + QString getMainShapeEntry() const { return myMainShapeEntry; } + void setMainShapeEntry( const QString& theEntry ) { myMainShapeEntry = theEntry; } + +signals: + void finished( int ); protected: struct StdParam @@ -71,9 +81,11 @@ protected: QString myName; QVariant myValue; bool isVariable; + QString myText; StdParam(){ isVariable = false; } + const char* text() const { return myText.toLatin1().constData(); } }; typedef QList ListOfStdParams; @@ -85,6 +97,7 @@ protected: const ListOfWidgets& widgets() const; ListOfWidgets& changeWidgets(); QtxDialog* dlg() const; + QString getVariableName(const char* methodName) const; virtual QFrame* buildFrame() = 0; QFrame* buildStdFrame(); @@ -96,7 +109,7 @@ protected: static QString stdParamValues( const ListOfStdParams& ); virtual void attuneStdWidget( QWidget*, const int ) const; virtual QWidget* getCustomWidget( const StdParam&, - QWidget*, const int ) const; + QWidget*, const int ) const; virtual bool getParamFromCustomWidget( StdParam&, QWidget* ) const; virtual void valueChanged( QWidget* ); virtual QString caption() const; @@ -110,8 +123,7 @@ private slots: virtual void onDialogFinished( int ); private: - bool editHypothesis( SMESH::SMESH_Hypothesis_ptr, - const QString&, QWidget* ); + void editHypothesis( SMESH::SMESH_Hypothesis_ptr, const QString&, QWidget*, QObject* obj, const QString& ); private: SMESH::SMESH_Hypothesis_var myHypo, myInitParamsHypo; @@ -120,7 +132,8 @@ private: ListOfWidgets myParamWidgets; bool myIsCreate; QtxDialog* myDlg; - QEventLoop* myEventLoop; + QString myShapeEntry; + QString myMainShapeEntry; }; class SMESHGUI_HypothesisDlg : public QtxDialog @@ -131,20 +144,19 @@ public: SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreator*, QWidget* ); virtual ~SMESHGUI_HypothesisDlg(); - void setHIcon( const QPixmap& ); - void setCustomFrame( QFrame* ); - void setType( const QString& ); + void setHIcon( const QPixmap& ); + void setCustomFrame( QFrame* ); + void setType( const QString& ); protected slots: - virtual void accept(); - virtual void reject(); - void onHelp(); + virtual void accept(); + virtual void reject(); + void onHelp(); private: - SMESHGUI_GenericHypothesisCreator* myCreator; - QLabel* myIconLabel; - QLabel* myTypeLabel; - QString myHelpFileName; + SMESHGUI_GenericHypothesisCreator* myCreator; + QLabel *myIconLabel, *myTypeLabel; + QString myHelpFileName; }; /*! @@ -158,7 +170,7 @@ public: const QList&, const bool, const QStringList&, const QStringList&, const QStringList&, const QStringList&, - const bool=true, const bool supportSub=false ); + const bool=true, const bool supportSub=false ); QString TypeName; //!< hypothesis type name QString PluginName; //!< plugin name @@ -189,8 +201,32 @@ public: HypothesesSet( const QString& ); HypothesesSet( const QString&, const QStringList&, const QStringList& ); - QString HypoSetName; - QStringList HypoList, AlgoList; + QString name() const; + void set( bool, const QStringList& ); + int count( bool ) const; + + void setIsCustom( bool ); + bool getIsCustom() const; + int maxDim() const; + + bool isAlgo() const; + + //this method sets internal index to -1, thus before any data access it is necessary to call next() + void init( bool ); + + bool more() const; + void next(); + QString current() const; + +private: + QStringList* list(bool) const; + QStringList* list() const; + +private: + QString myHypoSetName; + QStringList myHypoList, myAlgoList; + bool myIsAlgo, myIsCustom; + int myIndex; }; #endif // SMESHGUI_HYPOTHESES_H diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index 5f3500230..d7e3e6ce6 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_HypothesesUtils.cxx // Author : Julia DOROVSKIKH, Open CASCADE S.A.S. @@ -49,8 +50,10 @@ // Qt includes #include +#include //#include + // Other includes #ifdef WNT #include @@ -78,52 +81,87 @@ static int MYDEBUG = 0; namespace SMESH { - typedef QMap THypothesisDataMap; + typedef IMap THypothesisDataMap; THypothesisDataMap myHypothesesMap; THypothesisDataMap myAlgorithmsMap; - - typedef QMap THypCreatorMap; - THypCreatorMap myHypCreatorMap; + + // BUG 0020378 + //typedef QMap THypCreatorMap; + //THypCreatorMap myHypCreatorMap; QList myListOfHypothesesSets; void processHypothesisStatus(const int theHypStatus, - SMESH::SMESH_Hypothesis_ptr theHyp, - const bool theIsAddition) + SMESH::SMESH_Hypothesis_ptr theHyp, + const bool theIsAddition) { if (theHypStatus > SMESH::HYP_OK) { // get Hyp name QString aHypName ("NULL Hypothesis"); if (!CORBA::is_nil(theHyp)) { - _PTR(SObject) Shyp = SMESH::FindSObject(theHyp); - if (Shyp) - // name in study - aHypName = Shyp->GetName().c_str(); - else - // label in xml file - aHypName = GetHypothesisData(theHyp->GetName())->Label; + _PTR(SObject) Shyp = SMESH::FindSObject(theHyp); + if (Shyp) + // name in study + aHypName = Shyp->GetName().c_str(); + else + // label in xml file + aHypName = GetHypothesisData(theHyp->GetName())->Label; } // message bool isFatal = (theHypStatus >= SMESH::HYP_UNKNOWN_FATAL); QString aMsg; if (theIsAddition) - aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN"); + aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN"); else - aMsg = (isFatal ? "SMESH_CANT_RM_HYP" : "SMESH_RM_HYP_WRN"); + aMsg = (isFatal ? "SMESH_CANT_RM_HYP" : "SMESH_RM_HYP_WRN"); aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName) + - QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data()); + QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data()); if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) // PAL18501 aMsg = aMsg.arg( GetHypothesisData(theHyp->GetName())->Dim[0] ); SUIT_MessageBox::warning(SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - aMsg); + QObject::tr("SMESH_WRN_WARNING"), + aMsg); } } + //================================================================================ + /*! + * \brief Prepends dimension and appends '[custom]' to the name of hypothesis set + */ + //================================================================================ + + static QString mangledHypoSetName(HypothesesSet* hypSet) + { + QString name = hypSet->name(); + + // prepend 'xD: ' + int dim = hypSet->maxDim(); + if ( dim > -1 ) + name = QString("%1D: %2").arg(dim).arg(name); + + // custom + if ( hypSet->getIsCustom() ) + name = QString("%1 [custom]").arg(name); + + return name; + } + + //================================================================================ + /*! + * \brief Removes dimension and '[custom]' from the name of hypothesis set + */ + //================================================================================ + + static QString demangledHypoSetName(QString name) + { + name.remove(QRegExp("[0-3]D: ")); + name.remove(" [custom]"); + return name; + } void InitAvailableHypotheses() { @@ -137,72 +175,93 @@ namespace SMESH QString HypsXml; char* cenv = getenv("SMESH_MeshersList"); if (cenv) - HypsXml.sprintf("%s", cenv); + HypsXml.sprintf("%s", cenv); QStringList HypsXmlList = HypsXml.split(":", QString::SkipEmptyParts); if (HypsXmlList.count() == 0) { - SUIT_MessageBox::critical(SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("MESHERS_FILE_NO_VARIABLE")); - return; + SUIT_MessageBox::critical(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("MESHERS_FILE_NO_VARIABLE")); + return; } - - // loop on files in HypsXml - QString aNoAccessFiles; + // get full names of xml files from HypsXmlList + QStringList xmlFiles; + xmlFiles.append( QDir::home().filePath("CustomMeshers.xml")); // may be inexistent for (int i = 0; i < HypsXmlList.count(); i++) { - QString HypsXml = HypsXmlList[ i ]; + QString HypsXml = HypsXmlList[ i ]; - // Find full path to the resource XML file - QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml"); + // Find full path to the resource XML file + QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml"); if ( xmlFile.isEmpty() ) // try PLUGIN resources xmlFile = resMgr->path("resources", HypsXml, HypsXml + ".xml"); - - QFile file (xmlFile); - if (file.exists() && file.open(QIODevice::ReadOnly)) { - file.close(); - - SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler(); - ASSERT(aXmlHandler); - - QXmlInputSource source (&file); - QXmlSimpleReader reader; - reader.setContentHandler(aXmlHandler); - reader.setErrorHandler(aXmlHandler); - bool ok = reader.parse(source); - file.close(); - if (ok) { - myHypothesesMap.unite( aXmlHandler->myHypothesesMap ); - myAlgorithmsMap.unite( aXmlHandler->myAlgorithmsMap ); - QList::iterator it, pos = myListOfHypothesesSets.begin(); - for ( it = aXmlHandler->myListOfHypothesesSets.begin(); - it != aXmlHandler->myListOfHypothesesSets.end(); - ++it ) { - myListOfHypothesesSets.insert( pos, *it ); - } - } - else { - SUIT_MessageBox::critical(SMESHGUI::desktop(), - QObject::tr("INF_PARSE_ERROR"), - QObject::tr(aXmlHandler->errorProtocol().toLatin1().data())); - } - } - else { - if (aNoAccessFiles.isEmpty()) - aNoAccessFiles = xmlFile; - else - aNoAccessFiles += ", " + xmlFile; - } - } // end loop + if ( !xmlFile.isEmpty() ) + xmlFiles.append( xmlFile ); + } + + // loop on xmlFiles + QString aNoAccessFiles; + for (int i = 0; i < xmlFiles.count(); i++) + { + QString xmlFile = xmlFiles[ i ]; + QFile file (xmlFile); + if (file.exists() && file.open(QIODevice::ReadOnly)) + { + file.close(); + + SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler(); + ASSERT(aXmlHandler); + + QXmlInputSource source (&file); + QXmlSimpleReader reader; + reader.setContentHandler(aXmlHandler); + reader.setErrorHandler(aXmlHandler); + bool ok = reader.parse(source); + file.close(); + if (ok) { + + THypothesisDataMap::ConstIterator it1 = aXmlHandler->myHypothesesMap.begin(); + + for( ;it1 != aXmlHandler->myHypothesesMap.end(); it1++) + myHypothesesMap.insert( it1.key(), it1.value() ); + + + it1 = aXmlHandler->myAlgorithmsMap.begin(); + for( ;it1 != aXmlHandler->myAlgorithmsMap.end(); it1++) + myAlgorithmsMap.insert( it1.key(), it1.value() ); + + QList::iterator it, pos = myListOfHypothesesSets.begin(); + for ( it = aXmlHandler->myListOfHypothesesSets.begin(); + it != aXmlHandler->myListOfHypothesesSets.end(); + ++it ) + { + (*it)->setIsCustom( i == 0 ); + myListOfHypothesesSets.insert( pos, *it ); + } + } + else { + SUIT_MessageBox::critical(SMESHGUI::desktop(), + QObject::tr("INF_PARSE_ERROR"), + QObject::tr(aXmlHandler->errorProtocol().toLatin1().data())); + } + delete aXmlHandler; + } + else if ( i > 0 ) { // 1st is ~/CustomMeshers.xml + if (aNoAccessFiles.isEmpty()) + aNoAccessFiles = xmlFile; + else + aNoAccessFiles += ", " + xmlFile; + } + } // end loop on xmlFiles if (!aNoAccessFiles.isEmpty()) { - QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n"; - aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE"); - wc.suspend(); - SUIT_MessageBox::warning(SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - aMess); - wc.resume(); + QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n"; + aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE"); + wc.suspend(); + SUIT_MessageBox::warning(SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + aMess); + wc.resume(); } } } @@ -220,24 +279,25 @@ namespace SMESH bool checkGeometry = ( !isNeedGeometry && isAlgo ); // fill list of hypotheses/algorithms THypothesisDataMap& pMap = isAlgo ? myAlgorithmsMap : myHypothesesMap; - THypothesisDataMap::iterator anIter; + THypothesisDataMap::ConstIterator anIter; for ( anIter = pMap.begin(); anIter != pMap.end(); anIter++ ) { HypothesisData* aData = anIter.value(); + if(!aData || aData->Label.isEmpty()) continue; if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux) { - if (checkGeometry) { - if (aData->IsNeedGeometry == isNeedGeometry) - aHypList.append(anIter.key()); - } - else { - aHypList.append(anIter.key()); - } + if (checkGeometry) { + if (aData->IsNeedGeometry == isNeedGeometry) + aHypList.append(anIter.key()); + } + else { + aHypList.append(anIter.key()); + } } } return aHypList; } - QStringList GetHypothesesSets() + QStringList GetHypothesesSets(int maxDim) { QStringList aSetNameList; @@ -246,26 +306,36 @@ namespace SMESH QList::iterator hypoSet; for ( hypoSet = myListOfHypothesesSets.begin(); - hypoSet != myListOfHypothesesSets.end(); - ++hypoSet ) { + hypoSet != myListOfHypothesesSets.end(); + ++hypoSet ) { HypothesesSet* aSet = *hypoSet; - if ( aSet && aSet->AlgoList.count() ) { - aSetNameList.append( aSet->HypoSetName ); + if ( aSet && + ( aSet->count( true ) || aSet->count( false )) && + aSet->maxDim() <= maxDim) + { + aSetNameList.append( mangledHypoSetName( aSet )); } } + aSetNameList.sort(); + + // reverse order of aSetNameList + QStringList reversedNames; + for ( int i = 0; i < aSetNameList.count(); ++i ) + reversedNames.prepend( aSetNameList[i] ); - return aSetNameList; + return reversedNames; } HypothesesSet* GetHypothesesSet(const QString& theSetName) { + QString name = demangledHypoSetName( theSetName ); QList::iterator hypoSet; for ( hypoSet = myListOfHypothesesSets.begin(); - hypoSet != myListOfHypothesesSets.end(); - ++hypoSet ) { + hypoSet != myListOfHypothesesSets.end(); + ++hypoSet ) { HypothesesSet* aSet = *hypoSet; - if ( aSet && aSet->HypoSetName == theSetName ) - return aSet; + if ( aSet && aSet->name() == name ) + return aSet; } return 0; } @@ -277,10 +347,10 @@ namespace SMESH // Init list of available hypotheses, if needed InitAvailableHypotheses(); - if (myHypothesesMap.find(aHypType) != myHypothesesMap.end()) { + if (myHypothesesMap.contains(aHypType)) { aHypData = myHypothesesMap[aHypType]; } - else if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) { + else if (myAlgorithmsMap.contains(aHypType)) { aHypData = myAlgorithmsMap[aHypType]; } return aHypData; @@ -326,10 +396,12 @@ namespace SMESH SMESHGUI_GenericHypothesisCreator* aCreator = 0; // check, if creator for this hypothesis type already exists - if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) { - aCreator = myHypCreatorMap[aHypType]; - } - else { + // BUG 0020378 + //if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) { + // aCreator = myHypCreatorMap[aHypType]; + //} + //else + { // 1. Init list of available hypotheses, if needed InitAvailableHypotheses(); @@ -337,52 +409,60 @@ namespace SMESH HypothesisData* aHypData = GetHypothesisData(aHypType); if (!aHypData) return aCreator; + QString aClientLibName = aHypData->ClientLibName; QString aServerLibName = aHypData->ServerLibName; // 3. Load Client Plugin Library try { - // load plugin library - if(MYDEBUG) MESSAGE("Loading client meshers plugin library ..."); - LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() ); - if (!libHandle) { - // report any error, if occured - if ( MYDEBUG ) { + // load plugin library + if(MYDEBUG) MESSAGE("Loading client meshers plugin library ..."); + LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() ); + if (!libHandle) { + // report any error, if occured + if ( MYDEBUG ) { #ifdef WIN32 - const char* anError = "Can't load client meshers plugin library"; + const char* anError = "Can't load client meshers plugin library"; #else - const char* anError = dlerror(); + const char* anError = dlerror(); #endif - MESSAGE(anError); - } - } - else { - // get method, returning hypothesis creator - if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ..."); - typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \ - ( const QString& ); - GetHypothesisCreator procHandle = - (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator"); - if (!procHandle) { - if(MYDEBUG) MESSAGE("bad hypothesis client plugin library"); - UnLoadLib(libHandle); - } - else { - // get hypothesis creator - if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data()); - aCreator = procHandle( aHypType ); - if (!aCreator) { - if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin"); - } - else { - // map hypothesis creator to a hypothesis name - myHypCreatorMap[aHypType] = aCreator; - } - } - } + MESSAGE(anError); + } + } + else { + // get method, returning hypothesis creator + if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ..."); + typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \ + ( const QString& ); + GetHypothesisCreator procHandle = + (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator"); + if (!procHandle) { + if(MYDEBUG) MESSAGE("bad hypothesis client plugin library"); + UnLoadLib(libHandle); + } + else { + // get hypothesis creator + if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data()); + aCreator = procHandle( aHypType ); + if (!aCreator) { + if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin"); + } + else { + // map hypothesis creator to a hypothesis name + // BUG 0020378 + //myHypCreatorMap[aHypType] = aCreator; + + //rnv : This dynamic property of the QObject stores the name of the plugin. + // It is used to obtain plugin root dir environment variable + // in the SMESHGUI_HypothesisDlg class. Plugin root dir environment + // variable is used to display documentation. + aCreator->setProperty(PLUGIN_NAME,aHypData->PluginName); + } + } + } } catch (const SALOME::SALOME_Exception& S_ex) { - SalomeApp_Tools::QtCatchCorbaException(S_ex); + SalomeApp_Tools::QtCatchCorbaException(S_ex); } } @@ -391,25 +471,26 @@ namespace SMESH SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const QString& aHypType, - const QString& aHypName, - const bool isAlgo) + const QString& aHypName, + const bool isAlgo) { if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() << - " with name " << aHypName.toLatin1().data()); + " with name " << aHypName.toLatin1().data()); HypothesisData* aHypData = GetHypothesisData(aHypType); QString aServLib = aHypData->ServerLibName; try { SMESH::SMESH_Hypothesis_var aHypothesis; aHypothesis = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType.toLatin1().data(), - aServLib.toLatin1().data()); + aServLib.toLatin1().data()); if (!aHypothesis->_is_nil()) { - _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in()); - if (aHypSObject) { - if (!aHypName.isEmpty()) - SMESH::SetName(aHypSObject, aHypName); - SMESHGUI::GetSMESHGUI()->updateObjBrowser(); - return aHypothesis._retn(); - } + _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in()); + if (aHypSObject) { + if (!aHypName.isEmpty()) + SMESH::SetName(aHypSObject, aHypName); + SMESHGUI::Modified(); + SMESHGUI::GetSMESHGUI()->updateObjBrowser(); + return aHypothesis._retn(); + } } } catch (const SALOME::SALOME_Exception & S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); @@ -429,23 +510,23 @@ namespace SMESH _PTR(SObject) SM = SMESH::FindSObject(aMesh); GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM); try { - res = aMesh->AddHypothesis(aShapeObject, aHyp); - if (res < SMESH::HYP_UNKNOWN_FATAL) { - _PTR(SObject) aSH = SMESH::FindSObject(aHyp); - if (SM && aSH) { - SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0); - } - } - if (res > SMESH::HYP_OK) { - wc.suspend(); - processHypothesisStatus(res, aHyp, true); - wc.resume(); - } + res = aMesh->AddHypothesis(aShapeObject, aHyp); + if (res < SMESH::HYP_UNKNOWN_FATAL) { + _PTR(SObject) aSH = SMESH::FindSObject(aHyp); + if (SM && aSH) { + SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0); + } + } + if (res > SMESH::HYP_OK) { + wc.suspend(); + processHypothesisStatus(res, aHyp, true); + wc.resume(); + } } catch(const SALOME::SALOME_Exception& S_ex) { - wc.suspend(); - SalomeApp_Tools::QtCatchCorbaException(S_ex); - res = SMESH::HYP_UNKNOWN_FATAL; + wc.suspend(); + SalomeApp_Tools::QtCatchCorbaException(S_ex); + res = SMESH::HYP_UNKNOWN_FATAL; } } return res < SMESH::HYP_UNKNOWN_FATAL; @@ -460,33 +541,33 @@ namespace SMESH if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) { try { - SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); - _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh); - GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM); - if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) { - res = aMesh->AddHypothesis(aShapeObject, aHyp); - if (res < SMESH::HYP_UNKNOWN_FATAL) { + SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather(); + _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh); + GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM); + if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) { + res = aMesh->AddHypothesis(aShapeObject, aHyp); + if (res < SMESH::HYP_UNKNOWN_FATAL) { _PTR(SObject) meshSO = SMESH::FindSObject(aMesh); if (meshSO) SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); - } - if (res > SMESH::HYP_OK) { - wc.suspend(); - processHypothesisStatus(res, aHyp, true); - wc.resume(); - } - } - else { - SCRUTE(aHyp->_is_nil()); - SCRUTE(aMesh->_is_nil()); - SCRUTE(!SsubM); - SCRUTE(aShapeObject->_is_nil()); - } + } + if (res > SMESH::HYP_OK) { + wc.suspend(); + processHypothesisStatus(res, aHyp, true); + wc.resume(); + } + } + else { + SCRUTE(aHyp->_is_nil()); + SCRUTE(aMesh->_is_nil()); + SCRUTE(!SsubM); + SCRUTE(aShapeObject->_is_nil()); + } } catch(const SALOME::SALOME_Exception& S_ex) { - wc.suspend(); - SalomeApp_Tools::QtCatchCorbaException(S_ex); - res = SMESH::HYP_UNKNOWN_FATAL; + wc.suspend(); + SalomeApp_Tools::QtCatchCorbaException(S_ex); + res = SMESH::HYP_UNKNOWN_FATAL; } } else { @@ -505,28 +586,28 @@ namespace SMESH _PTR(Study) aStudy = GetActiveStudyDocument(); _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() ); if( aHypObj ) - { - _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj ); - _PTR(SObject) aRealHypo; - if( aHypObj->ReferencedObject( aRealHypo ) ) - { - SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) ); - RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo ); - } - else - { - SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) ); - SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo ); - for( int i = 0; i < meshList.size(); i++ ) - RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo ); - } - } + { + _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj ); + _PTR(SObject) aRealHypo; + if( aHypObj->ReferencedObject( aRealHypo ) ) + { + SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) ); + RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo ); + } + else + { + SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) ); + SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo ); + for( int i = 0; i < meshList.size(); i++ ) + RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo ); + } + } } catch(const SALOME::SALOME_Exception& S_ex) { - wc.suspend(); - SalomeApp_Tools::QtCatchCorbaException(S_ex); - res = SMESH::HYP_UNKNOWN_FATAL; + wc.suspend(); + SalomeApp_Tools::QtCatchCorbaException(S_ex); + res = SMESH::HYP_UNKNOWN_FATAL; } return res < SMESH::HYP_UNKNOWN_FATAL; } @@ -560,7 +641,7 @@ namespace SMESH } else if(!aMesh->HasShapeToMesh()){ res = aMesh->RemoveHypothesis(aShapeObject, anHyp); - if (res < SMESH::HYP_UNKNOWN_FATAL) { + if (res < SMESH::HYP_UNKNOWN_FATAL) { _PTR(SObject) meshSO = SMESH::FindSObject(aMesh); if (meshSO) SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); @@ -573,9 +654,9 @@ namespace SMESH } } } catch(const SALOME::SALOME_Exception& S_ex) { - wc.suspend(); - SalomeApp_Tools::QtCatchCorbaException(S_ex); - res = SMESH::HYP_UNKNOWN_FATAL; + wc.suspend(); + SalomeApp_Tools::QtCatchCorbaException(S_ex); + res = SMESH::HYP_UNKNOWN_FATAL; } } return res < SMESH::HYP_UNKNOWN_FATAL; @@ -590,25 +671,25 @@ namespace SMESH if (!AlgoOrHyp->_is_nil()) { _PTR(SObject) SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp); if (SO_Hypothesis) { - SObjectList listSO = - SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis); - - if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<GetFather(); - if (aFather) { - _PTR(SObject) SOfatherFather = aFather->GetFather(); - if (SOfatherFather) { - if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list"); - index++; - listSOmesh.resize(index); - listSOmesh[index - 1] = SOfatherFather; - } - } - } - } + SObjectList listSO = + SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis); + + if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<GetFather(); + if (aFather) { + _PTR(SObject) SOfatherFather = aFather->GetFather(); + if (SOfatherFather) { + if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list"); + index++; + listSOmesh.resize(index); + listSOmesh[index - 1] = SOfatherFather; + } + } + } + } } } if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed"); diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h index 18813f4c8..c1e485313 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_HypothesesUtils.h // Author : Julia DOROVSKIKH, Open CASCADE S.A.S. @@ -47,12 +48,18 @@ // STL includes #include +// boost includes +#include + class HypothesisData; class HypothesesSet; class SMESHGUI_GenericHypothesisCreator; class SALOMEDSClient_SObject; class algo_error_array; + +#define PLUGIN_NAME "PLUGIN_NAME" + namespace SMESH { SMESHGUI_EXPORT @@ -62,9 +69,9 @@ namespace SMESH QStringList GetAvailableHypotheses( const bool, const int = -1, const bool = false, - const bool = true); + const bool = true); SMESHGUI_EXPORT - QStringList GetHypothesesSets(); + QStringList GetHypothesesSets( int maxDim ); SMESHGUI_EXPORT HypothesesSet* GetHypothesesSet( const QString& ); @@ -74,20 +81,20 @@ namespace SMESH SMESHGUI_EXPORT bool IsAvailableHypothesis( const HypothesisData*, - const QString&, - bool& ); + const QString&, + bool& ); SMESHGUI_EXPORT bool IsCompatibleAlgorithm( const HypothesisData*, - const HypothesisData* ); + const HypothesisData* ); SMESHGUI_EXPORT SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator( const QString& ); SMESHGUI_EXPORT SMESH::SMESH_Hypothesis_ptr CreateHypothesis( const QString&, - const QString&, - const bool = false); + const QString&, + const bool = false ); SMESHGUI_EXPORT bool AddHypothesisOnMesh( SMESH::SMESH_Mesh_ptr, SMESH::SMESH_Hypothesis_ptr ); @@ -100,7 +107,7 @@ namespace SMESH SMESHGUI_EXPORT bool RemoveHypothesisOrAlgorithmOnMesh( _PTR(SObject), - SMESH::SMESH_Hypothesis_ptr ); + SMESH::SMESH_Hypothesis_ptr ); typedef std::vector<_PTR(SObject)> SObjectList; SObjectList GetMeshesUsingAlgoOrHypothesis( SMESH::SMESH_Hypothesis_ptr ); diff --git a/src/SMESHGUI/SMESHGUI_IdValidator.h b/src/SMESHGUI/SMESHGUI_IdValidator.h index 66dcd6322..b6b06db0b 100644 --- a/src/SMESHGUI/SMESHGUI_IdValidator.h +++ b/src/SMESHGUI/SMESHGUI_IdValidator.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_IdValidator.h // Author : Edward AGAPOV, Open CASCADE S.A.S. @@ -47,15 +48,15 @@ public: // truncate extra ids int ind = 0, nbId = 0; while ( ind < input.length() ) { - if ( input.at( ind ) != ' ' ) { - if ( ++nbId > myMaxNbId ) { - input.truncate( ind ); - break; - } - ind = input.indexOf( ' ', ind ); - if ( ind < 0 ) break; - } - ind++; + if ( input.at( ind ) != ' ' ) { + if ( ++nbId > myMaxNbId ) { + input.truncate( ind ); + break; + } + ind = input.indexOf( ' ', ind ); + if ( ind < 0 ) break; + } + ind++; } } if ( pos > input.length() ) diff --git a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx new file mode 100644 index 000000000..8cdc5b0ec --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx @@ -0,0 +1,529 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_Make2DFrom3D.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#include "SMESHGUI_Make2DFrom3DOp.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESH_TypeFilter.hxx" +#include "SMESH_LogicalFilter.hxx" +#include "SMESHGUI_VTKUtils.h" +#include "SMESH_Actor.h" + +// SALOME GUI includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) + +// Qt includes +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SPACING 6 +#define MARGIN 11 + +/*! + \class SMESHGUI_Make2DFrom3DDlg + \brief Copy Mesh dialog box +*/ + +SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent ) + : SMESHGUI_Dialog( parent, false, true, OK | Apply | Close | Help ) +{ + // title + setWindowTitle( tr("CAPTION") ); + + // mode + QGroupBox* aModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() ); + QHBoxLayout* aModeGrpLayout = new QHBoxLayout( aModeGrp ); + aModeGrpLayout->setMargin( MARGIN ); + aModeGrpLayout->setSpacing( SPACING ); + my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), aModeGrp ); + my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), aModeGrp ); + //my1dFrom3dRB = new QRadioButton( tr( "1D_FROM_3D" ), aModeGrp ); + aModeGrpLayout->addWidget( my2dFrom3dRB ); + aModeGrpLayout->addWidget( my1dFrom2dRB ); + //aModeGrpLayout->addWidget( my1dFrom3dRB ); + +// // Groups of mesh faces +// setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) ); +// createObject( tr( "Groups" ), mainFrame(), Groups ); +// setNameIndication( Groups, ListOfNames ); +// objectWg( Groups, Btn )->hide(); + + // Mesh or Groups + //setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) ); + createObject( tr( "Groups" ), mainFrame(), MeshOrGroups ); + setNameIndication( MeshOrGroups, ListOfNames ); + objectWg( MeshOrGroups, Btn )->hide(); + + // target + QGroupBox* aTargetGrp = new QGroupBox( tr( "TARGET" ), mainFrame() ); + QGridLayout* aTargetGrpLayout = new QGridLayout( aTargetGrp ); + aTargetGrpLayout->setMargin( MARGIN ); + aTargetGrpLayout->setSpacing( SPACING ); + myThisMeshRB = new QRadioButton( tr( "THIS_MESH" ), aTargetGrp ); + myNewMeshRB = new QRadioButton( tr( "NEW_MESH" ), aTargetGrp ); + myMeshName = new QLineEdit( aTargetGrp ); + myCopyCheck = new QCheckBox( tr( "COPY_SRC" ), aTargetGrp ); + aTargetGrpLayout->addWidget( myThisMeshRB, 0, 0 ); + aTargetGrpLayout->addWidget( myNewMeshRB, 1, 0 ); + aTargetGrpLayout->addWidget( myMeshName, 1, 1 ); + aTargetGrpLayout->addWidget( myCopyCheck, 2, 0 ); + myGroupCheck = new QCheckBox( tr( "CREATE_GROUP" ), mainFrame() ); + myGroupName = new QLineEdit( mainFrame() ); + + // layout + QGridLayout* aDlgLay = new QGridLayout( mainFrame() ); + aDlgLay->setMargin( 0 ); + aDlgLay->setSpacing( SPACING ); + aDlgLay->addWidget( aModeGrp, 0, 0, 1, 3 ); + aDlgLay->addWidget( objectWg( MeshOrGroups, Label ), 1, 0 ); + aDlgLay->addWidget( objectWg( MeshOrGroups, Control ), 1, 1 ); + aDlgLay->addWidget( aTargetGrp, 2, 0, 1, 3 ); + aDlgLay->addWidget( myGroupCheck, 3, 0 ); + aDlgLay->addWidget( myGroupName, 3, 1, 1, 2 ); + + // connect signals + connect( myThisMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) ); + connect( myNewMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) ); + connect( myGroupCheck, SIGNAL( clicked() ), this, SLOT( onGroupChecked() ) ); + + // init dlg + my2dFrom3dRB->setChecked( true ); + myThisMeshRB->setChecked( true ); + onTargetChanged(); + onGroupChecked(); +} + +SMESHGUI_Make2DFrom3DDlg::~SMESHGUI_Make2DFrom3DDlg() +{ +} + +SMESH::Bnd_Dimension SMESHGUI_Make2DFrom3DDlg::mode() const +{ + if ( my2dFrom3dRB->isChecked() ) + return SMESH::BND_2DFROM3D; + else if ( my1dFrom2dRB->isChecked() ) + return SMESH::BND_1DFROM2D; + else + return SMESH::BND_1DFROM3D; +} + +bool SMESHGUI_Make2DFrom3DDlg::needNewMesh() const +{ + return myNewMeshRB->isChecked(); +} + +QString SMESHGUI_Make2DFrom3DDlg::getNewMeshName() const +{ + return myMeshName->text().trimmed(); +} + +void SMESHGUI_Make2DFrom3DDlg::setNewMeshName( const QString& name ) +{ + myMeshName->setText( name ); +} + +void SMESHGUI_Make2DFrom3DDlg::setNewMeshEnabled( bool enable ) +{ + if ( !enable ) + myThisMeshRB->setChecked( true ); + + myNewMeshRB->setEnabled( enable ); + + onTargetChanged(); +} + +bool SMESHGUI_Make2DFrom3DDlg::getNewMeshEnabled() const +{ + return myNewMeshRB->isEnabled(); +} + +bool SMESHGUI_Make2DFrom3DDlg::needGroup() const +{ + return myGroupCheck->isChecked(); +} + +QString SMESHGUI_Make2DFrom3DDlg::getGroupName() const +{ + return myGroupName->text().trimmed(); +} + +void SMESHGUI_Make2DFrom3DDlg::setGroupName( const QString& name ) +{ + myGroupName->setText( name ); +} + +bool SMESHGUI_Make2DFrom3DDlg::copySource() const +{ + return myCopyCheck->isChecked(); +} + +void SMESHGUI_Make2DFrom3DDlg::onTargetChanged() +{ + myMeshName->setEnabled( myNewMeshRB->isChecked() ); + myCopyCheck->setEnabled( myNewMeshRB->isChecked() ); +} + +void SMESHGUI_Make2DFrom3DDlg::onGroupChecked() +{ + myGroupName->setEnabled( myGroupCheck->isChecked() ); +} + +/*! + \class SMESHGUI_Make2DFrom3DOp + \brief Copy Mesh operation class +*/ + +SMESHGUI_Make2DFrom3DOp::SMESHGUI_Make2DFrom3DOp() + : SMESHGUI_SelectionOp(), + myMeshFilter(MESH), + myGroupFilter(GROUP) +{ +} + +SMESHGUI_Make2DFrom3DOp::~SMESHGUI_Make2DFrom3DOp() +{ + if ( myDlg ) + delete myDlg; +} + +LightApp_Dialog* SMESHGUI_Make2DFrom3DOp::dlg() const +{ + return myDlg; +} + +void SMESHGUI_Make2DFrom3DOp::startOperation() +{ + if( !myDlg ) + myDlg = new SMESHGUI_Make2DFrom3DDlg( desktop() ); + + myHelpFileName = "make_2dmesh_from_3d_page.html"; + + SMESHGUI_SelectionOp::startOperation(); + + myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) ); + myDlg->setGroupName( SMESH::UniqueName( "Group" ) ); + myDlg->show(); + + connect( myDlg->my2dFrom3dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) ); + connect( myDlg->my1dFrom2dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) ); + //connect( myDlg->my1dFrom3dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) ); + + //onModeChanged(); + + myDlg->activateObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups ); + selectionDone(); +} + +//================================================================================ +/*! + * \brief Set filter corresponding to dimension + */ +//================================================================================ + +void SMESHGUI_Make2DFrom3DOp::onModeChanged() +{ +// QRadioButton* b = dynamic_cast( sender()); +// if ( b && !b->isChecked() ) +// return; + +// // enable "2D groups" field +// bool enableGroups = ( myDlg->mode() == SMESH::BND_1DFROM3D ); +// myDlg->setObjectEnabled( SMESHGUI_Make2DFrom3DDlg::Groups, enableGroups ); +// ((QToolButton*) myDlg->objectWg( SMESHGUI_Make2DFrom3DDlg::Groups, +// SMESHGUI_Make2DFrom3DDlg::Btn ))->setChecked( enableGroups ); + +// // install filter +// int id = enableGroups ? SMESHGUI_Make2DFrom3DDlg::Groups : SMESHGUI_Make2DFrom3DDlg::Mesh; +// onDeactivateObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups ); +// onActivateObject ( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups ); +// selectionDone(); +} + +void SMESHGUI_Make2DFrom3DOp::selectionDone() +{ + myDlg->clearSelection( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups ); + mySrcMesh = SMESH::SMESH_Mesh::_nil(); + + if ( !dlg() ) return; + + + if ( dlg()->isVisible() ) { + try { + QStringList names, ids; + LightApp_Dialog::TypesList types; + selected( names, types, ids ); + for ( int i = 0; i < names.count(); ++i ) + names[i] = names[i].trimmed(); + myDlg->selectObject( names, types, ids ); + + // enable/desable "new mesh" button + bool isMesh = true; + for ( int i = 0; i < ids.count() && isMesh; ++i ) + { + _PTR(SObject) sobj = + SMESHGUI::activeStudy()->studyDS()->FindObjectID( ids[i].toLatin1().constData() ); + mySrcMesh = SMESH::SObjectToInterface( sobj ); + isMesh = !mySrcMesh->_is_nil(); + } + myDlg->setNewMeshEnabled( isMesh ); + } + catch ( const SALOME::SALOME_Exception& S_ex ) { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + } + catch ( ... ) { + } + } +} + +SUIT_SelectionFilter* SMESHGUI_Make2DFrom3DOp::createFilter( const int theId ) const +{ + SMESHGUI_Make2DFrom3DOp* me = (SMESHGUI_Make2DFrom3DOp*) this; + + QList subFilters; + subFilters.append( & me->myMeshFilter ); + subFilters.append( & me->myGroupFilter ); + + SUIT_SelectionFilter* f = new SMESH_LogicalFilter( subFilters, SMESH_LogicalFilter::LO_OR ); + return f; +} + +bool SMESHGUI_Make2DFrom3DOp::isValid( QString& msg ) const +{ + if ( !dlg() ) return false; + + // check if a mesh is selected + if ( !myDlg->hasSelection( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups )) + { + msg = tr( "SMESH_ERR_NO_INPUT_MESH" ); + return false; + } + QStringList entries; + dlg()->selectedObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups, entries ); + const bool isMeshSelected = ( !mySrcMesh->_is_nil() ); + if ( isMeshSelected ) + { + // only one mesh is allowed + if ( entries.size() > 1 ) { + msg = tr( "SMESH_TOO_MANY_MESHES" ); + return false; + } + } + else + { + // check if only groups are selected + for ( int i = 0; i < entries.count(); ++i ) + { + SMESH::SMESH_GroupBase_var grp; + if ( _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[i].toLatin1().constData() )) + grp = SMESH::SObjectToInterface( sobj ); + if ( grp->_is_nil() ) { + msg = tr( "SMESH_NOT_ONLY_GROUPS" ); + return false; + } + } + } + // check if the selected objects contains elements of required type + bool hasFaces = false, hasVolumes = false; + SMESH::Bnd_Dimension mode = myDlg->mode(); + for ( int i = 0; i < entries.count(); ++i ) + { + SMESH::SMESH_IDSource_var idSource; + if ( _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[i].toLatin1().constData() )) + idSource = SMESH::SObjectToInterface( sobj ); + if ( !idSource->_is_nil() ) { + SMESH::array_of_ElementType_var types = idSource->GetTypes(); + for ( int j = 0; j < types->length(); ++j ) + if ( types[j] == SMESH::VOLUME ) + hasVolumes = true; + else if ( types[j] == SMESH::FACE ) + hasFaces = true; + } + } + if ( mode == SMESH::BND_2DFROM3D && !hasVolumes ) { + msg = tr( "SMESH_ERR_NO_3D_ELEMENTS" ); + return false; + } + else if ( mode == SMESH::BND_1DFROM2D && !hasFaces ) { + msg = tr( "SMESH_ERR_NO_2D_ELEMENTS" ); + return false; + } + + // check if new mesh name is specified + if ( myDlg->needNewMesh() && myDlg->getNewMeshName().isEmpty() ) { + msg = tr( "SMESH_ERR_MESH_NAME_NOT_SPECIFIED" ); + return false; + } + + // check if group name is specified + if ( myDlg->needGroup() && myDlg->getGroupName().isEmpty() ) { + msg = tr( "SMESH_ERR_GRP_NAME_NOT_SPECIFIED" ); + return false; + } + + return true; +} + +bool SMESHGUI_Make2DFrom3DOp::compute2DMesh( QStringList& theEntryList ) +{ + SUIT_OverrideCursor wc; + + bool ok = false; + try { + SMESH::Bnd_Dimension mode = myDlg->mode(); + QString meshName = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString(); + QString groupName = myDlg->needGroup() ? myDlg->getGroupName() : QString(); + bool copyAll = myDlg->copySource(); + + QStringList entries; + dlg()->selectedObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups, entries ); + SMESH::ListOfIDSources_var groups = new SMESH::ListOfIDSources; + QString wrongGroups = ""; + + if ( mySrcMesh->_is_nil() ) // get selected groups, find groups of wrong type + { + int nbGroups = 0; + int goodType = ( mode == SMESH::BND_2DFROM3D ? SMESH::VOLUME : SMESH::FACE ); + groups->length( entries.count() ); + for ( int i = 0; i < entries.count(); ++i ) + { + _PTR(SObject) sobj = + SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[i].toLatin1().constData() ); + SMESH::SMESH_IDSource_var grp = SMESH::SObjectToInterface( sobj ); + SMESH::array_of_ElementType_var types = grp->GetTypes(); + if ( types->length() < 1 || types[0] != goodType ) + { + if ( !wrongGroups.isEmpty() ) + wrongGroups += ", "; + wrongGroups += sobj->GetName().c_str(); + } + else + { + groups[ nbGroups++ ] = grp; + } + } + groups->length( nbGroups ); + mySrcMesh = groups[0]->GetMesh(); + } + + if ( !CORBA::is_nil( mySrcMesh ) ) { + SMESH::SMESH_MeshEditor_var aMeshEditor = mySrcMesh->GetMeshEditor(); + SMESH::SMESH_Group_var newGrp; + SMESH::SMESH_Mesh_var newMesh; + CORBA::Long nbAdded = aMeshEditor->MakeBoundaryElements( mode, + groupName.toLatin1().constData(), + meshName.toLatin1().constData(), + copyAll, + groups, + newMesh.out(), + newGrp.out() ); + QString msg = tr("NB_ADDED").arg( nbAdded ); + if ( !wrongGroups.isEmpty() ) + msg += ".\n" + tr("WRONG_GROUPS").arg( wrongGroups ); + SUIT_MessageBox::information( myDlg, tr("SMESH_INFORMATION"), msg); + + if ( !newMesh->_is_nil() ) { + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) ) + theEntryList.append( aSObject->GetID().c_str() ); +#ifdef WITHGENERICOBJ + newMesh->UnRegister(); +#endif + } + if ( !newGrp->_is_nil() ) { +#ifdef WITHGENERICOBJ + newGrp->UnRegister(); +#endif + } + ok = true; + + for ( int i = 0; i < entries.count(); ++i ) + if ( SMESH_Actor* actor = SMESH::FindActorByEntry( entries[i].toLatin1().constData() )) + SMESH::Update(actor->getIO(),actor->GetVisibility()); + SMESH::RepaintCurrentView(); + } + } + catch ( ... ) { + } + return ok; +} + +bool SMESHGUI_Make2DFrom3DOp::onApply() +{ + if ( isStudyLocked() ) + return false; + + QString msg; + if ( !isValid( msg ) ) { + dlg()->show(); + if ( msg != "" ) + SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), msg ); + return false; + } + + QStringList anEntryList; + bool res = false; + try { + res = compute2DMesh( anEntryList ); + } + catch ( const SALOME::SALOME_Exception& S_ex ) { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + } + catch ( ... ) { + } + + if ( res ) { + SMESHGUI::Modified(); + update( UF_ObjBrowser | UF_Model ); + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); + myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) ); + myDlg->setGroupName( SMESH::UniqueName( "Group" ) ); + } + else { + SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ) ); + } + + return res; +} diff --git a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h new file mode 100644 index 000000000..79ea60c42 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h @@ -0,0 +1,121 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_Make2DFrom3D.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#ifndef SMESHGUI_Make2DFrom3DOp_H +#define SMESHGUI_Make2DFrom3DOp_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" +#include "SMESHGUI_Dialog.h" +#include "SMESHGUI_SelectionOp.h" +#include "SMESH_TypeFilter.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QCheckBox; +class QLineEdit; +class QRadioButton; +class SMESHGUI_Make2DFrom3DOp; + +/*! + * \brief Dialog to show result mesh statistic + */ + +class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DDlg : public SMESHGUI_Dialog +{ + Q_OBJECT + +public: + enum { MeshOrGroups }; + + SMESHGUI_Make2DFrom3DDlg( QWidget* ); + virtual ~SMESHGUI_Make2DFrom3DDlg(); + + SMESH::Bnd_Dimension mode() const; + + bool needNewMesh() const; + QString getNewMeshName() const; + void setNewMeshName( const QString& ); + void setNewMeshEnabled( bool ); + bool getNewMeshEnabled() const; + + bool needGroup() const; + QString getGroupName() const; + void setGroupName( const QString& ); + + bool copySource() const; + +private slots: + void onTargetChanged(); + void onGroupChecked(); + +private: + QRadioButton* my2dFrom3dRB; + QRadioButton* my1dFrom2dRB; + QRadioButton* my1dFrom3dRB; + QRadioButton* myThisMeshRB; + QRadioButton* myNewMeshRB; + QLineEdit* myMeshName; + QCheckBox* myCopyCheck; + QCheckBox* myGroupCheck; + QLineEdit* myGroupName; + + friend class SMESHGUI_Make2DFrom3DOp; +}; + +/*! + * \brief Operation to compute 2D mesh on 3D + */ + +class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DOp : public SMESHGUI_SelectionOp +{ + Q_OBJECT + +public: + SMESHGUI_Make2DFrom3DOp(); + virtual ~SMESHGUI_Make2DFrom3DOp(); + + virtual LightApp_Dialog* dlg() const; + +protected: + virtual void startOperation(); + virtual void selectionDone(); + virtual SUIT_SelectionFilter* createFilter( const int ) const; + bool isValid( QString& ) const; + +protected slots: + virtual bool onApply(); + void onModeChanged(); + +private: + bool compute2DMesh( QStringList& ); + +private: + SMESH::SMESH_Mesh_var mySrcMesh; + QPointer myDlg; + + SMESH_TypeFilter myMeshFilter; + SMESH_TypeFilter myGroupFilter; +}; + +#endif // SMESHGUI_Make2DFrom3DOp_H diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx index ac654fdd6..090a385cc 100644 --- a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_MakeNodeAtPointDlg.cxx // Author : Edward AGAPOV, Open CASCADE S.A.S. // SMESH includes @@ -46,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -91,7 +93,7 @@ SMESHGUI_MakeNodeAtPointDlg::SMESHGUI_MakeNodeAtPointDlg() setWindowTitle(tr("CAPTION")); QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); - aDlgLay->setMargin(MARGIN);; + aDlgLay->setMargin(0); aDlgLay->setSpacing(SPACING); QWidget* aMainFrame = createMainFrame (mainFrame()); @@ -115,7 +117,7 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) // constructor - QGroupBox* aPixGrp = new QGroupBox(tr("MESH_PASS_THROUGH_POINT"), aFrame); + QGroupBox* aPixGrp = new QGroupBox(tr("MOVE_NODE"), aFrame); QButtonGroup* aBtnGrp = new QButtonGroup(this); QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp); aPixGrpLayout->setMargin(MARGIN); @@ -129,7 +131,7 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) // coordinates - QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame); + QGroupBox* aCoordGrp = new QGroupBox(tr("DESTINATION"), aFrame); QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp); aCoordGrpLayout->setMargin(MARGIN); aCoordGrpLayout->setSpacing(SPACING); @@ -147,9 +149,9 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp); myZ = new SMESHGUI_SpinBox(aCoordGrp); - myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); - myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); - myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); aCoordGrpLayout->addWidget(myCoordBtn); aCoordGrpLayout->addWidget(aXLabel); @@ -158,19 +160,9 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) aCoordGrpLayout->addWidget(myY); aCoordGrpLayout->addWidget(aZLabel); aCoordGrpLayout->addWidget(myZ); - - // Method selection - - QGroupBox* aMethodGrp = new QGroupBox(tr("METHOD"), aFrame); - QHBoxLayout* aMethodGrpLayout = new QHBoxLayout(aMethodGrp); - aMethodGrpLayout->setMargin(MARGIN); - aMethodGrpLayout->setSpacing(SPACING); - - myMoveRBtn = new QRadioButton(tr("MOVE_EXISTING_METHOD"), aMethodGrp); - myCreateRBtn = new QRadioButton(tr("CREATE_NEW_METHOD"), aMethodGrp); - - aMethodGrpLayout->addWidget(myMoveRBtn); - aMethodGrpLayout->addWidget(myCreateRBtn); + aCoordGrpLayout->setStretchFactor(myX, 1); + aCoordGrpLayout->setStretchFactor(myY, 1); + aCoordGrpLayout->setStretchFactor(myZ, 1); // node ID @@ -182,6 +174,65 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) myIdBtn->setCheckable(true); myId = new QLineEdit(myNodeToMoveGrp); myId->setValidator(new SMESHGUI_IdValidator(this, 1)); + + QWidget* aCoordWidget = new QWidget(myNodeToMoveGrp); + + QLabel* aCurrentXLabel = new QLabel(tr("SMESH_X"), aCoordWidget); + myCurrentX = new SMESHGUI_SpinBox(aCoordWidget); + myCurrentX->setButtonSymbols(QAbstractSpinBox::NoButtons); + myCurrentX->setReadOnly(true); + + QLabel* aCurrentYLabel = new QLabel(tr("SMESH_Y"), aCoordWidget); + myCurrentY = new SMESHGUI_SpinBox(aCoordWidget); + myCurrentY->setButtonSymbols(QAbstractSpinBox::NoButtons); + myCurrentY->setReadOnly(true); + + QLabel* aCurrentZLabel = new QLabel(tr("SMESH_Z"), aCoordWidget); + myCurrentZ = new SMESHGUI_SpinBox(aCoordWidget); + myCurrentZ->setButtonSymbols(QAbstractSpinBox::NoButtons); + myCurrentZ->setReadOnly(true); + + QLabel* aDXLabel = new QLabel(tr("SMESH_DX"), aCoordWidget); + myDX = new SMESHGUI_SpinBox(aCoordWidget); + myDX->setButtonSymbols(QAbstractSpinBox::NoButtons); + myDX->setReadOnly(true); + + QLabel* aDYLabel = new QLabel(tr("SMESH_DY"), aCoordWidget); + myDY = new SMESHGUI_SpinBox(aCoordWidget); + myDY->setButtonSymbols(QAbstractSpinBox::NoButtons); + myDY->setReadOnly(true); + + QLabel* aDZLabel = new QLabel(tr("SMESH_DZ"), aCoordWidget); + myDZ = new SMESHGUI_SpinBox(aCoordWidget); + myDZ->setButtonSymbols(QAbstractSpinBox::NoButtons); + myDZ->setReadOnly(true); + + myCurrentX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myCurrentY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myCurrentZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + + QGridLayout* aCoordLayout = new QGridLayout(aCoordWidget); + aCoordLayout->setMargin(0); + aCoordLayout->setSpacing(SPACING); + aCoordLayout->addWidget(aCurrentXLabel, 0, 0); + aCoordLayout->addWidget(myCurrentX, 0, 1); + aCoordLayout->addWidget(aCurrentYLabel, 0, 2); + aCoordLayout->addWidget(myCurrentY, 0, 3); + aCoordLayout->addWidget(aCurrentZLabel, 0, 4); + aCoordLayout->addWidget(myCurrentZ, 0, 5); + aCoordLayout->addWidget(aDXLabel, 1, 0); + aCoordLayout->addWidget(myDX, 1, 1); + aCoordLayout->addWidget(aDYLabel, 1, 2); + aCoordLayout->addWidget(myDY, 1, 3); + aCoordLayout->addWidget(aDZLabel, 1, 4); + aCoordLayout->addWidget(myDZ, 1, 5); + aCoordLayout->setColumnStretch(1, 1); + aCoordLayout->setColumnStretch(3, 1); + aCoordLayout->setColumnStretch(5, 1); + myAutoSearchChkBox = new QCheckBox( tr("AUTO_SEARCH"), myNodeToMoveGrp); myPreviewChkBox = new QCheckBox( tr("PREVIEW"), myNodeToMoveGrp); @@ -192,23 +243,20 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) myNodeToMoveGrpLayout->addWidget( idLabel, 0, 0 ); myNodeToMoveGrpLayout->addWidget( myIdBtn, 0, 1 ); myNodeToMoveGrpLayout->addWidget( myId, 0, 2 ); - myNodeToMoveGrpLayout->addWidget( myAutoSearchChkBox, 1, 0, 1, 3 ); - myNodeToMoveGrpLayout->addWidget( myPreviewChkBox, 2, 0, 1, 3 ); + myNodeToMoveGrpLayout->addWidget( aCoordWidget, 1, 0, 1, 3 ); + myNodeToMoveGrpLayout->addWidget( myAutoSearchChkBox, 2, 0, 1, 3 ); + myNodeToMoveGrpLayout->addWidget( myPreviewChkBox, 3, 0, 1, 3 ); QVBoxLayout* aLay = new QVBoxLayout(aFrame); aLay->addWidget(aPixGrp); aLay->addWidget(aCoordGrp); - aLay->addWidget(aMethodGrp); aLay->addWidget(myNodeToMoveGrp); connect(myCoordBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); - connect(myMoveRBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); - connect(myCreateRBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); connect(myIdBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); connect(myAutoSearchChkBox, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); - myMoveRBtn->setChecked(true); - myIdBtn->setDown(true); + myIdBtn->setChecked(true); myAutoSearchChkBox->setChecked(true); return aFrame; @@ -228,30 +276,27 @@ void SMESHGUI_MakeNodeAtPointDlg::ButtonToggled (bool on) if ( aSender == myCoordBtn ) // button to set coord by node selection { if ( myIdBtn->isEnabled() ) - myIdBtn->setDown( !on ); + myIdBtn->setChecked( !on ); } else if ( aSender == myIdBtn ) // button to select a node to move { - myCoordBtn->setDown( !on ); - } - else if ( aSender == myMoveRBtn ) // move node method - { - myNodeToMoveGrp->setEnabled( true ); - } - else if ( aSender == myCreateRBtn ) // create node method - { - myNodeToMoveGrp->setEnabled( false ); - myCoordBtn->setDown( true ); + myCoordBtn->setChecked( !on ); } } if ( aSender == myAutoSearchChkBox ) // automatic node search { if ( on ) { + myCurrentX->SetValue(0); + myCurrentY->SetValue(0); + myCurrentZ->SetValue(0); + myDX->SetValue(0); + myDY->SetValue(0); + myDZ->SetValue(0); myId->setText(""); myId->setReadOnly ( true ); - myIdBtn->setDown( false ); + myIdBtn->setChecked( false ); myIdBtn->setEnabled( false ); - myCoordBtn->setDown( true ); + myCoordBtn->setChecked( true ); } else { myId->setReadOnly ( false ); @@ -280,8 +325,10 @@ SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp() connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview())); connect(myDlg->myPreviewChkBox, SIGNAL (toggled(bool)),SLOT(redisplayPreview())); connect(myDlg->myAutoSearchChkBox,SIGNAL (toggled(bool)),SLOT(redisplayPreview())); - connect(myDlg->myMoveRBtn, SIGNAL (toggled(bool)),SLOT(redisplayPreview())); - connect(myDlg->myCreateRBtn, SIGNAL (toggled(bool)),SLOT(redisplayPreview())); + + // IPAL22913: TC6.5.0: selected in "Move node" dialog box node is not highlighted + // note: this slot seems to be lost together with removed obsolete SMESHGUI_MoveNodesDlg class + connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(onTextChange(const QString&))); } //======================================================================= @@ -320,13 +367,18 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation() myDlg->myX->SetValue(0); myDlg->myY->SetValue(0); myDlg->myZ->SetValue(0); + myDlg->myCurrentX->SetValue(0); + myDlg->myCurrentY->SetValue(0); + myDlg->myCurrentZ->SetValue(0); + myDlg->myDX->SetValue(0); + myDlg->myDY->SetValue(0); + myDlg->myDZ->SetValue(0); myDlg->myId->setText(""); myDlg->show(); onSelectionDone(); // init myMeshActor if ( myMeshActor ) { -// myMeshOldDisplayMode = myMeshActor->GetRepresentation(); // myMeshActor->SetRepresentation( VTK_WIREFRAME ); myMeshActor->SetPointRepresentation(true); SMESH::RepaintCurrentView(); @@ -345,7 +397,6 @@ void SMESHGUI_MakeNodeAtPointOp::stopOperation() myNoPreview = true; mySimulation->SetVisibility(false); if ( myMeshActor ) { -// myMeshActor->SetRepresentation( myMeshOldDisplayMode ); myMeshActor->SetPointRepresentation(false); SMESH::RepaintCurrentView(); myMeshActor = 0; @@ -367,7 +418,7 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply() if ( !myMeshActor ) { SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ), - tr("INVALID_MESH") ); + tr("INVALID_MESH") ); dlg()->show(); return false; } @@ -376,46 +427,49 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply() if ( !isValid( msg ) ) { // node id is invalid if( !msg.isEmpty() ) SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ), - tr("INVALID_ID") ); + tr("INVALID_ID") ); dlg()->show(); return false; } + QStringList aParameters; + aParameters << myDlg->myX->text(); + aParameters << myDlg->myY->text(); + aParameters << myDlg->myZ->text(); try { SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO()); if (aMesh->_is_nil()) { SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"), - tr("SMESHG_NO_MESH") ); + tr("SMESHG_NO_MESH") ); return true; } SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); if (aMeshEditor->_is_nil()) return true; - int aResult = 0; - if ( myDlg->myCreateRBtn->isDown() ) - { - 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); - } + aMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + + bool ok; + int anId = myDlg->myId->text().toInt( &ok ); + if( !ok || anId < 1 ) + anId = aMeshEditor->FindNodeClosestTo(myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue()); + + int aResult = aMeshEditor->MoveNode(anId, + myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue() ); + if (aResult) { - QStringList aParameters; - aParameters << myDlg->myX->text(); - aParameters << myDlg->myY->text(); - aParameters << myDlg->myZ->text(); - aMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); - + myDlg->myCurrentX->SetValue(0); + myDlg->myCurrentY->SetValue(0); + myDlg->myCurrentZ->SetValue(0); + myDlg->myDX->SetValue(0); + myDlg->myDY->SetValue(0); + myDlg->myDZ->SetValue(0); myDlg->myId->setText(""); SALOME_ListIO aList; @@ -423,6 +477,7 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply() aList.Append(myMeshActor->getIO()); selectionMgr()->setSelectedObjects(aList,false); SMESH::UpdateView(); + SMESHGUI::Modified(); } } catch (const SALOME::SALOME_Exception& S_ex) { @@ -444,7 +499,6 @@ bool SMESHGUI_MakeNodeAtPointOp::isValid( QString& msg ) { bool ok = true; if ( myMeshActor && - myDlg->myMoveRBtn->isDown() && !myDlg->myAutoSearchChkBox->isChecked() ) { ok = false; @@ -482,7 +536,7 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone() SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry()); if (!aMeshActor) { // coord by geom - if ( myDlg->myCoordBtn->isDown() ) { + if ( myDlg->myCoordBtn->isChecked() ) { GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface(anIO); if ( !geom->_is_nil() ) { TopoDS_Vertex aShape; @@ -510,19 +564,34 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone() if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh()) { if (const SMDS_MeshNode* aNode = aMesh->FindNode(aString.toInt())) { myNoPreview = true; - if ( myDlg->myCoordBtn->isDown() ) { // set coord + if ( myDlg->myCoordBtn->isChecked() ) { // set coord myDlg->myX->SetValue(aNode->X()); myDlg->myY->SetValue(aNode->Y()); myDlg->myZ->SetValue(aNode->Z()); myNoPreview = false; redisplayPreview(); } - else if ( myDlg->myIdBtn->isDown() && + else if ( myDlg->myIdBtn->isChecked() && myDlg->myIdBtn->isEnabled() ) { // set node to move myDlg->myId->setText(aString); myNoPreview = false; redisplayPreview(); } + + if (const SMDS_MeshNode* aCurrentNode = aMesh->FindNode(myDlg->myId->text().toInt())) { + double x = aCurrentNode->X(); + double y = aCurrentNode->Y(); + double z = aCurrentNode->Z(); + double dx = myDlg->myX->GetValue() - x; + double dy = myDlg->myY->GetValue() - y; + double dz = myDlg->myZ->GetValue() - z; + myDlg->myCurrentX->SetValue(x); + myDlg->myCurrentY->SetValue(y); + myDlg->myCurrentZ->SetValue(z); + myDlg->myDX->SetValue(dx); + myDlg->myDY->SetValue(dy); + myDlg->myDZ->SetValue(dz); + } } } } @@ -545,15 +614,22 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview() SMESH::MeshPreviewStruct_var aMeshPreviewStruct; bool moveShown = false; - if ( myDlg->myMoveRBtn->isDown() && // Move method - myMeshActor) + if ( myMeshActor) { const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked(); const bool preview = myDlg->myPreviewChkBox->isChecked(); if ( autoSearch ) + { + myDlg->myCurrentX->SetValue(0); + myDlg->myCurrentY->SetValue(0); + myDlg->myCurrentZ->SetValue(0); + myDlg->myDX->SetValue(0); + myDlg->myDY->SetValue(0); + myDlg->myDZ->SetValue(0); myDlg->myId->setText(""); + } QString msg; - if ( preview && ( autoSearch || isValid( msg ) )) + if ( autoSearch || isValid( msg ) ) { try { SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO()); @@ -563,11 +639,19 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview() { SUIT_OverrideCursor aWaitCursor; + int anId = 0; + if ( autoSearch ) + anId = aPreviewer->FindNodeClosestTo(myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue()); + else + anId = myDlg->myId->text().toInt(); + // find id and/or just compute preview - int anId = aPreviewer->MoveClosestNodeToPoint(myDlg->myX->GetValue(), - myDlg->myY->GetValue(), - myDlg->myZ->GetValue(), - myDlg->myId->text().toInt()); + aPreviewer->MoveNode(anId, + myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue()); if ( autoSearch ) { // set found id QString idTxt("%1"); if ( anId > 0 ) @@ -576,6 +660,24 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview() idTxt = ""; myDlg->myId->setText( idTxt ); } + + SMESH::double_array* aXYZ = aMesh->GetNodeXYZ( anId ); + if( aXYZ && aXYZ->length() >= 3 ) + { + double x = aXYZ->operator[](0); + double y = aXYZ->operator[](1); + double z = aXYZ->operator[](2); + double dx = myDlg->myX->GetValue() - x; + double dy = myDlg->myY->GetValue() - y; + double dz = myDlg->myZ->GetValue() - z; + myDlg->myCurrentX->SetValue(x); + myDlg->myCurrentY->SetValue(y); + myDlg->myCurrentZ->SetValue(z); + myDlg->myDX->SetValue(dx); + myDlg->myDY->SetValue(dy); + myDlg->myDZ->SetValue(dz); + } + if ( preview ) { // fill preview data aMeshPreviewStruct = aPreviewer->GetPreviewData(); moveShown = ( anId > 0 ); @@ -618,6 +720,35 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview() myNoPreview = false; } +//================================================================================ +/*! + * \brief SLOT called when the node id is manually changed + */ +//================================================================================ + +void SMESHGUI_MakeNodeAtPointOp::onTextChange( const QString& theText ) +{ + if( myMeshActor ) + { + if( SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh() ) + { + Handle(SALOME_InteractiveObject) anIO = myMeshActor->getIO(); + SALOME_ListIO aList; + aList.Append( anIO ); + selectionMgr()->setSelectedObjects( aList, false ); + + if( const SMDS_MeshNode* aNode = aMesh->FindNode( theText.toInt() ) ) + { + TColStd_MapOfInteger aListInd; + aListInd.Add( aNode->GetID() ); + selector()->AddOrRemoveIndex( anIO, aListInd, false ); + if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ) ) + aViewWindow->highlight( anIO, true, true ); + } + } + } +} + //================================================================================ /*! * \brief Activate Node selection diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h index 6df8ba722..11bf1189c 100644 --- a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h +++ b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_MakeNodeAtPointDlg.h // Author : Edward AGAPOV, Open CASCADE S.A.S. // @@ -35,7 +36,6 @@ class QGroupBox; class QLineEdit; class QPushButton; class QCheckBox; -class QRadioButton; class SMESHGUI_SpinBox; class SMESHGUI_MeshEditPreview; class SMESHGUI_MakeNodeAtPointDlg; @@ -68,6 +68,7 @@ protected slots: private slots: void onSelectionDone(); void redisplayPreview(); + void onTextChange( const QString& ); private: SMESHGUI_MakeNodeAtPointDlg* myDlg; @@ -97,11 +98,15 @@ private: SMESHGUI_SpinBox* myX; SMESHGUI_SpinBox* myY; SMESHGUI_SpinBox* myZ; - QRadioButton* myMoveRBtn; - QRadioButton* myCreateRBtn; QGroupBox* myNodeToMoveGrp; QPushButton* myIdBtn; QLineEdit* myId; + SMESHGUI_SpinBox* myCurrentX; + SMESHGUI_SpinBox* myCurrentY; + SMESHGUI_SpinBox* myCurrentZ; + SMESHGUI_SpinBox* myDX; + SMESHGUI_SpinBox* myDY; + SMESHGUI_SpinBox* myDZ; QCheckBox* myAutoSearchChkBox; QCheckBox* myPreviewChkBox; diff --git a/src/SMESHGUI/SMESHGUI_Measurements.cxx b/src/SMESHGUI/SMESHGUI_Measurements.cxx new file mode 100644 index 000000000..4e94217ed --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Measurements.cxx @@ -0,0 +1,1231 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_Measurements.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#include "SMESHGUI_Measurements.h" + +#include "SMESH_Actor.h" +#include "SMESHGUI.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) +#include CORBA_SERVER_HEADER(SMESH_Measurements) + +const int SPACING = 6; // layout spacing +const int MARGIN = 9; // layout margin +const int MAX_NB_FOR_EDITOR = 40; // max nb of items in the ID list editor field + +// Uncomment as soon as elements are supported by Min Distance operation +//#define MINDIST_ENABLE_ELEMENT + +// Uncomment as soon as objects are supported by Min Distance operation +//#define MINDIST_ENABLE_OBJECT + +/*! + \class SMESHGUI_MinDistance + \brief Minimum distance measurement widget. + + Widget to calculate minimum distance between two objects. +*/ + +/*! + \brief Constructor. + \param parent parent widget +*/ +SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent ) +: QWidget( parent ), myCurrentTgt( FirstTgt ), myFirstActor( 0 ), mySecondActor( 0 ), myPreview( 0 ) +{ + QGroupBox* aFirstTgtGrp = new QGroupBox( tr( "FIRST_TARGET" ), this ); + QRadioButton* aFNode = new QRadioButton( tr( "NODE" ), aFirstTgtGrp ); + QRadioButton* aFElem = new QRadioButton( tr( "ELEMENT" ), aFirstTgtGrp ); + QRadioButton* aFObject = new QRadioButton( tr( "OBJECT" ), aFirstTgtGrp ); + myFirstTgt = new QLineEdit( aFirstTgtGrp ); + + QGridLayout* fl = new QGridLayout( aFirstTgtGrp ); + fl->setMargin( MARGIN ); + fl->setSpacing( SPACING ); + fl->addWidget( aFNode, 0, 0 ); + fl->addWidget( aFElem, 0, 1 ); + fl->addWidget( aFObject, 0, 2 ); + fl->addWidget( myFirstTgt, 1, 0, 1, 3 ); + + myFirst = new QButtonGroup( this ); + myFirst->addButton( aFNode, NodeTgt ); + myFirst->addButton( aFElem, ElementTgt ); + myFirst->addButton( aFObject, ObjectTgt ); + + QGroupBox* aSecondTgtGrp = new QGroupBox( tr( "SECOND_TARGET" ), this ); + QRadioButton* aSOrigin = new QRadioButton( tr( "ORIGIN" ), aSecondTgtGrp ); + QRadioButton* aSNode = new QRadioButton( tr( "NODE" ), aSecondTgtGrp ); + QRadioButton* aSElem = new QRadioButton( tr( "ELEMENT" ), aSecondTgtGrp ); + QRadioButton* aSObject = new QRadioButton( tr( "OBJECT" ), aSecondTgtGrp ); + mySecondTgt = new QLineEdit( aSecondTgtGrp ); + + QGridLayout* sl = new QGridLayout( aSecondTgtGrp ); + sl->setMargin( MARGIN ); + sl->setSpacing( SPACING ); + sl->addWidget( aSOrigin, 0, 0 ); + sl->addWidget( aSNode, 0, 1 ); + sl->addWidget( aSElem, 0, 2 ); + sl->addWidget( aSObject, 0, 3 ); + sl->addWidget( mySecondTgt, 1, 0, 1, 4 ); + + mySecond = new QButtonGroup( this ); + mySecond->addButton( aSOrigin, OriginTgt ); + mySecond->addButton( aSNode, NodeTgt ); + mySecond->addButton( aSElem, ElementTgt ); + mySecond->addButton( aSObject, ObjectTgt ); + + QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this ); + + QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this ); + QLabel* aDxLab = new QLabel( "dX", aResults ); + myDX = new QLineEdit( aResults ); + QLabel* aDyLab = new QLabel( "dY", aResults ); + myDY = new QLineEdit( aResults ); + QLabel* aDzLab = new QLabel( "dZ", aResults ); + myDZ = new QLineEdit( aResults ); + QLabel* aDistLab = new QLabel( tr( "DISTANCE" ), aResults ); + myDistance = new QLineEdit( aResults ); + + QGridLayout* rl = new QGridLayout( aResults ); + rl->setMargin( MARGIN ); + rl->setSpacing( SPACING ); + rl->addWidget( aDxLab, 0, 0 ); + rl->addWidget( myDX, 0, 1 ); + rl->addWidget( aDyLab, 1, 0 ); + rl->addWidget( myDY, 1, 1 ); + rl->addWidget( aDzLab, 2, 0 ); + rl->addWidget( myDZ, 2, 1 ); + rl->addWidget( aDistLab, 0, 2 ); + rl->addWidget( myDistance, 0, 3 ); + + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + + l->addWidget( aFirstTgtGrp, 0, 0, 1, 2 ); + l->addWidget( aSecondTgtGrp, 1, 0, 1, 2 ); + l->addWidget( aCompute, 2, 0 ); + l->addWidget( aResults, 3, 0, 1, 2 ); + l->setColumnStretch( 1, 5 ); + l->setRowStretch( 4, 5 ); + + aFNode->setChecked( true ); + aSOrigin->setChecked( true ); +#ifndef MINDIST_ENABLE_ELEMENT + aFElem->setEnabled( false ); // NOT AVAILABLE YET + aSElem->setEnabled( false ); // NOT AVAILABLE YET +#endif +#ifndef MINDIST_ENABLE_OBJECT + aFObject->setEnabled( false ); // NOT AVAILABLE YET + aSObject->setEnabled( false ); // NOT AVAILABLE YET +#endif + myDX->setReadOnly( true ); + myDY->setReadOnly( true ); + myDZ->setReadOnly( true ); + myDistance->setReadOnly( true ); + + myValidator = new SMESHGUI_IdValidator( this, 1 ); + + myFirstTgt->installEventFilter( this ); + mySecondTgt->installEventFilter( this ); + + connect( myFirst, SIGNAL( buttonClicked( int ) ), this, SLOT( firstChanged() ) ); + connect( mySecond, SIGNAL( buttonClicked( int ) ), this, SLOT( secondChanged() ) ); + connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) ); + connect( myFirstTgt, SIGNAL( textEdited( QString ) ), this, SLOT( firstEdited() ) ); + connect( mySecondTgt, SIGNAL( textEdited( QString ) ), this, SLOT( secondEdited() ) ); + + QList filters; + filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) ); + filters.append( new SMESH_TypeFilter( GROUP ) ); + myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + + mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt ); + clear(); + + //setTarget( FirstTgt ); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MinDistance::~SMESHGUI_MinDistance() +{ + erasePreview(); + if ( myPreview ) + myPreview->Delete(); +} + +/*! + \brief Event filter + \param o object + \param o event + \return \c true if event is filtered or \c false otherwise +*/ +bool SMESHGUI_MinDistance::eventFilter( QObject* o, QEvent* e ) +{ + if ( e->type() == QEvent::FocusIn ) { + if ( o == myFirstTgt ) + setTarget( FirstTgt ); + else if ( o == mySecondTgt ) + setTarget( SecondTgt ); + } + return QWidget::eventFilter( o, e ); +} + +/*! + \brief Setup selection mode depending on the current widget state +*/ +void SMESHGUI_MinDistance::updateSelection() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + + disconnect( selMgr, 0, this, 0 ); + selMgr->clearFilters(); + + bool nodeMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == NodeTgt ) || + ( myCurrentTgt == SecondTgt && mySecond->checkedId() == NodeTgt ); + bool elemMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ElementTgt ) || + ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ElementTgt ); + bool objMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ObjectTgt ) || + ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ObjectTgt ) || + ( myCurrentTgt == NoTgt ); + + if ( nodeMode ) { + SMESH::SetPointRepresentation( true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( NodeSelection ); + } + else if ( elemMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( CellSelection ); + } + else if ( objMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + selMgr->installFilter( myFilter ); + } + + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) ); + + if ( myCurrentTgt == FirstTgt ) + firstEdited(); + else if ( myCurrentTgt == SecondTgt ) + secondEdited(); + + //selectionChanged(); +} + +/*! + \brief Deactivate widget +*/ +void SMESHGUI_MinDistance::deactivate() +{ + disconnect( SMESHGUI::selectionMgr(), 0, this, 0 ); +} + +/*! + \brief Set current target for selection + \param target new target ID +*/ +void SMESHGUI_MinDistance::setTarget( int target ) +{ + if ( myCurrentTgt != target ) { + myCurrentTgt = target; + updateSelection(); + } +} + +/*! + \brief Erase preview actor +*/ +void SMESHGUI_MinDistance::erasePreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->RemoveActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Display preview actor +*/ +void SMESHGUI_MinDistance::displayPreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->AddActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Create preview actor + \param x1 X coordinate of first point + \param y1 X coordinate of first point + \param z1 Y coordinate of first point + \param x2 Y coordinate of second point + \param y2 Z coordinate of second point + \param z2 Z coordinate of second point +*/ +void SMESHGUI_MinDistance::createPreview( double x1, double y1, double z1, double x2, double y2, double z2 ) +{ + if ( myPreview ) + myPreview->Delete(); + + vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New(); + // create points + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints( 2 ); + aPoints->SetPoint( 0, x1, y1, z1 ); + aPoints->SetPoint( 1, x2, y2, z2 ); + aGrid->SetPoints( aPoints ); + aPoints->Delete(); + // create cells + vtkIdList* anIdList = vtkIdList::New(); + anIdList->SetNumberOfIds( 2 ); + vtkCellArray* aCells = vtkCellArray::New(); + aCells->Allocate( 2, 0); + vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); + aCellTypesArray->SetNumberOfComponents( 1 ); + aCellTypesArray->Allocate( 1 ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->Delete(); + VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New(); + aCellLocationsArray->SetNumberOfComponents( 1 ); + aCellLocationsArray->SetNumberOfTuples( 1 ); + aCells->InitTraversal(); + for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ ) + aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) ); + aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells ); + aCellLocationsArray->Delete(); + aCellTypesArray->Delete(); + aCells->Delete(); + // create actor + vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); + aMapper->SetInput( aGrid ); + aGrid->Delete(); + myPreview = SALOME_Actor::New(); + myPreview->PickableOff(); + myPreview->SetMapper( aMapper ); + aMapper->Delete(); + vtkProperty* aProp = vtkProperty::New(); + aProp->SetRepresentationToWireframe(); + aProp->SetColor( 250, 0, 250 ); + aProp->SetPointSize( 5 ); + aProp->SetLineWidth( 3 ); + myPreview->SetProperty( aProp ); + aProp->Delete(); +} + +/*! + \brief Called when selection is changed +*/ +void SMESHGUI_MinDistance::selectionChanged() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + if ( myCurrentTgt == FirstTgt ) { + myFirstSrc = obj; + myFirstActor = SMESH::FindActorByEntry( IO->getEntry() ); + if ( myFirst->checkedId() == ObjectTgt ) { + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + myFirstTgt->setText( aName ); + } + else { + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( myFirstActor && selector ) { + nb = myFirst->checkedId() == NodeTgt ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + if ( nb == 1 ) + myFirstTgt->setText( ID.trimmed() ); + else + myFirstTgt->clear(); + } + } + else if ( myCurrentTgt == SecondTgt ) { + mySecondSrc = obj; + mySecondActor = SMESH::FindActorByEntry( IO->getEntry() ); + if ( mySecond->checkedId() == ObjectTgt ) { + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + mySecondTgt->setText( aName ); + } + else { + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( mySecondActor && selector ) { + nb = mySecond->checkedId() == NodeTgt ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + if ( nb == 1 ) + mySecondTgt->setText( ID.trimmed() ); + else + mySecondTgt->clear(); + } + } + } + } + clear(); +} + +/*! + \brief Called when first target mode is changed by the user +*/ +void SMESHGUI_MinDistance::firstChanged() +{ + myFirstSrc = SMESH::SMESH_IDSource::_nil(); + myFirstTgt->clear(); + myFirstTgt->setReadOnly( myFirst->checkedId() == ObjectTgt ); + myFirstTgt->setValidator( myFirst->checkedId() == ObjectTgt ? 0 : myValidator ); + setTarget( FirstTgt ); + updateSelection(); + clear(); +} + +/*! + \brief Called when second target mode is changed by the user +*/ +void SMESHGUI_MinDistance::secondChanged() +{ + mySecondSrc = SMESH::SMESH_IDSource::_nil(); + mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt ); + mySecondTgt->setReadOnly( mySecond->checkedId() == ObjectTgt ); + mySecondTgt->setValidator( mySecond->checkedId() == ObjectTgt ? 0 : myValidator ); + mySecondTgt->clear(); + setTarget( mySecond->checkedId() != OriginTgt ? SecondTgt : NoTgt ); + updateSelection(); + clear(); +} + +/*! + \brief Called when first target is edited by the user +*/ +void SMESHGUI_MinDistance::firstEdited() +{ + setTarget( FirstTgt ); + if ( sender() == myFirstTgt ) + clear(); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( myFirstActor && selector ) { + Handle(SALOME_InteractiveObject) IO = myFirstActor->getIO(); + if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) { + TColStd_MapOfInteger ID; + ID.Add( myFirstTgt->text().toLong() ); + selector->AddOrRemoveIndex( IO, ID, false ); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + } +} + +/*! + \brief Called when second target is edited by the user +*/ +void SMESHGUI_MinDistance::secondEdited() +{ + setTarget( SecondTgt ); + if ( sender() == mySecondTgt ) + clear(); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( mySecondActor && selector ) { + Handle(SALOME_InteractiveObject) IO = mySecondActor->getIO(); + if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) { + TColStd_MapOfInteger ID; + ID.Add( mySecondTgt->text().toLong() ); + selector->AddOrRemoveIndex( IO, ID, false ); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + } +} + +/*! + \brief Compute the minimum distance between targets +*/ +void SMESHGUI_MinDistance::compute() +{ + SUIT_OverrideCursor wc; + SMESH::SMESH_IDSource_var s1; + SMESH::SMESH_IDSource_var s2; + bool isOrigin = mySecond->checkedId() == OriginTgt; + + // process first target + if ( !CORBA::is_nil( myFirstSrc ) ) { + if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) { + SMESH::SMESH_Mesh_var m = myFirstSrc->GetMesh(); + long id = myFirstTgt->text().toLong(); + if ( !CORBA::is_nil( m ) && id ) { + SMESH::long_array_var ids = new SMESH::long_array(); + ids->length( 1 ); + ids[0] = id; + SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); + s1 = me->MakeIDSource( ids.in(), myFirst->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE ); + } + } + else { + s1 = myFirstSrc; + } + } + + // process second target + if ( !CORBA::is_nil( mySecondSrc ) ) { + if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) { + SMESH::SMESH_Mesh_var m = mySecondSrc->GetMesh(); + long id = mySecondTgt->text().toLong(); + if ( !CORBA::is_nil( m ) && id ) { + SMESH::long_array_var ids = new SMESH::long_array(); + ids->length( 1 ); + ids[0] = id; + SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); + s2 = me->MakeIDSource( ids.in(), mySecond->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE ); + } + } + else { + s2 = mySecondSrc; + } + } + + if ( !CORBA::is_nil( s1 ) && ( !CORBA::is_nil( s2 ) || isOrigin ) ) { + // compute min distance + int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements(); + SMESH::Measure result = measure->MinDistance( s1.in(), s2.in() ); + measure->UnRegister(); + myDX->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDY->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDZ->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDistance->setText( QString::number( result.value, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // update preview actor + erasePreview(); + double x1, y1, z1, x2, y2, z2; + SMESH::double_array_var coord = s1->GetMesh()->GetNodeXYZ( result.node1 ); + x1 = coord[0]; y1 = coord[1]; z1 = coord[2]; + if ( isOrigin ) { + x2 = y2 = z2 = 0.; + } + else { + coord = s2->GetMesh()->GetNodeXYZ( result.node2 ); + x2 = coord[0]; y2 = coord[1]; z2 = coord[2]; + } + createPreview( x1, y1, z1, x2, y2, z2 ); + displayPreview(); + } + else { + clear(); + } +} + +/*! + \brief Reset the widget to the initial state (nullify result fields) +*/ +void SMESHGUI_MinDistance::clear() +{ + myDX->clear(); + myDY->clear(); + myDZ->clear(); + myDistance->clear(); + erasePreview(); +} + +/*! + \class SMESHGUI_BoundingBox + \brief Bounding box measurement widget. + + Widget to calculate bounding box of the selected object(s). +*/ + +/*! + \brief Constructor. + \param parent parent widget +*/ +SMESHGUI_BoundingBox::SMESHGUI_BoundingBox( QWidget* parent ) +: QWidget( parent ), myActor( 0 ), myPreview( 0 ) +{ + QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE" ), this ); + QRadioButton* aObjects = new QRadioButton( tr( "OBJECTS" ), aSourceGrp ); + QRadioButton* aNodes = new QRadioButton( tr( "NODES" ), aSourceGrp ); + QRadioButton* aElements = new QRadioButton( tr( "ELEMENTS" ), aSourceGrp ); + mySource = new QLineEdit( aSourceGrp ); + + QGridLayout* fl = new QGridLayout( aSourceGrp ); + fl->setMargin( MARGIN ); + fl->setSpacing( SPACING ); + fl->addWidget( aObjects, 0, 0 ); + fl->addWidget( aNodes, 0, 1 ); + fl->addWidget( aElements, 0, 2 ); + fl->addWidget( mySource, 1, 0, 1, 3 ); + + mySourceMode = new QButtonGroup( this ); + mySourceMode->addButton( aObjects, ObjectsSrc ); + mySourceMode->addButton( aNodes, NodesSrc ); + mySourceMode->addButton( aElements, ElementsSrc ); + + QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this ); + + QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this ); + QLabel* aXminLab = new QLabel( "Xmin", aResults ); + myXmin = new QLineEdit( aResults ); + QLabel* aXmaxLab = new QLabel( "Xmax", aResults ); + myXmax = new QLineEdit( aResults ); + QLabel* aDxLab = new QLabel( "dX", aResults ); + myDX = new QLineEdit( aResults ); + QLabel* aYminLab = new QLabel( "Ymin", aResults ); + myYmin = new QLineEdit( aResults ); + QLabel* aYmaxLab = new QLabel( "Ymax", aResults ); + myYmax = new QLineEdit( aResults ); + QLabel* aDyLab = new QLabel( "dY", aResults ); + myDY = new QLineEdit( aResults ); + QLabel* aZminLab = new QLabel( "Zmin", aResults ); + myZmin = new QLineEdit( aResults ); + QLabel* aZmaxLab = new QLabel( "Zmax", aResults ); + myZmax = new QLineEdit( aResults ); + QLabel* aDzLab = new QLabel( "dZ", aResults ); + myDZ = new QLineEdit( aResults ); + + QGridLayout* rl = new QGridLayout( aResults ); + rl->setMargin( MARGIN ); + rl->setSpacing( SPACING ); + rl->addWidget( aXminLab, 0, 0 ); + rl->addWidget( myXmin, 0, 1 ); + rl->addWidget( aXmaxLab, 0, 2 ); + rl->addWidget( myXmax, 0, 3 ); + rl->addWidget( aDxLab, 0, 4 ); + rl->addWidget( myDX, 0, 5 ); + rl->addWidget( aYminLab, 1, 0 ); + rl->addWidget( myYmin, 1, 1 ); + rl->addWidget( aYmaxLab, 1, 2 ); + rl->addWidget( myYmax, 1, 3 ); + rl->addWidget( aDyLab, 1, 4 ); + rl->addWidget( myDY, 1, 5 ); + rl->addWidget( aZminLab, 2, 0 ); + rl->addWidget( myZmin, 2, 1 ); + rl->addWidget( aZmaxLab, 2, 2 ); + rl->addWidget( myZmax, 2, 3 ); + rl->addWidget( aDzLab, 2, 4 ); + rl->addWidget( myDZ, 2, 5 ); + + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + + l->addWidget( aSourceGrp, 0, 0, 1, 2 ); + l->addWidget( aCompute, 1, 0 ); + l->addWidget( aResults, 2, 0, 1, 2 ); + l->setColumnStretch( 1, 5 ); + l->setRowStretch( 3, 5 ); + + aObjects->setChecked( true ); + myXmin->setReadOnly( true ); + myXmax->setReadOnly( true ); + myDX->setReadOnly( true ); + myYmin->setReadOnly( true ); + myYmax->setReadOnly( true ); + myDY->setReadOnly( true ); + myZmin->setReadOnly( true ); + myZmax->setReadOnly( true ); + myDZ->setReadOnly( true ); + + myValidator = new SMESHGUI_IdValidator( this ); + + connect( mySourceMode, SIGNAL( buttonClicked( int ) ), this, SLOT( sourceChanged() ) ); + connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) ); + connect( mySource, SIGNAL( textEdited( QString ) ), this, SLOT( sourceEdited() ) ); + + QList filters; + filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) ); + filters.append( new SMESH_TypeFilter( GROUP ) ); + myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + + clear(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_BoundingBox::~SMESHGUI_BoundingBox() +{ + erasePreview(); + if ( myPreview ) + myPreview->Delete(); +} + +/*! + \brief Setup selection mode depending on the current widget state +*/ +void SMESHGUI_BoundingBox::updateSelection() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + + disconnect( selMgr, 0, this, 0 ); + selMgr->clearFilters(); + + bool nodeMode = mySourceMode->checkedId() == NodesSrc; + bool elemMode = mySourceMode->checkedId() == ElementsSrc; + bool objMode = mySourceMode->checkedId() == ObjectsSrc; + + if ( nodeMode ) { + SMESH::SetPointRepresentation( true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( NodeSelection ); + } + else if ( elemMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( CellSelection ); + } + else if ( objMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + selMgr->installFilter( myFilter ); + } + + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) ); + + sourceEdited(); + + //selectionChanged(); +} + +/*! + \brief Deactivate widget +*/ +void SMESHGUI_BoundingBox::deactivate() +{ + disconnect( SMESHGUI::selectionMgr(), 0, this, 0 ); +} + +/*! + \brief Erase preview actor +*/ +void SMESHGUI_BoundingBox::erasePreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->RemoveActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Display preview actor +*/ +void SMESHGUI_BoundingBox::displayPreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->AddActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Create preview actor + \param minX min X coordinate of bounding box + \param maxX max X coordinate of bounding box + \param minY min Y coordinate of bounding box + \param maxY max Y coordinate of bounding box + \param minZ min Z coordinate of bounding box + \param maxZ max Z coordinate of bounding box +*/ +void SMESHGUI_BoundingBox::createPreview( double minX, double maxX, double minY, double maxY, double minZ, double maxZ ) +{ + if ( myPreview ) + myPreview->Delete(); + + vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New(); + // create points + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints( 8 ); + aPoints->SetPoint( 0, minX, minY, minZ ); + aPoints->SetPoint( 1, maxX, minY, minZ ); + aPoints->SetPoint( 2, minX, maxY, minZ ); + aPoints->SetPoint( 3, maxX, maxY, minZ ); + aPoints->SetPoint( 4, minX, minY, maxZ ); + aPoints->SetPoint( 5, maxX, minY, maxZ ); + aPoints->SetPoint( 6, minX, maxY, maxZ ); + aPoints->SetPoint( 7, maxX, maxY, maxZ ); + aGrid->SetPoints( aPoints ); + aPoints->Delete(); + // create cells + // connectivity: 0-1 0-4 0-2 1-5 1-3 2-6 2-3 3-7 4-6 4-5 5-7 6-7 + vtkIdList* anIdList = vtkIdList::New(); + anIdList->SetNumberOfIds( 2 ); + vtkCellArray* aCells = vtkCellArray::New(); + aCells->Allocate( 2*12, 0); + vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); + aCellTypesArray->SetNumberOfComponents( 1 ); + aCellTypesArray->Allocate( 12 ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 4 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 2 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 5 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 3 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 6 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 3 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 3 ); anIdList->SetId( 1, 7 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 6 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 5 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 5 ); anIdList->SetId( 1, 7 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 6 ); anIdList->SetId( 1, 7 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->Delete(); + VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New(); + aCellLocationsArray->SetNumberOfComponents( 1 ); + aCellLocationsArray->SetNumberOfTuples( 12 ); + aCells->InitTraversal(); + for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ ) + aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) ); + aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells ); + aCellLocationsArray->Delete(); + aCellTypesArray->Delete(); + aCells->Delete(); + // create actor + vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); + aMapper->SetInput( aGrid ); + aGrid->Delete(); + myPreview = SALOME_Actor::New(); + myPreview->PickableOff(); + myPreview->SetMapper( aMapper ); + aMapper->Delete(); + vtkProperty* aProp = vtkProperty::New(); + aProp->SetRepresentationToWireframe(); + aProp->SetColor( 250, 0, 250 ); + aProp->SetPointSize( 5 ); + aProp->SetLineWidth( 3 ); + myPreview->SetProperty( aProp ); + aProp->Delete(); +} + +/*! + \brief Called when selection is changed +*/ +void SMESHGUI_BoundingBox::selectionChanged() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + mySrc.clear(); + mySrc.append( obj ); + myActor = SMESH::FindActorByEntry( IO->getEntry() ); + if ( mySourceMode->checkedId() == ObjectsSrc ) { + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + mySource->setText( aName ); + } + else { + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( myActor && selector ) { + nb = mySourceMode->checkedId() == NodesSrc ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + if ( nb > 0 ) { + myIDs = ID.trimmed(); + if ( nb < MAX_NB_FOR_EDITOR ) { + mySource->setReadOnly( false ); + if ( mySource->validator() != myValidator ) + mySource->setValidator( myValidator ); + mySource->setText( ID.trimmed() ); + } + else { + mySource->setReadOnly( true ); + mySource->setValidator( 0 ); + mySource->setText( tr( "SELECTED_NB_OBJ" ).arg( nb ) + .arg( mySourceMode->checkedId() == NodesSrc ? tr( "NB_NODES" ) : tr( "NB_ELEMENTS") ) ); + } + } + else { + myIDs = ""; + mySource->clear(); + mySource->setReadOnly( false ); + mySource->setValidator( myValidator ); + } + } + } + } + else if ( selected.Extent() > 1 ) { + myIDs = ""; + SALOME_ListIteratorOfListIO It( selected ); + mySrc.clear(); + myActor = 0; + if ( mySourceMode->checkedId() == ObjectsSrc ) { + for( ; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IO = It.Value(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + mySrc.append( obj ); + } + } + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + mySource->setText( aName ); + } + else { + mySource->clear(); + } + } + clear(); +} + +/*! + \brief Called when source mode is changed by the user +*/ +void SMESHGUI_BoundingBox::sourceChanged() +{ + myIDs = ""; + mySource->clear(); + mySource->setReadOnly( mySourceMode->checkedId() == ObjectsSrc ); + mySource->setValidator( mySourceMode->checkedId() == ObjectsSrc ? 0 : myValidator ); + updateSelection(); + clear(); +} + +/*! + \brief Called when source mode is edited by the user +*/ +void SMESHGUI_BoundingBox::sourceEdited() +{ + if ( sender() == mySource ) + clear(); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( myActor && selector ) { + Handle(SALOME_InteractiveObject) IO = myActor->getIO(); + if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) { + TColStd_MapOfInteger ID; + if ( !mySource->isReadOnly() ) + myIDs = mySource->text(); + QStringList ids = myIDs.split( " ", QString::SkipEmptyParts ); + foreach ( QString id, ids ) + ID.Add( id.trimmed().toLong() ); + selector->AddOrRemoveIndex( IO, ID, false ); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + } +} + +/*! + \brief Calculate bounding box of the selected object(s) +*/ +void SMESHGUI_BoundingBox::compute() +{ + SUIT_OverrideCursor wc; + SMESH::ListOfIDSources_var srcList = new SMESH::ListOfIDSources(); + if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) { + if ( mySrc.count() > 0 && !CORBA::is_nil( mySrc[0] ) ) { + SMESH::SMESH_Mesh_var m = mySrc[0]->GetMesh(); + QStringList ids = myIDs.split( " ", QString::SkipEmptyParts ); + if ( !CORBA::is_nil( m ) && ids.count() > 0 ) { + SMESH::long_array_var ids_in = new SMESH::long_array(); + ids_in->length( ids.count() ); + for( int i = 0; i < ids.count(); i++ ) + ids_in[i] = ids[i].trimmed().toLong(); + SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); + SMESH::SMESH_IDSource_var s = me->MakeIDSource( ids_in.in(), mySourceMode->checkedId() == NodesSrc ? SMESH::NODE : SMESH::FACE ); + srcList->length( 1 ); + srcList[0] = s; + } + } + } + else { + srcList->length( mySrc.count() ); + for( int i = 0; i < mySrc.count(); i++ ) + srcList[i] = mySrc[i]; + } + if ( srcList->length() > 0 ) { + // compute bounding box + int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements(); + SMESH::Measure result = measure->BoundingBox( srcList.in() ); + measure->UnRegister(); + myXmin->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myXmax->setText( QString::number( result.maxX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDX->setText( QString::number( result.maxX-result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myYmin->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myYmax->setText( QString::number( result.maxY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDY->setText( QString::number( result.maxY-result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myZmin->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myZmax->setText( QString::number( result.maxZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDZ->setText( QString::number( result.maxZ-result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // update preview actor + erasePreview(); + createPreview( result.minX, result.maxX, result.minY, result.maxY, result.minZ, result.maxZ ); + displayPreview(); + } + else { + clear(); + } +} + +/*! + \brief Reset the widget to the initial state (nullify result fields) +*/ +void SMESHGUI_BoundingBox::clear() +{ + myXmin->clear(); + myXmax->clear(); + myDX->clear(); + myYmin->clear(); + myYmax->clear(); + myDY->clear(); + myZmin->clear(); + myZmax->clear(); + myDZ->clear(); + erasePreview(); +} + +/*! + \class SMESHGUI_MeshInfoDlg + \brief Centralized dialog box for the measurements +*/ + +/*! + \brief Constructor + \param parent parent widget + \param page specifies the dialog page to be shown at the start-up +*/ +SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page ) +: QDialog( parent ) +{ + setModal( false ); + setAttribute( Qt::WA_DeleteOnClose, true ); + setWindowTitle( tr( "MEASUREMENTS" ) ); + setSizeGripEnabled( true ); + + SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr(); + + myTabWidget = new QTabWidget( this ); + + // min distance + + myMinDist = new SMESHGUI_MinDistance( myTabWidget ); + myTabWidget->addTab( myMinDist, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_MIN_DIST" ) ), tr( "MIN_DIST" ) ); + + // bounding box + + myBndBox = new SMESHGUI_BoundingBox( myTabWidget ); + myTabWidget->addTab( myBndBox, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BND_BOX" ) ), tr( "BND_BOX" ) ); + + // buttons + QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this ); + okBtn->setAutoDefault( true ); + okBtn->setDefault( true ); + okBtn->setFocus(); + QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this ); + helpBtn->setAutoDefault( true ); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setSpacing( SPACING ); + btnLayout->setMargin( 0 ); + btnLayout->addWidget( okBtn ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( helpBtn ); + + QVBoxLayout* l = new QVBoxLayout ( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + l->addWidget( myTabWidget ); + l->addStretch(); + l->addLayout( btnLayout ); + + myTabWidget->setCurrentIndex( qMax( (int)MinDistance, qMin( (int)BoundingBox, page ) ) ); + + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); + + updateSelection(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MeasureDlg::~SMESHGUI_MeasureDlg() +{ +} + +/*! + \brief Perform clean-up actions on the dialog box closing. +*/ +void SMESHGUI_MeasureDlg::reject() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + selMgr->clearFilters(); + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + QDialog::reject(); +} + +/*! + \brief Process keyboard event + \param e key press event +*/ +void SMESHGUI_MeasureDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) { + e->accept(); + help(); + } +} + +/*! + \brief Reactivate dialog box, when mouse pointer goes into it. +*/ +void SMESHGUI_MeasureDlg::enterEvent( QEvent* ) +{ + activate(); +} + +/*! + \brief Setup selection mode depending on the current dialog box state. +*/ +void SMESHGUI_MeasureDlg::updateSelection() +{ + if ( myTabWidget->currentIndex() == MinDistance ) + myMinDist->updateSelection(); + else if ( myTabWidget->currentIndex() == BoundingBox ) + myBndBox->updateSelection(); + +} + +/*! + \brief Show help page +*/ +void SMESHGUI_MeasureDlg::help() +{ + SMESH::ShowHelpFile( myTabWidget->currentIndex() == MinDistance ? + "measurements_page.html#min_distance_anchor" : + "measurements_page.html#bounding_box_anchor" ); +} + +/*! + \brief Activate dialog box +*/ +void SMESHGUI_MeasureDlg::activate() +{ + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); + SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); + myTabWidget->setEnabled( true ); + updateSelection(); +} + +/*! + \brief Deactivate dialog box +*/ +void SMESHGUI_MeasureDlg::deactivate() +{ + myMinDist->deactivate(); + myBndBox->deactivate(); + myTabWidget->setEnabled( false ); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); +} diff --git a/src/SMESHGUI/SMESHGUI_Measurements.h b/src/SMESHGUI/SMESHGUI_Measurements.h new file mode 100644 index 000000000..3b5079fcb --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Measurements.h @@ -0,0 +1,172 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_Measurements.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#ifndef SMESHGUI_MEASUREMENTS_H +#define SMESHGUI_MEASUREMENTS_H + +#include "SMESH_SMESHGUI.hxx" + +#include + +class QButtonGroup; +class QLineEdit; +class QTabWidget; +class SUIT_SelectionFilter; +class SALOME_Actor; +class SMESH_Actor; +class SMESHGUI_IdValidator; + +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class SMESHGUI_EXPORT SMESHGUI_MinDistance : public QWidget +{ + Q_OBJECT; + + enum { NoTgt, FirstTgt, SecondTgt }; + enum { OriginTgt, NodeTgt, ElementTgt, ObjectTgt }; + +public: + SMESHGUI_MinDistance( QWidget* = 0 ); + ~SMESHGUI_MinDistance(); + + bool eventFilter( QObject*, QEvent* ); + void updateSelection(); + void deactivate(); + +private: + void setTarget( int ); + void erasePreview(); + void displayPreview(); + void createPreview( double, double, double, double, double, double ); + +private slots: + void selectionChanged(); + void firstChanged(); + void secondChanged(); + void firstEdited(); + void secondEdited(); + void compute(); + void clear(); + +private: + QButtonGroup* myFirst; + QButtonGroup* mySecond; + QLineEdit* myFirstTgt; + QLineEdit* mySecondTgt; + QLineEdit* myDX; + QLineEdit* myDY; + QLineEdit* myDZ; + QLineEdit* myDistance; + int myCurrentTgt; + SMESH::SMESH_IDSource_var myFirstSrc; + SMESH::SMESH_IDSource_var mySecondSrc; + SMESH_Actor* myFirstActor; + SMESH_Actor* mySecondActor; + SMESHGUI_IdValidator* myValidator; + SUIT_SelectionFilter* myFilter; + SALOME_Actor* myPreview; +}; + +class SMESHGUI_EXPORT SMESHGUI_BoundingBox : public QWidget +{ + Q_OBJECT; + + enum { ObjectsSrc, NodesSrc, ElementsSrc }; + +public: + SMESHGUI_BoundingBox( QWidget* = 0 ); + ~SMESHGUI_BoundingBox(); + + void updateSelection(); + void deactivate(); + +private: + void erasePreview(); + void displayPreview(); + void createPreview( double, double, double, double, double, double ); + +private slots: + void selectionChanged(); + void sourceChanged(); + void sourceEdited(); + void compute(); + void clear(); + +private: + typedef QList SourceList; + QButtonGroup* mySourceMode; + QLineEdit* mySource; + QLineEdit* myXmin; + QLineEdit* myXmax; + QLineEdit* myDX; + QLineEdit* myYmin; + QLineEdit* myYmax; + QLineEdit* myDY; + QLineEdit* myZmin; + QLineEdit* myZmax; + QLineEdit* myDZ; + SourceList mySrc; + SMESH_Actor* myActor; + SMESHGUI_IdValidator* myValidator; + QString myIDs; + SUIT_SelectionFilter* myFilter; + SALOME_Actor* myPreview; +}; + +class SMESHGUI_EXPORT SMESHGUI_MeasureDlg : public QDialog +{ + Q_OBJECT; + + enum { NodeMode, ElemMode }; + +public: + //! Measurement type + enum { + MinDistance, //!< minimum distance + BoundingBox //!< bounding box + }; + + SMESHGUI_MeasureDlg( QWidget* = 0, int = MinDistance ); + ~SMESHGUI_MeasureDlg(); + + void reject(); + +protected: + void keyPressEvent( QKeyEvent* ); + void enterEvent( QEvent* ); + +private slots: + void help(); + void updateSelection(); + void activate(); + void deactivate(); + +private: + QTabWidget* myTabWidget; + SMESHGUI_MinDistance* myMinDist; + SMESHGUI_BoundingBox* myBndBox; +}; + +#endif // SMESHGUI_MEASUREMENTS_H diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.cxx b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx new file mode 100644 index 000000000..7446b54b2 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx @@ -0,0 +1,1325 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_MergeDlg.cxx +// Author : Open CASCADE S.A.S. +// SMESH includes +// +#include "SMESHGUI_MergeDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_SpinBox.h" + +#include +#include +#include +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +// OCCT includes +#include +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +// VTK includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(VTK_XVERSION) +#define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION) +#endif + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 + +namespace SMESH +{ + class TIdPreview + { // to display in the viewer IDs of the selected elements + SVTK_ViewWindow* myViewWindow; + + vtkUnstructuredGrid* myIdGrid; + SALOME_Actor* myIdActor; + + vtkUnstructuredGrid* myPointsNumDataSet; + vtkMaskPoints* myPtsMaskPoints; + vtkSelectVisiblePoints* myPtsSelectVisiblePoints; + vtkLabeledDataMapper* myPtsLabeledDataMapper; + vtkTextProperty* aPtsTextProp; + bool myIsPointsLabeled; + vtkActor2D* myPointLabels; + + std::vector myIDs; + + public: + TIdPreview(SVTK_ViewWindow* theViewWindow): + myViewWindow(theViewWindow) + { + myIdGrid = vtkUnstructuredGrid::New(); + + // Create and display actor + vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); + aMapper->SetInput( myIdGrid ); + + myIdActor = SALOME_Actor::New(); + myIdActor->SetInfinitive(true); + myIdActor->VisibilityOff(); + myIdActor->PickableOff(); + + myIdActor->SetMapper( aMapper ); + aMapper->Delete(); + + myViewWindow->AddActor(myIdActor); + + //Definition of points numbering pipeline + myPointsNumDataSet = vtkUnstructuredGrid::New(); + + myPtsMaskPoints = vtkMaskPoints::New(); + myPtsMaskPoints->SetInput(myPointsNumDataSet); + myPtsMaskPoints->SetOnRatio(1); + + myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New(); + myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput()); + myPtsSelectVisiblePoints->SelectInvisibleOff(); + myPtsSelectVisiblePoints->SetTolerance(0.1); + + myPtsLabeledDataMapper = vtkLabeledDataMapper::New(); + myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput()); +#if (VTK_XVERSION < 0x050200) + myPtsLabeledDataMapper->SetLabelFormat("%g"); +#endif + myPtsLabeledDataMapper->SetLabelModeToLabelScalars(); + + vtkTextProperty* aPtsTextProp = vtkTextProperty::New(); + aPtsTextProp->SetFontFamilyToTimes(); + static int aPointsFontSize = 12; + aPtsTextProp->SetFontSize(aPointsFontSize); + aPtsTextProp->SetBold(1); + aPtsTextProp->SetItalic(0); + aPtsTextProp->SetShadow(0); + myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp); + aPtsTextProp->Delete(); + + myIsPointsLabeled = false; + + myPointLabels = vtkActor2D::New(); + myPointLabels->SetMapper(myPtsLabeledDataMapper); + myPointLabels->GetProperty()->SetColor(1,1,1); + myPointLabels->SetVisibility(myIsPointsLabeled); + + AddToRender(myViewWindow->getRenderer()); + } + + void SetPointsData ( SMDS_Mesh* theMesh, + TColStd_MapOfInteger & theNodesIdMap ) + { + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints(theNodesIdMap.Extent()); + myIDs.clear(); + + TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap ); + for( int i = 0; idIter.More(); idIter.Next(), i++ ) { + const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key()); + aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() ); + myIDs.push_back(idIter.Key()); + } + + myIdGrid->SetPoints(aPoints); + + aPoints->Delete(); + + myIdActor->GetMapper()->Update(); + } + + void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, + std::list & aGrCentersXYZ ) + { + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints(theElemsIdMap.Extent()); + myIDs.clear(); + + TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); + for( ; idIter.More(); idIter.Next() ) { + myIDs.push_back(idIter.Key()); + } + + gp_XYZ aXYZ; + std::list::iterator coordIt = aGrCentersXYZ.begin(); + for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) { + aXYZ = *coordIt; + aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() ); + } + myIdGrid->SetPoints(aPoints); + aPoints->Delete(); + + myIdActor->GetMapper()->Update(); + } + + void AddToRender(vtkRenderer* theRenderer) + { + myIdActor->AddToRender(theRenderer); + + myPtsSelectVisiblePoints->SetRenderer(theRenderer); + theRenderer->AddActor2D(myPointLabels); + } + + void RemoveFromRender(vtkRenderer* theRenderer) + { + myIdActor->RemoveFromRender(theRenderer); + + myPtsSelectVisiblePoints->SetRenderer(theRenderer); + theRenderer->RemoveActor(myPointLabels); + } + + void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true ) + { + myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints(); + + if ( myIsPointsLabeled ) { + myPointsNumDataSet->ShallowCopy(myIdGrid); + vtkDataSet *aDataSet = myPointsNumDataSet; + int aNbElem = myIDs.size(); + vtkIntArray *anArray = vtkIntArray::New(); + anArray->SetNumberOfValues( aNbElem ); + for ( int i = 0; i < aNbElem; i++ ) + anArray->SetValue( i, myIDs[i] ); + aDataSet->GetPointData()->SetScalars( anArray ); + anArray->Delete(); + myPtsMaskPoints->SetInput( aDataSet ); + myPointLabels->SetVisibility( theIsActorVisible ); + } + else { + myPointLabels->SetVisibility( false ); + } + } + + ~TIdPreview() + { + RemoveFromRender(myViewWindow->getRenderer()); + + myIdGrid->Delete(); + + myViewWindow->RemoveActor(myIdActor); + myIdActor->Delete(); + + //Deleting of points numbering pipeline + //--------------------------------------- + myPointsNumDataSet->Delete(); + + //myPtsLabeledDataMapper->RemoveAllInputs(); //vtk 5.0 porting + myPtsLabeledDataMapper->Delete(); + + //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting + myPtsSelectVisiblePoints->Delete(); + + //myPtsMaskPoints->UnRegisterAllOutputs(); //vtk 5.0 porting + myPtsMaskPoints->Delete(); + + myPointLabels->Delete(); + +// myTimeStamp->Delete(); + } + }; +} + +static const char * IconFirst[] = { +"18 10 2 1", +" g None", +". g #000000", +" . . ", +" .. .. .. ", +" .. ... ... ", +" .. .... .... ", +" .. ..... ..... ", +" .. ..... ..... ", +" .. .... .... ", +" .. ... ... ", +" .. .. .. ", +" . . "}; + +//================================================================================= +// class : SMESHGUI_MergeDlg() +// purpose : +//================================================================================= +SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) + : QDialog(SMESH::GetDesktop(theModule)), + mySMESHGUI(theModule), + mySelectionMgr(SMESH::GetSelectionMgr(theModule)), + myAction(theAction) +{ + setModal(false); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES")); + + myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI )); + + SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI ); + QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES"))); + QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS"))); + QPixmap IconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); + QPixmap IconAdd (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND"))); + QPixmap IconRemove (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE"))); + + setSizeGripEnabled(true); + + QVBoxLayout* DlgLayout = new QVBoxLayout(this); + DlgLayout->setSpacing(SPACING); + DlgLayout->setMargin(MARGIN); + + /***************************************************************/ + GroupConstructors = new QGroupBox(myAction == 1 ? + tr("SMESH_MERGE_ELEMENTS") : + tr("SMESH_MERGE_NODES"), + this); + + QButtonGroup* ButtonGroup = new QButtonGroup(this); + QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors); + GroupConstructorsLayout->setSpacing(SPACING); + GroupConstructorsLayout->setMargin(MARGIN); + + RadioButton = new QRadioButton(GroupConstructors); + RadioButton->setIcon(myAction == 1 ? IconMergeElems : IconMergeNodes); + RadioButton->setChecked(true); + GroupConstructorsLayout->addWidget(RadioButton); + ButtonGroup->addButton(RadioButton, 0); + + /***************************************************************/ + // Controls for mesh defining + GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this); + QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh); + GroupMeshLayout->setSpacing(SPACING); + GroupMeshLayout->setMargin(MARGIN); + + TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh); + SelectMeshButton = new QPushButton(GroupMesh); + SelectMeshButton->setIcon(IconSelect); + LineEditMesh = new QLineEdit(GroupMesh); + LineEditMesh->setReadOnly(true); + + GroupMeshLayout->addWidget(TextLabelName); + GroupMeshLayout->addWidget(SelectMeshButton); + GroupMeshLayout->addWidget(LineEditMesh); + + /***************************************************************/ + // Controls for switch dialog behaviour + + TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this ); + GroupType = new QButtonGroup( this ); + QHBoxLayout* aTypeBoxLayout = new QHBoxLayout( TypeBox ); + aTypeBoxLayout->setMargin( MARGIN ); + aTypeBoxLayout->setSpacing( SPACING ); + + QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), TypeBox ); + QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL" ), TypeBox ); + GroupType->addButton( rb1, 0 ); + GroupType->addButton( rb2, 1 ); + aTypeBoxLayout->addWidget( rb1 ); + aTypeBoxLayout->addWidget( rb2 ); + + myTypeId = 0; + + /***************************************************************/ + // Controls for coincident elements detecting + GroupCoincident = new QGroupBox(myAction == 1 ? + tr("COINCIDENT_ELEMENTS") : + tr("COINCIDENT_NODES"), + this); + + QVBoxLayout* aCoincidentLayout = new QVBoxLayout(GroupCoincident); + aCoincidentLayout->setSpacing(SPACING); + aCoincidentLayout->setMargin(MARGIN); + + if (myAction == 0) { // case merge nodes + QWidget* foo = new QWidget(GroupCoincident); + TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), foo); + SpinBoxTolerance = new SMESHGUI_SpinBox(foo); + SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + + GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), foo); + GroupExclude->setCheckable( true ); + GroupExclude->setChecked( false ); + ListExclude = new QListWidget( GroupExclude ); + QVBoxLayout* GroupExcludeLayout = new QVBoxLayout(GroupExclude); + GroupExcludeLayout->setSpacing(SPACING); + GroupExcludeLayout->setMargin(MARGIN); + GroupExcludeLayout->addWidget(ListExclude); + + QGridLayout* fooLayout = new QGridLayout( foo ); + fooLayout->setSpacing(SPACING); + fooLayout->setMargin(0); + fooLayout->addWidget(TextLabelTolerance, 0, 0 ); + fooLayout->addWidget(SpinBoxTolerance, 0, 1 ); + fooLayout->addWidget(GroupExclude, 1, 0, 1, 2 ); + aCoincidentLayout->addWidget(foo); + } + else { + TextLabelTolerance = 0; + SpinBoxTolerance = 0; + GroupExclude = 0; + ListExclude = 0; + } + + GroupCoincidentWidget = new QWidget(GroupCoincident); + QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget); + GroupCoincidentLayout->setSpacing(SPACING); + GroupCoincidentLayout->setMargin(0); + + ListCoincident = new QListWidget(GroupCoincidentWidget); + ListCoincident->setSelectionMode(QListWidget::ExtendedSelection); + + DetectButton = new QPushButton(tr("DETECT"), GroupCoincidentWidget); + AddGroupButton = new QPushButton(tr("SMESH_BUT_ADD"), GroupCoincidentWidget); + RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincidentWidget); + + SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincidentWidget); + + GroupCoincidentLayout->addWidget(ListCoincident, 0, 0, 4, 2); + GroupCoincidentLayout->addWidget(DetectButton, 0, 2); + GroupCoincidentLayout->addWidget(AddGroupButton, 2, 2); + GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2); + GroupCoincidentLayout->addWidget(SelectAllCB, 4, 0, 1, 3); + GroupCoincidentLayout->setRowMinimumHeight(1, 10); + GroupCoincidentLayout->setRowStretch(1, 5); + + aCoincidentLayout->addWidget(GroupCoincidentWidget); + + /***************************************************************/ + // Controls for editing the selected group + GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this); + QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit); + GroupEditLayout->setSpacing(SPACING); + GroupEditLayout->setMargin(MARGIN); + + ListEdit = new QListWidget(GroupEdit); + //ListEdit->setRowMode(QListBox::FixedNumber); + //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn); + //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff); + ListEdit->setFlow( QListView::LeftToRight ); + ListEdit->setSelectionMode(QListWidget::ExtendedSelection); + + AddElemButton = new QPushButton(GroupEdit); + AddElemButton->setIcon(IconAdd); + RemoveElemButton = new QPushButton(GroupEdit); + RemoveElemButton->setIcon(IconRemove); + SetFirstButton = new QPushButton(GroupEdit); + SetFirstButton->setIcon(QPixmap(IconFirst)); + + GroupEditLayout->addWidget(ListEdit, 0, 0, 2, 1); + GroupEditLayout->addWidget(AddElemButton, 0, 1); + GroupEditLayout->addWidget(RemoveElemButton, 0, 2); + GroupEditLayout->addWidget(SetFirstButton, 1, 1, 1, 2); + + /***************************************************************/ + GroupButtons = new QGroupBox(this); + QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons); + GroupButtonsLayout->setSpacing(SPACING); + GroupButtonsLayout->setMargin(MARGIN); + + buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons); + buttonOk->setAutoDefault(true); + buttonOk->setDefault(true); + buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); + buttonApply->setAutoDefault(true); + buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons); + buttonCancel->setAutoDefault(true); + buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons); + buttonHelp->setAutoDefault(true); + + GroupButtonsLayout->addWidget(buttonOk); + GroupButtonsLayout->addSpacing(10); + GroupButtonsLayout->addWidget(buttonApply); + GroupButtonsLayout->addSpacing(10); + GroupButtonsLayout->addStretch(); + GroupButtonsLayout->addWidget(buttonCancel); + GroupButtonsLayout->addWidget(buttonHelp); + + /***************************************************************/ + DlgLayout->addWidget(GroupConstructors); + DlgLayout->addWidget(GroupMesh); + DlgLayout->addWidget(TypeBox); + DlgLayout->addWidget(GroupCoincident); + DlgLayout->addWidget(GroupEdit); + DlgLayout->addWidget(GroupButtons); + + GroupCoincidentWidget->setVisible( myAction != 0 ); + GroupCoincident->setVisible( myAction == 0 ); + //if GroupExclude->setVisible( myAction == 0 ); + GroupEdit->hide(); + + this->resize(10,10); + + Init(); // Initialisations +} + +//================================================================================= +// function : ~SMESHGUI_MergeDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_MergeDlg::~SMESHGUI_MergeDlg() +{ + delete myIdPreview; +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::Init() +{ + if (myAction == 0) { + SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision"); + SpinBoxTolerance->SetValue(1e-05); + } + + RadioButton->setChecked(true); + + GroupType->button(0)->setChecked(true); + + myEditCurrentArgument = (QWidget*)LineEditMesh; + + myActor = 0; + mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil(); + + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + myIsBusy = false; + + /* signals and slots connections */ + connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel())); + connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); + + connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); + connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect())); + connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup())); + connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup())); + connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup())); + connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool))); + connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup())); + connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement())); + connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement())); + connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) ); + connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); + + connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + /* to close dialog if study change */ + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); + + // Init Mesh field from selection + SelectionIntoArgument(); + + // Update Buttons + updateControls(); + + if (myAction == 0) + myHelpFileName = "merging_nodes_page.html"; + else + myHelpFileName = "merging_elements_page.html"; +} + +//================================================================================= +// function : FindGravityCenter() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, + std::list< gp_XYZ > & theGrCentersXYZ) +{ + if (!myActor) + return; + + SMDS_Mesh* aMesh = 0; + aMesh = myActor->GetObject()->GetMesh(); + if (!aMesh) + return; + + int nbNodes; + + TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); + for( ; idIter.More(); idIter.Next() ) { + const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key()); + if ( !anElem ) + continue; + + gp_XYZ anXYZ(0., 0., 0.); + SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator(); + for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) ); + } + anXYZ.Divide( nbNodes ); + + theGrCentersXYZ.push_back( anXYZ ); + } +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool SMESHGUI_MergeDlg::ClickOnApply() +{ + if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil()) + return false; + + try { + if (myTypeId == 0) + onDetect(); + + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + + SMESH::long_array_var anIds = new SMESH::long_array; + SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array; + + if ( ListCoincident->count() == 0) { + if (myAction == 0) + SUIT_MessageBox::warning(this, + tr("SMESH_WARNING"), + tr("SMESH_NO_NODES_DETECTED")); + else + SUIT_MessageBox::warning(this, + tr("SMESH_WARNING"), + tr("SMESH_NO_ELEMENTS_DETECTED")); + return false; + } + + aGroupsOfElements->length(ListCoincident->count()); + + int anArrayNum = 0; + for (int i = 0; i < ListCoincident->count(); i++) { + QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts); + + anIds->length(aListIds.count()); + for (int i = 0; i < aListIds.count(); i++) + anIds[i] = aListIds[i].toInt(); + + aGroupsOfElements[anArrayNum++] = anIds.inout(); + } + + if( myAction == 0 ) + aMeshEditor->MergeNodes (aGroupsOfElements.inout()); + else + aMeshEditor->MergeElements (aGroupsOfElements.inout()); + + if ( myTypeId == 0 ) { + if (myAction ==0) + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), + tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data())); + else + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), + tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data())); + } + + + } catch(...) { + } + + ListCoincident->clear(); + + SMESH::UpdateView(); + SMESHGUI::Modified(); + + return true; +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::ClickOnOk() +{ + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::ClickOnCancel() +{ + myIdPreview->SetPointsLabeled(false); + SMESH::SetPointRepresentation(false); + disconnect(mySelectionMgr, 0, this, 0); + disconnect(mySMESHGUI, 0, this, 0); + mySMESHGUI->ResetState(); + + mySelectionMgr->clearFilters(); + //mySelectionMgr->clearSelected(); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + + reject(); +} + +//================================================================================= +// function : ClickOnHelp() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::ClickOnHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} + +//================================================================================= +// function : onEditGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onEditGroup() +{ + QList selItems = ListCoincident->selectedItems(); + if ( selItems.count() != 1 ) { + ListEdit->clear(); + return; + } + + QStringList aNewIds; + + for (int i = 0; i < ListEdit->count(); i++ ) + aNewIds.append(ListEdit->item(i)->text()); + + ListCoincident->clearSelection(); + selItems.first()->setText(aNewIds.join(" ")); + selItems.first()->setSelected(true); +} + +//================================================================================= +// function : updateControls() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::updateControls() +{ + if (ListEdit->count() == 0) + SetFirstButton->setEnabled(false); + bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0)); + buttonOk->setEnabled(enable); + buttonApply->setEnabled(enable); +} + +//================================================================================= +// function : onDetect() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onDetect() +{ + if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) + return; + + try { + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + + ListCoincident->clear(); + ListEdit->clear(); + + SMESH::array_of_long_array_var aGroupsArray; + SMESH::ListOfIDSources_var aExcludeGroups = new SMESH::ListOfIDSources; + + SMESH::SMESH_IDSource_var src; + if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh ); + else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup ); + + switch (myAction) { + case 0 : + for ( int i = 0; GroupExclude->isChecked() && i < ListExclude->count(); i++ ) { + if ( ListExclude->item( i )->checkState() == Qt::Checked ) { + aExcludeGroups->length( aExcludeGroups->length()+1 ); + aExcludeGroups[ aExcludeGroups->length()-1 ] = SMESH::SMESH_IDSource::_duplicate( myGroups[i] ); + } + } + aMeshEditor->FindCoincidentNodesOnPartBut(src.in(), + SpinBoxTolerance->GetValue(), + aGroupsArray.out(), + aExcludeGroups.in()); + break; + case 1 : + aMeshEditor->FindEqualElements(src.in(), aGroupsArray.out()); + break; + } + + for (int i = 0; i < aGroupsArray->length(); i++) { + SMESH::long_array& aGroup = aGroupsArray[i]; + + QStringList anIDs; + for (int j = 0; j < aGroup.length(); j++) + anIDs.append(QString::number(aGroup[j])); + + ListCoincident->addItem(anIDs.join(" ")); + } + } catch(...) { + } + + ListCoincident->selectAll(); + updateControls(); +} + +//================================================================================= +// function : onSelectGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSelectGroup() +{ + if (myIsBusy || !myActor) + return; + myEditCurrentArgument = (QWidget*)ListCoincident; + + ListEdit->clear(); + + TColStd_MapOfInteger anIndices; + QList selItems = ListCoincident->selectedItems(); + QListWidgetItem* anItem; + QStringList aListIds; + + ListEdit->clear(); + + foreach(anItem, selItems) { + aListIds = anItem->text().split(" ", QString::SkipEmptyParts); + for (int i = 0; i < aListIds.count(); i++) + anIndices.Add(aListIds[i].toInt()); + } + + if (selItems.count() == 1) { + ListEdit->addItems(aListIds); + ListEdit->selectAll(); + } + + mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); + SALOME_ListIO aList; + aList.Append(myActor->getIO()); + mySelectionMgr->setSelectedObjects(aList,false); + + if (myAction == 0) { + myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } + else { + std::list< gp_XYZ > aGrCentersXYZ; + FindGravityCenter(anIndices, aGrCentersXYZ); + myIdPreview->SetElemsData( anIndices, aGrCentersXYZ); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } + + updateControls(); +} + +//================================================================================= +// function : onSelectAll() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSelectAll (bool isToggled) +{ + if ( isToggled ) + ListCoincident->selectAll(); + else + ListCoincident->clearSelection(); +} + +//================================================================================= +// function : onSelectElementFromGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSelectElementFromGroup() +{ + if (myIsBusy || !myActor) + return; + + TColStd_MapOfInteger anIndices; + QList selItems = ListEdit->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) + anIndices.Add(anItem->text().toInt()); + + SetFirstButton->setEnabled(selItems.count() == 1); + + mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); + SALOME_ListIO aList; + aList.Append(myActor->getIO()); + mySelectionMgr->setSelectedObjects(aList); + + if (myAction == 0) { + myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } + else { + std::list< gp_XYZ > aGrCentersXYZ; + FindGravityCenter(anIndices, aGrCentersXYZ); + myIdPreview->SetElemsData(anIndices, aGrCentersXYZ); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } +} + +//================================================================================= +// function : onAddGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onAddGroup() +{ + if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) + return; + + QString anIDs = ""; + int aNbElements = 0; + aNbElements = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs); + + if (aNbElements < 1) + return; + + ListCoincident->clearSelection(); + ListCoincident->addItem(anIDs); + int nbGroups = ListCoincident->count(); + if (nbGroups) { + ListCoincident->setCurrentRow(nbGroups-1); + ListCoincident->item(nbGroups-1)->setSelected(true); + } + else { + // VSR ? this code seems to be never executed!!! + ListCoincident->setCurrentRow(0); + //ListCoincident->setSelected(0, true); // VSR: no items - no selection + } + + updateControls(); +} + +//================================================================================= +// function : onRemoveGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onRemoveGroup() +{ + if (myEditCurrentArgument != (QWidget*)ListCoincident) + return; + myIsBusy = true; + + QList selItems = ListCoincident->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) + delete anItem; + + ListEdit->clear(); + updateControls(); + + myIsBusy = false; +} + +//================================================================================= +// function : onAddElement() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onAddElement() +{ + if (!myActor) + return; + myIsBusy = true; + + QString aListStr = ""; + int aNbNnodes = 0; + + aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); + if (aNbNnodes < 1) + return; + + QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts); + + for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) { + QList found = ListEdit->findItems(*it, Qt::MatchExactly); + if ( found.count() == 0 ) { + QListWidgetItem* anItem = new QListWidgetItem(*it); + ListEdit->addItem(anItem); + anItem->setSelected(true); + } + else { + QListWidgetItem* anItem; + foreach(anItem, found) anItem->setSelected(true); + } + } + + myIsBusy = false; + onEditGroup(); +} + +//================================================================================= +// function : onRemoveElement() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onRemoveElement() +{ + if (myEditCurrentArgument != (QWidget*)ListCoincident) + return; + myIsBusy = true; + + QList selItems = ListEdit->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) + delete anItem; + + myIsBusy = false; + onEditGroup(); +} + +//================================================================================= +// function : onSetFirst() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSetFirst() +{ + if (myEditCurrentArgument != (QWidget*)ListCoincident) + return; + myIsBusy = true; + + QList selItems = ListEdit->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) { + ListEdit->takeItem(ListEdit->row(anItem)); + ListEdit->insertItem(0, anItem); + } + + myIsBusy = false; + onEditGroup(); +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + disconnect(mySelectionMgr, 0, this, 0); + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + + if (send == SelectMeshButton) { + myEditCurrentArgument = (QWidget*)LineEditMesh; + SMESH::SetPointRepresentation(false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + if (myTypeId == 1) + mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + } + + myEditCurrentArgument->setFocus(); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + SelectionIntoArgument(); +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void SMESHGUI_MergeDlg::SelectionIntoArgument() +{ + if (myEditCurrentArgument == (QWidget*)LineEditMesh) { + QString aString = ""; + LineEditMesh->setText(aString); + + ListCoincident->clear(); + ListEdit->clear(); + myActor = 0; + QString aCurrentEntry = myEntry; + + int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); + if (nbSel != 1) { + myIdPreview->SetPointsLabeled(false); + SMESH::SetPointRepresentation(false); + mySelectionMgr->clearFilters(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + return; + } + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList); + + Handle(SALOME_InteractiveObject) IO = aList.First(); + myEntry = IO->getEntry(); + myMesh = SMESH::GetMeshByIO(IO); + + if (myMesh->_is_nil()) + return; + + LineEditMesh->setText(aString); + + myActor = SMESH::FindActorByEntry(IO->getEntry()); + if (!myActor) + myActor = SMESH::FindActorByObject(myMesh); + + if ( myActor && myTypeId ==1 ) { + mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil(); + mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + + if ((!SMESH::IObjectToInterface(IO)->_is_nil() || //SUBMESH OR GROUP + !SMESH::IObjectToInterface(IO)->_is_nil()) && + !SMESH::IObjectToInterface(IO)->_is_nil()) + mySubMeshOrGroup = SMESH::IObjectToInterface(IO); + + if (myAction == 0) { + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + } + else + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(CellSelection); + } + + // process groups + if ( myAction == 0 && !myMesh->_is_nil() && myEntry != aCurrentEntry ) { + myGroups.clear(); + ListExclude->clear(); + SMESH::ListOfGroups_var aListOfGroups = myMesh->GetGroups(); + for( int i = 0, n = aListOfGroups->length(); i < n; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; + if ( !aGroup->_is_nil() ) { // && aGroup->GetType() == SMESH::NODE + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + QListWidgetItem* item = new QListWidgetItem( aGroupName ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ); + item->setCheckState( Qt::Unchecked ); + ListExclude->addItem( item ); + } + } + } + } + + updateControls(); + } +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::DeactivateActiveDialog() +{ + if (GroupConstructors->isEnabled()) { + GroupConstructors->setEnabled(false); + TypeBox->setEnabled(false); + GroupMesh->setEnabled(false); + GroupCoincident->setEnabled(false); + GroupEdit->setEnabled(false); + GroupButtons->setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } + + mySelectionMgr->clearSelected(); + disconnect(mySelectionMgr, 0, this, 0); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + mySMESHGUI->EmitSignalDeactivateDialog(); + GroupConstructors->setEnabled(true); + TypeBox->setEnabled(true); + GroupMesh->setEnabled(true); + GroupCoincident->setEnabled(true); + GroupEdit->setEnabled(true); + GroupButtons->setEnabled(true); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + SelectionIntoArgument(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::enterEvent(QEvent*) +{ + if (!GroupConstructors->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::closeEvent(QCloseEvent*) +{ + /* same than click on cancel button */ + ClickOnCancel(); +} + +//======================================================================= +//function : hideEvent +//purpose : caused by ESC key +//======================================================================= +void SMESHGUI_MergeDlg::hideEvent (QHideEvent *) +{ + if (!isMinimized()) + ClickOnCancel(); +} + +//================================================================================= +// function : keyPressEvent() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::keyPressEvent( QKeyEvent* e) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + ClickOnHelp(); + } +} + +//================================================================================= +// function : onTypeChanged() +// purpose : the type radio button management +//================================================================================= +void SMESHGUI_MergeDlg::onTypeChanged (int id) +{ + if (myTypeId == id) + return; + + myTypeId = id; + switch (id) + { + case 0: // automatic + myIdPreview->SetPointsLabeled(false); + SMESH::SetPointRepresentation(false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->clearFilters(); + if (myAction == 0) + GroupCoincidentWidget->hide(); + else + GroupCoincident->hide(); + GroupEdit->hide(); + break; + + case 1: // manual + SMESH::UpdateView(); + + // Costruction of the logical filter + SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH); + SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP); + + QList aListOfFilters; + if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); + if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); + + myMeshOrSubMeshOrGroupFilter = + new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR); + + if (myAction == 0) { + GroupCoincidentWidget->show(); + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + } + else { + GroupCoincident->show(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(CellSelection); + } + GroupEdit->show(); + break; + } + updateControls(); + + qApp->processEvents(); + updateGeometry(); + resize(10,10); + + SelectionIntoArgument(); +} diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.h b/src/SMESHGUI/SMESHGUI_MergeDlg.h new file mode 100644 index 000000000..dd9458d61 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MergeDlg.h @@ -0,0 +1,175 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_MergeDlg.h +// Author : Open CASCADE S.A.S. +// +#ifndef SMESHGUI_MergeDlg_H +#define SMESHGUI_MergeDlg_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +// OCCT includes +#include + +// STL includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QCheckBox; +class QListWidget; +class QButtonGroup; +class SMESHGUI; +class SMESHGUI_SpinBox; +class SMESH_Actor; +class SVTK_Selector; +class LightApp_SelectionMgr; +class SUIT_SelectionFilter; +class TColStd_MapOfInteger; + +namespace SMESH +{ + struct TIdPreview; +} + +//================================================================================= +// class : SMESHGUI_MergeDlg +// purpose : +//================================================================================= +class SMESHGUI_EXPORT SMESHGUI_MergeDlg : public QDialog +{ + Q_OBJECT; + +public: + SMESHGUI_MergeDlg( SMESHGUI*, int ); + ~SMESHGUI_MergeDlg(); + +private: + void Init(); + void closeEvent( QCloseEvent* ); + void enterEvent( QEvent* ); /* mouse enter the QWidget */ + void hideEvent( QHideEvent* ); /* ESC key */ + void keyPressEvent( QKeyEvent* ); + void onEditGroup(); + + void FindGravityCenter( TColStd_MapOfInteger&, + std::list& ); + // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list + +private: + typedef QList GrpList; + + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + SVTK_Selector* mySelector; + + QWidget* myEditCurrentArgument; + + SMESH::SMESH_Mesh_var myMesh; + SMESH::SMESH_IDSource_var mySubMeshOrGroup; + SMESH_Actor* myActor; + SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter; + + SMESH::TIdPreview* myIdPreview; + + int myAction; + bool myIsBusy; + int myTypeId; + + // Widgets + QGroupBox* GroupConstructors; + QRadioButton* RadioButton; + + QGroupBox* GroupButtons; + QPushButton* buttonOk; + QPushButton* buttonCancel; + QPushButton* buttonApply; + QPushButton* buttonHelp; + + QGroupBox* GroupMesh; + QLabel* TextLabelName; + QPushButton* SelectMeshButton; + QLineEdit* LineEditMesh; + + QGroupBox* GroupCoincident; + QWidget* GroupCoincidentWidget; + QLabel* TextLabelTolerance; + SMESHGUI_SpinBox* SpinBoxTolerance; + QPushButton* DetectButton; + QListWidget* ListCoincident; + QPushButton* AddGroupButton; + QPushButton* RemoveGroupButton; + QCheckBox* SelectAllCB; + + QGroupBox* GroupEdit; + QListWidget* ListEdit; + QPushButton* AddElemButton; + QPushButton* RemoveElemButton; + QPushButton* SetFirstButton; + + QGroupBox* GroupExclude; + QListWidget* ListExclude; + + QGroupBox* TypeBox; + QButtonGroup* GroupType; + + QString myHelpFileName; + + QString myEntry; + GrpList myGroups; + + private slots: + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void ClickOnHelp(); + void updateControls(); + void onDetect(); + void onAddGroup(); + void onRemoveGroup(); + void onSelectGroup(); + void onSelectAll( bool ); + void onSelectElementFromGroup(); + void onAddElement(); + void onRemoveElement(); + void onSetFirst(); + void SetEditCurrentArgument(); + void SelectionIntoArgument(); + void DeactivateActiveDialog(); + void ActivateThisDialog(); + void onTypeChanged(int); +}; + +#endif // SMESHGUI_MergeDlg_H diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx index b877f7fc0..beafb18b2 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -112,9 +113,9 @@ SMESHGUI_MeshTab::SMESHGUI_MeshTab( QWidget* theParent ) // Connect signals and slots for ( int i = MainHyp; i <= AddHyp; i++ ) { - connect( myCreateHyp[ i ], SIGNAL( clicked() ), SLOT( onCreateHyp() ) ); - connect( myEditHyp[ i ], SIGNAL( clicked() ), SLOT( onEditHyp() ) ); - connect( myHyp[ i ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) ); + connect( myCreateHyp[ i ], SIGNAL( clicked() ) , SLOT( onCreateHyp() ) ); + connect( myEditHyp[ i ] , SIGNAL( clicked() ) , SLOT( onEditHyp() ) ); + connect( myHyp[ i ] , SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) ); } connect( myHyp[ Algo ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) ); @@ -381,7 +382,7 @@ SMESHGUI_MeshDlg::SMESHGUI_MeshDlg( const bool theToCreate, const bool theIsMesh myHypoSetButton->setText( tr( "HYPOTHESES_SETS" ) ); myHypoSetButton->setEnabled( false ); myHypoSetButton->setSizePolicy( QSizePolicy::MinimumExpanding, - myHypoSetButton->sizePolicy().verticalPolicy() ); + myHypoSetButton->sizePolicy().verticalPolicy() ); // Fill layout QGridLayout* aLay = new QGridLayout( mainFrame() ); @@ -478,9 +479,13 @@ void SMESHGUI_MeshDlg::setMaxHypoDim( const int maxDim ) const int DIM = maxDim; for ( int dim = Dim0D; dim <= Dim3D; ++dim ) { bool enable = ( dim <= DIM ); - if ( !enable ) + if ( !enable ) { myTabs[ dim ]->reset(); - myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ dim ] ), enable ); + disableTab( dim ); + } + else { + enableTab( dim ); + } } // deselect desabled tab if ( !myTabWg->isTabEnabled( myTabWg->currentIndex() ) ) @@ -542,14 +547,14 @@ void SMESHGUI_MeshDlg::setGeomPopupEnabled( const bool enable ) myGeomPopup->addAction( tr("DIRECT_GEOM_SELECTION") )->setData( DIRECT_GEOM_INDEX ); myGeomPopup->addAction( tr("GEOM_BY_MESH_ELEM_SELECTION") )->setData( GEOM_BY_MESH_INDEX ); connect( myGeomPopup, SIGNAL( triggered( QAction* ) ), SLOT( onGeomPopup( QAction* ) ) ); - connect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) )); + connect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) )); } } else { disconnect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) )); if ( myGeomPopup ) { - delete myGeomPopup; - myGeomPopup = 0; + delete myGeomPopup; + myGeomPopup = 0; } } } @@ -564,6 +569,7 @@ void SMESHGUI_MeshDlg::setGeomPopupEnabled( const bool enable ) //================================================================================ void SMESHGUI_MeshDlg::disableTab(const int theTabId) { myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ), false ); + if ( theTabId == Dim3D ) myHypoSetButton->setEnabled( false ); } //================================================================================ @@ -574,6 +580,20 @@ void SMESHGUI_MeshDlg::disableTab(const int theTabId) { //================================================================================ void SMESHGUI_MeshDlg::enableTab(const int theTabId) { myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ), true ); + if ( theTabId == Dim3D ) { + QMenu* aHypoSetPopup = myHypoSetButton->menu(); + myHypoSetButton->setEnabled( aHypoSetPopup && !aHypoSetPopup->actions().isEmpty() ); + } +} + +//================================================================================ +/*! + * \brief Check if tab enabled + * \param int - tab ID + */ +//================================================================================ +bool SMESHGUI_MeshDlg::isTabEnabled(const int theTabId) const { + return myTabWg->isTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ) ); } void SMESHGUI_MeshDlg::onGeomSelectionButton(bool isBtnOn) @@ -586,3 +606,12 @@ void SMESHGUI_MeshDlg::onGeomPopup( QAction* a ) { emit geomSelectionByMesh( a->data().toInt() == GEOM_BY_MESH_INDEX ); } + +int SMESHGUI_MeshDlg::getActiveObject() +{ + for (int i = 0; i < 3; ++i ) + if ( isObjectShown( i ) && + (( QToolButton* )objectWg( i, Btn ))->isChecked()) + return i; + return -1; +} diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.h b/src/SMESHGUI/SMESHGUI_MeshDlg.h index 34ee3a565..212449ff9 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -71,7 +72,8 @@ public: void setGeomPopupEnabled( const bool ); void disableTab(const int); void enableTab(const int); - + bool isTabEnabled(const int) const; + int getActiveObject(); signals: void hypoSet( const QString& ); diff --git a/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx b/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx index 8bed7191f..ac71ddbc4 100644 --- a/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshEditPreview.cxx // Author : Open CASCADE S.A.S. @@ -72,6 +73,11 @@ SMESHGUI_MeshEditPreview::SMESHGUI_MeshEditPreview(SVTK_ViewWindow* theViewWindo myPreviewActor->VisibilityOn(); myPreviewActor->PickableOff(); + vtkFloatingPointType aFactor,aUnits; + myPreviewActor->SetResolveCoincidentTopology(true); + myPreviewActor->GetPolygonOffsetParameters(aFactor,aUnits); + myPreviewActor->SetPolygonOffsetParameters(aFactor,0.2*aUnits); + vtkFloatingPointType anRGB[3]; SMESH::GetColor( "SMESH", "selection_element_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); SetColor( anRGB[0], anRGB[1], anRGB[2] ); @@ -122,6 +128,7 @@ vtkIdType getCellType( const SMDSAbs_ElementType theType, else if ( theNbNodes == 4 ) return VTK_QUAD; else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE; else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD; + else if ( theNbNodes == 9 ) return VTK_BIQUADRATIC_QUAD; else return VTK_EMPTY_CELL; case SMDSAbs_Volume: @@ -130,18 +137,11 @@ vtkIdType getCellType( const SMDSAbs_ElementType theType, 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==15 ) { - return VTK_QUADRATIC_WEDGE; - } - else if ( theNbNodes==13 ) { - return VTK_CONVEX_POINT_SET; - } + else if ( theNbNodes == 10 ) return VTK_QUADRATIC_TETRA; + else if ( theNbNodes == 20 ) return VTK_QUADRATIC_HEXAHEDRON; + else if ( theNbNodes == 27 ) return VTK_TRIQUADRATIC_HEXAHEDRON; + else if ( theNbNodes == 15 ) return VTK_QUADRATIC_WEDGE; + else if ( theNbNodes == 13 ) return VTK_QUADRATIC_PYRAMID;//VTK_CONVEX_POINT_SET; else return VTK_EMPTY_CELL; default: return VTK_EMPTY_CELL; diff --git a/src/SMESHGUI/SMESHGUI_MeshEditPreview.h b/src/SMESHGUI/SMESHGUI_MeshEditPreview.h index 1b5fb3c9a..4a0f840fe 100644 --- a/src/SMESHGUI/SMESHGUI_MeshEditPreview.h +++ b/src/SMESHGUI/SMESHGUI_MeshEditPreview.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshEditPreview.h // Author : Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx new file mode 100644 index 000000000..25ee42a9a --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -0,0 +1,2175 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_MeshInfo.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#include "SMESHGUI_MeshInfo.h" + +#include "SMESH_Actor.h" +#include "SMESHGUI.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMDSAbs_ElementType.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_BallElement.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utilities.h" + +#include +#include CORBA_SERVER_HEADER(GEOM_Gen) + +const int SPACING = 6; +const int MARGIN = 9; +const int MAXITEMS = 10; +const int GROUPS_ID = 100; +const int SUBMESHES_ID = 200; + +/*! + \class ExtraWidget + \internal +*/ + +class ExtraWidget : public QWidget +{ +public: + ExtraWidget( QWidget*, bool = false ); + ~ExtraWidget(); + + void updateControls( int, int, int = MAXITEMS ); + +public: + QLabel* current; + QPushButton* prev; + QPushButton* next; + bool brief; +}; + +ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b ) +{ + current = new QLabel( this ); + current->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); + prev = new QPushButton( tr( "<<" ), this ); + next = new QPushButton( tr( ">>" ), this ); + QHBoxLayout* hbl = new QHBoxLayout( this ); + hbl->setContentsMargins( 0, SPACING, 0, 0 ); + hbl->setSpacing( SPACING ); + hbl->addStretch(); + hbl->addWidget( current ); + hbl->addWidget( prev ); + hbl->addWidget( next ); +} + +ExtraWidget::~ExtraWidget() +{ +} + +void ExtraWidget::updateControls( int total, int index, int blockSize ) +{ + setVisible( total > blockSize ); + QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" ); + current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total ) ).arg( total ) ); + prev->setEnabled( index > 0 ); + next->setEnabled( (index+1)*blockSize < total ); +} + +/*! + \class SMESHGUI_MeshInfo + \brief Base mesh information widget + + Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source. +*/ + +/*! + \brief Constructor. + \param parent parent widget +*/ +SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) + : QFrame( parent ), myWidgets( iElementsEnd ) +{ + setFrameStyle( StyledPanel | Sunken ); + + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + + int index = 0; + + // object + QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this ); + QLabel* aName = createField(); + aName->setMinimumWidth( 150 ); + QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this ); + QLabel* aObj = createField(); + aObj->setMinimumWidth( 150 ); + myWidgets[ index++ ] << aNameLab << aName; + myWidgets[ index++ ] << aObjLab << aObj; + + // nodes + QWidget* aNodesLine = createLine(); + QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this ); + QLabel* aNodes = createField(); + myWidgets[ index++ ] << aNodesLine; + myWidgets[ index++ ] << aNodesLab << aNodes; + + // elements + QWidget* aElemLine = createLine(); + QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this ); + QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this ); + QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this ); + QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this ); + myWidgets[ index++ ] << aElemLine; + myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad; + + // ... 0D elements + QWidget* a0DLine = createLine(); + QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this ); + QLabel* a0DTotal = createField(); + myWidgets[ index++ ] << a0DLine; + myWidgets[ index++ ] << a0DLab << a0DTotal; + + // ... Ball elements + QWidget* aBallLine = createLine(); + QLabel* aBallLab = new QLabel( tr( "BALL_LAB" ), this ); + QLabel* aBallTotal = createField(); + myWidgets[ index++ ] << aBallLine; + myWidgets[ index++ ] << aBallLab << aBallTotal; + + // ... 1D elements + QWidget* a1DLine = createLine(); + QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this ); + QLabel* a1DTotal = createField(); + QLabel* a1DLin = createField(); + QLabel* a1DQuad = createField(); + myWidgets[ index++ ] << a1DLine; + myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad; + + // ... 2D elements + QWidget* a2DLine = createLine(); + QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this ); + QLabel* a2DTotal = createField(); + QLabel* a2DLin = createField(); + QLabel* a2DQuad = createField(); + QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this ); + QLabel* a2DTriTotal = createField(); + QLabel* a2DTriLin = createField(); + QLabel* a2DTriQuad = createField(); + QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this ); + QLabel* a2DQuaTotal = createField(); + QLabel* a2DQuaLin = createField(); + QLabel* a2DQuaQuad = createField(); + QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this ); + QLabel* a2DPolTotal = createField(); + myWidgets[ index++ ] << a2DLine; + myWidgets[ index++ ] << a2DLab << a2DTotal << a2DLin << a2DQuad; + myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad; + myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad; + myWidgets[ index++ ] << a2DPolLab << a2DPolTotal; + + // ... 3D elements + QWidget* a3DLine = createLine(); + QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this ); + QLabel* a3DTotal = createField(); + QLabel* a3DLin = createField(); + QLabel* a3DQuad = createField(); + QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this ); + QLabel* a3DTetTotal = createField(); + QLabel* a3DTetLin = createField(); + QLabel* a3DTetQuad = createField(); + QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this ); + QLabel* a3DHexTotal = createField(); + QLabel* a3DHexLin = createField(); + QLabel* a3DHexQuad = createField(); + QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this ); + QLabel* a3DPyrTotal = createField(); + QLabel* a3DPyrLin = createField(); + QLabel* a3DPyrQuad = createField(); + QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this ); + QLabel* a3DPriTotal = createField(); + QLabel* a3DPriLin = createField(); + QLabel* a3DPriQuad = createField(); + QLabel* a3DHexPriLab = new QLabel( tr( "HEX_PRISMS_LAB" ), this ); + QLabel* a3DHexPriTotal = createField(); + QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this ); + QLabel* a3DPolTotal = createField(); + myWidgets[ index++ ] << a3DLine; + myWidgets[ index++ ] << a3DLab << a3DTotal << a3DLin << a3DQuad; + myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad; + myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad; + myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad; + myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad; + myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal; + myWidgets[ index++ ] << a3DPolLab << a3DPolTotal; + + myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this ); + myLoadBtn->setAutoDefault( true ); + connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) ); + + setFontAttributes( aNameLab, Bold ); + setFontAttributes( aObjLab, Bold ); + setFontAttributes( aNodesLab, Bold ); + setFontAttributes( aElemLab, Bold ); + setFontAttributes( aElemTotal, Italic ); + setFontAttributes( aElemLin, Italic ); + setFontAttributes( aElemQuad, Italic ); + setFontAttributes( a0DLab, Bold ); + setFontAttributes( aBallLab, Bold ); + setFontAttributes( a1DLab, Bold ); + setFontAttributes( a2DLab, Bold ); + setFontAttributes( a3DLab, Bold ); + + l->addWidget( aNameLab, 0, 0 ); + l->addWidget( aName, 0, 1, 1, 3 ); + l->addWidget( aObjLab, 1, 0 ); + l->addWidget( aObj, 1, 1, 1, 3 ); + l->addWidget( aNodesLine, 2, 0, 1, 4 ); + l->addWidget( aNodesLab, 3, 0 ); + l->addWidget( aNodes, 3, 1 ); + l->addWidget( aElemLine, 4, 0, 1, 4 ); + l->addWidget( aElemLab, 5, 0 ); + l->addWidget( aElemTotal, 5, 1 ); + l->addWidget( aElemLin, 5, 2 ); + l->addWidget( aElemQuad, 5, 3 ); + l->addWidget( a0DLine, 6, 1, 1, 3 ); + l->addWidget( a0DLab, 7, 0 ); + l->addWidget( a0DTotal, 7, 1 ); + l->addWidget( aBallLine, 8, 1, 1, 3 ); + l->addWidget( aBallLab, 9, 0 ); + l->addWidget( aBallTotal, 9, 1 ); + l->addWidget( a1DLine, 10, 1, 1, 3 ); + l->addWidget( a1DLab, 11, 0 ); + l->addWidget( a1DTotal, 11, 1 ); + l->addWidget( a1DLin, 11, 2 ); + l->addWidget( a1DQuad, 11, 3 ); + l->addWidget( a2DLine, 12, 1, 1, 3 ); + l->addWidget( a2DLab, 13, 0 ); + l->addWidget( a2DTotal, 13, 1 ); + l->addWidget( a2DLin, 13, 2 ); + l->addWidget( a2DQuad, 13, 3 ); + l->addWidget( a2DTriLab, 14, 0 ); + l->addWidget( a2DTriTotal, 14, 1 ); + l->addWidget( a2DTriLin, 14, 2 ); + l->addWidget( a2DTriQuad, 14, 3 ); + l->addWidget( a2DQuaLab, 15, 0 ); + l->addWidget( a2DQuaTotal, 15, 1 ); + l->addWidget( a2DQuaLin, 15, 2 ); + l->addWidget( a2DQuaQuad, 15, 3 ); + l->addWidget( a2DPolLab, 16, 0 ); + l->addWidget( a2DPolTotal, 16, 1 ); + l->addWidget( a3DLine, 17, 1, 1, 3 ); + l->addWidget( a3DLab, 18, 0 ); + l->addWidget( a3DTotal, 18, 1 ); + l->addWidget( a3DLin, 18, 2 ); + l->addWidget( a3DQuad, 18, 3 ); + l->addWidget( a3DTetLab, 19, 0 ); + l->addWidget( a3DTetTotal, 19, 1 ); + l->addWidget( a3DTetLin, 19, 2 ); + l->addWidget( a3DTetQuad, 19, 3 ); + l->addWidget( a3DHexLab, 20, 0 ); + l->addWidget( a3DHexTotal, 20, 1 ); + l->addWidget( a3DHexLin, 20, 2 ); + l->addWidget( a3DHexQuad, 20, 3 ); + l->addWidget( a3DPyrLab, 21, 0 ); + l->addWidget( a3DPyrTotal, 21, 1 ); + l->addWidget( a3DPyrLin, 21, 2 ); + l->addWidget( a3DPyrQuad, 21, 3 ); + l->addWidget( a3DPriLab, 22, 0 ); + l->addWidget( a3DPriTotal, 22, 1 ); + l->addWidget( a3DPriLin, 22, 2 ); + l->addWidget( a3DPriQuad, 22, 3 ); + l->addWidget( a3DHexPriLab, 23, 0 ); + l->addWidget( a3DHexPriTotal, 23, 1 ); + l->addWidget( a3DPolLab, 24, 0 ); + l->addWidget( a3DPolTotal, 24, 1 ); + l->addWidget( myLoadBtn, 25, 1, 1, 3 ); + l->setColumnStretch( 0, 0 ); + l->setColumnStretch( 1, 5 ); + l->setColumnStretch( 2, 5 ); + l->setColumnStretch( 3, 5 ); + l->setRowStretch( 23, 5 ); + + clear(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo() +{ +} + +/*! + \brief Show information on the mesh object. + \param obj object being processed (mesh, sub-mesh, group, ID source) +*/ +void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +{ + clear(); + if ( !CORBA::is_nil( obj ) ) { + _PTR(SObject) sobj = SMESH::ObjectToSObject( obj ); + if ( sobj ) + myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() ); + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj ); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj ); + if ( !aMesh->_is_nil() ) { + myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) ); + } + else if ( !aSubMesh->_is_nil() ) { + myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) ); + } + else if ( !aGroup->_is_nil() ) { + QString objType; + switch( aGroup->GetType() ) { + case SMESH::NODE: + objType = tr( "OBJECT_GROUP_NODES" ); + break; + case SMESH::EDGE: + objType = tr( "OBJECT_GROUP_EDGES" ); + break; + case SMESH::FACE: + objType = tr( "OBJECT_GROUP_FACES" ); + break; + case SMESH::VOLUME: + objType = tr( "OBJECT_GROUP_VOLUMES" ); + break; + case SMESH::ELEM0D: + objType = tr( "OBJECT_GROUP_0DELEMS" ); + break; + case SMESH::BALL: + objType = tr( "OBJECT_GROUP_BALLS" ); + break; + default: + objType = tr( "OBJECT_GROUP" ); + break; + } + myWidgets[iObject][iSingle]->setProperty( "text", objType ); + } + SMESH::long_array_var info = obj->GetMeshInfo(); + myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) ); + myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) ); + myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) ); + long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge]; + myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( nbEdges ) ); + myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) ); + myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) ); + long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle]; + long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; + long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon]; + long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle]; + myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ) ); + myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( nb2DLinear ) ); + myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( nb2DQuadratic ) ); + myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( nbTriangles ) ); + myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) ); + myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) ); + myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( nbQuadrangles ) ); + myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) ); + myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] )); + myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) ); + long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra]; + long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa]; + long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid]; + long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta]; + long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism]; + long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta]; + myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( nb3DLinear + nb3DQuadratic ) ); + myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( nb3DLinear ) ); + myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( nb3DQuadratic ) ); + myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( nbTetrahedrons ) ); + myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) ); + myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( nbHexahedrons ) ); + myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) ); + myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] ) ); + myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( nbPyramids ) ); + myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) ); + myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) ); + myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( nbPrisms ) ); + myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) ); + myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) ); + myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) ); + myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) ); + + // before full loading from study file, type of elements in a sub-mesh can't be defined + // in some cases + bool infoOK = obj->IsMeshInfoCorrect(); + myLoadBtn->setVisible( !infoOK ); + if ( !infoOK ) + { + // two options: + // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh) + // 2. No info at all (for a group on geom or filter) + bool hasAnyInfo = false; + for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i ) + hasAnyInfo = info[i]; + if ( hasAnyInfo ) // believe it is a sub-mesh + { + if ( nb2DLinear + nb2DQuadratic > 0 ) + { + myWidgets[i2D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", "?" ); + myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); + } + else if ( nb3DLinear + nb3DQuadratic > 0 ) + { + myWidgets[i3D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" ); + } + } + else + { + myWidgets[iNodes][iTotal] ->setProperty( "text", "?" ); + myWidgets[i0D][iTotal] ->setProperty( "text", "?" ); + myWidgets[iBalls][iTotal] ->setProperty( "text", "?" ); + myWidgets[i1D][iTotal] ->setProperty( "text", "?" ); + myWidgets[i1D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i1D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2D][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", "?" ); + myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i2DPolygons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3D][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3D][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3D][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iLinear] ->setProperty( "text", "?" ); + myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", "?" ); + myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", "?" ); + myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", "?" ); + } + } + } +} + +/*! + \brief Load mesh from a study file +*/ +void SMESHGUI_MeshInfo::loadMesh() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + SMESH::SMESH_Mesh_var mesh = obj->GetMesh(); + if ( !mesh->_is_nil() ) + { + mesh->Load(); + showInfo( obj ); + } + } + } +} + +/*! + \brief Reset the widget to the initial state (nullify all fields). +*/ +void SMESHGUI_MeshInfo::clear() +{ + myWidgets[iName][iSingle] ->setProperty( "text", QString() ); + myWidgets[iObject][iSingle] ->setProperty( "text", QString() ); + myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i0D][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i1D][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i1D][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i1D][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2D][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2D][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2D][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DTriangles][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DTriangles][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DTriangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DQuadrangles][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DQuadrangles][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DPolygons][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3D][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3D][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3D][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DTetrahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DTetrahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexahedrons][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexahedrons][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPyramids][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPyramids][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPyramids][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPrisms][iLinear] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPrisms][iQuadratic] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexaPrisms][iTotal] ->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPolyhedrons][iTotal] ->setProperty( "text", QString::number( 0 ) ); +} + +/*! + \brief Create info field + \return new info field +*/ +QLabel* SMESHGUI_MeshInfo::createField() +{ + QLabel* lab = new QLabel( this ); + lab->setFrameStyle( StyledPanel | Sunken ); + lab->setAlignment( Qt::AlignCenter ); + lab->setAutoFillBackground( true ); + QPalette pal = lab->palette(); + pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) ); + lab->setPalette( pal ); + lab->setMinimumWidth( 70 ); + return lab; +} + +/*! + \brief Create horizontal rule. + \return new line object +*/ +QWidget* SMESHGUI_MeshInfo::createLine() +{ + QFrame* line = new QFrame( this ); + line->setFrameStyle( HLine | Sunken ); + return line; +} + +/*! + \brief Change widget font attributes (bold, italic, ...). + \param w widget + \param attr font attributes (XORed flags) + \param val value to be set to attributes +*/ +void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val ) +{ + if ( w && attr ) { + QFont f = w->font(); + if ( attr & Bold ) f.setBold( val ); + if ( attr & Italic ) f.setItalic( val ); + w->setFont( f ); + } +} + +/*! + \brief Show/hide group(s) of fields. + \param start beginning of the block + \param end end of the block + \param on visibility flag +*/ +void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on ) +{ + start = qMax( 0, start ); + end = qMin( end, (int)iElementsEnd ); + for ( int i = start; i < end; i++ ) { + wlist wl = myWidgets[i]; + foreach ( QWidget* w, wl ) w->setVisible( on ); + } +} + +/*! + \class SMESHGUI_ElemInfo + \brief Base class for the mesh element information widget. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ) +: QWidget( parent ), myActor( 0 ), myIsElement( -1 ) +{ + myFrame = new QWidget( this ); + myExtra = new ExtraWidget( this ); + QVBoxLayout* vbl = new QVBoxLayout( this ); + vbl->setMargin( 0 ); + vbl->setSpacing( 0 ); + vbl->addWidget( myFrame ); + vbl->addWidget( myExtra ); + connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) ); + connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) ); + clear(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo() +{ +} + +/*! + \brief Set mesh data source (actor) + \param actor mesh object actor +*/ +void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor ) +{ + if ( myActor != actor ) { + myActor = actor; + myIsElement = -1; + clear(); + } +} + +/*! + \brief Show mesh element information + \param id mesh node / element ID + \param isElem show mesh element information if \c true or mesh node information if \c false +*/ +void SMESHGUI_ElemInfo::showInfo( long id, bool isElem ) +{ + QSet ids; + ids << id; + showInfo( ids, isElem ); +} + +/*! + \brief Show mesh element information + \param ids mesh nodes / elements identifiers + \param isElem show mesh element information if \c true or mesh node information if \c false +*/ +void SMESHGUI_ElemInfo::showInfo( QSet ids, bool isElem ) +{ + QList newIds = ids.toList(); + qSort( newIds ); + if ( myIDs == newIds && myIsElement == isElem ) return; + + myIDs = newIds; + myIsElement = isElem; + myIndex = 0; + updateControls(); + information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) ); +} + +/*! + \brief Clear mesh element information widget +*/ +void SMESHGUI_ElemInfo::clear() +{ + myIDs.clear(); + myIndex = 0; + clearInternal(); + updateControls(); +} + +/*! + \brief Get central area widget + \return central widget +*/ +QWidget* SMESHGUI_ElemInfo::frame() const +{ + return myFrame; +} + +/*! + \brief Get actor + \return actor being used +*/ +SMESH_Actor* SMESHGUI_ElemInfo::actor() const +{ + return myActor; +} + +/*! + \brief Get current info mode. + \return \c true if mesh element information is shown or \c false if node information is shown +*/ +bool SMESHGUI_ElemInfo::isElements() const +{ + return myIsElement; +} + +/*! + \fn void SMESHGUI_ElemInfo::information( const QList& ids ) + \brief Show information on the specified nodes / elements + + This function is to be redefined in sub-classes. + + \param ids nodes / elements identifiers information is to be shown on +*/ + +/*! + \brief Internal clean-up (reset widget) +*/ +void SMESHGUI_ElemInfo::clearInternal() +{ +} + +/*! + \brief Get node connectivity + \param node mesh node + \return node connectivity map +*/ +SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node ) +{ + Connectivity elmap; + if ( node ) { + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while ( it && it->more() ) { + const SMDS_MeshElement* ne = it->next(); + elmap[ ne->GetType() ] << ne->GetID(); + } + } + return elmap; +} + +/*! + \brief Format connectivity data to string representation + \param connectivity connetivity map + \param type element type + \return string representation of the connectivity +*/ +QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type ) +{ + QStringList str; + if ( connectivity.contains( type ) ) { + QList elements = connectivity[ type ]; + qSort( elements ); + foreach( int id, elements ) + str << QString::number( id ); + } + return str.join( " " ); +} + +/*! + \brief Calculate gravity center of the mesh element + \param element mesh element +*/ +SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element ) +{ + XYZ xyz; + if ( element ) { + SMDS_ElemIteratorPtr nodeIt = element->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + xyz.add( node->X(), node->Y(), node->Z() ); + } + xyz.divide( element->NbNodes() ); + } + return xyz; +} + +/*! + \brief This slot is called from "Show Previous" button click. + Shows information on the previous group of the items. +*/ +void SMESHGUI_ElemInfo::showPrevious() +{ + myIndex = qMax( 0, myIndex-1 ); + updateControls(); + information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) ); +} + +/*! + \brief This slot is called from "Show Next" button click. + Shows information on the next group of the items. +*/ +void SMESHGUI_ElemInfo::showNext() +{ + myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS ); + updateControls(); + information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) ); +} + +/*! + \brief Update widgets state +*/ +void SMESHGUI_ElemInfo::updateControls() +{ + myExtra->updateControls( myIDs.count(), myIndex ); +} + +/*! + \class SMESHGUI_SimpleElemInfo + \brief Represents mesh element information in the simple text area. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent ) +: SMESHGUI_ElemInfo( parent ) +{ + myInfo = new QTextBrowser( frame() ); + QVBoxLayout* l = new QVBoxLayout( frame() ); + l->setMargin( 0 ); + l->addWidget( myInfo ); +} + +/*! + \brief Show mesh element information + \param ids mesh nodes / elements identifiers +*/ +void SMESHGUI_SimpleElemInfo::information( const QList& ids ) +{ + clearInternal(); + + if ( actor() ) { + int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + foreach ( long id, ids ) { + if ( !isElements() ) { + // + // show node info + // + const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id ); + if ( !node ) return; + + // node ID + myInfo->append( QString( "%1 #%2" ).arg( tr( "NODE" ) ).arg( id ) ); + // separator + myInfo->append( "" ); + // coordinates + myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ). + arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // separator + myInfo->append( "" ); + // connectivity + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + myInfo->append( QString( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Ball ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "BALL_ELEMENTS" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); + } + else { + myInfo->append( QString( "%1" ).arg( tr( "FREE_NODE" ) ).arg( id ) ); + } + } + else { + // + // show element info + // + const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( !e ) return; + + // element ID && type + QString stype; + switch( e->GetType() ) { + case SMDSAbs_0DElement: + stype = tr( "0D ELEMENT" ); break; + case SMDSAbs_Ball: + stype = tr( "BALL" ); break; + case SMDSAbs_Edge: + stype = tr( "EDGE" ); break; + case SMDSAbs_Face: + stype = tr( "FACE" ); break; + case SMDSAbs_Volume: + stype = tr( "VOLUME" ); break; + default: + break; + } + if ( stype.isEmpty() ) return; + myInfo->append( QString( "%1 #%2" ).arg( stype ).arg( id ) ); + // separator + myInfo->append( "" ); + // geometry type + QString gtype; + switch( e->GetEntityType() ) { + case SMDSEntity_Triangle: + case SMDSEntity_Quad_Triangle: + gtype = tr( "TRIANGLE" ); break; + case SMDSEntity_Quadrangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + gtype = tr( "QUADRANGLE" ); break; + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: + gtype = tr( "POLYGON" ); break; + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: + gtype = tr( "TETRAHEDRON" ); break; + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + gtype = tr( "PYRAMID" ); break; + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + gtype = tr( "HEXAHEDRON" ); break; + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + gtype = tr( "PRISM" ); break; + case SMDSEntity_Hexagonal_Prism: + gtype = tr( "HEX_PRISM" ); break; + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: + gtype = tr( "POLYHEDRON" ); break; + default: + break; + } + if ( !gtype.isEmpty() ) + myInfo->append( QString( "%1: %2" ).arg( tr( "TYPE" ) ).arg( gtype ) ); + // quadratic flag and gravity center (any element except 0D) + if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) { + // quadratic flag + myInfo->append( QString( "%1? %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) ); + // separator + myInfo->append( "" ); + // gravity center + XYZ gc = gravityCenter( e ); + myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) ); + } + if ( const SMDS_BallElement* ball = dynamic_cast( e )) { + // ball diameter + myInfo->append( QString( "%1: %2" ).arg( tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() )); + } + // separator + myInfo->append( "" ); + // connectivity + SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); + for ( int idx = 1; nodeIt->more(); idx++ ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + // node number and ID + myInfo->append( QString( "%1 %2/%3 - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) ); + // node coordinates + myInfo->append( QString( "%1: (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ). + arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ). + arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // node connectivity + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + myInfo->append( QString( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); + } + else { + myInfo->append( QString( "%1" ).arg( tr( "FREE_NODE" ) ).arg( id ) ); + } + } + } + // separator + if ( ids.count() > 1 ) { + myInfo->append( "" ); + myInfo->append( "------" ); + myInfo->append( "" ); + } + } + } +} + +/*! + \brief Internal clean-up (reset widget) +*/ +void SMESHGUI_SimpleElemInfo::clearInternal() +{ + myInfo->clear(); +} + +/*! + \class SMESHGUI_TreeElemInfo::ItemDelegate + \brief Item delegate for tree mesh info widget + \internal +*/ +class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate +{ +public: + ItemDelegate( QObject* ); + QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const; +}; + +/*! + \brief Constructor + \internal +*/ +SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent ) +{ +} + +/*! + \brief Create item editor widget + \internal +*/ +QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index ); + if ( qobject_cast( w ) ) qobject_cast( w )->setReadOnly( true ); + return w; +} + +/*! + \class SMESHGUI_TreeElemInfo + \brief Represents mesh element information in the tree-like form. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent ) +: SMESHGUI_ElemInfo( parent ) +{ + myInfo = new QTreeWidget( frame() ); + myInfo->setColumnCount( 2 ); + myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) ); + myInfo->header()->setStretchLastSection( true ); + myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents ); + myInfo->setItemDelegate( new ItemDelegate( myInfo ) ); + QVBoxLayout* l = new QVBoxLayout( frame() ); + l->setMargin( 0 ); + l->addWidget( myInfo ); +} + +/*! + \brief Show mesh element information + \param ids mesh nodes / elements identifiers +*/ +void SMESHGUI_TreeElemInfo::information( const QList& ids ) +{ + clearInternal(); + + if ( actor() ) { + int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + foreach ( long id, ids ) { + if ( !isElements() ) { + // + // show node info + // + const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id ); + if ( !e ) return; + const SMDS_MeshNode* node = static_cast( e ); + + // node ID + QTreeWidgetItem* nodeItem = createItem( 0, Bold | All ); + nodeItem->setText( 0, tr( "NODE" ) ); + nodeItem->setText( 1, QString( "#%1" ).arg( id ) ); + // coordinates + QTreeWidgetItem* coordItem = createItem( nodeItem, Bold ); + coordItem->setText( 0, tr( "COORDINATES" ) ); + QTreeWidgetItem* xItem = createItem( coordItem ); + xItem->setText( 0, "X" ); + xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* yItem = createItem( coordItem ); + yItem->setText( 0, "Y" ); + yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* zItem = createItem( coordItem ); + zItem->setText( 0, "Z" ); + zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // connectivity + QTreeWidgetItem* conItem = createItem( nodeItem, Bold ); + conItem->setText( 0, tr( "CONNECTIVITY" ) ); + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "0D_ELEMENTS" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Ball ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "BALL_ELEMENTS" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "EDGES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "FACES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( conItem ); + i->setText( 0, tr( "VOLUMES" ) ); + i->setText( 1, con ); + } + } + else { + conItem->setText( 1, tr( "FREE_NODE" ) ); + } + // node position + int shapeID = node->getshapeId(); + if ( shapeID > 0 ) + { + SMDS_PositionPtr pos = node->GetPosition(); + SMDS_TypeOfPosition posType = pos->GetTypeOfPosition(); + QString shapeType; + double u,v; + switch ( posType ) { + case SMDS_TOP_EDGE: shapeType = tr( "EDGE" ); + u = static_cast( pos )->GetUParameter(); + break; + case SMDS_TOP_FACE: shapeType = tr( "FACE" ); + u = static_cast( pos )->GetUParameter(); + v = static_cast( pos )->GetVParameter(); + break; + case SMDS_TOP_VERTEX: shapeType = tr( "VERTEX" ); break; + default: shapeType = tr( "SOLID" ); + } + QTreeWidgetItem* posItem = createItem( nodeItem, Bold ); + posItem->setText( 0, tr("NODE_POSITION") ); + posItem->setText( 1, (shapeType + " #%1").arg( shapeID )); + if ( posType == SMDS_TOP_EDGE || posType == SMDS_TOP_FACE ) { + QTreeWidgetItem* uItem = createItem( posItem ); + uItem->setText( 0, tr("U_POSITION") ); + uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision ))); + if ( posType == SMDS_TOP_FACE ) { + QTreeWidgetItem* vItem = createItem( posItem ); + vItem->setText( 0, tr("V_POSITION") ); + vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision ))); + } + } + } + } + else { + // + // show element info + // + const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id ); + if ( !e ) return; + + // element ID && type + QString stype; + switch( e->GetType() ) { + case SMDSAbs_0DElement: + stype = tr( "0D ELEMENT" ); break; + case SMDSAbs_Ball: + stype = tr( "BALL" ); break; + case SMDSAbs_Edge: + stype = tr( "EDGE" ); break; + case SMDSAbs_Face: + stype = tr( "FACE" ); break; + case SMDSAbs_Volume: + stype = tr( "VOLUME" ); break; + default: + break; + } + if ( stype.isEmpty() ) return; + QTreeWidgetItem* elemItem = createItem( 0, Bold | All ); + elemItem->setText( 0, stype ); + elemItem->setText( 1, QString( "#%1" ).arg( id ) ); + // geometry type + QString gtype; + switch( e->GetEntityType() ) { + case SMDSEntity_Triangle: + case SMDSEntity_Quad_Triangle: + gtype = tr( "TRIANGLE" ); break; + case SMDSEntity_Quadrangle: + case SMDSEntity_Quad_Quadrangle: + case SMDSEntity_BiQuad_Quadrangle: + gtype = tr( "QUADRANGLE" ); break; + case SMDSEntity_Polygon: + case SMDSEntity_Quad_Polygon: + gtype = tr( "POLYGON" ); break; + case SMDSEntity_Tetra: + case SMDSEntity_Quad_Tetra: + gtype = tr( "TETRAHEDRON" ); break; + case SMDSEntity_Pyramid: + case SMDSEntity_Quad_Pyramid: + gtype = tr( "PYRAMID" ); break; + case SMDSEntity_Hexa: + case SMDSEntity_Quad_Hexa: + case SMDSEntity_TriQuad_Hexa: + gtype = tr( "HEXAHEDRON" ); break; + case SMDSEntity_Penta: + case SMDSEntity_Quad_Penta: + gtype = tr( "PRISM" ); break; + case SMDSEntity_Hexagonal_Prism: + gtype = tr( "HEX_PRISM" ); break; + case SMDSEntity_Polyhedra: + case SMDSEntity_Quad_Polyhedra: + gtype = tr( "POLYHEDRON" ); break; + default: + break; + } + if ( !gtype.isEmpty() ) { + QTreeWidgetItem* typeItem = createItem( elemItem, Bold ); + typeItem->setText( 0, tr( "TYPE" ) ); + typeItem->setText( 1, gtype ); + } + // quadratic flag and gravity center (any element except 0D) + if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) { + // quadratic flag + QTreeWidgetItem* quadItem = createItem( elemItem, Bold ); + quadItem->setText( 0, tr( "QUADRATIC" ) ); + quadItem->setText( 1, e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ); + // gravity center + XYZ gc = gravityCenter( e ); + QTreeWidgetItem* gcItem = createItem( elemItem, Bold ); + gcItem->setText( 0, tr( "GRAVITY_CENTER" ) ); + QTreeWidgetItem* xItem = createItem( gcItem ); + xItem->setText( 0, "X" ); + xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* yItem = createItem( gcItem ); + yItem->setText( 0, "Y" ); + yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* zItem = createItem( gcItem ); + zItem->setText( 0, "Z" ); + zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + } + if ( const SMDS_BallElement* ball = dynamic_cast( e )) { + // ball diameter + QTreeWidgetItem* diamItem = createItem( elemItem, Bold ); + diamItem->setText( 0, tr( "BALL_DIAMETER" ) ); + diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() )); + } + // connectivity + QTreeWidgetItem* conItem = createItem( elemItem, Bold ); + conItem->setText( 0, tr( "CONNECTIVITY" ) ); + SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); + for ( int idx = 1; nodeIt->more(); idx++ ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + // node number and ID + QTreeWidgetItem* nodeItem = createItem( conItem, Bold ); + nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ) ); + nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) ); + nodeItem->setExpanded( false ); + // node coordinates + QTreeWidgetItem* coordItem = createItem( nodeItem ); + coordItem->setText( 0, tr( "COORDINATES" ) ); + QTreeWidgetItem* xItem = createItem( coordItem ); + xItem->setText( 0, "X" ); + xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* yItem = createItem( coordItem ); + yItem->setText( 0, "Y" ); + yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + QTreeWidgetItem* zItem = createItem( coordItem ); + zItem->setText( 0, "Z" ); + zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // node connectivity + QTreeWidgetItem* nconItem = createItem( nodeItem ); + nconItem->setText( 0, tr( "CONNECTIVITY" ) ); + Connectivity connectivity = nodeConnectivity( node ); + if ( !connectivity.isEmpty() ) { + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "0D_ELEMENTS" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "EDGES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Ball ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "BALL_ELEMENTS" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "FACES" ) ); + i->setText( 1, con ); + } + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) { + QTreeWidgetItem* i = createItem( nconItem ); + i->setText( 0, tr( "VOLUMES" ) ); + i->setText( 1, con ); + } + } + } + } + } + } +} + +/*! + \brief Internal clean-up (reset widget) +*/ +void SMESHGUI_TreeElemInfo::clearInternal() +{ + myInfo->clear(); + myInfo->repaint(); +} + +/*! + \brief Create new tree item. + \param parent parent tree widget item + \param flags item flag + \return new tree widget item +*/ +QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags ) +{ + QTreeWidgetItem* item; + if ( parent ) + item = new QTreeWidgetItem( parent ); + else + item = new QTreeWidgetItem( myInfo ); + + item->setFlags( item->flags() | Qt::ItemIsEditable ); + + QFont f = item->font( 0 ); + f.setBold( true ); + for ( int i = 0; i < myInfo->columnCount(); i++ ) { + if ( ( flags & Bold ) && ( i == 0 || flags & All ) ) + item->setFont( i, f ); + } + + item->setExpanded( true ); + return item; +} + +/*! + \class GrpComputor + \brief Mesh information computer + \internal + + The class is created for different computation operation. Currently it is used + to compute number of underlying nodes for the groups. +*/ + +/*! + \brief Contructor +*/ +GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* item, QObject* parent ) + : QObject( parent ), myItem( item ) +{ + myGroup = SMESH::SMESH_GroupBase::_narrow( grp ); +} + +/*! + \brief Compute function +*/ +void GrpComputor::compute() +{ + if ( !CORBA::is_nil( myGroup ) && myItem ) { + QTreeWidgetItem* item = myItem; + myItem = 0; + int nbNodes = myGroup->GetNumberOfNodes(); + item->treeWidget()->removeItemWidget( item, 1 ); + item->setText( 1, QString::number( nbNodes )); + } +} + +/*! + \class SMESHGUI_AddInfo + \brief The wigdet shows additional information on the mesh object. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent ) +: QTreeWidget( parent ) +{ + setColumnCount( 2 ); + header()->setStretchLastSection( true ); + header()->setResizeMode( 0, QHeaderView::ResizeToContents ); + header()->hide(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_AddInfo::~SMESHGUI_AddInfo() +{ +} + +/*! + \brief Show additional information on the selected object + \param obj object being processed (mesh, sub-mesh, group, ID source) +*/ +void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +{ + setProperty( "group_index", 0 ); + setProperty( "submesh_index", 0 ); + myComputors.clear(); + clear(); + + if ( CORBA::is_nil( obj ) ) return; + + _PTR(SObject) sobj = SMESH::ObjectToSObject( obj ); + if ( !sobj ) return; + + // name + QTreeWidgetItem* nameItem = createItem( 0, Bold | All ); + nameItem->setText( 0, tr( "NAME" ) ); + nameItem->setText( 1, sobj->GetName().c_str() ); + + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj ); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj ); + + if ( !aMesh->_is_nil() ) + meshInfo( aMesh, nameItem ); + else if ( !aSubMesh->_is_nil() ) + subMeshInfo( aSubMesh, nameItem ); + else if ( !aGroup->_is_nil() ) + groupInfo( aGroup.in(), nameItem ); +} + +/*! + \brief Create new tree item. + \param parent parent tree widget item + \param flags item flag + \return new tree widget item +*/ +QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags ) +{ + QTreeWidgetItem* item; + + if ( parent ) + item = new QTreeWidgetItem( parent ); + else + item = new QTreeWidgetItem( this ); + + //item->setFlags( item->flags() | Qt::ItemIsEditable ); + + QFont f = item->font( 0 ); + f.setBold( true ); + for ( int i = 0; i < columnCount(); i++ ) { + if ( ( flags & Bold ) && ( i == 0 || flags & All ) ) + item->setFont( i, f ); + } + + item->setExpanded( true ); + return item; +} + +/*! + \brief Show mesh info + \param mesh mesh object + \param parent parent tree item +*/ +void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent ) +{ + // type + GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh(); + SALOME_MED::MedFileInfo* inf = mesh->GetMEDFileInfo(); + QTreeWidgetItem* typeItem = createItem( parent, Bold ); + typeItem->setText( 0, tr( "TYPE" ) ); + if ( !CORBA::is_nil( shape ) ) { + typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) ); + _PTR(SObject) sobj = SMESH::ObjectToSObject( shape ); + if ( sobj ) { + QTreeWidgetItem* gobjItem = createItem( typeItem ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, sobj->GetName().c_str() ); + } + } + else if ( strlen( (char*)inf->fileName ) > 0 ) { + typeItem->setText( 1, tr( "MESH_FROM_FILE" ) ); + QTreeWidgetItem* fileItem = createItem( typeItem ); + fileItem->setText( 0, tr( "FILE_NAME" ) ); + fileItem->setText( 1, (char*)inf->fileName ); + } + else { + typeItem->setText( 1, tr( "STANDALONE_MESH" ) ); + } + + // groups + myGroups = mesh->GetGroups(); + showGroups(); + + // sub-meshes + mySubMeshes = mesh->GetSubMeshes(); + showSubMeshes(); +} + +/*! + \brief Show sub-mesh info + \param subMesh sub-mesh object + \param parent parent tree item +*/ +void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent ) +{ + bool isShort = parent->parent() != 0; + + if ( !isShort ) { + // parent mesh + _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() ); + if ( sobj ) { + QTreeWidgetItem* nameItem = createItem( parent, Bold ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, sobj->GetName().c_str() ); + } + } + + // shape + GEOM::GEOM_Object_var gobj = subMesh->GetSubShape(); + _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); + if ( sobj ) { + QTreeWidgetItem* gobjItem = createItem( parent, Bold ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, sobj->GetName().c_str() ); + } +} + +/*! + \brief Show group info + \param grp mesh group object + \param parent parent tree item +*/ +void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent ) +{ + bool isShort = parent->parent() != 0; + + SMESH::SMESH_Group_var aStdGroup = SMESH::SMESH_Group::_narrow( grp ); + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp ); + SMESH::SMESH_GroupOnFilter_var aFltGroup = SMESH::SMESH_GroupOnFilter::_narrow( grp ); + + if ( !isShort ) { + // parent mesh + _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() ); + if ( sobj ) { + QTreeWidgetItem* nameItem = createItem( parent, Bold ); + nameItem->setText( 0, tr( "PARENT_MESH" ) ); + nameItem->setText( 1, sobj->GetName().c_str() ); + } + } + + // type : group on geometry, standalone group, group on filter + QTreeWidgetItem* typeItem = createItem( parent, Bold ); + typeItem->setText( 0, tr( "TYPE" ) ); + if ( !CORBA::is_nil( aStdGroup ) ) { + typeItem->setText( 1, tr( "STANDALONE_GROUP" ) ); + } + else if ( !CORBA::is_nil( aGeomGroup ) ) { + typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) ); + GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape(); + _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj ); + if ( sobj ) { + QTreeWidgetItem* gobjItem = createItem( typeItem ); + gobjItem->setText( 0, tr( "GEOM_OBJECT" ) ); + gobjItem->setText( 1, sobj->GetName().c_str() ); + } + } + else if ( !CORBA::is_nil( aFltGroup ) ) { + typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) ); + } + + if ( !isShort ) { + // entity type + QString etype = tr( "UNKNOWN" ); + switch( grp->GetType() ) { + case SMESH::NODE: + etype = tr( "NODE" ); + break; + case SMESH::EDGE: + etype = tr( "EDGE" ); + break; + case SMESH::FACE: + etype = tr( "FACE" ); + break; + case SMESH::VOLUME: + etype = tr( "VOLUME" ); + break; + case SMESH::ELEM0D: + etype = tr( "0DELEM" ); + break; + case SMESH::BALL: + etype = tr( "BALL" ); + break; + default: + break; + } + QTreeWidgetItem* etypeItem = createItem( parent, Bold ); + etypeItem->setText( 0, tr( "ENTITY_TYPE" ) ); + etypeItem->setText( 1, etype ); + } + + // size + QTreeWidgetItem* sizeItem = createItem( parent, Bold ); + sizeItem->setText( 0, tr( "SIZE" ) ); + sizeItem->setText( 1, QString::number( grp->Size() ) ); + + // color + SALOMEDS::Color color = grp->GetColor(); + QTreeWidgetItem* colorItem = createItem( parent, Bold ); + colorItem->setText( 0, tr( "COLOR" ) ); + colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) ); + + // nb of underlying nodes + if ( grp->GetType() != SMESH::NODE) { + QTreeWidgetItem* nodesItem = createItem( parent, Bold ); + nodesItem->setText( 0, tr( "NB_NODES" ) ); + int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 ); + SMESH::SMESH_Mesh_var mesh = grp->GetMesh(); + bool meshLoaded = mesh->IsLoaded(); + bool toShowNodes = ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || grp->Size() <= nbNodesLimit ); + if ( toShowNodes && meshLoaded ) { + // already calculated and up-to-date + nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) ); + } + else { + QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this ); + setItemWidget( nodesItem, 1, btn ); + GrpComputor* comp = new GrpComputor( grp, nodesItem, this ); + connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) ); + myComputors.append( comp ); + if ( !meshLoaded ) + connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) ); + } + } +} + +void SMESHGUI_AddInfo::showGroups() +{ + myComputors.clear(); + + QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item + if ( !parent ) return; + + int idx = property( "group_index" ).toInt(); + + QTreeWidgetItem* itemGroups = 0; + for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) { + if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) { + itemGroups = parent->child( i ); + ExtraWidget* extra = dynamic_cast( itemWidget( itemGroups, 1 ) ); + if ( extra ) + extra->updateControls( myGroups->length(), idx ); + while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items + } + } + + QMap grpItems; + for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) { + SMESH::SMESH_GroupBase_var grp = myGroups[i]; + if ( CORBA::is_nil( grp ) ) continue; + _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp ); + if ( !grpSObj ) continue; + + int grpType = grp->GetType(); + + if ( !itemGroups ) { + // create top-level groups container item + itemGroups = createItem( parent, Bold | All ); + itemGroups->setText( 0, tr( "GROUPS" ) ); + itemGroups->setData( 0, Qt::UserRole, GROUPS_ID ); + + // total number of groups > 10, show extra widgets for info browsing + if ( myGroups->length() > MAXITEMS ) { + ExtraWidget* extra = new ExtraWidget( this, true ); + connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) ); + connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) ); + setItemWidget( itemGroups, 1, extra ); + extra->updateControls( myGroups->length(), idx ); + } + } + + if ( grpItems.find( grpType ) == grpItems.end() ) { + grpItems[ grpType ] = createItem( itemGroups, Bold | All ); + grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) ); + itemGroups->insertChild( grpType-1, grpItems[ grpType ] ); + } + + // group name + QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] ); + grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed + + // group info + groupInfo( grp.in(), grpNameItem ); + } +} + +void SMESHGUI_AddInfo::showSubMeshes() +{ + QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item + if ( !parent ) return; + + int idx = property( "submesh_index" ).toInt(); + + QTreeWidgetItem* itemSubMeshes = 0; + for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) { + if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) { + itemSubMeshes = parent->child( i ); + ExtraWidget* extra = dynamic_cast( itemWidget( itemSubMeshes, 1 ) ); + if ( extra ) + extra->updateControls( mySubMeshes->length(), idx ); + while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items + } + } + + QMap smItems; + for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) { + SMESH::SMESH_subMesh_var sm = mySubMeshes[i]; + if ( CORBA::is_nil( sm ) ) continue; + _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm ); + if ( !smSObj ) continue; + + GEOM::GEOM_Object_var gobj = sm->GetSubShape(); + if ( CORBA::is_nil(gobj ) ) continue; + + int smType = gobj->GetShapeType(); + if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND; + + if ( !itemSubMeshes ) { + itemSubMeshes = createItem( parent, Bold | All ); + itemSubMeshes->setText( 0, tr( "SUBMESHES" ) ); + itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID ); + + // total number of sub-meshes > 10, show extra widgets for info browsing + if ( mySubMeshes->length() > MAXITEMS ) { + ExtraWidget* extra = new ExtraWidget( this, true ); + connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) ); + connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) ); + setItemWidget( itemSubMeshes, 1, extra ); + extra->updateControls( mySubMeshes->length(), idx ); + } + } + + if ( smItems.find( smType ) == smItems.end() ) { + smItems[ smType ] = createItem( itemSubMeshes, Bold | All ); + smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) ); + itemSubMeshes->insertChild( smType, smItems[ smType ] ); + } + + // submesh name + QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] ); + smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed + + // submesh info + subMeshInfo( sm.in(), smNameItem ); + } +} + +/*! + * \brief Change button label of "nb underlying node" group from "Load" to "Compute" + */ +void SMESHGUI_AddInfo::changeLoadToCompute() +{ + for ( int i = 0; i < myComputors.count(); ++i ) + { + if ( QTreeWidgetItem* item = myComputors[i]->getItem() ) + { + if ( QPushButton* btn = qobject_cast( itemWidget ( item, 1 ) ) ) + btn->setText( tr("COMPUTE") ); + } + } +} + +void SMESHGUI_AddInfo::showPreviousGroups() +{ + int idx = property( "group_index" ).toInt(); + setProperty( "group_index", idx-1 ); + showGroups(); +} + +void SMESHGUI_AddInfo::showNextGroups() +{ + int idx = property( "group_index" ).toInt(); + setProperty( "group_index", idx+1 ); + showGroups(); +} + +void SMESHGUI_AddInfo::showPreviousSubMeshes() +{ + int idx = property( "submesh_index" ).toInt(); + setProperty( "submesh_index", idx-1 ); + showSubMeshes(); +} + +void SMESHGUI_AddInfo::showNextSubMeshes() +{ + int idx = property( "submesh_index" ).toInt(); + setProperty( "submesh_index", idx+1 ); + showSubMeshes(); +} + +/*! + \class SMESHGUI_MeshInfoDlg + \brief Mesh information dialog box +*/ + +/*! + \brief Constructor + \param parent parent widget + \param page specifies the dialog page to be shown at the start-up +*/ +SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) +: QDialog( parent ), myActor( 0 ) +{ + setModal( false ); + setAttribute( Qt::WA_DeleteOnClose, true ); + setWindowTitle( tr( "MESH_INFO" ) ); + setSizeGripEnabled( true ); + + myTabWidget = new QTabWidget( this ); + + // base info + + myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget ); + myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) ); + + // elem info + + QWidget* w = new QWidget( myTabWidget ); + + myMode = new QButtonGroup( this ); + myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode ); + myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode ); + myMode->button( NodeMode )->setChecked( true ); + myID = new QLineEdit( w ); + myID->setValidator( new SMESHGUI_IdValidator( this ) ); + + int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 ); + mode = qMin( 1, qMax( 0, mode ) ); + + if ( mode == 0 ) + myElemInfo = new SMESHGUI_SimpleElemInfo( w ); + else + myElemInfo = new SMESHGUI_TreeElemInfo( w ); + + QGridLayout* elemLayout = new QGridLayout( w ); + elemLayout->setMargin( MARGIN ); + elemLayout->setSpacing( SPACING ); + elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 ); + elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 ); + elemLayout->addWidget( myID, 0, 2 ); + elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 ); + + myTabWidget->addTab( w, tr( "ELEM_INFO" ) ); + + // additional info + + myAddInfo = new SMESHGUI_AddInfo( myTabWidget ); + myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) ); + + // buttons + + QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this ); + okBtn->setAutoDefault( true ); + okBtn->setDefault( true ); + okBtn->setFocus(); + QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this ); + helpBtn->setAutoDefault( true ); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setSpacing( SPACING ); + btnLayout->setMargin( 0 ); + + btnLayout->addWidget( okBtn ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( helpBtn ); + + QVBoxLayout* l = new QVBoxLayout ( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + l->addWidget( myTabWidget ); + l->addLayout( btnLayout ); + + myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) ); + + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) ); + connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) ); + connect( myID, SIGNAL( textEdited( QString ) ), this, SLOT( idChanged() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); + + updateSelection(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg() +{ +} + +/*! + \brief Show mesh information + \param IO interactive object +*/ +void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO ) +{ + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + myBaseInfo->showInfo( obj ); + myAddInfo->showInfo( obj ); + + myActor = SMESH::FindActorByEntry( IO->getEntry() ); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( myActor && selector ) { + nb = myMode->checkedId() == NodeMode ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + myElemInfo->setSource( myActor ) ; + if ( nb > 0 ) { + myID->setText( ID.trimmed() ); + QSet ids; + QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); + foreach ( ID, idTxt ) + ids << ID.trimmed().toLong(); + myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); + } + else { + myID->clear(); + myElemInfo->clear(); + } + } +} + +/*! + \brief Perform clean-up actions on the dialog box closing. +*/ +void SMESHGUI_MeshInfoDlg::reject() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + selMgr->clearFilters(); + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + QDialog::reject(); +} + +/*! + \brief Process keyboard event + \param e key press event +*/ +void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) { + e->accept(); + help(); + } +} + +/*! + \brief Reactivate dialog box, when mouse pointer goes into it. +*/ +void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* ) +{ + //activate(); +} + +/*! + \brief Setup selection mode depending on the current dialog box state. +*/ +void SMESHGUI_MeshInfoDlg::updateSelection() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + + disconnect( selMgr, 0, this, 0 ); + selMgr->clearFilters(); + + if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + } + else { + if ( myMode->checkedId() == NodeMode ) { + SMESH::SetPointRepresentation( true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( NodeSelection ); + } + else { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( CellSelection ); + } + } + + QString oldID = myID->text().trimmed(); + SMESH_Actor* oldActor = myActor; + myID->clear(); + + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); + updateInfo(); + + if ( oldActor == myActor && myActor && !oldID.isEmpty() ) { + myID->setText( oldID ); + idChanged(); + } +} + +/*! + \brief Show help page +*/ +void SMESHGUI_MeshInfoDlg::help() +{ + SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ? + "mesh_infos_page.html#advanced_mesh_infos_anchor" : + "mesh_infos_page.html#mesh_element_info_anchor" ); +} + +/*! + \brief Show mesh information +*/ +void SMESHGUI_MeshInfoDlg::updateInfo() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + showInfo( IO ); + } +// else { +// myBaseInfo->clear(); +// myElemInfo->clear(); +// myAddInfo->clear(); +// } +} + +/*! + \brief Activate dialog box +*/ +void SMESHGUI_MeshInfoDlg::activate() +{ + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); + SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); + myTabWidget->setEnabled( true ); + updateSelection(); +} + +/*! + \brief Deactivate dialog box +*/ +void SMESHGUI_MeshInfoDlg::deactivate() +{ + myTabWidget->setEnabled( false ); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); +} + +/*! + \brief Called when users switches between node / element modes. +*/ +void SMESHGUI_MeshInfoDlg::modeChanged() +{ + myID->clear(); + updateSelection(); +} + +/*! + \brief Caled when users prints mesh element ID in the corresponding field. +*/ +void SMESHGUI_MeshInfoDlg::idChanged() +{ + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( myActor && selector ) { + Handle(SALOME_InteractiveObject) IO = myActor->getIO(); + TColStd_MapOfInteger ID; + QSet ids; + QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts ); + foreach ( QString tid, idTxt ) { + long id = tid.trimmed().toLong(); + const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ? + myActor->GetObject()->GetMesh()->FindElement( id ) : + myActor->GetObject()->GetMesh()->FindNode( id ); + if ( e ) { + ID.Add( id ); + ids << id; + } + } + selector->AddOrRemoveIndex( IO, ID, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); + } +} diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h new file mode 100644 index 000000000..a2fa39930 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.h @@ -0,0 +1,305 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_MeshInfo.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#ifndef SMESHGUI_MESHINFO_H +#define SMESHGUI_MESHINFO_H + +#include "SMESH_SMESHGUI.hxx" +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) + +class QButtonGroup; +class QLabel; +class QLineEdit; +class QPushButton; +class QTabWidget; +class QTextBrowser; +class SMESH_Actor; +class SMDS_MeshNode; +class SMDS_MeshElement; + +class ExtraWidget; + +class SMESHGUI_EXPORT SMESHGUI_MeshInfo : public QFrame +{ + Q_OBJECT; + + enum { + iName, + iObject, + iNodesStart, + iNodes, + iNodesEnd, + iElementsStart = iNodesEnd, + iElements, + i0DStart, + i0D, + i0DEnd, + iBallsStart = i0DEnd, + iBalls, + iBallsEnd, + i1DStart = iBallsEnd, + i1D, + i1DEnd, + i2DStart = i1DEnd, + i2D, + i2DTriangles, + i2DQuadrangles, + i2DPolygons, + i2DEnd, + i3DStart = i2DEnd, + i3D, + i3DTetrahedrons, + i3DHexahedrons, + i3DPyramids, + i3DPrisms, + i3DHexaPrisms, + i3DPolyhedrons, + i3DEnd, + iElementsEnd = i3DEnd + }; + + enum { + iSingle = 1, + iTotal = iSingle, + iLinear, + iQuadratic + }; + + typedef QList wlist; + typedef QVector iwlist; + +public: + SMESHGUI_MeshInfo( QWidget* = 0 ); + ~SMESHGUI_MeshInfo(); + + void showInfo( SMESH::SMESH_IDSource_ptr ); + void clear(); + +private: + enum { Bold = 0x01, Italic = 0x02 }; + + QLabel* createField(); + QWidget* createLine(); + void setFontAttributes( QWidget*, int, bool = true ); + void setFieldsVisible( int, int, bool ); + +private slots: + void loadMesh(); + +private: + iwlist myWidgets; + QPushButton* myLoadBtn; +}; + +class SMESHGUI_EXPORT SMESHGUI_ElemInfo : public QWidget +{ + Q_OBJECT; + +public: + SMESHGUI_ElemInfo( QWidget* = 0 ); + ~SMESHGUI_ElemInfo(); + + void setSource( SMESH_Actor* ); + void showInfo( long, bool ); + void showInfo( QSet, bool ); + void clear(); + +protected: + struct XYZ + { + double myX, myY, myZ; + XYZ() { myX = myY = myZ = 0.0; } + void add( double x, double y, double z ) { myX += x; myY += y; myZ += z; } + void divide( double a ) { if ( a != 0.) { myX /= a; myY /= a; myZ /= a; } } + double x() const { return myX; } + double y() const { return myY; } + double z() const { return myZ; } + }; + typedef QMap< int, QList > Connectivity; + + QWidget* frame() const; + SMESH_Actor* actor() const; + bool isElements() const; + + virtual void information( const QList& ) = 0; + virtual void clearInternal(); + + Connectivity nodeConnectivity( const SMDS_MeshNode* ); + QString formatConnectivity( Connectivity, int ); + XYZ gravityCenter( const SMDS_MeshElement* ); + +private slots: + void showPrevious(); + void showNext(); + void updateControls(); + +private: + SMESH_Actor* myActor; + QList myIDs; + int myIsElement; + QWidget* myFrame; + ExtraWidget* myExtra; + int myIndex; +}; + +class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo +{ +public: + SMESHGUI_SimpleElemInfo( QWidget* = 0 ); + +protected: + void information( const QList& ); + void clearInternal(); + +private: + QTextBrowser* myInfo; +}; + +class SMESHGUI_EXPORT SMESHGUI_TreeElemInfo : public SMESHGUI_ElemInfo +{ + class ItemDelegate; + + enum { Bold = 0x01, All = 0x80 }; + +public: + SMESHGUI_TreeElemInfo( QWidget* = 0 ); + +protected: + void information( const QList& ); + void clearInternal(); + +private: + QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 0 ); + +private: + QTreeWidget* myInfo; +}; + +class GrpComputor: public QObject +{ + Q_OBJECT; + +public: + GrpComputor( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem*, QObject* ); + QTreeWidgetItem* getItem() { return myItem; } + +public slots: + void compute(); + +private: + SMESH::SMESH_GroupBase_var myGroup; + QTreeWidgetItem* myItem; +}; + +class SMESHGUI_EXPORT SMESHGUI_AddInfo : public QTreeWidget +{ + Q_OBJECT; + + enum { Bold = 0x01, All = 0x80 }; + +public: + SMESHGUI_AddInfo( QWidget* = 0 ); + ~SMESHGUI_AddInfo(); + + void showInfo( SMESH::SMESH_IDSource_ptr ); + // void clear(); + +private slots: + void changeLoadToCompute(); + void showPreviousGroups(); + void showNextGroups(); + void showPreviousSubMeshes(); + void showNextSubMeshes(); + +private: + QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 0 ); + void meshInfo( SMESH::SMESH_Mesh_ptr, QTreeWidgetItem* ); + void subMeshInfo( SMESH::SMESH_subMesh_ptr, QTreeWidgetItem* ); + void groupInfo( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem* ); + + void showGroups(); + void showSubMeshes(); + +private: + QList myComputors; + SMESH::ListOfGroups_var myGroups; + SMESH::submesh_array_var mySubMeshes; +}; + +class SMESHGUI_EXPORT SMESHGUI_MeshInfoDlg : public QDialog +{ + Q_OBJECT; + + enum { NodeMode, ElemMode }; + +public: + //! Information type + enum { + BaseInfo, //!< base mesh information + ElemInfo, //!< mesh element information + AddInfo //!< additional information + }; + + SMESHGUI_MeshInfoDlg( QWidget* = 0, int = BaseInfo ); + ~SMESHGUI_MeshInfoDlg(); + + void showInfo( const Handle(SALOME_InteractiveObject)& ); + void reject(); + +protected: + void keyPressEvent( QKeyEvent* ); + void enterEvent( QEvent* ); + +private slots: + void help(); + void updateSelection(); + void updateInfo(); + void activate(); + void deactivate(); + void modeChanged(); + void idChanged(); + +private: + QTabWidget* myTabWidget; + SMESHGUI_MeshInfo* myBaseInfo; + QButtonGroup* myMode; + QLineEdit* myID; + SMESHGUI_ElemInfo* myElemInfo; + SMESHGUI_AddInfo* myAddInfo; + SMESH_Actor* myActor; +}; + +#endif // SMESHGUI_MESHINFO_H diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx new file mode 100644 index 000000000..17f653938 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx @@ -0,0 +1,475 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_MeshInfosBox.cxx +// Author : Edward AGAPOV, Open CASCADE S.A.S. +// SMESH includes +// +#include "SMESHGUI_MeshInfosBox.h" + +#include "SMDSAbs_ElementType.hxx" + +// Qt includes +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 + +#define COLONIZE(str) (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" ) + +static void addSeparator( QWidget* parent ) +{ + QGridLayout* l = qobject_cast( parent->layout() ); + int row = l->rowCount(); + int cols = l->columnCount(); + for ( int i = 0; i < cols; i++ ) { + QFrame* hline = new QFrame( parent ); + hline->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + l->addWidget( hline, row, i ); + } +} + +enum TCol { + COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS +}; + +// ========================================================================================= +/*! + * \brief Box showing mesh info + */ +// ========================================================================================= + +SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent) +: QGroupBox( tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full ), + myNbNode(0), + my0DElem(0), + myBall(0), + myNbEdge(0), myNbLinEdge(0), myNbQuadEdge(0), + myNbTrai(0), myNbLinTrai(0), myNbQuadTrai(0), + myNbQuad(0), myNbLinQuad(0), myNbQuadQuad(0), + myNbFace(0), myNbLinFace(0), myNbQuadFace(0), + myNbPolyg(0), + myNbHexa(0), myNbLinHexa(0), myNbQuadHexa(0), + myNbTetra(0),myNbLinTetra(0),myNbQuadTetra(0), + myNbPyra(0), myNbLinPyra(0), myNbQuadPyra(0), + myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0), + myNbVolum(0), myNbLinVolum(0), myNbQuadVolum(0), + myNbHexaPrism(0), + myNbPolyh(0) +{ + QGridLayout* l = new QGridLayout(this); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + + QFont italic = font(); italic.setItalic(true); + QFont bold = font(); bold.setBold(true); + + QLabel* lab; + int row = 0; + + // title + lab = new QLabel( this ); + lab->setMinimumWidth(100); lab->setFont( italic ); + l->addWidget( lab, row, 0 ); + // -- + lab = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this ); + lab->setMinimumWidth(100); lab->setFont( italic ); + l->addWidget( lab, row, 1 ); + // -- + lab = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this ); + lab->setMinimumWidth(100); lab->setFont( italic ); + l->addWidget( lab, row, 2 ); + // -- + lab = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this ); + lab->setMinimumWidth(100); lab->setFont( italic ); + l->addWidget( lab, row, 3 ); + + if ( myFull ) + { + // nodes + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ); + lab->setFont( bold ); + l->addWidget( lab, row, 0 ); + // -- + myNbNode = new QLabel( this ); + l->addWidget( myNbNode, row, 1 ); + + addSeparator(this); // add separator + + // 0D elements + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_0DELEMS")), this ); + lab->setFont( bold ); + l->addWidget( lab, row, 0 ); + // -- + my0DElem = new QLabel( this ); + l->addWidget( my0DElem, row, 1 ); + + addSeparator(this); // add separator + + // balls + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_BALLS")), this ); + lab->setFont( bold ); + l->addWidget( lab, row, 0 ); + // -- + myBall = new QLabel( this ); + l->addWidget( myBall, row, 1 ); + + addSeparator(this); // add separator + + // edges + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ); + lab->setFont( bold ); + l->addWidget( lab, row, 0 ); + // -- + myNbEdge = new QLabel( this ); + l->addWidget( myNbEdge, row, 1 ); + // -- + myNbLinEdge = new QLabel( this ); + l->addWidget( myNbLinEdge, row, 2 ); + // -- + myNbQuadEdge = new QLabel( this ); + l->addWidget( myNbQuadEdge, row, 3 ); + + addSeparator(this); // add separator + + // faces + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this); + lab->setFont( bold ); + l->addWidget( lab, row, 0 ); + // -- + myNbFace = new QLabel( this ); + l->addWidget( myNbFace, row, 1 ); + // -- + myNbLinFace = new QLabel( this ); + l->addWidget( myNbLinFace, row, 2 ); + // -- + myNbQuadFace = new QLabel( this ); + l->addWidget( myNbQuadFace, row, 3 ); + // -- + row++; // increment row count + // ... triangles + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbTrai = new QLabel( this ); + l->addWidget( myNbTrai, row, 1 ); + // -- + myNbLinTrai = new QLabel( this ); + l->addWidget( myNbLinTrai, row, 2 ); + // -- + myNbQuadTrai = new QLabel( this ); + l->addWidget( myNbQuadTrai, row, 3 ); + // -- + row++; // increment row count + // ... quadrangles + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbQuad = new QLabel( this ); + l->addWidget( myNbQuad, row, 1 ); + // -- + myNbLinQuad = new QLabel( this ); + l->addWidget( myNbLinQuad, row, 2 ); + // -- + myNbQuadQuad = new QLabel( this ); + l->addWidget( myNbQuadQuad, row, 3 ); + // -- + row++; // increment row count + // ... poligones + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this ); + l->addWidget( lab, row, 0 ); + myNbPolyg = new QLabel( this ); + l->addWidget( myNbPolyg, row, 1 ); + + addSeparator(this); // add separator + + // volumes + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this); + lab->setFont( bold ); + l->addWidget( lab, row, 0 ); + // -- + myNbVolum = new QLabel( this ); + l->addWidget( myNbVolum, row, 1 ); + // -- + myNbLinVolum = new QLabel( this ); + l->addWidget( myNbLinVolum, row, 2 ); + // -- + myNbQuadVolum = new QLabel( this ); + l->addWidget( myNbQuadVolum, row, 3 ); + // -- + row++; // increment row count + // ... tetras + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbTetra = new QLabel( this ); + l->addWidget( myNbTetra, row, 1 ); + // -- + myNbLinTetra = new QLabel( this ); + l->addWidget( myNbLinTetra, row, 2 ); + // -- + myNbQuadTetra = new QLabel( this ); + l->addWidget( myNbQuadTetra, row, 3 ); + // -- + row++; // increment row count + // ... hexas + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbHexa = new QLabel( this ); + l->addWidget( myNbHexa, row, 1 ); + // -- + myNbLinHexa = new QLabel( this ); + l->addWidget( myNbLinHexa, row, 2 ); + // -- + myNbQuadHexa = new QLabel( this ); + l->addWidget( myNbQuadHexa, row, 3 ); + // -- + row++; // increment row count + // ... pyras + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbPyra = new QLabel( this ); + l->addWidget( myNbPyra, row, 1 ); + // -- + myNbLinPyra = new QLabel( this ); + l->addWidget( myNbLinPyra, row, 2 ); + // -- + myNbQuadPyra = new QLabel( this ); + l->addWidget( myNbQuadPyra, row, 3 ); + // -- + row++; // increment row count + // ... prisms + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbPrism = new QLabel( this ); + l->addWidget( myNbPrism, row, 1 ); + // -- + myNbLinPrism = new QLabel( this ); + l->addWidget( myNbLinPrism, row, 2 ); + // -- + myNbQuadPrism = new QLabel( this ); + l->addWidget( myNbQuadPrism, row, 3 ); + // -- + row++; // increment row count + // ... hexa prisms + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAPRISM")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbHexaPrism = new QLabel( this ); + l->addWidget( myNbHexaPrism, row, 1 ); + // -- + row++; // increment row count + // ... polyedres + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbPolyh = new QLabel( this ); + l->addWidget( myNbPolyh, row, 1 ); + } + else + { + // nodes + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbNode = new QLabel( this ); + l->addWidget( myNbNode, row, 1 ); + + // 0D elements + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_0DELEMS")), this ); + l->addWidget( lab, row, 0 ); + // -- + my0DElem = new QLabel( this ); + l->addWidget( my0DElem, row, 1 ); + + addSeparator(this); // add separator + + // edges + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ); + l->addWidget( lab, row, 0 ); + // -- + myNbEdge = new QLabel( this ); + l->addWidget( myNbEdge, row, 1 ); + // -- + myNbLinEdge = new QLabel( this ); + l->addWidget( myNbLinEdge, row, 2 ); + // -- + myNbQuadEdge = new QLabel( this ); + l->addWidget( myNbQuadEdge, row, 3 ); + + // faces + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this); + l->addWidget( lab, row, 0 ); + // -- + myNbFace = new QLabel( this ); + l->addWidget( myNbFace, row, 1 ); + // -- + myNbLinFace = new QLabel( this ); + l->addWidget( myNbLinFace, row, 2 ); + // -- + myNbQuadFace = new QLabel( this ); + l->addWidget( myNbQuadFace, row, 3 ); + + // volumes + row = l->rowCount(); // retrieve current row count + // -- + lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this); + l->addWidget( lab, row, 0 ); + // -- + myNbVolum = new QLabel( this ); + l->addWidget( myNbVolum, row, 1 ); + // -- + myNbLinVolum = new QLabel( this ); + l->addWidget( myNbLinVolum, row, 2 ); + // -- + myNbQuadVolum = new QLabel( this ); + l->addWidget( myNbQuadVolum, row, 3 ); + } +} + +// ========================================================================================= +/*! + * \brief Set mesh info + */ +// ========================================================================================= + +void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo) +{ + // nodes + myNbNode ->setText( QString("%1").arg( theInfo[SMDSEntity_Node] )); + + //0D elements + my0DElem ->setText( QString("%1").arg( theInfo[SMDSEntity_0D] )); + + //balls + myBall ->setText( QString("%1").arg( theInfo[SMDSEntity_Ball] )); + + // edges + myNbEdge ->setText( QString("%1").arg( theInfo[SMDSEntity_Edge] + + theInfo[SMDSEntity_Quad_Edge] )); + myNbLinEdge ->setText( QString("%1").arg( theInfo[SMDSEntity_Edge] )); + myNbQuadEdge ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Edge] )); + + // faces + myNbFace ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] + + theInfo[SMDSEntity_Quad_Triangle] + + theInfo[SMDSEntity_Quadrangle] + + theInfo[SMDSEntity_Quad_Quadrangle] + + theInfo[SMDSEntity_BiQuad_Quadrangle] + + theInfo[SMDSEntity_Polygon] )); + myNbLinFace ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] + + theInfo[SMDSEntity_Quadrangle] + + theInfo[SMDSEntity_Polygon] )); + myNbQuadFace ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Triangle] + + theInfo[SMDSEntity_Quad_Quadrangle] + + theInfo[SMDSEntity_BiQuad_Quadrangle] )); + + // volumes + myNbVolum ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] + + theInfo[SMDSEntity_Quad_Tetra] + + theInfo[SMDSEntity_Pyramid] + + theInfo[SMDSEntity_Quad_Pyramid] + + theInfo[SMDSEntity_Hexa] + + theInfo[SMDSEntity_Quad_Hexa] + + theInfo[SMDSEntity_TriQuad_Hexa] + + theInfo[SMDSEntity_Penta] + + theInfo[SMDSEntity_Quad_Penta] + + theInfo[SMDSEntity_Hexagonal_Prism] + + theInfo[SMDSEntity_Polyhedra] )); + myNbLinVolum ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] + + theInfo[SMDSEntity_Pyramid] + + theInfo[SMDSEntity_Hexa] + + theInfo[SMDSEntity_Penta] + + theInfo[SMDSEntity_Polyhedra] )); + myNbQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Tetra] + + theInfo[SMDSEntity_Quad_Pyramid] + + theInfo[SMDSEntity_Quad_Hexa] + + theInfo[SMDSEntity_TriQuad_Hexa] + + theInfo[SMDSEntity_Quad_Penta] )); + + if ( myFull ) + { + // triangles + myNbTrai ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] + + theInfo[SMDSEntity_Quad_Triangle] )); + myNbLinTrai ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] )); + myNbQuadTrai ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Triangle] )); + // quadrangles + myNbQuad ->setText( QString("%1").arg( theInfo[SMDSEntity_Quadrangle] + + theInfo[SMDSEntity_Quad_Quadrangle] + + theInfo[SMDSEntity_BiQuad_Quadrangle] )); + myNbLinQuad ->setText( QString("%1").arg( theInfo[SMDSEntity_Quadrangle] )); + myNbQuadQuad ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Quadrangle] + + theInfo[SMDSEntity_BiQuad_Quadrangle])); + // poligones + myNbPolyg ->setText( QString("%1").arg( theInfo[SMDSEntity_Polygon] )); + + // tetras + myNbTetra ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] + + theInfo[SMDSEntity_Quad_Tetra] )); + myNbLinTetra ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] )); + myNbQuadTetra->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Tetra] )); + // hexas + myNbHexa ->setText( QString("%1").arg( theInfo[SMDSEntity_Hexa] + + theInfo[SMDSEntity_TriQuad_Hexa], + theInfo[SMDSEntity_Quad_Hexa] )); + myNbLinHexa ->setText( QString("%1").arg( theInfo[SMDSEntity_Hexa] )); + myNbQuadHexa ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Hexa] + + theInfo[SMDSEntity_TriQuad_Hexa] )); + // pyras + myNbPyra ->setText( QString("%1").arg( theInfo[SMDSEntity_Pyramid] + + theInfo[SMDSEntity_Quad_Pyramid] )); + myNbLinPyra ->setText( QString("%1").arg( theInfo[SMDSEntity_Pyramid] )); + myNbQuadPyra ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Pyramid] )); + // prisms + myNbPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] + + theInfo[SMDSEntity_Quad_Penta] )); + myNbLinPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] )); + myNbQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] )); + // octahedra + myNbHexaPrism->setText( QString("%1").arg( theInfo[ SMDSEntity_Hexagonal_Prism ])); + // polyedres + myNbPolyh ->setText( QString("%1").arg( theInfo[SMDSEntity_Polyhedra] )); + } +} diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosBox.h b/src/SMESHGUI/SMESHGUI_MeshInfosBox.h new file mode 100644 index 000000000..a90a37b29 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshInfosBox.h @@ -0,0 +1,88 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_MeshInfosBox.h +// Author : Edward AGAPOV, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_MeshInfosBox_H +#define SMESHGUI_MeshInfosBox_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QLabel; + +/*! + * \brief Box showing mesh info + */ + +class SMESHGUI_EXPORT SMESHGUI_MeshInfosBox : public QGroupBox +{ + Q_OBJECT + +public: + SMESHGUI_MeshInfosBox( const bool, QWidget* ); + + void SetMeshInfo( const SMESH::long_array& theInfo ); + +private: + bool myFull; + QLabel* myNbNode; + QLabel* my0DElem; + QLabel* myBall; + QLabel* myNbEdge; + QLabel* myNbLinEdge; + QLabel* myNbQuadEdge; + QLabel* myNbTrai; + QLabel* myNbLinTrai; + QLabel* myNbQuadTrai; + QLabel* myNbQuad; + QLabel* myNbLinQuad; + QLabel* myNbQuadQuad; + QLabel* myNbFace; + QLabel* myNbLinFace; + QLabel* myNbQuadFace; + QLabel* myNbPolyg; + QLabel* myNbHexa; + QLabel* myNbLinHexa; + QLabel* myNbQuadHexa; + QLabel* myNbTetra; + QLabel* myNbLinTetra; + QLabel* myNbQuadTetra; + QLabel* myNbPyra; + QLabel* myNbLinPyra; + QLabel* myNbQuadPyra; + QLabel* myNbPrism; + QLabel* myNbLinPrism; + QLabel* myNbQuadPrism; + QLabel* myNbVolum; + QLabel* myNbLinVolum; + QLabel* myNbQuadVolum; + QLabel* myNbHexaPrism; + QLabel* myNbPolyh; +}; + +#endif // SMESHGUI_MeshInfosBox_H diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx deleted file mode 100644 index 005183023..000000000 --- a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx +++ /dev/null @@ -1,645 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_MeshInfosDlg.cxx -// Author : Nicolas BARBEROU -// SMESH includes -// -#include "SMESHGUI_MeshInfosDlg.h" - -#include "SMESHGUI.h" -#include "SMESHGUI_Utils.h" - -// SALOME GUI includes -#include -#include -#include -#include -#include - -#include -#include -#include - -// SALOME KERNEL includes -#include - -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Mesh) -#include CORBA_SERVER_HEADER(SMESH_Group) - -#define COLONIZE(str) (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" ) -#define SPACING 6 -#define MARGIN 11 - -//================================================================================= -// function : SMESHGUI_MeshInfosDlg() -// purpose : Constructor -//================================================================================= -SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg(SMESHGUI* theModule): - QDialog(SMESH::GetDesktop(theModule)), - mySelectionMgr(SMESH::GetSelectionMgr(theModule)), - mySMESHGUI(theModule) -{ - setModal( false ); - setAttribute( Qt::WA_DeleteOnClose, true ); - setWindowTitle(tr("SMESH_MESHINFO_TITLE")); - setSizeGripEnabled(true); - - myStartSelection = true; - myIsActiveWindow = true; - - QVBoxLayout* aTopLayout = new QVBoxLayout(this); - aTopLayout->setSpacing(SPACING); aTopLayout->setMargin(MARGIN); - - // select button & label - QPixmap image0(SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH",tr("ICON_SELECT"))); - mySelectBtn = new QPushButton(this); - mySelectBtn->setIcon(image0); - mySelectBtn->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - - mySelectLab = new QLabel(this); - mySelectLab->setAlignment(Qt::AlignCenter); - QFont fnt = mySelectLab->font(); fnt.setBold(true); - mySelectLab->setFont(fnt); - - QHBoxLayout* aSelectLayout = new QHBoxLayout; - aSelectLayout->setMargin(0); aSelectLayout->setSpacing(0); - aSelectLayout->addWidget(mySelectBtn); - aSelectLayout->addWidget(mySelectLab); - - // top widget stack - myWGStack = new QStackedWidget(this); - - // no valid selection - QWidget* myBadWidget = new QWidget(myWGStack); - QVBoxLayout* aBadLayout = new QVBoxLayout(myBadWidget); - QLabel* myBadLab = new QLabel(tr("SMESH_BAD_SELECTION"), myBadWidget); - myBadLab->setAlignment(Qt::AlignCenter); - myBadLab->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); - aBadLayout->addWidget(myBadLab); - myWGStack->addWidget(myBadWidget); - - // mesh - myMeshWidget = new QWidget(myWGStack); - QGridLayout* aMeshLayout = new QGridLayout(myMeshWidget); - aMeshLayout->setSpacing(SPACING); aMeshLayout->setMargin(0); - myWGStack->addWidget(myMeshWidget); - - // --> name - QLabel* myMeshNameLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NAME")), myMeshWidget); - myMeshName = new QLabel(myMeshWidget); - myMeshName->setMinimumWidth(100); - QFrame* line1 = new QFrame(myMeshWidget); - line1->setFrameStyle(QFrame::HLine | QFrame::Sunken); - - // --> nodes - QLabel* myMeshNbNodesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), myMeshWidget); - myMeshNbNodes = new QLabel(myMeshWidget); - myMeshNbNodes->setMinimumWidth(100); - - // --> header with orders - QLabel* myMeshOrder0Lab = new QLabel(tr("SMESH_MESHINFO_ORDER0"), myMeshWidget); - QLabel* myMeshOrder1Lab = new QLabel(tr("SMESH_MESHINFO_ORDER1"), myMeshWidget); - QLabel* myMeshOrder2Lab = new QLabel(tr("SMESH_MESHINFO_ORDER2"), myMeshWidget); - QFont fnti = myMeshOrder0Lab->font(); fnti.setItalic(true); - myMeshOrder0Lab->setFont(fnti); - myMeshOrder1Lab->setFont(fnti); - myMeshOrder2Lab->setFont(fnti); - - // --> edges - QLabel* myMeshNbEdgesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), myMeshWidget); - myMeshNbEdges = new QLabel(myMeshWidget); - myMeshNbEdges->setMinimumWidth(100); - myMeshNbEdges1 = new QLabel(myMeshWidget); - myMeshNbEdges1->setMinimumWidth(100); - myMeshNbEdges2 = new QLabel(myMeshWidget); - myMeshNbEdges2->setMinimumWidth(100); - - // --> faces - myMeshFacesGroup = new QGroupBox(tr("SMESH_MESHINFO_FACES"), myMeshWidget); - QGridLayout* myMeshFacesGroupLayout = new QGridLayout(myMeshFacesGroup); - myMeshFacesGroupLayout->setSpacing(SPACING); myMeshFacesGroupLayout->setMargin(MARGIN); - - // --> faces --> total - QLabel* myMeshNbFacesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TOTAL")), myMeshFacesGroup); - myMeshNbFacesLab->setFont(fnt); - myMeshNbFaces = new QLabel(myMeshFacesGroup); - myMeshNbFaces->setMinimumWidth(100); - myMeshNbFaces->setFont(fnt); - myMeshNbFaces1 = new QLabel(myMeshFacesGroup); - myMeshNbFaces1->setMinimumWidth(100); - myMeshNbFaces1->setFont(fnt); - myMeshNbFaces2 = new QLabel(myMeshFacesGroup); - myMeshNbFaces2->setMinimumWidth(100); - myMeshNbFaces2->setFont(fnt); - - // --> faces --> triangles - QLabel* myMeshNbTrianglesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), myMeshFacesGroup); - myMeshNbTriangles = new QLabel(myMeshFacesGroup); - myMeshNbTriangles->setMinimumWidth(100); - myMeshNbTriangles1 = new QLabel(myMeshFacesGroup); - myMeshNbTriangles1->setMinimumWidth(100); - myMeshNbTriangles2 = new QLabel(myMeshFacesGroup); - myMeshNbTriangles2->setMinimumWidth(100); - - // --> faces --> quadrangles - QLabel* myMeshNbQuadranglesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), myMeshFacesGroup); - myMeshNbQuadrangles = new QLabel(myMeshFacesGroup); - myMeshNbQuadrangles->setMinimumWidth(100); - myMeshNbQuadrangles1 = new QLabel(myMeshFacesGroup); - myMeshNbQuadrangles1->setMinimumWidth(100); - myMeshNbQuadrangles2 = new QLabel(myMeshFacesGroup); - myMeshNbQuadrangles2->setMinimumWidth(100); - - // --> faces --> polygons - QLabel* myMeshNbPolygonesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_POLYGONES" ) ), myMeshFacesGroup ); - myMeshNbPolygones = new QLabel( myMeshFacesGroup ); - myMeshNbPolygones->setMinimumWidth( 100 ); - - myMeshFacesGroupLayout->addWidget(myMeshNbFacesLab, 0, 0); - myMeshFacesGroupLayout->addWidget(myMeshNbFaces, 0, 1); - myMeshFacesGroupLayout->addWidget(myMeshNbFaces1, 0, 2); - myMeshFacesGroupLayout->addWidget(myMeshNbFaces2, 0, 3); - myMeshFacesGroupLayout->addWidget(myMeshNbTrianglesLab, 1, 0); - myMeshFacesGroupLayout->addWidget(myMeshNbTriangles, 1, 1); - myMeshFacesGroupLayout->addWidget(myMeshNbTriangles1, 1, 2); - myMeshFacesGroupLayout->addWidget(myMeshNbTriangles2, 1, 3); - myMeshFacesGroupLayout->addWidget(myMeshNbQuadranglesLab, 2, 0); - myMeshFacesGroupLayout->addWidget(myMeshNbQuadrangles, 2, 1); - myMeshFacesGroupLayout->addWidget(myMeshNbQuadrangles1, 2, 2); - myMeshFacesGroupLayout->addWidget(myMeshNbQuadrangles2, 2, 3); - myMeshFacesGroupLayout->addWidget(myMeshNbPolygonesLab, 3, 0); - myMeshFacesGroupLayout->addWidget(myMeshNbPolygones, 3, 1); - - // --> volumes - myMeshVolumesGroup = new QGroupBox(tr("SMESH_MESHINFO_VOLUMES"), myMeshWidget); - QGridLayout* myMeshVolumesGroupLayout = new QGridLayout(myMeshVolumesGroup); - myMeshVolumesGroupLayout->setSpacing(SPACING); myMeshVolumesGroupLayout->setMargin(MARGIN); - - // --> volumes --> total - QLabel* myMeshNbVolumesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TOTAL")), myMeshVolumesGroup); - myMeshNbVolumesLab->setFont(fnt); - myMeshNbVolumes = new QLabel(myMeshVolumesGroup); - myMeshNbVolumes->setMinimumWidth(100); - myMeshNbVolumes->setFont(fnt); - myMeshNbVolumes1 = new QLabel(myMeshVolumesGroup); - myMeshNbVolumes1->setMinimumWidth(100); - myMeshNbVolumes1->setFont(fnt); - myMeshNbVolumes2 = new QLabel(myMeshVolumesGroup); - myMeshNbVolumes2->setMinimumWidth(100); - myMeshNbVolumes2->setFont(fnt); - - // --> volumes --> tetrahedrons - QLabel* myMeshNbTetraLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), myMeshVolumesGroup); - myMeshNbTetra = new QLabel(myMeshVolumesGroup); - myMeshNbTetra->setMinimumWidth(100); - myMeshNbTetra1 = new QLabel(myMeshVolumesGroup); - myMeshNbTetra1->setMinimumWidth(100); - myMeshNbTetra2 = new QLabel(myMeshVolumesGroup); - myMeshNbTetra2->setMinimumWidth(100); - - // --> volumes --> hexahedrons - QLabel* myMeshNbHexaLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), myMeshVolumesGroup); - myMeshNbHexa = new QLabel(myMeshVolumesGroup); - myMeshNbHexa->setMinimumWidth(100); - myMeshNbHexa1 = new QLabel(myMeshVolumesGroup); - myMeshNbHexa1->setMinimumWidth(100); - myMeshNbHexa2 = new QLabel(myMeshVolumesGroup); - myMeshNbHexa2->setMinimumWidth(100); - - // --> volumes --> prisms - QLabel* myMeshNbPrismLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), myMeshVolumesGroup); - myMeshNbPrism = new QLabel(myMeshVolumesGroup); - myMeshNbPrism->setMinimumWidth(100); - myMeshNbPrism1 = new QLabel(myMeshVolumesGroup); - myMeshNbPrism1->setMinimumWidth(100); - myMeshNbPrism2 = new QLabel(myMeshVolumesGroup); - myMeshNbPrism2->setMinimumWidth(100); - - // --> volumes --> pyramids - QLabel* myMeshNbPyraLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), myMeshVolumesGroup); - myMeshNbPyra = new QLabel(myMeshVolumesGroup); - myMeshNbPyra->setMinimumWidth(100); - myMeshNbPyra1 = new QLabel(myMeshVolumesGroup); - myMeshNbPyra1->setMinimumWidth(100); - myMeshNbPyra2 = new QLabel(myMeshVolumesGroup); - myMeshNbPyra2->setMinimumWidth(100); - - // --> volumes --> polyherones - QLabel* myMeshNbPolyhedronesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_POLYEDRES" ) ), myMeshVolumesGroup ); - myMeshNbPolyhedrones = new QLabel( myMeshVolumesGroup ); - myMeshNbPolyhedrones->setMinimumWidth( 100 ); - - myMeshVolumesGroupLayout->addWidget(myMeshNbVolumesLab, 0, 0); - myMeshVolumesGroupLayout->addWidget(myMeshNbVolumes, 0, 1); - myMeshVolumesGroupLayout->addWidget(myMeshNbVolumes1, 0, 2); - myMeshVolumesGroupLayout->addWidget(myMeshNbVolumes2, 0, 3); - myMeshVolumesGroupLayout->addWidget(myMeshNbTetraLab, 1, 0); - myMeshVolumesGroupLayout->addWidget(myMeshNbTetra, 1, 1); - myMeshVolumesGroupLayout->addWidget(myMeshNbTetra1, 1, 2); - myMeshVolumesGroupLayout->addWidget(myMeshNbTetra2, 1, 3); - myMeshVolumesGroupLayout->addWidget(myMeshNbHexaLab, 2, 0); - myMeshVolumesGroupLayout->addWidget(myMeshNbHexa, 2, 1); - myMeshVolumesGroupLayout->addWidget(myMeshNbHexa1, 2, 2); - myMeshVolumesGroupLayout->addWidget(myMeshNbHexa2, 2, 3); - myMeshVolumesGroupLayout->addWidget(myMeshNbPrismLab, 3, 0); - myMeshVolumesGroupLayout->addWidget(myMeshNbPrism, 3, 1); - myMeshVolumesGroupLayout->addWidget(myMeshNbPrism1, 3, 2); - myMeshVolumesGroupLayout->addWidget(myMeshNbPrism2, 3, 3); - myMeshVolumesGroupLayout->addWidget(myMeshNbPyraLab, 4, 0); - myMeshVolumesGroupLayout->addWidget(myMeshNbPyra, 4, 1); - myMeshVolumesGroupLayout->addWidget(myMeshNbPyra1, 4, 2); - myMeshVolumesGroupLayout->addWidget(myMeshNbPyra2, 4, 3); - myMeshVolumesGroupLayout->addWidget(myMeshNbPolyhedronesLab, 5, 0); - myMeshVolumesGroupLayout->addWidget(myMeshNbPolyhedrones, 5, 1); - - aMeshLayout->addWidget(myMeshNameLab, 0, 0); - aMeshLayout->addWidget(myMeshName, 0, 1); - aMeshLayout->addWidget(line1, 1, 0, 1, 2); - aMeshLayout->addWidget(myMeshNbNodesLab, 2, 0); - aMeshLayout->addWidget(myMeshNbNodes, 2, 1); - aMeshLayout->addWidget(myMeshOrder0Lab, 3, 1); - aMeshLayout->addWidget(myMeshOrder1Lab, 3, 2); - aMeshLayout->addWidget(myMeshOrder2Lab, 3, 3); - aMeshLayout->addWidget(myMeshNbEdgesLab, 4, 0); - aMeshLayout->addWidget(myMeshNbEdges, 4, 1); - aMeshLayout->addWidget(myMeshNbEdges1, 4, 2); - aMeshLayout->addWidget(myMeshNbEdges2, 4, 3); - aMeshLayout->addWidget(myMeshFacesGroup, 5, 0, 1, 4); - aMeshLayout->addWidget(myMeshVolumesGroup, 6, 0, 1, 4); - aMeshLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 7, 0); - - // submesh - mySubMeshWidget = new QWidget(myWGStack); - QGridLayout* aSubMeshLayout = new QGridLayout(mySubMeshWidget); - aSubMeshLayout->setSpacing(SPACING); aSubMeshLayout->setMargin(0); - myWGStack->addWidget(mySubMeshWidget); - - // --> name - QLabel* mySubMeshNameLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NAME")), mySubMeshWidget); - mySubMeshName = new QLabel(mySubMeshWidget); - mySubMeshName->setMinimumWidth(100); - QFrame* line2 = new QFrame(mySubMeshWidget); - line2->setFrameStyle(QFrame::HLine | QFrame::Sunken); - - // --> nodes - QLabel* mySubMeshNbNodesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), mySubMeshWidget); - mySubMeshNbNodes = new QLabel(mySubMeshWidget); - mySubMeshNbNodes->setMinimumWidth(100); - - // --> elements - mySubMeshElementsGroup = new QGroupBox(tr("SMESH_MESHINFO_ELEMENTS"), mySubMeshWidget); - QGridLayout* mySubMeshElementsGroupLayout = new QGridLayout(mySubMeshElementsGroup); - mySubMeshElementsGroupLayout->setSpacing(SPACING); mySubMeshElementsGroupLayout->setMargin(MARGIN); - - // --> elements --> total - QLabel* mySubMeshNbElementsLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TOTAL")), mySubMeshElementsGroup); - mySubMeshNbElementsLab->setFont(fnt); - mySubMeshNbElements = new QLabel(mySubMeshElementsGroup); - mySubMeshNbElements->setMinimumWidth(100); - mySubMeshNbElements->setFont(fnt); - - // --> elements --> edges - QLabel* mySubMeshNbEdgesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), mySubMeshElementsGroup); - mySubMeshNbEdges = new QLabel(mySubMeshElementsGroup); - mySubMeshNbEdges->setMinimumWidth(100); - - // --> elements --> faces - QLabel* mySubMeshNbFacesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), mySubMeshElementsGroup); - mySubMeshNbFaces = new QLabel(mySubMeshElementsGroup); - mySubMeshNbFaces->setMinimumWidth(100); - - // --> elements --> volumes - QLabel* mySubMeshNbVolumesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), mySubMeshElementsGroup); - mySubMeshNbVolumes = new QLabel(mySubMeshElementsGroup); - mySubMeshNbVolumes->setMinimumWidth(100); - - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbElementsLab, 0, 0); - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbElements, 0, 1); - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbEdgesLab, 1, 0); - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbEdges, 1, 1); - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbFacesLab, 2, 0); - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbFaces, 2, 1); - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbVolumesLab, 3, 0); - mySubMeshElementsGroupLayout->addWidget(mySubMeshNbVolumes, 3, 1); - - aSubMeshLayout->addWidget(mySubMeshNameLab, 0, 0); - aSubMeshLayout->addWidget(mySubMeshName, 0, 1); - aSubMeshLayout->addWidget(line2, 1, 0, 1, 2); - aSubMeshLayout->addWidget(mySubMeshNbNodesLab, 2, 0); - aSubMeshLayout->addWidget(mySubMeshNbNodes, 2, 1); - aSubMeshLayout->addWidget(mySubMeshElementsGroup, 3, 0, 1, 2); - aSubMeshLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0); - - // group - myGroupWidget = new QWidget(myWGStack); - QGridLayout* myGroupWidgetLayout = new QGridLayout(myGroupWidget); - myGroupWidgetLayout->setSpacing(SPACING); myGroupWidgetLayout->setMargin(0); - myWGStack->addWidget(myGroupWidget); - - // --> name - QLabel* myGroupNameLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NAME")), myGroupWidget); - myGroupName = new QLabel(myGroupWidget); - myGroupName->setMinimumWidth(100); - QFrame* line3 = new QFrame(myGroupWidget); - line3->setFrameStyle(QFrame::HLine | QFrame::Sunken); - - // --> type - QLabel* myGroupTypeLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TYPE")), myGroupWidget); - myGroupType = new QLabel(myGroupWidget); - myGroupType->setMinimumWidth(100); - - // --> number of entities - QLabel* myGroupNbLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_ENTITIES")), myGroupWidget); - myGroupNb = new QLabel(myGroupWidget); - myGroupNb->setMinimumWidth(100); - - myGroupWidgetLayout->addWidget(myGroupNameLab, 0, 0); - myGroupWidgetLayout->addWidget(myGroupName, 0, 1); - myGroupWidgetLayout->addWidget(line3, 1, 0, 1, 2); - myGroupWidgetLayout->addWidget(myGroupTypeLab, 2, 0); - myGroupWidgetLayout->addWidget(myGroupType, 2, 1); - myGroupWidgetLayout->addWidget(myGroupNbLab, 3, 0); - myGroupWidgetLayout->addWidget(myGroupNb, 3, 1); - myGroupWidgetLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0); - - // buttons - myButtonsGroup = new QGroupBox(this); - QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout(myButtonsGroup); - myButtonsGroupLayout->setSpacing(SPACING); myButtonsGroupLayout->setMargin(MARGIN); - - // buttons --> OK and Help buttons - myOkBtn = new QPushButton(tr("SMESH_BUT_OK" ), myButtonsGroup); - myOkBtn->setAutoDefault(true); myOkBtn->setDefault(true); - myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP" ), myButtonsGroup); - myHelpBtn->setAutoDefault(true); - - myButtonsGroupLayout->addWidget(myOkBtn); - myButtonsGroupLayout->addSpacing(10); - myButtonsGroupLayout->addStretch(); - myButtonsGroupLayout->addWidget(myHelpBtn); - - aTopLayout->addLayout(aSelectLayout); - aTopLayout->addWidget(myWGStack); - aTopLayout->addWidget(myButtonsGroup); - - mySMESHGUI->SetActiveDialogBox(this); - - // connect signals - connect(myOkBtn, SIGNAL(clicked()), this, SLOT(close())); - connect( myHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp())); - connect(mySelectBtn, SIGNAL(clicked()), this, SLOT(onStartSelection())); - connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close())); - connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); - - // init dialog with current selection - onSelectionChanged(); - - myHelpFileName = "mesh_infos_page.html#advanced_mesh_infos_anchor"; -} - -//================================================================================= -// function : ~SMESHGUI_MeshInfosDlg() -// purpose : Destructor -//================================================================================= -SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg() -{ -} - -//================================================================================= -// function : DumpMeshInfos() -// purpose : -//================================================================================= -void SMESHGUI_MeshInfosDlg::DumpMeshInfos() -{ - SUIT_OverrideCursor wc; - - SALOME_ListIO aList; - mySelectionMgr->selectedObjects(aList); - - int nbSel = aList.Extent(); - if (nbSel == 1) { - myStartSelection = false; - mySelectLab->setText(""); - Handle(SALOME_InteractiveObject) IObject = aList.First(); - _PTR(SObject) aSO = SMESH::GetActiveStudyDocument()->FindObjectID(IObject->getEntry()); - if (aSO) { - //CORBA::Object_var anObject = aSO->GetObject(); - CORBA::Object_var anObject = SMESH::SObjectToObject(aSO); - if (!CORBA::is_nil(anObject)) { - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObject); - if (!aMesh->_is_nil()) { - myWGStack->setCurrentWidget(myMeshWidget); - setWindowTitle(tr("SMESH_MESHINFO_TITLE") + " [" + tr("SMESH_OBJECT_MESH") + "]"); - myMeshName->setText(aSO->GetName().c_str()); - myMeshNbNodes->setNum((int)aMesh->NbNodes()); - myMeshNbEdges->setNum((int)aMesh->NbEdges()); - myMeshNbEdges1->setNum((int)aMesh->NbEdgesOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbEdges2->setNum((int)aMesh->NbEdgesOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbFaces->setNum((int)aMesh->NbFaces()); - myMeshNbFaces1->setNum((int)aMesh->NbFacesOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbFaces2->setNum((int)aMesh->NbFacesOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbTriangles->setNum((int)aMesh->NbTriangles()); - myMeshNbTriangles1->setNum((int)aMesh->NbTrianglesOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbTriangles2->setNum((int)aMesh->NbTrianglesOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbQuadrangles->setNum((int)aMesh->NbQuadrangles()); - myMeshNbQuadrangles1->setNum((int)aMesh->NbQuadranglesOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbQuadrangles2->setNum((int)aMesh->NbQuadranglesOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbPolygones->setNum( (int)aMesh->NbPolygons() ); - myMeshNbVolumes->setNum((int)aMesh->NbVolumes()); - myMeshNbVolumes1->setNum((int)aMesh->NbVolumesOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbVolumes2->setNum((int)aMesh->NbVolumesOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbTetra->setNum((int)aMesh->NbTetras()); - myMeshNbTetra1->setNum((int)aMesh->NbTetrasOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbTetra2->setNum((int)aMesh->NbTetrasOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbHexa->setNum((int)aMesh->NbHexas()); - myMeshNbHexa1->setNum((int)aMesh->NbHexasOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbHexa2->setNum((int)aMesh->NbHexasOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbPrism->setNum((int)aMesh->NbPrisms()); - myMeshNbPrism1->setNum((int)aMesh->NbPrismsOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbPrism2->setNum((int)aMesh->NbPrismsOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbPyra->setNum((int)aMesh->NbPyramids()); - myMeshNbPyra1->setNum((int)aMesh->NbPyramidsOfOrder(SMESH::ORDER_LINEAR)); - myMeshNbPyra2->setNum((int)aMesh->NbPyramidsOfOrder(SMESH::ORDER_QUADRATIC)); - myMeshNbPolyhedrones->setNum( (int)aMesh->NbPolyhedrons() ); - return; - } - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObject); - if (!aSubMesh->_is_nil()) { - myWGStack->setCurrentWidget(mySubMeshWidget); - setWindowTitle(tr("SMESH_MESHINFO_TITLE") + " [" + tr("SMESH_SUBMESH") + "]"); - mySubMeshName->setText(aSO->GetName().c_str()); - mySubMeshNbNodes->setNum((int)aSubMesh->GetNumberOfNodes(true)); - mySubMeshNbElements->setNum((int)aSubMesh->GetNumberOfElements()); - mySubMeshNbEdges->setNum((int)(aSubMesh->GetElementsByType(SMESH::EDGE)->length())); - mySubMeshNbFaces->setNum((int)(aSubMesh->GetElementsByType(SMESH::FACE)->length())); - mySubMeshNbVolumes->setNum((int)(aSubMesh->GetElementsByType(SMESH::VOLUME)->length())); - return; - } - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject); - if (!aGroup->_is_nil()) { - myWGStack->setCurrentWidget(myGroupWidget); - setWindowTitle(tr("SMESH_MESHINFO_TITLE") + " [" + tr("SMESH_GROUP") + "]"); - myGroupName->setText(aSO->GetName().c_str()); - int aType = aGroup->GetType(); - QString strType; - switch (aType) { - case SMESH::NODE: - strType = "SMESH_MESHINFO_NODES"; break; - case SMESH::EDGE: - strType = "SMESH_MESHINFO_EDGES"; break; - case SMESH::FACE: - strType = "SMESH_MESHINFO_FACES"; break; - case SMESH::VOLUME: - strType = "SMESH_MESHINFO_VOLUMES"; break; - default: - strType = "SMESH_MESHINFO_ALL_TYPES"; break; - } - - myGroupType->setText(tr(strType.toLatin1().data())); - myGroupNb->setNum((int)aGroup->Size()); - return; - } - } - } - } - myWGStack->setCurrentIndex(0); - setWindowTitle(tr("SMESH_MESHINFO_TITLE")); -} - -//================================================================================= -// function : SelectionIntoArgument() -// purpose : Called when selection has changed -//================================================================================= -void SMESHGUI_MeshInfosDlg::onSelectionChanged() -{ - if (myStartSelection) - DumpMeshInfos(); -} - -//================================================================================= -// function : closeEvent() -// purpose : -//================================================================================= -void SMESHGUI_MeshInfosDlg::closeEvent(QCloseEvent* e) -{ - mySMESHGUI->ResetState(); - QDialog::closeEvent(e); -} - -//================================================================================= -// function : windowActivationChange() -// purpose : called when window is activated/deactivated -//================================================================================= -void SMESHGUI_MeshInfosDlg::windowActivationChange(bool oldActive) -{ - QDialog::windowActivationChange(oldActive); - if (isActiveWindow() && myIsActiveWindow != isActiveWindow()) - ActivateThisDialog(); - myIsActiveWindow = isActiveWindow(); -} - -//================================================================================= -// function : DeactivateActiveDialog() -// purpose : -//================================================================================= -void SMESHGUI_MeshInfosDlg::DeactivateActiveDialog() -{ - disconnect(mySelectionMgr, 0, this, 0); -} - -//================================================================================= -// function : ActivateThisDialog() -// purpose : -//================================================================================= -void SMESHGUI_MeshInfosDlg::ActivateThisDialog() -{ - /* Emit a signal to deactivate any active dialog */ - mySMESHGUI->EmitSignalDeactivateDialog(); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); -} - -//================================================================================= -// function : onStartSelection() -// purpose : starts selection -//================================================================================= -void SMESHGUI_MeshInfosDlg::onStartSelection() -{ - myStartSelection = true; - onSelectionChanged(); - myStartSelection = true; - mySelectLab->setText(tr("INF_SELECT_OBJECT")); -} - -//================================================================================= -// function : onHelp() -// purpose : -//================================================================================= -void SMESHGUI_MeshInfosDlg::onHelp() -{ - LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) - app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); - else { - QString platform; -#ifdef WIN32 - platform = "winapplication"; -#else - platform = "application"; -#endif - SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); - } -} - -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void SMESHGUI_MeshInfosDlg::keyPressEvent( QKeyEvent* e ) -{ - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; - - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - onHelp(); - } -} diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h deleted file mode 100644 index b2b84c9e6..000000000 --- a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_MeshInfosDlg.h -// Author : Nicolas BARBEROU -// -#ifndef SMESHGUI_MESHINFOSDLG_H -#define SMESHGUI_MESHINFOSDLG_H - -// SMESH includes -#include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include - -class QGroupBox; -class QLabel; -class QPushButton; -class QStackedWidget; - -class LightApp_SelectionMgr; -class SMESHGUI; - -class SMESHGUI_EXPORT SMESHGUI_MeshInfosDlg : public QDialog -{ - Q_OBJECT - -public: - SMESHGUI_MeshInfosDlg( SMESHGUI* ); - ~SMESHGUI_MeshInfosDlg(); - -protected: - void closeEvent( QCloseEvent* ); - void keyPressEvent( QKeyEvent* ); - void windowActivationChange( bool ); - void DumpMeshInfos(); - -private slots: - void onSelectionChanged(); - void DeactivateActiveDialog(); - void ActivateThisDialog(); - void onStartSelection(); - void onHelp(); - -private: - SMESHGUI* mySMESHGUI; - LightApp_SelectionMgr* mySelectionMgr; - bool myStartSelection; - bool myIsActiveWindow; - - QPushButton* mySelectBtn; - QLabel* mySelectLab; - - QStackedWidget* myWGStack; - - QWidget* myMeshWidget; - QLabel* myMeshName; - QLabel* myMeshNbNodes; - QLabel* myMeshNbEdges; - QLabel* myMeshNbEdges1; - QLabel* myMeshNbEdges2; - QGroupBox* myMeshFacesGroup; - QLabel* myMeshNbFaces; - QLabel* myMeshNbFaces1; - QLabel* myMeshNbFaces2; - QLabel* myMeshNbTriangles; - QLabel* myMeshNbTriangles1; - QLabel* myMeshNbTriangles2; - QLabel* myMeshNbQuadrangles; - QLabel* myMeshNbQuadrangles1; - QLabel* myMeshNbQuadrangles2; - QLabel* myMeshNbPolygones; - QGroupBox* myMeshVolumesGroup; - QLabel* myMeshNbVolumes; - QLabel* myMeshNbVolumes1; - QLabel* myMeshNbVolumes2; - QLabel* myMeshNbTetra; - QLabel* myMeshNbTetra1; - QLabel* myMeshNbTetra2; - QLabel* myMeshNbHexa; - QLabel* myMeshNbHexa1; - QLabel* myMeshNbHexa2; - QLabel* myMeshNbPyra; - QLabel* myMeshNbPyra1; - QLabel* myMeshNbPyra2; - QLabel* myMeshNbPrism; - QLabel* myMeshNbPrism1; - QLabel* myMeshNbPrism2; - QLabel* myMeshNbPolyhedrones; - - QWidget* mySubMeshWidget; - QLabel* mySubMeshName; - QLabel* mySubMeshNbNodes; - QGroupBox* mySubMeshElementsGroup; - QLabel* mySubMeshNbElements; - QLabel* mySubMeshNbEdges; - QLabel* mySubMeshNbFaces; - QLabel* mySubMeshNbVolumes; - - QWidget* myGroupWidget; - QLabel* myGroupName; - QLabel* myGroupType; - QLabel* myGroupNb; - - QGroupBox* myButtonsGroup; - QPushButton* myOkBtn; - QPushButton* myHelpBtn; - - QString myHelpFileName; -}; - -#endif // SMESHGUI_MESHINFOSDLG_H diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 351e6034e..9ad1a47fc 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_MeshOp.cxx -// Author : Sergey LITONIN, Open CASCADE S.A.S. +// File : SMESHGUI_MeshOp.cxx +// Author : Sergey LITONIN, Open CASCADE S.A.S. + // SMESH includes -// #include "SMESHGUI_MeshOp.h" #include "SMESHGUI.h" @@ -45,10 +44,12 @@ // SALOME GUI includes #include #include +#include #include #include #include #include +#include #include #include @@ -71,6 +72,10 @@ #include #include CORBA_CLIENT_HEADER(SMESH_Gen) +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + //================================================================================ /*! * \brief Constructor @@ -85,7 +90,8 @@ SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh ) myToCreate( theToCreate ), myIsMesh( theIsMesh ), myDlg( 0 ), - myShapeByMeshOp( 0 ) + myShapeByMeshOp( 0 ), + myHypoSet( 0 ) { if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists GeometryGUI::InitGeomGen(); @@ -141,14 +147,21 @@ bool SMESHGUI_MeshOp::onApply() aMess = ""; try { + QStringList anEntryList; if ( myToCreate && myIsMesh ) - aResult = createMesh( aMess ); + aResult = createMesh( aMess, anEntryList ); if ( myToCreate && !myIsMesh ) - aResult = createSubMesh( aMess ); + aResult = createSubMesh( aMess, anEntryList ); else if ( !myToCreate ) aResult = editMeshOrSubMesh( aMess ); if ( aResult ) + { + SMESHGUI::Modified(); update( UF_ObjBrowser | UF_Model ); + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() ); + } } catch ( const SALOME::SALOME_Exception& S_ex ) { @@ -232,14 +245,36 @@ void SMESHGUI_MeshOp::startOperation() else myDlg->activateObject( SMESHGUI_MeshDlg::Obj ); - myDlg->setHypoSets( SMESH::GetHypothesesSets() ); - myDlg->setCurrentTab( SMESH::DIM_3D ); myDlg->show(); - + myDlg->setGeomPopupEnabled(false); selectionDone(); myIgnoreAlgoSelection = false; + + myObjectToSelect.clear(); +} + +//================================================================================= +/*! + * \brief Selects a recently created mesh or sub-mesh if necessary + * + * Virtual method redefined from base class called when operation is commited + * selects a recently created mesh or sub-mesh if necessary. Allows to perform + * selection when the custom selection filters are removed. + */ +//================================================================================= +void SMESHGUI_MeshOp::commitOperation() +{ + SMESHGUI_SelectionOp::commitOperation(); + + if ( !myObjectToSelect.isEmpty() ) { + if ( LightApp_SelectionMgr* aSelectionMgr = selectionMgr() ) { + SUIT_DataOwnerPtrList aList; + aList.append( new LightApp_DataOwner( myObjectToSelect ) ); + aSelectionMgr->setSelected( aList ); + } + } } //================================================================================ @@ -271,11 +306,10 @@ SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const //================================================================================ /*! - * \brief check if selected shape is a subshape of the shape to mesh + * \brief check if selected shape is a sub-shape of the shape to mesh * \retval bool - check result */ //================================================================================ - bool SMESHGUI_MeshOp::isSubshapeOk() const { if ( !myToCreate || myIsMesh ) // not submesh creation @@ -338,11 +372,10 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const //================================================================================ /*! * \brief Return name of the algorithm that does not support submeshes and makes - * submesh creation useless + * submesh creation useless * \retval char* - string is to be deleted!!! */ //================================================================================ - char* SMESHGUI_MeshOp::isSubmeshIgnored() const { if ( myToCreate && !myIsMesh ) { @@ -388,7 +421,6 @@ char* SMESHGUI_MeshOp::isSubmeshIgnored() const * \retval _PTR(SObject) - the found submesh SObject */ //================================================================================ - _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const { QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); @@ -499,48 +531,52 @@ void SMESHGUI_MeshOp::selectionDone() } if (aSeq->length() > 0) { - shapeDim = 0; + shapeDim = -1; for (int iss = 0; iss < aSeq->length() && shapeDim < 3; iss++) { GEOM::GEOM_Object_var aGeomVar = aSeq[iss]; switch ( aGeomVar->GetShapeType() ) { case GEOM::SOLID: shapeDim = 3; break; case GEOM::SHELL: - { - //shapeDim = 3; // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab - shapeDim = (shapeDim < 2) ? 2 : shapeDim; - TopoDS_Shape aShape; - if (GEOMBase::GetShape(aGeomVar, aShape)) { - if (/*aShape.Closed()*/BRep_Tool::IsClosed(aShape)) - shapeDim = 3; - } - } - break; - case GEOM::FACE: shapeDim = (shapeDim < 2) ? 2 : shapeDim; break; + // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab + // { + // TopoDS_Shape aShape; + // bool isClosed = GEOMBase::GetShape(aGeomVar, aShape) && /*aShape.Closed()*/BRep_Tool::IsClosed(aShape); + // shapeDim = qMax(isClosed ? 3 : 2, shapeDim); + // } + // break; + case GEOM::FACE: shapeDim = qMax(2, shapeDim); break; case GEOM::WIRE: - case GEOM::EDGE: shapeDim = (shapeDim < 1) ? 1 : shapeDim; break; - case GEOM::VERTEX: break; + case GEOM::EDGE: shapeDim = qMax(1, shapeDim); break; + case GEOM::VERTEX: shapeDim = qMax(0, shapeDim); break; default: { TopoDS_Shape aShape; - if (GEOMBase::GetShape(aGeomVar, aShape)) { - TopExp_Explorer exp (aShape, TopAbs_SHELL); + if (GEOMBase::GetShape(aGeomVar, aShape)) + { + TopExp_Explorer exp (aShape, TopAbs_SOLID); if (exp.More()) { - //shapeDim = 3; // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab - shapeDim = (shapeDim < 2) ? 2 : shapeDim; - for (; exp.More() && shapeDim == 2; exp.Next()) { - if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current())) - shapeDim = 3; - } + shapeDim = 3; } + // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab + // else if ( exp.Init( aShape, TopAbs_SHELL ), exp.More() ) + // { + // shapeDim = 2; + // for (; exp.More() && shapeDim == 2; exp.Next()) { + // if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current())) + // shapeDim = 3; + // } + // } else if ( exp.Init( aShape, TopAbs_FACE ), exp.More() ) - shapeDim = (shapeDim < 2) ? 2 : shapeDim; + shapeDim = qMax(2, shapeDim); else if ( exp.Init( aShape, TopAbs_EDGE ), exp.More() ) - shapeDim = (shapeDim < 1) ? 1 : shapeDim; - else - ;//shapeDim = 0; + shapeDim = qMax(1, shapeDim); + else if ( exp.Init( aShape, TopAbs_VERTEX ), exp.More() ) + shapeDim = qMax(0, shapeDim); } } } + if ( shapeDim == 3 ) + break; } } for (int i = SMESH::DIM_3D; i > shapeDim; i--) { @@ -548,7 +584,7 @@ void SMESHGUI_MeshOp::selectionDone() onAlgoSelected(-1, i); } myDlg->setMaxHypoDim( shapeDim ); - + myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim )); if (!myToCreate) // edition: read hypotheses { @@ -575,11 +611,11 @@ void SMESHGUI_MeshOp::selectionDone() SMESH::SObjectToInterface( pSubmesh ); bool editSubmesh = ( !sm->_is_nil() && SUIT_MessageBox::question( myDlg, tr( "SMESH_WARNING" ), - tr( "EDIT_SUBMESH_QUESTION"), - SUIT_MessageBox::Yes | - SUIT_MessageBox::No, - SUIT_MessageBox::No ) - == SUIT_MessageBox::Yes ); + tr( "EDIT_SUBMESH_QUESTION"), + SUIT_MessageBox::Yes | + SUIT_MessageBox::No, + SUIT_MessageBox::No ) + == SUIT_MessageBox::Yes ); if ( editSubmesh ) { selectionMgr()->clearFilters(); @@ -612,13 +648,19 @@ void SMESHGUI_MeshOp::selectionDone() QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() )) { SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface( pMesh ); - if ( !mesh->_is_nil() ) + if ( !mesh->_is_nil() ) { + //rnv: issue 21056: EDF 1608 SMESH: Dialog Box "Create Sub Mesh": focus should automatically switch to geometry + QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() ); + if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() ) + myDlg->activateObject(SMESHGUI_MeshDlg::Geom); enable = ( shapeDim > 1 ) && ( mesh->NbEdges() > 0 ); + } } myDlg->setGeomPopupEnabled( enable ); } } - else { + else { // no geometry defined myDlg->enableTab( SMESH::DIM_3D ); QStringList hypList; availableHyps( SMESH::DIM_3D, Algo, hypList, @@ -738,7 +780,6 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const * \retval bool - check result */ //================================================================================ - static bool isCompatible(const HypothesisData* theAlgoData, const HypothesisData* theHypData, const int theHypType) @@ -856,6 +897,7 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, if ( !aHypVar->_is_nil() ) { HypothesisData* aData = SMESH::GetHypothesisData( aHypVar->GetName() ); + if ( !aData) continue; if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) && ( isCompatible ( theAlgoData, aData, theHypType )) && ( isAux == aData->IsAux )) @@ -874,14 +916,13 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, //================================================================================ /*! * \brief If create or edit a submesh, return a hypothesis holding parameters used - * to mesh a subshape + * to mesh a sub-shape * \param aHypType - The hypothesis type name * \param aServerLib - Server library name * \param hypData - The structure holding the hypothesis type etc. * \retval SMESH::SMESH_Hypothesis_var - the hypothesis holding parameter values */ //================================================================================ - SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType, const QString& aServerLib ) const @@ -944,12 +985,19 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType, } } - return SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(), - aServerLib.toLatin1().data(), - aMeshVar, - aGeomVar, - /*byMesh = */isSubMesh); - + SMESH::SMESH_Hypothesis_var hyp = + SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(), + aServerLib.toLatin1().data(), + aMeshVar, + aGeomVar, + /*byMesh = */isSubMesh); + if ( hyp->_is_nil() && isSubMesh ) + hyp = SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(), + aServerLib.toLatin1().data(), + aMeshVar, + aGeomVar, + /*byMesh = */false); + return hyp; } //================================================================================ @@ -960,7 +1008,6 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType, * \retval int - dimention */ //================================================================================ - static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg ) { int aDim = -1; @@ -997,14 +1044,6 @@ void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex ) createHypothesis(aDim, theHypType, aHypTypeName); } -//================================================================================ -/*! - * Create hypothesis and update dialog. - * \param theDim - dimension of hypothesis to be created - * \param theType - hypothesis category (algorithm, hypothesis, additional hypothesis) - * \param theTypeName - specifies hypothesis to be created - */ -//================================================================================ namespace { QString GetUniqueName (const QStringList& theHypNames, @@ -1018,18 +1057,24 @@ namespace } } -void SMESHGUI_MeshOp::createHypothesis (const int theDim, - const int theType, - const QString& theTypeName) +//================================================================================ +/*! + * Create hypothesis and update dialog. + * \param theDim - dimension of hypothesis to be created + * \param theType - hypothesis category (algorithm, hypothesis, additional hypothesis) + * \param theTypeName - specifies hypothesis to be created + */ +//================================================================================ +void SMESHGUI_MeshOp::createHypothesis(const int theDim, + const int theType, + const QString& theTypeName) { - // During a hypothesis creation we might need to select some objects. - // Main dialog must not update it's own selected objects in this case. - dlg()->deactivateAll(); - HypothesisData* aData = SMESH::GetHypothesisData(theTypeName); if (!aData) return; + myDim = theDim; + myType = theType; QStringList aHypNames; TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin(); for ( ; aDimIter != myExistingHyps.end(); aDimIter++) { @@ -1048,14 +1093,21 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim, QString aHypName = GetUniqueName( aHypNames, aData->Label); // existing hypos - int nbHyp = myExistingHyps[theDim][theType].count(); + bool dialog = false; QString aClientLibName = aData->ClientLibName; if (aClientLibName == "") { // Call hypothesis creation server method (without GUI) - SMESH::CreateHypothesis(theTypeName, aHypName, false); + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(theTypeName, aHypName, false); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->UnRegister(); +#endif } else { // Get hypotheses creator client (GUI) + // BUG 0020378 + //SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName); SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName); // Create hypothesis @@ -1063,23 +1115,110 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim, // Get parameters appropriate to initialize a new hypothesis SMESH::SMESH_Hypothesis_var initParamHyp = getInitParamsHypothesis(theTypeName, aData->ServerLibName); + + removeCustomFilters(); // Issue 0020170 + + // Get Entry of the Geom object + QString aGeomEntry = ""; + QString aMeshEntry = ""; + QString anObjEntry = ""; + aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); + anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); + + if ( myToCreate && myIsMesh ) + aMeshEntry = aGeomEntry; + + if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited + _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() ); + GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj ); + aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry(); + } + + if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); + bool isMesh; + GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh ); + if ( !aGeomVar->_is_nil() ) + { + aGeomEntry = aGeomVar->GetStudyEntry(); + if ( isMesh ) + aMeshEntry = aGeomEntry; + } + } + + if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) { + // take geometry from submesh being created + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); + if ( pObj ) { + // if current object is sub-mesh + SMESH::SMESH_subMesh_var aSubMeshVar = + SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() ); + if ( !aSubMeshVar->_is_nil() ) { + SMESH::SMESH_Mesh_var aMeshVar = aSubMeshVar->GetFather(); + if ( !aMeshVar->_is_nil() ) { + _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar ); + GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO ); + if ( !aGeomVar->_is_nil() ) + aMeshEntry = aGeomVar->GetStudyEntry(); + } + } + } + } + + aCreator->setShapeEntry( aGeomEntry ); + if ( aMeshEntry != "" ) + aCreator->setMainShapeEntry( aMeshEntry ); myDlg->setEnabled( false ); - aCreator->create(initParamHyp, aHypName, myDlg); - myDlg->setEnabled( true ); - } else { - SMESH::CreateHypothesis(theTypeName, aHypName, false); + aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) ); + dialog = true; + } + else { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(theTypeName, aHypName, false); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->UnRegister(); +#endif } } + if( !dialog ) + onHypoCreated(2); +} + +//================================================================================ +/*! + * Necessary steps after hypothesis creation + * \param result - creation result: + * 0 = rejected + * 1 = accepted + * 2 = additional value meaning that slot is called not from dialog box + */ +//================================================================================ +void SMESHGUI_MeshOp::onHypoCreated( int result ) +{ + if( result != 2 ) + { + int obj = myDlg->getActiveObject(); + onActivateObject( obj ); // Issue 0020170. Restore filters + myDlg->setEnabled( true ); + } + _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); - HypothesisData* algoData = hypData( theDim, Algo, currentHyp( theDim, Algo )); + int nbHyp = myExistingHyps[myDim][myType].count(); + HypothesisData* algoData = hypData( myDim, Algo, currentHyp( myDim, Algo )); QStringList aNewHyps; - existingHyps(theDim, theType, aFather, aNewHyps, myExistingHyps[theDim][theType], algoData); - if (aNewHyps.count() > nbHyp) { + existingHyps(myDim, myType, aFather, aNewHyps, myExistingHyps[myDim][myType], algoData); + if (aNewHyps.count() > nbHyp) + { for (int i = nbHyp; i < aNewHyps.count(); i++) - myDlg->tab(theDim)->addHyp(theType, aNewHyps[i]); + myDlg->tab(myDim)->addHyp(myType, aNewHyps[i]); } + + if( result!=2 && myHypoSet ) + processSet(); } //================================================================================ @@ -1107,18 +1246,86 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex ) if ( aHyp->_is_nil() ) return; - SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( aHyp->GetName() ); - if ( aCreator ) { + SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHyp->GetName()); + if ( aCreator ) + { // Get initial parameters SMESH::SMESH_Hypothesis_var initParamHyp = getInitParamsHypothesis( aHyp->GetName(), aHyp->GetLibName()); - myDlg->setEnabled( false ); aCreator->setInitParamsHypothesis( initParamHyp ); - aCreator->edit( aHyp.in(), aHypItem.second, dlg() ); - myDlg->setEnabled( true ); + + // Get Entry of the Geom object + QString aGeomEntry = ""; + QString aMeshEntry = ""; + QString anObjEntry = ""; + aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); + anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); + + if ( myToCreate && myIsMesh ) + aMeshEntry = aGeomEntry; + + if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited + _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() ); + GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj ); + aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry(); + } + + if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); + bool isMesh; + GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh ); + if ( !aGeomVar->_is_nil() ) + { + aGeomEntry = aGeomVar->GetStudyEntry(); + if ( isMesh ) + aMeshEntry = aGeomEntry; + } + } + + if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) { + // take geometry from submesh being created + _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); + if ( pObj ) { + // if current object is sub-mesh + SMESH::SMESH_subMesh_var aSubMeshVar = + SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() ); + if ( !aSubMeshVar->_is_nil() ) { + SMESH::SMESH_Mesh_var aMeshVar = aSubMeshVar->GetFather(); + if ( !aMeshVar->_is_nil() ) { + _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar ); + GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO ); + if ( !aGeomVar->_is_nil() ) + aMeshEntry = aGeomVar->GetStudyEntry(); + } + } + } + } + + aCreator->setShapeEntry( aGeomEntry ); + if ( aMeshEntry != "" ) + aCreator->setMainShapeEntry( aMeshEntry ); + removeCustomFilters(); // Issue 0020170 + myDlg->setEnabled( false ); + aCreator->edit( aHyp.in(), aHypItem.second, dlg(), this, SLOT( onHypoEdited( int ) ) ); } } +//================================================================================ +/*! + * Necessary steps after hypothesis edition + * \param result - creation result: + * 0 = rejected + * 1 = accepted + */ +//================================================================================ +void SMESHGUI_MeshOp::onHypoEdited( int result ) +{ + int obj = myDlg->getActiveObject(); + onActivateObject( obj ); // Issue 0020170. Restore filters + myDlg->setEnabled( true ); +} + //================================================================================ /*! * \brief access to hypothesis data @@ -1128,7 +1335,6 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex ) * \retval HypothesisData* - result data, may be 0 */ //================================================================================ - HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim, const int theHypType, const int theIndex) @@ -1146,7 +1352,6 @@ HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim, * \param theIndex - algorithm index */ //================================================================================ - void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, const int theDim ) { @@ -1255,7 +1460,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, CORBA::String_var curHypType = curHyp->GetName(); if ( !algoDeselectedByUser && myObjHyps[ dim ][ type ].count() > 0 && - curHypType == myObjHyps[ dim ][ type ].first().first->GetName()) + !strcmp( curHypType, myObjHyps[ dim ][ type ].first().first->GetName()) ) { HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() ); for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) { @@ -1310,8 +1515,9 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, //================================================================================ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName ) { - HypothesesSet* aHypoSet = SMESH::GetHypothesesSet(theSetName); - if (!aHypoSet) return; + myHypoSet = SMESH::GetHypothesesSet(theSetName); + if (!myHypoSet) + return; // clear all hyps for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) { @@ -1320,57 +1526,81 @@ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName ) setCurrentHyp(dim, MainHyp, -1); } - for (int aHypType = Algo; aHypType < AddHyp; aHypType++) { - bool isAlgo = (aHypType == Algo); + myHypoSet->init(true); //algorithms + processSet(); + myHypoSet->init(false); //hypotheses + processSet(); + myHypoSet = 0; +} - // set hyps from the set - QStringList* aHypoList = isAlgo ? &aHypoSet->AlgoList : &aHypoSet->HypoList; - for (int i = 0, n = aHypoList->count(); i < n; i++) { - const QString& aHypoTypeName = (*aHypoList)[ i ]; - HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName); - if (!aHypData) - continue; +//================================================================================ +/*! + * \brief One step of hypothesis/algorithm list creation + * + * Creates a hypothesis or an algorithm for current item of internal list of names myHypoSet + */ +//================================================================================ +void SMESHGUI_MeshOp::processSet() +{ + myHypoSet->next(); + if( !myHypoSet->more() ) + return; - int aDim = aHypData->Dim[0]; - // create or/and set - if (isAlgo) { - int index = myAvailableHypData[aDim][Algo].indexOf( aHypData ); - if ( index < 0 ) { - QStringList anAvailable; - availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] ); - myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable ); - index = myAvailableHypData[aDim][Algo].indexOf( aHypData ); - } - setCurrentHyp( aDim, Algo, index ); - onAlgoSelected( index, aDim ); - } - else { - bool mainHyp = true; - QStringList anAvailable; - availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] ); - myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable ); - int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData ); - if ( index < 0 ) { - mainHyp = false; - index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData ); - } - if (index >= 0) - createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName); - } - } // loop on hypos in the set - } // loop on algo/hypo + bool isAlgo = myHypoSet->isAlgo(); + QString aHypoTypeName = myHypoSet->current(); + HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName); + if (!aHypData) + { + processSet(); + return; + } + + int aDim = aHypData->Dim[0]; + // create or/and set + if (isAlgo) + { + int index = myAvailableHypData[aDim][Algo].indexOf( aHypData ); + if ( index < 0 ) + { + QStringList anAvailable; + availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] ); + myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable ); + index = myAvailableHypData[aDim][Algo].indexOf( aHypData ); + } + setCurrentHyp( aDim, Algo, index ); + onAlgoSelected( index, aDim ); + processSet(); + } + else + { + bool mainHyp = true; + QStringList anAvailable; + availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] ); + myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable ); + int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData ); + if ( index < 0 ) + { + mainHyp = false; + index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData ); + } + if (index >= 0) + createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName); + else + processSet(); + } } //================================================================================ /*! * \brief Creates mesh * \param theMess - Output parameter intended for returning error message + * \param theEntryList - List of entries of published objects * \retval bool - TRUE if mesh is created, FALSE otherwise * * Creates mesh */ //================================================================================ -bool SMESHGUI_MeshOp::createMesh( QString& theMess ) +bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList ) { theMess = ""; @@ -1398,8 +1628,10 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess ) if ( aMeshVar->_is_nil() ) return false; _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() ); - if ( aMeshSO ) + if ( aMeshSO ) { SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) ); + theEntryList.append( aMeshSO->GetID().c_str() ); + } for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) { if ( !isAccessibleDim( aDim )) continue; @@ -1418,7 +1650,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess ) if ( !anAlgoVar->_is_nil() ) SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar ); } - +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + if (aMeshSO) + aMeshVar->UnRegister(); +#endif } return true; } @@ -1427,12 +1665,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess ) /*! * \brief Creates sub-mesh * \param theMess - Output parameter intended for returning error message + * \param theEntryList - List of entries of published objects * \retval bool - TRUE if sub-mesh is created, FALSE otherwise * * Creates sub-mesh */ //================================================================================ -bool SMESHGUI_MeshOp::createSubMesh( QString& theMess ) +bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList ) { theMess = ""; @@ -1506,8 +1745,8 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess ) QString aNewGeomGroupName ("Auto_group_for_"); aNewGeomGroupName += aName; SALOMEDS::SObject_var aNewGroupSO = - geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, - aNewGeomGroupName.toLatin1().data(), mainGeom); + geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, + aNewGeomGroupName.toLatin1().data(), mainGeom); } } } @@ -1522,8 +1761,10 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess ) // create sub-mesh SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.toLatin1().data() ); _PTR(SObject) aSubMeshSO = SMESH::FindSObject( aSubMeshVar.in() ); - if ( aSubMeshSO ) + if ( aSubMeshSO ) { SMESH::SetName( aSubMeshSO, aName.toLatin1().data() ); + theEntryList.append( aSubMeshSO->GetID().c_str() ); + } for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) { @@ -1547,7 +1788,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess ) } } - // deselect geometry: next submesh should be created on other subshape + // deselect geometry: next submesh should be created on other sub-shape myDlg->clearSelection( SMESHGUI_MeshDlg::Geom ); selectObject( _PTR(SObject)() ); selectionDone(); @@ -1579,7 +1820,7 @@ int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const //================================================================================ bool SMESHGUI_MeshOp::isAccessibleDim( const int theDim ) const { - return myDlg->tab( theDim )->isEnabled(); + return myDlg->isTabEnabled( theDim ); } //================================================================================ @@ -1653,36 +1894,53 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) QStringList tmp; existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]); - // look for anexisting algo of such a type + // look for an existing algo of such a type THypList& aHypVarList = myExistingHyps[ theDim ][ Algo ]; THypList::iterator anIter = aHypVarList.begin(); for ( ; anIter != aHypVarList.end(); anIter++) { SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first; CORBA::String_var aName = aHypVar->GetName(); - if ( !aHypVar->_is_nil() && aHypName == aName ) + if ( !aHypVar->_is_nil() && !strcmp(aHypName.toLatin1().data(), aName) ) { anAlgoVar = aHypVar; break; } } - if (anAlgoVar->_is_nil()) { + if (anAlgoVar->_is_nil()) + { HypothesisData* aHypData = SMESH::GetHypothesisData( aHypName ); - if (aHypData) { + if (aHypData) + { QString aClientLibName = aHypData->ClientLibName; - if (aClientLibName == "") { + if (aClientLibName == "") + { // Call hypothesis creation server method (without GUI) - SMESH::CreateHypothesis(aHypName, aHypData->Label, true); - } else { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(aHypName, aHypName, true); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->UnRegister(); +#endif + } + else + { // Get hypotheses creator client (GUI) + // BUG 0020378 SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypName); // Create algorithm if (aCreator) - aCreator->create(true, aHypName, myDlg); - else - SMESH::CreateHypothesis(aHypName, aHypData->Label, true); + aCreator->create(true, aHypName, myDlg, 0, QString::null ); + else { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(aHypName, aHypName, true); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->UnRegister(); +#endif + } } QStringList tmpList; _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" ); @@ -1694,7 +1952,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) { SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first; CORBA::String_var aName = aHypVar->GetName(); - if ( !aHypVar->_is_nil() && aHypName == aName ) + if ( !aHypVar->_is_nil() && !strcmp(aHypName.toLatin1().data(), aName) ) { anAlgoVar = aHypVar; break; @@ -1983,14 +2241,14 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) //================================================================================ /*! * \brief Verifies whether given operator is valid for this one - * \param theOtherOp - other operation - * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise -* -* method redefined from base class verifies whether given operator is valid for -* this one (i.e. can be started "above" this operator). In current implementation method -* retuns false if theOtherOp operation is not intended for deleting objects or mesh -* elements. -*/ + * \param theOtherOp - other operation + * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise + * + * method redefined from base class verifies whether given operator is valid for + * this one (i.e. can be started "above" this operator). In current implementation method + * retuns false if theOtherOp operation is not intended for deleting objects or mesh + * elements. + */ //================================================================================ bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const { @@ -2000,10 +2258,9 @@ bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const //================================================================================ /*! * \brief SLOT. Is called when the user selects a way of geometry selection - * \param theByMesh - true if the user wants to find geometry by mesh element + * \param theByMesh - true if the user wants to find geometry by mesh element */ //================================================================================ - void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh ) { if ( theByMesh ) { @@ -2035,7 +2292,6 @@ void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh ) * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg */ //================================================================================ - void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op) { if ( myShapeByMeshOp == op ) { @@ -2059,7 +2315,6 @@ void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op) * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg */ //================================================================================ - void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op) { if ( myShapeByMeshOp == op && myDlg ) { @@ -2070,10 +2325,9 @@ void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op) //================================================================================ /*! * \brief Selects a SObject - * \param theSObj - the SObject to select + * \param theSObj - the SObject to select */ //================================================================================ - void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const { if ( LightApp_SelectionMgr* sm = selectionMgr() ) { diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.h b/src/SMESHGUI/SMESHGUI_MeshOp.h index 1046b699c..c7b11d437 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.h +++ b/src/SMESHGUI/SMESHGUI_MeshOp.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshOp.h // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -31,6 +32,7 @@ #include "SMESHGUI_SelectionOp.h" +class HypothesesSet; class SMESHGUI_MeshDlg; class SMESHGUI_ShapeByMeshOp; class HypothesisData; @@ -64,6 +66,7 @@ public: protected: virtual void startOperation(); + virtual void commitOperation(); virtual void selectionDone(); virtual SUIT_SelectionFilter* createFilter( const int ) const; virtual bool isValid( SUIT_Operation* ) const; @@ -77,6 +80,9 @@ protected slots: void onPublishShapeByMeshDlg( SUIT_Operation* ); void onCloseShapeByMeshDlg( SUIT_Operation* ); void onAlgoSelected( const int, const int = -1 ); + void processSet(); + void onHypoCreated( int ); + void onHypoEdited( int ); private: typedef QList THypDataList; // typedef: list of hypothesis data @@ -98,10 +104,10 @@ private: const int ); // access to myAvailableHypData void createHypothesis( const int, const int, - const QString& ); + const QString& ); - bool createMesh( QString& ); - bool createSubMesh( QString& ); + bool createMesh( QString&, QStringList& ); + bool createSubMesh( QString&, QStringList& ); bool editMeshOrSubMesh( QString& ); int currentHyp( const int, const int ) const; @@ -135,6 +141,10 @@ private: THypDataList myAvailableHypData[4][NbHypTypes]; bool myIgnoreAlgoSelection; + HypothesesSet* myHypoSet; + int myDim, myType; + + QString myObjectToSelect; }; #endif // SMESHGUI_MESHOP_H diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshOrderDlg.cxx new file mode 100644 index 000000000..7b55ee575 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshOrderDlg.cxx @@ -0,0 +1,330 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_MeshOrderDlg.cxx +// Author : Pavel TELKOV, Open CASCADE S.A.S. +// SMESH includes +// +#include "SMESHGUI_MeshOrderDlg.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 + +/*! + * Enumeartion of list widget item types (mesh name or separator) + */ +enum MeshOrderItemType { MeshItem = QListWidgetItem::UserType, SeparatorItem }; + +// ========================================================================================= +/*! + * \brief Constructor + */ +// ========================================================================================= + +SMESHGUI_MeshOrderBox::SMESHGUI_MeshOrderBox(QWidget* theParent) +: QGroupBox( theParent ), myIsChanged( false ), myUpBtn(0), myDownBtn(0) +{ + QHBoxLayout* hBoxLayout = new QHBoxLayout(this); + hBoxLayout->setMargin( MARGIN ); + hBoxLayout->setSpacing( SPACING ); + + myMeshNames = new QListWidget(this); + myMeshNames->setSelectionMode(QAbstractItemView::SingleSelection); + myMeshNames->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding )); + hBoxLayout->addWidget(myMeshNames); + + QGroupBox* btnGrp = new QGroupBox(this); + hBoxLayout->addWidget(btnGrp); + + myUpBtn = new QToolButton(btnGrp); + myDownBtn = new QToolButton(btnGrp); + myUpBtn-> setArrowType( Qt::UpArrow ); + myDownBtn->setArrowType( Qt::DownArrow ); + + QVBoxLayout* vBoxLayout = new QVBoxLayout(btnGrp); + vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); + vBoxLayout->addWidget( myUpBtn ); + vBoxLayout->addWidget( myDownBtn ); + vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); + + connect( myUpBtn, SIGNAL( clicked() ), this, SLOT( onMoveItem() ) ); + connect( myDownBtn, SIGNAL( clicked() ), this, SLOT( onMoveItem() ) ); + connect( myMeshNames, SIGNAL( itemSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); + + onSelectionChanged(); +} + +// ========================================================================================= +/*! + * \brief Destructor + */ +//======================================================================= + +SMESHGUI_MeshOrderBox::~SMESHGUI_MeshOrderBox() +{ +} + +// ========================================================================================= +/*! + * \brief add separator item + */ +// ========================================================================================= + +static void addSeparator( QListWidget* theList ) +{ + QListWidgetItem* item = new QListWidgetItem( theList, SeparatorItem ); + QFrame* hline = new QFrame( theList ); + hline->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + theList->addItem( item ); + theList->setItemWidget( item, hline ); +} + +// ========================================================================================= +/*! + * \brief add sub-mesh item + */ +// ========================================================================================= + +static void addMeshItem( QListWidget* theList, + const QString& theName, + const int theId ) +{ + QListWidgetItem* item = new QListWidgetItem( theName, theList, MeshItem ); + item->setData( Qt::UserRole, theId ); + theList->addItem( item ); +} + +// ========================================================================================= +/*! + * \brief Clear submesh names and indeces + */ +// ========================================================================================= + +void SMESHGUI_MeshOrderBox::Clear() +{ + myMeshNames->clear(); + myIsChanged = false; +} + +// ========================================================================================= +/*! + * \brief Set submesh names and indeces + */ +// ========================================================================================= + +void SMESHGUI_MeshOrderBox::SetMeshes(const ListListName& theMeshNames, + const ListListId& theMeshIds) +{ + Clear(); + ListListName::const_iterator nLIt = theMeshNames.constBegin(); + ListListId::const_iterator idLIt = theMeshIds.constBegin(); + for ( ; nLIt != theMeshNames.constEnd(); ++nLIt, ++idLIt ) + { + const QStringList& names = (*nLIt); + const QList& ids = (*idLIt); + if ( myMeshNames->count() ) + addSeparator( myMeshNames ); + QStringList::const_iterator nameIt = names.constBegin(); + QList::const_iterator idIt = ids.constBegin(); + for ( ; nameIt != names.constEnd(); ++nameIt, ++idIt ) + addMeshItem( myMeshNames, *nameIt, *idIt ); + } +} + +// ========================================================================================= +/*! + * \brief cehck that item exists and not a separator + */ +// ========================================================================================= + +static bool checkItem(QListWidgetItem* theItem) +{ + return theItem && (int)theItem->type() != (int)SeparatorItem; +} + +// ========================================================================================= +/*! + * \brief Returns result (ordered by user) mesh names + */ +// ========================================================================================= + +ListListId SMESHGUI_MeshOrderBox::GetMeshIds() const +{ + ListListId aLLIds; + aLLIds.append( QList() ); + for ( int i = 0, n = myMeshNames->count(); i < n; i++ ) + { + QListWidgetItem* it = myMeshNames->item( i ); + if (checkItem( it )) + aLLIds.last().append( it->data( Qt::UserRole ).toInt() ); + else // separator before next list of mesh items + aLLIds.append( QList() ); + } + return aLLIds; +} + +// ========================================================================================= +/*! + * \brief Returns result (ordered by user) mesh indeces + */ +// ========================================================================================= + +ListListName SMESHGUI_MeshOrderBox::GetMeshNames() const +{ + ListListName aLLNames; + aLLNames.append( QStringList() ); + for ( int i = 0, n = myMeshNames->count(); i < n; i++ ) + { + QListWidgetItem* it = myMeshNames->item( i ); + if (checkItem( it )) + aLLNames.last().append( it->text() ); + else // separator before next list of mesh items + aLLNames.append( QStringList() ); + } + return aLLNames; +} + +// ========================================================================================= +/*! + * \brief update state of arrow buttons according to selection + */ +// ========================================================================================= + +void SMESHGUI_MeshOrderBox::onSelectionChanged() +{ + bool isUp = false; + bool isDown = false; + QList items = myMeshNames->selectedItems(); + if ( !items.isEmpty() ) + { + QListWidgetItem* selItem = (*(items.begin())); + if (checkItem(selItem)) + { + const int rowId = myMeshNames->row( selItem ); + isUp = checkItem( myMeshNames->item( rowId - 1 ) ); + isDown = checkItem( myMeshNames->item( rowId + 1 ) ); + } + } + myUpBtn-> setEnabled( isUp ); + myDownBtn->setEnabled( isDown ); +} + +// ========================================================================================= +/*! + * \brief move item according to clicked arrow button + */ +// ========================================================================================= + +void SMESHGUI_MeshOrderBox::onMoveItem() +{ + moveItem( sender() == myUpBtn ); +} + +// ========================================================================================= +/*! + * \brief move mesh in order up or down + */ +// ========================================================================================= + +void SMESHGUI_MeshOrderBox::moveItem(const bool theIsUp) +{ + // move selected list item up or down + QList items = myMeshNames->selectedItems(); + if ( items.isEmpty() ) + return; + QListWidgetItem * selItem = (*(items.begin())); + if (!checkItem(selItem)) + return; + int rowId = myMeshNames->row( selItem ); + if ( rowId == -1 ) + return; + + // move item in list widget + myIsChanged = true; + myMeshNames->takeItem( rowId ); + myMeshNames->insertItem(theIsUp ? rowId-1 : rowId+1, selItem ); + + // restore selection and current status + selItem->setSelected( true ); + myMeshNames->setCurrentItem( selItem ); +} + +// ========================================================================================= +/*! + * \brief returns status is order changed by user + */ +// ========================================================================================= + +bool SMESHGUI_MeshOrderBox:: IsOrderChanged() const +{ + return myIsChanged; +} + +// ========================================================================================= +/*! + * \brief Constructor + */ +// ========================================================================================= + +SMESHGUI_MeshOrderDlg::SMESHGUI_MeshOrderDlg(QWidget* theParent) +: SMESHGUI_Dialog( theParent, false, false, OK | Cancel | Help ) +{ + setWindowTitle( tr( "SMESH_MESHORDER_TITLE") ); + QFrame* main = mainFrame(); + + QVBoxLayout* aDlgLay = new QVBoxLayout (main); + aDlgLay->setMargin( 0 ); + aDlgLay->setSpacing( SPACING ); + + myBox = new SMESHGUI_MeshOrderBox( main ); + + aDlgLay->addWidget(myBox); + aDlgLay->setStretchFactor(main, 1); +} + +// ========================================================================================= +/*! + * \brief Destructor + */ +// ========================================================================================= + +SMESHGUI_MeshOrderDlg::~SMESHGUI_MeshOrderDlg() +{ +} + +// ========================================================================================= +/*! + * \brief return Box widget to show mesh order + */ +// ========================================================================================= + +SMESHGUI_MeshOrderBox* SMESHGUI_MeshOrderDlg::GetMeshOrderBox() const +{ + return myBox; +} diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderDlg.h b/src/SMESHGUI/SMESHGUI_MeshOrderDlg.h new file mode 100644 index 000000000..ec12055bb --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshOrderDlg.h @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_MeshOrderDlg.h +// Author : Pavel TELKOV, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_MeshOrderDlg_H +#define SMESHGUI_MeshOrderDlg_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" +#include "SMESHGUI_Dialog.h" + +// Qt includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QToolButton; +class QListWidget; + +typedef QList ListListName; +typedef QList ListId; +typedef QList ListListId; + +/*! + * \brief Reusable widget that shows and allows modify meshing order + */ + +class SMESHGUI_EXPORT SMESHGUI_MeshOrderBox : public QGroupBox +{ + Q_OBJECT + + public: + /*! Public methods */ + SMESHGUI_MeshOrderBox( QWidget* ); + ~SMESHGUI_MeshOrderBox(); + + //! Clear mesh box + void Clear(); + + //! Set mesh (submesh) names and indeces + void SetMeshes(const ListListName& theMeshNames, + const ListListId& theMeshIds); + + //! returns status is order changed by user + bool IsOrderChanged() const; + + //! Returns result (ordered by user) mesh names + ListListId GetMeshIds() const; + //! Returns result (ordered by user) mesh indeces + ListListName GetMeshNames() const; + + private slots: + /*! Private slots */ + //! update state of arrow buttons according to selection + void onSelectionChanged(); + //! move item according to clicked arrow button + void onMoveItem(); + + private: + /*! Privatemethods */ + //! move mesh in order up or down + void moveItem(const bool theIsUp); + + private: + /*! Private fields */ + bool myIsChanged; + QToolButton* myUpBtn; + QToolButton* myDownBtn; + QListWidget* myMeshNames; +}; + +/*! + * \brief Dialog contains mesh order box for modification operation + */ + +class SMESHGUI_EXPORT SMESHGUI_MeshOrderDlg : public SMESHGUI_Dialog +{ + Q_OBJECT + + public: + /*! Public methods */ + SMESHGUI_MeshOrderDlg( QWidget* ); + ~SMESHGUI_MeshOrderDlg(); + + SMESHGUI_MeshOrderBox* GetMeshOrderBox() const; + + private: + /*! Private fields */ + SMESHGUI_MeshOrderBox* myBox; +}; + +#endif // SMESHGUI_MeshOrderDlg_H diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx new file mode 100644 index 000000000..f2a138d1d --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx @@ -0,0 +1,325 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_MeshOrderOp.cxx +// Author : Pavel TELKOV, Open CASCADE S.A.S. +// +#include "SMESHGUI_MeshOrderOp.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_MeshUtils.h" + +// SALOME GUI includes +#include +#include +#include +#include +#include +#include + +// SALOME KERNEL includes +#include +#include + +// STL includes +#include + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_MeshOrderOp::SMESHGUI_MeshOrderOp() + : SMESHGUI_Operation(), myDlg(0), myMgr(0) +{ + myDlg = new SMESHGUI_MeshOrderDlg( desktop() ); + + myHelpFileName = "constructing_meshes_page.html#mesh_order_anchor"; +} + +//================================================================================ +/*! + * \brief Destructor +*/ +//================================================================================ + +SMESHGUI_MeshOrderOp::~SMESHGUI_MeshOrderOp() +{ +} + +//================================================================================ +/*! + * \brief Return operation dialog + */ +//================================================================================ + +LightApp_Dialog* SMESHGUI_MeshOrderOp::dlg() const +{ + return myDlg; +} + +//================================================================================ +/*! + * \brief perform it's intention action: compute 2D mesh on 3D + */ +//================================================================================ + +void SMESHGUI_MeshOrderOp::startOperation() +{ + SMESHGUI_Operation::startOperation(); + if (myMgr) + myDlg->show(); +} + +//================================================================================ +/*! + * \brief Init dialog and mesh order box + */ +//================================================================================ + +void SMESHGUI_MeshOrderOp::initDialog() +{ + if (!myDlg ) + return; + + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil(); + // check selection + LightApp_SelectionMgr *Sel = selectionMgr(); + SALOME_ListIO selected; Sel->selectedObjects( selected ); + + if (selected.Extent() == 1) + aMesh = SMESH::GetMeshByIO(selected.First()); + if (aMesh->_is_nil()) { + SUIT_MessageBox::warning(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_NO_AVAILABLE_DATA")); + onCancel(); + return; + } + + myMgr = new SMESHGUI_MeshOrderMgr( myDlg->GetMeshOrderBox() ); + myMgr->SetMesh( aMesh ); + if ( !myMgr->GetMeshOrder() ) { + SUIT_MessageBox::information(desktop(), + tr("SMESH_INFORMATION"), + tr("SMESH_NO_CONCURENT_MESH")); + + onCancel(); + return; + } +} + +//================================================================================ +/*! + * \brief Apply changes + */ +//================================================================================ + +bool SMESHGUI_MeshOrderOp::onApply() +{ + SUIT_OverrideCursor aWaitCursor; + bool res = myMgr ? myMgr->SetMeshOrder() : false; + + if( res ) + SMESHGUI::Modified(); + + delete myMgr; + myMgr = 0; + + return res; +} + +//================================================================================ +/*! + * \brief Apply changes + */ +//================================================================================ + +void SMESHGUI_MeshOrderOp::onCancel() +{ + delete myMgr; + myMgr = 0; + + abort(); +} + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_MeshOrderMgr::SMESHGUI_MeshOrderMgr( SMESHGUI_MeshOrderBox* theBox ) +: myBox( theBox ) +{ + myMesh = SMESH::SMESH_Mesh::_nil(); +} + +//================================================================================ +/*! + * \brief Destructor +*/ +//================================================================================ + +SMESHGUI_MeshOrderMgr::~SMESHGUI_MeshOrderMgr() +{ +} + +//================================================================================ +/*! + * \brief Set root mesh object + */ +//================================================================================ + +void SMESHGUI_MeshOrderMgr::SetMesh(SMESH::SMESH_Mesh_var& theMesh) +{ + myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh); + _PTR(SObject) aMeshSObj = SMESH::FindSObject(theMesh); + if ( myBox && aMeshSObj ) + myBox->setTitle( aMeshSObj->GetName().c_str() ); +} + +//================================================================================ +/*! + * \brief Check for concurents between submesh objects + */ +//================================================================================ + +bool SMESHGUI_MeshOrderMgr::GetMeshOrder() +{ + ListListId idListList; + return GetMeshOrder(idListList); +} + +//================================================================================ +/*! + * \brief Check for concurents between submesh objects + */ +//================================================================================ + +bool SMESHGUI_MeshOrderMgr::GetMeshOrder(ListListId& theIdListList) +{ + if (!myBox || myMesh->_is_nil()) + return false; + myBox->Clear(); + SMESH::submesh_array_array_var meshOrder = myMesh->GetMeshOrder(); + if ( !meshOrder.operator->() || !meshOrder->length() ) + return false; + ListListName nameListList; + for ( int i = 0, n = meshOrder->length(); i < n; i++ ) + { + QList idList; + QStringList nameList; + const SMESH::submesh_array& aSMArray = meshOrder[i]; + for ( int j = 0, jn = aSMArray.length(); j < jn; j++ ) + { + const SMESH::SMESH_subMesh_var subMesh = aSMArray[j]; + + _PTR(SObject) aSubMeshSObj = SMESH::FindSObject(subMesh); + if ( !aSubMeshSObj ) + continue; + + idList.append(subMesh->GetId() ); + nameList.append( QString(aSubMeshSObj->GetName().c_str()) ); + } + theIdListList.append(idList); + nameListList.append(nameList); + } + myBox->SetMeshes(nameListList, theIdListList); + return !theIdListList.isEmpty(); +} + +//================================================================================ +/*! + * \brief Returns status is order changed by user + */ +//================================================================================ + +bool SMESHGUI_MeshOrderMgr::IsOrderChanged() const +{ + return myBox && myBox->IsOrderChanged(); +} + +//================================================================================ +/*! + * \brief Store submesh priority order + */ +//================================================================================ + +bool SMESHGUI_MeshOrderMgr::SetMeshOrder() +{ + return myBox ? SetMeshOrder(myBox->GetMeshIds()) : false; +} + +//================================================================================ +/*! + * \brief Store submesh priority order + */ +//================================================================================ + +bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const ListListId& theListListIds ) +{ + if (theListListIds.isEmpty() || myMesh->_is_nil()) + return false; + + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh); + if ( !aStudy || !aMeshSObj ) + return false; + + std::map mapOfSubMesh; + for (int i = SMESH::Tag_FirstSubMesh; i <= SMESH::Tag_LastSubMesh; i++) { + _PTR(SObject) aSubmeshRoot; + if ( !aMeshSObj->FindSubObject( i, aSubmeshRoot ) ) + continue; + _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot ); + for ( ; smIter->More(); smIter->Next() ) { + _PTR(SObject) aSmObj = smIter->Value(); + SMESH::SMESH_subMesh_var sm = + SMESH::SObjectToInterface( aSmObj ); + mapOfSubMesh[ sm->GetId() ] = SMESH::SMESH_subMesh::_duplicate(sm); + } + } + + // is it enought to set modifid attribute on root mesh objects only? + // it is seems that modifaction flag will be set on child submeshes + // automatically (see SMESH::ModifiedMesh for details) + SMESH::ModifiedMesh( aMeshSObj, false, false ); + + SMESH::submesh_array_array_var meshOrder = new SMESH::submesh_array_array(); + meshOrder->length(theListListIds.count() ); + ListListId::const_iterator it = theListListIds.constBegin(); + for ( int i = 0; it != theListListIds.constEnd(); ++it ) { + const QList& ids = *it; + SMESH::submesh_array_var subMeshList = new SMESH::submesh_array(); + subMeshList->length( ids.count() ); + QList::const_iterator subIt = ids.constBegin(); + for( int j = 0; subIt != ids.constEnd(); ++subIt ) + if ( mapOfSubMesh.find( *subIt ) != mapOfSubMesh.end() ) + subMeshList[ j++ ] = mapOfSubMesh[ *subIt ]; + + meshOrder[ i++ ] = subMeshList; + } + // update object browser + SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); + + return myMesh->SetMeshOrder(meshOrder); +} diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderOp.h b/src/SMESHGUI/SMESHGUI_MeshOrderOp.h new file mode 100644 index 000000000..f21e84842 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshOrderOp.h @@ -0,0 +1,93 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_MeshOrderOp.h +// Author : Pavel TELKOV, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_MeshOrderOp_H +#define SMESHGUI_MeshOrderOp_H + + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +#include "SMESHGUI_Operation.h" +#include "SMESHGUI_MeshOrderDlg.h" + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Gen) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +/*! + * \brief Operator to check and modify mesh computation submesh priority (order) + */ +class SMESHGUI_EXPORT SMESHGUI_MeshOrderMgr +{ +public: + SMESHGUI_MeshOrderMgr( SMESHGUI_MeshOrderBox* ); + virtual ~SMESHGUI_MeshOrderMgr(); + //! Set root mesh object + void SetMesh( SMESH::SMESH_Mesh_var& theMesh ); + //! Check for concurents between submesh objects + bool GetMeshOrder(); + //! Check for concurents between submesh objects + bool GetMeshOrder( ListListId& theIds ); + //! Store submesh priority order + bool SetMeshOrder(); + //! Store given submesh priority order + bool SetMeshOrder( const ListListId& theIds ); + + //! Returns status is order changed by user + bool IsOrderChanged() const; + +private: + SMESH::SMESH_Mesh_var myMesh; + SMESHGUI_MeshOrderBox* myBox; +}; + +/*! + * \brief Operator to check and modify mesh computation submesh priority (order) + */ +class SMESHGUI_EXPORT SMESHGUI_MeshOrderOp: public SMESHGUI_Operation +{ + Q_OBJECT + +public: + SMESHGUI_MeshOrderOp(); + virtual ~SMESHGUI_MeshOrderOp(); + +protected: + virtual LightApp_Dialog* dlg() const; + + virtual void startOperation(); + + //! sets the dialog widgets to state just after operation start + virtual void initDialog(); + + protected slots: + virtual bool onApply(); + virtual void onCancel(); + + private: + SMESHGUI_MeshOrderDlg* myDlg; + SMESHGUI_MeshOrderMgr* myMgr; +}; + +#endif // SMESHGUI_MeshOrderOp_H diff --git a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx index 8456928f7..cfb1f0e64 100755 --- a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshPatternDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -397,7 +398,7 @@ void SMESHGUI_MeshPatternDlg::Init() updateGeometry(); - resize(minimumSize()); + resize(100,100); activateSelection(); onSelectionDone(); @@ -420,10 +421,10 @@ bool SMESHGUI_MeshPatternDlg::isValid (const bool theMess) ok = myNode2->isValid( msg, theMess ) && ok; if( !ok ) { if( theMess ) { - QString str( tr( "SMESH_INCORRECT_INPUT" ) ); - if ( !msg.isEmpty() ) - str += "\n" + msg; - SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str ); + QString str( tr( "SMESH_INCORRECT_INPUT" ) ); + if ( !msg.isEmpty() ) + str += "\n" + msg; + SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str ); } return false; } @@ -432,22 +433,22 @@ bool SMESHGUI_MeshPatternDlg::isValid (const bool theMess) QList ids; if ((isRefine() && (myMesh->_is_nil() || !getIds(ids) || getNode(false) < 0 || - myType == Type_3d && (getNode(true) < 0 || getNode(false) == getNode(true)))) + (myType == Type_3d && (getNode(true) < 0 || getNode(false) == getNode(true))))) || (!isRefine() && (myMesh->_is_nil() || myMeshShape->_is_nil() || myGeomObj[ Object ]->_is_nil() || - myGeomObj[ Vertex1 ]->_is_nil() || myType == Type_3d && myGeomObj[ Vertex2 ]->_is_nil()))) + myGeomObj[ Vertex1 ]->_is_nil() || (myType == Type_3d && myGeomObj[ Vertex2 ]->_is_nil())))) { if (theMess) SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"), - tr("SMESHGUI_INVALID_PARAMETERS")); + tr("SMESHGUI_INVALID_PARAMETERS")); return false; } if ( myName->text().isEmpty() ) { if (theMess) SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"), - tr("SMESHGUI_INVALID_PARAMETERS")); + tr("SMESHGUI_INVALID_PARAMETERS")); return false; } @@ -467,22 +468,23 @@ bool SMESHGUI_MeshPatternDlg::onApply() erasePreview(); if (isRefine()) { // Refining existing mesh elements + { + QStringList aParameters; + aParameters << myNode1->text(); + if(myType == Type_3d ) + aParameters << myNode2->text(); + myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + } QList ids; getIds(ids); SMESH::long_array_var varIds = new SMESH::long_array(); varIds->length(ids.count()); int i = 0; for (QList::iterator it = ids.begin(); it != ids.end(); ++it) - varIds[i++] = *it; + varIds[i++] = *it; myType == Type_2d - ? myPattern->ApplyToMeshFaces (myMesh, varIds, getNode(false), myReverseChk->isChecked()) - : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true)); - - QStringList aParameters; - aParameters << myNode1->text(); - if(myType == Type_3d ) - aParameters << myNode2->text(); - myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); + ? myPattern->ApplyToMeshFaces (myMesh, varIds, getNode(false), myReverseChk->isChecked()) + : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true)); } else { // Applying a pattern to geometrical object if (myType == Type_2d) @@ -497,18 +499,19 @@ bool SMESHGUI_MeshPatternDlg::onApply() //mySelectionMgr->clearSelected(); bool autoUpdate = SMESHGUI::automaticUpdate(); if (!isRefine() && autoUpdate) { - _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in()); - SMESH_Actor* anActor = SMESH::FindActorByEntry(aSO->GetID().c_str()); - if (!anActor) { - anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()); - if (anActor) { - SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor); - SMESH::FitAll(); - } - } + _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in()); + SMESH_Actor* anActor = SMESH::FindActorByEntry(aSO->GetID().c_str()); + if (!anActor) { + anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()); + if (anActor) { + SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor); + SMESH::FitAll(); + } + } } mySelectionMgr->clearSelected(); SMESH::UpdateView(); + SMESHGUI::Modified(); mySMESHGUI->updateObjBrowser(true); @@ -517,7 +520,7 @@ bool SMESHGUI_MeshPatternDlg::onApply() return true; } else { SUIT_MessageBox::information(this, tr("SMESH_ERROR"), - tr("SMESH_OPERATION_FAILED")); + tr("SMESH_OPERATION_FAILED")); return false; } } catch (const SALOME::SALOME_Exception& S_ex) { @@ -565,17 +568,17 @@ void SMESHGUI_MeshPatternDlg::onHelp() if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { - QString platform; + QString platform; #ifdef WIN32 - platform = "winapplication"; + platform = "winapplication"; #else - platform = "application"; + platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -593,7 +596,7 @@ void SMESHGUI_MeshPatternDlg::onSelectionDone() SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); if (aList.Extent() != 1) - return; + return; // Retrieve mesh from selection Handle(SALOME_InteractiveObject) anIO = aList.First(); @@ -624,11 +627,11 @@ void SMESHGUI_MeshPatternDlg::onSelectionDone() SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); if (aList.Extent() != 1) - return; + return; QString anIds; if (!SMESH::GetNameOfSelectedElements(mySelector, aList.First(), anIds)) - anIds = ""; + anIds = ""; myBusy = true; mySelEdit[ Ids ]->setText(anIds); @@ -638,7 +641,7 @@ void SMESHGUI_MeshPatternDlg::onSelectionDone() SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type()); if (aList.Extent() != 1) - return; + return; // Get geom object from selection Handle(SALOME_InteractiveObject) anIO = aList.First(); @@ -809,14 +812,14 @@ void SMESHGUI_MeshPatternDlg::onOpen() QFile aFile(fName); if (!aFile.open(QIODevice::ReadOnly)) { SUIT_MessageBox::information(this, tr("SMESH_ERROR"), - tr("ERROR_OF_OPENING")); + tr("ERROR_OF_OPENING")); return; } QByteArray aDataArray = aFile.readAll(); if (aDataArray.isEmpty()) { SUIT_MessageBox::information(this, tr("SMESH_ERROR"), - tr("ERROR_OF_READING")); + tr("ERROR_OF_READING")); return; } @@ -1046,11 +1049,11 @@ void SMESHGUI_MeshPatternDlg::updateWgState() if (!CORBA::is_nil(myPattern)/* && getIds(ids)*/) { SMESH::long_array_var keyPoints = myPattern->GetKeyPoints(); if (keyPoints->length()) { - myNode1->setEnabled(true); - myNode2->setEnabled(true); - myNode1->setRange(1, keyPoints->length()); - myNode2->setRange(1, keyPoints->length()); - return; + myNode1->setEnabled(true); + myNode2->setEnabled(true); + myNode1->setRange(1, keyPoints->length()); + myNode2->setRange(1, keyPoints->length()); + return; } } @@ -1075,13 +1078,13 @@ void SMESHGUI_MeshPatternDlg::activateSelection() if (myType == Type_2d) { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); } else { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(CellSelection); } } else { @@ -1123,7 +1126,7 @@ bool SMESHGUI_MeshPatternDlg::loadFromFile (const QString& theName) SMESH::SMESH_Pattern_var aPattern = SMESH::GetPattern(); if (!aPattern->LoadFromFile(theName.toLatin1().data()) || - myType == Type_2d && !aPattern->Is2D()) { + (myType == Type_2d && !aPattern->Is2D())) { SMESH::SMESH_Pattern::ErrorCode aCode = aPattern->GetErrorCode(); QString aMess; if (aCode == SMESH::SMESH_Pattern::ERR_READ_NB_POINTS ) aMess = tr("ERR_READ_NB_POINTS"); @@ -1146,7 +1149,7 @@ bool SMESHGUI_MeshPatternDlg::loadFromFile (const QString& theName) } catch (const SALOME::SALOME_Exception& S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); SUIT_MessageBox::information(this, tr("SMESH_ERROR"), - tr("ERROR_OF_LOADING") ); + tr("ERROR_OF_LOADING") ); return false; } } @@ -1229,13 +1232,13 @@ vtkUnstructuredGrid* SMESHGUI_MeshPatternDlg::getGrid() varIds->length(ids.count()); int i = 0; for (QList::iterator it = ids.begin(); it != ids.end(); ++it) - varIds[i++] = *it; + varIds[i++] = *it; pnts = myType == Type_2d - ? myPattern->ApplyToMeshFaces (myMesh, varIds, getNode(false), myReverseChk->isChecked()) - : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true)); + ? myPattern->ApplyToMeshFaces (myMesh, varIds, getNode(false), myReverseChk->isChecked()) + : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true)); } else { pnts = myType == Type_2d - ? myPattern->ApplyToFace (myGeomObj[ Object ], myGeomObj[ Vertex1 ], myReverseChk->isChecked()) + ? myPattern->ApplyToFace (myGeomObj[ Object ], myGeomObj[ Vertex1 ], myReverseChk->isChecked()) : myPattern->ApplyTo3DBlock(myGeomObj[ Object ], myGeomObj[ Vertex1 ], myGeomObj[ Vertex2 ]); } @@ -1380,7 +1383,7 @@ void SMESHGUI_MeshPatternDlg::onTextChanged (const QString& theNewText) for (int i = 0; i < aListId.count(); i++) { const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); if (e && e->GetType() == (myType == Type_2d ? SMDSAbs_Face : SMDSAbs_Volume)) - newIndices.Add(e->GetID()); + newIndices.Add(e->GetID()); } mySelector->AddOrRemoveIndex( anActor->getIO(), newIndices, false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) diff --git a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h index e3e2d6870..76e6aca77 100755 --- a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h +++ b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_MeshPatternDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. // diff --git a/src/SMESHGUI/SMESHGUI_MeshUtils.cxx b/src/SMESHGUI/SMESHGUI_MeshUtils.cxx index b524c2f83..13898d991 100644 --- a/src/SMESHGUI/SMESHGUI_MeshUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshUtils.cxx // Author : Open CASCADE S.A.S. @@ -26,6 +27,7 @@ // #include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI.h" #include "SMESHGUI_Utils.h" // SALOME KERNEL includes @@ -37,6 +39,7 @@ // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Measurements) namespace SMESH { @@ -46,13 +49,13 @@ namespace SMESH if(!CORBA::is_nil(anObj)){ SMESH_Mesh_var aMesh = SMESH_Mesh::_narrow(anObj); if(!CORBA::is_nil(aMesh)) - return aMesh; + return aMesh; SMESH_GroupBase_var aGroup = SMESH_GroupBase::_narrow(anObj); if(!CORBA::is_nil(aGroup)) - return aGroup->GetMesh(); + return aGroup->GetMesh(); SMESH_subMesh_var aSubMesh = SMESH_subMesh::_narrow(anObj); if(!CORBA::is_nil(aSubMesh)) - return aSubMesh->GetFather(); + return aSubMesh->GetFather(); } return SMESH_Mesh::_nil(); } @@ -65,20 +68,69 @@ namespace SMESH QString name = baseName; while ( !aStudy->FindObjectByName( name.toLatin1().data(), "SMESH" ).empty() ) { int nb = 0; - QStringList names = name.split("_", QString::KeepEmptyParts); - if ( names.count() > 0 ) { - bool ok; - int index = names.last().toInt( &ok ); - if ( ok ) { - nb = index; - names.removeLast(); - } - } - names.append( QString::number( nb+1 ) ); - name = names.join( "_" ); + QStringList names = name.split("_", QString::KeepEmptyParts); + if ( names.count() > 0 ) { + bool ok; + int index = names.last().toInt( &ok ); + if ( ok ) { + nb = index; + names.removeLast(); + } + } + names.append( QString::number( nb+1 ) ); + name = names.join( "_" ); } return name; } return baseName; } + + QString UniqueName(const QString& theBaseName, _PTR(SObject) theParent, const QString& thePostfix) + { + QString baseName = thePostfix.isEmpty() ? + theBaseName : theBaseName + "_" + thePostfix; + QString name = baseName; + if ( _PTR(Study) aStudy = GetActiveStudyDocument() ) { + _PTR(SObject) p = theParent; + if ( !p ) p = aStudy->FindComponent( "SMESH" ); + if ( p ) { + _PTR(ChildIterator) iter = aStudy->NewChildIterator( p ); + int idx = 0; + while( true ) { + bool found = false; + for ( ; iter->More(); iter->Next() ) { + _PTR(SObject) so = iter->Value(); + if ( !so ) continue; // skip bad objects + _PTR(SObject) ref; + if ( so->ReferencedObject( ref ) ) continue; // skip references + QString n = so->GetName().c_str(); + if ( !n.isEmpty() && n == name ) { + QStringList names = name.split("_", QString::KeepEmptyParts); + if ( names.count() > 0 ) { + bool ok; + names.last().toInt( &ok ); + if ( ok ) + names.removeLast(); + } + names.append( QString::number( ++idx ) ); + name = names.join( "_" ); + found = true; + break; + } + } + if ( !found ) break; + } + } + } + return name; + } + + SMESH::Measurements_var& GetMeasurements() + { + static SMESH::Measurements_var aMeasurements; + if (CORBA::is_nil(aMeasurements)) { + aMeasurements = SMESHGUI::GetSMESHGen()->CreateMeasurements(); + } + return aMeasurements; + } } // end of namespace SMESH diff --git a/src/SMESHGUI/SMESHGUI_MeshUtils.h b/src/SMESHGUI/SMESHGUI_MeshUtils.h index 0544d4306..1adbabccc 100644 --- a/src/SMESHGUI/SMESHGUI_MeshUtils.h +++ b/src/SMESHGUI/SMESHGUI_MeshUtils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_MeshUtils.h // Author : Open CASCADE S.A.S. @@ -35,9 +36,15 @@ // SALOME GUI includes #include +// SALOME KERNEL includes +#include + // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Measurements) + +class SALOMEDSClient_SObject; namespace SMESH { @@ -46,6 +53,10 @@ namespace SMESH SMESHGUI_EXPORT QString UniqueMeshName( const QString&, const QString& = QString() ); + SMESHGUI_EXPORT + QString UniqueName( const QString&, _PTR(SObject) = _PTR(SObject)(), const QString& = QString() ); + + SMESHGUI_EXPORT SMESH::Measurements_var& GetMeasurements(); } #endif // SMESHGUI_MESHUTILS_H diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx deleted file mode 100644 index 199575293..000000000 --- a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx +++ /dev/null @@ -1,660 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_MoveNodesDlg.cxx -// Author : Nicolas REJNERI, Open CASCADE S.A.S. -// SMESH includes -// -#include "SMESHGUI_MoveNodesDlg.h" - -#include "SMESHGUI.h" -#include "SMESHGUI_SpinBox.h" -#include "SMESHGUI_IdValidator.h" -#include "SMESHGUI_Utils.h" -#include "SMESHGUI_VTKUtils.h" -#include "SMESHGUI_MeshUtils.h" - -#include -#include - -// SALOME GUI includes -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -// OCCT includes -#include - -// VTK includes -#include -#include -#include -#include -#include -#include - -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Mesh) -#include CORBA_SERVER_HEADER(SMESH_MeshEditor) - -#define SPACING 6 -#define MARGIN 11 - -//================================================================================= -// name : SMESHGUI_MoveNodesDlg::SMESHGUI_MoveNodesDlg -// Purpose : -//================================================================================= -SMESHGUI_MoveNodesDlg::SMESHGUI_MoveNodesDlg(SMESHGUI* theModule): - QDialog(SMESH::GetDesktop(theModule)), - mySelectionMgr(SMESH::GetSelectionMgr(theModule)), - mySMESHGUI(theModule) -{ - myPreviewActor = 0; - myBusy = false; - - setModal(false); - setWindowTitle(tr("CAPTION")); - - QVBoxLayout* aDlgLay = new QVBoxLayout(this); - aDlgLay->setSpacing(SPACING); - aDlgLay->setMargin(MARGIN); - - QWidget* aMainFrame = createMainFrame (this); - QWidget* aBtnFrame = createButtonFrame(this); - - aDlgLay->addWidget(aMainFrame); - aDlgLay->addWidget(aBtnFrame); - - mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); - - myHelpFileName = "moving_nodes_page.html"; - - Init(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::createButtonFrame -// Purpose : Create frame containing buttons -//======================================================================= -QWidget* SMESHGUI_MoveNodesDlg::createButtonFrame (QWidget* theParent) -{ - QFrame* aFrame = new QFrame(theParent); - aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken); - - myOkBtn = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aFrame); - myApplyBtn = new QPushButton(tr("SMESH_BUT_APPLY"), aFrame); - myCloseBtn = new QPushButton(tr("SMESH_BUT_CLOSE"), aFrame); - myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP"), aFrame); - - QHBoxLayout* aLay = new QHBoxLayout(aFrame); - aLay->setSpacing(SPACING); - aLay->setMargin(MARGIN); - - aLay->addWidget(myOkBtn); - aLay->addSpacing(10); - aLay->addWidget(myApplyBtn); - aLay->addSpacing(10); - aLay->addStretch(); - aLay->addWidget(myCloseBtn); - aLay->addWidget(myHelpBtn); - - connect(myOkBtn, SIGNAL(clicked()), SLOT(onOk())); - connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose())); - connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply())); - connect(myHelpBtn, SIGNAL(clicked()), SLOT(onHelp())); - - return aFrame; -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::createMainFrame -// Purpose : Create frame containing dialog's input fields -//======================================================================= -QWidget* SMESHGUI_MoveNodesDlg::createMainFrame (QWidget* theParent) -{ - QWidget* aFrame = new QWidget(theParent); - - QPixmap iconMoveNode (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MOVE_NODE"))); - QPixmap iconSelect (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); - - //------------------------------------------------------------ - QGroupBox* aPixGrp = new QGroupBox(tr("MESH_NODE"), aFrame); - QButtonGroup* aBtnGrp = new QButtonGroup(this); - QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp); - aPixGrpLayout->setSpacing(SPACING); - aPixGrpLayout->setMargin(MARGIN); - - QRadioButton* aRBut = new QRadioButton(aPixGrp); - aRBut->setIcon(iconMoveNode); - aRBut->setChecked(true); - - aPixGrpLayout->addWidget(aRBut); - aBtnGrp->addButton(aRBut, 0); - - //------------------------------------------------------------ - QGroupBox* anIdGrp = new QGroupBox(tr("SMESH_MOVE"), aFrame); - QHBoxLayout* anIdGrpLayout = new QHBoxLayout(anIdGrp); - anIdGrpLayout->setSpacing(SPACING); - anIdGrpLayout->setMargin(MARGIN); - - QLabel* idLabl = new QLabel(tr("NODE_ID"), anIdGrp); - QPushButton* idBtn = new QPushButton(anIdGrp); - idBtn->setIcon(iconSelect); - myId = new QLineEdit(anIdGrp); - myId->setValidator(new SMESHGUI_IdValidator(this, 1)); - - anIdGrpLayout->addWidget(idLabl); - anIdGrpLayout->addWidget(idBtn); - anIdGrpLayout->addWidget(myId); - - //------------------------------------------------------------ - QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame); - QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp); - aCoordGrpLayout->setSpacing(SPACING); - aCoordGrpLayout->setMargin(MARGIN); - - QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp); - myX = new SMESHGUI_SpinBox(aCoordGrp); - - QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp); - myY = new SMESHGUI_SpinBox(aCoordGrp); - - QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp); - myZ = new SMESHGUI_SpinBox(aCoordGrp); - - aCoordGrpLayout->addWidget(aXLabel); - aCoordGrpLayout->addWidget(myX); - aCoordGrpLayout->addWidget(aYLabel); - aCoordGrpLayout->addWidget(myY); - aCoordGrpLayout->addWidget(aZLabel); - aCoordGrpLayout->addWidget(myZ); - - //------------------------------------------------------------ - myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY); - myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY); - myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY); - - //------------------------------------------------------------ - QVBoxLayout* aLay = new QVBoxLayout(aFrame); - aLay->setMargin(0); - aLay->setMargin(SPACING); - aLay->addWidget(aPixGrp); - aLay->addWidget(anIdGrp); - aLay->addWidget(aCoordGrp); - - //------------------------------------------------------------ - // connect signale and slots - connect(myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - connect(myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - connect(myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); - connect(myId, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); - - return aFrame; -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg -// Purpose : -//======================================================================= -SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg() -{ - erasePreview(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::Init -// Purpose : Init dialog fields -//======================================================================= -void SMESHGUI_MoveNodesDlg::Init() -{ - myPreviewActor = 0; - myMeshActor = 0; - myBusy = false; - - mySMESHGUI->SetActiveDialogBox((QDialog*)this); - - // selection and SMESHGUI - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone())); - connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate())); - connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose())); - - reset(); - setEnabled(true); - - // set selection mode - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - - onSelectionDone(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::isValid -// Purpose : Verify validity of entry information -//======================================================================= -bool SMESHGUI_MoveNodesDlg::isValid (const bool theMess) -{ - if (myId->text().isEmpty()) { - if (theMess) - SUIT_MessageBox::information(this, tr("SMESH_WARNING"), - tr("NODE_ID_IS_NOT_DEFINED")); - return false; - } - - QString msg; - bool ok = true; - ok = myX->isValid( msg, theMess ) && ok; - ok = myY->isValid( msg, theMess ) && ok; - ok = myZ->isValid( msg, theMess ) && ok; - if( !ok ) { - if( theMess ) { - QString str( tr( "SMESH_INCORRECT_INPUT" ) ); - if ( !msg.isEmpty() ) - str += "\n" + msg; - SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str ); - } - return false; - } - - return true; -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::reset -// Purpose : Reset the dialog state -//======================================================================= -void SMESHGUI_MoveNodesDlg::reset() -{ - myId->clear(); - myX->SetValue(0); - myY->SetValue(0); - myZ->SetValue(0); - redisplayPreview(); - updateButtons(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::onApply -// Purpose : SLOT called when "Apply" button pressed. -//======================================================================= -bool SMESHGUI_MoveNodesDlg::onApply() -{ - if (mySMESHGUI->isActiveStudyLocked()) - return false; - - if (!isValid(true)) - return false; - - SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO()); - if (aMesh->_is_nil()) { - SUIT_MessageBox::information(this, tr("SMESH_ERROR"), - tr("SMESHG_NO_MESH")); - return false; - } - - SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); - if (aMeshEditor->_is_nil()) - return false; - - int anId = myId->text().toInt(); - bool aResult = false; - try { - aResult = aMeshEditor->MoveNode(anId, myX->GetValue(), myY->GetValue(), myZ->GetValue()); - - QStringList aParameters; - aParameters << myX->text(); - aParameters << myY->text(); - aParameters << myZ->text(); - aMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); - } catch (...) { - } - - if (aResult) { - SALOME_ListIO aList; - aList.Append(myMeshActor->getIO()); - mySelectionMgr->setSelectedObjects(aList,false); - SMESH::UpdateView(); - reset(); - } - - return aResult; -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::onOk -// Purpose : SLOT called when "Ok" button pressed. -//======================================================================= -void SMESHGUI_MoveNodesDlg::onOk() -{ - if (onApply()) - onClose(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::onClose -// Purpose : SLOT called when "Close" button pressed. Close dialog -//======================================================================= -void SMESHGUI_MoveNodesDlg::onClose() -{ - //mySelectionMgr->clearSelected(); - SMESH::SetPointRepresentation(false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - disconnect(mySelectionMgr, 0, this, 0); - disconnect(mySMESHGUI, 0, this, 0); - erasePreview(); - mySMESHGUI->ResetState(); - reject(); -} - -//================================================================================= -// function : onHelp() -// purpose : -//================================================================================= -void SMESHGUI_MoveNodesDlg::onHelp() -{ - LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) - app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); - else { - QString platform; -#ifdef WIN32 - platform = "winapplication"; -#else - platform = "application"; -#endif - SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); - } -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::onTextChange -// Purpose : -//======================================================================= -void SMESHGUI_MoveNodesDlg::onTextChange (const QString& theNewText) -{ - if (myBusy) return; - - myOkBtn->setEnabled(false); - myApplyBtn->setEnabled(false); - erasePreview(); - - // select entered node - if(myMeshActor){ - if(SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()){ - myBusy = true; - Handle(SALOME_InteractiveObject) anIO = myMeshActor->getIO(); - SALOME_ListIO aList; - aList.Append(anIO); - mySelectionMgr->setSelectedObjects(aList,false); - myBusy = false; - - if(const SMDS_MeshElement *anElem = aMesh->FindElement(theNewText.toInt())) { - TColStd_MapOfInteger aListInd; - aListInd.Add(anElem->GetID()); - mySelector->AddOrRemoveIndex(anIO,aListInd, false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight(anIO,true,true); - - onSelectionDone(); - } - } - } -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::onSelectionDone -// Purpose : SLOT called when selection changed -//======================================================================= -void SMESHGUI_MoveNodesDlg::onSelectionDone() -{ - if (myBusy) return; - myMeshActor = 0; - - SALOME_ListIO aList; - mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); - - if (aList.Extent() == 1) { - Handle(SALOME_InteractiveObject) anIO = aList.First(); - myMeshActor = SMESH::FindActorByEntry(anIO->getEntry()); - if(myMeshActor){ - QString aText; - if (SMESH::GetNameOfSelectedNodes(mySelector,anIO,aText) == 1) { - if(SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()) { - if(const SMDS_MeshNode* aNode = aMesh->FindNode(aText.toInt())) { - myBusy = true; - myId->setText(aText); - myX->SetValue(aNode->X()); - myY->SetValue(aNode->Y()); - myZ->SetValue(aNode->Z()); - myBusy = false; - erasePreview(); // avoid overlapping of a selection and a preview - updateButtons(); - return; - } - } - } - } - } - - reset(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::onDeactivate -// Purpose : SLOT called when dialog must be deativated -//======================================================================= -void SMESHGUI_MoveNodesDlg::onDeactivate() -{ - setEnabled(false); - erasePreview(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::enterEvent -// Purpose : Event filter -//======================================================================= -void SMESHGUI_MoveNodesDlg::enterEvent (QEvent*) -{ - if (!isEnabled()) { - mySMESHGUI->EmitSignalDeactivateDialog(); - - // set selection mode - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - - redisplayPreview(); - - setEnabled(true); - } -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::closeEvent -// Purpose : -//======================================================================= -void SMESHGUI_MoveNodesDlg::closeEvent (QCloseEvent*) -{ - onClose(); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->Repaint(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::hideEvent -// Purpose : may be caused by ESC key -//======================================================================= -void SMESHGUI_MoveNodesDlg::hideEvent (QHideEvent*) -{ - if (!isMinimized()) - onClose(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::updateButtons -// Purpose : Update buttons state -//======================================================================= -void SMESHGUI_MoveNodesDlg::updateButtons() -{ - bool isEnabled = isValid(false); - myOkBtn->setEnabled(isEnabled); - myApplyBtn->setEnabled(isEnabled); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::erasePreview -// Purpose : Erase preview -//======================================================================= -void SMESHGUI_MoveNodesDlg::erasePreview() -{ - if (myPreviewActor == 0) - return; - - SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ); - if (aViewWindow) - aViewWindow->RemoveActor(myPreviewActor); - myPreviewActor->Delete(); - myPreviewActor = 0; - if (aViewWindow) - aViewWindow->Repaint(); -} - -//======================================================================= -// name : SMESHGUI_MoveNodesDlg::redisplayPreview -// Purpose : Redisplay preview -//======================================================================= -void SMESHGUI_MoveNodesDlg::redisplayPreview() -{ - if (myBusy) - return; - - if (myPreviewActor != 0) - erasePreview(); - - if (!isValid(false)) - return; - - vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New(); - - vtkPoints* aPoints = vtkPoints::New(); - aPoints->SetNumberOfPoints(1); - aPoints->SetPoint(0, myX->GetValue(), myY->GetValue(), myZ->GetValue()); - - // Create cells - - vtkIdList *anIdList = vtkIdList::New(); - anIdList->SetNumberOfIds(1); - - vtkCellArray *aCells = vtkCellArray::New(); - aCells->Allocate(2, 0); - - vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); - aCellTypesArray->SetNumberOfComponents(1); - aCellTypesArray->Allocate(1); - - anIdList->SetId(0, 0); - aCells->InsertNextCell(anIdList); - aCellTypesArray->InsertNextValue(VTK_VERTEX); - anIdList->Delete(); - - VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New(); - aCellLocationsArray->SetNumberOfComponents(1); - aCellLocationsArray->SetNumberOfTuples(1); - - aCells->InitTraversal(); - vtkIdType npts; - aCellLocationsArray->SetValue(0, aCells->GetTraversalLocation(npts)); - - aGrid->SetPoints(aPoints); - aPoints->Delete(); - - aGrid->SetCells(aCellTypesArray,aCellLocationsArray,aCells); - aCellLocationsArray->Delete(); - aCellTypesArray->Delete(); - aCells->Delete(); - - // Create and display actor - vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); - aMapper->SetInput(aGrid); - aGrid->Delete(); - - myPreviewActor = SALOME_Actor::New(); - myPreviewActor->PickableOff(); - myPreviewActor->SetMapper(aMapper); - aMapper->Delete(); - - vtkProperty* aProp = vtkProperty::New(); - aProp->SetRepresentationToWireframe(); - aProp->SetColor(250, 0, 250); - aProp->SetPointSize(5); - myPreviewActor->SetProperty(aProp); - aProp->Delete(); - - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - { - aViewWindow->AddActor(myPreviewActor); - aViewWindow->Repaint(); - } -} - -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void SMESHGUI_MoveNodesDlg::keyPressEvent( QKeyEvent* e ) -{ - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; - - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - onHelp(); - } -} diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.h b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.h deleted file mode 100644 index cfd43786f..000000000 --- a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_MoveNodesDlg.h -// Author : Nicolas REJNERI, Open CASCADE S.A.S. -// -#ifndef SMESHGUI_MOVENODESDLG_H -#define SMESHGUI_MOVENODESDLG_H - -// SMESH includes -#include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include - -class QLineEdit; -class QPushButton; - -class SMESHGUI; -class SMESH_Actor; -class SMESHGUI_SpinBox; -class SALOME_Actor; -class SVTK_Selector; -class LightApp_SelectionMgr; - -//================================================================================= -// class : SMESHGUI_MoveNodesDlg -// purpose : -//================================================================================= -class SMESHGUI_EXPORT SMESHGUI_MoveNodesDlg : public QDialog -{ - Q_OBJECT - -public: - SMESHGUI_MoveNodesDlg( SMESHGUI* ); - virtual ~SMESHGUI_MoveNodesDlg(); - - void Init(); - -private slots: - void onOk(); - bool onApply(); - void onClose(); - void onHelp(); - - void onDeactivate(); - - void onSelectionDone(); - void redisplayPreview(); - void onTextChange( const QString& ); - -private: - void closeEvent( QCloseEvent* ); - void enterEvent( QEvent* ); - void hideEvent( QHideEvent* ); - void keyPressEvent( QKeyEvent* ); - void erasePreview(); - QWidget* createButtonFrame( QWidget* ); - QWidget* createMainFrame ( QWidget* ); - bool isValid( const bool ); - void reset(); - void updateButtons(); - -private: - QPushButton* myOkBtn; - QPushButton* myApplyBtn; - QPushButton* myCloseBtn; - QPushButton* myHelpBtn; - - QLineEdit* myId; - SMESHGUI_SpinBox* myX; - SMESHGUI_SpinBox* myY; - SMESHGUI_SpinBox* myZ; - - LightApp_SelectionMgr* mySelectionMgr; - SVTK_Selector* mySelector; - SMESHGUI* mySMESHGUI; - - SALOME_Actor* myPreviewActor; - SMESH_Actor* myMeshActor; - bool myBusy; - - QString myHelpFileName; -}; - -#endif // SMESHGUI_MOVENODESDLG_H diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index 526c3f3e3..a12ca8fbe 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_MultiEditDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. // SMESH includes -// + #include "SMESHGUI_MultiEditDlg.h" #include "SMESHGUI.h" @@ -39,15 +40,17 @@ #include // SALOME GUI includes -#include #include -#include #include +#include +#include +#include #include #include #include #include +#include #include #include @@ -100,8 +103,8 @@ //======================================================================= SMESHGUI_MultiEditDlg ::SMESHGUI_MultiEditDlg(SMESHGUI* theModule, - const int theMode, - const bool the3d2d): + const int theMode, + const bool the3d2d): QDialog(SMESH::GetDesktop(theModule)), mySelector(SMESH::GetViewWindow(theModule)->GetSelector()), mySelectionMgr(SMESH::GetSelectionMgr(theModule)), @@ -192,7 +195,7 @@ QWidget* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp); mySelGrpLayout->addWidget(myToAllChk, mySelGrpLayout->rowCount(), 0, - 1, mySelGrpLayout->columnCount()); + 1, mySelGrpLayout->columnCount()); // Split/Join criterion group myCriterionGrp = new QGroupBox(tr("SPLIT_JOIN_CRITERION"), aMainGrp); @@ -301,7 +304,7 @@ QWidget* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent) bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) { return (!myMesh->_is_nil() && - (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor))); + (myListBox->count() > 0 || (myToAllChk->isChecked()/* && myActor*/))); } //======================================================================= @@ -423,63 +426,65 @@ void SMESHGUI_MultiEditDlg::onOk() //======================================================================= // name : SMESHGUI_MultiEditDlg::getIds -// Purpose : Retrive identifiers from list box +// Purpose : Retrive identifiers from list box or the whole object //======================================================================= -SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds() + +SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds(SMESH::SMESH_IDSource_var& obj) { SMESH::long_array_var anIds = new SMESH::long_array; if (myToAllChk->isChecked()) { myIds.Clear(); - SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh); - if (!anActor) - anActor = myActor; - if (anActor != 0) - { - // skl 07.02.2006 - SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); - if( myFilterType == SMESH::TriaFilter || - myFilterType == SMESH::QuadFilter || - myFilterType == SMESH::FaceFilter ) { - SMDS_FaceIteratorPtr it = aMesh->facesIterator(); - while(it->more()) { - const SMDS_MeshFace* f = it->next(); - if(myFilterType == SMESH::FaceFilter) { - myIds.Add(f->GetID()); - } - else if( myFilterType==SMESH::TriaFilter && - ( f->NbNodes()==3 || f->NbNodes()==6 ) ) { - myIds.Add(f->GetID()); - } - else if( myFilterType==SMESH::QuadFilter && - ( f->NbNodes()==4 || f->NbNodes()==8 ) ) { - myIds.Add(f->GetID()); - } - } - } - else if(myFilterType == SMESH::VolumeFilter) { - SMDS_VolumeIteratorPtr it = aMesh->volumesIterator(); - while(it->more()) { - const SMDS_MeshVolume* f = it->next(); - myIds.Add(f->GetID()); - } - } - /* commented by skl 07.02.2006 + obj = SMESH::SMESH_IDSource::_narrow( myMesh ); +// SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh); +// if (!anActor) +// anActor = myActor; +// if (anActor != 0) +// { +// // skl 07.02.2006 +// SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); +// if( myFilterType == SMESH::TriaFilter || +// myFilterType == SMESH::QuadFilter || +// myFilterType == SMESH::FaceFilter ) { +// SMDS_FaceIteratorPtr it = aMesh->facesIterator(); +// while(it->more()) { +// const SMDS_MeshFace* f = it->next(); +// if(myFilterType == SMESH::FaceFilter) { +// myIds.Add(f->GetID()); +// } +// else if( myFilterType==SMESH::TriaFilter && +// ( f->NbNodes()==3 || f->NbNodes()==6 ) ) { +// myIds.Add(f->GetID()); +// } +// else if( myFilterType==SMESH::QuadFilter && +// ( f->NbNodes()==4 || f->NbNodes()==8 ) ) { +// myIds.Add(f->GetID()); +// } +// } +// } +// else if(myFilterType == SMESH::VolumeFilter) { +// SMDS_VolumeIteratorPtr it = aMesh->volumesIterator(); +// while(it->more()) { +// const SMDS_MeshVolume* f = it->next(); +// myIds.Add(f->GetID()); +// } +// } + /* commented by skl 07.02.2006 - to work with quadratic elements TVisualObjPtr aVisualObj = anActor->GetObject(); vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid(); if (aGrid != 0) { for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) { vtkCell* aCell = aGrid->GetCell(i); if (aCell != 0) { - vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell); - vtkQuad* aQua = vtkQuad::SafeDownCast(aCell); - vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell); + vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell); + vtkQuad* aQua = vtkQuad::SafeDownCast(aCell); + vtkPolygon* aPG = vtkPolygon::SafeDownCast(aCell); - vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell); - vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell); + vtkCell3D* a3d = vtkCell3D::SafeDownCast(aCell); + vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell); - if (aTri && myFilterType == SMESHGUI_TriaFilter || + if (aTri && myFilterType == SMESHGUI_TriaFilter || aQua && myFilterType == SMESHGUI_QuadFilter || (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter || (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) { @@ -490,7 +495,7 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds() } } */ - } + //} } anIds->length(myIds.Extent()); @@ -540,10 +545,10 @@ void SMESHGUI_MultiEditDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -594,10 +599,10 @@ void SMESHGUI_MultiEditDlg::onSelectionDone() if (aNbItems > 0) { QStringList anElements = aListStr.split(" ", QString::SkipEmptyParts); for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) { - QList items = myListBox->findItems(*it, Qt::MatchExactly); - QListWidgetItem* anItem; - foreach(anItem, items) - anItem->setSelected(true); + QList items = myListBox->findItems(*it, Qt::MatchExactly); + QListWidgetItem* anItem; + foreach(anItem, items) + anItem->setSelected(true); } } myMesh = SMESH::GetMeshByIO(anIO); @@ -753,9 +758,8 @@ void SMESHGUI_MultiEditDlg::onAddBtn() for ( ; anIter.More(); anIter.Next()) { SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface(anIter.Value()); - if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE && - entityType() == 0 || aGroup->GetType() == SMESH::VOLUME && - entityType() == 1)) { + if (!aGroup->_is_nil() && ((aGroup->GetType() == SMESH::FACE && entityType() == 0) || + (aGroup->GetType() == SMESH::VOLUME && entityType() == 1))) { if (aGroup->GetMesh()->GetId() == myMesh->GetId()) { SMESH::long_array_var anIds = aGroup->GetListOfID(); for (int i = 0, n = anIds->length(); i < n; i++) { @@ -772,12 +776,13 @@ void SMESHGUI_MultiEditDlg::onAddBtn() bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked()); mySubmeshChk->setChecked(false); myGroupChk->setChecked(false); + QStringList items; for(int i = 1; i <= toBeAdded.Extent(); i++) if (myIds.Add(toBeAdded(i))) { - QListWidgetItem* item = new QListWidgetItem(QString("%1").arg(toBeAdded(i))); - myListBox->addItem(item); - item->setSelected(true); + items.append(QString("%1").arg(toBeAdded(i))); } + myListBox->addItems(items); + myListBox->selectAll(); myBusy = false; emit ListContensChanged(); @@ -1034,9 +1039,12 @@ bool SMESHGUI_MultiEditDlg::onApply() myBusy = true; - SMESH::long_array_var anIds = getIds(); + SUIT_OverrideCursor aWaitCursor; + + SMESH::SMESH_IDSource_var obj; + SMESH::long_array_var anIds = getIds(obj); - bool aResult = process(aMeshEditor, anIds.inout()); + bool aResult = process(aMeshEditor, anIds.inout(), obj); if (aResult) { if (myActor) { SALOME_ListIO sel; @@ -1044,6 +1052,7 @@ bool SMESHGUI_MultiEditDlg::onApply() mySelector->ClearIndex(); mySelectionMgr->setSelectedObjects( sel ); SMESH::UpdateView(); + SMESHGUI::Modified(); } myListBox->clear(); @@ -1124,9 +1133,13 @@ SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg() } bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor, - const SMESH::long_array& theIds) + const SMESH::long_array& theIds, + SMESH::SMESH_IDSource_ptr obj) { - return theEditor->Reorient(theIds); + if ( CORBA::is_nil( obj )) + return theEditor->Reorient(theIds); + else + return theEditor->ReorientObject( obj ); } /*! @@ -1152,7 +1165,7 @@ SMESHGUI_UnionOfTrianglesDlg QLabel* aLab = new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp); myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp); - myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3); + myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, "angle_precision"); myMaxAngleSpin->SetValue(30.0); aMaxAngleGrpLayout->addWidget(aLab); @@ -1180,7 +1193,7 @@ bool SMESHGUI_UnionOfTrianglesDlg::isValid (const bool theMess) if( theMess ) { QString str( tr( "SMESH_INCORRECT_INPUT" ) ); if ( !msg.isEmpty() ) - str += "\n" + msg; + str += "\n" + msg; SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str ); } return false; @@ -1190,16 +1203,21 @@ bool SMESHGUI_UnionOfTrianglesDlg::isValid (const bool theMess) } bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor, - const SMESH::long_array& theIds) + const SMESH::long_array& theIds, + SMESH::SMESH_IDSource_ptr obj) { - SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor(); - double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0; - bool ok = theEditor->TriToQuad(theIds, aCriterion, aMaxAngle); - if( ok ) { + { QStringList aParameters; aParameters << myMaxAngleSpin->text(); - myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); + myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); } + SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor(); + double aMaxAngle = myMaxAngleSpin->GetValue() * M_PI / 180.0; + bool ok; + if ( CORBA::is_nil( obj )) + ok = theEditor->TriToQuad(theIds, aCriterion, aMaxAngle); + else + ok = theEditor->TriToQuadObject(obj, aCriterion, aMaxAngle); return ok; } @@ -1243,19 +1261,21 @@ void SMESHGUI_CuttingOfQuadsDlg::onClose() } bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor, - const SMESH::long_array& theIds) + const SMESH::long_array& theIds, + SMESH::SMESH_IDSource_ptr obj) { + bool hasObj = (! CORBA::is_nil( obj )); switch (myGroupChoice->checkedId()) { case 0: // use diagonal 1-3 - return theEditor->SplitQuad(theIds, true); + return hasObj ? theEditor->SplitQuadObject(obj, true) : theEditor->SplitQuad(theIds, true); case 1: // use diagonal 2-4 - return theEditor->SplitQuad(theIds, false); + return hasObj ? theEditor->SplitQuadObject(obj, false) : theEditor->SplitQuad(theIds, false); default: // use numeric functor break; } - SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor(); - return theEditor->QuadToTri(theIds, aCriterion); + SMESH::NumericalFunctor_var aCrit = getNumericalFunctor(); + return hasObj ? theEditor->QuadToTriObject(obj, aCrit) : theEditor->QuadToTri(theIds, aCrit); } void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB() @@ -1295,8 +1315,9 @@ void SMESHGUI_CuttingOfQuadsDlg::displayPreview() erasePreview(); // get Ids of elements - SMESH::long_array_var anElemIds = getIds(); - if (getIds()->length() == 0) + SMESH::SMESH_IDSource_var obj; + SMESH::long_array_var anElemIds = getIds(obj); + if (anElemIds->length() == 0 && obj->_is_nil() ) return; SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); @@ -1449,3 +1470,55 @@ void SMESHGUI_CuttingOfQuadsDlg::displayPreview() aCellTypesArray->Delete(); aCellLocationsArray->Delete(); } + +/*! + * Class : SMESHGUI_CuttingIntoTetraDlg + * Description : Modification of orientation of faces + */ + +SMESHGUI_CuttingIntoTetraDlg::SMESHGUI_CuttingIntoTetraDlg(SMESHGUI* theModule) + : SMESHGUI_MultiEditDlg(theModule, SMESH::VolumeFilter, false) +{ + setWindowTitle(tr("CAPTION")); + myHelpFileName = "split_to_tetra_page.html"; + myEntityType = 1; + + myToAllChk->setChecked( true ); //aplly to the whole mesh by default + + bool hasHexa = true;//myMesh->_is_nil() ? false : myMesh->NbHexas(); + + if ( hasHexa ) + { + myGroupChoice->button(0)->setText( tr("SPLIT_HEX_TO_5_TETRA")); + myGroupChoice->button(1)->setText( tr("SPLIT_HEX_TO_6_TETRA")); + myGroupChoice->button(2)->setText( tr("SPLIT_HEX_TO_24_TETRA")); + + myCriterionGrp->setTitle( tr("SPLIT_METHOD")); + myCriterionGrp->show(); + myComboBoxFunctor->hide(); + myChoiceWidget->show(); + } + setSelectionMode(); + updateButtons(); +} + +SMESHGUI_CuttingIntoTetraDlg::~SMESHGUI_CuttingIntoTetraDlg() +{ +} + +bool SMESHGUI_CuttingIntoTetraDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor, + const SMESH::long_array& theIds, + SMESH::SMESH_IDSource_ptr theObj) +{ + SMESH::SMESH_IDSource_var obj = theObj; + if ( CORBA::is_nil( obj )) + obj = theEditor->MakeIDSource( theIds, myEntityType ? SMESH::VOLUME : SMESH::FACE ); + try { + theEditor->SplitVolumesIntoTetra( obj, myGroupChoice->checkedId()+1 ); + } + catch ( const SALOME::SALOME_Exception& S_ex ) { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + return false; + } + return true; +} diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.h b/src/SMESHGUI/SMESHGUI_MultiEditDlg.h index 0ada531f9..de9b0b67f 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.h +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_MultiEditDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. // @@ -108,12 +109,13 @@ protected: QWidget* createButtonFrame( QWidget* ); QWidget* createMainFrame( QWidget*, const bool ); virtual bool isValid( const bool ); - SMESH::long_array_var getIds(); + SMESH::long_array_var getIds(SMESH::SMESH_IDSource_var& obj); void updateButtons(); void setSelectionMode(); virtual bool isIdValid( const int ) const; virtual bool process( SMESH::SMESH_MeshEditor_ptr, - const SMESH::long_array& ) = 0; + const SMESH::long_array& , + SMESH::SMESH_IDSource_ptr obj) = 0; int entityType(); protected: @@ -174,7 +176,9 @@ public: virtual ~SMESHGUI_ChangeOrientationDlg(); protected: - virtual bool process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& ); + virtual bool process( SMESH::SMESH_MeshEditor_ptr, + const SMESH::long_array& , + SMESH::SMESH_IDSource_ptr obj); }; /*! @@ -191,7 +195,9 @@ public: protected: virtual bool isValid( const bool ); - virtual bool process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& ); + virtual bool process( SMESH::SMESH_MeshEditor_ptr, + const SMESH::long_array&, + SMESH::SMESH_IDSource_ptr obj ); private: SMESHGUI_SpinBox* myMaxAngleSpin; @@ -210,7 +216,9 @@ public: virtual ~SMESHGUI_CuttingOfQuadsDlg(); protected: - virtual bool process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& ); + virtual bool process( SMESH::SMESH_MeshEditor_ptr, + const SMESH::long_array& , + SMESH::SMESH_IDSource_ptr obj); protected slots: virtual void onClose(); @@ -226,4 +234,22 @@ private: QCheckBox* myPreviewChk; }; +/*! + * Class : SMESHGUI_CuttingIntoTetraDlg + * Description : Split all volumes into tetrahedrons + */ +class SMESHGUI_CuttingIntoTetraDlg : public SMESHGUI_MultiEditDlg +{ + Q_OBJECT + +public: + SMESHGUI_CuttingIntoTetraDlg( SMESHGUI* ); + virtual ~SMESHGUI_CuttingIntoTetraDlg(); + +protected: + virtual bool process( SMESH::SMESH_MeshEditor_ptr, + const SMESH::long_array&, + SMESH::SMESH_IDSource_ptr obj ); +}; + #endif // SMESHGUI_MULTIEDITDLG_H diff --git a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx index 38869cedd..3f369e790 100644 --- a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_NodesDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -31,6 +32,7 @@ #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_GroupUtils.h" #include #include @@ -49,7 +51,10 @@ #include #include +#include + #include +#include #include // SALOME KERNEL includes @@ -69,6 +74,7 @@ #include // Qt includes +#include #include #include #include @@ -87,18 +93,19 @@ namespace SMESH { - void AddNode( SMESH::SMESH_Mesh_ptr theMesh, float x, float y, float z, const QStringList& theParameters ) + long AddNode( SMESH::SMESH_Mesh_ptr theMesh, float x, float y, float z, const QStringList& theParameters ) { + long aNodeId = -1; SUIT_OverrideCursor wc; try { _PTR(SObject) aSobj = SMESH::FindSObject( theMesh ); SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor(); - aMeshEditor->AddNode( x, y, z ); - theMesh->SetParameters( SMESHGUI::JoinObjectParameters(theParameters) ); + theMesh->SetParameters( theParameters.join(":").toLatin1().constData() ); + aNodeId = aMeshEditor->AddNode( x, y, z ); _PTR(Study) aStudy = GetActiveStudyDocument(); CORBA::Long anId = aStudy->StudyId(); if (TVisualObjPtr aVisualObj = SMESH::GetVisualObj( anId, aSobj->GetID().c_str() ) ) { - aVisualObj->Update( true ); + aVisualObj->Update( true ); } } catch ( SALOME::SALOME_Exception& exc ) { @@ -110,6 +117,7 @@ namespace SMESH catch ( ... ) { INFOS( "Unknown exception was cought !!!" ); } + return aNodeId; } class TNodeSimulation @@ -234,7 +242,7 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( SMESHGUI* theModule ): mySimulation = new SMESH::TNodeSimulation( SMESH::GetViewWindow( mySMESHGUI ) ); QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", - tr( "ICON_DLG_NODE" ) ) ); + tr( "ICON_DLG_NODE" ) ) ); QVBoxLayout* SMESHGUI_NodesDlgLayout = new QVBoxLayout( this ); SMESHGUI_NodesDlgLayout->setSpacing( SPACING ); @@ -270,11 +278,29 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( SMESHGUI* theModule ): SpinBox_Z = new SMESHGUI_SpinBox( GroupCoordinates ); GroupCoordinatesLayout->addWidget( TextLabel_X ); - GroupCoordinatesLayout->addWidget( SpinBox_X ); + GroupCoordinatesLayout->addWidget( SpinBox_X ); GroupCoordinatesLayout->addWidget( TextLabel_Y); GroupCoordinatesLayout->addWidget( SpinBox_Y ); GroupCoordinatesLayout->addWidget( TextLabel_Z ); GroupCoordinatesLayout->addWidget( SpinBox_Z ); + GroupCoordinatesLayout->setStretch(1, 1); + GroupCoordinatesLayout->setStretch(3, 1); + GroupCoordinatesLayout->setStretch(5, 1); + + /***************************************************************/ + GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this ); + GroupGroups->setCheckable( true ); + QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups); + GroupGroupsLayout->setSpacing(SPACING); + GroupGroupsLayout->setMargin(MARGIN); + + TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups ); + ComboBox_GroupName = new QComboBox( GroupGroups ); + ComboBox_GroupName->setEditable( true ); + ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert ); + + GroupGroupsLayout->addWidget( TextLabel_GroupName ); + GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 ); /***************************************************************/ GroupButtons = new QGroupBox( this ); @@ -302,6 +328,7 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( SMESHGUI* theModule ): /***************************************************************/ SMESHGUI_NodesDlgLayout->addWidget( GroupConstructors ); SMESHGUI_NodesDlgLayout->addWidget( GroupCoordinates ); + SMESHGUI_NodesDlgLayout->addWidget( GroupGroups ); SMESHGUI_NodesDlgLayout->addWidget( GroupButtons ); myHelpFileName = "adding_nodes_and_elements_page.html#adding_nodes_anchor"; @@ -329,13 +356,16 @@ void SMESHGUI_NodesDlg::Init() double step = 25.0; /* min, max, step and decimals for spin boxes */ - SpinBox_X->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY ); - SpinBox_Y->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY ); - SpinBox_Z->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY ); + SpinBox_X->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, "length_precision" ); + SpinBox_Y->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, "length_precision" ); + SpinBox_Z->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, "length_precision" ); SpinBox_X->SetValue( 0.0 ); SpinBox_Y->SetValue( 0.0 ); SpinBox_Z->SetValue( 0.0 ); + /* reset "Add to group" control */ + GroupGroups->setChecked( false ); + mySMESHGUI->SetActiveDialogBox( this ); /* signals and slots connections */ @@ -352,6 +382,7 @@ void SMESHGUI_NodesDlg::Init() connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() ) ); /* to close dialog if study frame change */ connect( mySMESHGUI, SIGNAL( SignalStudyFrameChanged() ), SLOT( ClickOnCancel() ) ); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(ClickOnCancel())); // set selection mode SMESH::SetPointRepresentation( true ); @@ -397,7 +428,7 @@ bool SMESHGUI_NodesDlg::ClickOnApply() if ( myMesh->_is_nil() ) { SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), - tr( "MESH_IS_NOT_SELECTED" ) ); + tr( "MESH_IS_NOT_SELECTED" ) ); return false; } @@ -414,16 +445,74 @@ bool SMESHGUI_NodesDlg::ClickOnApply() aParameters << SpinBox_Y->text(); aParameters << SpinBox_Z->text(); + bool addToGroup = GroupGroups->isChecked(); + QString aGroupName; + + SMESH::SMESH_GroupBase_var aGroup; + int idx = 0; + if( addToGroup ) { + aGroupName = ComboBox_GroupName->currentText(); + for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { + QString aName = ComboBox_GroupName->itemText( i ); + if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) + idx = i; + } + if ( idx > 0 && idx < myGroups.count() ) { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); + if ( !aGeomGroup->_is_nil() ) { + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return false; + } + aGroup = myGroups[idx-1]; + } + } + mySimulation->SetVisibility( false ); - SMESH::AddNode( myMesh, x, y, z, aParameters ); + + long aNodeId = SMESH::AddNode( myMesh, x, y, z, aParameters ); + SMESH::SetPointRepresentation( true ); + if ( aNodeId != -1 && addToGroup && !aGroupName.isEmpty() ) { + SMESH::SMESH_Group_var aGroupUsed; + if ( aGroup->_is_nil() ){ + // create new group + aGroupUsed = SMESH::AddGroup( myMesh, SMESH::NODE, aGroupName ); + if ( !aGroupUsed->_is_nil() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + else { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); + if ( !aGeomGroup->_is_nil() ) { + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } + } + else + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + } + + if ( !aGroupUsed->_is_nil() ) { + SMESH::long_array_var anIdList = new SMESH::long_array; + anIdList->length( 1 ); + anIdList[0] = aNodeId; + aGroupUsed->Add( anIdList.inout() ); + } + } + // select myMesh SALOME_ListIO aList; mySelectionMgr->selectedObjects( aList ); if ( aList.Extent() != 1 ) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() ) { - vtkActorCollection *aCollection = aViewWindow->getRenderer()->GetActors(); + VTK::ActorCollectionCopy aCopy(aViewWindow->getRenderer()->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); aCollection->InitTraversal(); while ( vtkActor *anAct = aCollection->GetNextActor() ) { if ( SMESH_Actor *anActor = dynamic_cast( anAct ) ) { @@ -441,6 +530,11 @@ bool SMESHGUI_NodesDlg::ClickOnApply() } } } + + SMESHGUI::Modified(); + SMESH::UpdateView(); + mySimulation->SetVisibility(false); + return true; } @@ -470,7 +564,7 @@ void SMESHGUI_NodesDlg::ClickOnHelp() LightApp_Application* app = (LightApp_Application*)( SUIT_Session::session()->activeApplication() ); if ( app ) app->onHelpContextModule( mySMESHGUI ? app->moduleName( mySMESHGUI->moduleName() ) : - QString( "" ), myHelpFileName ); + QString( "" ), myHelpFileName ); else { QString platform; #ifdef WIN32 @@ -479,10 +573,10 @@ void SMESHGUI_NodesDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning( this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg( app->resourceMgr()->stringValue( "ExternalBrowser", - platform ) ). - arg( myHelpFileName ) ); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg( app->resourceMgr()->stringValue( "ExternalBrowser", + platform ) ). + arg( myHelpFileName ) ); } } @@ -498,27 +592,48 @@ void SMESHGUI_NodesDlg::SelectionIntoArgument() mySimulation->SetVisibility( false ); SMESH::SetPointRepresentation( true ); + QString aCurrentEntry = myEntry; + const SALOME_ListIO& aList = mySelector->StoredIObjects(); if ( aList.Extent() == 1 ) { Handle(SALOME_InteractiveObject) anIO = aList.First(); if ( anIO->hasEntry() ) { + myEntry = anIO->getEntry(); myMesh = SMESH::GetMeshByIO( anIO ); if ( myMesh->_is_nil() ) return; QString aText; if ( SMESH::GetNameOfSelectedNodes( mySelector, anIO, aText ) == 1 ) { - if ( SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh.in() ) ) { - if ( SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh() ) { - if ( const SMDS_MeshNode* aNode = aMesh->FindNode( aText.toInt() ) ) { - SpinBox_X->SetValue( aNode->X() ); - SpinBox_Y->SetValue( aNode->Y() ); - SpinBox_Z->SetValue( aNode->Z() ); + if ( SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh.in() ) ) { + if ( SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh() ) { + if ( const SMDS_MeshNode* aNode = aMesh->FindNode( aText.toInt() ) ) { + SpinBox_X->SetValue( aNode->X() ); + SpinBox_Y->SetValue( aNode->Y() ); + SpinBox_Z->SetValue( aNode->Z() ); } - } - } + } + } } mySimulation->SetPosition( SpinBox_X->GetValue(), - SpinBox_Y->GetValue(), - SpinBox_Z->GetValue() ); + SpinBox_Y->GetValue(), + SpinBox_Z->GetValue() ); + } + } + + // process groups + if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) { + myGroups.clear(); + ComboBox_GroupName->clear(); + ComboBox_GroupName->addItem( QString() ); + SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups(); + for( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; + if ( !aGroup->_is_nil() && aGroup->GetType() == SMESH::NODE ) { + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); + } + } } } } @@ -621,5 +736,10 @@ bool SMESHGUI_NodesDlg::isValid() SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str ); return false; } + + if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) { + SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) ); + return false; + } return true; } diff --git a/src/SMESHGUI/SMESHGUI_NodesDlg.h b/src/SMESHGUI/SMESHGUI_NodesDlg.h index 8fc28eacc..de2058f5a 100644 --- a/src/SMESHGUI/SMESHGUI_NodesDlg.h +++ b/src/SMESHGUI/SMESHGUI_NodesDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_NodesDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -36,6 +37,7 @@ #include #include CORBA_SERVER_HEADER(SMESH_Mesh) +class QComboBox; class QGroupBox; class QLabel; class QPushButton; @@ -64,12 +66,16 @@ public: ~SMESHGUI_NodesDlg(); private: + typedef QList GrpList; + LightApp_SelectionMgr* mySelectionMgr; SVTK_Selector* mySelector; SMESHGUI* mySMESHGUI; SMESH::SMESH_Mesh_var myMesh; SMESH::TNodeSimulation* mySimulation; + QString myEntry; + GrpList myGroups; void Init(); void enterEvent( QEvent* ); @@ -78,7 +84,7 @@ private: void keyPressEvent( QKeyEvent* ); bool isValid(); - + QGroupBox* GroupConstructors; QRadioButton* Constructor1; QGroupBox* GroupCoordinates; @@ -90,6 +96,10 @@ private: QLabel* TextLabel_Y; QLabel* TextLabel_Z; + QGroupBox* GroupGroups; + QLabel* TextLabel_GroupName; + QComboBox* ComboBox_GroupName; + QGroupBox* GroupButtons; QPushButton* buttonApply; QPushButton* buttonOk; diff --git a/src/SMESHGUI/SMESHGUI_Operation.cxx b/src/SMESHGUI/SMESHGUI_Operation.cxx index 40bb88e65..5646c7202 100755 --- a/src/SMESHGUI/SMESHGUI_Operation.cxx +++ b/src/SMESHGUI/SMESHGUI_Operation.cxx @@ -1,29 +1,27 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMDS : implementaion of Salome mesh data structure -// File : SMESHGUI_Operation.cxx -// Author : Sergey LITONIN, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI_Operation.cxx +// Author : Sergey LITONIN, Open CASCADE S.A.S. + #include "SMESHGUI_Operation.h" #include "SMESHGUI.h" @@ -51,7 +49,8 @@ // Purpose : Constructor //======================================================================= SMESHGUI_Operation::SMESHGUI_Operation() -: LightApp_Operation() +: LightApp_Operation(), + myIsApplyAndClose( false ) { myHelpFileName = ""; } @@ -86,19 +85,19 @@ void SMESHGUI_Operation::startOperation() disconnect( dlg(), SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) ); disconnect( dlg(), SIGNAL( dlgClose() ), this, SLOT( onCancel() ) ); disconnect( dlg(), SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) ); - + if( dlg()->testButtonFlags( QtxDialog::OK ) ) connect( dlg(), SIGNAL( dlgOk() ), this, SLOT( onOk() ) ); - + if( dlg()->testButtonFlags( QtxDialog::Apply ) ) connect( dlg(), SIGNAL( dlgApply() ), this, SLOT( onApply() ) ); - + if( dlg()->testButtonFlags( QtxDialog::Cancel ) ) connect( dlg(), SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) ); if( dlg()->testButtonFlags( QtxDialog::Help ) ) connect( dlg(), SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) ); - + //if( dlg()->testButtonFlags( QtxDialog::Close ) ) //if dialog hasn't close, cancel, no and etc buttons, dlgClose will be emitted when dialog is closed not by OK connect( dlg(), SIGNAL( dlgClose() ), this, SLOT( onCancel() ) ); @@ -120,18 +119,18 @@ bool SMESHGUI_Operation::isReadyToStart() const else if ( getSMESHGUI() == 0 ) { SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NO_MODULE" ) ); + tr( "NO_MODULE" ) ); return false; } else if ( isStudyLocked() ) return false; - + return true; } //======================================================================= // name : setDialogActive -// Purpose : +// Purpose : //======================================================================= void SMESHGUI_Operation::setDialogActive( const bool active ) { @@ -159,8 +158,10 @@ _PTR(Study) SMESHGUI_Operation::studyDS() const //======================================================================= void SMESHGUI_Operation::onOk() { + setIsApplyAndClose( true ); if( onApply() ) commit(); + setIsApplyAndClose( false ); //else // abort(); } @@ -190,7 +191,7 @@ void SMESHGUI_Operation::onCancel() void SMESHGUI_Operation::onHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(getSMESHGUI() ? app->moduleName(getSMESHGUI()->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -200,10 +201,10 @@ void SMESHGUI_Operation::onHelp() platform = "application"; #endif SUIT_MessageBox::warning( desktop(), tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName) ); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName) ); } } @@ -215,6 +216,26 @@ void SMESHGUI_Operation::initDialog() { } +//================================================================ +// name : setIsApplyAndClose +// Purpose : Set value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +void SMESHGUI_Operation::setIsApplyAndClose( const bool theFlag ) +{ + myIsApplyAndClose = theFlag; +} + +//================================================================ +// name : isApplyAndClose +// Purpose : Get value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +bool SMESHGUI_Operation::isApplyAndClose() const +{ + return myIsApplyAndClose; +} + /*! * \brief Verifies whether study of operation is locked * \param theMess - specifies whether message box must be shown if study is locked @@ -231,11 +252,11 @@ bool SMESHGUI_Operation::isStudyLocked( const bool theMess ) const { if ( theMess ) SUIT_MessageBox::warning( SMESHGUI::desktop(), tr( "WRN_WARNING" ), - tr( "WRN_STUDY_LOCKED" ) ); + tr( "WRN_STUDY_LOCKED" ) ); return true; } } - + return false; } @@ -258,9 +279,9 @@ bool SMESHGUI_Operation::isValid( SUIT_Operation* theOtherOp ) const // to do add other operations here } - return theOtherOp && theOtherOp->inherits( "SMESHGUI_Operation" ) && - ( !anOps.contains( theOtherOp->metaObject()->className() ) || - anOps.contains( metaObject()->className() ) ); + return ( theOtherOp && + ( ( theOtherOp->inherits("SMESHGUI_Operation") && ( !anOps.contains(theOtherOp->metaObject()->className() ) || anOps.contains(metaObject()->className()) ) ) || + ( theOtherOp->inherits("LightApp_ShowHideOp") ) ) ); return true; } diff --git a/src/SMESHGUI/SMESHGUI_Operation.h b/src/SMESHGUI/SMESHGUI_Operation.h index b3b119e71..2bbad5c1f 100755 --- a/src/SMESHGUI/SMESHGUI_Operation.h +++ b/src/SMESHGUI/SMESHGUI_Operation.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMDS : implementaion of Salome mesh data structure // File : SMESHGUI_Operation.h // Author : Sergey LITONIN, Open CASCADE S.A.S. @@ -57,6 +58,9 @@ protected: virtual void startOperation(); virtual bool isReadyToStart() const; + virtual void setIsApplyAndClose( const bool theFlag ); + virtual bool isApplyAndClose() const; + //! Set according dialog active or inactive virtual void setDialogActive( const bool ); @@ -68,6 +72,7 @@ protected: virtual bool isValid( SUIT_Operation* ) const; QString myHelpFileName; + bool myIsApplyAndClose; protected slots: virtual void onOk(); diff --git a/src/SMESHGUI/SMESHGUI_PatternUtils.cxx b/src/SMESHGUI/SMESHGUI_PatternUtils.cxx index d6ea44b2e..349314182 100644 --- a/src/SMESHGUI/SMESHGUI_PatternUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_PatternUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_PatternUtils.cxx // Author : Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_PatternUtils.h b/src/SMESHGUI/SMESHGUI_PatternUtils.h index cd5fd7040..a455061c6 100644 --- a/src/SMESHGUI/SMESHGUI_PatternUtils.h +++ b/src/SMESHGUI/SMESHGUI_PatternUtils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_PatternUtils.h // Author : Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_PatternWidget.cxx b/src/SMESHGUI/SMESHGUI_PatternWidget.cxx index c8ab77ac8..f3483ba25 100644 --- a/src/SMESHGUI/SMESHGUI_PatternWidget.cxx +++ b/src/SMESHGUI/SMESHGUI_PatternWidget.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_PatternWidget.cxx // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -95,9 +96,9 @@ void SMESHGUI_PatternWidget::paintEvent( QPaintEvent* ) QPoint aQPnt = mapCoords( aPoint.x, aPoint.y ); painter.drawPie( aQPnt.x() - Radius, aQPnt.y() - Radius, - Radius * 2, Radius * 2, 0, 360 * 16 ); + Radius * 2, Radius * 2, 0, 360 * 16 ); painter.drawText( aQPnt.x() + Shift, aQPnt.y() - Shift, - QString::number( i+1 ) ); + QString::number( i+1 ) ); } // Draw lines diff --git a/src/SMESHGUI/SMESHGUI_PatternWidget.h b/src/SMESHGUI/SMESHGUI_PatternWidget.h index e4a6e41d3..82ffdeea9 100644 --- a/src/SMESHGUI/SMESHGUI_PatternWidget.h +++ b/src/SMESHGUI/SMESHGUI_PatternWidget.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_PatternWidget.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -53,8 +54,8 @@ public: ~SMESHGUI_PatternWidget(); void SetPoints( const PointVector&, - const QVector&, - const ConnectivityVector& ); + const QVector&, + const ConnectivityVector& ); private: PointVector myPoints; diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx index 3b16aaf0b..c7b6d5e7d 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Preferences_ColorDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -27,12 +28,18 @@ #include "SMESHGUI_Preferences_ColorDlg.h" #include "SMESHGUI.h" +#include "SMESHGUI_SpinBox.h" #include "SMESHGUI_Utils.h" // SALOME GUI includes #include +#include +#include +#include #include -#include +#include +#include +#include // Qt includes #include @@ -41,7 +48,8 @@ #include #include #include -#include +#include +#include #define SPACING 6 #define MARGIN 11 @@ -58,7 +66,7 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul mySMESHGUI( theModule ) { setModal( true ); - setWindowTitle( tr( "Preferences - Set Color" ) ); + setWindowTitle( tr( "DIALOG_TITLE" ) ); setSizeGripEnabled( true ); // ------------------------------- @@ -67,65 +75,148 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul topLayout->setMargin( MARGIN ); // ------------------------------- - QGroupBox* ButtonGroup1 = new QGroupBox( tr( "Elements" ), this ); + QGroupBox* ButtonGroup1 = new QGroupBox( tr( "GRP_ELEMENTS" ), this ); QGridLayout* ButtonGroup1Layout = new QGridLayout( ButtonGroup1 ); ButtonGroup1Layout->setSpacing( SPACING ); ButtonGroup1Layout->setMargin( MARGIN ); - QLabel* TextLabel_Fill = new QLabel( tr( "Fill" ), ButtonGroup1 ); - btnFillColor = new QtxColorButton( ButtonGroup1 ); + QLabel* TextLabel_Fill = new QLabel( tr( "SURFACE_COLOR_LBL" ), ButtonGroup1 ); - QLabel* TextLabel_BackFace = new QLabel( tr( "Back Face" ), ButtonGroup1 ); - btnBackFaceColor = new QtxColorButton( ButtonGroup1 ); + toolSurfColor = new QtxBiColorTool(ButtonGroup1); + toolSurfColor->setText( tr( "BACKSURFACE_COLOR_LBL" )); - QLabel* TextLabel_Outine = new QLabel( tr( "Outline" ), ButtonGroup1 ); + QLabel* TextLabel_Outline = new QLabel( tr( "OUTLINE_COLOR_LBL" ), ButtonGroup1 ); btnOutlineColor = new QtxColorButton( ButtonGroup1 ); - QLabel* TextLabel_Width = new QLabel( tr( "Width" ), ButtonGroup1 ); - SpinBox_Width = new QSpinBox( ButtonGroup1 ); - SpinBox_Width->setRange( 0, 5 ); + QLabel* TextLabel_Wireframe = new QLabel( tr( "WIREFRAME_COLOR_LBL" ), ButtonGroup1 ); + btnWireframeColor = new QtxColorButton( ButtonGroup1 ); + + QLabel* TextLabel_0DElements_Color = new QLabel( tr( "0D_ELEMENTS_COLOR_LBL" ), ButtonGroup1 ); + btn0DElementsColor = new QtxColorButton( ButtonGroup1 ); + + QLabel* TextLabel_0DElements_Size = new QLabel( tr( "0D_ELEMENTS_SIZE_LBL" ), ButtonGroup1 ); + SpinBox_0DElements_Size = new SalomeApp_IntSpinBox( ButtonGroup1 ); + SpinBox_0DElements_Size->setAcceptNames( false ); // No Notebook variables allowed + SpinBox_0DElements_Size->setRange( 1, 10 ); + SpinBox_0DElements_Size->setSingleStep( 1 ); + SpinBox_0DElements_Size->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + SpinBox_0DElements_Size->setButtonSymbols( QSpinBox::PlusMinus ); + + QLabel* TextLabel_BallElem_Color = new QLabel( tr( "0D_ELEMENTS_COLOR_LBL" ), ButtonGroup1 ); + btnBallElemColor = new QtxColorButton( ButtonGroup1 ); + + QLabel* TextLabel_BallElem_Size = new QLabel( tr( "BALLELEM_SIZE_LBL" ), ButtonGroup1 ); + SpinBox_BallElem_Size = new SalomeApp_IntSpinBox( ButtonGroup1 ); + SpinBox_BallElem_Size->setAcceptNames( false ); // No Notebook variables allowed + SpinBox_BallElem_Size->setRange( 1, 10 ); + SpinBox_BallElem_Size->setSingleStep( 1 ); + SpinBox_BallElem_Size->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + SpinBox_BallElem_Size->setButtonSymbols( QSpinBox::PlusMinus ); + + QLabel* TextLabel_Width = new QLabel( tr( "LINE_WIDTH_LBL" ), ButtonGroup1 ); + SpinBox_Width = new SalomeApp_IntSpinBox( ButtonGroup1 ); + SpinBox_Width->setAcceptNames( false ); // No Notebook variables allowed + SpinBox_Width->setRange( 1, 5 ); SpinBox_Width->setSingleStep( 1 ); SpinBox_Width->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); SpinBox_Width->setButtonSymbols( QSpinBox::PlusMinus ); - QLabel* TextLabel_ShrinkCoeff = new QLabel( tr( "Shrink coef." ), ButtonGroup1 ); - SpinBox_Shrink = new QtxIntSpinBox( ButtonGroup1 ); + QLabel* TextLabel_ShrinkCoeff = new QLabel( tr( "SHRINK_COEF_LBL" ), ButtonGroup1 ); + SpinBox_Shrink = new SalomeApp_IntSpinBox( ButtonGroup1 ); + SpinBox_Shrink->setAcceptNames( false ); // No Notebook variables allowed SpinBox_Shrink->setRange( 20, 100 ); SpinBox_Shrink->setSingleStep( 1 ); SpinBox_Shrink->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); SpinBox_Shrink->setButtonSymbols( QSpinBox::PlusMinus ); - ButtonGroup1Layout->addWidget( TextLabel_Fill, 0, 0 ); - ButtonGroup1Layout->addWidget( btnFillColor, 0, 1 ); - ButtonGroup1Layout->addWidget( TextLabel_BackFace, 0, 2 ); - ButtonGroup1Layout->addWidget( btnBackFaceColor, 0, 3 ); - ButtonGroup1Layout->addWidget( TextLabel_Outine, 1, 0 ); - ButtonGroup1Layout->addWidget( btnOutlineColor, 1, 1 ); - ButtonGroup1Layout->addWidget( TextLabel_Width, 1, 2 ); - ButtonGroup1Layout->addWidget( SpinBox_Width, 1, 3 ); - ButtonGroup1Layout->addWidget( TextLabel_ShrinkCoeff, 2, 0 ); - ButtonGroup1Layout->addWidget( SpinBox_Shrink, 2, 1, 1, 3 ); + ButtonGroup1Layout->addWidget( TextLabel_Fill, 0, 0 ); + ButtonGroup1Layout->addWidget( toolSurfColor, 0, 1, 1, 3 ); + + ButtonGroup1Layout->addWidget( TextLabel_Outline, 1, 0 ); + ButtonGroup1Layout->addWidget( btnOutlineColor, 1, 1 ); + ButtonGroup1Layout->addWidget( TextLabel_Wireframe, 1, 2 ); + ButtonGroup1Layout->addWidget( btnWireframeColor, 1, 3 ); + + ButtonGroup1Layout->addWidget( TextLabel_0DElements_Color, 2, 0 ); + ButtonGroup1Layout->addWidget( btn0DElementsColor, 2, 1 ); + + ButtonGroup1Layout->addWidget( TextLabel_0DElements_Size, 2, 2 ); + ButtonGroup1Layout->addWidget( SpinBox_0DElements_Size, 2, 3 ); + + ButtonGroup1Layout->addWidget( TextLabel_BallElem_Color, 2, 0 ); + ButtonGroup1Layout->addWidget( btnBallElemColor, 2, 1 ); + + ButtonGroup1Layout->addWidget( TextLabel_BallElem_Size, 2, 2 ); + ButtonGroup1Layout->addWidget( SpinBox_BallElem_Size, 2, 3 ); + + ButtonGroup1Layout->addWidget( TextLabel_Width, 3, 0 ); + ButtonGroup1Layout->addWidget( SpinBox_Width, 3, 1 ); + ButtonGroup1Layout->addWidget( TextLabel_ShrinkCoeff, 3, 2 ); + ButtonGroup1Layout->addWidget( SpinBox_Shrink, 3, 3 ); // ------------------------------- - QGroupBox* ButtonGroup2 = new QGroupBox( tr( "Nodes" ), this ); - QHBoxLayout* ButtonGroup2Layout = new QHBoxLayout( ButtonGroup2 ); + QGroupBox* ButtonGroup2 = new QGroupBox( tr( "GRP_NODES" ), this ); + QGridLayout* ButtonGroup2Layout = new QGridLayout( ButtonGroup2 ); ButtonGroup2Layout->setSpacing( SPACING ); ButtonGroup2Layout->setMargin( MARGIN ); - QLabel* TextLabel_Nodes_Color = new QLabel( tr( "Color" ), ButtonGroup2 ); + QLabel* TextLabel_Nodes_Color = new QLabel( tr( "NODES_COLOR_LBL" ), ButtonGroup2 ); btnNodeColor = new QtxColorButton( ButtonGroup2 ); - QLabel* TextLabel_Nodes_Size = new QLabel( tr( "Size" ), ButtonGroup2 ); - SpinBox_Nodes_Size = new QSpinBox( ButtonGroup2 ); - SpinBox_Nodes_Size->setRange( 0, 5 ); - SpinBox_Nodes_Size->setSingleStep( 1 ); - SpinBox_Nodes_Size->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - SpinBox_Nodes_Size->setButtonSymbols( QSpinBox::PlusMinus ); + QGroupBox* MarkerGroup = new QGroupBox( tr( "NODES_MARKER_LBL" ), ButtonGroup2 ); + QVBoxLayout* MarkerGroupLayout = new QVBoxLayout( MarkerGroup ); + MarkerGroupLayout->setSpacing( 0 ); + MarkerGroupLayout->setMargin( 0 ); + + MarkerWidget = new VTKViewer_MarkerWidget( MarkerGroup ); + + MarkerGroupLayout->addWidget( MarkerWidget ); + + ButtonGroup2Layout->addWidget( TextLabel_Nodes_Color, 0, 0 ); + ButtonGroup2Layout->addWidget( btnNodeColor, 0, 1 ); + ButtonGroup2Layout->addWidget( MarkerGroup, 1, 0, 1, 3 ); + ButtonGroup2Layout->setColumnStretch( 2, 1 ); + + // ------------------------------- + QGroupBox* ButtonGroup3 = new QGroupBox( tr( "GRP_ORIENTATION" ), this ); + QGridLayout* ButtonGroup3Layout = new QGridLayout( ButtonGroup3 ); + ButtonGroup3Layout->setSpacing( SPACING ); + ButtonGroup3Layout->setMargin( MARGIN ); + + QLabel* TextLabel_Orientation_Color = new QLabel( tr( "ORIENTATION_COLOR_LBL" ), ButtonGroup3 ); + btnOrientationColor = new QtxColorButton( ButtonGroup3 ); + + QLabel* TextLabel_Orientation_Scale = new QLabel( tr( "ORIENTATION_SCALE_LBL" ), ButtonGroup3 ); + SpinBox_Orientation_Scale = new SMESHGUI_SpinBox( ButtonGroup3 ); + SpinBox_Orientation_Scale->setAcceptNames( false ); // No Notebook variables allowed + SpinBox_Orientation_Scale->RangeStepAndValidator( .05, .5, .05, "parametric_precision" ); + SpinBox_Orientation_Scale->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + SpinBox_Orientation_Scale->setButtonSymbols( QSpinBox::PlusMinus ); + + CheckBox_Orientation_3DVectors = new QCheckBox( tr( "3D_VECTORS_LBL" ), ButtonGroup3 ); + + ButtonGroup3Layout->addWidget( TextLabel_Orientation_Color, 0, 0 ); + ButtonGroup3Layout->addWidget( btnOrientationColor, 0, 1 ); + ButtonGroup3Layout->addWidget( TextLabel_Orientation_Scale, 0, 2 ); + ButtonGroup3Layout->addWidget( SpinBox_Orientation_Scale, 0, 3 ); + ButtonGroup3Layout->addWidget( CheckBox_Orientation_3DVectors, 1, 0, 1, 4 ); - ButtonGroup2Layout->addWidget( TextLabel_Nodes_Color ); - ButtonGroup2Layout->addWidget( btnNodeColor ); - ButtonGroup2Layout->addWidget( TextLabel_Nodes_Size ); - ButtonGroup2Layout->addWidget( SpinBox_Nodes_Size ); + // ------------------------------- + QGroupBox* ButtonGroup4 = new QGroupBox( tr( "GRP_SELECTION" ), this ); + QGridLayout* ButtonGroup4Layout = new QGridLayout( ButtonGroup4 ); + ButtonGroup3Layout->setSpacing( SPACING ); + ButtonGroup3Layout->setMargin( MARGIN ); + + QLabel* TextLabel_Selection_Color = new QLabel( tr( "SELECTION_COLOR_LBL" ), ButtonGroup4 ); + btnSelectionColor = new QtxColorButton( ButtonGroup4 ); + + QLabel* TextLabel_Preselection_Color = new QLabel( tr( "PRESELECTION_COLOR_LBL" ), ButtonGroup4 ); + btnPreselectionColor = new QtxColorButton( ButtonGroup4 ); + + ButtonGroup4Layout->addWidget( TextLabel_Selection_Color, 0, 0 ); + ButtonGroup4Layout->addWidget( btnSelectionColor, 0, 1 ); + ButtonGroup4Layout->addWidget( TextLabel_Preselection_Color, 0, 2 ); + ButtonGroup4Layout->addWidget( btnPreselectionColor, 0, 3 ); // ------------------------------- QGroupBox* GroupButtons = new QGroupBox( this ); @@ -133,35 +224,46 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul GroupButtonsLayout->setSpacing( SPACING ); GroupButtonsLayout->setMargin( MARGIN ); - QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons ); + QPushButton* buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons ); buttonOk->setAutoDefault( true ); buttonOk->setDefault( true ); - QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ), GroupButtons ); + QPushButton* buttonCancel = new QPushButton( tr( "SMESH_BUT_CANCEL" ), GroupButtons ); buttonCancel->setAutoDefault( true ); + QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons ); + buttonHelp->setAutoDefault( true ); + GroupButtonsLayout->addWidget( buttonOk ); GroupButtonsLayout->addSpacing( 10 ); GroupButtonsLayout->addStretch(); GroupButtonsLayout->addWidget( buttonCancel ); + GroupButtonsLayout->addWidget( buttonHelp ); // ------------------------------- topLayout->addWidget( ButtonGroup1 ); topLayout->addWidget( ButtonGroup2 ); + topLayout->addWidget( ButtonGroup3 ); + // rnv: Selection and preselection colors are defined only in the Preferences + // topLayout->addWidget( ButtonGroup4 ); + ButtonGroup4->hide(); topLayout->addWidget( GroupButtons ); // ------------------------------- mySMESHGUI->SetActiveDialogBox( this ); + myHelpFileName = "colors_size_page.html"; + /* signals and slots connections */ connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ); + connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) ); connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ), - this, SLOT( DeactivateActiveDialog() ) ); + this, SLOT( DeactivateActiveDialog() ) ); /* to close dialog if study change */ connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), - this, SLOT( ClickOnCancel() ) ); + this, SLOT( ClickOnCancel() ) ); } //================================================================================= @@ -192,6 +294,30 @@ void SMESHGUI_Preferences_ColorDlg::ClickOnCancel() reject(); } +//================================================================================= +// function : ClickOnHelp() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::ClickOnHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} + //================================================================================= // function : DeactivateActiveDialog() // purpose : @@ -226,10 +352,15 @@ void SMESHGUI_Preferences_ColorDlg::ActivateThisDialog() void SMESHGUI_Preferences_ColorDlg::SetColor( int type, const QColor& color ) { switch ( type ) { - case 1 : btnFillColor->setColor( color ); break; // fill - case 2 : btnOutlineColor->setColor( color ); break; // outline - case 3 : btnNodeColor->setColor( color ); break; // node - case 4 : btnBackFaceColor->setColor( color ); break; // back face + case 1 : toolSurfColor->setMainColor( color ); break; // fill + case 2 : btnWireframeColor->setColor( color ); break; // wireframe + case 3 : btnNodeColor->setColor( color ); break; // node + case 4 : btnOutlineColor->setColor( color ); break; // outline + case 5 : btn0DElementsColor->setColor( color ); break; // 0d elements + case 6 : btnBallElemColor->setColor( color ); break; // ball elements + case 7 : btnOrientationColor->setColor( color ); break; // orientation of faces + case 8 : btnSelectionColor->setColor( color ); break; // selection color + case 9 : btnPreselectionColor->setColor( color ); break; // pre-selection color default: break; } } @@ -242,10 +373,16 @@ QColor SMESHGUI_Preferences_ColorDlg::GetColor( int type ) { QColor color; switch ( type ) { - case 1 : color = btnFillColor->color(); break; // fill - case 2 : color = btnOutlineColor->color(); break; // outline - case 3 : color = btnNodeColor->color(); break; // node - case 4 : color = btnBackFaceColor->color(); break; // back face + case 1 : color = toolSurfColor->mainColor(); break; // fill + case 2 : color = btnWireframeColor->color(); break; // outline + case 3 : color = btnNodeColor->color(); break; // node + case 4 : color = btnOutlineColor->color(); break; // node + case 5 : color = btn0DElementsColor->color(); break; // 0d elements + case 6 : color = btnBallElemColor->color(); break; // 0d elements + case 7 : color = btnOrientationColor->color(); break; // orientation of faces + case 8 : color = btnSelectionColor->color(); break; // selection color + case 9 : color = btnPreselectionColor->color(); break; // pre-selection color + default: break; } return color; @@ -258,9 +395,10 @@ QColor SMESHGUI_Preferences_ColorDlg::GetColor( int type ) void SMESHGUI_Preferences_ColorDlg::SetIntValue( int type, int value ) { switch ( type ) { - case 1 : SpinBox_Width->setValue( value ); break; // width - case 2 : SpinBox_Nodes_Size->setValue( value ); break; // nodes size = value; break; - case 3 : SpinBox_Shrink->setValue( value ); break; // shrink coeff + case 1 : SpinBox_Width->setValue( value ); break; // width + case 2 : SpinBox_Shrink->setValue( value ); break; // shrink coeff + case 3 : SpinBox_0DElements_Size->setValue( value ); break; // 0d elements + case 4 : SpinBox_BallElem_Size->setValue( value ); break; // 0d elements default: break; } } @@ -273,10 +411,160 @@ int SMESHGUI_Preferences_ColorDlg::GetIntValue( int type ) { int res = 0; switch ( type ) { - case 1 : res = SpinBox_Width->value(); break; // width - case 2 : res = SpinBox_Nodes_Size->value(); break; // nodes size - case 3 : res = SpinBox_Shrink->value(); break; // shrink coeff + case 1 : res = SpinBox_Width->value(); break; // width + case 2 : res = SpinBox_Shrink->value(); break; // shrink coeff + case 3 : res = SpinBox_0DElements_Size->value(); break; // 0d elements + case 4 : res = SpinBox_BallElem_Size->value(); break; // 0d elements + default: break; + } + return res; +} + +//================================================================================= +// function : SetDoubleValue() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::SetDoubleValue( int type, double value ) +{ + switch ( type ) { + case 1 : SpinBox_Orientation_Scale->setValue( value ); break; // orientation scale + default: break; + } +} + +//================================================================================= +// function : GetDoubleValue() +// purpose : +//================================================================================= +double SMESHGUI_Preferences_ColorDlg::GetDoubleValue( int type ) +{ + double res = 0; + switch ( type ) { + case 1 : res = SpinBox_Orientation_Scale->value(); break; // orientation scale + default: break; + } + return res; +} + +//================================================================================= +// function : SetBooleanValue() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::SetBooleanValue( int type, bool value ) +{ + switch ( type ) { + case 1 : CheckBox_Orientation_3DVectors->setChecked( value ); break; // 3D vectors + default: break; + } +} + +//================================================================================= +// function : GetBooleanValue() +// purpose : +//================================================================================= +bool SMESHGUI_Preferences_ColorDlg::GetBooleanValue( int type ) +{ + bool res = false; + switch ( type ) { + case 1 : res = CheckBox_Orientation_3DVectors->isChecked(); break; // 3D vectors default: break; } return res; } + +//================================================================================= +// function : setCustomMarkerMap() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::setCustomMarkerMap( VTK::MarkerMap theMarkerMap ) +{ + MarkerWidget->setCustomMarkerMap( theMarkerMap ); +} + +//================================================================================= +// function : getCustomMarkerMap() +// purpose : +//================================================================================= +VTK::MarkerMap SMESHGUI_Preferences_ColorDlg::getCustomMarkerMap() +{ + return MarkerWidget->getCustomMarkerMap(); +} + +//================================================================================= +// function : setStandardMarker() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::setStandardMarker( VTK::MarkerType theMarkerType, + VTK::MarkerScale theMarkerScale ) +{ + MarkerWidget->setStandardMarker( theMarkerType, theMarkerScale ); +} + +//================================================================================= +// function : setCustomMarker() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::setCustomMarker( int theId ) +{ + MarkerWidget->setCustomMarker( theId ); +} + +//================================================================================= +// function : getMarkerType() +// purpose : +//================================================================================= +VTK::MarkerType SMESHGUI_Preferences_ColorDlg::getMarkerType() const +{ + return MarkerWidget->getMarkerType(); +} + +//================================================================================= +// function : getStandardMarkerScale() +// purpose : +//================================================================================= +VTK::MarkerScale SMESHGUI_Preferences_ColorDlg::getStandardMarkerScale() const +{ + return MarkerWidget->getStandardMarkerScale(); +} + +//================================================================================= +// function : getCustomMarkerID() +// purpose : +//================================================================================= +int SMESHGUI_Preferences_ColorDlg::getCustomMarkerID() const +{ + return MarkerWidget->getCustomMarkerID(); +} + +//================================================================================= +// function : SetDeltaBrightness(int) +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::SetDeltaBrightness(int delta) +{ + toolSurfColor->setDelta(delta); +} +//================================================================================= +// function : GetDeltaBrightness() +// purpose : +//================================================================================= +int SMESHGUI_Preferences_ColorDlg::GetDeltaBrightness() +{ + return toolSurfColor->delta(); +} + +//================================================================================= +// function : keyPressEvent() +// purpose : +//================================================================================= +void SMESHGUI_Preferences_ColorDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + ClickOnHelp(); + } +} diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h index f3f43f94d..9533ca748 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h +++ b/src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Preferences_ColorDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -29,13 +30,19 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" +// SALOME GUI includes +#include +#include + // Qt includes #include -class QSpinBox; +class QCheckBox; class SMESHGUI; -class QtxIntSpinBox; +class SMESHGUI_SpinBox; +class SalomeApp_IntSpinBox; class QtxColorButton; +class VTKViewer_MarkerWidget; class SMESHGUI_EXPORT SMESHGUI_Preferences_ColorDlg : public QDialog { @@ -49,26 +56,55 @@ public: QColor GetColor( int ); void SetIntValue( int, int ); int GetIntValue( int ); + void SetDoubleValue( int, double ); + double GetDoubleValue( int ); + void SetBooleanValue( int, bool ); + bool GetBooleanValue( int ); + + void setCustomMarkerMap( VTK::MarkerMap ); + VTK::MarkerMap getCustomMarkerMap(); + + void SetDeltaBrightness(int); + int GetDeltaBrightness(); + + void setStandardMarker( VTK::MarkerType, VTK::MarkerScale ); + void setCustomMarker( int ); + VTK::MarkerType getMarkerType() const; + VTK::MarkerScale getStandardMarkerScale() const; + int getCustomMarkerID() const; protected: void closeEvent( QCloseEvent* ); + void keyPressEvent( QKeyEvent* ); private slots: void ClickOnOk(); void ClickOnCancel(); + void ClickOnHelp(); void DeactivateActiveDialog(); void ActivateThisDialog(); private: SMESHGUI* mySMESHGUI; - - QtxColorButton* btnFillColor; - QtxColorButton* btnBackFaceColor; + + QtxBiColorTool* toolSurfColor; + QtxColorButton* btnWireframeColor; QtxColorButton* btnOutlineColor; - QSpinBox* SpinBox_Width; - QtxIntSpinBox* SpinBox_Shrink; + QtxColorButton* btn0DElementsColor; + QtxColorButton* btnBallElemColor; + SalomeApp_IntSpinBox* SpinBox_0DElements_Size; + SalomeApp_IntSpinBox* SpinBox_BallElem_Size; + SalomeApp_IntSpinBox* SpinBox_Width; + SalomeApp_IntSpinBox* SpinBox_Shrink; QtxColorButton* btnNodeColor; - QSpinBox* SpinBox_Nodes_Size; + VTKViewer_MarkerWidget* MarkerWidget; + QtxColorButton* btnOrientationColor; + SMESHGUI_SpinBox* SpinBox_Orientation_Scale; + QCheckBox* CheckBox_Orientation_3DVectors; + QtxColorButton* btnPreselectionColor; + QtxColorButton* btnSelectionColor; + + QString myHelpFileName; }; #endif // SMESHGUI_PREFERENCES_COLORDLG_H diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx index a6d44e57a..7f0a861ae 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Preferences_ScalarBarDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -27,10 +28,14 @@ #include "SMESHGUI_Preferences_ScalarBarDlg.h" #include "SMESHGUI.h" +#include "SMESHGUI_SpinBox.h" #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_Utils.h" #include +#include +#include +#include // SALOME GUI includes #include @@ -41,8 +46,8 @@ #include #include #include +#include -#include #include // Qt includes @@ -54,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -62,7 +66,6 @@ // VTK includes #include -#include #include #define MINIMUM_WIDTH 70 @@ -199,13 +202,15 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* QHBoxLayout* myLabColorGrpLayout = new QHBoxLayout( myLabColorGrp ); myLabColorGrpLayout->setSpacing( SPACING_SIZE ); myLabColorGrpLayout->setMargin( MARGIN_SIZE ); - myColorsSpin = new QSpinBox( myLabColorGrp ); + myColorsSpin = new SalomeApp_IntSpinBox( myLabColorGrp ); + myColorsSpin->setAcceptNames( false ); // No Notebook variables allowed myColorsSpin->setRange( 2, 256 ); myColorsSpin->setSingleStep( 1 ); myColorsSpin->setMinimumWidth( MINIMUM_WIDTH ); myColorsSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myLabelsSpin = new QSpinBox( myLabColorGrp ); + myLabelsSpin = new SalomeApp_IntSpinBox( myLabColorGrp ); + myLabelsSpin->setAcceptNames( false ); // No Notebook variables allowed myLabelsSpin->setRange( 2, 65 ); myLabelsSpin->setSingleStep( 1 ); myLabelsSpin->setMinimumWidth( MINIMUM_WIDTH ); @@ -242,19 +247,27 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* QGridLayout* myOriginDimGrpLayout = new QGridLayout( myOriginDimGrp ); myOriginDimGrpLayout->setSpacing( SPACING_SIZE ); myOriginDimGrpLayout->setMargin( MARGIN_SIZE ); - myXSpin = new QtxDoubleSpinBox (0.0, 1.0, 0.1, myOriginDimGrp); + myXSpin = new SMESHGUI_SpinBox(myOriginDimGrp); + myXSpin->setAcceptNames( false ); + myXSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" ); myXSpin->setMinimumWidth( MINIMUM_WIDTH ); myXSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myYSpin = new QtxDoubleSpinBox(0.0, 1.0, 0.1, myOriginDimGrp); + myYSpin = new SMESHGUI_SpinBox(myOriginDimGrp); + myYSpin->setAcceptNames( false ); + myYSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" ); myYSpin->setMinimumWidth( MINIMUM_WIDTH ); myYSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myWidthSpin = new QtxDoubleSpinBox(0.0, 1.0, 0.1, myOriginDimGrp); + myWidthSpin = new SMESHGUI_SpinBox(myOriginDimGrp); + myWidthSpin->setAcceptNames( false ); + myWidthSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" ); myWidthSpin->setMinimumWidth( MINIMUM_WIDTH ); myWidthSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myHeightSpin = new QtxDoubleSpinBox(0.0, 1.0, 0.1, myOriginDimGrp); + myHeightSpin = new SMESHGUI_SpinBox(myOriginDimGrp); + myHeightSpin->setAcceptNames( false ); + myHeightSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" ); myHeightSpin->setMinimumWidth( MINIMUM_WIDTH ); myHeightSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); @@ -268,8 +281,35 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* myOriginDimGrpLayout->addWidget( myHeightSpin, 1, 3 ); aTopLayout->addWidget( myOriginDimGrp ); + /******************************************************************************/ - /***************************************************************/ + // Destribution + myDistributionGrp = new QGroupBox ( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), this ); + myDistributionGrp->setCheckable(true); + QHBoxLayout* aDistributionGrpLayout = new QHBoxLayout( myDistributionGrp ); + aDistributionGrpLayout->setSpacing( SPACING_SIZE ); aDistributionGrpLayout->setMargin( MARGIN_SIZE ); + + myDistribColorGrp = new QButtonGroup( this ); + + myDMonoColor = new QRadioButton( tr( "SMESH_MONOCOLOR" ) , myDistributionGrp ); + myDMultiColor = new QRadioButton( tr( "SMESH_MULTICOLOR" ), myDistributionGrp ); + myDMonoColor->setChecked( true ); + + myDistribColorGrp->addButton(myDMonoColor);myDistribColorGrp->setId(myDMonoColor,1); + myDistribColorGrp->addButton(myDMultiColor);myDistribColorGrp->setId(myDMultiColor,2); + + aDistributionGrpLayout->addWidget( myDMultiColor ); + aDistributionGrpLayout->addWidget( myDMonoColor ); + + //Color of the Distribution in monocolor case: + myDistributionColorLbl = new QLabel( tr( "SMESH_DISTRIBUTION_COLOR" ), myDistributionGrp ); + aDistributionGrpLayout->addWidget( myDistributionColorLbl ); + myMonoColorBtn = new QtxColorButton( myDistributionGrp ); + aDistributionGrpLayout->addWidget(myMonoColorBtn); + + aTopLayout->addWidget(myDistributionGrp); + + /******************************************************************************/ // Common buttons myButtonGrp = new QGroupBox( this ); QHBoxLayout* myButtonGrpLayout = new QHBoxLayout( myButtonGrp ); @@ -300,7 +340,7 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI ); QColor titleColor = mgr->colorValue("SMESH", "scalar_bar_title_color", - QColor(255, 255, 255)); + QColor(255, 255, 255)); myTitleColorBtn->setColor(titleColor); myTitleFontCombo->setCurrentIndex(0); if (mgr->hasValue("SMESH", "scalar_bar_title_font")) { @@ -316,9 +356,9 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* myTitleItalicCheck->setChecked( f.italic() ); myTitleShadowCheck->setChecked( f.overline() ); } - + QColor labelColor = mgr->colorValue("SMESH", "scalar_bar_label_color", - QColor(255, 255, 255)); + QColor(255, 255, 255)); myLabelsColorBtn->setColor(labelColor); myLabelsFontCombo->setCurrentIndex(0); if (mgr->hasValue("SMESH", "scalar_bar_label_font")) { @@ -352,19 +392,39 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* QString name = isHoriz ? "scalar_bar_horizontal_%1" : "scalar_bar_vertical_%1"; myIniX = mgr->doubleValue("SMESH", name.arg( "x" ), - myHorizRadioBtn->isChecked() ? DEF_HOR_X : DEF_VER_X); + myHorizRadioBtn->isChecked() ? DEF_HOR_X : DEF_VER_X); myIniY = mgr->doubleValue("SMESH", name.arg( "y" ), - myHorizRadioBtn->isChecked() ? DEF_HOR_Y : DEF_VER_Y); + myHorizRadioBtn->isChecked() ? DEF_HOR_Y : DEF_VER_Y); myIniW = mgr->doubleValue("SMESH", name.arg( "width" ), - myHorizRadioBtn->isChecked() ? DEF_HOR_W : DEF_VER_W); + myHorizRadioBtn->isChecked() ? DEF_HOR_W : DEF_VER_W); myIniH = mgr->doubleValue("SMESH", name.arg( "height" ), - myHorizRadioBtn->isChecked() ? DEF_HOR_H : DEF_VER_H); + myHorizRadioBtn->isChecked() ? DEF_HOR_H : DEF_VER_H); setOriginAndSize(myIniX, myIniY, myIniW, myIniH); + + bool distributionVisibility = mgr->booleanValue("SMESH","distribution_visibility"); + myDistributionGrp->setChecked(distributionVisibility); + + int coloringType = mgr->integerValue("SMESH", "distribution_coloring_type", 0); + if( coloringType == SMESH_MONOCOLOR_TYPE ) { + myDMonoColor->setChecked(true); + onDistributionChanged(myDistribColorGrp->id(myDMonoColor)); + } else { + myDMultiColor->setChecked(true); + onDistributionChanged(myDistribColorGrp->id(myDMultiColor)); + + } + + QColor distributionColor = mgr->colorValue("SMESH", "distribution_color", + QColor(255, 255, 255)); + myMonoColorBtn->setColor(distributionColor); + + + // --> then init from selection if necessary onSelectionChanged(); @@ -377,10 +437,12 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* connect( myXSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) ); connect( myYSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) ); connect( aOrientationGrp, SIGNAL( buttonClicked( int ) ), this, SLOT( onOrientationChanged() ) ); + connect( myDistributionGrp, SIGNAL( toggled(bool) ), this, SLOT(onDistributionActivated(bool)) ); + connect( myDistribColorGrp, SIGNAL( buttonClicked( int ) ), this, SLOT( onDistributionChanged( int ) ) ); connect( mySelectionMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( onCancel() ) ); - myHelpFileName = "about_quality_controls_page.html"; + myHelpFileName = "quality_page.html"; } //================================================================================================= @@ -419,7 +481,7 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply() // Scalar Bar properties if (!myActor) return false; - vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); + SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty(); QColor aTColor = myTitleColorBtn->color(); @@ -450,7 +512,6 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply() myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp ); myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() ); - myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() ); if ( myHorizRadioBtn->isChecked() ) myScalarBarActor->SetOrientationToHorizontal(); @@ -461,13 +522,59 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply() myScalarBarActor->SetWidth( myWidthSpin->value() ); myScalarBarActor->SetHeight( myHeightSpin->value() ); + // Distribution + bool distributionTypeChanged = false, colorChanged=false; + myScalarBarActor->SetDistributionVisibility((int)myDistributionGrp->isChecked()); + if( myDistributionGrp->isChecked() ) { + int ColoringType = myDMultiColor->isChecked() ? SMESH_MULTICOLOR_TYPE : SMESH_MONOCOLOR_TYPE; + distributionTypeChanged = (ColoringType != myScalarBarActor->GetDistributionColoringType()); + if(distributionTypeChanged) + myScalarBarActor->SetDistributionColoringType(ColoringType); + + if( !myDMultiColor->isChecked() ) { + QColor aTColor = myMonoColorBtn->color(); + double rgb[3], oldRgb[3];; + rgb [0] = aTColor.red()/255.; + rgb [1] = aTColor.green()/255.; + rgb [2] = aTColor.blue()/255.; + myScalarBarActor->GetDistributionColor(oldRgb); + colorChanged = (rgb[0] != oldRgb[0] || rgb[1] != oldRgb[1] || rgb[2] != oldRgb[2]); + if(colorChanged) + myScalarBarActor->SetDistributionColor(rgb); + } + } + double aMin = myMinEdit->text().toDouble(); double aMax = myMaxEdit->text().toDouble(); vtkLookupTable* myLookupTable = static_cast(myScalarBarActor->GetLookupTable()); + double oldMinMax[2] = { myLookupTable->GetRange()[0], myLookupTable->GetRange()[1] }; + bool rangeChanges = ( fabs( oldMinMax[0] - aMin ) + fabs( oldMinMax[1] - aMax ) > + 0.001 * ( aMax-aMin + oldMinMax[1]-oldMinMax[0] )); + + bool nbColorsChanged = (myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors()); + if(nbColorsChanged) + myScalarBarActor->SetMaximumNumberOfColors(myColorsSpin->value()); + + myLookupTable->SetRange( aMin, aMax ); myLookupTable->SetNumberOfTableValues(myColorsSpin->value()); myLookupTable->Build(); + + if( nbColorsChanged || rangeChanges) + myActor->UpdateDistribution(); + +#ifndef DISABLE_PLOT2DVIEWER + if( myActor->GetPlot2Histogram() && + (nbColorsChanged || + rangeChanges || + distributionTypeChanged || + colorChanged )) + SMESH::ProcessIn2DViewers(myActor); +#endif + + + SMESH::RepaintCurrentView(); return true; } @@ -504,10 +611,10 @@ void SMESHGUI_Preferences_ScalarBarDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -528,56 +635,71 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged() if( anIO->hasEntry() ) { SMESH_Actor* anActor = SMESH::FindActorByEntry(anIO->getEntry()); if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) { - myActor = anActor; - vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); - - if ( myScalarBarActor->GetLookupTable() ) { - vtkFloatingPointType *range = myScalarBarActor->GetLookupTable()->GetRange(); - myMinEdit->setText( QString::number( range[0],'g',12 ) ); - myMaxEdit->setText( QString::number( range[1],'g',12 ) ); - } - - vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty(); - vtkFloatingPointType aTColor[3]; - aTitleTextPrp->GetColor( aTColor ); - myTitleColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) ); - myTitleFontCombo->setCurrentIndex( aTitleTextPrp->GetFontFamily() ); - myTitleBoldCheck->setChecked( aTitleTextPrp->GetBold() ); - myTitleItalicCheck->setChecked( aTitleTextPrp->GetItalic() ); - myTitleShadowCheck->setChecked( aTitleTextPrp->GetShadow() ); - - vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty(); - vtkFloatingPointType aLColor[3]; - aLabelsTextPrp->GetColor( aLColor ); - myLabelsColorBtn->setColor( QColor( (int)( aLColor[0]*255 ), (int)( aLColor[1]*255 ), (int)( aLColor[2]*255 ) ) ); - myLabelsFontCombo->setCurrentIndex( aLabelsTextPrp->GetFontFamily() ); - myLabelsBoldCheck->setChecked( aLabelsTextPrp->GetBold() ); - myLabelsItalicCheck->setChecked( aLabelsTextPrp->GetItalic() ); - myLabelsShadowCheck->setChecked( aLabelsTextPrp->GetShadow() ); - - myLabelsSpin->setValue( myScalarBarActor->GetNumberOfLabels() ); - myColorsSpin->setValue( myScalarBarActor->GetMaximumNumberOfColors() ); - - if ( myScalarBarActor->GetOrientation() == VTK_ORIENT_VERTICAL ) - myVertRadioBtn->setChecked( true ); - else - myHorizRadioBtn->setChecked( true ); - myIniOrientation = myVertRadioBtn->isChecked(); - - myIniX = myScalarBarActor->GetPosition()[0]; - myIniY = myScalarBarActor->GetPosition()[1]; - myIniW = myScalarBarActor->GetWidth(); - myIniH = myScalarBarActor->GetHeight(); - setOriginAndSize( myIniX, myIniY, myIniW, myIniH ); - - myRangeGrp->setEnabled( true ); - myFontGrp->setEnabled( true ); - myLabColorGrp->setEnabled( true ); - myOrientationGrp->setEnabled( true ); - myOriginDimGrp->setEnabled( true ); - myOkBtn->setEnabled( true ); - myApplyBtn->setEnabled( true ); - return; + myActor = anActor; + SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); + + if ( myScalarBarActor->GetLookupTable() ) { + vtkFloatingPointType *range = myScalarBarActor->GetLookupTable()->GetRange(); + myMinEdit->setText( QString::number( range[0],'g',12 ) ); + myMaxEdit->setText( QString::number( range[1],'g',12 ) ); + } + + vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty(); + vtkFloatingPointType aTColor[3]; + aTitleTextPrp->GetColor( aTColor ); + myTitleColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) ); + myTitleFontCombo->setCurrentIndex( aTitleTextPrp->GetFontFamily() ); + myTitleBoldCheck->setChecked( aTitleTextPrp->GetBold() ); + myTitleItalicCheck->setChecked( aTitleTextPrp->GetItalic() ); + myTitleShadowCheck->setChecked( aTitleTextPrp->GetShadow() ); + + vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty(); + vtkFloatingPointType aLColor[3]; + aLabelsTextPrp->GetColor( aLColor ); + myLabelsColorBtn->setColor( QColor( (int)( aLColor[0]*255 ), (int)( aLColor[1]*255 ), (int)( aLColor[2]*255 ) ) ); + myLabelsFontCombo->setCurrentIndex( aLabelsTextPrp->GetFontFamily() ); + myLabelsBoldCheck->setChecked( aLabelsTextPrp->GetBold() ); + myLabelsItalicCheck->setChecked( aLabelsTextPrp->GetItalic() ); + myLabelsShadowCheck->setChecked( aLabelsTextPrp->GetShadow() ); + + myLabelsSpin->setValue( myScalarBarActor->GetNumberOfLabels() ); + myColorsSpin->setValue( myScalarBarActor->GetMaximumNumberOfColors() ); + + if ( myScalarBarActor->GetOrientation() == VTK_ORIENT_VERTICAL ) + myVertRadioBtn->setChecked( true ); + else + myHorizRadioBtn->setChecked( true ); + myIniOrientation = myVertRadioBtn->isChecked(); + + myIniX = myScalarBarActor->GetPosition()[0]; + myIniY = myScalarBarActor->GetPosition()[1]; + myIniW = myScalarBarActor->GetWidth(); + myIniH = myScalarBarActor->GetHeight(); + setOriginAndSize( myIniX, myIniY, myIniW, myIniH ); + + int coloringType = myScalarBarActor->GetDistributionColoringType(); + myScalarBarActor->GetDistributionColor( aTColor ); + myMonoColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) ); + if ( coloringType == SMESH_MONOCOLOR_TYPE ) { + myDMonoColor->setChecked(true); + onDistributionChanged(myDistribColorGrp->id(myDMonoColor)); + } else { + myDMultiColor->setChecked(true); + onDistributionChanged(myDistribColorGrp->id(myDMultiColor)); + } + myDistributionGrp->setChecked((bool)myScalarBarActor->GetDistributionVisibility()); + onDistributionActivated(myScalarBarActor->GetDistributionVisibility()); + + + myRangeGrp->setEnabled( true ); + myFontGrp->setEnabled( true ); + myLabColorGrp->setEnabled( true ); + myOrientationGrp->setEnabled( true ); + myOriginDimGrp->setEnabled( true ); + myOkBtn->setEnabled( true ); + myApplyBtn->setEnabled( true ); + myDistributionGrp->setEnabled( true ); + return; } } } @@ -589,6 +711,7 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged() myOriginDimGrp->setEnabled( false ); myOkBtn->setEnabled( false ); myApplyBtn->setEnabled( false ); + myDistributionGrp->setEnabled( false ); } //================================================================================================= @@ -625,9 +748,9 @@ void SMESHGUI_Preferences_ScalarBarDlg::onXYChanged() */ //================================================================================================= void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x, - const double y, - const double w, - const double h ) + const double y, + const double w, + const double h ) { blockSignals( true ); myXSpin->setValue( x ); @@ -640,6 +763,42 @@ void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x, onXYChanged(); } + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged + * + * Called when coloring type of the distribution is changed + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged( int id ) { + + bool isActive = myDistribColorGrp->id(myDMonoColor) == id; + + myMonoColorBtn->setEnabled(isActive); + myDistributionColorLbl->setEnabled(isActive); +} +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onDistributionActivated + * + * Called when distribution group check box is changed + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onDistributionActivated(bool on) { + if(on) { + if(myDMonoColor->isChecked()) + onDistributionChanged(myDistribColorGrp->id(myDMonoColor) ); + else if(myDMultiColor->isChecked()) + onDistributionChanged(myDistribColorGrp->id(myDMultiColor) ); + } + else { + myMonoColorBtn->setEnabled(false); + myDistributionColorLbl->setEnabled(false); + } +} + + //================================================================================================= /*! * SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged @@ -656,9 +815,9 @@ void SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged() setOriginAndSize( myIniX, myIniY, myIniW, myIniH ); else setOriginAndSize( aOrientation ? DEF_VER_X : DEF_HOR_X, - aOrientation ? DEF_VER_Y : DEF_HOR_Y, - aOrientation ? DEF_VER_W : DEF_HOR_W, - aOrientation ? DEF_VER_H : DEF_HOR_H ); + aOrientation ? DEF_VER_Y : DEF_HOR_Y, + aOrientation ? DEF_VER_W : DEF_HOR_W, + aOrientation ? DEF_VER_H : DEF_HOR_H ); } //================================================================================================= diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h index 609631267..804b4aa6a 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Preferences_ScalarBarDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -39,11 +40,13 @@ class QLineEdit; class QPushButton; class QToolButton; class QRadioButton; -class QSpinBox; +class QButtonGroup; +class QLabel; class SMESHGUI; class SMESH_Actor; -class QtxDoubleSpinBox; +class SMESHGUI_SpinBox; +class SalomeApp_IntSpinBox; class QtxColorButton; class LightApp_SelectionMgr; @@ -63,9 +66,9 @@ public: void closeEvent( QCloseEvent* ); void setOriginAndSize( const double, - const double, - const double, - const double ); + const double, + const double, + const double ); void initScalarBarFromResources(); protected slots: @@ -76,6 +79,8 @@ protected slots: void onSelectionChanged(); void onXYChanged(); void onOrientationChanged(); + void onDistributionChanged( int ); + void onDistributionActivated( bool ); private: SMESHGUI* mySMESHGUI; @@ -103,20 +108,27 @@ private: QCheckBox* myLabelsShadowCheck; QGroupBox* myLabColorGrp; - QSpinBox* myColorsSpin; - QSpinBox* myLabelsSpin; + SalomeApp_IntSpinBox* myColorsSpin; + SalomeApp_IntSpinBox* myLabelsSpin; QGroupBox* myOrientationGrp; QRadioButton* myVertRadioBtn; QRadioButton* myHorizRadioBtn; QGroupBox* myOriginDimGrp; - QtxDoubleSpinBox* myXSpin; - QtxDoubleSpinBox* myYSpin; - QtxDoubleSpinBox* myWidthSpin; - QtxDoubleSpinBox* myHeightSpin; + SMESHGUI_SpinBox* myXSpin; + SMESHGUI_SpinBox* myYSpin; + SMESHGUI_SpinBox* myWidthSpin; + SMESHGUI_SpinBox* myHeightSpin; + + QGroupBox* myDistributionGrp; + QRadioButton* myDMonoColor; + QRadioButton* myDMultiColor; + QtxColorButton* myMonoColorBtn; + QLabel* myDistributionColorLbl; QGroupBox* myButtonGrp; + QButtonGroup* myDistribColorGrp; QPushButton* myOkBtn; QPushButton* myApplyBtn; QPushButton* myCancelBtn; diff --git a/src/SMESHGUI/SMESHGUI_PreviewDlg.cxx b/src/SMESHGUI/SMESHGUI_PreviewDlg.cxx new file mode 100644 index 000000000..0a9bf6842 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_PreviewDlg.cxx @@ -0,0 +1,125 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_PreviewDlg.cxx +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. +// SMESH includes +// + +//SMESH includes +#include "SMESHGUI.h" +#include "SMESHGUI_PreviewDlg.h" +#include "SMESHGUI_MeshEditPreview.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_Utils.h" + +//GUI includes +#include + +//QT includes +#include + + +//================================================================================= +// class : SMESHGUI_SMESHGUI_PreviewDlg() +// purpose : +//================================================================================= +SMESHGUI_PreviewDlg::SMESHGUI_PreviewDlg(SMESHGUI* theModule) : + mySMESHGUI(theModule), + QDialog(SMESH::GetDesktop( theModule )), + myIsApplyAndClose( false ) +{ + mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI )); +} + +//================================================================================= +// function : ~SMESHGUI_PreviewDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_PreviewDlg::~SMESHGUI_PreviewDlg() +{ + delete mySimulation; +} + +//================================================================================= +// function : showPreview +// purpose : Show preview in the viewer +//================================================================================= +void SMESHGUI_PreviewDlg::showPreview(){ + if(mySimulation) + mySimulation->SetVisibility(true); +} + +//================================================================================= +// function : hidePreview +// purpose : Hide preview in the viewer +//================================================================================= +void SMESHGUI_PreviewDlg::hidePreview(){ + if(mySimulation) + mySimulation->SetVisibility(false); +} + +//================================================================================= +// function : connectPreviewControl +// purpose : Connect the preview check box +//================================================================================= +void SMESHGUI_PreviewDlg::connectPreviewControl(){ + connect(myPreviewCheckBox, SIGNAL(toggled(bool)), this, SLOT(onDisplaySimulation(bool))); +} + + +//================================================================================= +// function : toDisplaySimulation +// purpose : +//================================================================================= +void SMESHGUI_PreviewDlg::toDisplaySimulation() { + onDisplaySimulation(true); +} + +//================================================================================= +// function : onDisplaySimulation +// purpose : +//================================================================================= +void SMESHGUI_PreviewDlg::onDisplaySimulation(bool toDisplayPreview) { + //Empty implementation here +} + +//================================================================ +// Function : setIsApplyAndClose +// Purpose : Set value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +void SMESHGUI_PreviewDlg::setIsApplyAndClose( const bool theFlag ) +{ + myIsApplyAndClose = theFlag; +} + +//================================================================ +// Function : isApplyAndClose +// Purpose : Get value of the flag indicating that the dialog is +// accepted by Apply & Close button +//================================================================ +bool SMESHGUI_PreviewDlg::isApplyAndClose() const +{ + return myIsApplyAndClose; +} diff --git a/src/SMESHGUI/SMESHGUI_PreviewDlg.h b/src/SMESHGUI/SMESHGUI_PreviewDlg.h new file mode 100644 index 000000000..f4731149f --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_PreviewDlg.h @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_RotationDlg.h +// Author : Roman NIKOLAEV, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_PREVIEWDLG_H +#define SMESHGUI_PREVIEWDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +class SMESHGUI; +class SMESHGUI_MeshEditPreview; +class QCheckBox; + +class SMESHGUI_EXPORT SMESHGUI_PreviewDlg : public QDialog { + Q_OBJECT +public: + SMESHGUI_PreviewDlg( SMESHGUI* ); + ~SMESHGUI_PreviewDlg(); + + void showPreview(); + void hidePreview(); + +protected: + void connectPreviewControl(); + + virtual void setIsApplyAndClose( const bool theFlag ); + virtual bool isApplyAndClose() const; + +protected slots: + void toDisplaySimulation(); + virtual void onDisplaySimulation( bool ); + + +protected: + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + SMESHGUI_MeshEditPreview* mySimulation; + QCheckBox* myPreviewCheckBox; + bool myIsApplyAndClose; +}; + +#endif diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx index 118d2d17c..f16f568fe 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RemoveElementsDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -122,6 +123,7 @@ SMESHGUI_RemoveElementsDlg SelectButtonC1A1->setIcon(image1); LineEditC1A1 = new QLineEdit(GroupC1); LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this)); + LineEditC1A1->setMaxLength(-1); QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 ); connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -204,7 +206,7 @@ void SMESHGUI_RemoveElementsDlg::Init() /* to close dialog if study change */ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)), - SLOT(onTextChange(const QString&))); + SLOT(onTextChange(const QString&))); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->SetSelectionMode(CellSelection); @@ -231,7 +233,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply() bool aResult = false; try { SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.inout()); + aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in()); } catch (const SALOME::SALOME_Exception& S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); myEditCurrentArgument->clear(); @@ -243,6 +245,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply() myEditCurrentArgument->clear(); mySelector->ClearIndex(); SMESH::UpdateView(); + SMESHGUI::Modified(); } } } @@ -291,10 +294,10 @@ void SMESHGUI_RemoveElementsDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -309,9 +312,6 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText) myNbOkElements = 0; - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // hilight entered elements if(myActor){ if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){ @@ -321,24 +321,20 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText) QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); for (int i = 0; i < aListId.count(); i++) { - if(const SMDS_MeshElement *anElem = aMesh->FindElement(aListId[i].toInt())) { - newIndices.Add(anElem->GetID()); - myNbOkElements++; - } + if(const SMDS_MeshElement *anElem = aMesh->FindElement(aListId[i].toInt())) { + newIndices.Add(anElem->GetID()); + myNbOkElements++; + } } mySelector->AddOrRemoveIndex(anIO,newIndices,false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight(anIO,true,true); + aViewWindow->highlight(anIO,true,true); } } - if (myNbOkElements) { - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); - } - myBusy = false; + updateButtons(); } //================================================================================= @@ -347,56 +343,52 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText) //================================================================================= void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument() { - if (myBusy) return; + if (myBusy) return; // busy + if (myFilterDlg && myFilterDlg->isVisible()) return; // filter digl active + if (!GroupButtons->isEnabled()) return; // inactive // clear - myNbOkElements = false; + myNbOkElements = 0; myActor = 0; myBusy = true; myEditCurrentArgument->setText(""); myBusy = false; - if (!GroupButtons->isEnabled()) // inactive - return; - - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // get selected mesh SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); int nbSel = aList.Extent(); - if (nbSel != 1) - return; - - Handle(SALOME_InteractiveObject) anIO = aList.First(); - myMesh = SMESH::GetMeshByIO(anIO); - if (myMesh->_is_nil()) - return; - - myActor = SMESH::FindActorByEntry(anIO->getEntry()); - if (!myActor) - return; - - // get selected nodes - QString aString = ""; - int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString); - if(nbElems < 1) - return; - myBusy = true; - myEditCurrentArgument->setText(aString); - myBusy = false; - - // OK - - myNbOkElements = nbElems; - - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); + if (nbSel == 1) { + + Handle(SALOME_InteractiveObject) anIO = aList.First(); + myMesh = SMESH::GetMeshByIO(anIO); + + if (!myMesh->_is_nil()) { + + myActor = SMESH::FindActorByEntry(anIO->getEntry()); + if (myActor) { + + // get selected nodes + QString aString = ""; + int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString); + if (nbElems > 0) { + myBusy = true; + myEditCurrentArgument->setText(aString); + myBusy = false; + + // OK + + myNbOkElements = nbElems; + } // if (nbElems > 0) + } // if (myActor) + } // if (!myMesh->_is_nil()) + } // if (nbSel == 1) { + + updateButtons(); } //================================================================================= @@ -410,8 +402,8 @@ void SMESHGUI_RemoveElementsDlg::SetEditCurrentArgument() case 0: /* default constructor */ { if(send == SelectButtonC1A1) { - LineEditC1A1->setFocus(); - myEditCurrentArgument = LineEditC1A1; + LineEditC1A1->setFocus(); + myEditCurrentArgument = LineEditC1A1; } SelectionIntoArgument(); break; @@ -507,6 +499,12 @@ void SMESHGUI_RemoveElementsDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_RemoveElementsDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL ); @@ -516,3 +514,13 @@ void SMESHGUI_RemoveElementsDlg::setFilters() myFilterDlg->show(); } + +//================================================================================= +// function : updateButtons +// purpose : enable / disable control buttons +//================================================================================= +void SMESHGUI_RemoveElementsDlg::updateButtons() +{ + buttonOk->setEnabled(myNbOkElements > 0); + buttonApply->setEnabled(myNbOkElements > 0); +} diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h index 7138acfe5..6cc8d5ae4 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RemoveElementsDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -106,6 +107,7 @@ private slots: void ActivateThisDialog(); void onTextChange( const QString& ); void setFilters(); + void updateButtons(); }; #endif // SMESHGUI_REMOVEELEMENTSDLG_H diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx index bf218290a..303aee6f6 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RemoveNodesDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -122,6 +123,7 @@ SMESHGUI_RemoveNodesDlg SelectButtonC1A1->setIcon(image1); LineEditC1A1 = new QLineEdit(GroupC1); LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this)); + LineEditC1A1->setMaxLength(-1); QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 ); connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); @@ -204,7 +206,7 @@ void SMESHGUI_RemoveNodesDlg::Init() /* to close dialog if study change */ connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)), - SLOT(onTextChange(const QString&))); + SLOT(onTextChange(const QString&))); SMESH::SetPointRepresentation(true); @@ -233,7 +235,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply() bool aResult = false; try { SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.inout()); + aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.in()); } catch (const SALOME::SALOME_Exception& S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); myEditCurrentArgument->clear(); @@ -245,6 +247,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply() myEditCurrentArgument->clear(); mySelector->ClearIndex(); SMESH::UpdateView(); + SMESHGUI::Modified(); } SMESH::SetPointRepresentation(true); @@ -297,10 +300,10 @@ void SMESHGUI_RemoveNodesDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -315,9 +318,6 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText) myNbOkNodes = 0; - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // hilight entered nodes if(myActor){ if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){ @@ -327,24 +327,20 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText) QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); for (int i = 0; i < aListId.count(); i++) { - if (const SMDS_MeshNode *aNode = aMesh->FindNode(aListId[i].toInt())) { - newIndices.Add(aNode->GetID()); - myNbOkNodes++; - } + if (const SMDS_MeshNode *aNode = aMesh->FindNode(aListId[i].toInt())) { + newIndices.Add(aNode->GetID()); + myNbOkNodes++; + } } mySelector->AddOrRemoveIndex(anIO,newIndices,false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight(anIO,true,true); + aViewWindow->highlight(anIO,true,true); } } - if (myNbOkNodes) { - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); - } - myBusy = false; + updateButtons(); } //================================================================================= @@ -353,56 +349,51 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText) //================================================================================= void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument() { - if (myBusy) return; - + if (myBusy) return; // busy + if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active + if (!GroupButtons->isEnabled()) return; // inactive + // clear - myNbOkNodes = false; + myNbOkNodes = 0; myActor = 0; myBusy = true; myEditCurrentArgument->setText(""); myBusy = false; - if (!GroupButtons->isEnabled()) // inactive - return; - - buttonOk->setEnabled(false); - buttonApply->setEnabled(false); - // get selected mesh SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); int nbSel = aList.Extent(); - if (nbSel != 1) - return; - - Handle(SALOME_InteractiveObject) anIO = aList.First(); - myMesh = SMESH::GetMeshByIO(anIO); - if (myMesh->_is_nil()) - return; - - myActor = SMESH::FindActorByEntry(anIO->getEntry()); - if (!myActor) - return; - - // get selected nodes - - QString aString = ""; - int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString); - if(nbNodes < 1) - return; - myBusy = true; - myEditCurrentArgument->setText(aString); - myBusy = false; - - // OK - - myNbOkNodes = true; - - buttonOk->setEnabled(true); - buttonApply->setEnabled(true); + if (nbSel == 1) { + + Handle(SALOME_InteractiveObject) anIO = aList.First(); + myMesh = SMESH::GetMeshByIO(anIO); + + if (!myMesh->_is_nil()) { + + myActor = SMESH::FindActorByEntry(anIO->getEntry()); + if (myActor) { + + // get selected nodes + QString aString = ""; + int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString); + if (nbNodes > 0) { + myBusy = true; + myEditCurrentArgument->setText(aString); + myBusy = false; + + // OK + + myNbOkNodes = nbNodes; + } // if (nbNodes > 0) + } // if (myActor) + } // if (!myMesh->_is_nil()) + } // if (nbSel == 1) + + updateButtons(); } //================================================================================= @@ -416,8 +407,8 @@ void SMESHGUI_RemoveNodesDlg::SetEditCurrentArgument() case 0: /* default constructor */ { if(send == SelectButtonC1A1) { - LineEditC1A1->setFocus(); - myEditCurrentArgument = LineEditC1A1; + LineEditC1A1->setFocus(); + myEditCurrentArgument = LineEditC1A1; } SelectionIntoArgument(); break; @@ -514,6 +505,12 @@ void SMESHGUI_RemoveNodesDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_RemoveNodesDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::NODE ); @@ -523,3 +520,13 @@ void SMESHGUI_RemoveNodesDlg::setFilters() myFilterDlg->show(); } + +//================================================================================= +// function : updateButtons +// purpose : enable / disable control buttons +//================================================================================= +void SMESHGUI_RemoveNodesDlg::updateButtons() +{ + buttonOk->setEnabled(myNbOkNodes > 0); + buttonApply->setEnabled(myNbOkNodes > 0); +} diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h index e26e963d3..75a7afed3 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h +++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RemoveNodesDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -106,6 +107,7 @@ private slots: void ActivateThisDialog(); void onTextChange( const QString& ); void setFilters(); + void updateButtons(); }; #endif // SMESHGUI_REMOVENODESDLG_H diff --git a/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx b/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx index 26a2614ac..278fe0b96 100644 --- a/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RenumberingDlg.cxx // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -78,14 +79,14 @@ SMESHGUI_RenumberingDlg::SMESHGUI_RenumberingDlg( SMESHGUI* theModule, const int setModal(false); setAttribute(Qt::WA_DeleteOnClose, true); setWindowTitle(unit == 0 ? - tr("SMESH_RENUMBERING_NODES_TITLE") : - tr("SMESH_RENUMBERING_ELEMENTS_TITLE")); + tr("SMESH_RENUMBERING_NODES_TITLE") : + tr("SMESH_RENUMBERING_ELEMENTS_TITLE")); setSizeGripEnabled(true); SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( mySMESHGUI ); QPixmap image0(resMgr->loadPixmap("SMESH", unit == 0 ? - tr("ICON_DLG_RENUMBERING_NODES") : - tr("ICON_DLG_RENUMBERING_ELEMENTS"))); + tr("ICON_DLG_RENUMBERING_NODES") : + tr("ICON_DLG_RENUMBERING_ELEMENTS"))); QPixmap image1(resMgr->loadPixmap("SMESH",tr("ICON_SELECT"))); QVBoxLayout* SMESHGUI_RenumberingDlgLayout = new QVBoxLayout(this); @@ -94,9 +95,9 @@ SMESHGUI_RenumberingDlg::SMESHGUI_RenumberingDlg( SMESHGUI* theModule, const int /***************************************************************/ GroupConstructors = new QGroupBox(unit == 0 ? - tr("SMESH_NODES") : - tr("SMESH_ELEMENTS"), - this); + tr("SMESH_NODES") : + tr("SMESH_ELEMENTS"), + this); myHelpFileName = unit == 0 ? "renumbering_nodes_and_elements_page.html#renumbering_nodes_anchor" : "renumbering_nodes_and_elements_page.html#renumbering_elements_anchor"; @@ -219,22 +220,22 @@ void SMESHGUI_RenumberingDlg::ClickOnApply() bool isUnitsLabeled = false; if (myUnit == 0 && anActor) { - isUnitsLabeled = anActor->GetPointsLabeled(); - if (isUnitsLabeled) anActor->SetPointsLabeled(false); + isUnitsLabeled = anActor->GetPointsLabeled(); + if (isUnitsLabeled) anActor->SetPointsLabeled(false); } else if (myUnit == 1 && anActor) { - isUnitsLabeled = anActor->GetCellsLabeled(); - if (isUnitsLabeled) anActor->SetCellsLabeled(false); + isUnitsLabeled = anActor->GetCellsLabeled(); + if (isUnitsLabeled) anActor->SetCellsLabeled(false); } SUIT_OverrideCursor aWaitCursor; if (myUnit == 0) { - aMeshEditor->RenumberNodes(); - if (isUnitsLabeled && anActor) anActor->SetPointsLabeled(true); + aMeshEditor->RenumberNodes(); + if (isUnitsLabeled && anActor) anActor->SetPointsLabeled(true); } else if (myUnit == 1) { - aMeshEditor->RenumberElements(); - if (isUnitsLabeled && anActor) anActor->SetCellsLabeled(true); + aMeshEditor->RenumberElements(); + if (isUnitsLabeled && anActor) anActor->SetCellsLabeled(true); } } catch(...) { @@ -242,6 +243,7 @@ void SMESHGUI_RenumberingDlg::ClickOnApply() //mySelectionMgr->clearSelected(); SMESH::UpdateView(); + SMESHGUI::Modified(); } } @@ -285,10 +287,10 @@ void SMESHGUI_RenumberingDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -316,7 +318,7 @@ void SMESHGUI_RenumberingDlg::SelectionIntoArgument() Handle(SALOME_InteractiveObject) IO = aList.First(); myMesh = SMESH::IObjectToInterface(IO); if (myMesh->_is_nil()) - aString = ""; + aString = ""; } } @@ -338,12 +340,12 @@ void SMESHGUI_RenumberingDlg::SetEditCurrentArgument() { case 0: /* default constructor */ { - if(send == SelectButton) { - LineEditMesh->setFocus(); - myEditCurrentArgument = LineEditMesh; - } - SelectionIntoArgument(); - break; + if(send == SelectButton) { + LineEditMesh->setFocus(); + myEditCurrentArgument = LineEditMesh; + } + SelectionIntoArgument(); + break; } } } diff --git a/src/SMESHGUI/SMESHGUI_RenumberingDlg.h b/src/SMESHGUI/SMESHGUI_RenumberingDlg.h index 95c9d4688..5ebbe6ca3 100644 --- a/src/SMESHGUI/SMESHGUI_RenumberingDlg.h +++ b/src/SMESHGUI/SMESHGUI_RenumberingDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RenumberingDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx new file mode 100644 index 000000000..cc5db9fe2 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx @@ -0,0 +1,852 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_ReorientFacesDlg.cxx +// Author : Edward AGAPOV, Open CASCADE S.A.S. +// SMESH includes +// +#include "SMESHGUI_ReorientFacesDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_SpinBox.h" +#include "SMESHGUI_MeshEditPreview.h" + +#include +#include +#include +#include +#include +#include + +// SALOME GEOM includes +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// SALOME KERNEL includes +#include + +// OCCT includes +#include +#include +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// VTK includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +// std +#include + +#define SPACING 6 +#define MARGIN 11 + +enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE, + EObject, EPoint, EFace, EDirection }; + +//======================================================================= +/*! + * \brief Dialog to reorient faces acoording to vector + */ +//======================================================================= + +SMESHGUI_ReorientFacesDlg::SMESHGUI_ReorientFacesDlg() + : SMESHGUI_Dialog( 0, false, true ) +{ + setWindowTitle(tr("CAPTION")); + + QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); + aDlgLay->setMargin(0); + aDlgLay->setSpacing(SPACING); + + QWidget* aMainFrame = createMainFrame (mainFrame()); + + aDlgLay->addWidget(aMainFrame); + + aDlgLay->setStretchFactor(aMainFrame, 1); +} + +//================================================================================ +/*! + * \brief Create frame containing dialog's input fields + */ +//================================================================================ + +QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) +{ + QWidget* aFrame = new QWidget(theParent); + + // constructors + + QPixmap iconReoriPoint (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_POINT"))); + QPixmap iconReoriFace (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_FACE"))); + + QGroupBox* aConstructorBox = new QGroupBox(tr("REORIENT_FACES"), aFrame); + myConstructorGrp = new QButtonGroup(aConstructorBox); + QHBoxLayout* aConstructorGrpLayout = new QHBoxLayout(aConstructorBox); + aConstructorGrpLayout->setMargin(MARGIN); + aConstructorGrpLayout->setSpacing(SPACING); + + QRadioButton* aPntBut = new QRadioButton(aConstructorBox); + aPntBut->setIcon(iconReoriPoint); + aPntBut->setChecked(true); + aConstructorGrpLayout->addWidget(aPntBut); + myConstructorGrp->addButton(aPntBut, CONSTRUCTOR_POINT); + + QRadioButton* aFaceBut= new QRadioButton(aConstructorBox); + aFaceBut->setIcon(iconReoriFace); + aConstructorGrpLayout->addWidget(aFaceBut); + myConstructorGrp->addButton(aFaceBut, CONSTRUCTOR_FACE); + + // Create other controls + + setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) ); + + createObject( tr("OBJECT") , aFrame, EObject ); + createObject( tr("POINT") , aFrame, EPoint ); + createObject( tr("FACE") , aFrame, EFace ); + createObject( tr("DIRECTION"), aFrame, EDirection ); + setNameIndication( EObject, OneName ); + setNameIndication( EFace, OneName ); + setReadOnly( EFace, false ); + if ( QLineEdit* le = qobject_cast( objectWg( EFace, Control ) )) + le->setValidator( new SMESHGUI_IdValidator( this,1 )); + + const int width = aFaceBut->fontMetrics().width( tr("DIRECTION")); + objectWg( EDirection, Label )->setFixedWidth( width ); + objectWg( EObject , Label )->setFixedWidth( width ); + objectWg( EPoint , Label )->setFixedWidth( width ); + objectWg( EFace , Label )->setFixedWidth( width ); + + QLabel* aXLabel = new QLabel(tr("SMESH_X"), aFrame); + myX = new SMESHGUI_SpinBox(aFrame); + QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aFrame); + myY = new SMESHGUI_SpinBox(aFrame); + QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aFrame); + myZ = new SMESHGUI_SpinBox(aFrame); + + myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myX->SetValue(0); + myY->SetValue(0); + myZ->SetValue(0); + + QLabel* aDXLabel = new QLabel(tr("SMESH_DX"), aFrame); + myDX = new SMESHGUI_SpinBox(aFrame); + QLabel* aDYLabel = new QLabel(tr("SMESH_DY"), aFrame); + myDY = new SMESHGUI_SpinBox(aFrame); + QLabel* aDZLabel = new QLabel(tr("SMESH_DZ"), aFrame); + myDZ = new SMESHGUI_SpinBox(aFrame); + myDX->SetValue(1); + myDY->SetValue(0); + myDZ->SetValue(0); + + myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + + // Layouting + + QGroupBox* anObjectGrp = new QGroupBox(tr("FACES"), aFrame); + QHBoxLayout* anObjectGrpLayout = new QHBoxLayout(anObjectGrp); + anObjectGrpLayout->setMargin(MARGIN); + anObjectGrpLayout->setSpacing(SPACING); + anObjectGrpLayout->addWidget( objectWg( EObject, Label )); + anObjectGrpLayout->addWidget( objectWg( EObject, Btn )); + anObjectGrpLayout->addWidget( objectWg( EObject, Control )); + + myPointFrm = new QFrame(aFrame); + QHBoxLayout* aPointGrpLayout = new QHBoxLayout(myPointFrm); + aPointGrpLayout->setMargin(0); + objectWg( EPoint, Control )->hide(); + aPointGrpLayout->addWidget( objectWg( EPoint, Label ) ); + aPointGrpLayout->addWidget( objectWg( EPoint, Btn ) ); + aPointGrpLayout->addWidget( aXLabel ); + aPointGrpLayout->addWidget( myX ); + aPointGrpLayout->addWidget( aYLabel ); + aPointGrpLayout->addWidget( myY ); + aPointGrpLayout->addWidget( aZLabel ); + aPointGrpLayout->addWidget( myZ ); + + myFaceFrm = new QFrame(aFrame); + QHBoxLayout* aFaceGrpLayout = new QHBoxLayout(myFaceFrm); + aFaceGrpLayout->setMargin(0); + aFaceGrpLayout->addWidget( objectWg( EFace, Label ) ); + aFaceGrpLayout->addWidget( objectWg( EFace, Btn ) ); + aFaceGrpLayout->addWidget( objectWg( EFace, Control ) ); + + QFrame* aDirectFrm = new QFrame(aFrame); + QHBoxLayout* aDirectGrpLayout = new QHBoxLayout(aDirectFrm); + aDirectGrpLayout->setMargin(0); + objectWg( EDirection, Control )->hide(); + aDirectGrpLayout->addWidget( objectWg( EDirection, Label ) ); + aDirectGrpLayout->addWidget( objectWg( EDirection, Btn ) ); + aDirectGrpLayout->addWidget(aDXLabel ); + aDirectGrpLayout->addWidget(myDX ); + aDirectGrpLayout->addWidget(aDYLabel ); + aDirectGrpLayout->addWidget(myDY ); + aDirectGrpLayout->addWidget(aDZLabel ); + aDirectGrpLayout->addWidget(myDZ ); + + + QGroupBox* anOrientGrp = new QGroupBox(tr("ORIENTATION"), aFrame); + QVBoxLayout* anOrientGrpLayout = new QVBoxLayout ( anOrientGrp ); + anOrientGrpLayout->addWidget(myPointFrm); + anOrientGrpLayout->addWidget(myFaceFrm); + anOrientGrpLayout->addWidget(aDirectFrm); + + + QVBoxLayout* aLay = new QVBoxLayout(aFrame); + aLay->addWidget(aConstructorBox); + aLay->addWidget(anObjectGrp); + aLay->addWidget(anOrientGrp); + + connect( myConstructorGrp, SIGNAL(buttonClicked (int)), this, SLOT(constructorChange(int))); + + return aFrame; +} + +//================================================================================ +/*! + * \brief Show point or face + */ +//================================================================================ + +void SMESHGUI_ReorientFacesDlg::constructorChange(int id) +{ + if ( id == CONSTRUCTOR_FACE ) + { + myPointFrm->hide(); + myFaceFrm->show(); + activateObject( EFace ); + } + else + { + myFaceFrm->hide(); + myPointFrm->show(); + activateObject( EPoint ); + } +} + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_ReorientFacesOp::SMESHGUI_ReorientFacesOp() + :SMESHGUI_SelectionOp( ActorSelection ) +{ + //myVectorPreview = 0; + myHelpFileName = "reorient_faces_page.html"; + + myDlg = new SMESHGUI_ReorientFacesDlg; + myDlg->constructorChange( CONSTRUCTOR_POINT ); + + // connect signals and slots + connect( myDlg->objectWg( EFace, LightApp_Dialog::Control ), SIGNAL(textChanged(const QString&)), + this, SLOT(onTextChange(const QString&))); + // 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->myDX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); + // connect(myDlg->myDY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); + // connect(myDlg->myDZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview())); + +} + +//======================================================================= +// function : startOperation() +// purpose : Init dialog fields, connect signals and slots, show dialog +//======================================================================= + +void SMESHGUI_ReorientFacesOp::startOperation() +{ + myObjectActor = 0; + + // init simulation with a current View + //if ( myVectorPreview ) delete myVectorPreview; + // myVectorPreview = 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); + // myVectorPreview->GetActor()->SetProperty(aProp); + // aProp->Delete(); + + SMESHGUI_SelectionOp::startOperation(); + + myDlg->show(); + + mySelectionMode = 0; + myDlg->activateObject( EObject ); +} + +//================================================================================ +/*! + * \brief Stops operation + */ +//================================================================================ + +void SMESHGUI_ReorientFacesOp::stopOperation() +{ + //myVectorPreview->SetVisibility(false); + if ( myObjectActor ) { + myObjectActor->SetPointRepresentation(false); + SMESH::RepaintCurrentView(); + myObjectActor = 0; + } + SMESHGUI_SelectionOp::stopOperation(); + myDlg->deactivateAll(); +} + +//================================================================================ +/*! + * \brief Set selection mode corresponding to a pressed selection button + */ +//================================================================================ + +void SMESHGUI_ReorientFacesOp::onActivateObject( int what ) +{ + if ( what == mySelectionMode ) + return; + mySelectionMode = what; + switch ( mySelectionMode ) + { + case EPoint: + case EDirection: + SMESH::SetPointRepresentation(true); + setSelectionMode( NodeSelection ); + SMESH::SetPickable(); + break; + case EObject: + SMESH::SetPointRepresentation(false); + setSelectionMode( ActorSelection ); + break; + case EFace: + SMESH::SetPointRepresentation(false); + setSelectionMode( FaceSelection ); + if ( myObjectActor ) + SMESH::SetPickable( myObjectActor ); + else + SMESH::SetPickable(); + break; + } + SMESHGUI_SelectionOp::onActivateObject( what ); +} + +//================================================================================ +/*! + * \brief Creates a filter corresponding to a pressed selection button + */ +//================================================================================ + +SUIT_SelectionFilter* SMESHGUI_ReorientFacesOp::createFilter( const int what ) const +{ + switch ( what ) + { + case EObject: + { + QList filters; + filters.append( new SMESH_TypeFilter( MESH )); + filters.append( new SMESH_TypeFilter( SUBMESH_FACE )); + filters.append( new SMESH_TypeFilter( GROUP_FACE )); + return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + } + case EPoint: + { + QList filters; + filters.append( new SMESH_TypeFilter( IDSOURCE )); + filters.append( new SMESH_NumberFilter( "GEOM",TopAbs_VERTEX, 1, TopAbs_VERTEX )); + return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + } + case EFace: + case EDirection: + { + return new SMESH_TypeFilter( IDSOURCE ); + } + } + return NULL; +} + +//================================================================================ +/*! + * \brief get data from selection + */ +//================================================================================ + +void SMESHGUI_ReorientFacesOp::selectionDone() +{ + if ( !myDlg->isVisible() || !myDlg->isEnabled() ) + return; + + myDlg->clearSelection( mySelectionMode ); + + SALOME_ListIO aList; + selectionMgr()->selectedObjects(aList); + const int nbSelected = aList.Extent(); + if ( nbSelected == 0 ) + return; + + Handle(SALOME_InteractiveObject) anIO = aList.First(); + + try + { + switch ( mySelectionMode ) + { + case EObject: { // get an actor of object + + if ( nbSelected == 1 ) + { + myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true ); + // typeById( aList.First()->getEntry(), + // SMESHGUI_SelectionOp::Object ), + myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() ); + } + break; + } + case EFace: { // get a face ID + + if ( nbSelected == 1 ) + { + TColStd_IndexedMapOfInteger faceIndices; + selector()->GetIndex( anIO, faceIndices ); + if ( faceIndices.Extent() == 1 ) + { + SMESH_Actor* savedActor = myObjectActor; + myObjectActor = 0; // to prevent work of onTextChange() + myDlg->setObjectText( EFace, QString("%1").arg( faceIndices(1) )); + myObjectActor = savedActor; + + if ( !myObjectActor ) + { + myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true ); + // typeById( aList.First()->getEntry(), + // SMESHGUI_SelectionOp::Object ), + myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() ); + } + } + } + break; + } + case EPoint: + case EDirection: { // set XYZ by selected nodes or vertices + + if ( mySelectionMode == EPoint && aList.Extent() > 1 ) + return; + + TColgp_SequenceOfXYZ points; + for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() ) + { + anIO = anIt.Value(); + GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface(anIO); + if ( !geom->_is_nil() ) { + TopoDS_Vertex aShape; + if ( GEOMBase::GetShape(geom, aShape) && aShape.ShapeType() == TopAbs_VERTEX ) { + gp_Pnt P = BRep_Tool::Pnt(aShape); + points.Append( P.XYZ() ); + } + } + else + { + TColStd_IndexedMapOfInteger nodeIndices; + selector()->GetIndex( anIO, nodeIndices ); + if ( nodeIndices.Extent() > 0 && nodeIndices.Extent() <=2 ) + { + if ( SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry())) + if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh()) + { + if (const SMDS_MeshNode* aNode = aMesh->FindNode( nodeIndices(1))) + points.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z())); + if ( nodeIndices.Extent() == 2 ) + if (const SMDS_MeshNode* aNode = aMesh->FindNode( nodeIndices(2))) + points.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z())); + } + } + } + } + gp_XYZ xyz; + if ( points.Length() == 1 ) + xyz = points(1); + else if ( points.Length() == 2 ) + xyz = points(2) - points(1); + else + return; + if ( points.Length() == 1 && mySelectionMode == EPoint ) + { + myDlg->myX->SetValue( xyz.X() ); + myDlg->myY->SetValue( xyz.Y() ); + myDlg->myZ->SetValue( xyz.Z() ); + redisplayPreview(); + } + if ( mySelectionMode == EDirection ) + { + myDlg->myDX->SetValue( xyz.X() ); + myDlg->myDY->SetValue( xyz.Y() ); + myDlg->myDZ->SetValue( xyz.Z() ); + redisplayPreview(); + } + break; + } // case EPoint || EDirection + } // switch + } + catch (...) + { + } +} + +//================================================================================ +/*! + * \brief SLOT called when the face id is changed + */ +//================================================================================ + +void SMESHGUI_ReorientFacesOp::onTextChange( const QString& theText ) +{ + if( myObjectActor ) + { + sender()->blockSignals( true ); + if ( mySelectionMode != EFace ) + { + myDlg->activateObject( EFace ); + myDlg->setObjectText( EFace, theText ); + } + TColStd_MapOfInteger ids; + if ( !theText.isEmpty() && theText.toInt() > 0 ) + ids.Add( theText.toInt() ); + + SMESHGUI_SelectionOp::addOrRemoveIndex( myObjectActor->getIO(), ids, false ); + SMESHGUI_SelectionOp::highlight( myObjectActor->getIO(), true, true ); + sender()->blockSignals( false ); + } +} + +//================================================================================ +/*! + * \brief perform it's intention action: reorient faces of myObject + */ +//================================================================================ + +bool SMESHGUI_ReorientFacesOp::onApply() +{ + if( isStudyLocked() ) + return false; + + QString msg; + if ( !isValid( msg ) ) { // node id is invalid + if( !msg.isEmpty() ) + SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ), msg ); + dlg()->show(); + return false; + } + + QStringList aParameters; + aParameters << myDlg->myDX->text(); + aParameters << myDlg->myDY->text(); + aParameters << myDlg->myDZ->text(); + aParameters << myDlg->myX->text(); + aParameters << myDlg->myY->text(); + aParameters << myDlg->myZ->text(); + + try { + SUIT_OverrideCursor wc; + SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh(); + if ( aMesh->_is_nil() ) return false; + + SMESH::DirStruct direction; + direction.PS.x = myDlg->myDX->GetValue(); + direction.PS.y = myDlg->myDY->GetValue(); + direction.PS.z = myDlg->myDZ->GetValue(); + + long face = myDlg->objectText( EFace ).toInt(); + if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_POINT ) + face = -1; + + SMESH::PointStruct point; + point.x = myDlg->myX->GetValue(); + point.y = myDlg->myY->GetValue(); + point.z = myDlg->myZ->GetValue(); + + SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); + if (aMeshEditor->_is_nil()) return false; + + aMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + + int aResult = aMeshEditor->Reorient2D( myObject, direction, face, point ); + if (aResult) + { + SALOME_ListIO aList; + selectionMgr()->setSelectedObjects(aList,false); + SMESH::UpdateView(); + SMESHGUI::Modified(); + } + wc.suspend(); + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), + tr("NB_REORIENTED").arg(aResult)); + } + catch (const SALOME::SALOME_Exception& S_ex) { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + catch (...) { + } + + return true; +} + +//================================================================================ +/*! + * \brief Check data validity + */ +//================================================================================ + +bool SMESHGUI_ReorientFacesOp::isValid( QString& msg ) +{ + // check object + QString objectEntry = myDlg->selectedObject( EObject ); + _PTR(SObject) pSObject = studyDS()->FindObjectID( objectEntry.toLatin1().data() ); + myObject = SMESH::SMESH_IDSource::_narrow( _CAST( SObject,pSObject )->GetObject() ); + if ( myObject->_is_nil() ) + { + msg = tr("NO_OBJECT_SELECTED"); + return false; + } + bool hasFaces = false; + SMESH::array_of_ElementType_var types = myObject->GetTypes(); + for ( size_t i = 0; i < types->length() && !hasFaces; ++i ) + hasFaces = ( types[i] == SMESH::FACE ); + if ( !hasFaces ) + { + msg = tr("NO_FACES"); + return false; + } + + // check vector + gp_Vec vec( myDlg->myDX->GetValue(), + myDlg->myDY->GetValue(), + myDlg->myDZ->GetValue() ); + if ( vec.Magnitude() < std::numeric_limits::min() ) + { + msg = tr("ZERO_SIZE_VECTOR"); + return false; + } + + // check face ID + if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_FACE ) + { + int faceID = myDlg->objectText( EFace ).toInt(); + bool faceOK = ( faceID > 0 ); + if ( faceOK ) + { + if ( myObjectActor ) + { + faceOK = ( myObjectActor->GetObject()->GetElemDimension( faceID ) == 2 ); + } + else + { + SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh(); + if ( !aMesh->_is_nil() ) + faceOK = ( aMesh->GetElementType( faceID, true ) == SMESH::FACE ); + } + } + if ( !faceOK ) + { + msg = tr("INVALID_FACE"); + return false; + } + } + + return true; +} + +//================================================================================ +/*! + * \brief Destructor +*/ +//================================================================================ + +SMESHGUI_ReorientFacesOp::~SMESHGUI_ReorientFacesOp() +{ + if ( myDlg ) delete myDlg; + //if ( myVectorPreview ) delete myVectorPreview; +} + +//================================================================================ +/*! + * \brief Gets dialog of this operation + * \retval LightApp_Dialog* - pointer to dialog of this operation + */ +//================================================================================ + +LightApp_Dialog* SMESHGUI_ReorientFacesOp::dlg() const +{ + return myDlg; +} + +//================================================================================ +/*! + * \brief update preview + */ +//================================================================================ + +void SMESHGUI_ReorientFacesOp::redisplayPreview() +{ +// SMESH::MeshPreviewStruct_var aMeshPreviewStruct; + +// bool moveShown = false; +// if ( myObjectActor) +// { +// const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked(); +// const bool preview = myDlg->myPreviewChkBox->isChecked(); +// if ( autoSearch ) +// { +// myDlg->myCurrentX->SetValue(0); +// myDlg->myCurrentY->SetValue(0); +// myDlg->myCurrentZ->SetValue(0); +// myDlg->myDX->SetValue(0); +// myDlg->myDY->SetValue(0); +// myDlg->myDZ->SetValue(0); +// myDlg->myId->setText(""); +// } +// QString msg; +// if ( autoSearch || isValid( msg ) ) +// { +// try { +// SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myObjectActor->getIO()); +// if (!aMesh->_is_nil()) { +// SMESH::SMESH_MeshEditor_var aPreviewer = aMesh->GetMeshEditPreviewer(); +// if (!aPreviewer->_is_nil()) +// { +// SUIT_OverrideCursor aWaitCursor; + +// int anId = 0; +// if ( autoSearch ) +// anId = aPreviewer->FindNodeClosestTo(myDlg->myX->GetValue(), +// myDlg->myY->GetValue(), +// myDlg->myZ->GetValue()); +// else +// anId = myDlg->myId->text().toInt(); + +// // find id and/or just compute preview +// aPreviewer->MoveNode(anId, +// myDlg->myX->GetValue(), +// myDlg->myY->GetValue(), +// myDlg->myZ->GetValue()); +// if ( autoSearch ) { // set found id +// QString idTxt("%1"); +// if ( anId > 0 ) +// idTxt = idTxt.arg( anId ); +// else +// idTxt = ""; +// myDlg->myId->setText( idTxt ); +// } + +// SMESH::double_array* aXYZ = aMesh->GetNodeXYZ( anId ); +// if( aXYZ && aXYZ->length() >= 3 ) +// { +// double x = aXYZ->operator[](0); +// double y = aXYZ->operator[](1); +// double z = aXYZ->operator[](2); +// double dx = myDlg->myX->GetValue() - x; +// double dy = myDlg->myY->GetValue() - y; +// double dz = myDlg->myZ->GetValue() - z; +// myDlg->myCurrentX->SetValue(x); +// myDlg->myCurrentY->SetValue(y); +// myDlg->myCurrentZ->SetValue(z); +// myDlg->myDX->SetValue(dx); +// myDlg->myDY->SetValue(dy); +// myDlg->myDZ->SetValue(dz); +// } + +// if ( preview ) { // fill preview data +// aMeshPreviewStruct = aPreviewer->GetPreviewData(); +// moveShown = ( anId > 0 ); +// } +// } +// } +// }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->() ) +// { +// myVectorPreview->SetData(aMeshPreviewStruct._retn()); +// } +// else +// { +// myVectorPreview->SetVisibility(false); +// } + +} diff --git a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h new file mode 100644 index 000000000..aaea78340 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h @@ -0,0 +1,118 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESHGUI_ReorientFacesDlg.h +// Author : Edward AGAPOV, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_ReorientFacesDlg_H +#define SMESHGUI_ReorientFacesDlg_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +#include "SMESHGUI_Dialog.h" +#include "SMESHGUI_SelectionOp.h" + +class QButtonGroup; +class QLineEdit; +class SMESHGUI_SpinBox; +class SMESHGUI_ReorientFacesDlg; + +/*! + * \brief Operation to reorient faces acoording to vector + */ +class SMESHGUI_EXPORT SMESHGUI_ReorientFacesOp: public SMESHGUI_SelectionOp +{ + Q_OBJECT + +public: + SMESHGUI_ReorientFacesOp(); + virtual ~SMESHGUI_ReorientFacesOp(); + + virtual LightApp_Dialog* dlg() const; + +protected: + + virtual void startOperation(); + virtual void stopOperation(); + + virtual SUIT_SelectionFilter* createFilter( const int ) const; + virtual void selectionDone(); + + bool isValid( QString& ); + +protected slots: + virtual bool onApply(); + +private slots: + virtual void onActivateObject( int ); + void redisplayPreview(); + void onTextChange( const QString& ); + +private: + SMESHGUI_ReorientFacesDlg* myDlg; + + //SMESHGUI_MeshEditPreview* myVectorPreview; + SMESH_Actor* myObjectActor; + int mySelectionMode; + + SMESH::SMESH_IDSource_var myObject; +}; + +/*! + * \brief Dialog to reorient faces acoording to vector + */ + +class SMESHGUI_EXPORT SMESHGUI_ReorientFacesDlg : public SMESHGUI_Dialog +{ + Q_OBJECT + +public: + SMESHGUI_ReorientFacesDlg(); + +public slots: + void constructorChange(int id); + +private: + QWidget* createMainFrame( QWidget* ); + + QButtonGroup* myConstructorGrp; + QFrame* myFaceFrm; + QFrame* myPointFrm; + SMESHGUI_SpinBox* myX; + SMESHGUI_SpinBox* myY; + SMESHGUI_SpinBox* myZ; + //QPushButton* myIdBtn; + //QLineEdit* myId; + SMESHGUI_SpinBox* myDX; + SMESHGUI_SpinBox* myDY; + SMESHGUI_SpinBox* myDZ; + + QString myHelpFileName; + + friend class SMESHGUI_ReorientFacesOp; + + //private slots: + //void ButtonToggled( bool ); +}; + +#endif // SMESHGUI_ReorientFacesDlg_H diff --git a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx index 355e01ec3..2d198bb68 100644 --- a/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RevolutionDlg.cxx // Author : Michael ZORIN, Open CASCADE S.A.S. // SMESH includes -// + #include "SMESHGUI_RevolutionDlg.h" #include "SMESHGUI.h" @@ -88,12 +89,12 @@ // purpose : //================================================================================= SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule ) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), + : SMESHGUI_PreviewDlg( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), myVectorDefinition(NONE_SELECT), myFilterDlg( 0 ), - mySelectedObject(SMESH::SMESH_IDSource::_nil()) + mySelectedObject(SMESH::SMESH_IDSource::_nil()), + myActor(0) { mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI )); @@ -144,8 +145,9 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule ) LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); - QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); - connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + LineEditElements->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); // Control for the whole mesh selection CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); @@ -229,7 +231,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule ) SpinBox_Tolerance = new SMESHGUI_SpinBox(GroupArguments); // Control for mesh preview - CheckBoxPreview = new QCheckBox(tr("PREVIEW"), GroupArguments); + myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); // CheckBox for groups generation MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments); @@ -238,13 +240,13 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule ) GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 2); - GroupArgumentsLayout->addWidget(filterBtn, 0, 3); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 3); GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4); GroupArgumentsLayout->addWidget(GroupAxis, 2, 0, 1, 4); GroupArgumentsLayout->addWidget(GroupAngleBox, 3, 0, 1, 4); GroupArgumentsLayout->addWidget(TextLabelTolerance, 4, 0, 1, 2); GroupArgumentsLayout->addWidget(SpinBox_Tolerance, 4, 2, 1, 2); - GroupArgumentsLayout->addWidget(CheckBoxPreview, 5, 0, 1, 4); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 5, 0, 1, 4); GroupArgumentsLayout->addWidget(MakeGroupsCheck, 6, 0, 1, 4); /***************************************************************/ @@ -277,20 +279,20 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule ) SMESHGUI_RevolutionDlgLayout->addWidget(GroupButtons); /* Initialisations */ - SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); + SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); RadioButton3->setChecked(true); - SpinBox_Angle->RangeStepAndValidator(COORD_MIN, COORD_MAX, 5.0, 3); + SpinBox_Angle->RangeStepAndValidator(COORD_MIN, COORD_MAX, 5.0, "angle_precision"); SpinBox_NbSteps->setRange(1, 999999); - SpinBox_Tolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, 6); + SpinBox_Tolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision"); RadioButton1->setChecked(true); @@ -349,7 +351,9 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule ) connect(SpinBox_Angle, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); connect(SpinBox_NbSteps, SIGNAL(valueChanged(int)), this, SLOT(toDisplaySimulation())); connect(SpinBox_Tolerance, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); - connect(CheckBoxPreview, SIGNAL(toggled(bool)), this, SLOT(onDisplaySimulation(bool))); + + //To Connect preview check box + connectPreviewControl(); connect(SpinBox_Angle, SIGNAL(textChanged(const QString&)), this, SLOT(onAngleTextChange(const QString&))); @@ -383,6 +387,7 @@ void SMESHGUI_RevolutionDlg::Init (bool ResetControls) LineEditElements->clear(); myElementsId = ""; myNbOkElements = 0; + myIDs.clear(); myActor = 0; myMesh = SMESH::SMESH_Mesh::_nil(); @@ -401,7 +406,7 @@ void SMESHGUI_RevolutionDlg::Init (bool ResetControls) CheckBoxMesh->setChecked(false); onSelectMesh(false); - CheckBoxPreview->setChecked(false); + myPreviewCheckBox->setChecked(false); onDisplaySimulation(false); } } @@ -412,14 +417,13 @@ void SMESHGUI_RevolutionDlg::Init (bool ResetControls) //================================================================================= void SMESHGUI_RevolutionDlg::ConstructorsClicked (int constructorId) { - //disconnect(mySelectionMgr, 0, this, 0); + disconnect(mySelectionMgr, 0, this, 0); - SALOME_ListIO io; + /* SALOME_ListIO io; mySelectionMgr->selectedObjects( io ); SALOME_ListIO aList; - mySelectionMgr->setSelectedObjects( aList ); -// LineEditElements->clear(); - myNbOkElements = 0; + mySelectionMgr->setSelectedObjects( aList );*/ + buttonApply->setEnabled(false); buttonOk->setEnabled(false); mySimulation->SetVisibility(false); @@ -447,8 +451,11 @@ void SMESHGUI_RevolutionDlg::ConstructorsClicked (int constructorId) if (!CheckBoxMesh->isChecked()) { + LineEditElements->clear(); + myIDs.clear(); + myNbOkElements = 0; if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(aSelMode); + aViewWindow->SetSelectionMode(aSelMode); } myEditCurrentArgument = (QWidget*)LineEditElements; @@ -457,8 +464,8 @@ void SMESHGUI_RevolutionDlg::ConstructorsClicked (int constructorId) if (CheckBoxMesh->isChecked()) onSelectMesh(true); - //connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - mySelectionMgr->setSelectedObjects( io ); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + // mySelectionMgr->setSelectedObjects( io ); } //================================================================================= @@ -491,7 +498,7 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply() anAxis.vy = SpinBox_DY->GetValue(); anAxis.vz = SpinBox_DZ->GetValue(); - double anAngle = (SpinBox_Angle->GetValue())*PI/180; + double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.; long aNbSteps = (long)SpinBox_NbSteps->value(); double aTolerance = SpinBox_Tolerance->GetValue(); @@ -513,44 +520,48 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply() SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) { if( CheckBoxMesh->isChecked() ) { - if( GetConstructorId() == 0 ) - SMESH::ListOfGroups_var groups = - aMeshEditor->RotationSweepObject1DMakeGroups(mySelectedObject, anAxis, - anAngle, aNbSteps, aTolerance); - else - SMESH::ListOfGroups_var groups = - aMeshEditor->RotationSweepObject2DMakeGroups(mySelectedObject, anAxis, - anAngle, aNbSteps, aTolerance); - } - else - SMESH::ListOfGroups_var groups = - aMeshEditor->RotationSweepMakeGroups(anElementsId.inout(), anAxis, - anAngle, aNbSteps, aTolerance); + if( GetConstructorId() == 0 ) + SMESH::ListOfGroups_var groups = + aMeshEditor->RotationSweepObject1DMakeGroups(mySelectedObject, anAxis, + anAngle, aNbSteps, aTolerance); + else + SMESH::ListOfGroups_var groups = + aMeshEditor->RotationSweepObject2DMakeGroups(mySelectedObject, anAxis, + anAngle, aNbSteps, aTolerance); + } + else + SMESH::ListOfGroups_var groups = + aMeshEditor->RotationSweepMakeGroups(anElementsId.inout(), anAxis, + anAngle, aNbSteps, aTolerance); } else { if( CheckBoxMesh->isChecked() ) { - if( GetConstructorId() == 0 ) - aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance); - else - aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance); - } - else - aMeshEditor->RotationSweep(anElementsId.inout(), anAxis, anAngle, aNbSteps, aTolerance); + if( GetConstructorId() == 0 ) + aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance); + else + aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance); + } + else + aMeshEditor->RotationSweep(anElementsId.inout(), anAxis, anAngle, aNbSteps, aTolerance); } - myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); } catch (...) { } SMESH::UpdateView(); + SMESH::Update(myIO, SMESH::eDisplay); if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) mySMESHGUI->updateObjBrowser(true); // new groups may appear Init(false); ConstructorsClicked(GetConstructorId()); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; @@ -572,19 +583,14 @@ void SMESHGUI_RevolutionDlg::ClickOnOk() //================================================================================= void SMESHGUI_RevolutionDlg::ClickOnCancel() { - disconnect(mySelectionMgr, 0, this, 0); - mySelectionMgr->clearFilters(); - //mySelectionMgr->clearSelected(); - if (SMESH::GetCurrentVtkView()) { - SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters - SMESH::SetPointRepresentation(false); - } - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - mySMESHGUI->ResetState(); reject(); } +void SMESHGUI_RevolutionDlg::reject() +{ + close(); +} + //================================================================================= // function : ClickOnHelp() // purpose : @@ -602,10 +608,10 @@ void SMESHGUI_RevolutionDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -653,15 +659,15 @@ void SMESHGUI_RevolutionDlg::onTextChange (const QString& theNewText) QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); for (int i = 0; i < aListId.count(); i++) { - const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); - if (e) - newIndices.Add(e->GetID()); - myNbOkElements++; + const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); + if (e) + newIndices.Add(e->GetID()); + myNbOkElements++; } mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( myActor->getIO(), true, true ); + aViewWindow->highlight( myActor->getIO(), true, true ); myElementsId = theNewText; } @@ -685,7 +691,6 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument() if (myBusy) return; // clear - myActor = 0; QString aString = ""; myBusy = true; @@ -704,24 +709,27 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument() const SALOME_ListIO& aList = mySelector->StoredIObjects(); int nbSel = aList.Extent(); - if (nbSel != 1) + if (nbSel != 1) return; Handle(SALOME_InteractiveObject) IO = aList.First(); - myMesh = SMESH::GetMeshByIO(IO); - if (myMesh->_is_nil()) + SMESH::SMESH_Mesh_var aMeshVar = SMESH::GetMeshByIO(IO); + if (aMeshVar->_is_nil()) return; - myActor = SMESH::FindActorByObject(myMesh); - if (!myActor) - myActor = SMESH::FindActorByEntry(IO->getEntry()); - if (!myActor) + SMESH_Actor* anActor = SMESH::FindActorByObject(aMeshVar); + if (!anActor) + anActor = SMESH::FindActorByEntry(IO->getEntry()); + if (!anActor && !CheckBoxMesh->isChecked()) return; int aNbUnits = 0; if (myEditCurrentArgument == (QWidget*)LineEditElements) { myElementsId = ""; + myMesh = aMeshVar; + myActor = anActor; + myIO = IO; // MakeGroups is available if there are groups if ( myMesh->NbGroups() == 0 ) { @@ -742,12 +750,12 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument() aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString); myElementsId = aString; if (aNbUnits < 1) - return; + return; } myNbOkElements = true; } else { - SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); + SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); if (!aMesh) return; @@ -832,20 +840,20 @@ void SMESHGUI_RevolutionDlg::SetEditCurrentArgument() SMESH::SetPointRepresentation(false); if (CheckBoxMesh->isChecked()) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); + aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); } else { int aConstructorId = GetConstructorId(); if (aConstructorId == 0) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - } + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); + } else if (aConstructorId == 1) - { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - } + { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + } } } else if (send == SelectPointButton) { myEditCurrentArgument = (QWidget*)SpinBox_X; @@ -909,17 +917,16 @@ void SMESHGUI_RevolutionDlg::enterEvent (QEvent*) void SMESHGUI_RevolutionDlg::closeEvent (QCloseEvent*) { /* same than click on cancel button */ - ClickOnCancel(); -} - -//======================================================================= -// function : hideEvent() -// purpose : caused by ESC key -//======================================================================= -void SMESHGUI_RevolutionDlg::hideEvent (QHideEvent*) -{ - if (!isMinimized()) - ClickOnCancel(); + disconnect(mySelectionMgr, 0, this, 0); + mySelectionMgr->clearFilters(); + //mySelectionMgr->clearSelected(); + if (SMESH::GetCurrentVtkView()) { + SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters + SMESH::SetPointRepresentation(false); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySMESHGUI->ResetState(); } //======================================================================= @@ -928,10 +935,13 @@ void SMESHGUI_RevolutionDlg::hideEvent (QHideEvent*) //======================================================================= void SMESHGUI_RevolutionDlg::onSelectMesh (bool toSelectMesh) { - if (toSelectMesh) + if (toSelectMesh) { + myIDs = LineEditElements->text(); TextLabelElements->setText(tr("SMESH_NAME")); + } else TextLabelElements->setText(tr("SMESH_ID_ELEMENTS")); + myFilterBtn->setEnabled(!toSelectMesh); if (myEditCurrentArgument != LineEditElements) { LineEditElements->clear(); @@ -952,13 +962,13 @@ void SMESHGUI_RevolutionDlg::onSelectMesh (bool toSelectMesh) int aConstructorId = GetConstructorId(); if (aConstructorId == 0) { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(EdgeSelection); } - else if (aConstructorId == 0) + else if (aConstructorId == 1) { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); } LineEditElements->setReadOnly(false); @@ -968,6 +978,9 @@ void SMESHGUI_RevolutionDlg::onSelectMesh (bool toSelectMesh) } SelectionIntoArgument(); + + if (!toSelectMesh) + LineEditElements->setText( myIDs ); } //================================================================================= @@ -986,8 +999,8 @@ int SMESHGUI_RevolutionDlg::GetConstructorId() bool SMESHGUI_RevolutionDlg::IsAxisOk() { return (SpinBox_DX->GetValue() != 0 || - SpinBox_DY->GetValue() != 0 || - SpinBox_DZ->GetValue() != 0); + SpinBox_DY->GetValue() != 0 || + SpinBox_DZ->GetValue() != 0); } //================================================================================= @@ -1022,22 +1035,13 @@ void SMESHGUI_RevolutionDlg::keyPressEvent( QKeyEvent* e ) } } -//================================================================================= -// function : toDisplaySimulation() -// purpose : -//================================================================================= -void SMESHGUI_RevolutionDlg::toDisplaySimulation() -{ - onDisplaySimulation(true); -} - //================================================================================= // function : onDisplaySimulation() -// purpose : +// purpose : Show/Hide preview //================================================================================= void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview) { - if (CheckBoxPreview->isChecked() && toDisplayPreview) + if (myPreviewCheckBox->isChecked() && toDisplayPreview) { //display preview if (myNbOkElements && IsAxisOk()) @@ -1048,7 +1052,7 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview) anElementsId->length(aListElementsId.count()); for (int i = 0; i < aListElementsId.count(); i++) - anElementsId[i] = aListElementsId[i].toInt(); + anElementsId[i] = aListElementsId[i].toInt(); SMESH::AxisStruct anAxis; @@ -1058,33 +1062,33 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview) anAxis.vx = SpinBox_DX->GetValue(); anAxis.vy = SpinBox_DY->GetValue(); anAxis.vz = SpinBox_DZ->GetValue(); - - double anAngle = (SpinBox_Angle->GetValue())*PI/180; + + double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.; long aNbSteps = (long)SpinBox_NbSteps->value(); double aTolerance = SpinBox_Tolerance->GetValue(); if (GroupAngle->checkedId() == 1) - anAngle = anAngle/aNbSteps; + anAngle = anAngle/aNbSteps; try { - SUIT_OverrideCursor aWaitCursor; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); if( CheckBoxMesh->isChecked() ) { - if( GetConstructorId() == 0 ) - aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis, - anAngle, aNbSteps, aTolerance); - else - aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis, - anAngle, aNbSteps, aTolerance); - } - else - aMeshEditor->RotationSweep(anElementsId.inout(), - anAxis, - anAngle, - aNbSteps, - aTolerance); - SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); - mySimulation->SetData(aMeshPreviewStruct._retn()); + if( GetConstructorId() == 0 ) + aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis, + anAngle, aNbSteps, aTolerance); + else + aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis, + anAngle, aNbSteps, aTolerance); + } + else + aMeshEditor->RotationSweep(anElementsId.inout(), + anAxis, + anAngle, + aNbSteps, + aTolerance); + SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); + mySimulation->SetData(aMeshPreviewStruct._retn()); } catch (...) {} } else @@ -1117,6 +1121,8 @@ void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action){ if(!action) return; + disconnect(mySelectionMgr, 0, this, 0); + switch(myMenuActions[action]) { case POINT_SELECT: SMESH::SetPointRepresentation(true); @@ -1144,6 +1150,12 @@ void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action){ //================================================================================= void SMESHGUI_RevolutionDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) { QList types; diff --git a/src/SMESHGUI/SMESHGUI_RevolutionDlg.h b/src/SMESHGUI/SMESHGUI_RevolutionDlg.h index a4c3fc111..91d1e4268 100644 --- a/src/SMESHGUI/SMESHGUI_RevolutionDlg.h +++ b/src/SMESHGUI/SMESHGUI_RevolutionDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RevolutionDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -28,9 +29,12 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" +#include "SMESHGUI_PreviewDlg.h" + +// SALOME GUI includes +#include // Qt includes -#include #include // IDL includes @@ -62,7 +66,7 @@ class QAction; // class : SMESHGUI_RevolutionDlg // purpose : //================================================================================= -class SMESHGUI_EXPORT SMESHGUI_RevolutionDlg : public QDialog +class SMESHGUI_EXPORT SMESHGUI_RevolutionDlg : public SMESHGUI_PreviewDlg { Q_OBJECT @@ -70,26 +74,27 @@ public: SMESHGUI_RevolutionDlg( SMESHGUI* ); ~SMESHGUI_RevolutionDlg(); + void reject(); + private: enum {NONE_SELECT, POINT_SELECT, FACE_SELECT}; void Init( bool = true); void closeEvent( QCloseEvent* ); void enterEvent( QEvent* ); /* mouse enter the QWidget */ - void hideEvent( QHideEvent* ); /* ESC key */ void keyPressEvent( QKeyEvent* ); int GetConstructorId(); bool IsAxisOk(); bool isValid(); - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ SMESHGUI_IdValidator* myIdValidator; LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ int myNbOkElements; /* to check when elements are defined */ QString myElementsId; QWidget* myEditCurrentArgument; /* Current argument */ SVTK_Selector* mySelector; + Handle(SALOME_InteractiveObject) myIO; SMESH::SMESH_IDSource_var mySelectedObject; @@ -120,7 +125,6 @@ private: QButtonGroup* GroupAngle; QRadioButton* RadioButton3; QRadioButton* RadioButton4; - QCheckBox* CheckBoxPreview; QLabel* TextLabelPoint; QPushButton* SelectPointButton; @@ -152,8 +156,13 @@ private: QString myHelpFileName; + QString myIDs; + QPushButton* myFilterBtn; SMESHGUI_FilterDlg* myFilterDlg; + +protected slots: + virtual void onDisplaySimulation( bool ); private slots: void ConstructorsClicked( int ); @@ -169,8 +178,6 @@ private slots: void onAngleTextChange( const QString& ); void onSelectMesh( bool ); void onVectorChanged(); - void toDisplaySimulation(); - void onDisplaySimulation( bool ); void onSelectVectorMenu( QAction* ); void onSelectVectorButton(); void setFilters(); diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx index 1e7010974..f257c3c87 100644 --- a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_RotationDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI_RotationDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes + #include "SMESHGUI_RotationDlg.h" #include "SMESHGUI.h" @@ -33,6 +32,7 @@ #include "SMESHGUI_MeshUtils.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_MeshEditPreview.h" #include #include @@ -83,13 +83,16 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action #define SPACING 8 #define MARGIN 11 +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + //================================================================================= // class : SMESHGUI_RotationDlg() // purpose : //================================================================================= -SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), +SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) : + SMESHGUI_PreviewDlg( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), myFilterDlg(0), mySelectedObject(SMESH::SMESH_IDSource::_nil()) @@ -133,8 +136,9 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) SelectElementsButton->setIcon(image1); LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); - QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); - connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + LineEditElements->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); // Control for the whole mesh selection CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); @@ -212,10 +216,14 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) // Name of a mesh to create LineEditNewMesh = new QLineEdit(GroupArguments); + + //Preview check box + myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); + GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 1); - GroupArgumentsLayout->addWidget(filterBtn, 0, 3); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 3); GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4); GroupArgumentsLayout->addWidget(GroupAxis, 2, 0, 1, 4); GroupArgumentsLayout->addWidget(TextLabelAngle, 3, 0, 1, 2); @@ -223,6 +231,8 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) GroupArgumentsLayout->addWidget(ActionBox, 4, 0, 3, 3); GroupArgumentsLayout->addWidget(MakeGroupsCheck, 5, 3); GroupArgumentsLayout->addWidget(LineEditNewMesh, 6, 3); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 7, 0); + /***************************************************************/ GroupButtons = new QGroupBox(this); @@ -254,14 +264,14 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) SMESHGUI_RotationDlgLayout->addWidget(GroupButtons); /* Initialisations */ - SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); + SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); - SpinBox_Angle->RangeStepAndValidator(-360.0, +360.0, 5.0, 3); + SpinBox_Angle->RangeStepAndValidator(-360.0, +360.0, 5.0, "angle_precision"); myConstructorId = 0; RadioButton1->setChecked(true); @@ -307,6 +317,17 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); connect(ActionGroup, SIGNAL(buttonClicked(int)), SLOT(onActionClicked(int))); + connect(SpinBox_X, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Y, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Z, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Angle, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + + //To Connect preview check box + connectPreviewControl(); + onActionClicked(MOVE_ELEMS_BUTTON); } @@ -354,6 +375,9 @@ void SMESHGUI_RotationDlg::Init (bool ResetControls) ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true); CheckBoxMesh->setChecked(false); + myPreviewCheckBox->setChecked(false); + onDisplaySimulation(false); + // MakeGroupsCheck->setChecked(false); // MakeGroupsCheck->setEnabled(false); // onSelectMesh(false); @@ -392,7 +416,7 @@ bool SMESHGUI_RotationDlg::ClickOnApply() anAxis.vy = SpinBox_DY->GetValue(); anAxis.vz = SpinBox_DZ->GetValue(); - double anAngle = (SpinBox_Angle->GetValue())*PI/180; + double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.; QStringList aParameters; aParameters << SpinBox_X->text(); @@ -405,17 +429,19 @@ bool SMESHGUI_RotationDlg::ClickOnApply() int actionButton = ActionGroup->checkedId(); bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ); + QStringList anEntryList; try { SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + + myMesh->SetParameters(aParameters.join(":").toLatin1().constData()); + switch ( actionButton ) { case MOVE_ELEMS_BUTTON: if(CheckBoxMesh->isChecked()) aMeshEditor->RotateObject(mySelectedObject, anAxis, anAngle, false); else aMeshEditor->Rotate(anElementsId, anAxis, anAngle, false); - if( !myMesh->_is_nil()) - myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); break; case COPY_ELEMS_BUTTON: if ( makeGroups ) { @@ -428,33 +454,47 @@ bool SMESHGUI_RotationDlg::ClickOnApply() else { if(CheckBoxMesh->isChecked()) aMeshEditor->RotateObject(mySelectedObject, anAxis, anAngle, true); - else + else aMeshEditor->Rotate(anElementsId, anAxis, anAngle, true); } - if( !myMesh->_is_nil()) - myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); break; - case MAKE_MESH_BUTTON: + case MAKE_MESH_BUTTON: { SMESH::SMESH_Mesh_var mesh; - if(CheckBoxMesh->isChecked()) + if (CheckBoxMesh->isChecked()) mesh = aMeshEditor->RotateObjectMakeMesh(mySelectedObject, anAxis, anAngle, makeGroups, LineEditNewMesh->text().toLatin1().data()); - else + else mesh = aMeshEditor->RotateMakeMesh(anElementsId, anAxis, anAngle, makeGroups, LineEditNewMesh->text().toLatin1().data()); - if( !mesh->_is_nil()) - mesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); + if (!mesh->_is_nil()) { + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) ) + anEntryList.append( aSObject->GetID().c_str() ); +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + mesh->UnRegister(); +#endif + } + break; + } } } catch (...) { } SMESH::UpdateView(); - if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() || - actionButton == MAKE_MESH_BUTTON ) + if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) || + actionButton == MAKE_MESH_BUTTON ) { mySMESHGUI->updateObjBrowser(true); // new groups may appear + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); + } Init(false); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; @@ -466,6 +506,7 @@ bool SMESHGUI_RotationDlg::ClickOnApply() //================================================================================= void SMESHGUI_RotationDlg::ClickOnOk() { + setIsApplyAndClose( true ); if( ClickOnApply() ) ClickOnCancel(); } @@ -496,7 +537,7 @@ void SMESHGUI_RotationDlg::ClickOnCancel() void SMESHGUI_RotationDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -506,10 +547,10 @@ void SMESHGUI_RotationDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -538,21 +579,21 @@ void SMESHGUI_RotationDlg::onTextChange (const QString& theNewText) if (aMesh) { if (send == LineEditElements) { Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); - + TColStd_MapOfInteger newIndices; - + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); for (int i = 0; i < aListId.count(); i++) { - const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); - if (e) - newIndices.Add(e->GetID()); - myNbOkElements++; + const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); + if (e) + newIndices.Add(e->GetID()); + myNbOkElements++; } mySelector->AddOrRemoveIndex( anIO, newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( anIO, true, true ); - + aViewWindow->highlight( anIO, true, true ); + myElementsId = theNewText; } } @@ -605,7 +646,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() myActor = SMESH::FindActorByObject(myMesh); if (!myActor) myActor = SMESH::FindActorByEntry(IO->getEntry()); - if (!myActor) + if (!myActor && !CheckBoxMesh->isChecked()) return; int aNbUnits = 0; @@ -645,7 +686,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() } else if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //SUBMESH // get submesh SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(IO); - + // get IDs from submesh SMESH::long_array_var anElementsIds = new SMESH::long_array; anElementsIds = aSubMesh->GetElementsId(); @@ -711,7 +752,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() LineEditElements->setText(aString); LineEditElements->repaint(); LineEditElements->setEnabled(false); // to update lineedit IPAL 19809 - LineEditElements->setEnabled(true); + LineEditElements->setEnabled(true); setNewMeshName(); } myBusy = false; @@ -721,6 +762,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() buttonOk->setEnabled(true); buttonApply->setEnabled(true); } + onDisplaySimulation(true); } //================================================================================= @@ -743,23 +785,23 @@ void SMESHGUI_RotationDlg::SetEditCurrentArgument() myEditCurrentArgument = (QWidget*)LineEditElements; SMESH::SetPointRepresentation(false); if (CheckBoxMesh->isChecked()) { - if ( aViewWindow ) - aViewWindow->SetSelectionMode(ActorSelection); + if ( aViewWindow ) + aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); } else { - if ( aViewWindow ) - aViewWindow->SetSelectionMode( CellSelection ); - } + if ( aViewWindow ) + aViewWindow->SetSelectionMode( CellSelection ); + } } else if (send == SelectPointButton) { myEditCurrentArgument = (QWidget*)SpinBox_X; SMESH::SetPointRepresentation(true); - if ( aViewWindow ) - aViewWindow->SetSelectionMode( NodeSelection ); + if ( aViewWindow ) + aViewWindow->SetSelectionMode( NodeSelection ); } else if (send == SelectVectorButton) { myEditCurrentArgument = (QWidget*)SpinBox_DX; SMESH::SetPointRepresentation(true); - if ( aViewWindow ) - aViewWindow->SetSelectionMode( NodeSelection ); + if ( aViewWindow ) + aViewWindow->SetSelectionMode( NodeSelection ); } break; } @@ -845,6 +887,7 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh) TextLabelElements->setText(tr("SMESH_NAME")); else TextLabelElements->setText(tr("SMESH_ID_ELEMENTS")); + myFilterBtn->setEnabled(!toSelectMesh); if (myEditCurrentArgument != LineEditElements) { LineEditElements->clear(); @@ -866,6 +909,7 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh) LineEditElements->setReadOnly(false); LineEditElements->setValidator(myIdValidator); onTextChange(LineEditElements->text()); + hidePreview(); } SelectionIntoArgument(); @@ -878,8 +922,8 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh) bool SMESHGUI_RotationDlg::IsAxisOk() { return (SpinBox_DX->GetValue() != 0 || - SpinBox_DY->GetValue() != 0 || - SpinBox_DZ->GetValue() != 0); + SpinBox_DY->GetValue() != 0 || + SpinBox_DZ->GetValue() != 0); } //================================================================================= @@ -928,6 +972,7 @@ void SMESHGUI_RotationDlg::onActionClicked(int button) break; } setNewMeshName(); + toDisplaySimulation(); } //======================================================================= @@ -974,6 +1019,12 @@ void SMESHGUI_RotationDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_RotationDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL ); @@ -1010,3 +1061,52 @@ bool SMESHGUI_RotationDlg::isValid() } return true; } + + +//================================================================================= +// function : onDisplaySimulation +// purpose : Show/Hide preview +//================================================================================= +void SMESHGUI_RotationDlg::onDisplaySimulation( bool toDisplayPreview ) { + if (myPreviewCheckBox->isChecked() && toDisplayPreview) { + if(myNbOkElements && isValid() && IsAxisOk()) { + QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts); + SMESH::long_array_var anElementsId = new SMESH::long_array; + + anElementsId->length(aListElementsId.count()); + for (int i = 0; i < aListElementsId.count(); i++) + anElementsId[i] = aListElementsId[i].toInt(); + + SMESH::AxisStruct anAxis; + + anAxis.x = SpinBox_X->GetValue(); + anAxis.y = SpinBox_Y->GetValue(); + anAxis.z = SpinBox_Z->GetValue();; + anAxis.vx = SpinBox_DX->GetValue(); + anAxis.vy = SpinBox_DY->GetValue(); + anAxis.vz = SpinBox_DZ->GetValue(); + double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.; + + try { + SUIT_OverrideCursor aWaitCursor; + bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON || + ActionGroup->checkedId() == MAKE_MESH_BUTTON ); + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); + if(CheckBoxMesh->isChecked()) + aMeshEditor->RotateObject(mySelectedObject, anAxis, anAngle, copy); + else + aMeshEditor->Rotate(anElementsId, anAxis, anAngle, copy); + + SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); + mySimulation->SetData(aMeshPreviewStruct._retn()); + } catch (...) { + hidePreview(); + } + } + else { + hidePreview(); + } + } else { + hidePreview(); + } +} diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.h b/src/SMESHGUI/SMESHGUI_RotationDlg.h index 4dd572f29..a4e6b4af2 100644 --- a/src/SMESHGUI/SMESHGUI_RotationDlg.h +++ b/src/SMESHGUI/SMESHGUI_RotationDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_RotationDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -28,9 +29,8 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" +#include "SMESHGUI_PreviewDlg.h" -// Qt includes -#include // IDL includes #include @@ -56,7 +56,7 @@ class SMESH_LogicalFilter; // class : SMESHGUI_RotationDlg // purpose : //================================================================================= -class SMESHGUI_EXPORT SMESHGUI_RotationDlg : public QDialog +class SMESHGUI_EXPORT SMESHGUI_RotationDlg : public SMESHGUI_PreviewDlg { Q_OBJECT @@ -75,7 +75,6 @@ private: bool isValid(); - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ SMESHGUI_IdValidator* myIdValidator; LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ int myNbOkElements; /* to check when elements are defined */ @@ -131,8 +130,12 @@ private: QString myHelpFileName; + QPushButton* myFilterBtn; SMESHGUI_FilterDlg* myFilterDlg; +protected slots: + virtual void onDisplaySimulation( bool ); + private slots: void ClickOnOk(); void ClickOnCancel(); diff --git a/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx b/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx new file mode 100644 index 000000000..1e3cd9f95 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx @@ -0,0 +1,1136 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESHGUI_ScaleDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes + +#include "SMESHGUI_ScaleDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_SpinBox.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_MeshEditPreview.h" + +#include +#include +#include +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +// SALOME KERNEL includes +#include + +// OCCT includes +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action type + +/*! + \class BusyLocker + \brief Simple 'busy state' flag locker. + \internal +*/ + +class BusyLocker +{ +public: + //! Constructor. Sets passed boolean flag to \c true. + BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; } + //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false. + ~BusyLocker() { myBusy = false; } +private: + bool& myBusy; //! External 'busy state' boolean flag +}; + +#define SPACING 6 +#define MARGIN 11 + +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + +//================================================================================= +// class : SMESHGUI_ScaleDlg() +// purpose : +//================================================================================= +SMESHGUI_ScaleDlg::SMESHGUI_ScaleDlg( SMESHGUI* theModule ) : + SMESHGUI_PreviewDlg( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myFilterDlg(0), + mySelectedObject(SMESH::SMESH_IDSource::_nil()) +{ + QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MESH_SCALE"))); + QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_SCALE_ALONG_AXES"))); + QPixmap image2 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT"))); + + setModal(false); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(tr("SMESH_SCALE_TITLE")); + setSizeGripEnabled(true); + + QVBoxLayout* SMESHGUI_ScaleDlgLayout = new QVBoxLayout(this); + SMESHGUI_ScaleDlgLayout->setSpacing(SPACING); + SMESHGUI_ScaleDlgLayout->setMargin(MARGIN); + + /***************************************************************/ + ConstructorsBox = new QGroupBox(tr("SMESH_SCALE"), this); + GroupConstructors = new QButtonGroup(this); + QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox); + ConstructorsBoxLayout->setSpacing(SPACING); + ConstructorsBoxLayout->setMargin(MARGIN); + + RadioButton1= new QRadioButton(ConstructorsBox); + RadioButton1->setIcon(image0); + RadioButton2= new QRadioButton(ConstructorsBox); + RadioButton2->setIcon(image1); + + ConstructorsBoxLayout->addWidget(RadioButton1); + ConstructorsBoxLayout->addWidget(RadioButton2); + GroupConstructors->addButton(RadioButton1, 0); + GroupConstructors->addButton(RadioButton2, 1); + + /***************************************************************/ + GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this); + QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments); + GroupArgumentsLayout->setSpacing(SPACING); + GroupArgumentsLayout->setMargin(MARGIN); + + myIdValidator = new SMESHGUI_IdValidator(this); + + // Controls for elements selection + TextLabelElements = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments); + SelectElementsButton = new QPushButton(GroupArguments); + SelectElementsButton->setIcon(image2); + LineEditElements = new QLineEdit(GroupArguments); + LineEditElements->setValidator(myIdValidator); + LineEditElements->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + + // Control for the whole mesh selection + CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); + + // Controls for vector and points selection + TextLabel1 = new QLabel(tr("SMESH_BASE_POINT"), GroupArguments); + SelectButton1 = new QPushButton(GroupArguments); + SelectButton1->setIcon(image2); + + TextLabel1_1 = new QLabel(tr("SMESH_X"), GroupArguments); + SpinBox1_1 = new SMESHGUI_SpinBox(GroupArguments); + TextLabel1_2 = new QLabel(tr("SMESH_Y"), GroupArguments); + SpinBox1_2 = new SMESHGUI_SpinBox(GroupArguments); + TextLabel1_3 = new QLabel(tr("SMESH_Z"), GroupArguments); + SpinBox1_3 = new SMESHGUI_SpinBox(GroupArguments); + + TextLabel2 = new QLabel(tr("SMESH_SCALE_FACTOR"), GroupArguments); + SpinBox_FX = new SMESHGUI_SpinBox(GroupArguments); + + TextLabel3 = new QLabel(tr("SMESH_SCALE_FACTOR_Y"), GroupArguments); + SpinBox_FY = new SMESHGUI_SpinBox(GroupArguments); + + TextLabel4 = new QLabel(tr("SMESH_SCALE_FACTOR_Z"), GroupArguments); + SpinBox_FZ = new SMESHGUI_SpinBox(GroupArguments); + + + // switch of action type + ActionBox = new QGroupBox(GroupArguments); + ActionGroup = new QButtonGroup(GroupArguments); + QVBoxLayout* ActionBoxLayout = new QVBoxLayout(ActionBox); + ActionBoxLayout->addSpacing(SPACING); + ActionBoxLayout->setMargin(MARGIN); + + QRadioButton* aMoveElements = new QRadioButton(tr("SMESH_MOVE_ELEMENTS"), ActionBox); + QRadioButton* aCopyElements = new QRadioButton(tr("SMESH_COPY_ELEMENTS"), ActionBox); + QRadioButton* aCreateMesh = new QRadioButton(tr("SMESH_CREATE_MESH"), ActionBox); + + ActionBoxLayout->addWidget(aMoveElements); + ActionBoxLayout->addWidget(aCopyElements); + ActionBoxLayout->addWidget(aCreateMesh); + ActionGroup->addButton(aMoveElements, MOVE_ELEMS_BUTTON); + ActionGroup->addButton(aCopyElements, COPY_ELEMS_BUTTON); + ActionGroup->addButton(aCreateMesh, MAKE_MESH_BUTTON); + + // CheckBox for groups generation + MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments); + MakeGroupsCheck->setChecked(false); + + // Name of a mesh to create + LineEditNewMesh = new QLineEdit(GroupArguments); + + //Preview check box + myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); + + // layout + GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); + GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); + GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 7); + GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8); + GroupArgumentsLayout->addWidget(TextLabel1, 2, 0); + GroupArgumentsLayout->addWidget(SelectButton1, 2, 1); + GroupArgumentsLayout->addWidget(TextLabel1_1, 2, 2); + GroupArgumentsLayout->addWidget(SpinBox1_1, 2, 3); + GroupArgumentsLayout->addWidget(TextLabel1_2, 2, 4); + GroupArgumentsLayout->addWidget(SpinBox1_2, 2, 5); + GroupArgumentsLayout->addWidget(TextLabel1_3, 2, 6); + GroupArgumentsLayout->addWidget(SpinBox1_3, 2, 7); + GroupArgumentsLayout->addWidget(TextLabel2, 3, 0); + GroupArgumentsLayout->addWidget(SpinBox_FX, 3, 3); + GroupArgumentsLayout->addWidget(TextLabel3, 4, 0); + GroupArgumentsLayout->addWidget(SpinBox_FY, 4, 3); + GroupArgumentsLayout->addWidget(TextLabel4, 5, 0); + GroupArgumentsLayout->addWidget(SpinBox_FZ, 5, 3); + GroupArgumentsLayout->addWidget(ActionBox, 7, 0, 3, 4); + GroupArgumentsLayout->addWidget(MakeGroupsCheck, 8, 5, 1, 4); + GroupArgumentsLayout->addWidget(LineEditNewMesh, 9, 5, 1, 4); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 10, 0); + + /***************************************************************/ + GroupButtons = new QGroupBox(this); + QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons); + GroupButtonsLayout->setSpacing(SPACING); + GroupButtonsLayout->setMargin(MARGIN); + + buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons); + buttonOk->setAutoDefault(true); + buttonOk->setDefault(true); + buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); + buttonApply->setAutoDefault(true); + buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons); + buttonCancel->setAutoDefault(true); + buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons); + buttonHelp->setAutoDefault(true); + + GroupButtonsLayout->addWidget(buttonOk); + GroupButtonsLayout->addSpacing(10); + GroupButtonsLayout->addWidget(buttonApply); + GroupButtonsLayout->addSpacing(10); + GroupButtonsLayout->addStretch(); + GroupButtonsLayout->addWidget(buttonCancel); + GroupButtonsLayout->addWidget(buttonHelp); + + /***************************************************************/ + SMESHGUI_ScaleDlgLayout->addWidget(ConstructorsBox); + SMESHGUI_ScaleDlgLayout->addWidget(GroupArguments); + SMESHGUI_ScaleDlgLayout->addWidget(GroupButtons); + + /* Initialisations */ + SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_FX->RangeStepAndValidator(1.e-6, 1.e+6, 1.0, "parametric_precision"); + SpinBox_FX->SetStep(0.1); + SpinBox_FY->RangeStepAndValidator(1.e-6, 1.e+6, 1.0, "parametric_precision"); + SpinBox_FY->SetStep(0.1); + SpinBox_FZ->RangeStepAndValidator(1.e-6, 1.e+6, 1.0, "parametric_precision"); + SpinBox_FZ->SetStep(0.1); + + RadioButton1->setChecked(true); + + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // Costruction of the logical filter + SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH); + SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP); + + QList aListOfFilters; + if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); + if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); + + myMeshOrSubMeshOrGroupFilter = + new SMESH_LogicalFilter(aListOfFilters, SMESH_LogicalFilter::LO_OR); + + myHelpFileName = "scale_page.html"; + + Init(); + + /* signals and slots connections */ + connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk())); + connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel())); + connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); + connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); + connect(GroupConstructors, SIGNAL(buttonClicked(int)), SLOT(ConstructorsClicked(int))); + + connect(SelectElementsButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); + connect(SelectButton1, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); + + 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(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); + connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); + connect(ActionGroup, SIGNAL(buttonClicked(int)), SLOT(onActionClicked(int))); + + connect(SpinBox1_1, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox1_2, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox1_3, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + + connect(SpinBox_FX, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_FY, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_FZ, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + + //To Connect preview check box + connectPreviewControl(); + + ConstructorsClicked(0); + SelectionIntoArgument(); + onActionClicked(MOVE_ELEMS_BUTTON); +} + +//================================================================================= +// function : ~SMESHGUI_ScaleDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_ScaleDlg::~SMESHGUI_ScaleDlg() +{ + if ( myFilterDlg ) { + myFilterDlg->setParent( 0 ); + delete myFilterDlg; + myFilterDlg = 0; + } +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::Init (bool ResetControls) +{ + myBusy = false; + + myEditCurrentArgument = 0; + LineEditElements->clear(); + myElementsId = ""; + myNbOkElements = 0; + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + myActor = 0; + myMesh = SMESH::SMESH_Mesh::_nil(); + + if (ResetControls) { + SpinBox1_1->SetValue(0.0); + SpinBox1_2->SetValue(0.0); + SpinBox1_3->SetValue(0.0); + SpinBox_FX->SetValue(1.0); + SpinBox_FY->SetValue(1.0); + SpinBox_FZ->SetValue(1.0); + myPreviewCheckBox->setChecked(false); + onDisplaySimulation(false); + + ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true); + CheckBoxMesh->setChecked(false); + onSelectMesh(false); + } +} + +//================================================================================= +// function : ConstructorsClicked() +// purpose : Radio button management +//================================================================================= +void SMESHGUI_ScaleDlg::ConstructorsClicked (int constructorId) +{ + disconnect(mySelectionMgr, 0, this, 0); + + switch (constructorId) { + case 0: + { + TextLabel2->setText(tr("SMESH_SCALE_FACTOR")); + TextLabel3->hide(); + TextLabel4->hide(); + SpinBox_FY->hide(); + SpinBox_FZ->hide(); + break; + } + case 1: + { + TextLabel2->setText(tr("SMESH_SCALE_FACTOR_X")); + TextLabel3->show(); + TextLabel4->show(); + SpinBox_FY->show(); + SpinBox_FZ->show(); + break; + } + } + + if (myEditCurrentArgument != (QWidget*)LineEditElements) { + SMESH::SetPointRepresentation(false); + if (!CheckBoxMesh->isChecked()) + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( CellSelection ); + } + + myEditCurrentArgument = (QWidget*)LineEditElements; + LineEditElements->setFocus(); + + if (CheckBoxMesh->isChecked()) + onSelectMesh(true); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + + QApplication::instance()->processEvents(); + updateGeometry(); + resize(100,100); +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool SMESHGUI_ScaleDlg::ClickOnApply() +{ + if (mySMESHGUI->isActiveStudyLocked()) + return false; + + if( !isValid() ) + return false; + + if (myNbOkElements) { + QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts); + + SMESH::long_array_var anElementsId = new SMESH::long_array; + + anElementsId->length(aListElementsId.count()); + for (int i = 0; i < aListElementsId.count(); i++) + anElementsId[i] = aListElementsId[i].toInt(); + + SMESH::PointStruct aPoint; + SMESH::double_array_var aScaleFact = new SMESH::double_array; + getScale(aPoint, aScaleFact); + + QStringList aParameters; + aParameters << SpinBox1_1->text(); + aParameters << SpinBox1_2->text(); + aParameters << SpinBox1_3->text(); + aParameters << SpinBox_FX->text(); + if (GetConstructorId() == 1) { + aParameters << SpinBox_FX->text(); + aParameters << SpinBox_FX->text(); + } + else { + aParameters << SpinBox_FY->text(); + aParameters << SpinBox_FZ->text(); + } + + int actionButton = ActionGroup->checkedId(); + bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ); + QStringList anEntryList; + try { + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + + myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + + SMESH::SMESH_IDSource_var obj; + if ( CheckBoxMesh->isChecked() ) + obj = mySelectedObject; + else + obj = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL); + + switch ( actionButton ) { + + case MOVE_ELEMS_BUTTON: + aMeshEditor->Scale(obj, aPoint, aScaleFact, false); + break; + + case COPY_ELEMS_BUTTON: + if ( makeGroups ) + SMESH::ListOfGroups_var groups = + aMeshEditor->ScaleMakeGroups(obj, aPoint, aScaleFact); + else + aMeshEditor->Scale(obj, aPoint, aScaleFact, true); + break; + + case MAKE_MESH_BUTTON: { + SMESH::SMESH_Mesh_var mesh = + aMeshEditor->ScaleMakeMesh(obj, aPoint, aScaleFact, makeGroups, + LineEditNewMesh->text().toLatin1().data()); + if (!mesh->_is_nil()) { + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) ) + anEntryList.append( aSObject->GetID().c_str() ); +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + mesh->UnRegister(); +#endif + } + break; + } + } + } catch (...) { + } + + SMESH::UpdateView(); + if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) || + actionButton == MAKE_MESH_BUTTON ) { + mySMESHGUI->updateObjBrowser(true); // new groups may appear + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); + } + Init(false); + ConstructorsClicked(GetConstructorId()); + mySelectedObject = SMESH::SMESH_IDSource::_nil(); + SelectionIntoArgument(); + + SMESHGUI::Modified(); + } + + return true; +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::ClickOnOk() +{ + setIsApplyAndClose( true ); + if( ClickOnApply() ) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::ClickOnCancel() +{ + disconnect(mySelectionMgr, 0, this, 0); + mySelectionMgr->clearFilters(); + //mySelectionMgr->clearSelected(); + if (SMESH::GetCurrentVtkView()) { + SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters + SMESH::SetPointRepresentation(false); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + mySMESHGUI->ResetState(); + reject(); +} + +//================================================================================= +// function : ClickOnHelp() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::ClickOnHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} + +//======================================================================= +// function : onTextChange() +// purpose : +//======================================================================= +void SMESHGUI_ScaleDlg::onTextChange (const QString& theNewText) +{ + QLineEdit* send = (QLineEdit*)sender(); + + if (myBusy) return; + BusyLocker lock( myBusy ); + + if (send == LineEditElements) + myNbOkElements = 0; + + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + + // hilight entered elements + SMDS_Mesh* aMesh = 0; + if (myActor) + aMesh = myActor->GetObject()->GetMesh(); + + if (aMesh) { + Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); + + TColStd_MapOfInteger newIndices; + + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); + + if (send == LineEditElements) { + for (int i = 0; i < aListId.count(); i++) { + const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); + if (e) + newIndices.Add(e->GetID()); + myNbOkElements++; + } + } + + mySelector->AddOrRemoveIndex( anIO, newIndices, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( anIO, true, true ); + + myElementsId = theNewText; + } + + if (myNbOkElements) { + buttonOk->setEnabled(true); + buttonApply->setEnabled(true); + } +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void SMESHGUI_ScaleDlg::SelectionIntoArgument() +{ + if (myBusy) return; + BusyLocker lock( myBusy ); + // clear + myActor = 0; + QString aString = ""; + + if (myEditCurrentArgument == (QWidget*)LineEditElements) { + LineEditElements->setText(aString); + myNbOkElements = 0; + buttonOk->setEnabled(false); + buttonApply->setEnabled(false); + } + + if (!GroupButtons->isEnabled()) // inactive + return; + + // get selected mesh + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); + + int nbSel = aList.Extent(); + if (nbSel != 1) + return; + + Handle(SALOME_InteractiveObject) IO = aList.First(); + myMesh = SMESH::GetMeshByIO(IO); + if (myMesh->_is_nil()) + return; + + myActor = SMESH::FindActorByObject(myMesh); + if (!myActor) + myActor = SMESH::FindActorByEntry(IO->getEntry()); + if (!myActor && !CheckBoxMesh->isChecked()) + return; + + int aNbUnits = 0; + + if (myEditCurrentArgument == (QWidget*)LineEditElements) { + myElementsId = ""; + + // MakeGroups is available if there are groups and "Copy" + if ( myMesh->NbGroups() == 0 ) { + MakeGroupsCheck->setChecked(false); + MakeGroupsCheck->setEnabled(false); + } + else if ( ActionGroup->checkedId() != MOVE_ELEMS_BUTTON ) { + MakeGroupsCheck->setEnabled(true); + } + + if (CheckBoxMesh->isChecked()) { + SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString ); + + if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //MESH, SUBMESH, OR GROUP + mySelectedObject = SMESH::IObjectToInterface(IO); + } + else + return; + // get IDs from mesh + /* + SMDS_Mesh* aSMDSMesh = myActor->GetObject()->GetMesh(); + if (!aSMDSMesh) + return; + + for (int i = aSMDSMesh->MinElementID(); i <= aSMDSMesh->MaxElementID(); i++) { + const SMDS_MeshElement * e = aSMDSMesh->FindElement(i); + if (e) { + myElementsId += QString(" %1").arg(i); + aNbUnits++; + } + } + } else if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //SUBMESH + // get submesh + SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(IO); + + // get IDs from submesh + SMESH::long_array_var anElementsIds = new SMESH::long_array; + anElementsIds = aSubMesh->GetElementsId(); + for (int i = 0; i < anElementsIds->length(); i++) { + myElementsId += QString(" %1").arg(anElementsIds[i]); + } + aNbUnits = anElementsIds->length(); + } else { // GROUP + // get smesh group + SMESH::SMESH_GroupBase_var aGroup = + SMESH::IObjectToInterface(IO); + if (aGroup->_is_nil()) + return; + + // get IDs from smesh group + SMESH::long_array_var anElementsIds = new SMESH::long_array; + anElementsIds = aGroup->GetListOfID(); + for (int i = 0; i < anElementsIds->length(); i++) { + myElementsId += QString(" %1").arg(anElementsIds[i]); + } + aNbUnits = anElementsIds->length(); + } + */ + } else { + aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString); + myElementsId = aString; + if (aNbUnits < 1) + return; + } + + myNbOkElements = true; + } else { + aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); + if (aNbUnits != 1) + return; + + SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); + if (!aMesh) + return; + + const SMDS_MeshNode * n = aMesh->FindNode(aString.toInt()); + if (!n) + return; + + double x = n->X(); + double y = n->Y(); + double z = n->Z(); + + if (myEditCurrentArgument == (QWidget*)SpinBox1_1) { + SpinBox1_1->SetValue(x); + SpinBox1_2->SetValue(y); + SpinBox1_3->SetValue(z); + } + else if (myEditCurrentArgument == (QWidget*)SpinBox_FX) { + SpinBox_FX->SetValue(x); + SpinBox_FY->SetValue(y); + SpinBox_FZ->SetValue(z); + } + } + + if (myEditCurrentArgument == (QWidget*)LineEditElements) { + LineEditElements->setText(aString); + LineEditElements->repaint(); + LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809 + LineEditElements->setEnabled(true); + setNewMeshName(); + } + + // OK + if (myNbOkElements) { + buttonOk->setEnabled(true); + buttonApply->setEnabled(true); + } + + onDisplaySimulation(true); +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + disconnect(mySelectionMgr, 0, this, 0); + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + + if (send == SelectElementsButton) { + myEditCurrentArgument = (QWidget*)LineEditElements; + SMESH::SetPointRepresentation(false); + if (CheckBoxMesh->isChecked()) { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + } + else { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( CellSelection ); + } + } + else if (send == SelectButton1) { + myEditCurrentArgument = (QWidget*)SpinBox1_1; + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( NodeSelection ); + } + + myEditCurrentArgument->setFocus(); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + SelectionIntoArgument(); +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::DeactivateActiveDialog() +{ + if (ConstructorsBox->isEnabled()) { + ConstructorsBox->setEnabled(false); + GroupArguments->setEnabled(false); + GroupButtons->setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + mySMESHGUI->EmitSignalDeactivateDialog(); + ConstructorsBox->setEnabled(true); + GroupArguments->setEnabled(true); + GroupButtons->setEnabled(true); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( CellSelection ); + + SelectionIntoArgument(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::enterEvent (QEvent*) +{ + if (!ConstructorsBox->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::closeEvent (QCloseEvent*) +{ + /* same than click on cancel button */ + ClickOnCancel(); +} + +//======================================================================= +//function : hideEvent +//purpose : caused by ESC key +//======================================================================= +void SMESHGUI_ScaleDlg::hideEvent (QHideEvent*) +{ + if (!isMinimized()) + ClickOnCancel(); +} + +//======================================================================= +//function : onSelectMesh +//purpose : +//======================================================================= +void SMESHGUI_ScaleDlg::onSelectMesh (bool toSelectMesh) +{ + if (toSelectMesh) + TextLabelElements->setText(tr("SMESH_NAME")); + else + TextLabelElements->setText(tr("SMESH_ID_ELEMENTS")); + myFilterBtn->setEnabled(!toSelectMesh); + + if (myEditCurrentArgument != LineEditElements) { + LineEditElements->clear(); + return; + } + + mySelectionMgr->clearFilters(); + SMESH::SetPointRepresentation(false); + + if (toSelectMesh) { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + LineEditElements->setReadOnly(true); + LineEditElements->setValidator(0); + } else { + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( CellSelection ); + LineEditElements->setReadOnly(false); + LineEditElements->setValidator(myIdValidator); + onTextChange(LineEditElements->text()); + hidePreview(); + } + + SelectionIntoArgument(); +} + +//======================================================================= +//function : onActionClicked +//purpose : slot called when an action type changed +//======================================================================= + +void SMESHGUI_ScaleDlg::onActionClicked(int button) +{ + switch ( button ) { + case MOVE_ELEMS_BUTTON: + MakeGroupsCheck->setEnabled(false); + LineEditNewMesh->setEnabled(false); + break; + case COPY_ELEMS_BUTTON: + LineEditNewMesh->setEnabled(false); + MakeGroupsCheck->setText( tr("SMESH_MAKE_GROUPS")); + if ( myMesh->_is_nil() || myMesh->NbGroups() > 0) + MakeGroupsCheck->setEnabled(true); + else + MakeGroupsCheck->setEnabled(false); + break; + case MAKE_MESH_BUTTON: + LineEditNewMesh->setEnabled(true); + MakeGroupsCheck->setText( tr("SMESH_COPY_GROUPS")); + if ( myMesh->_is_nil() || myMesh->NbGroups() > 0) + MakeGroupsCheck->setEnabled(true); + else + MakeGroupsCheck->setEnabled(false); + break; + } + setNewMeshName(); + toDisplaySimulation(); +} + +//======================================================================= +//function : setNewMeshName +//purpose : update contents of LineEditNewMesh +//======================================================================= + +void SMESHGUI_ScaleDlg::setNewMeshName() +{ + LineEditNewMesh->setText(""); + if ( LineEditNewMesh->isEnabled() && !myMesh->_is_nil() ) { + QString name; + if ( CheckBoxMesh->isChecked() ) { + name = LineEditElements->text(); + } + else { + _PTR(SObject) meshSO = SMESH::FindSObject( myMesh ); + name = meshSO->GetName().c_str(); + } + if ( !name.isEmpty() ) + LineEditNewMesh->setText( SMESH::UniqueMeshName( name, "scaled")); + } +} + +//================================================================================= +// function : GetConstructorId() +// purpose : +//================================================================================= +int SMESHGUI_ScaleDlg::GetConstructorId() +{ + return GroupConstructors->checkedId(); +} + +//================================================================================= +// function : keyPressEvent() +// purpose : +//================================================================================= +void SMESHGUI_ScaleDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + ClickOnHelp(); + } +} + +//================================================================================= +// function : setFilters() +// purpose : SLOT. Called when "Filter" button pressed. +//================================================================================= +void SMESHGUI_ScaleDlg::setFilters() +{ + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } + if ( !myFilterDlg ) + myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL ); + + myFilterDlg->SetSelection(); + myFilterDlg->SetMesh( myMesh ); + myFilterDlg->SetSourceWg( LineEditElements ); + + myFilterDlg->show(); +} + +//================================================================================= +// function : isValid +// purpose : +//================================================================================= +bool SMESHGUI_ScaleDlg::isValid() +{ + bool ok = true; + QString msg; + + ok = SpinBox1_1->isValid( msg, true ) && ok; + ok = SpinBox1_2->isValid( msg, true ) && ok; + ok = SpinBox1_3->isValid( msg, true ) && ok; + ok = SpinBox_FX->isValid( msg, true ) && ok; + if (GetConstructorId() == 1) { + ok = SpinBox_FY->isValid( msg, true ) && ok; + ok = SpinBox_FZ->isValid( msg, true ) && ok; + } + + if( !ok ) { + QString str( tr( "SMESH_INCORRECT_INPUT" ) ); + if ( !msg.isEmpty() ) + str += "\n" + msg; + SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str ); + return false; + } + return true; +} + +//================================================================================= +// function : onDisplaySimulation +// purpose : Show/Hide preview +//================================================================================= +void SMESHGUI_ScaleDlg::onDisplaySimulation( bool toDisplayPreview ) { + if (myPreviewCheckBox->isChecked() && toDisplayPreview) { + if ( myNbOkElements && isValid() ) { + QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts); + + SMESH::long_array_var anElementsId = new SMESH::long_array; + + anElementsId->length(aListElementsId.count()); + for (int i = 0; i < aListElementsId.count(); i++) + anElementsId[i] = aListElementsId[i].toInt(); + + SMESH::PointStruct aPoint; + SMESH::double_array_var aScaleFact = new SMESH::double_array; + getScale(aPoint, aScaleFact); + + try { + bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON || + ActionGroup->checkedId() == MAKE_MESH_BUTTON ); + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); + SMESH::SMESH_IDSource_var obj; + if ( CheckBoxMesh->isChecked() ) + obj = mySelectedObject; + else + obj = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL); + aMeshEditor->Scale(obj, aPoint, aScaleFact, copy); + + SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); + mySimulation->SetData(aMeshPreviewStruct._retn()); + + } catch (...) { + hidePreview(); + } + } else { + hidePreview(); + } + } else { + hidePreview(); + } +} + +//================================================================================= +// function : getScale +// purpose : get scale parameters +//================================================================================= +void SMESHGUI_ScaleDlg::getScale( SMESH::PointStruct& thePoint , SMESH::double_array_var& theScaleFact) { + thePoint.x = SpinBox1_1->GetValue(); + thePoint.y = SpinBox1_2->GetValue(); + thePoint.z = SpinBox1_3->GetValue(); + + theScaleFact->length(3); + theScaleFact[0] = SpinBox_FX->GetValue(); + if (GetConstructorId() == 0) { + theScaleFact[1] = SpinBox_FX->GetValue(); + theScaleFact[2] = SpinBox_FX->GetValue(); + } + else { + theScaleFact[1] = SpinBox_FY->GetValue(); + theScaleFact[2] = SpinBox_FZ->GetValue(); + } +} diff --git a/src/SMESHGUI/SMESHGUI_ScaleDlg.h b/src/SMESHGUI/SMESHGUI_ScaleDlg.h new file mode 100644 index 000000000..7293a99e7 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_ScaleDlg.h @@ -0,0 +1,150 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_ScaleDlg.h +// Author : Sergey Kuul, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_SCALEDLG_H +#define SMESHGUI_SCALEDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" +#include "SMESHGUI_PreviewDlg.h" + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QButtonGroup; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QCheckBox; +class SMESHGUI; +class SMESHGUI_IdValidator; +class SMESHGUI_SpinBox; +class SMESHGUI_FilterDlg; +class SMESH_Actor; +class SVTK_Selector; +class LightApp_SelectionMgr; +class SMESH_LogicalFilter; + +//================================================================================= +// class : SMESHGUI_ScaleDlg +// purpose : +//================================================================================= +class SMESHGUI_EXPORT SMESHGUI_ScaleDlg : public SMESHGUI_PreviewDlg +{ + Q_OBJECT + +public: + SMESHGUI_ScaleDlg( SMESHGUI* ); + ~SMESHGUI_ScaleDlg(); + +private: + void Init( bool = true ); + void closeEvent( QCloseEvent* ); + void enterEvent( QEvent* ); /* mouse enter the QWidget */ + void hideEvent( QHideEvent* ); /* ESC key */ + void keyPressEvent( QKeyEvent* ); + int GetConstructorId(); + void setNewMeshName(); + + bool isValid(); + void getScale( SMESH::PointStruct& thePoint, + SMESH::double_array_var& theScaleFact); + + SMESHGUI_IdValidator* myIdValidator; + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + QString myElementsId; + int myNbOkElements; /* to check when elements are defined */ + + SVTK_Selector* mySelector; + + QWidget* myEditCurrentArgument; + + bool myBusy; + SMESH::SMESH_Mesh_var myMesh; + SMESH_Actor* myActor; + SMESH_LogicalFilter* myMeshOrSubMeshOrGroupFilter; + + SMESH::SMESH_IDSource_var mySelectedObject; + + QGroupBox* ConstructorsBox; + QButtonGroup* GroupConstructors; + QRadioButton* RadioButton1; + QRadioButton* RadioButton2; + QGroupBox* GroupButtons; + QPushButton* buttonOk; + QPushButton* buttonCancel; + QPushButton* buttonApply; + QPushButton* buttonHelp; + QGroupBox* GroupArguments; + QLabel* TextLabelElements; + QPushButton* SelectElementsButton; + QLineEdit* LineEditElements; + QCheckBox* CheckBoxMesh; + QLabel* TextLabel1; + QPushButton* SelectButton1; + QLabel* TextLabel1_1; + SMESHGUI_SpinBox* SpinBox1_1; + QLabel* TextLabel1_2; + SMESHGUI_SpinBox* SpinBox1_2; + QLabel* TextLabel1_3; + SMESHGUI_SpinBox* SpinBox1_3; + QLabel* TextLabel2; + SMESHGUI_SpinBox* SpinBox_FX; + QLabel* TextLabel3; + SMESHGUI_SpinBox* SpinBox_FY; + QLabel* TextLabel4; + SMESHGUI_SpinBox* SpinBox_FZ; + QGroupBox* ActionBox; + QButtonGroup* ActionGroup; + QCheckBox* MakeGroupsCheck; + QLineEdit* LineEditNewMesh; + + QString myHelpFileName; + + QPushButton* myFilterBtn; + SMESHGUI_FilterDlg* myFilterDlg; + + +protected slots: + virtual void onDisplaySimulation( bool ); + +private slots: + void ConstructorsClicked( int ); + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void ClickOnHelp(); + void SetEditCurrentArgument(); + void SelectionIntoArgument(); + void DeactivateActiveDialog(); + void ActivateThisDialog(); + void onTextChange( const QString& ); + void onSelectMesh( bool ); + void onActionClicked( int ); + void setFilters(); +}; + +#endif // SMESHGUI_SCALEDLG_H diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx index e0e63d4cc..8fff50e3c 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.cxx +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -1,37 +1,41 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI_Selection // File : SMESHGUI_Selection.cxx // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. -// SMESH includes // + +// SMESH includes #include "SMESHGUI_Selection.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_GEOMGenUtils.h" +#include "SMESHGUI_ComputeDlg.h" #include #include +#include // SALOME GUI includes #include @@ -85,7 +89,7 @@ void SMESHGUI_Selection::init( const QString& client, LightApp_SelectionMgr* mgr //function : processOwner //purpose : //======================================================================= -void SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow ) +bool SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow ) { const LightApp_SVTKDataOwner* owner = dynamic_cast ( ow ); @@ -93,6 +97,7 @@ void SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow ) myActors.append( dynamic_cast( owner->GetActor() ) ); else myActors.append( 0 ); + return true; } //======================================================================= @@ -107,16 +112,21 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const else if ( p=="elemTypes" ) val = QVariant( elemTypes( ind ) ); else if ( p=="isAutoColor" ) val = QVariant( isAutoColor( ind ) ); else if ( p=="numberOfNodes" ) val = QVariant( numberOfNodes( ind ) ); + else if ( p=="dim" ) val = QVariant( dim( ind ) ); else if ( p=="labeledTypes" ) val = QVariant( labeledTypes( ind ) ); else if ( p=="shrinkMode" ) val = QVariant( shrinkMode( ind ) ); else if ( p=="entityMode" ) val = QVariant( entityMode( ind ) ); else if ( p=="controlMode" ) val = QVariant( controlMode( ind ) ); + else if ( p=="isNumFunctor" ) val = QVariant( isNumFunctor( ind ) ); else if ( p=="displayMode" ) val = QVariant( displayMode( ind ) ); else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) ); + else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( ind ) ); else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) ); else if ( p=="isImported" ) val = QVariant( isImported( ind ) ); else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) ); else if ( p=="groupType" ) val = QVariant( groupType( ind ) ); + else if ( p=="quadratic2DMode") val = QVariant(quadratic2DMode(ind)); + else if ( p=="isDistributionVisible") val = QVariant(isDistributionVisible(ind)); if( val.isValid() ) return val; @@ -139,7 +149,7 @@ SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const //======================================================================= //function : elemTypes -//purpose : may return {'Edge' 'Face' 'Volume'} at most +//purpose : may return {'Elem0d' 'Edge' 'Face' 'Volume' 'BallElem'} at most //======================================================================= QList SMESHGUI_Selection::elemTypes( int ind ) const @@ -149,6 +159,8 @@ QList SMESHGUI_Selection::elemTypes( int ind ) const if ( actor ) { TVisualObjPtr object = actor->GetObject(); if ( object ) { + if ( object->GetNbEntities( SMDSAbs_0DElement )) types.append( "Elem0d" ); + if ( object->GetNbEntities( SMDSAbs_Ball )) types.append( "BallElem" ); if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" ); if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" ); if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" ); @@ -192,6 +204,34 @@ QString SMESHGUI_Selection::displayMode( int ind ) const return "Unknown"; } + +//======================================================================= +//function : quadratic2DMode +//purpose : return SMESH_Actor::EQuadratic2DRepresentation +//======================================================================= +QString SMESHGUI_Selection::quadratic2DMode( int ind ) const +{ + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + switch( actor->GetQuadratic2DRepresentation() ) { + case SMESH_Actor::eLines: return "eLines"; + case SMESH_Actor::eArcs: return "eArcs"; + default: break; + } + } + return "Unknown"; +} + +//======================================================================= +//function : isDistributionVisible +//purpose : Visible/Invisible distribution of the ScalarBar Actor +//======================================================================= + +bool SMESHGUI_Selection::isDistributionVisible(int ind) const { + SMESH_Actor* actor = getActor( ind ); + return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetDistributionVisibility()); +} + //======================================================================= //function : shrinkMode //purpose : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable' @@ -210,7 +250,7 @@ QString SMESHGUI_Selection::shrinkMode( int ind ) const //======================================================================= //function : entityMode -//purpose : may return {'Edge' 'Face' 'Volume'} at most +//purpose : may return {'Elem0d' 'Edge' 'Face' 'Volume' 'BallElem' } at most //======================================================================= QList SMESHGUI_Selection::entityMode( int ind ) const @@ -219,9 +259,11 @@ QList SMESHGUI_Selection::entityMode( int ind ) const SMESH_Actor* actor = getActor( ind ); if ( actor ) { unsigned int aMode = actor->GetEntityMode(); - if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume"); - if ( aMode & SMESH_Actor::eFaces ) types.append( "Face" ); - if ( aMode & SMESH_Actor::eEdges ) types.append( "Edge" ); + if ( aMode & SMESH_Actor::eVolumes ) types.append( "Volume" ); + if ( aMode & SMESH_Actor::eFaces ) types.append( "Face" ); + if ( aMode & SMESH_Actor::eEdges ) types.append( "Edge" ); + if ( aMode & SMESH_Actor::e0DElements ) types.append( "Elem0d" ); + if ( aMode & SMESH_Actor::eBallElem ) types.append( "BallElem" ); } return types; } @@ -233,28 +275,69 @@ QList SMESHGUI_Selection::entityMode( int ind ) const QString SMESHGUI_Selection::controlMode( int ind ) const { + SMESH_Actor* actor = getActor( ind ); + QString mode = "eNone"; + if ( actor ) { + switch( actor->GetControlMode() ) { + case SMESH_Actor::eLength: mode = "eLength"; break; + case SMESH_Actor::eLength2D: mode = "eLength2D"; break; + case SMESH_Actor::eFreeEdges: mode = "eFreeEdges"; break; + case SMESH_Actor::eFreeNodes: mode = "eFreeNodes"; break; + case SMESH_Actor::eFreeBorders: mode = "eFreeBorders"; break; + case SMESH_Actor::eFreeFaces: mode = "eFreeFaces"; break; + case SMESH_Actor::eMultiConnection: mode = "eMultiConnection"; break; + case SMESH_Actor::eMultiConnection2D: mode = "eMultiConnection2D"; break; + case SMESH_Actor::eArea: mode = "eArea"; break; + case SMESH_Actor::eVolume3D: mode = "eVolume3D"; break; + case SMESH_Actor::eMaxElementLength2D: mode = "eMaxElementLength2D"; break; + case SMESH_Actor::eMaxElementLength3D: mode = "eMaxElementLength3D"; break; + case SMESH_Actor::eTaper: mode = "eTaper"; break; + case SMESH_Actor::eAspectRatio: mode = "eAspectRatio"; break; + case SMESH_Actor::eAspectRatio3D: mode = "eAspectRatio3D"; break; + case SMESH_Actor::eMinimumAngle: mode = "eMinimumAngle"; break; + case SMESH_Actor::eWarping: mode = "eWarping"; break; + case SMESH_Actor::eSkew: mode = "eSkew"; break; + case SMESH_Actor::eBareBorderFace: mode = "eBareBorderFace"; break; + case SMESH_Actor::eBareBorderVolume: mode = "eBareBorderVolume"; break; + case SMESH_Actor::eOverConstrainedFace: mode = "eOverConstrainedFace"; break; + case SMESH_Actor::eOverConstrainedVolume: mode = "eOverConstrainedVolume"; break; + case SMESH_Actor::eCoincidentNodes: mode = "eCoincidentNodes"; break; + case SMESH_Actor::eCoincidentElems1D: mode = "eCoincidentElems1D"; break; + case SMESH_Actor::eCoincidentElems2D: mode = "eCoincidentElems2D"; break; + case SMESH_Actor::eCoincidentElems3D: mode = "eCoincidentElems3D"; break; + default:break; + } + } + return mode; +} + +bool SMESHGUI_Selection::isNumFunctor( int ind ) const +{ + bool result = false; SMESH_Actor* actor = getActor( ind ); if ( actor ) { switch( actor->GetControlMode() ) { - case SMESH_Actor::eLength: return "eLength"; - case SMESH_Actor::eLength2D: return "eLength2D"; - case SMESH_Actor::eFreeEdges: return "eFreeEdges"; - case SMESH_Actor::eFreeBorders: return "eFreeBorders"; - case SMESH_Actor::eFreeFaces: return "eFreeFaces"; - case SMESH_Actor::eMultiConnection: return "eMultiConnection"; - case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D"; - case SMESH_Actor::eArea: return "eArea"; - case SMESH_Actor::eVolume3D: return "eVolume3D"; - case SMESH_Actor::eTaper: return "eTaper"; - case SMESH_Actor::eAspectRatio: return "eAspectRatio"; - case SMESH_Actor::eAspectRatio3D: return "eAspectRatio3D"; - case SMESH_Actor::eMinimumAngle: return "eMinimumAngle"; - case SMESH_Actor::eWarping: return "eWarping"; - case SMESH_Actor::eSkew: return "eSkew"; - default:; + case SMESH_Actor::eLength: + case SMESH_Actor::eLength2D: + case SMESH_Actor::eMultiConnection: + case SMESH_Actor::eMultiConnection2D: + case SMESH_Actor::eArea: + case SMESH_Actor::eVolume3D: + case SMESH_Actor::eMaxElementLength2D: + case SMESH_Actor::eMaxElementLength3D: + case SMESH_Actor::eTaper: + case SMESH_Actor::eAspectRatio: + case SMESH_Actor::eAspectRatio3D: + case SMESH_Actor::eMinimumAngle: + case SMESH_Actor::eWarping: + case SMESH_Actor::eSkew: + result = true; + break; + default: + break; } } - return "eNone"; + return result; } //======================================================================= @@ -321,6 +404,42 @@ int SMESHGUI_Selection::numberOfNodes( int ind ) const return 0; } +//================================================================================ +/*! + * \brief return dimension of elements of the selected object + * + * \retval int - 0 for 0D elements, -1 for an empty object (the rest as usual) + */ +//================================================================================ + +int SMESHGUI_Selection::dim( int ind ) const +{ + int dim = -1; + if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" ) + { + _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() ); + CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() ); + + if ( ! CORBA::is_nil( obj )) { + SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( obj ); + if ( ! idSrc->_is_nil() ) + { + SMESH::array_of_ElementType_var types = idSrc->GetTypes(); + for ( int i = 0; i < types->length(); ++ i) + switch ( types[i] ) { + case SMESH::EDGE : dim = std::max( dim, 1 ); break; + case SMESH::FACE : dim = std::max( dim, 2 ); break; + case SMESH::VOLUME: dim = std::max( dim, 3 ); break; + case SMESH::ELEM0D: dim = std::max( dim, 0 ); break; + case SMESH::BALL : dim = std::max( dim, 0 ); break; + default:; + } + } + } + } + return dim; +} + //======================================================================= //function : isComputable //purpose : @@ -336,7 +455,7 @@ QVariant SMESHGUI_Selection::isComputable( int ind ) const SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io); // m,sm,gr->m if ( !mesh->_is_nil() ) {*/ _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() ); - //FindSObject( mesh ); + //FindSObject( mesh ); if ( so ) { CORBA::Object_var obj = SMESH::SObjectToObject(so, SMESH::GetActiveStudyDocument()); if(!CORBA::is_nil(obj)){ @@ -364,6 +483,23 @@ QVariant SMESHGUI_Selection::isComputable( int ind ) const return QVariant( false ); } +//======================================================================= +//function : isPreComputable +//purpose : +//======================================================================= + +QVariant SMESHGUI_Selection::isPreComputable( int ind ) const +{ + if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" ) + { + QMap modeMap; + _PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() ); + SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap ); + return QVariant( modeMap.size() > 1 ); + } + return QVariant( false ); +} + //======================================================================= //function : hasReference //purpose : @@ -387,7 +523,7 @@ QVariant SMESHGUI_Selection::isVisible( int ind ) const SMESH_Actor* actor = SMESH::FindActorByEntry( ent.toLatin1().data() ); if ( actor && actor->hasIO() ) { if(SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView()) - return QVariant( aViewWindow->isVisible( actor->getIO() ) ); + return QVariant( aViewWindow->isVisible( actor->getIO() ) ); } } return QVariant( false ); @@ -512,7 +648,6 @@ bool SMESHGUI_Selection::isImported( const int ind ) const QString e = entry( ind ); _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() ); bool res = false; - /* if( SO ) { SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( SO ) ); @@ -522,7 +657,6 @@ bool SMESHGUI_Selection::isImported( const int ind ) const res = strlen( (char*)inf->fileName ) > 0; } } - */ return res; } @@ -535,17 +669,19 @@ QString SMESHGUI_Selection::groupType( int ind ) const { QString e = entry( ind ); _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() ); - QString type; if( SO ) { - CORBA::Object_var obj = SMESH::SObjectToObject( SO ); - - SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( obj ); - SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( obj ); - if( !aGroup->_is_nil() ) - type = QString( "Group" ); - else if ( !aGroupOnGeom->_is_nil() ) - type = QString( "GroupOnGeom" ); + SMESH::SMESH_Group_var g = SMESH::SObjectToInterface( SO ); + if( !g->_is_nil() ) + return "Group"; + + SMESH::SMESH_GroupOnGeom_var gog = SMESH::SObjectToInterface( SO ); + if( !gog->_is_nil() ) + return "GroupOnGeom"; + + SMESH::SMESH_GroupOnFilter_var gof = SMESH::SObjectToInterface(SO); + if ( !gof->_is_nil() ) + return "GroupOnFilter"; } - return type; + return ""; } diff --git a/src/SMESHGUI/SMESHGUI_Selection.h b/src/SMESHGUI/SMESHGUI_Selection.h index 72ed58cb4..82293358c 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.h +++ b/src/SMESHGUI/SMESHGUI_Selection.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI_Selection // File : SMESHGUI_Selection.h // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. @@ -48,15 +49,21 @@ public: virtual void init( const QString&, LightApp_SelectionMgr* ); virtual QVariant parameter( const int, const QString& ) const; - virtual void processOwner( const LightApp_DataOwner* ); + virtual bool processOwner( const LightApp_DataOwner* ); // got from object, not from actor virtual bool isAutoColor( int ) const; virtual int numberOfNodes( int ) const; + virtual int dim( int ) const; virtual QVariant isComputable( int ) const; + virtual QVariant isPreComputable( int ) const; virtual QVariant hasReference( int ) const; virtual QVariant isVisible( int ) const; + virtual QString quadratic2DMode(int ) const; + + virtual bool isDistributionVisible(int ) const; + // parameters got from actor return nothing if an actor is not visible virtual QList elemTypes( int ) const; virtual QList labeledTypes( int ) const; @@ -64,6 +71,7 @@ public: virtual QString shrinkMode( int ) const; virtual QList entityMode( int ) const; virtual QString controlMode( int ) const; + virtual bool isNumFunctor( int ) const; virtual QString facesOrientationMode( int ) const; virtual QString groupType( int ) const; diff --git a/src/SMESHGUI/SMESHGUI_SelectionOp.cxx b/src/SMESHGUI/SMESHGUI_SelectionOp.cxx index 1cb2fc213..7e4039a3a 100644 --- a/src/SMESHGUI/SMESHGUI_SelectionOp.cxx +++ b/src/SMESHGUI/SMESHGUI_SelectionOp.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_SelectionOp.cxx // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. // SMESH includes @@ -423,9 +424,9 @@ void SMESHGUI_SelectionOp::selected( QStringList& names, SalomeApp_Study* _study = dynamic_cast( study() ); if( _study ) { - _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() ); - if( obj ) - names.append( obj->GetName().c_str() ); + _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() ); + if( obj ) + names.append( obj->GetName().c_str() ); } } } diff --git a/src/SMESHGUI/SMESHGUI_SelectionOp.h b/src/SMESHGUI/SMESHGUI_SelectionOp.h index 34e5e1135..874bcea22 100644 --- a/src/SMESHGUI/SMESHGUI_SelectionOp.h +++ b/src/SMESHGUI/SMESHGUI_SelectionOp.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_SelectionOp.h // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. // @@ -103,18 +104,18 @@ protected: //! Hilight object in VTK viewer void highlight( const Handle( SALOME_InteractiveObject )&, - const bool, const bool = true ); + const bool, const bool = true ); //! Select some nodes or elements in VTK void addOrRemoveIndex( const Handle( SALOME_InteractiveObject )&, - const TColStd_MapOfInteger&, const bool ); + const TColStd_MapOfInteger&, const bool isModeShift); SVTK_ViewWindow* viewWindow() const; SVTK_Selector* selector() const; //! Get names, types and ids of selected objects virtual void selected( QStringList&, - SMESHGUI_Dialog::TypesList&, QStringList& ) const; + SMESHGUI_Dialog::TypesList&, QStringList& ) const; //! Find type by id virtual int typeById( const QString&, const EntityType ) const; diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx index 1017b19e9..24d85f012 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_SewingDlg.cxx // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -385,9 +386,9 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId) LineEdit5->setEnabled(false); if (!CheckBoxPolygons->isVisible()) - CheckBoxPolygons->show(); + CheckBoxPolygons->show(); if (!CheckBoxPolyedrs->isVisible()) - CheckBoxPolyedrs->show(); + CheckBoxPolyedrs->show(); myOk5 = true; @@ -412,7 +413,7 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId) SMESH::SetPointRepresentation(false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); + aViewWindow->SetSelectionMode(CellSelection); break; } } @@ -439,7 +440,7 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId) QApplication::instance()->processEvents(); updateGeometry(); - resize( minimumSize() ); + resize(100,100); } //================================================================================= @@ -472,8 +473,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply() LineEdit4->text().toLong(), LineEdit5->text().toLong(), LineEdit6->text().toLong(), - toCreatePolygons, - toCreatePolyedrs); + toCreatePolygons, + toCreatePolyedrs); else if (aConstructorId == 1) anError = aMeshEditor->SewConformFreeBorders(LineEdit1->text().toLong(), LineEdit2->text().toLong(), @@ -486,8 +487,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply() LineEdit3->text().toLong(), LineEdit4->text().toLong(), LineEdit6->text().toLong(), - toCreatePolygons, - toCreatePolyedrs); + toCreatePolygons, + toCreatePolyedrs); else if (aConstructorId == 3) { QStringList aListElementsId1 = LineEdit1->text().split(" ", QString::SkipEmptyParts); QStringList aListElementsId2 = LineEdit4->text().split(" ", QString::SkipEmptyParts); @@ -532,6 +533,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply() Init(); ConstructorsClicked(GetConstructorId()); + + SMESHGUI::Modified(); } } @@ -580,10 +583,10 @@ void SMESHGUI_SewingDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -632,15 +635,15 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText) SMESH::SetPointRepresentation(true); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); + aViewWindow->SetSelectionMode(NodeSelection); const SMDS_MeshNode * n = aMesh->FindNode(theNewText.toInt()); if (n) { - newIndices.Add(n->GetID()); - mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( myActor->getIO(), true, true ); - + newIndices.Add(n->GetID()); + mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( myActor->getIO(), true, true ); + if (send == LineEdit1) myOk1 = true; else if (send == LineEdit2) @@ -658,7 +661,7 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText) SMESH::SetPointRepresentation(false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); + aViewWindow->SetSelectionMode(CellSelection); QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); @@ -667,8 +670,8 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText) for (int i = 0; i < aListId.count(); i++) { const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); if (e) - newIndices.Add(e->GetID()); - + newIndices.Add(e->GetID()); + if (!isEvenOneExists) isEvenOneExists = true; } @@ -676,7 +679,7 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText) mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( myActor->getIO(), true, true ); + aViewWindow->highlight( myActor->getIO(), true, true ); if (isEvenOneExists) { if (send == LineEdit1) diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.h b/src/SMESHGUI/SMESHGUI_SewingDlg.h index d21d1b573..f8ff617d0 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.h +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_SewingDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx index 82352334b..940dd4f3e 100644 --- a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_ShapeByMeshDlg.cxx // Author : Edward AGAPOV, Open CASCADE S.A.S. // SMESH includes @@ -129,7 +130,7 @@ QFrame* SMESHGUI_ShapeByMeshDlg::createMainFrame (QWidget* theParent) QLabel* anIdLabel = new QLabel( tr("ELEMENT_ID"), aMainGrp ); myElementId = new QLineEdit( aMainGrp ); myElementId->setValidator( new SMESHGUI_IdValidator( theParent, - !myIsMultipleAllowed ? 1 : 0 ) ); // 0 for any number of entities + !myIsMultipleAllowed ? 1 : 0 ) ); // 0 for any number of entities // shape name QLabel* aNameLabel = new QLabel( tr("GEOMETRY_NAME"), aMainGrp ); @@ -250,36 +251,36 @@ void SMESHGUI_ShapeByMeshOp::SetMesh (SMESH::SMESH_Mesh_ptr thePtr) int shapeDim = 0; // max dim with several shapes //if ( /*mySelectionMgr*/ selectionMgr()->isOk(anIObj) ) // check that the mesh has a valid shape { - _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in()); - GEOM::GEOM_Object_var mainShape = SMESH::GetGeom(aSO); - if ( !mainShape->_is_nil() ) - { - TopoDS_Shape aShape; - if ( GEOMBase::GetShape(mainShape, aShape)) - { - TopAbs_ShapeEnum types[4] = { TopAbs_EDGE, TopAbs_FACE, TopAbs_SHELL, TopAbs_SOLID }; - for ( int dim = 4; dim > 0; --dim ) { - TopAbs_ShapeEnum type = types[ dim - 1 ]; - TopAbs_ShapeEnum avoid = ( type == TopAbs_SHELL ) ? TopAbs_SOLID : TopAbs_SHAPE; - TopExp_Explorer exp( aShape, type, avoid ); - for ( ; nbShapes[ type ] < 2 && exp.More(); exp.Next() ) - ++nbShapes[ type ]; - if ( nbShapes[ type ] > 1 ) { - shapeDim = dim; - break; - } - } - } - } + _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in()); + GEOM::GEOM_Object_var mainShape = SMESH::GetGeom(aSO); + if ( !mainShape->_is_nil() ) + { + TopoDS_Shape aShape; + if ( GEOMBase::GetShape(mainShape, aShape)) + { + TopAbs_ShapeEnum types[4] = { TopAbs_EDGE, TopAbs_FACE, TopAbs_SHELL, TopAbs_SOLID }; + for ( int dim = 4; dim > 0; --dim ) { + TopAbs_ShapeEnum type = types[ dim - 1 ]; + TopAbs_ShapeEnum avoid = ( type == TopAbs_SHELL ) ? TopAbs_SOLID : TopAbs_SHAPE; + TopExp_Explorer exp( aShape, type, avoid ); + for ( ; nbShapes[ type ] < 2 && exp.More(); exp.Next() ) + ++nbShapes[ type ]; + if ( nbShapes[ type ] > 1 ) { + shapeDim = dim; + break; + } + } + } + } } if (shapeDim > 0) - { - if ( nbShapes[ TopAbs_SHELL ] + nbShapes[ TopAbs_SOLID ] > 1 ) - shapeDim = 3; - hasElement[ EDGE ] = shapeDim > 0 && myMesh->NbEdges(); - hasElement[ FACE ] = shapeDim > 1 && myMesh->NbFaces(); - hasElement[ VOLUME ] = shapeDim > 2 && myMesh->NbVolumes(); - } + { + if ( nbShapes[ TopAbs_SHELL ] + nbShapes[ TopAbs_SOLID ] > 1 ) + shapeDim = 3; + hasElement[ EDGE ] = shapeDim > 0 && myMesh->NbEdges(); + hasElement[ FACE ] = shapeDim > 1 && myMesh->NbFaces(); + hasElement[ VOLUME ] = shapeDim > 2 && myMesh->NbVolumes(); + } myHasSolids = nbShapes[ TopAbs_SOLID ]; } @@ -306,83 +307,83 @@ void SMESHGUI_ShapeByMeshOp::commitOperation() QStringList aListId = myDlg->myElementId->text().split( " ", QString::SkipEmptyParts); if (aListId.count() == 1) { - int elemID = (aListId.first()).toInt(); - myGeomObj = GEOM::GEOM_Object::_duplicate( - SMESHGUI::GetSMESHGen()->GetGeometryByMeshElement - ( myMesh.in(), elemID, myDlg->myGeomName->text().toLatin1().constData()) ); + int elemID = (aListId.first()).toInt(); + myGeomObj = GEOM::GEOM_Object::_duplicate( + SMESHGUI::GetSMESHGen()->GetGeometryByMeshElement + ( myMesh.in(), elemID, myDlg->myGeomName->text().toLatin1().constData()) ); } else { - GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen(); - _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); - - if (geomGen->_is_nil() || !aStudy) - return; - - GEOM::GEOM_IShapesOperations_var aShapesOp = - geomGen->GetIShapesOperations(aStudy->StudyId()); - if (aShapesOp->_is_nil() ) - return; - - TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE; - - std::map aGeomObjectsMap; - GEOM::GEOM_Object_var aGeomObject; - - GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh(); - - for ( int i = 0; i < aListId.count(); i++ ) - { - aGeomObject = - SMESHGUI::GetSMESHGen()->FindGeometryByMeshElement(myMesh.in(), aListId[i].toInt()); - - if (aGeomObject->_is_nil()) continue; - - double anId = aShapesOp->GetSubShapeIndex(aMeshShape, aGeomObject); - if (aShapesOp->IsDone() && aGeomObjectsMap.find(anId) == aGeomObjectsMap.end()) - { - aGeomObjectsMap[anId] = aGeomObject; - - TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)aGeomObject->GetShapeType(); - if (i == 0) - aGroupType = aSubShapeType; - else if (aSubShapeType != aGroupType) - aGroupType = TopAbs_SHAPE; - } - } - - int aNumberOfGO = aGeomObjectsMap.size(); - if (aNumberOfGO == 1) - myGeomObj = (*aGeomObjectsMap.begin()).second; - else if (aNumberOfGO > 1) - { - GEOM::GEOM_IGroupOperations_var aGroupOp = - geomGen->GetIGroupOperations(aStudy->StudyId()); - if(aGroupOp->_is_nil()) - return; - - GEOM::ListOfGO_var aGeomObjects = new GEOM::ListOfGO(); - aGeomObjects->length( aNumberOfGO ); - - int i = 0; - std::map::iterator anIter; - for (anIter = aGeomObjectsMap.begin(); anIter!=aGeomObjectsMap.end(); anIter++) - aGeomObjects[i++] = (*anIter).second; - - //create geometry group - myGeomObj = aGroupOp->CreateGroup(aMeshShape, aGroupType); - aGroupOp->UnionList(myGeomObj, aGeomObjects); - - if (!aGroupOp->IsDone()) - return; - } - - // publish the GEOM object in study - QString aNewGeomGroupName ( myDlg->myGeomName->text() ); - - SALOMEDS::SObject_var aNewGroupSO = - geomGen->AddInStudy(SMESHGUI::GetSMESHGen()->GetCurrentStudy(), myGeomObj, - aNewGeomGroupName.toLatin1().data(), aMeshShape); + GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen(); + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + + if (geomGen->_is_nil() || !aStudy) + return; + + GEOM::GEOM_IShapesOperations_var aShapesOp = + geomGen->GetIShapesOperations(aStudy->StudyId()); + if (aShapesOp->_is_nil() ) + return; + + TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE; + + std::map aGeomObjectsMap; + GEOM::GEOM_Object_var aGeomObject; + + GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh(); + + for ( int i = 0; i < aListId.count(); i++ ) + { + aGeomObject = + SMESHGUI::GetSMESHGen()->FindGeometryByMeshElement(myMesh.in(), aListId[i].toInt()); + + if (aGeomObject->_is_nil()) continue; + + double anId = aShapesOp->GetSubShapeIndex(aMeshShape, aGeomObject); + if (aShapesOp->IsDone() && aGeomObjectsMap.find(anId) == aGeomObjectsMap.end()) + { + aGeomObjectsMap[anId] = aGeomObject; + + TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)aGeomObject->GetShapeType(); + if (i == 0) + aGroupType = aSubShapeType; + else if (aSubShapeType != aGroupType) + aGroupType = TopAbs_SHAPE; + } + } + + int aNumberOfGO = aGeomObjectsMap.size(); + if (aNumberOfGO == 1) + myGeomObj = (*aGeomObjectsMap.begin()).second; + else if (aNumberOfGO > 1) + { + GEOM::GEOM_IGroupOperations_var aGroupOp = + geomGen->GetIGroupOperations(aStudy->StudyId()); + if(aGroupOp->_is_nil()) + return; + + GEOM::ListOfGO_var aGeomObjects = new GEOM::ListOfGO(); + aGeomObjects->length( aNumberOfGO ); + + int i = 0; + std::map::iterator anIter; + for (anIter = aGeomObjectsMap.begin(); anIter!=aGeomObjectsMap.end(); anIter++) + aGeomObjects[i++] = (*anIter).second; + + //create geometry group + myGeomObj = aGroupOp->CreateGroup(aMeshShape, aGroupType); + aGroupOp->UnionList(myGeomObj, aGeomObjects); + + if (!aGroupOp->IsDone()) + return; + } + + // publish the GEOM object in study + QString aNewGeomGroupName ( myDlg->myGeomName->text() ); + + SALOMEDS::SObject_var aNewGroupSO = + geomGen->AddInStudy(SMESHGUI::GetSMESHGen()->GetCurrentStudy(), myGeomObj, + aNewGeomGroupName.toLatin1().data(), aMeshShape); } } catch (const SALOME::SALOME_Exception& S_ex) { @@ -422,7 +423,7 @@ void SMESHGUI_ShapeByMeshOp::onSelectionDone() aList.First(), aString); if (nbElems > 0) { if (!myIsMultipleAllowed && nbElems != 1 ) - return; + return; setElementID( aString ); myDlg->setButtonEnabled( true, QtxDialog::OK ); } @@ -485,31 +486,31 @@ void SMESHGUI_ShapeByMeshOp::onElemIdChanged(const QString& theNewText) { if ( SMDS_Mesh* aMesh = actor->GetObject()->GetMesh() ) { - SMDSAbs_ElementType type = SMDSAbs_Edge; - switch ( myDlg->myElemTypeGroup->checkedId() ) { - case EDGE : type = SMDSAbs_Edge; break; - case FACE : type = SMDSAbs_Face; break; - case VOLUME: type = SMDSAbs_Volume; break; - default: return; - } - TColStd_MapOfInteger newIndices; - QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts); - for ( int i = 0; i < aListId.count(); i++ ) { - if ( const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() )) - if ( e->GetType() == type ) - newIndices.Add( e->GetID() ); - } - - if ( !newIndices.IsEmpty() ) - { - if (!myIsMultipleAllowed && newIndices.Extent() != 1) - return; - if ( SVTK_Selector* s = selector() ) { - s->AddOrRemoveIndex( actor->getIO(), newIndices, false ); - viewWindow()->highlight( actor->getIO(), true, true ); - myDlg->setButtonEnabled( true, QtxDialog::OK ); - } - } + SMDSAbs_ElementType type = SMDSAbs_Edge; + switch ( myDlg->myElemTypeGroup->checkedId() ) { + case EDGE : type = SMDSAbs_Edge; break; + case FACE : type = SMDSAbs_Face; break; + case VOLUME: type = SMDSAbs_Volume; break; + default: return; + } + TColStd_MapOfInteger newIndices; + QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts); + for ( int i = 0; i < aListId.count(); i++ ) { + if ( const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() )) + if ( e->GetType() == type ) + newIndices.Add( e->GetID() ); + } + + if ( !newIndices.IsEmpty() ) + { + if (!myIsMultipleAllowed && newIndices.Extent() != 1) + return; + if ( SVTK_Selector* s = selector() ) { + s->AddOrRemoveIndex( actor->getIO(), newIndices, false ); + viewWindow()->highlight( actor->getIO(), true, true ); + myDlg->setButtonEnabled( true, QtxDialog::OK ); + } + } } } } diff --git a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.h b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.h index 51f74b810..63477e34c 100644 --- a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_ShapeByMeshDlg.h // Author : Edward AGAPOV, Open CASCADE S.A.S. // diff --git a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx index 6a27b17a3..f93ce9556 100755 --- a/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_SingleEditDlg.cxx // Author : Sergey LITONIN, Open CASCADE S.A.S. // SMESH includes @@ -278,10 +279,10 @@ void SMESHGUI_SingleEditDlg::onHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -312,12 +313,14 @@ static bool findTriangles (const SMDS_MeshNode * theNode1, const SMDS_MeshElement* elem = it->next(); if (elem->GetType() == SMDSAbs_Face && emap.find(elem) != emap.end()) + { if (theTria1) { theTria2 = elem; break; } else { theTria1 = elem; } + } } return (theTria1 && theTria2); } @@ -348,13 +351,13 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText) int id1, id2; if ( !getNodeIds(myEdge->text(), id1, id2) ) - return; + return; const SMDS_MeshNode* aNode1 = aMesh->FindNode( id1 ); const SMDS_MeshNode* aNode2 = aMesh->FindNode( id2 ); if ( !aNode1 || !aNode2 || aNode1 == aNode2 ) - return; + return; // find a triangle and an edge index const SMDS_MeshElement* tria1; @@ -362,23 +365,23 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText) if ( findTriangles(aNode1,aNode2,tria1,tria2) ) { - newIndices.Add(tria1->GetID()); - - const SMDS_MeshNode* a3Nodes[3]; - SMDS_ElemIteratorPtr it; - int edgeInd = 2, i; - for (i = 0, it = tria1->nodesIterator(); it->more(); i++) { - a3Nodes[ i ] = static_cast(it->next()); - if (i > 0 && ( a3Nodes[ i ] == aNode1 && a3Nodes[ i - 1] == aNode2 || - a3Nodes[ i ] == aNode2 && a3Nodes[ i - 1] == aNode1 ) ) { - edgeInd = i - 1; - break; - } - } - newIndices.Add(-edgeInd-1); - - myOkBtn->setEnabled(true); - myApplyBtn->setEnabled(true); + newIndices.Add(tria1->GetID()); + + const SMDS_MeshNode* a3Nodes[3]; + SMDS_ElemIteratorPtr it; + int edgeInd = 2, i; + for (i = 0, it = tria1->nodesIterator(); it->more(); i++) { + a3Nodes[ i ] = static_cast(it->next()); + if (i > 0 && ( (a3Nodes[ i ] == aNode1 && a3Nodes[ i - 1] == aNode2) || + (a3Nodes[ i ] == aNode2 && a3Nodes[ i - 1] == aNode1) ) ) { + edgeInd = i - 1; + break; + } + } + newIndices.Add(-edgeInd-1); + + myOkBtn->setEnabled(true); + myApplyBtn->setEnabled(true); } mySelector->AddOrRemoveIndex(anIO,newIndices, false); SMESH::GetViewWindow(mySMESHGUI)->highlight( anIO, true, true ); @@ -416,17 +419,17 @@ void SMESHGUI_SingleEditDlg::onSelectionDone() { const SMDS_MeshElement* tria[2]; if( SMESH::GetEdgeNodes( mySelector, aVisualObj, anId1, anId2 ) >= 1 && - findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) ) + findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) ) { - QString aText = QString("%1-%2").arg(anId1).arg(anId2); - myEdge->setText(aText); - - myOkBtn->setEnabled(true); - myApplyBtn->setEnabled(true); + QString aText = QString("%1-%2").arg(anId1).arg(anId2); + myEdge->setText(aText); + + myOkBtn->setEnabled(true); + myApplyBtn->setEnabled(true); } else { - myEdge->clear(); + myEdge->clear(); } } } @@ -494,8 +497,8 @@ bool SMESHGUI_SingleEditDlg::onApply() if (aMesh->_is_nil()) { SUIT_MessageBox::information(SMESH::GetDesktop(mySMESHGUI), - tr("SMESH_ERROR"), - tr("SMESHG_NO_MESH")); + tr("SMESH_ERROR"), + tr("SMESHG_NO_MESH")); return false; } @@ -513,6 +516,7 @@ bool SMESHGUI_SingleEditDlg::onApply() mySelectionMgr->setSelectedObjects(aList, false); onSelectionDone(); SMESH::UpdateView(); + SMESHGUI::Modified(); } return aResult; diff --git a/src/SMESHGUI/SMESHGUI_SingleEditDlg.h b/src/SMESHGUI/SMESHGUI_SingleEditDlg.h index df0192cb0..cc04610ac 100755 --- a/src/SMESHGUI/SMESHGUI_SingleEditDlg.h +++ b/src/SMESHGUI/SMESHGUI_SingleEditDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESHGUI_SingleEditDlg.h // Author : Sergey LITONIN, Open CASCADE S.A.S. // diff --git a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx index c2144b1f4..2eb9b521e 100644 --- a/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_SmoothingDlg.cxx // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -84,6 +85,24 @@ #define SPACING 6 #define MARGIN 11 +/*! + \class BusyLocker + \brief Simple 'busy state' flag locker. + \internal +*/ + +class BusyLocker +{ +public: + //! Constructor. Sets passed boolean flag to \c true. + BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; } + //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false. + ~BusyLocker() { myBusy = false; } +private: + bool& myBusy; //! External 'busy state' boolean flag +}; + + //================================================================================= // function : SMESHGUI_SmoothingDlg() // purpose : constructor @@ -137,8 +156,9 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule ) LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); - QPushButton* filterElemBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); - connect(filterElemBtn, SIGNAL(clicked()), this, SLOT(setElemFilters())); + LineEditElements->setMaxLength(-1); + myElemFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myElemFilterBtn, SIGNAL(clicked()), this, SLOT(setElemFilters())); // Control for the whole mesh selection CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); @@ -151,6 +171,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule ) LineEditNodes = new QLineEdit(GroupArguments); LineEditNodes->setValidator(myIdValidator); + LineEditNodes->setMaxLength(-1); QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); connect(filterNodeBtn, SIGNAL(clicked()), this, SLOT(setNodeFilters())); @@ -175,7 +196,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule ) GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 2); - GroupArgumentsLayout->addWidget(filterElemBtn, 0, 3); + GroupArgumentsLayout->addWidget(myElemFilterBtn, 0, 3); GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4); GroupArgumentsLayout->addWidget(TextLabelNodes, 2, 0); GroupArgumentsLayout->addWidget(SelectNodesButton, 2, 1); @@ -229,7 +250,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule ) SpinBox_IterationLimit->setRange(1, 999999); SpinBox_IterationLimit->setValue(20); - SpinBox_AspectRatio->RangeStepAndValidator(0.0, +999999.999, 0.1, 3); + SpinBox_AspectRatio->RangeStepAndValidator(0.0, +999999.999, 0.1, "parametric_precision"); SpinBox_AspectRatio->SetValue(1.1); GroupArguments->show(); @@ -241,12 +262,8 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule ) mySMESHGUI->SetActiveDialogBox(this); // Costruction of the logical filter for the elements: mesh/sub-mesh/group - SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH); - SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP); - QList aListOfFilters; - if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); - if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); + aListOfFilters << new SMESH_TypeFilter(MESHorSUBMESH) << new SMESH_TypeFilter(GROUP); myMeshOrSubMeshOrGroupFilter = new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR); @@ -306,10 +323,10 @@ void SMESHGUI_SmoothingDlg::Init() LineEditElements->setFocus(); LineEditElements->clear(); LineEditNodes->clear(); - myElementsId = ""; myNbOkElements = 0; myNbOkNodes = 0; myActor = 0; + myIO.Nullify(); myMesh = SMESH::SMESH_Mesh::_nil(); CheckBoxMesh->setChecked(false); @@ -329,7 +346,7 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply() return false; if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) { - QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts); + QStringList aListElementsId = LineEditElements->text().split(" ", QString::SkipEmptyParts); QStringList aListNodesId = LineEditNodes->text().split(" ", QString::SkipEmptyParts); SMESH::long_array_var anElementsId = new SMESH::long_array; @@ -363,35 +380,31 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply() SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + if ( CheckBoxParametric->isChecked() ) { if(CheckBoxMesh->isChecked()) - aResult = aMeshEditor->SmoothParametricObject(mySelectedObject, aNodesId.inout(), - anIterationLimit, aMaxAspectRatio, aMethod); - else - aResult = aMeshEditor->SmoothParametric(anElementsId.inout(), aNodesId.inout(), - anIterationLimit, aMaxAspectRatio, aMethod); + aResult = aMeshEditor->SmoothParametricObject(mySelectedObject, aNodesId.inout(), + anIterationLimit, aMaxAspectRatio, aMethod); + else + aResult = aMeshEditor->SmoothParametric(anElementsId.inout(), aNodesId.inout(), + anIterationLimit, aMaxAspectRatio, aMethod); } else { if(CheckBoxMesh->isChecked()) - aResult = aMeshEditor->SmoothObject(mySelectedObject, aNodesId.inout(), - anIterationLimit, aMaxAspectRatio, aMethod); - else - aResult = aMeshEditor->Smooth(anElementsId.inout(), aNodesId.inout(), - anIterationLimit, aMaxAspectRatio, aMethod); + aResult = aMeshEditor->SmoothObject(mySelectedObject, aNodesId.inout(), + anIterationLimit, aMaxAspectRatio, aMethod); + else + aResult = aMeshEditor->Smooth(anElementsId.inout(), aNodesId.inout(), + anIterationLimit, aMaxAspectRatio, aMethod); } - myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) ); - } catch (...) { } if (aResult) { - Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); - - SALOME_ListIO aList; - aList.Append(anIO); - mySelectionMgr->setSelectedObjects(aList, false); - SMESH::UpdateView(); + SMESH::Update(myIO, SMESH::eDisplay); + SMESHGUI::Modified(); Init(); mySelectedObject = SMESH::SMESH_IDSource::_nil(); @@ -448,10 +461,10 @@ void SMESHGUI_SmoothingDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -464,10 +477,10 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText) QLineEdit* send = (QLineEdit*)sender(); // return if busy - if (myBusy) return; + if (myBusy || myIO.IsNull()) return; // set busy flag - myBusy = true; + BusyLocker lock( myBusy ); if (send == LineEditElements) myNbOkElements = 0; @@ -478,40 +491,37 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText) buttonApply->setEnabled(false); // hilight entered elements/nodes - SMDS_Mesh* aMesh = 0; - if (myActor) - aMesh = myActor->GetObject()->GetMesh(); - - if (aMesh) { - - QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); - - if (send == LineEditElements) { - const Handle(SALOME_InteractiveObject)& anIO = myActor->getIO(); - TColStd_MapOfInteger newIndices; - for (int i = 0; i < aListId.count(); i++) { - const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); - if (e) - newIndices.Add(e->GetID()); - myNbOkElements++; + SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0; + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); + + if (send == LineEditElements) { + TColStd_MapOfInteger newIndices; + for (int i = 0; i < aListId.count(); i++) { + int id = aListId[ i ].toInt(); + if ( id > 0 ) { + bool validId = aMesh ? ( aMesh->FindElement( id ) != 0 ) : ( myMesh->GetElementType( id, true ) != SMESH::EDGE ); + if ( validId ) + newIndices.Add( id ); } - mySelector->AddOrRemoveIndex(anIO, newIndices, false); + myNbOkElements = newIndices.Extent(); + mySelector->AddOrRemoveIndex(myIO, newIndices, false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( anIO, true, true ); - myElementsId = theNewText; - - } else if (send == LineEditNodes) { - TColStd_MapOfInteger newIndices; - - for (int i = 0; i < aListId.count(); i++) { - const SMDS_MeshNode * n = aMesh->FindNode(aListId[ i ].toInt()); - if (n) - newIndices.Add(n->GetID()); - myNbOkNodes++; + aViewWindow->highlight( myIO, true, true ); + } + } + else if (send == LineEditNodes) { + TColStd_MapOfInteger newIndices; + for (int i = 0; i < aListId.count(); i++) { + int id = aListId[ i ].toInt(); + if ( id > 0 ) { + bool validId = aMesh ? ( aMesh->FindNode( id ) != 0 ) : ( myMesh->GetElementType( id, false ) != SMESH::EDGE ); + if ( validId ) + newIndices.Add( id ); } - mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false); + myNbOkNodes = newIndices.Extent(); + mySelector->AddOrRemoveIndex(myIO, newIndices, false); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( myActor->getIO(), true, true ); + aViewWindow->highlight( myIO, true, true ); } } @@ -519,8 +529,6 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText) buttonOk->setEnabled(true); buttonApply->setEnabled(true); } - - myBusy = false; } //================================================================================= @@ -534,19 +542,23 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument() // clear QString aString = ""; - myBusy = true; + // set busy flag + BusyLocker lock( myBusy ); + if (myEditCurrentArgument == LineEditElements || myEditCurrentArgument == LineEditNodes) { myEditCurrentArgument->setText(aString); - if (myEditCurrentArgument == LineEditElements) + if (myEditCurrentArgument == LineEditElements) { myNbOkElements = 0; - else + myActor = 0; + myIO.Nullify(); + } + else { myNbOkNodes = 0; + } buttonOk->setEnabled(false); buttonApply->setEnabled(false); - myActor = 0; } - myBusy = false; if (!GroupButtons->isEnabled()) // inactive return; @@ -559,50 +571,45 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument() return; Handle(SALOME_InteractiveObject) IO = aList.First(); - myMesh = SMESH::GetMeshByIO(IO); - if (myMesh->_is_nil()) - return; - - myActor = SMESH::FindActorByObject(myMesh); - if (!myActor) - return; - - int aNbUnits = 0; if (myEditCurrentArgument == LineEditElements) { - myElementsId = ""; + myMesh = SMESH::GetMeshByIO(IO); + if (myMesh->_is_nil()) + return; + myIO = IO; + myActor = SMESH::FindActorByObject(myMesh); if (CheckBoxMesh->isChecked()) { SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); - if (!SMESH::IObjectToInterface(IO)->_is_nil()) - mySelectedObject = SMESH::IObjectToInterface(IO); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( myIO ); + if ( !CORBA::is_nil( obj ) ) + mySelectedObject = obj; else return; + myNbOkElements = true; } else { - aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString); - myElementsId = aString; - if (aNbUnits < 1) + // get indices of selected elements + TColStd_IndexedMapOfInteger aMapIndex; + mySelector->GetIndex(IO,aMapIndex); + myNbOkElements = aMapIndex.Extent(); + + if (myNbOkElements < 1) return; + + QStringList elements; + for ( int i = 0; i < myNbOkElements; ++i ) + elements << QString::number( aMapIndex( i+1 ) ); + aString = elements.join(" "); } - } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myActor) { - myNbOkNodes = 0; - aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); - } else { + } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myIO == IO ) { + myNbOkNodes = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); } - myBusy = true; myEditCurrentArgument->setText(aString); myEditCurrentArgument->repaint(); myEditCurrentArgument->setEnabled(false); // to update lineedit IPAL 19809 myEditCurrentArgument->setEnabled(true); - myBusy = false; - - // OK - if (myEditCurrentArgument == LineEditElements) - myNbOkElements = aNbUnits; - else if (myEditCurrentArgument == LineEditNodes) - myNbOkNodes = aNbUnits; if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) { buttonOk->setEnabled(true); @@ -629,21 +636,21 @@ void SMESHGUI_SmoothingDlg::SetEditCurrentArgument() myEditCurrentArgument = LineEditElements; SMESH::SetPointRepresentation(false); if (CheckBoxMesh->isChecked()) { - // mySelectionMgr->setSelectionModes(ActorSelection); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + // mySelectionMgr->setSelectionModes(ActorSelection); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); } else { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(FaceSelection); + } } else if (send == SelectNodesButton) { - LineEditNodes->clear(); + LineEditNodes->clear(); myEditCurrentArgument = LineEditNodes; SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) { - aViewWindow->SetSelectionMode(NodeSelection); - } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) { + aViewWindow->SetSelectionMode(NodeSelection); + } } myEditCurrentArgument->setFocus(); @@ -727,6 +734,7 @@ void SMESHGUI_SmoothingDlg::onSelectMesh (bool toSelectMesh) TextLabelElements->setText(tr("SMESH_NAME")); else TextLabelElements->setText(tr("SMESH_ID_ELEMENTS")); + myElemFilterBtn->setEnabled(!toSelectMesh); if (myEditCurrentArgument != LineEditElements && myEditCurrentArgument != LineEditNodes) { @@ -779,6 +787,12 @@ void SMESHGUI_SmoothingDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_SmoothingDlg::setFilters( const bool theIsElem ) { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) { QList types; diff --git a/src/SMESHGUI/SMESHGUI_SmoothingDlg.h b/src/SMESHGUI/SMESHGUI_SmoothingDlg.h index 40b8170a3..efb9723a6 100644 --- a/src/SMESHGUI/SMESHGUI_SmoothingDlg.h +++ b/src/SMESHGUI/SMESHGUI_SmoothingDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_SmoothingDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -32,6 +33,9 @@ // Qt includes #include +// SALOME GUI includes +#include + // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Mesh) @@ -78,7 +82,6 @@ private: SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ SMESHGUI_IdValidator* myIdValidator; LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ - QString myElementsId; int myNbOkElements; /* to check when elements are defined */ int myNbOkNodes; /* to check when fixed nodes are defined */ int myConstructorId; /* Current constructor id = radio button id */ @@ -90,6 +93,7 @@ private: bool myBusy; SMESH::SMESH_Mesh_var myMesh; SMESH_Actor* myActor; + Handle(SALOME_InteractiveObject) myIO; SMESH_LogicalFilter* myMeshOrSubMeshOrGroupFilter; QGroupBox* GroupConstructors; @@ -116,7 +120,8 @@ private: QCheckBox* CheckBoxParametric; QString myHelpFileName; - + + QPushButton* myElemFilterBtn; SMESHGUI_FilterDlg* myFilterDlg; private slots: diff --git a/src/SMESHGUI/SMESHGUI_SpinBox.cxx b/src/SMESHGUI/SMESHGUI_SpinBox.cxx index 1b30cb08a..cda1357f0 100644 --- a/src/SMESHGUI/SMESHGUI_SpinBox.cxx +++ b/src/SMESHGUI/SMESHGUI_SpinBox.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_SpinBox.cxx // Author : Lucien PIGNOLONI, Open CASCADE S.A.S. @@ -26,9 +27,12 @@ // #include "SMESHGUI_SpinBox.h" +#include +#include + // Qt includes -#include #include +#include //================================================================================= // class : SMESHGUI_SpinBox() @@ -62,7 +66,7 @@ void SMESHGUI_SpinBox::SetStep( double newStep ) //================================================================================= void SMESHGUI_SpinBox::SetValue( double v ) { - setValue(v); + setValue(valueFromText(textFromValue(v))); editor()->setCursorPosition( 0 ); } @@ -93,28 +97,29 @@ QLineEdit* SMESHGUI_SpinBox::editor() const return SalomeApp_DoubleSpinBox::lineEdit(); } -//================================================================================= -// function : validator() -// purpose : returns validator -//================================================================================= -QDoubleValidator* SMESHGUI_SpinBox::validator() const -{ - return (QDoubleValidator*)editor()->validator(); -} - //================================================================================= // function : RangeStepAndValidator() // purpose : //================================================================================= void SMESHGUI_SpinBox::RangeStepAndValidator( double min, - double max, - double step, - unsigned short precision ) + double max, + double step, + const char* quantity ) { - setPrecision(precision*(-1)); // PAL8769. Minus is for using 'g' double->string conversion specifier, - // see QtxDoubleSpinBox::mapValueToText( double v ) - setDecimals(32); + // Obtain precision from preferences + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int precision = resMgr->integerValue( "SMESH", quantity, -3 ); + + setPrecision(precision); // PAL8769. Minus is for using 'g' double->string conversion specifier, + // see QtxDoubleSpinBox::mapValueToText( double v ) + // san: this can be achieved using preferences + setDecimals( 20 ); // qAbs(precision) setRange(min, max); setSingleStep( step ); setDefaultValue( min ); + + // Add a hint for the user saying how to tune precision + QString userPropName = QObject::tr( QString( "SMESH_PREF_%1" ).arg( quantity ).toLatin1().constData() ); + setProperty( "validity_tune_hint", + QVariant( QObject::tr( "SMESH_PRECISION_HINT" ).arg( userPropName ) ) ); } diff --git a/src/SMESHGUI/SMESHGUI_SpinBox.h b/src/SMESHGUI/SMESHGUI_SpinBox.h index cdca31653..d12cd6560 100644 --- a/src/SMESHGUI/SMESHGUI_SpinBox.h +++ b/src/SMESHGUI/SMESHGUI_SpinBox.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_SpinBox.h // Author : Lucien PIGNOLONI, Open CASCADE S.A.S. @@ -52,14 +53,13 @@ public: ~SMESHGUI_SpinBox(); void RangeStepAndValidator( double = -1000000.0, - double = +1000000.0, - double = 100.0, - unsigned short = 3 ); + double = +1000000.0, + double = 100.0, + const char* = "length_precision" ); void SetValue( double ); double GetValue() const; QString GetString() const; QLineEdit* editor() const; - QDoubleValidator* validator() const; public slots: void SetStep( double ); diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx deleted file mode 100644 index 4b7540fc0..000000000 --- a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_StandardMeshInfosDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes -// -#include "SMESHGUI_StandardMeshInfosDlg.h" - -#include "SMESHGUI.h" -#include "SMESHGUI_Utils.h" -#include "SMESHGUI_MeshUtils.h" - -#include - -// SALOME KERNEL includes -#include -#include - -// SALOME GUI includes -#include -#include -#include -#include -#include - -#include -#include - -#include - -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Mesh) -#include CORBA_SERVER_HEADER(SMESH_Group) - -#define SPACING 6 -#define MARGIN 11 - -//================================================================================= -/*! - * SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg - * - * Constructor - */ -//================================================================================= -SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg( SMESHGUI* theModule ) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), - mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) -{ - setModal(false); - setAttribute(Qt::WA_DeleteOnClose, true); - setWindowTitle(tr("SMESH_STANDARD_MESHINFO_TITLE")); - setSizeGripEnabled(true); - - myStartSelection = true; - myIsActiveWindow = true; - - // dialog layout - QVBoxLayout* aDlgLayout = new QVBoxLayout(this); - aDlgLayout->setSpacing(SPACING); - aDlgLayout->setMargin(MARGIN); - - // mesh group box - myMeshGroup = new QGroupBox(tr("SMESH_MESH"), this); - QHBoxLayout* myMeshGroupLayout = new QHBoxLayout(myMeshGroup); - myMeshGroupLayout->setSpacing(SPACING); - myMeshGroupLayout->setMargin(MARGIN); - - // select button, label and line edit with mesh name - myNameLab = new QLabel(tr("SMESH_NAME"), myMeshGroup); - myMeshGroupLayout->addWidget(myNameLab); - - QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("SMESH",tr("ICON_SELECT"))); - mySelectBtn = new QPushButton(myMeshGroup); - mySelectBtn->setIcon(image0); - myMeshGroupLayout->addWidget(mySelectBtn); - - myMeshLine = new QLineEdit(myMeshGroup); - myMeshGroupLayout->addWidget(myMeshLine); - - aDlgLayout->addWidget(myMeshGroup); - - // information group box - myInfoGroup = new QGroupBox(tr("SMESH_INFORMATION"), this); - QVBoxLayout* myInfoGroupLayout = new QVBoxLayout(myInfoGroup); - myInfoGroupLayout->setSpacing(SPACING); - myInfoGroupLayout->setMargin(MARGIN); - - // information text browser - myInfo = new QTextBrowser(myInfoGroup); - myInfo->setMinimumSize(200, 150); - myInfoGroupLayout->addWidget(myInfo); - - aDlgLayout->addWidget(myInfoGroup); - - // buttons group - myButtonsGroup = new QGroupBox(this); - QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout(myButtonsGroup); - myButtonsGroupLayout->setSpacing(SPACING); - myButtonsGroupLayout->setMargin(MARGIN); - - // buttons --> OK and Help buttons - myOkBtn = new QPushButton(tr("SMESH_BUT_OK"), myButtonsGroup); - myOkBtn->setAutoDefault(true); myOkBtn->setDefault(true); - myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP"), myButtonsGroup); - myHelpBtn->setAutoDefault(true); - - myButtonsGroupLayout->addWidget(myOkBtn); - myButtonsGroupLayout->addSpacing(10); - myButtonsGroupLayout->addStretch(); - myButtonsGroupLayout->addWidget(myHelpBtn); - - aDlgLayout->addWidget(myButtonsGroup); - - mySMESHGUI->SetActiveDialogBox(this); - - // connect signals - connect( myOkBtn, SIGNAL(clicked()), this, SLOT(close())); - connect( myHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp())); - connect( mySelectBtn, SIGNAL(clicked()), this, SLOT(onStartSelection())); - connect( mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(close())); - connect( mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); - connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); - - // init dialog with current selection - myMeshFilter = new SMESH_TypeFilter (MESH); - mySelectionMgr->installFilter(myMeshFilter); - onSelectionChanged(); - - myHelpFileName = "mesh_infos_page.html#standard_mesh_infos_anchor"; -} - -//================================================================================= -/*! - * SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg - * - * Destructor - */ -//================================================================================= -SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg() -{ -} - -//================================================================================= -/*! - * SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos - */ -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos() -{ - SUIT_OverrideCursor wc; - - SALOME_ListIO aList; - mySelectionMgr->selectedObjects(aList); - - int nbSel = aList.Extent(); - myInfo->clear(); - if (nbSel == 1) { - myStartSelection = false; - myMeshLine->setText(""); - SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(aList.First()); - - if (!aMesh->_is_nil()) { - QString aName, anInfo; - SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName); - myMeshLine->setText(aName); - int aNbNodes = (int)aMesh->NbNodes(); - int aNbEdges = (int)aMesh->NbEdges(); - int aNbFaces = (int)aMesh->NbFaces(); - int aNbVolumes = (int)aMesh->NbVolumes(); - - int aDimension = 0; - double aNbDimElements = 0; - if (aNbVolumes > 0) { - aNbDimElements = aNbVolumes; - aDimension = 3; - } - else if(aNbFaces > 0) { - aNbDimElements = aNbFaces; - aDimension = 2; - } - else if(aNbEdges > 0) { - aNbDimElements = aNbEdges; - aDimension = 1; - } - else if(aNbNodes > 0) { - aNbDimElements = aNbNodes; - aDimension = 0; - } - - // information about the mesh - anInfo.append(QString("Nb of element of dimension %1: %2
                    ").arg(aDimension).arg(aNbDimElements)); - anInfo.append(QString("Nb of nodes: %1

                    ").arg(aNbNodes)); - - // information about the groups of the mesh - _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); - _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh); - _PTR(SObject) anObj; - - bool hasGroup = false; - - // info about groups on nodes - aMeshSO->FindSubObject(SMESH::Tag_NodeGroups, anObj); - if (anObj) { - _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj); - if (it->More()) { - anInfo.append(QString("Groups:

                    ")); - hasGroup = true; - } - for ( ; it->More(); it->Next()) { - _PTR(SObject) subObj = it->Value(); - CORBA::Object_var anObject = SMESH::SObjectToObject(subObj); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject); - if (!aGroup->_is_nil()) { - anInfo.append(QString("- %1
                    ").arg(aGroup->GetName())); - anInfo.append(QString("%1
                    ").arg("on nodes")); - anInfo.append(QString("%1
                    ").arg(aGroup->Size())); - // check if the group based on geometry - SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); - if (!aGroupOnGeom->_is_nil()) { - GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); - QString aShapeName = ""; - _PTR(SObject) aGeomObj, aRef; - if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef)) - aShapeName = aRef->GetName().c_str(); - anInfo.append(QString("based on %1 geometry object

                    ").arg(aShapeName)); - } else { - anInfo.append(QString("
                    ")); - } - } - } - } - - // info about groups on edges - anObj.reset(); - aMeshSO->FindSubObject(SMESH::Tag_EdgeGroups, anObj); - if (anObj) { - _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj); - if (!hasGroup && it->More()) { - anInfo.append(QString("Groups:

                    ")); - hasGroup = true; - } - for ( ; it->More(); it->Next()) { - _PTR(SObject) subObj = it->Value(); - CORBA::Object_var anObject = SMESH::SObjectToObject(subObj); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject); - if (!aGroup->_is_nil()) { - anInfo.append(QString("- %1
                    ").arg(aGroup->GetName())); - anInfo.append(QString("%1
                    ").arg("on edges")); - anInfo.append(QString("%1
                    ").arg(aGroup->Size())); - // check if the group based on geometry - SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); - if (!aGroupOnGeom->_is_nil()) { - GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); - QString aShapeName = ""; - _PTR(SObject) aGeomObj, aRef; - if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef)) - aShapeName = aRef->GetName().c_str(); - anInfo.append(QString("based on %1 geometry object

                    ").arg(aShapeName)); - } else { - anInfo.append(QString("
                    ")); - } - } - } - } - - // info about groups on faces - anObj.reset(); - aMeshSO->FindSubObject(SMESH::Tag_FaceGroups, anObj); - if (anObj) { - _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj); - if (!hasGroup && it->More()) { - anInfo.append(QString("Groups:

                    ")); - hasGroup = true; - } - for ( ; it->More(); it->Next()) { - _PTR(SObject) subObj = it->Value(); - CORBA::Object_var anObject = SMESH::SObjectToObject(subObj); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject); - if (!aGroup->_is_nil()) { - anInfo.append(QString("- %1
                    ").arg(aGroup->GetName())); - anInfo.append(QString("%1
                    ").arg("on faces")); - anInfo.append(QString("%1
                    ").arg(aGroup->Size())); - // check if the group based on geometry - SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); - if (!aGroupOnGeom->_is_nil()) { - GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); - QString aShapeName = ""; - _PTR(SObject) aGeomObj, aRef; - if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef)) - aShapeName = aRef->GetName().c_str(); - anInfo.append(QString("based on %1 geometry object

                    ").arg(aShapeName)); - } else { - anInfo.append(QString("
                    ")); - } - } - } - } - - // info about groups on volumes - anObj.reset(); - aMeshSO->FindSubObject(SMESH::Tag_VolumeGroups, anObj); - if (anObj) { - _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj); - if (!hasGroup && it->More()) - anInfo.append(QString("Groups:
                    ")); - for ( ; it->More(); it->Next()) { - _PTR(SObject) subObj = it->Value(); - CORBA::Object_var anObject = SMESH::SObjectToObject(subObj); - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject); - if (!aGroup->_is_nil()) { - anInfo.append(QString("- %1
                    ").arg(aGroup->GetName())); - anInfo.append(QString("%1
                    ").arg("on volumes")); - anInfo.append(QString("%1
                    ").arg(aGroup->Size())); - // check if the group based on geometry - SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); - if (!aGroupOnGeom->_is_nil()) { - GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); - QString aShapeName = ""; - _PTR(SObject) aGeomObj, aRef; - if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef)) - aShapeName = aRef->GetName().c_str(); - anInfo.append(QString("based on %1 geometry object

                    ").arg(aShapeName)); - } else { - anInfo.append(QString("
                    ")); - } - } - } - } - - myInfo->setText(anInfo); - return; - } - } -} - -//================================================================================= -// function : SelectionIntoArgument() -// purpose : Called when selection has changed -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::onSelectionChanged() -{ - if (myStartSelection) - DumpMeshInfos(); -} - -//================================================================================= -// function : closeEvent() -// purpose : -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::closeEvent (QCloseEvent* e) -{ - mySelectionMgr->clearFilters(); - mySMESHGUI->ResetState(); - QDialog::closeEvent(e); -} - -//================================================================================= -// function : windowActivationChange() -// purpose : called when window is activated/deactivated -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::windowActivationChange (bool oldActive) -{ - QDialog::windowActivationChange(oldActive); - if (isActiveWindow() && myIsActiveWindow != isActiveWindow()) - ActivateThisDialog(); - myIsActiveWindow = isActiveWindow(); -} - -//================================================================================= -// function : DeactivateActiveDialog() -// purpose : -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::DeactivateActiveDialog() -{ - disconnect(mySelectionMgr, 0, this, 0); -} - -//================================================================================= -// function : ActivateThisDialog() -// purpose : -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::ActivateThisDialog() -{ - /* Emit a signal to deactivate any active dialog */ - mySMESHGUI->EmitSignalDeactivateDialog(); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); -} - -//================================================================================= -// function : onStartSelection() -// purpose : starts selection -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::onStartSelection() -{ - myStartSelection = true; - mySelectionMgr->installFilter(myMeshFilter); - myMeshLine->setText(tr("Select a mesh")); - onSelectionChanged(); - myStartSelection = true; -} - -//================================================================================= -// function : onHelp() -// purpose : -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::onHelp() -{ - LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) - app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); - else { - QString platform; -#ifdef WIN32 - platform = "winapplication"; -#else - platform = "application"; -#endif - SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); - } -} - -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void SMESHGUI_StandardMeshInfosDlg::keyPressEvent( QKeyEvent* e ) -{ - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; - - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - onHelp(); - } -} diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h deleted file mode 100644 index e6e34328a..000000000 --- a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_StandardMeshInfosDlg.h -// Author : Michael ZORIN, Open CASCADE S.A.S. -// -#ifndef SMESHGUI_STANDARDMESHINFOSDLG_H -#define SMESHGUI_STANDARDMESHINFOSDLG_H - -// SMESH includes -#include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include - -class QGroupBox; -class QLabel; -class QPushButton; -class QLineEdit; -class QTextBrowser; -class SMESHGUI; -class LightApp_SelectionMgr; -class SUIT_SelectionFilter; - -class SMESHGUI_EXPORT SMESHGUI_StandardMeshInfosDlg : public QDialog -{ - Q_OBJECT - -public: - SMESHGUI_StandardMeshInfosDlg( SMESHGUI* ); - ~SMESHGUI_StandardMeshInfosDlg(); - -protected: - void closeEvent( QCloseEvent* ); - void keyPressEvent( QKeyEvent* ); - void windowActivationChange( bool ); - void DumpMeshInfos(); - -private slots: - void onSelectionChanged(); - void DeactivateActiveDialog(); - void ActivateThisDialog(); - void onStartSelection(); - void onHelp(); - -private: - SMESHGUI* mySMESHGUI; - LightApp_SelectionMgr* mySelectionMgr; - bool myStartSelection; - bool myIsActiveWindow; - - SUIT_SelectionFilter* myMeshFilter; - - QLabel* myNameLab; - QPushButton* mySelectBtn; - QLineEdit* myMeshLine; - - QTextBrowser* myInfo; - - QGroupBox* myMeshGroup; - QGroupBox* myInfoGroup; - - QGroupBox* myButtonsGroup; - QPushButton* myOkBtn; - QPushButton* myHelpBtn; - - QString myHelpFileName; -}; - -#endif // SMESHGUI_STANDARDMESHINFOSDLG_H diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx index ed49f5217..5f4b1e206 100644 --- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_SymmetryDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI_SymmetryDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes + #include "SMESHGUI_SymmetryDlg.h" #include "SMESHGUI.h" @@ -33,6 +32,7 @@ #include "SMESHGUI_MeshUtils.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_MeshEditPreview.h" #include #include @@ -83,14 +83,17 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action #define SPACING 6 #define MARGIN 11 +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + //================================================================================= // class : SMESHGUI_SymmetryDlg() // purpose : //================================================================================= SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule ) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), + : SMESHGUI_PreviewDlg( theModule ), mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), myFilterDlg(0), mySelectedObject(SMESH::SMESH_IDSource::_nil()) @@ -144,8 +147,9 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule ) SelectElementsButton->setIcon(image3); LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); - QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); - connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + LineEditElements->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); // Control for the whole mesh selection CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); @@ -220,16 +224,21 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule ) // Name of a mesh to create LineEditNewMesh = new QLineEdit(GroupArguments); + + //Preview check box + myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); + // layout GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 1); - GroupArgumentsLayout->addWidget(filterBtn, 0, 3); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 3); GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 4); GroupArgumentsLayout->addWidget(GroupMirror, 2, 0, 1, 4); GroupArgumentsLayout->addWidget(ActionBox, 3, 0, 3, 3); GroupArgumentsLayout->addWidget(MakeGroupsCheck, 4, 3); GroupArgumentsLayout->addWidget(LineEditNewMesh, 5, 3); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 6, 0); /***************************************************************/ GroupButtons = new QGroupBox(this); @@ -261,12 +270,12 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule ) SMESHGUI_SymmetryDlgLayout->addWidget(GroupButtons); /* Initialisations */ - SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); - SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3); + SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); RadioButton1->setChecked(true); @@ -312,6 +321,16 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule ) connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); connect(ActionGroup, SIGNAL(buttonClicked(int)), SLOT(onActionClicked(int))); + connect(SpinBox_X, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Y, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_Z, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + + //To Connect preview check box + connectPreviewControl(); + ConstructorsClicked(0); SelectionIntoArgument(); onActionClicked(MOVE_ELEMS_BUTTON); @@ -358,6 +377,9 @@ void SMESHGUI_SymmetryDlg::Init (bool ResetControls) ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true); CheckBoxMesh->setChecked(false); + myPreviewCheckBox->setChecked(false); + onDisplaySimulation(false); + // MakeGroupsCheck->setChecked(false); // MakeGroupsCheck->setEnabled(false); onSelectMesh(false); @@ -416,8 +438,8 @@ void SMESHGUI_SymmetryDlg::ConstructorsClicked (int constructorId) SMESH::SetPointRepresentation(false); if (!CheckBoxMesh->isChecked()) { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(CellSelection); } } @@ -429,9 +451,11 @@ void SMESHGUI_SymmetryDlg::ConstructorsClicked (int constructorId) connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + onDisplaySimulation(true); + QApplication::instance()->processEvents(); updateGeometry(); - resize( minimumSize() ); + resize(100,100); } //================================================================================= @@ -456,17 +480,8 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() anElementsId[i] = aListElementsId[i].toInt(); SMESH::AxisStruct aMirror; - - aMirror.x = SpinBox_X->GetValue(); - aMirror.y = SpinBox_Y->GetValue(); - aMirror.z = SpinBox_Z->GetValue(); - if (GetConstructorId() == 0) { - aMirror.vx = aMirror.vy = aMirror.vz = 0; - } else { - aMirror.vx = SpinBox_DX->GetValue(); - aMirror.vy = SpinBox_DY->GetValue(); - aMirror.vz = SpinBox_DZ->GetValue(); - } + SMESH::SMESH_MeshEditor::MirrorType aMirrorType; + getMirror(aMirror,aMirrorType); QStringList aParameters; aParameters << SpinBox_X->text(); @@ -476,31 +491,22 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() aParameters << ( GetConstructorId() == 0 ? QString::number(0) : SpinBox_DY->text() ); aParameters << ( GetConstructorId() == 0 ? QString::number(0) : SpinBox_DZ->text() ); - SMESH::SMESH_MeshEditor::MirrorType aMirrorType; - - if (GetConstructorId() == 0) - aMirrorType = SMESH::SMESH_MeshEditor::POINT; - if (GetConstructorId() == 1) - aMirrorType = SMESH::SMESH_MeshEditor::AXIS; - if (GetConstructorId() == 2) - aMirrorType = SMESH::SMESH_MeshEditor::PLANE; - int actionButton = ActionGroup->checkedId(); bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ); - + QStringList anEntryList; try { SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + myMesh->SetParameters(aParameters.join(":").toLatin1().constData()); + switch ( actionButton ) { case MOVE_ELEMS_BUTTON: { if(CheckBoxMesh->isChecked()) aMeshEditor->MirrorObject(mySelectedObject, aMirror, aMirrorType, false ); else aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, false ); - - if( !myMesh->_is_nil()) - myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); + break; } case COPY_ELEMS_BUTTON: { @@ -517,34 +523,44 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() else aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, true); } - if( !myMesh->_is_nil()) - myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); break; } case MAKE_MESH_BUTTON: { SMESH::SMESH_Mesh_var mesh; - if(CheckBoxMesh->isChecked()) + if (CheckBoxMesh->isChecked()) mesh = aMeshEditor->MirrorObjectMakeMesh(mySelectedObject, aMirror, aMirrorType, makeGroups, LineEditNewMesh->text().toLatin1().data()); else mesh = aMeshEditor->MirrorMakeMesh(anElementsId, aMirror, aMirrorType, makeGroups, LineEditNewMesh->text().toLatin1().data()); - if( !mesh->_is_nil()) - mesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) ) + anEntryList.append( aSObject->GetID().c_str() ); +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + mesh->UnRegister(); +#endif + } break; } - } } catch (...) { } - + SMESH::UpdateView(); - if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() || - actionButton == MAKE_MESH_BUTTON ) + if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) || + actionButton == MAKE_MESH_BUTTON ) { mySMESHGUI->updateObjBrowser(true); // new groups may appear + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); + } Init(false); ConstructorsClicked(GetConstructorId()); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } return true; } @@ -555,6 +571,7 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() //================================================================================= void SMESHGUI_SymmetryDlg::ClickOnOk() { + setIsApplyAndClose( true ); if( ClickOnApply() ) ClickOnCancel(); } @@ -585,7 +602,7 @@ void SMESHGUI_SymmetryDlg::ClickOnCancel() void SMESHGUI_SymmetryDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -595,10 +612,10 @@ void SMESHGUI_SymmetryDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -628,21 +645,21 @@ void SMESHGUI_SymmetryDlg::onTextChange (const QString& theNewText) Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); TColStd_MapOfInteger newIndices; - + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); if (send == LineEditElements) { for (int i = 0; i < aListId.count(); i++) { - const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); - if (e) - newIndices.Add(e->GetID()); - myNbOkElements++; + const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); + if (e) + newIndices.Add(e->GetID()); + myNbOkElements++; } mySelector->AddOrRemoveIndex( anIO, newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( anIO, true, true ); - + aViewWindow->highlight( anIO, true, true ); + myElementsId = theNewText; } } @@ -695,7 +712,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() myActor = SMESH::FindActorByObject(myMesh); if (!myActor) myActor = SMESH::FindActorByEntry(IO->getEntry()); - if (!myActor) + if (!myActor && !CheckBoxMesh->isChecked()) return; int aNbUnits = 0; @@ -732,7 +749,6 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() aNbUnits++; } } - } else if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //SUBMESH // get submesh SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(IO); @@ -745,7 +761,6 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() myElementsId += QString(" %1").arg(anElementsIds[i]); } aNbUnits = anElementsIds->length(); - } else { // GROUP // get smesh group SMESH::SMESH_GroupBase_var aGroup = @@ -768,7 +783,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() if (aNbUnits < 1) return; } - + myNbOkElements = true; } else { aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); @@ -803,7 +818,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() LineEditElements->setText(aString); LineEditElements->repaint(); LineEditElements->setEnabled(false); // to update lineedit IPAL 19809 - LineEditElements->setEnabled(true); + LineEditElements->setEnabled(true); setNewMeshName(); } myBusy = false; @@ -813,6 +828,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() buttonOk->setEnabled(true); buttonApply->setEnabled(true); } + onDisplaySimulation(true); } //================================================================================= @@ -832,11 +848,11 @@ void SMESHGUI_SymmetryDlg::SetEditCurrentArgument() SMESH::SetPointRepresentation(false); if (CheckBoxMesh->isChecked()) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); + aViewWindow->SetSelectionMode(ActorSelection); mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); } else { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); + aViewWindow->SetSelectionMode(CellSelection); } } else if (send == SelectPointButton) { myEditCurrentArgument = (QWidget*)SpinBox_X; @@ -931,6 +947,7 @@ void SMESHGUI_SymmetryDlg::onSelectMesh (bool toSelectMesh) TextLabelElements->setText(tr("SMESH_NAME")); else TextLabelElements->setText(tr("SMESH_ID_ELEMENTS")); + myFilterBtn->setEnabled(!toSelectMesh); if (myEditCurrentArgument != LineEditElements) { LineEditElements->clear(); @@ -952,6 +969,7 @@ void SMESHGUI_SymmetryDlg::onSelectMesh (bool toSelectMesh) LineEditElements->setReadOnly(false); LineEditElements->setValidator(myIdValidator); onTextChange(LineEditElements->text()); + hidePreview(); } SelectionIntoArgument(); @@ -1027,6 +1045,7 @@ void SMESHGUI_SymmetryDlg::onActionClicked(int button) break; } setNewMeshName(); + toDisplaySimulation(); } //======================================================================= @@ -1073,6 +1092,12 @@ void SMESHGUI_SymmetryDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_SymmetryDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL ); @@ -1110,3 +1135,68 @@ bool SMESHGUI_SymmetryDlg::isValid() } return true; } + +//================================================================================= +// function : onDisplaySimulation +// purpose : Show/Hide preview +//================================================================================= +void SMESHGUI_SymmetryDlg::onDisplaySimulation( bool toDisplayPreview ) { + if (myPreviewCheckBox->isChecked() && toDisplayPreview) { + if ( myNbOkElements && isValid() && IsMirrorOk() ) { + QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts); + SMESH::long_array_var anElementsId = new SMESH::long_array; + + anElementsId->length(aListElementsId.count()); + for (int i = 0; i < aListElementsId.count(); i++) + anElementsId[i] = aListElementsId[i].toInt(); + + SMESH::AxisStruct aMirror; + SMESH::SMESH_MeshEditor::MirrorType aMirrorType; + + getMirror(aMirror,aMirrorType); + + try { + bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON || + ActionGroup->checkedId() == MAKE_MESH_BUTTON ); + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); + if(CheckBoxMesh->isChecked()) + aMeshEditor->MirrorObject(mySelectedObject, aMirror, aMirrorType, copy ); + else + aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, copy ); + + SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); + mySimulation->SetData(aMeshPreviewStruct._retn()); + } catch (...) { + hidePreview(); + } + } else { + hidePreview(); + } + } else { + hidePreview(); + } +} + +//================================================================================= +// function : getMirror +// purpose : return mirror parameters +//================================================================================= +void SMESHGUI_SymmetryDlg::getMirror(SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType& theMirrorType) { + theMirror.x = SpinBox_X->GetValue(); + theMirror.y = SpinBox_Y->GetValue(); + theMirror.z = SpinBox_Z->GetValue(); + if (GetConstructorId() == 0) { + theMirror.vx = theMirror.vy = theMirror.vz = 0; + } else { + theMirror.vx = SpinBox_DX->GetValue(); + theMirror.vy = SpinBox_DY->GetValue(); + theMirror.vz = SpinBox_DZ->GetValue(); + } + if (GetConstructorId() == 0) + theMirrorType = SMESH::SMESH_MeshEditor::POINT; + if (GetConstructorId() == 1) + theMirrorType = SMESH::SMESH_MeshEditor::AXIS; + if (GetConstructorId() == 2) + theMirrorType = SMESH::SMESH_MeshEditor::PLANE; +} diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.h b/src/SMESHGUI/SMESHGUI_SymmetryDlg.h index c56317d0b..a039ac27f 100644 --- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.h +++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_SymmetryDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -28,13 +29,12 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include +#include "SMESHGUI_PreviewDlg.h" // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) class QButtonGroup; class QGroupBox; @@ -56,7 +56,7 @@ class SMESH_LogicalFilter; // class : SMESHGUI_SymmetryDlg // purpose : //================================================================================= -class SMESHGUI_EXPORT SMESHGUI_SymmetryDlg : public QDialog +class SMESHGUI_EXPORT SMESHGUI_SymmetryDlg : public SMESHGUI_PreviewDlg { Q_OBJECT @@ -74,9 +74,10 @@ private: bool IsMirrorOk(); void setNewMeshName(); + void getMirror(SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType& aMirrorType); + bool isValid(); - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ SMESHGUI_IdValidator* myIdValidator; LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ int myNbOkElements; /* to check when elements are defined */ @@ -133,7 +134,11 @@ private: QString myHelpFileName; + QPushButton* myFilterBtn; SMESHGUI_FilterDlg* myFilterDlg; + +protected slots: + virtual void onDisplaySimulation( bool ); private slots: void ConstructorsClicked( int ); diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx index 091446d10..31ff3a796 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_TranslationDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI_TranslationDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes + #include "SMESHGUI_TranslationDlg.h" #include "SMESHGUI.h" @@ -33,6 +32,7 @@ #include "SMESHGUI_MeshUtils.h" #include "SMESHGUI_IdValidator.h" #include "SMESHGUI_FilterDlg.h" +#include "SMESHGUI_MeshEditPreview.h" #include #include @@ -101,16 +101,19 @@ private: #define SPACING 6 #define MARGIN 11 +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ + //================================================================================= // class : SMESHGUI_TranslationDlg() // purpose : //================================================================================= -SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), - mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), - myFilterDlg(0), - mySelectedObject(SMESH::SMESH_IDSource::_nil()) +SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) : + SMESHGUI_PreviewDlg( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ), + myFilterDlg(0), + mySelectedObject(SMESH::SMESH_IDSource::_nil()) { QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_TRANSLATION_POINTS"))); QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_TRANSLATION_VECTOR"))); @@ -156,8 +159,9 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) SelectElementsButton->setIcon(image2); LineEditElements = new QLineEdit(GroupArguments); LineEditElements->setValidator(myIdValidator); - QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); - connect(filterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); + LineEditElements->setMaxLength(-1); + myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments ); + connect(myFilterBtn, SIGNAL(clicked()), this, SLOT(setFilters())); // Control for the whole mesh selection CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments); @@ -210,11 +214,14 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) // Name of a mesh to create LineEditNewMesh = new QLineEdit(GroupArguments); + //Preview check box + myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments); + // layout GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1); GroupArgumentsLayout->addWidget(LineEditElements, 0, 2, 1, 5); - GroupArgumentsLayout->addWidget(filterBtn, 0, 7); + GroupArgumentsLayout->addWidget(myFilterBtn, 0, 7); GroupArgumentsLayout->addWidget(CheckBoxMesh, 1, 0, 1, 8); GroupArgumentsLayout->addWidget(TextLabel1, 2, 0); GroupArgumentsLayout->addWidget(SelectButton1, 2, 1); @@ -235,6 +242,7 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) GroupArgumentsLayout->addWidget(ActionBox, 4, 0, 3, 4); GroupArgumentsLayout->addWidget(MakeGroupsCheck, 5, 5, 1, 4); GroupArgumentsLayout->addWidget(LineEditNewMesh, 6, 5, 1, 4); + GroupArgumentsLayout->addWidget(myPreviewCheckBox, 7, 0); /***************************************************************/ GroupButtons = new QGroupBox(this); @@ -266,12 +274,12 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) SMESHGUI_TranslationDlgLayout->addWidget(GroupButtons); /* Initialisations */ - SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); - SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); - SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); - SpinBox2_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); - SpinBox2_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); - SpinBox2_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY); + SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox2_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox2_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + SpinBox2_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); RadioButton1->setChecked(true); @@ -313,6 +321,19 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) connect(CheckBoxMesh, SIGNAL(toggled(bool)), SLOT(onSelectMesh(bool))); connect(ActionGroup, SIGNAL(buttonClicked(int)), SLOT(onActionClicked(int))); + connect(SpinBox1_1, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox1_2, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox1_3, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + + connect(SpinBox2_1, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox2_2, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox2_3, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + connect(SpinBox2_3, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation())); + + + //To Connect preview check box + connectPreviewControl(); + ConstructorsClicked(0); SelectionIntoArgument(); onActionClicked(MOVE_ELEMS_BUTTON); @@ -362,6 +383,8 @@ void SMESHGUI_TranslationDlg::Init (bool ResetControls) CheckBoxMesh->setChecked(false); // MakeGroupsCheck->setChecked(false); // MakeGroupsCheck->setEnabled(false); + myPreviewCheckBox->setChecked(false); + onDisplaySimulation(false); onSelectMesh(false); } } @@ -417,7 +440,7 @@ void SMESHGUI_TranslationDlg::ConstructorsClicked (int constructorId) SMESH::SetPointRepresentation(false); if (!CheckBoxMesh->isChecked()) if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( CellSelection ); + aViewWindow->SetSelectionMode( CellSelection ); } myEditCurrentArgument = (QWidget*)LineEditElements; @@ -428,9 +451,11 @@ void SMESHGUI_TranslationDlg::ConstructorsClicked (int constructorId) connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + onDisplaySimulation(true); + QApplication::instance()->processEvents(); updateGeometry(); - resize( minimumSize() ); + resize(100,100); } //================================================================================= @@ -455,44 +480,43 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() anElementsId[i] = aListElementsId[i].toInt(); SMESH::DirStruct aVector; + QStringList aParameters; if (GetConstructorId() == 0) { aVector.PS.x = SpinBox2_1->GetValue() - SpinBox1_1->GetValue(); aVector.PS.y = SpinBox2_2->GetValue() - SpinBox1_2->GetValue(); aVector.PS.z = SpinBox2_3->GetValue() - SpinBox1_3->GetValue(); + // not supported so far + // aParameters << QString("%1 - %2").arg( SpinBox2_1->text() ).arg( SpinBox1_1->text() ); + // aParameters << QString("%1 - %2").arg( SpinBox2_2->text() ).arg( SpinBox1_2->text() ); + // aParameters << QString("%1 - %2").arg( SpinBox2_3->text() ).arg( SpinBox1_3->text() ); } else if (GetConstructorId() == 1) { aVector.PS.x = SpinBox1_1->GetValue(); aVector.PS.y = SpinBox1_2->GetValue(); aVector.PS.z = SpinBox1_3->GetValue(); + aParameters << SpinBox1_1->text(); + aParameters << SpinBox1_2->text(); + aParameters << SpinBox1_3->text(); } - QStringList aParameters; - aParameters << SpinBox1_1->text(); - if (GetConstructorId() == 0) - aParameters << SpinBox2_1->text(); - aParameters << SpinBox1_2->text(); - if (GetConstructorId() == 0) - aParameters << SpinBox2_2->text(); - aParameters << SpinBox1_3->text(); - if (GetConstructorId() == 0) - aParameters << SpinBox2_3->text(); - int actionButton = ActionGroup->checkedId(); bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ); + QStringList anEntryList; try { SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + + myMesh->SetParameters(aParameters.join(":").toLatin1().constData()); + switch ( actionButton ) { case MOVE_ELEMS_BUTTON: if(CheckBoxMesh->isChecked()) aMeshEditor->TranslateObject(mySelectedObject, aVector, false); else aMeshEditor->Translate(anElementsId, aVector, false); - if( !myMesh->_is_nil()) - myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); break; case COPY_ELEMS_BUTTON: if ( makeGroups ) { - SMESH::ListOfGroups_var groups; + SMESH::ListOfGroups_var groups; if(CheckBoxMesh->isChecked()) groups = aMeshEditor->TranslateObjectMakeGroups(mySelectedObject,aVector); else @@ -504,33 +528,45 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() else aMeshEditor->Translate(anElementsId, aVector, true); } - if( !myMesh->_is_nil()) - myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); break; - case MAKE_MESH_BUTTON: - SMESH::SMESH_Mesh_var mesh; - if(CheckBoxMesh->isChecked()) + case MAKE_MESH_BUTTON: { + SMESH::SMESH_Mesh_var mesh; + if (CheckBoxMesh->isChecked()) mesh = aMeshEditor->TranslateObjectMakeMesh(mySelectedObject, aVector, makeGroups, LineEditNewMesh->text().toLatin1().data()); else mesh = aMeshEditor->TranslateMakeMesh(anElementsId, aVector, makeGroups, LineEditNewMesh->text().toLatin1().data()); - if( !mesh->_is_nil()) - mesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters)); + if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) ) + anEntryList.append( aSObject->GetID().c_str() ); +#ifdef WITHGENERICOBJ + // obj has been published in study. Its refcount has been incremented. + // It is safe to decrement its refcount + // so that it will be destroyed when the entry in study will be removed + mesh->UnRegister(); +#endif + } } } catch (...) { } - + SMESH::UpdateView(); - if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() || - actionButton == MAKE_MESH_BUTTON ) + if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) || + actionButton == MAKE_MESH_BUTTON ) { mySMESHGUI->updateObjBrowser(true); // new groups may appear + if( LightApp_Application* anApp = + dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + anApp->browseObjects( anEntryList, isApplyAndClose() ); + } + Init(false); ConstructorsClicked(GetConstructorId()); mySelectedObject = SMESH::SMESH_IDSource::_nil(); SelectionIntoArgument(); + + SMESHGUI::Modified(); } - + return true; } @@ -540,6 +576,7 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() //================================================================================= void SMESHGUI_TranslationDlg::ClickOnOk() { + setIsApplyAndClose( true ); if( ClickOnApply() ) ClickOnCancel(); } @@ -570,7 +607,7 @@ void SMESHGUI_TranslationDlg::ClickOnCancel() void SMESHGUI_TranslationDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -580,10 +617,10 @@ void SMESHGUI_TranslationDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); } } @@ -611,24 +648,24 @@ void SMESHGUI_TranslationDlg::onTextChange (const QString& theNewText) if (aMesh) { Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); - + TColStd_MapOfInteger newIndices; QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); if (send == LineEditElements) { for (int i = 0; i < aListId.count(); i++) { - const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); - if (e) - newIndices.Add(e->GetID()); - myNbOkElements++; + const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); + if (e) + newIndices.Add(e->GetID()); + myNbOkElements++; } } mySelector->AddOrRemoveIndex( anIO, newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->highlight( anIO, true, true ); - + myElementsId = theNewText; } @@ -669,19 +706,24 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() return; Handle(SALOME_InteractiveObject) IO = aList.First(); - myMesh = SMESH::GetMeshByIO(IO); - if (myMesh->_is_nil()) + SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(IO); + if (aMesh->_is_nil()) return; - myActor = SMESH::FindActorByObject(myMesh); - if (!myActor) - myActor = SMESH::FindActorByEntry(IO->getEntry()); - if (!myActor) - return; + SMESH_Actor* anActor = SMESH::FindActorByObject(aMesh); + if (!anActor) + anActor = SMESH::FindActorByEntry(IO->getEntry()); + + if (!anActor && !CheckBoxMesh->isChecked()) + return; int aNbUnits = 0; - if (myEditCurrentArgument == (QWidget*)LineEditElements) { + if (myEditCurrentArgument == (QWidget*)LineEditElements) + { + myMesh = aMesh; + myActor = anActor; + myElementsId = ""; // MakeGroups is available if there are groups and "Copy" @@ -701,51 +743,11 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() } else return; - // get IDs from mesh - /* - SMDS_Mesh* aSMDSMesh = myActor->GetObject()->GetMesh(); - if (!aSMDSMesh) - return; - - for (int i = aSMDSMesh->MinElementID(); i <= aSMDSMesh->MaxElementID(); i++) { - const SMDS_MeshElement * e = aSMDSMesh->FindElement(i); - if (e) { - myElementsId += QString(" %1").arg(i); - aNbUnits++; - } - } - } else if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //SUBMESH - // get submesh - SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(IO); - - // get IDs from submesh - SMESH::long_array_var anElementsIds = new SMESH::long_array; - anElementsIds = aSubMesh->GetElementsId(); - for (int i = 0; i < anElementsIds->length(); i++) { - myElementsId += QString(" %1").arg(anElementsIds[i]); - } - aNbUnits = anElementsIds->length(); - } else { // GROUP - // get smesh group - SMESH::SMESH_GroupBase_var aGroup = - SMESH::IObjectToInterface(IO); - if (aGroup->_is_nil()) - return; - - // get IDs from smesh group - SMESH::long_array_var anElementsIds = new SMESH::long_array; - anElementsIds = aGroup->GetListOfID(); - for (int i = 0; i < anElementsIds->length(); i++) { - myElementsId += QString(" %1").arg(anElementsIds[i]); - } - aNbUnits = anElementsIds->length(); - } - */ } else { aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString); myElementsId = aString; if (aNbUnits < 1) - return; + return; } myNbOkElements = true; @@ -754,7 +756,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() if (aNbUnits != 1) return; - SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh(); + SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh(); if (!aMesh) return; @@ -781,7 +783,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() LineEditElements->setText(aString); LineEditElements->repaint(); LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809 - LineEditElements->setEnabled(true); + LineEditElements->setEnabled(true); setNewMeshName(); } @@ -790,6 +792,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() buttonOk->setEnabled(true); buttonApply->setEnabled(true); } + onDisplaySimulation(true); } //================================================================================= @@ -803,18 +806,18 @@ void SMESHGUI_TranslationDlg::SetEditCurrentArgument() disconnect(mySelectionMgr, 0, this, 0); mySelectionMgr->clearSelected(); mySelectionMgr->clearFilters(); - + if (send == SelectElementsButton) { myEditCurrentArgument = (QWidget*)LineEditElements; SMESH::SetPointRepresentation(false); if (CheckBoxMesh->isChecked()) { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( ActorSelection ); + aViewWindow->SetSelectionMode( ActorSelection ); mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); } else { if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( CellSelection ); + aViewWindow->SetSelectionMode( CellSelection ); } } else if (send == SelectButton1) { myEditCurrentArgument = (QWidget*)SpinBox1_1; @@ -910,6 +913,7 @@ void SMESHGUI_TranslationDlg::onSelectMesh (bool toSelectMesh) TextLabelElements->setText(tr("SMESH_NAME")); else TextLabelElements->setText(tr("SMESH_ID_ELEMENTS")); + myFilterBtn->setEnabled(!toSelectMesh); if (myEditCurrentArgument != LineEditElements) { LineEditElements->clear(); @@ -931,6 +935,7 @@ void SMESHGUI_TranslationDlg::onSelectMesh (bool toSelectMesh) LineEditElements->setReadOnly(false); LineEditElements->setValidator(myIdValidator); onTextChange(LineEditElements->text()); + hidePreview(); } SelectionIntoArgument(); @@ -966,6 +971,7 @@ void SMESHGUI_TranslationDlg::onActionClicked(int button) break; } setNewMeshName(); + toDisplaySimulation(); } //======================================================================= @@ -1021,6 +1027,12 @@ void SMESHGUI_TranslationDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_TranslationDlg::setFilters() { + if(myMesh->_is_nil()) { + SUIT_MessageBox::critical(this, + tr("SMESH_ERROR"), + tr("NO_MESH_SELECTED")); + return; + } if ( !myFilterDlg ) myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL ); @@ -1058,3 +1070,54 @@ bool SMESHGUI_TranslationDlg::isValid() } return true; } + +//================================================================================= +// function : onDisplaySimulation +// purpose : Show/Hide preview +//================================================================================= +void SMESHGUI_TranslationDlg::onDisplaySimulation( bool toDisplayPreview ) { + if (myPreviewCheckBox->isChecked() && toDisplayPreview) { + + if (isValid() && myNbOkElements) { + QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts); + + SMESH::long_array_var anElementsId = new SMESH::long_array; + + anElementsId->length(aListElementsId.count()); + for (int i = 0; i < aListElementsId.count(); i++) + anElementsId[i] = aListElementsId[i].toInt(); + + SMESH::DirStruct aVector; + if (GetConstructorId() == 0) { + aVector.PS.x = SpinBox2_1->GetValue() - SpinBox1_1->GetValue(); + aVector.PS.y = SpinBox2_2->GetValue() - SpinBox1_2->GetValue(); + aVector.PS.z = SpinBox2_3->GetValue() - SpinBox1_3->GetValue(); + } else if (GetConstructorId() == 1) { + aVector.PS.x = SpinBox1_1->GetValue(); + aVector.PS.y = SpinBox1_2->GetValue(); + aVector.PS.z = SpinBox1_3->GetValue(); + } + + try { + bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON || + ActionGroup->checkedId() == MAKE_MESH_BUTTON ); + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer(); + if(CheckBoxMesh->isChecked()) + aMeshEditor->TranslateObject(mySelectedObject, aVector, copy); + else + aMeshEditor->Translate(anElementsId, aVector, copy); + + SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData(); + mySimulation->SetData(aMeshPreviewStruct._retn()); + } catch (...) { + + } + } + else { + hidePreview(); + } + } else { + hidePreview(); + } +} diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.h b/src/SMESHGUI/SMESHGUI_TranslationDlg.h index 279ec596b..2c7294378 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.h +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_TranslationDlg.h // Author : Michael ZORIN, Open CASCADE S.A.S. @@ -28,9 +29,7 @@ // SMESH includes #include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include +#include "SMESHGUI_PreviewDlg.h" // IDL includes #include @@ -56,7 +55,7 @@ class SMESH_LogicalFilter; // class : SMESHGUI_TranslationDlg // purpose : //================================================================================= -class SMESHGUI_EXPORT SMESHGUI_TranslationDlg : public QDialog +class SMESHGUI_EXPORT SMESHGUI_TranslationDlg : public SMESHGUI_PreviewDlg { Q_OBJECT @@ -75,7 +74,6 @@ private: bool isValid(); - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ SMESHGUI_IdValidator* myIdValidator; LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ QString myElementsId; @@ -130,7 +128,11 @@ private: QString myHelpFileName; + QPushButton* myFilterBtn; SMESHGUI_FilterDlg* myFilterDlg; + +protected slots: + virtual void onDisplaySimulation( bool ); private slots: void ConstructorsClicked( int ); diff --git a/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx b/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx index b979ddffc..a279d0be4 100644 --- a/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_TransparencyDlg.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -86,7 +87,7 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( SMESHGUI* theModule ) GroupC1Layout->setMargin( MARGIN ); TextLabelTransparent = new QLabel( tr( "SMESH_TRANSPARENCY_TRANSPARENT" ), GroupC1 ); - TextLabelTransparent->setAlignment( Qt::AlignLeft ); + TextLabelTransparent->setAlignment( Qt::AlignRight ); ValueLab = new QLabel( GroupC1 ); ValueLab->setAlignment( Qt::AlignCenter ); @@ -94,7 +95,7 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( SMESHGUI* theModule ) QFont fnt = ValueLab->font(); fnt.setBold( true ); ValueLab->setFont( fnt ); TextLabelOpaque = new QLabel( tr( "SMESH_TRANSPARENCY_OPAQUE" ), GroupC1 ); - TextLabelOpaque->setAlignment( Qt::AlignRight ); + TextLabelOpaque->setAlignment( Qt::AlignLeft ); Slider1 = new QSlider( Qt::Horizontal, GroupC1 ); Slider1->setRange( 0, 100 ); @@ -106,9 +107,9 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( SMESHGUI* theModule ) Slider1->setFocusPolicy( Qt::NoFocus ); Slider1->setMinimumWidth( 300 ); - GroupC1Layout->addWidget( TextLabelTransparent, 0, 0 ); + GroupC1Layout->addWidget( TextLabelOpaque, 0, 0 ); GroupC1Layout->addWidget( ValueLab, 0, 1 ); - GroupC1Layout->addWidget( TextLabelOpaque, 0, 2 ); + GroupC1Layout->addWidget( TextLabelTransparent, 0, 2 ); GroupC1Layout->addWidget( Slider1, 1, 0, 1, 3 ); /*************************************************************************/ @@ -172,7 +173,7 @@ void SMESHGUI_TransparencyDlg::ClickOnHelp() LightApp_Application* app = (LightApp_Application*)( SUIT_Session::session()->activeApplication() ); if ( app ) app->onHelpContextModule( mySMESHGUI ? app->moduleName( mySMESHGUI->moduleName() ) : - QString( "" ), myHelpFileName ); + QString( "" ), myHelpFileName ); else { QString platform; #ifdef WIN32 @@ -181,10 +182,10 @@ void SMESHGUI_TransparencyDlg::ClickOnHelp() platform = "application"; #endif SUIT_MessageBox::warning( this, tr( "WRN_WARNING" ), - tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ). - arg( app->resourceMgr()->stringValue( "ExternalBrowser", - platform ) ). - arg( myHelpFileName ) ); + tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ). + arg( app->resourceMgr()->stringValue( "ExternalBrowser", + platform ) ). + arg( myHelpFileName ) ); } } @@ -197,7 +198,7 @@ void SMESHGUI_TransparencyDlg::SetTransparency() { if ( myViewWindow ) { SUIT_OverrideCursor wc; - float opacity = Slider1->value() / 100.; + float opacity = ( 100 - Slider1->value() ) / 100.; SALOME_ListIO aList; mySelectionMgr->selectedObjects( aList ); @@ -207,7 +208,7 @@ void SMESHGUI_TransparencyDlg::SetTransparency() Handle(SALOME_InteractiveObject) IOS = It.Value(); SMESH_Actor* anActor = SMESH::FindActorByEntry( IOS->getEntry() ); if ( anActor ) - anActor->SetOpacity( opacity ); + anActor->SetOpacity( opacity ); } myViewWindow->Repaint(); } @@ -238,35 +239,35 @@ void SMESHGUI_TransparencyDlg::onSelectionChanged() if ( aList.Extent() == 1 ) { Handle(SALOME_InteractiveObject) FirstIOS = aList.First(); if ( !FirstIOS.IsNull() ) { - SMESH_Actor* anActor = SMESH::FindActorByEntry( FirstIOS->getEntry() ); - if ( anActor ) - opacity = int( anActor->GetOpacity() * 100. + 0.5 ); + SMESH_Actor* anActor = SMESH::FindActorByEntry( FirstIOS->getEntry() ); + if ( anActor ) + opacity = int( anActor->GetOpacity() * 100. + 0.5 ); } } else if ( aList.Extent() > 1 ) { SALOME_ListIteratorOfListIO It( aList ); int setOp = -1; for ( ; It.More(); It.Next() ) { - Handle(SALOME_InteractiveObject) IO = It.Value(); - if ( !IO.IsNull() ) { - SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() ); - if ( anActor ) { - int op = int( anActor->GetOpacity() * 100. + 0.5 ); - if ( setOp < 0 ) - setOp = op; - else if ( setOp != op ) { - setOp = 100; - break; - } - } - } + Handle(SALOME_InteractiveObject) IO = It.Value(); + if ( !IO.IsNull() ) { + SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() ); + if ( anActor ) { + int op = int( anActor->GetOpacity() * 100. + 0.5 ); + if ( setOp < 0 ) + setOp = op; + else if ( setOp != op ) { + setOp = 100; + break; + } + } + } } if ( setOp >= 0 ) - opacity = setOp; + opacity = setOp; } else { } - Slider1->setValue( opacity ); + Slider1->setValue( 100 - opacity ); } ValueHasChanged(); } diff --git a/src/SMESHGUI/SMESHGUI_TransparencyDlg.h b/src/SMESHGUI/SMESHGUI_TransparencyDlg.h index 28595ed7e..7659b59cc 100644 --- a/src/SMESHGUI/SMESHGUI_TransparencyDlg.h +++ b/src/SMESHGUI/SMESHGUI_TransparencyDlg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_TransparencyDlg.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. diff --git a/src/SMESHGUI/SMESHGUI_Utils.cxx b/src/SMESHGUI/SMESHGUI_Utils.cxx index 33eb25b96..94ef5c93b 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.cxx +++ b/src/SMESHGUI/SMESHGUI_Utils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Utils.cxx // Author : Open CASCADE S.A.S. @@ -26,6 +27,8 @@ // #include "SMESHGUI_Utils.h" #include "SMESHGUI.h" +#include "SMESHGUI_Selection.h" +#include "SMESH_Type.h" #include #include @@ -47,6 +50,8 @@ #include #include +#include CORBA_SERVER_HEADER(SMESH_Group) + namespace SMESH { SUIT_Desktop* @@ -80,11 +85,11 @@ namespace SMESH if(theOwner){ const Handle(SALOME_InteractiveObject)& anIO = theOwner->IO(); if(!anIO.IsNull()){ - if(anIO->hasEntry()){ - _PTR(Study) aStudy = GetActiveStudyDocument(); - _PTR(SObject) aSObj = aStudy->FindObjectID(anIO->getEntry()); - anObj = SObjectToObject(aSObj,aStudy); - } + if(anIO->hasEntry()){ + _PTR(Study) aStudy = GetActiveStudyDocument(); + _PTR(SObject) aSObj = aStudy->FindObjectID(anIO->getEntry()); + anObj = SObjectToObject(aSObj,aStudy); + } } } return anObj; @@ -124,9 +129,9 @@ namespace SMESH (SUIT_Session::session()->activeApplication()); if (app && !CORBA::is_nil(theObject)) { if(_PTR(Study) aStudy = GetActiveStudyDocument()){ - CORBA::String_var anIOR = app->orb()->object_to_string(theObject); - if (strcmp(anIOR.in(), "") != 0) - return aStudy->FindObjectIOR(anIOR.in()); + CORBA::String_var anIOR = app->orb()->object_to_string(theObject); + if (strcmp(anIOR.in(), "") != 0) + return aStudy->FindObjectIOR(anIOR.in()); } } return _PTR(SObject)(); @@ -187,9 +192,12 @@ namespace SMESH if (theSObject) { _PTR(GenericAttribute) anAttr; if (theSObject->FindAttribute(anAttr, "AttributeIOR")) { - _PTR(AttributeIOR) anIOR = anAttr; - CORBA::String_var aVal = anIOR->Value().c_str(); - return app->orb()->string_to_object(aVal); + _PTR(AttributeIOR) anIOR = anAttr; + CORBA::String_var aVal = anIOR->Value().c_str(); + // string_to_object() DOC: If the input string is not valid ... + // a CORBA::SystemException is thrown. + if ( aVal && strlen( aVal ) > 0 ) + return app->orb()->string_to_object(aVal); } } return CORBA::Object::_nil(); @@ -201,13 +209,27 @@ namespace SMESH return SObjectToObject(theSObject,aStudy); } + _PTR(SObject) ObjectToSObject( CORBA::Object_ptr theObject ) + { + _PTR(SObject) res; + SalomeApp_Application* app = dynamic_cast + (SUIT_Session::session()->activeApplication()); + if ( app ) { + QString IOR = app->orb()->object_to_string( theObject ); + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( study && !IOR.isEmpty() ) + res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() ); + } + return res; + } + CORBA::Object_var IObjectToObject (const Handle(SALOME_InteractiveObject)& theIO) { if (!theIO.IsNull()) { if (theIO->hasEntry()) { - _PTR(Study) aStudy = GetActiveStudyDocument(); - _PTR(SObject) anObj = aStudy->FindObjectID(theIO->getEntry()); - return SObjectToObject(anObj,aStudy); + _PTR(Study) aStudy = GetActiveStudyDocument(); + _PTR(SObject) anObj = aStudy->FindObjectID(theIO->getEntry()); + return SObjectToObject(anObj,aStudy); } } return CORBA::Object::_nil(); @@ -230,7 +252,7 @@ namespace SMESH int aNbSel = selected.Extent(); if (aNbSel == 1) { Handle(SALOME_InteractiveObject) anIObject = selected.First(); - theName = anIObject->getName(); + theName = QString( anIObject->getName() ).trimmed(); } else { theName = QObject::tr("SMESH_OBJECTS_SELECTED").arg(aNbSel); } @@ -261,31 +283,63 @@ namespace SMESH _PTR(GenericAttribute) anAttr = aBuilder->FindOrCreateAttribute(theSObject,"AttributePixMap"); _PTR(AttributePixMap) aPixmap = anAttr; - 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"); - } + + std::string pmName; + if (theIsNotModif) + pmName = "ICON_SMESH_TREE_MESH"; + else if ( isEmptyMesh ) + pmName = "ICON_SMESH_TREE_MESH_WARN"; + else + pmName = "ICON_SMESH_TREE_MESH_PARTIAL"; + aPixmap->SetPixMap( pmName ); _PTR(ChildIterator) anIter = aStudy->NewChildIterator(theSObject); for (int i = 1; anIter->More(); anIter->Next(), i++) { _PTR(SObject) aSObj = anIter->Value(); if (i >= 4) { - _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSObj); - for ( ; anIter1->More(); anIter1->Next()) { - _PTR(SObject) aSObj1 = anIter1->Value(); - anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap"); - aPixmap = anAttr; - 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"); + _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSObj); + for ( ; anIter1->More(); anIter1->Next()) + { + _PTR(SObject) aSObj1 = anIter1->Value(); + + anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap"); + aPixmap = anAttr; + + std::string entry = aSObj1->GetID(); + int objType = SMESHGUI_Selection::type( entry.c_str(), aStudy ); + + SMESH::SMESH_IDSource_var idSrc = SObjectToInterface( aSObj1 ); + if ( !idSrc->_is_nil() ) + { + SMESH::SMESH_GroupOnFilter_var gof = + SObjectToInterface( aSObj1 ); + const bool isGroupOnFilter = !gof->_is_nil(); + + bool isEmpty = false; + if ( !isGroupOnFilter ) // GetTypes() can be very long on isGroupOnFilter! + { + SMESH::array_of_ElementType_var elemTypes = idSrc->GetTypes(); + isEmpty = ( elemTypes->length() == 0 ); + } + if ( isEmpty ) + aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN"); + else if ( objType != GROUP ) + aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" ); + else if ( isGroupOnFilter ) + aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP_ON_FILTER" ); + else + aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" ); + } + else + { + if ( !theIsNotModif ) + aPixmap->SetPixMap( pmName ); + else if ( objType == GROUP ) + aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" ); + else + aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" ); } - } + } } } } @@ -300,10 +354,10 @@ namespace SMESH } else { SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"), - QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - "application")). - arg(theHelpFileName)); + QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + "application")). + arg(theHelpFileName)); } } diff --git a/src/SMESHGUI/SMESHGUI_Utils.h b/src/SMESHGUI/SMESHGUI_Utils.h index 77f26e3e1..c813e1078 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.h +++ b/src/SMESHGUI/SMESHGUI_Utils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Utils.h // Author : Open CASCADE S.A.S. @@ -88,7 +89,7 @@ SMESHGUI_EXPORT { CORBA::Object_var anObj = DataOwnerToObject(theDataOwner); if(!CORBA::is_nil(anObj)) - return TInterface::_narrow(anObj); + return TInterface::_narrow(anObj); return TInterface::_nil(); } @@ -114,7 +115,7 @@ SMESHGUI_EXPORT SMESHGUI_EXPORT CORBA::Object_var SObjectToObject( _PTR(SObject), - _PTR(Study) ); + _PTR(Study) ); SMESHGUI_EXPORT CORBA::Object_var SObjectToObject( _PTR(SObject) ); @@ -124,10 +125,13 @@ SMESHGUI_EXPORT { CORBA::Object_var anObj = SObjectToObject(theSObject); if(!CORBA::is_nil(anObj)) - return TInterface::_narrow(anObj); + return TInterface::_narrow(anObj); return TInterface::_nil(); } +SMESHGUI_EXPORT + _PTR(SObject) ObjectToSObject( CORBA::Object_ptr ); + SMESHGUI_EXPORT CORBA::Object_var IObjectToObject( const Handle(SALOME_InteractiveObject)& ); @@ -136,7 +140,7 @@ SMESHGUI_EXPORT { CORBA::Object_var anObj = IObjectToObject(theIO); if(!CORBA::is_nil(anObj)) - return TInterface::_narrow(anObj); + return TInterface::_narrow(anObj); return TInterface::_nil(); } @@ -148,7 +152,7 @@ SMESHGUI_EXPORT { CORBA::Object_var anObj = IORToObject( theIOR ); if ( !CORBA::is_nil( anObj ) ) - return TInterface::_narrow( anObj ); + return TInterface::_narrow( anObj ); return TInterface::_nil(); } diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index 9289f0108..baafa985c 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_VTKUtils.cxx // Author : Open CASCADE S.A.S. @@ -29,6 +30,7 @@ #include "SMESHGUI.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_Filter.h" +#include "SMESH_ControlsDef.hxx" #include #include @@ -49,6 +51,8 @@ #include #include +#include + #include #include #include @@ -62,6 +66,7 @@ #include CORBA_CLIENT_HEADER(SMESH_Group) // VTK includes +#include #include #include #include @@ -98,31 +103,54 @@ namespace SMESH */ //================================================================================ - void RemoveVisualObjectWithActors( const char* theEntry ) + void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews ) { - SalomeApp_Application* app = dynamic_cast - ( SUIT_Session::session()->activeApplication() ); - SUIT_ViewManager* aViewManager = - app ? app->getViewManager(SVTK_Viewer::Type(), true) : 0; - if ( aViewManager ) { + SalomeApp_Application* app = dynamic_cast(SUIT_Session::session()->activeApplication()); + if(!app) + return; + SalomeApp_Study* aStudy = dynamic_cast(app->activeStudy()); + if(!aStudy) + return; + ViewManagerList aList; + + if(fromAllViews) { + app->viewManagers(SVTK_Viewer::Type() , aList); + } else { + SUIT_ViewManager* aVM = app->getViewManager(SVTK_Viewer::Type(), true); + if(aVM) + aList.append(aVM); + } + bool actorRemoved = false; + ViewManagerList::ConstIterator it = aList.begin(); + SUIT_ViewManager* aViewManager = 0; + for( ; it!=aList.end();it++) { + aViewManager = *it; QVector views = aViewManager->getViews(); for ( int iV = 0; iV < views.count(); ++iV ) { if ( SMESH_Actor* actor = FindActorByEntry( views[iV], theEntry)) { - if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) + if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) { vtkWnd->RemoveActor(actor); + actorRemoved = true; + } actor->Delete(); } } + } + + if (aViewManager ) { int aStudyId = aViewManager->study()->id(); TVisualObjCont::key_type aKey(aStudyId,theEntry); TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey); if(anIter != VISUAL_OBJ_CONT.end()) { // for unknown reason, object destructor is not called, so clear object manually - anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0); anIter->second->GetUnstructuredGrid()->SetPoints(0); } VISUAL_OBJ_CONT.erase(aKey); } + + if(actorRemoved) + aStudy->setVisibilityState(theEntry, Qtx::HiddenState); } //================================================================================ /*! @@ -143,10 +171,11 @@ namespace SMESH for ( int iV = 0; iV < views.count(); ++iV ) { if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) { vtkRenderer *aRenderer = vtkWnd->getRenderer(); - vtkActorCollection *actors = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *actors = aCopy.GetActors(); for (int i = 0; i < actors->GetNumberOfItems(); ++i ) { // size of actors changes inside the loop - while (SMESH_Actor *actor = dynamic_cast(actors->GetItemAsObject(i))) + if (SMESH_Actor *actor = dynamic_cast(actors->GetItemAsObject(i))) { vtkWnd->RemoveActor(actor); actor->Delete(); @@ -159,7 +188,7 @@ namespace SMESH TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin(); for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) { // for unknown reason, object destructor is not called, so clear object manually - anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0); anIter->second->GetUnstructuredGrid()->SetPoints(0); } VISUAL_OBJ_CONT.clear(); @@ -185,10 +214,11 @@ namespace SMESH for ( int iV = 0; iV < views.count(); ++iV ) { if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) { vtkRenderer *aRenderer = vtkWnd->getRenderer(); - vtkActorCollection *actors = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *actors = aCopy.GetActors(); for (int i = 0; i < actors->GetNumberOfItems(); ++i ) { // size of actors changes inside the loop - while(SMESH_Actor *actor = dynamic_cast(actors->GetItemAsObject(i))) + if(SMESH_Actor *actor = dynamic_cast(actors->GetItemAsObject(i))) { vtkWnd->RemoveActor(actor); actor->Delete(); @@ -199,13 +229,16 @@ namespace SMESH } } TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin(); - for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) { + for ( ; anIter != VISUAL_OBJ_CONT.end(); ) { int curId = anIter->first.first; if ( curId == studyID ) { // for unknown reason, object destructor is not called, so clear object manually - anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); + anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0); anIter->second->GetUnstructuredGrid()->SetPoints(0); - VISUAL_OBJ_CONT.erase( anIter-- ); // dercement occures before erase() + VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing + } + else { + anIter++; } } } @@ -227,18 +260,18 @@ namespace SMESH // char* buf = new char[100*1024]; // delete [] buf; SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_VISU_PROBLEM")); + QObject::tr("SMESH_VISU_PROBLEM")); } catch (...) { // no more memory at all: last resort MESSAGE_BEGIN ( "SMESHGUI_VTKUtils::OnVisuException(), exception even at showing a message!!!" << - std::endl << "Try to remove all visual data..." ); + std::endl << "Try to remove all visual data..." ); if (theVISU_MemoryReserve) { delete theVISU_MemoryReserve; theVISU_MemoryReserve = 0; } RemoveAllObjectsWithActors(); SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_VISU_PROBLEM_CLEAR")); + QObject::tr("SMESH_VISU_PROBLEM_CLEAR")); MESSAGE_END ( "...done" ); } } @@ -248,7 +281,7 @@ namespace SMESH */ //================================================================================ - TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){ + TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry, bool nulData){ TVisualObjPtr aVisualObj; TVisualObjCont::key_type aKey(theStudyId,theEntry); try{ @@ -257,59 +290,59 @@ namespace SMESH #endif TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey); if(anIter != VISUAL_OBJ_CONT.end()){ - aVisualObj = anIter->second; + aVisualObj = anIter->second; }else{ SalomeApp_Application* app = dynamic_cast( SMESHGUI::activeStudy()->application() ); - _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS(); - _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry); - if(aSObj){ - _PTR(GenericAttribute) anAttr; - if(aSObj->FindAttribute(anAttr,"AttributeIOR")){ - _PTR(AttributeIOR) anIOR = anAttr; - CORBA::String_var aVal = anIOR->Value().c_str(); - CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() ); - if(!CORBA::is_nil(anObj)){ - //Try narrow to SMESH_Mesh interface - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj); - if(!aMesh->_is_nil()){ - aVisualObj.reset(new SMESH_MeshObj(aMesh)); - TVisualObjCont::value_type aValue(aKey,aVisualObj); - VISUAL_OBJ_CONT.insert(aValue); - } - //Try narrow to SMESH_Group interface - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj); - if(!aGroup->_is_nil()){ - _PTR(SObject) aFatherSObj = aSObj->GetFather(); - if(!aFatherSObj) return aVisualObj; - aFatherSObj = aFatherSObj->GetFather(); - if(!aFatherSObj) return aVisualObj; - CORBA::String_var anEntry = aFatherSObj->GetID().c_str(); - TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); - if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ - aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj)); - TVisualObjCont::value_type aValue(aKey,aVisualObj); - VISUAL_OBJ_CONT.insert(aValue); - } - } - //Try narrow to SMESH_subMesh interface - SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj); - if(!aSubMesh->_is_nil()){ - _PTR(SObject) aFatherSObj = aSObj->GetFather(); - if(!aFatherSObj) return aVisualObj; - aFatherSObj = aFatherSObj->GetFather(); - if(!aFatherSObj) return aVisualObj; - CORBA::String_var anEntry = aFatherSObj->GetID().c_str(); - TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); - if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ - aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj)); - TVisualObjCont::value_type aValue(aKey,aVisualObj); - VISUAL_OBJ_CONT.insert(aValue); - } - } - } - } - } + _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS(); + _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry); + if(aSObj){ + _PTR(GenericAttribute) anAttr; + if(aSObj->FindAttribute(anAttr,"AttributeIOR")){ + _PTR(AttributeIOR) anIOR = anAttr; + CORBA::String_var aVal = anIOR->Value().c_str(); + CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() ); + if(!CORBA::is_nil(anObj)){ + //Try narrow to SMESH_Mesh interface + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj); + if(!aMesh->_is_nil()){ + aVisualObj.reset(new SMESH_MeshObj(aMesh)); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUAL_OBJ_CONT.insert(aValue); + } + //Try narrow to SMESH_Group interface + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj); + if(!aGroup->_is_nil()){ + _PTR(SObject) aFatherSObj = aSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + aFatherSObj = aFatherSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + CORBA::String_var anEntry = aFatherSObj->GetID().c_str(); + TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); + if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ + aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj)); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUAL_OBJ_CONT.insert(aValue); + } + } + //Try narrow to SMESH_subMesh interface + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj); + if(!aSubMesh->_is_nil()){ + _PTR(SObject) aFatherSObj = aSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + aFatherSObj = aFatherSObj->GetFather(); + if(!aFatherSObj) return aVisualObj; + CORBA::String_var anEntry = aFatherSObj->GetID().c_str(); + TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in()); + if(SMESH_MeshObj* aMeshObj = dynamic_cast(aVisObj.get())){ + aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj)); + TVisualObjCont::value_type aValue(aKey,aVisualObj); + VISUAL_OBJ_CONT.insert(aValue); + } + } + } + } + } } }catch(...){ INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!"); @@ -322,7 +355,11 @@ namespace SMESH #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif - objModified = aVisualObj->Update(); + //MESSAGE("GetVisualObj"); + if (nulData) + objModified = aVisualObj->NulData(); + else + objModified = aVisualObj->Update(); } catch (...) { #ifdef _DEBUG_ @@ -336,34 +373,31 @@ namespace SMESH if ( objModified ) { // PAL16631. Mesurements showed that to show aVisualObj in SHADING(default) mode, - // ~10 times more memory is used than it occupies. + // ~5 times more memory is used than it occupies. // Warn the user if there is less free memory than 30 sizes of a grid // TODO: estimate memory usage in other modes and take current mode into account int freeMB = SMDS_Mesh::CheckMemory(true); int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024; - if ( freeMB > 0 && usedMB * 30 > freeMB ) { -#ifdef _DEBUG_ - MESSAGE ( "SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB - << ", usedMB=" << usedMB ); -#endif - bool continu = false; - if ( usedMB * 10 > freeMB ) - // even dont try to show - SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_NO_MESH_VISUALIZATION")); - else - // there is a chance to succeed - continu = SUIT_MessageBox::warning - (SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes; - if ( !continu ) { - // remove the corresponding actors from all views - RemoveVisualObjectWithActors( theEntry ); - aVisualObj.reset(); - } + MESSAGE("SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB << ", usedMB=" < 0 && usedMB * 5 > freeMB ) { + bool continu = false; + if ( usedMB * 3 > freeMB ) + // even dont try to show + SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_NO_MESH_VISUALIZATION")); + else + // there is a chance to succeed + continu = SUIT_MessageBox::warning + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes; + if ( !continu ) { + // remove the corresponding actors from all views + RemoveVisualObjectWithActors( theEntry ); + aVisualObj.reset(); + } } } @@ -387,7 +421,7 @@ namespace SMESH if (anApp) { if (SVTK_ViewWindow* aView = dynamic_cast(anApp->desktop()->activeWindow())) - return aView; + return aView; SUIT_ViewManager* aViewManager = anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound); @@ -512,21 +546,22 @@ namespace SMESH SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow, - const char* theEntry) + const char* theEntry) { if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){ vtkRenderer *aRenderer = aViewWindow->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); aCollection->InitTraversal(); while(vtkActor *anAct = aCollection->GetNextActor()){ - if(SMESH_Actor *anActor = dynamic_cast(anAct)){ - if(anActor->hasIO()){ - Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); - if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){ - return anActor; - } - } - } + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){ + return anActor; + } + } + } } } return NULL; @@ -548,8 +583,8 @@ namespace SMESH CORBA::String_var anIOR = app->orb()->object_to_string( theObject ); _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in()); if(aSObject){ - CORBA::String_var anEntry = aSObject->GetID().c_str(); - return FindActorByEntry(anEntry.in()); + CORBA::String_var anEntry = aSObject->GetID().c_str(); + return FindActorByEntry(anEntry.in()); } } return NULL; @@ -557,43 +592,51 @@ namespace SMESH SMESH_Actor* CreateActor(_PTR(Study) theStudy, - const char* theEntry, - int theIsClear) + const char* theEntry, + int theIsClear) { SMESH_Actor *anActor = NULL; CORBA::Long anId = theStudy->StudyId(); if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){ _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry); if(aSObj){ - _PTR(GenericAttribute) anAttr; - if(aSObj->FindAttribute(anAttr,"AttributeName")){ - _PTR(AttributeName) aName = anAttr; - std::string aNameVal = aName->Value(); - anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear); - } - - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj )); - if(!CORBA::is_nil(aGroup)) - { - SALOMEDS::Color aColor = aGroup->GetColor(); - if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ) ) - { - int r = 0, g = 0, b = 0; - SMESH::GetColor( "SMESH", "fill_color", r, g, b, QColor( 0, 170, 255 ) ); - aColor.R = (float)r / 255.0; - aColor.G = (float)g / 255.0; - aColor.B = (float)b / 255.0; - aGroup->SetColor( aColor ); - } - if( aGroup->GetType() == SMESH::NODE ) - anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); - else if( aGroup->GetType() == SMESH::EDGE ) - anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); - else - anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B ); - } + _PTR(GenericAttribute) anAttr; + if(aSObj->FindAttribute(anAttr,"AttributeName")){ + _PTR(AttributeName) aName = anAttr; + std::string aNameVal = aName->Value(); + anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear); + } + + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj )); + if(!CORBA::is_nil(aGroup) && anActor) + { + QColor c;int delta; + SMESH::GetColor( "SMESH", "fill_color", c, delta, "0,170,255|-100" ); + SALOMEDS::Color aColor = aGroup->GetColor(); + if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 )) + { + aColor.R = (float)c.red() / 255.0; + aColor.G = (float)c.green() / 255.0; + aColor.B = (float)c.blue() / 255.0; + aGroup->SetColor( aColor ); + } + if( aGroup->GetType() == SMESH::NODE ) + anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); + else if( aGroup->GetType() == SMESH::EDGE ) + anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); + else if( aGroup->GetType() == SMESH::ELEM0D ) + anActor->Set0DColor( aColor.R, aColor.G, aColor.B ); + else if( aGroup->GetType() == SMESH::BALL ) + anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); + else + anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); + } } } + MESSAGE("CreateActor " << anActor); + if( anActor ) + if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() ) + aSMESHGUI->addActorAsObserver( anActor ); return anActor; } @@ -604,6 +647,7 @@ namespace SMESH #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif + MESSAGE("DisplayActor " << theActor); vtkWnd->AddActor(theActor); vtkWnd->Repaint(); } @@ -619,16 +663,17 @@ namespace SMESH void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){ if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){ + MESSAGE("RemoveActor " << theActor); vtkWnd->RemoveActor(theActor); if(theActor->hasIO()){ - Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); - if(anIO->hasEntry()){ - std::string anEntry = anIO->getEntry(); - SalomeApp_Study* aStudy = dynamic_cast( vtkWnd->getViewManager()->study() ); - int aStudyId = aStudy->id(); - TVisualObjCont::key_type aKey(aStudyId,anEntry); - VISUAL_OBJ_CONT.erase(aKey); - } + Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); + if(anIO->hasEntry()){ + std::string anEntry = anIO->getEntry(); + SalomeApp_Study* aStudy = dynamic_cast( vtkWnd->getViewManager()->study() ); + int aStudyId = aStudy->id(); + TVisualObjCont::key_type aKey(aStudyId,anEntry); + VISUAL_OBJ_CONT.erase(aKey); + } } theActor->Delete(); vtkWnd->Repaint(); @@ -645,10 +690,11 @@ namespace SMESH { if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWnd)) { vtkRenderer *aRenderer = aViewWindow->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); aCollection->InitTraversal(); while(vtkActor *anAct = aCollection->GetNextActor()) - if(dynamic_cast(anAct)) + if(dynamic_cast(anAct)) return false; } return true; @@ -656,60 +702,90 @@ namespace SMESH bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry) { + //MESSAGE("UpdateView"); bool OK = false; SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd); if (!aViewWnd) return OK; + SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd); + if (!vtkWnd) + return OK; + + SalomeApp_Study* aStudy = dynamic_cast( vtkWnd->getViewManager()->study() ); + + if (!aStudy) + return OK; + { OK = true; vtkRenderer *aRenderer = aViewWnd->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); aCollection->InitTraversal(); switch (theAction) { case eDisplayAll: { - while (vtkActor *anAct = aCollection->GetNextActor()) { - if (SMESH_Actor *anActor = dynamic_cast(anAct)) { - anActor->SetVisibility(true); - } - } - break; + while (vtkActor *anAct = aCollection->GetNextActor()) { + if (SMESH_Actor *anActor = dynamic_cast(anAct)) { + MESSAGE("--- display " << anActor); + anActor->SetVisibility(true); + + if(anActor->hasIO()){ + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if(anIO->hasEntry()){ + aStudy->setVisibilityState(anIO->getEntry(), Qtx::ShownState); + } + } + } + } + break; } case eDisplayOnly: case eEraseAll: { - while (vtkActor *anAct = aCollection->GetNextActor()) { - if (SMESH_Actor *anActor = dynamic_cast(anAct)) { - anActor->SetVisibility(false); - } - } + //MESSAGE("---case eDisplayOnly"); + while (vtkActor *anAct = aCollection->GetNextActor()) { + if (SMESH_Actor *anActor = dynamic_cast(anAct)) { + //MESSAGE("--- erase " << anActor); + anActor->SetVisibility(false); + } + } + aStudy->setVisibilityStateForAll(Qtx::HiddenState); } default: { - if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) { - switch (theAction) { - case eDisplay: - case eDisplayOnly: - anActor->SetVisibility(true); - if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange(); - break; - case eErase: - anActor->SetVisibility(false); - break; - } - } else { - switch (theAction) { - case eDisplay: - case eDisplayOnly: + if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) { + switch (theAction) { + case eDisplay: + case eDisplayOnly: + //MESSAGE("--- display " << anActor); + anActor->Update(); + anActor->SetVisibility(true); + if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange(); + aStudy->setVisibilityState(theEntry, Qtx::ShownState); + break; + case eErase: + //MESSAGE("--- erase " << anActor); + anActor->SetVisibility(false); + aStudy->setVisibilityState(theEntry, Qtx::HiddenState); + break; + } + } else { + switch (theAction) { + case eDisplay: + case eDisplayOnly: { + //MESSAGE("---"); SalomeApp_Study* aStudy = dynamic_cast(theWnd->getViewManager()->study()); _PTR(Study) aDocument = aStudy->studyDS(); // Pass non-visual objects (hypotheses, etc.), return true in this case CORBA::Long anId = aDocument->StudyId(); - if (TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)) + TVisualObjPtr aVisualObj; + if ( (aVisualObj = GetVisualObj(anId,theEntry)) && aVisualObj->IsValid()) { if ((anActor = CreateActor(aDocument,theEntry,true))) { bool needFitAll = noSmeshActors(theWnd); // fit for the first object only DisplayActor(theWnd,anActor); + aStudy->setVisibilityState(theEntry, Qtx::ShownState); // FitAll(); - PAL16770(Display of a group performs an automatic fit all) if (needFitAll) FitAll(); } else { @@ -718,8 +794,8 @@ namespace SMESH } break; } - } - } + } + } } } } @@ -728,6 +804,7 @@ namespace SMESH bool UpdateView(EDisplaing theAction, const char* theEntry){ + //MESSAGE("UpdateView"); SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() ); SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() ); SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView(); @@ -740,23 +817,24 @@ namespace SMESH SALOME_ListIO selected; mgr->selectedObjects( selected ); if( selected.Extent() == 0){ - vtkRenderer* aRenderer = aWnd->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); - aCollection->InitTraversal(); - while(vtkActor *anAct = aCollection->GetNextActor()){ - if(SMESH_Actor *anActor = dynamic_cast(anAct)){ - if(anActor->hasIO()) - if (!Update(anActor->getIO(),anActor->GetVisibility())) + vtkRenderer* aRenderer = aWnd->getRenderer(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO()) + if (!Update(anActor->getIO(),anActor->GetVisibility())) break; // avoid multiple warinings if visu failed - } - } + } + } }else{ - SALOME_ListIteratorOfListIO anIter( selected ); - for( ; anIter.More(); anIter.Next()){ - Handle(SALOME_InteractiveObject) anIO = anIter.Value(); - if ( !Update(anIO,true) ) + SALOME_ListIteratorOfListIO anIter( selected ); + for( ; anIter.More(); anIter.Next()){ + Handle(SALOME_InteractiveObject) anIO = anIter.Value(); + if ( !Update(anIO,true) ) break; // avoid multiple warinings if visu failed - } + } } RepaintCurrentView(); } @@ -765,6 +843,7 @@ namespace SMESH bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay) { + MESSAGE("Update"); _PTR(Study) aStudy = GetActiveStudyDocument(); CORBA::Long anId = aStudy->StudyId(); if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) { @@ -775,6 +854,18 @@ namespace SMESH return false; } + bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay) + { + MESSAGE("UpdateNulData"); + _PTR(Study) aStudy = GetActiveStudyDocument(); + CORBA::Long anId = aStudy->StudyId(); + if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) { + if ( theDisplay ) + UpdateView(SMESH::eDisplay,theIO->getEntry()); + return true; + } + return false; + } void UpdateSelectionProp( SMESHGUI* theModule ) { if( !theModule ) @@ -805,45 +896,49 @@ namespace SMESH QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ), aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ), - aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan ); + aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan ); - int SW = mgr->integerValue( "SMESH", "selection_width", 5 ), - PW = mgr->integerValue( "SMESH", "highlight_width", 5 ); + int aElem0DSize = mgr->integerValue("SMESH", "elem0d_size", 5); + int aBallSize = mgr->integerValue("SMESH", "ball_elem_size", 5); + int aLineWidth = mgr->integerValue("SMESH", "element_width", 1); + int maxSize = aElem0DSize; + if (aElem0DSize > maxSize) maxSize = aElem0DSize; + if (aLineWidth > maxSize) maxSize = aLineWidth; + if (aBallSize > maxSize) maxSize = aBallSize; double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ), SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ), - SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 ); + SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 ); for ( int i=0, n=views.count(); iSetSelectionProp(aSelColor.red()/255., - aSelColor.green()/255., - aSelColor.blue()/255., - SW ); - // tolerances - aVtkView->SetSelectionTolerance(SP1, SP2, SP3); - - // pre-selection - aVtkView->SetPreselectionProp(aPreColor.red()/255., - aPreColor.green()/255., - aPreColor.blue()/255., - PW); - // update actors - vtkRenderer* aRenderer = aVtkView->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); - aCollection->InitTraversal(); - while(vtkActor *anAct = aCollection->GetNextActor()){ - if(SMESH_Actor *anActor = dynamic_cast(anAct)){ - anActor->SetHighlightColor(aHiColor.red()/255., - aHiColor.green()/255., - aHiColor.blue()/255.); - anActor->SetPreHighlightColor(aPreColor.red()/255., - aPreColor.green()/255., - aPreColor.blue()/255.); - } - } + // mesh element selection + aVtkView->SetSelectionProp(aSelColor.red()/255., + aSelColor.green()/255., + aSelColor.blue()/255.); + // tolerances + aVtkView->SetSelectionTolerance(SP1, SP2, SP3); + + // pre-selection + aVtkView->SetPreselectionProp(aPreColor.red()/255., + aPreColor.green()/255., + aPreColor.blue()/255.); + // update actors + vtkRenderer* aRenderer = aVtkView->getRenderer(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + anActor->SetHighlightColor(aHiColor.red()/255., + aHiColor.green()/255., + aHiColor.blue()/255.); + anActor->SetPreHighlightColor(aPreColor.red()/255., + aPreColor.green()/255., + aPreColor.blue()/255.); + } + } } } } @@ -860,7 +955,7 @@ namespace SMESH } void SetFilter(const Handle(VTKViewer_Filter)& theFilter, - SVTK_Selector* theSelector) + SVTK_Selector* theSelector) { if (theSelector) theSelector->SetFilter(theFilter); @@ -888,7 +983,7 @@ namespace SMESH } bool IsValid(SALOME_Actor* theActor, int theCellId, - SVTK_Selector* theSelector) + SVTK_Selector* theSelector) { return theSelector->IsValid(theActor,theCellId); } @@ -898,14 +993,15 @@ namespace SMESH void SetPointRepresentation(bool theIsVisible){ if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){ vtkRenderer *aRenderer = aViewWindow->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); aCollection->InitTraversal(); while(vtkActor *anAct = aCollection->GetNextActor()){ - if(SMESH_Actor *anActor = dynamic_cast(anAct)){ - if(anActor->GetVisibility()){ - anActor->SetPointRepresentation(theIsVisible); - } - } + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->GetVisibility()){ + anActor->SetPointRepresentation(theIsVisible); + } + } } RepaintCurrentView(); } @@ -916,17 +1012,18 @@ namespace SMESH if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){ int anIsAllPickable = (theActor == NULL); vtkRenderer *aRenderer = aWnd->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); aCollection->InitTraversal(); while(vtkActor *anAct = aCollection->GetNextActor()){ - if(SALOME_Actor *anActor = dynamic_cast(anAct)){ - if(anActor->GetVisibility()){ - anActor->SetPickable(anIsAllPickable); - } - } + if(SALOME_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->GetVisibility()){ + anActor->SetPickable(anIsAllPickable); + } + } } if(theActor) - theActor->SetPickable(!anIsAllPickable); + theActor->SetPickable(!anIsAllPickable); RepaintCurrentView(); } } @@ -934,8 +1031,8 @@ namespace SMESH //---------------------------------------------------------------------------- int GetNameOfSelectedNodes(SVTK_Selector* theSelector, - const Handle(SALOME_InteractiveObject)& theIO, - QString& theName) + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) { theName = ""; TColStd_IndexedMapOfInteger aMapIndex; @@ -948,8 +1045,8 @@ namespace SMESH } int GetNameOfSelectedElements(SVTK_Selector* theSelector, - const Handle(SALOME_InteractiveObject)& theIO, - QString& theName) + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) { theName = ""; TColStd_IndexedMapOfInteger aMapIndex; @@ -969,9 +1066,9 @@ namespace SMESH int GetEdgeNodes(SVTK_Selector* theSelector, - const TVisualObjPtr& theVisualObject, - int& theId1, - int& theId2) + const TVisualObjPtr& theVisualObject, + int& theId1, + int& theId2) { const SALOME_ListIO& selected = theSelector->StoredIObjects(); @@ -991,9 +1088,9 @@ namespace SMESH for ( int i = 1; i <= aMapIndex.Extent(); i++ ) { int aVal = aMapIndex( i ); if ( aVal > 0 ) - anObjId = aVal; + anObjId = aVal; else - anEdgeNum = abs( aVal ) - 1; + anEdgeNum = abs( aVal ) - 1; } if ( anObjId == -1 || anEdgeNum == -1 ) @@ -1004,18 +1101,18 @@ namespace SMESH //---------------------------------------------------------------------------- int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, - const Handle(SALOME_InteractiveObject)& theIO, - QString& theName) + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) { theName = ""; if(theIO->hasEntry()){ if(FindActorByEntry(theIO->getEntry())){ - TColStd_IndexedMapOfInteger aMapIndex; - theMgr->GetIndexes(theIO,aMapIndex); - for(int i = 1; i <= aMapIndex.Extent(); i++){ - theName += QString(" %1").arg(aMapIndex(i)); - } - return aMapIndex.Extent(); + TColStd_IndexedMapOfInteger aMapIndex; + theMgr->GetIndexes(theIO,aMapIndex); + for(int i = 1; i <= aMapIndex.Extent(); i++){ + theName += QString(" %1").arg(aMapIndex(i)); + } + return aMapIndex.Extent(); } } return -1; @@ -1033,23 +1130,23 @@ namespace SMESH int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, - const Handle(SALOME_InteractiveObject)& theIO, - QString& theName) + const Handle(SALOME_InteractiveObject)& theIO, + QString& theName) { theName = ""; if(theIO->hasEntry()){ if(FindActorByEntry(theIO->getEntry())){ - TColStd_IndexedMapOfInteger aMapIndex; - theMgr->GetIndexes(theIO,aMapIndex); - typedef std::set TIdContainer; - TIdContainer anIdContainer; - for( int i = 1; i <= aMapIndex.Extent(); i++) - anIdContainer.insert(aMapIndex(i)); - TIdContainer::const_iterator anIter = anIdContainer.begin(); - for( ; anIter != anIdContainer.end(); anIter++){ - theName += QString(" %1").arg(*anIter); - } - return aMapIndex.Extent(); + TColStd_IndexedMapOfInteger aMapIndex; + theMgr->GetIndexes(theIO,aMapIndex); + typedef std::set TIdContainer; + TIdContainer anIdContainer; + for( int i = 1; i <= aMapIndex.Extent(); i++) + anIdContainer.insert(aMapIndex(i)); + TIdContainer::const_iterator anIter = anIdContainer.begin(); + for( ; anIter != anIdContainer.end(); anIter++){ + theName += QString(" %1").arg(*anIter); + } + return aMapIndex.Extent(); } } return -1; @@ -1069,8 +1166,8 @@ namespace SMESH } int GetSelected(LightApp_SelectionMgr* theMgr, - TColStd_IndexedMapOfInteger& theMap, - const bool theIsElement) + TColStd_IndexedMapOfInteger& theMap, + const bool theIsElement) { theMap.Clear(); SALOME_ListIO selected; theMgr->selectedObjects( selected ); @@ -1079,7 +1176,7 @@ namespace SMESH { Handle(SALOME_InteractiveObject) anIO = selected.First(); if ( anIO->hasEntry() ) { - theMgr->GetIndexes( anIO, theMap ); + theMgr->GetIndexes( anIO, theMap ); } } return theMap.Extent(); @@ -1110,9 +1207,9 @@ namespace SMESH for ( int i = 1; i <= aMapIndex.Extent(); i++ ) { int aVal = aMapIndex( i ); if ( aVal > 0 ) - anObjId = aVal; + anObjId = aVal; else - anEdgeNum = abs( aVal ); + anEdgeNum = abs( aVal ); } if ( anObjId == -1 || anEdgeNum == -1 ) @@ -1126,7 +1223,8 @@ namespace SMESH if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() ) { vtkRenderer *aRenderer = aWnd->getRenderer(); - vtkActorCollection *aCollection = aRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); aCollection->InitTraversal(); while ( vtkActor *anAct = aCollection->GetNextActor()) @@ -1140,4 +1238,134 @@ namespace SMESH } } + + //---------------------------------------------------------------------------- + // internal function + void ComputeBoundsParam( vtkFloatingPointType theBounds[6], + vtkFloatingPointType theDirection[3], + vtkFloatingPointType theMinPnt[3], + vtkFloatingPointType& theMaxBoundPrj, + vtkFloatingPointType& theMinBoundPrj ) + { + //Enlarge bounds in order to avoid conflicts of precision + for(int i = 0; i < 6; i += 2){ + static double EPS = 1.0E-3; + vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS; + theBounds[i] -= aDelta; + theBounds[i+1] += aDelta; + } + + vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]}, + {theBounds[1],theBounds[2],theBounds[4]}, + {theBounds[0],theBounds[3],theBounds[4]}, + {theBounds[1],theBounds[3],theBounds[4]}, + {theBounds[0],theBounds[2],theBounds[5]}, + {theBounds[1],theBounds[2],theBounds[5]}, + {theBounds[0],theBounds[3],theBounds[5]}, + {theBounds[1],theBounds[3],theBounds[5]}}; + + int aMaxId = 0; + theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]); + theMinBoundPrj = theMaxBoundPrj; + for(int i = 1; i < 8; i++){ + vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]); + if(theMaxBoundPrj < aTmp){ + theMaxBoundPrj = aTmp; + aMaxId = i; + } + if(theMinBoundPrj > aTmp){ + theMinBoundPrj = aTmp; + } + } + vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId]; + theMinPnt[0] = aMinPnt[0]; + theMinPnt[1] = aMinPnt[1]; + theMinPnt[2] = aMinPnt[2]; + } + + // internal function + void DistanceToPosition( vtkFloatingPointType theBounds[6], + vtkFloatingPointType theDirection[3], + vtkFloatingPointType theDist, + vtkFloatingPointType thePos[3] ) + { + vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3]; + ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj); + vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist; + thePos[0] = aMinPnt[0]-theDirection[0]*aLength; + thePos[1] = aMinPnt[1]-theDirection[1]*aLength; + thePos[2] = aMinPnt[2]-theDirection[2]*aLength; + } + + // internal function (currently unused, left just in case) + void PositionToDistance( vtkFloatingPointType theBounds[6], + vtkFloatingPointType theDirection[3], + vtkFloatingPointType thePos[3], + vtkFloatingPointType& theDist ) + { + vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3]; + ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj); + vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos); + theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj); + } + + bool ComputeClippingPlaneParameters( std::list theActorList, + vtkFloatingPointType theNormal[3], + vtkFloatingPointType theDist, + vtkFloatingPointType theBounds[6], + vtkFloatingPointType theOrigin[3] ) + { + bool anIsOk = false; + theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX; + theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX; + std::list::iterator anIter = theActorList.begin(); + for( ; anIter != theActorList.end(); anIter++ ) { + if( vtkActor* aVTKActor = *anIter ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) { + vtkFloatingPointType aBounds[6]; + anActor->GetUnstructuredGrid()->GetBounds( aBounds ); + theBounds[0] = std::min( theBounds[0], aBounds[0] ); + theBounds[1] = std::max( theBounds[1], aBounds[1] ); + theBounds[2] = std::min( theBounds[2], aBounds[2] ); + theBounds[3] = std::max( theBounds[3], aBounds[3] ); + theBounds[4] = std::min( theBounds[4], aBounds[4] ); + theBounds[5] = std::max( theBounds[5], aBounds[5] ); + anIsOk = true; + } + } + } + + if( !anIsOk ) + return false; + + DistanceToPosition( theBounds, theNormal, theDist, theOrigin ); + return true; + } + +#ifndef DISABLE_PLOT2DVIEWER + //================================================================================ + /*! + * \brief Find all SMESH_Actor's in the View Window. + * If actor constains Plot2d_Histogram object remove it from each Plot2d Viewer. + */ + //================================================================================ + + void ClearPlot2Viewers( SUIT_ViewWindow* theWindow ) { + if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){ + vtkRenderer *aRenderer = aViewWindow->getRenderer(); + VTK::ActorCollectionCopy aCopy(aRenderer->GetActors()); + vtkActorCollection *aCollection = aCopy.GetActors(); + aCollection->InitTraversal(); + while(vtkActor *anAct = aCollection->GetNextActor()){ + if(SMESH_Actor *anActor = dynamic_cast(anAct)){ + if(anActor->hasIO() && anActor->GetPlot2Histogram() ){ + ProcessIn2DViewers(anActor,RemoveFrom2dViewer); + } + } + } + } + } + +#endif + } // end of namespace SMESH diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.h b/src/SMESHGUI/SMESHGUI_VTKUtils.h index 05d2e268b..94d69a9cd 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.h +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_VTKUtils.h // Author : Open CASCADE S.A.S. @@ -56,20 +57,22 @@ class SMESHGUI; class SMESH_Actor; class SALOME_Actor; +class vtkActor; + namespace SMESH { //---------------------------------------------------------------------------- typedef std::pair TKeyOfVisualObj; SMESHGUI_EXPORT - TVisualObjPtr GetVisualObj( int, const char* ); + TVisualObjPtr GetVisualObj( int, const char*, bool nulData =false ); SMESHGUI_EXPORT void OnVisuException(); // PAL16631 //---------------------------------------------------------------------------- SMESHGUI_EXPORT SVTK_ViewWindow* GetViewWindow( const SalomeApp_Module* = 0, - bool = false ); + bool = false ); SMESHGUI_EXPORT SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager*, SUIT_ViewWindow* ); SMESHGUI_EXPORT @@ -112,14 +115,17 @@ SMESHGUI_EXPORT SMESHGUI_EXPORT bool UpdateView( SUIT_ViewWindow*, EDisplaing, const char* = "" ); -SMESHGUI_EXPORT +SMESHGUI_EXPORT bool UpdateView( EDisplaing, const char* = "" ); SMESHGUI_EXPORT void UpdateView(); SMESHGUI_EXPORT - bool Update( const Handle(SALOME_InteractiveObject)&, bool ); + bool UpdateNulData( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay); + +SMESHGUI_EXPORT + bool Update( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay); //---------------------------------------------------------------------------- SMESHGUI_EXPORT @@ -153,37 +159,52 @@ SMESHGUI_EXPORT //---------------------------------------------------------------------------- SMESHGUI_EXPORT int GetNameOfSelectedNodes( SVTK_Selector*, - const Handle(SALOME_InteractiveObject)&, - QString& ); + const Handle(SALOME_InteractiveObject)&, + QString& ); SMESHGUI_EXPORT int GetNameOfSelectedElements( SVTK_Selector*, - const Handle(SALOME_InteractiveObject)&, - QString& ); + const Handle(SALOME_InteractiveObject)&, + QString& ); SMESHGUI_EXPORT int GetEdgeNodes( SVTK_Selector*, const TVisualObjPtr&, int&, int& ); //---------------------------------------------------------------------------- SMESHGUI_EXPORT int GetNameOfSelectedNodes( LightApp_SelectionMgr*, - const Handle(SALOME_InteractiveObject)&, - QString& ); + const Handle(SALOME_InteractiveObject)&, + QString& ); SMESHGUI_EXPORT int GetNameOfSelectedNodes( LightApp_SelectionMgr*, QString& ); SMESHGUI_EXPORT int GetNameOfSelectedElements( LightApp_SelectionMgr*, - const Handle(SALOME_InteractiveObject)&, - QString& ); + const Handle(SALOME_InteractiveObject)&, + QString& ); SMESHGUI_EXPORT int GetNameOfSelectedElements( LightApp_SelectionMgr*, QString& ); SMESHGUI_EXPORT int GetSelected( LightApp_SelectionMgr*, TColStd_IndexedMapOfInteger&, - const bool = true ); + const bool = true ); SMESHGUI_EXPORT int GetEdgeNodes( LightApp_SelectionMgr*, int&, int& ); SMESHGUI_EXPORT void SetControlsPrecision( const long ); + +#ifndef DISABLE_PLOT2DVIEWER +SMESHGUI_EXPORT + void ClearPlot2Viewers( SUIT_ViewWindow* theWindow ); +#endif + + //---------------------------------------------------------------------------- +SMESHGUI_EXPORT + bool ComputeClippingPlaneParameters( std::list theActorList, + vtkFloatingPointType theNormal[3], + vtkFloatingPointType theDist, + vtkFloatingPointType theBounds[6], + vtkFloatingPointType theOrigin[3] ); + SMESHGUI_EXPORT + void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews = false ); }; #endif // SMESHGUI_VTKUTILS_H diff --git a/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx b/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx deleted file mode 100755 index c49e2dc1c..000000000 --- a/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx +++ /dev/null @@ -1,589 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_WhatIsDlg.cxx -// Author : Vladimir TURIN, Open CASCADE S.A.S. -// SMESH includes -// -#include "SMESHGUI_WhatIsDlg.h" - -#include "SMESHGUI.h" -#include "SMESHGUI_Utils.h" -#include "SMESHGUI_VTKUtils.h" -#include "SMESHGUI_MeshUtils.h" -#include "SMESHGUI_IdValidator.h" - -#include "SMESH_Actor.h" -#include "SMESH_TypeFilter.hxx" -#include "SMESH_LogicalFilter.hxx" -#include "SMDS_Mesh.hxx" -#include "SMDS_VolumeTool.hxx" - -// SALOME GUI includes -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -// OCCT includes -#include -#include - -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Group) - -#define SPACING 6 -#define MARGIN 11 - -//================================================================================= -// class : SMESHGUI_WhatIsDlg() -// purpose : -//================================================================================= -SMESHGUI_WhatIsDlg::SMESHGUI_WhatIsDlg( SMESHGUI* theModule ) - : QDialog( SMESH::GetDesktop( theModule ) ), - mySMESHGUI( theModule ), - mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) -{ - setModal( false ); - setAttribute( Qt::WA_DeleteOnClose, true ); - setWindowTitle(tr("SMESH_WHAT_IS_TITLE")); - setSizeGripEnabled(true); - QVBoxLayout* SMESHGUI_WhatIsDlgLayout = new QVBoxLayout(this); - SMESHGUI_WhatIsDlgLayout->setSpacing(SPACING); - SMESHGUI_WhatIsDlgLayout->setMargin(MARGIN); - - /***************************************************************/ - GroupMesh = new QGroupBox(this); - QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh); - GroupMeshLayout->setSpacing(SPACING); - GroupMeshLayout->setMargin(MARGIN); - - MeshLabel = new QLabel(tr("SMESH_NAME"), GroupMesh); - GroupMeshLayout->addWidget(MeshLabel); - MeshName = new QLineEdit(GroupMesh); - MeshName->setReadOnly(true); - GroupMeshLayout->addWidget(MeshName); - - /***************************************************************/ - GroupSelections = new QGroupBox(tr("ENTITY_TYPE"), this); - QButtonGroup* GroupSel = new QButtonGroup(this); - QHBoxLayout* GroupSelectionsLayout = new QHBoxLayout(GroupSelections); - GroupSelectionsLayout->setSpacing(SPACING); - GroupSelectionsLayout->setMargin(MARGIN); - - RadioButtonNodes = new QRadioButton(tr("SMESH_NODES"), GroupSelections); - GroupSelectionsLayout->addWidget(RadioButtonNodes); - GroupSel->addButton(RadioButtonNodes, 0); - RadioButtonElements = new QRadioButton(tr("SMESH_ELEMENTS"), GroupSelections); - GroupSelectionsLayout->addWidget(RadioButtonElements); - GroupSel->addButton(RadioButtonElements, 1); - - /***************************************************************/ - GroupArguments = new QGroupBox(tr("SMESH_INFORMATION"), this); - QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments); - GroupArgumentsLayout->setSpacing(SPACING); - GroupArgumentsLayout->setMargin(MARGIN); - - // Controls for elements selection - TextLabelElements = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments); - GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0); - - LineEditElements = new QLineEdit(GroupArguments); - LineEditElements->setValidator(new SMESHGUI_IdValidator(this)); - GroupArgumentsLayout->addWidget(LineEditElements, 0, 1); - - // information text browser - Info = new QTextBrowser(GroupArguments); - Info->setMinimumSize(200, 150); - GroupArgumentsLayout->addWidget(Info, 1, 0, 1, 2); - - /***************************************************************/ - GroupButtons = new QGroupBox(this); - QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons); - GroupButtonsLayout->setSpacing(SPACING); - GroupButtonsLayout->setMargin(MARGIN); - - buttonOk = new QPushButton(tr("SMESH_BUT_OK"), GroupButtons); - buttonOk->setAutoDefault(true); - buttonOk->setDefault(true); - buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons); - buttonHelp->setAutoDefault(true); - - GroupButtonsLayout->addWidget(buttonOk); - GroupButtonsLayout->addSpacing(10); - GroupButtonsLayout->addStretch(); - GroupButtonsLayout->addWidget(buttonHelp); - - SMESHGUI_WhatIsDlgLayout->addWidget(GroupMesh); - SMESHGUI_WhatIsDlgLayout->addWidget(GroupSelections); - SMESHGUI_WhatIsDlgLayout->addWidget(GroupArguments); - SMESHGUI_WhatIsDlgLayout->addWidget(GroupButtons); - - RadioButtonNodes->setChecked(true); - - mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); - - mySMESHGUI->SetActiveDialogBox((QDialog*)this); - - // Costruction of the logical filter - SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH); - SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP); - - QList aListOfFilters; - if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); - if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); - - myMeshOrSubMeshOrGroupFilter = - new SMESH_LogicalFilter(aListOfFilters, SMESH_LogicalFilter::LO_OR); - - myHelpFileName = "mesh_infos_page.html#mesh_element_info_anchor"; - - Init(); - - /* signals and slots connections */ - connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk())); - connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); - connect(GroupSel, SIGNAL(buttonClicked(int)), SLOT(SelectionsClicked(int))); - - connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - /* to close dialog if study change */ - connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - connect(LineEditElements, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&))); - - SelectionsClicked(0); - SelectionIntoArgument(); -} - -//================================================================================= -// function : ~SMESHGUI_WhatIsDlg() -// purpose : Destroys the object and frees any allocated resources -//================================================================================= -SMESHGUI_WhatIsDlg::~SMESHGUI_WhatIsDlg() -{ -} - -//================================================================================= -// function : Init() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::Init (bool ResetControls) -{ - myBusy = false; - - LineEditElements->clear(); - - myActor = 0; - myMesh = SMESH::SMESH_Mesh::_nil(); - - if (ResetControls) { - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( CellSelection ); - onTextChange(LineEditElements->text()); - - SelectionIntoArgument(); - } -} - -//================================================================================= -// function : SelectionsClicked() -// purpose : Radio button management -//================================================================================= -void SMESHGUI_WhatIsDlg::SelectionsClicked (int selectionId) -{ - disconnect(mySelectionMgr, 0, this, 0); - - mySelectionMgr->clearFilters(); - - switch (selectionId) { - case 0: - { - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( NodeSelection ); - break; - } - case 1: - { - SMESH::SetPointRepresentation(false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( CellSelection ); - break; - } - } - - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - SelectionIntoArgument(); -} - -//================================================================================= -// function : ClickOnOk() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::ClickOnOk() -{ - if (mySMESHGUI->isActiveStudyLocked()) - return; - - SMESH::UpdateView(); - Init(false); - SelectionIntoArgument(); - ClickOnCancel(); -} - -//================================================================================= -// function : ClickOnCancel() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::ClickOnCancel() -{ - disconnect(mySelectionMgr, 0, this, 0); - mySelectionMgr->clearFilters(); - SMESH::SetPointRepresentation(false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( ActorSelection ); - mySMESHGUI->ResetState(); - reject(); -} - -//================================================================================= -// function : ClickOnHelp() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::ClickOnHelp() -{ - LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) - app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); - else { - SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - "application")). - arg(myHelpFileName)); - } -} - -//======================================================================= -// function : onTextChange() -// purpose : -//======================================================================= -void SMESHGUI_WhatIsDlg::onTextChange (const QString& theNewText) -{ - if (myBusy) return; - myBusy = true; - - // hilight entered elements - SMDS_Mesh* aMesh = 0; - if (myActor) - aMesh = myActor->GetObject()->GetMesh(); - - if (aMesh) { - Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); - - TColStd_MapOfInteger newIndices; - - QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); - - for (int i = 0; i < aListId.count(); i++) { - const SMDS_MeshElement * e = RadioButtonNodes->isChecked()? - aMesh->FindNode(aListId[ i ].toInt()): - aMesh->FindElement(aListId[ i ].toInt()); - if (e) - newIndices.Add(e->GetID()); - } - - mySelector->AddOrRemoveIndex( anIO, newIndices, false ); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->highlight( anIO, true, true ); - } - - SelectionIntoArgument(); - - myBusy = false; -} - -//================================================================================= -// function : SelectionIntoArgument() -// purpose : Called when selection as changed or other case -//================================================================================= -void SMESHGUI_WhatIsDlg::SelectionIntoArgument() -{ - int curBusy = myBusy; - - // clear - myActor = 0; - QString aString = ""; - - myBusy = true; - if(!curBusy) - LineEditElements->setText(aString); - MeshName->setText(aString); - GroupMesh->setTitle(tr("")); - Info->clear(); - myBusy = curBusy; - - if (!GroupButtons->isEnabled()) // inactive - return; - - // get selected mesh - SALOME_ListIO aList; - mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type()); - - int nbSel = aList.Extent(); - - if (nbSel != 1) - return; - - Handle(SALOME_InteractiveObject) IO = aList.First(); - myMesh = SMESH::GetMeshByIO(IO); - if (myMesh->_is_nil()) - return; - - myActor = SMESH::FindActorByObject(myMesh); - if (!myActor) - myActor = SMESH::FindActorByEntry(IO->getEntry()); - if (!myActor) - return; - - QString aName; - SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName); - MeshName->setText(aName); - if(!SMESH::IObjectToInterface(IO)->_is_nil()) { - GroupMesh->setTitle(tr("SMESH_MESH")); - } else if(!SMESH::IObjectToInterface(IO)->_is_nil()) { - GroupMesh->setTitle(tr("SMESH_SUBMESH")); - } else if(!SMESH::IObjectToInterface(IO)->_is_nil()) { - GroupMesh->setTitle(tr("SMESH_GROUP")); - } - - int aNbUnits = 0; - - aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString); - - if (aNbUnits < 1) - return; - - const SMDS_MeshElement * e = RadioButtonNodes->isChecked()? - myActor->GetObject()->GetMesh()->FindNode(aString.toInt()): - myActor->GetObject()->GetMesh()->FindElement(aString.toInt()); - if (e) { - QString anInfo; - anInfo=tr("ENTITY_TYPE") + ": "; - if(e->GetType() == SMDSAbs_Node) { - anInfo+=tr("MESH_NODE")+"\n"; - //const SMDS_MeshNode *en = (SMDS_MeshNode*) e; // VSR: not used! - } else if(e->GetType() == SMDSAbs_Edge) { - anInfo+=tr("SMESH_EDGE")+"\n"; - anInfo+=tr("SMESH_MESHINFO_TYPE")+": "; - const SMDS_MeshEdge *ee = (SMDS_MeshEdge*) e; - anInfo+=(ee->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+"\n"; - } else if(e->GetType() == SMDSAbs_Face) { - const SMDS_MeshFace *ef = (SMDS_MeshFace*) e; - anInfo+=tr("SMESH_FACE")+"\n"; - anInfo+=tr("SMESH_MESHINFO_TYPE")+": "; - if(!ef->IsPoly()) - anInfo+=(ef->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+" "; - switch(ef->NbNodes()) { - case 3: - case 6: - { - anInfo+=tr("SMESH_TRIANGLE"); - break; - } - case 4: - case 8: - { - anInfo+=tr("SMESH_QUADRANGLE"); - break; - } - default: - break; - } - anInfo+="\n"; - } else if(e->GetType() == SMDSAbs_Volume) { - anInfo+=tr("SMESH_VOLUME")+"\n"; - anInfo+=tr("SMESH_MESHINFO_TYPE")+": "; - const SMDS_MeshVolume *ev = (SMDS_MeshVolume*) e; - SMDS_VolumeTool vt(ev); - if(vt.GetVolumeType() != SMDS_VolumeTool::POLYHEDA) - anInfo+=(ev->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+" "; - switch(vt.GetVolumeType()) { - case SMDS_VolumeTool::TETRA: - case SMDS_VolumeTool::QUAD_TETRA: - { - anInfo+=tr("SMESH_TETRAS"); - break; - } - case SMDS_VolumeTool::PYRAM: - case SMDS_VolumeTool::QUAD_PYRAM: - { - anInfo+=tr("SMESH_PYRAMID"); - break; - } - case SMDS_VolumeTool::PENTA: - case SMDS_VolumeTool::QUAD_PENTA: - { - anInfo+=tr("SMESH_PRISM"); - break; - } - case SMDS_VolumeTool::HEXA: - case SMDS_VolumeTool::QUAD_HEXA: - { - anInfo+=tr("SMESH_HEXAS"); - break; - } - case SMDS_VolumeTool::POLYHEDA: - { - anInfo+=tr("SMESH_POLYEDRON"); - break; - } - default: - break; - } - anInfo+="\n"; - } - if(e->GetType() != SMDSAbs_Node) - anInfo+=tr("GRAVITY_CENTER") + ":\n"; - gp_XYZ anXYZ(0.,0.,0.); - SMDS_ElemIteratorPtr nodeIt = e->nodesIterator(); - int nbNodes = 0; - for( ; nodeIt->more(); nbNodes++) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) ); - } - anXYZ.Divide(e->NbNodes()); - anInfo+=QString("X=%1\nY=%2\nZ=%3\n").arg(anXYZ.X()).arg(anXYZ.Y()).arg(anXYZ.Z()); - Info->setText(anInfo); - } - - if(!curBusy) { - myBusy = true; - LineEditElements->setText(aString); - myBusy = false; - } -} - -//================================================================================= -// function : DeactivateActiveDialog() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::DeactivateActiveDialog() -{ - if (GroupArguments->isEnabled()) { - GroupSelections->setEnabled(false); - GroupMesh->setEnabled(false); - GroupArguments->setEnabled(false); - GroupButtons->setEnabled(false); - mySMESHGUI->ResetState(); - mySMESHGUI->SetActiveDialogBox(0); - } -} - -//================================================================================= -// function : ActivateThisDialog() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::ActivateThisDialog() -{ - /* Emit a signal to deactivate the active dialog */ - mySMESHGUI->EmitSignalDeactivateDialog(); - GroupArguments->setEnabled(true); - GroupButtons->setEnabled(true); - GroupSelections->setEnabled(true); - GroupMesh->setEnabled(true); - - mySMESHGUI->SetActiveDialogBox((QDialog*)this); - - if ( SMESH::GetViewWindow( mySMESHGUI )) - SelectionsClicked(RadioButtonNodes->isChecked()?0:1); - - SelectionIntoArgument(); -} - -//================================================================================= -// function : enterEvent() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::enterEvent (QEvent*) -{ - if (!GroupArguments->isEnabled()) - ActivateThisDialog(); -} - -//================================================================================= -// function : closeEvent() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::closeEvent (QCloseEvent*) -{ - /* same than click on cancel button */ - ClickOnCancel(); -} - -//======================================================================= -//function : hideEvent -//purpose : caused by ESC key -//======================================================================= -void SMESHGUI_WhatIsDlg::hideEvent (QHideEvent*) -{ - if (!isMinimized()) - ClickOnCancel(); -} - -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void SMESHGUI_WhatIsDlg::keyPressEvent( QKeyEvent* e ) -{ - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; - - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - ClickOnHelp(); - } -} diff --git a/src/SMESHGUI/SMESHGUI_WhatIsDlg.h b/src/SMESHGUI/SMESHGUI_WhatIsDlg.h deleted file mode 100755 index e308c53c1..000000000 --- a/src/SMESHGUI/SMESHGUI_WhatIsDlg.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_WhatIsDlg.h -// Author : Vladimir TURIN, Open CASCADE S.A.S. -// -#ifndef SMESHGUI_WHATISDLG_H -#define SMESHGUI_WHATISDLG_H - -// Qt includes -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Mesh) - -class QGroupBox; -class QLabel; -class QLineEdit; -class QPushButton; -class QRadioButton; -class QTextBrowser; -class SMESHGUI; -class SMESH_Actor; -class SVTK_Selector; -class LightApp_SelectionMgr; -class SMESH_LogicalFilter; - -//================================================================================= -// class : SMESHGUI_WhatIsDlg -// purpose : -//================================================================================= -class SMESHGUI_WhatIsDlg : public QDialog -{ - Q_OBJECT - -public: - SMESHGUI_WhatIsDlg( SMESHGUI* ); - ~SMESHGUI_WhatIsDlg(); - -private: - void Init( bool = true ); - void closeEvent( QCloseEvent* ); - void enterEvent( QEvent* ); /* mouse enter the QWidget */ - void hideEvent( QHideEvent* ); /* ESC key */ - void keyPressEvent( QKeyEvent* ); - - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ - LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ - - SVTK_Selector* mySelector; - - bool myBusy; - SMESH::SMESH_Mesh_var myMesh; - SMESH_Actor* myActor; - SMESH_LogicalFilter* myMeshOrSubMeshOrGroupFilter; - - QGroupBox* GroupSelections; - QRadioButton* RadioButtonNodes; - QRadioButton* RadioButtonElements; - QGroupBox* GroupButtons; - QPushButton* buttonOk; - QPushButton* buttonHelp; - QGroupBox* GroupArguments; - QGroupBox* GroupMesh; - QLabel* TextLabelElements; - QLineEdit* LineEditElements; - QLabel* MeshLabel; - QLineEdit* MeshName; - - QTextBrowser* Info; - - QString myHelpFileName; - -private slots: - void SelectionsClicked( int ); - void ClickOnOk(); - void ClickOnCancel(); - void ClickOnHelp(); - void SelectionIntoArgument(); - void DeactivateActiveDialog(); - void ActivateThisDialog(); - void onTextChange( const QString& ); -}; - -#endif // SMESHGUI_WHATISDLG_H diff --git a/src/SMESHGUI/SMESHGUI_XmlHandler.cxx b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx index f10cb0341..d02d9cd02 100644 --- a/src/SMESHGUI/SMESHGUI_XmlHandler.cxx +++ b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms // File : SMESHGUI_XmlHandler.cxx // Author : Julia DOROVSKIKH, Open CASCADE S.A.S. @@ -103,7 +104,7 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, { MESSAGE("Loading Resources " << aResName.toLatin1().data()); SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr(); - QString lang = resMgr->stringValue( resMgr->langSection(), "language", "en" ); + QString lang = resMgr->stringValue( resMgr->langSection(), "language", "en" ); resMgr->loadTranslator( "resources", QString( "%1_msg_%2.qm" ).arg( aResName, lang ) ); resMgr->loadTranslator( "resources", QString( "%1_images.qm" ).arg( aResName, lang ) ); } @@ -164,11 +165,11 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, if (qName == "algorithm") { - myAlgorithmsMap[aHypAlType] = aHypData; + myAlgorithmsMap.insert(aHypAlType,aHypData); } else { - myHypothesesMap[aHypAlType] = aHypData; + myHypothesesMap.insert(aHypAlType,aHypData); } } } @@ -186,11 +187,17 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, { QString aHypos = isHypo ? atts.value("hypos") : atts.value("algos"); aHypos = aHypos.remove( ' ' ); - QStringList* aHypoList = isHypo ? & aHypoSet->HypoList : & aHypoSet->AlgoList; - *aHypoList = aHypos.split( ',', QString::SkipEmptyParts ); + aHypoSet->set( !isHypo, aHypos.split( ',', QString::SkipEmptyParts ) ); } } } + else if ( qName == "python-wrap" || + qName == "algo" || + qName == "hypo" ) + { + // elements used in SMESH_2smeshpy + return true; + } else { // error diff --git a/src/SMESHGUI/SMESHGUI_XmlHandler.h b/src/SMESHGUI/SMESHGUI_XmlHandler.h index 09db44219..813938ddf 100644 --- a/src/SMESHGUI/SMESHGUI_XmlHandler.h +++ b/src/SMESHGUI/SMESHGUI_XmlHandler.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms // File : SMESHGUI_XmlHandler.h // Author : Julia DOROVSKIKH, Open CASCADE S.A.S. @@ -34,6 +35,9 @@ #include #include +//GUI includes +#include + class HypothesisData; class HypothesesSet; @@ -45,7 +49,7 @@ public: bool startDocument(); bool startElement( const QString&, const QString&, - const QString&, const QXmlAttributes& ); + const QString&, const QXmlAttributes& ); bool endElement( const QString&, const QString&, const QString& ); bool characters( const QString& ); @@ -54,8 +58,8 @@ public: bool fatalError( const QXmlParseException& ); public: - QMap myHypothesesMap; - QMap myAlgorithmsMap; + IMap myHypothesesMap; + IMap myAlgorithmsMap; QList myListOfHypothesesSets; diff --git a/src/SMESHGUI/SMESH_SMESHGUI.hxx b/src/SMESHGUI/SMESH_SMESHGUI.hxx index 46a6cb93a..62d860960 100755 --- a/src/SMESHGUI/SMESH_SMESHGUI.hxx +++ b/src/SMESHGUI/SMESH_SMESHGUI.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_SMESHGUI.hxx // Author : Alexander BORODIN, Open CASCADE S.A.S. // @@ -26,7 +27,7 @@ #define SMESH_SMESHGUI_HXX #ifdef WNT - #if defined SMESHGUI_EXPORTS + #if defined SMESHGUI_EXPORTS || defined SMESH_EXPORTS #define SMESHGUI_EXPORT __declspec( dllexport ) #else #define SMESHGUI_EXPORT __declspec( dllimport ) diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts index 0319ce689..6012d758c 100644 --- a/src/SMESHGUI/SMESH_images.ts +++ b/src/SMESHGUI/SMESH_images.ts @@ -1,28 +1,6 @@ + - - + @default @@ -53,6 +31,10 @@ ICON_BUILD_COMPOUND mesh_build_compound.png + + ICON_COPY_MESH + copy_mesh.png + ICON_COMPUTE mesh_compute.png @@ -109,6 +91,22 @@ ICON_DLG_BUILD_COMPOUND_MESH mesh_build_compound.png + + ICON_DLG_COPY_MESH + copy_mesh.png + + + ICON_DLG_BALL + mesh_ball.png + + + ICON_DLG_BALL_ELEMENT + mesh_ball.png + + + ICON_DLG_ELEM0D + mesh_vertex.png + ICON_DLG_EDGE mesh_line.png @@ -153,6 +151,14 @@ ICON_DLG_NODE mesh_vertex.png + + ICON_DLG_OCTA + mesh_octahedron.png + + + ICON_DLG_PENTA + mesh_pentahedron.png + ICON_DLG_POLYGON mesh_polygon.png @@ -161,6 +167,10 @@ ICON_DLG_POLYHEDRON mesh_polyhedron.png + + ICON_DLG_PYRAMID + mesh_pyramid.png + ICON_DLG_QUADRANGLE mesh_quad.png @@ -173,6 +183,10 @@ ICON_DLG_QUADRATIC_HEXAHEDRON mesh_quad_hexahedron.png + + ICON_DLG_TRIQUADRATIC_HEXAHEDRON + mesh_triquad_hexahedron.png + ICON_DLG_QUADRATIC_PENTAHEDRON mesh_quad_pentahedron.png @@ -185,6 +199,10 @@ ICON_DLG_QUADRATIC_QUADRANGLE mesh_quad_quadrangle.png + + ICON_DLG_BIQUADRATIC_QUADRANGLE + mesh_biquad_quadrangle.png + ICON_DLG_QUADRATIC_TETRAHEDRON mesh_quad_tetrahedron.png @@ -201,6 +219,10 @@ ICON_DLG_REM_NODE mesh_rem_node.png + + ICON_DLG_REM_ORPHAN_NODES + mesh_rem_orphan_nodes.png + ICON_DLG_RENUMBERING_ELEMENTS mesh_renumbering_elements.png @@ -253,6 +275,10 @@ ICON_FREE_FACES mesh_free_faces.png + + ICON_FIND_ELEM + mesh_find_elem_by_point.png + ICON_HYPO mesh_hypo_length.png @@ -277,6 +303,14 @@ ICON_MAP mesh_pattern.png + + ICON_MAX_ELEMENT_LENGTH_2D + mesh_max_element_length_2d.png + + + ICON_MAX_ELEMENT_LENGTH_3D + mesh_max_element_length_3d.png + ICON_OBJBROWSER_SMESH mesh.png @@ -365,6 +399,34 @@ ICON_SMESH_TRANSLATION_VECTOR mesh_translation_vector.png + + ICON_DLG_MESH_SCALE + scale.png + + + ICON_DLG_SCALE_ALONG_AXES + scale_along_axes.png + + + ICON_DLG_REORIENT2D_POINT + reorient_faces_point.png + + + ICON_DLG_REORIENT2D_FACE + reorient_faces_face.png + + + ICON_REORIENT_2D + reorient_faces_face.png + + + ICON_SMESH_DUPLICATE_NODES + mesh_duplicate_nodes.png + + + ICON_SMESH_DUPLICATE_NODES_WITH_ELEM + mesh_duplicate_nodes_with_elem.png + ICON_SMESH_TREE_ALGO mesh_tree_algo.png @@ -373,6 +435,10 @@ ICON_SMESH_TREE_GROUP mesh_tree_group.png + + ICON_SMESH_TREE_GROUP_ON_FILTER + mesh_tree_group_on_filter.png + ICON_SMESH_TREE_HYPO mesh_tree_hypo.png @@ -421,13 +487,45 @@ ICON_VOLUME_3D mesh_volume_3d.png + + ICON_BARE_BORDER_VOLUME + bare_border_volume.png + + + ICON_BARE_BORDER_FACE + bare_border_face.png + + + ICON_OVER_CONSTRAINED_VOLUME + over_constrained_volume.png + + + ICON_OVER_CONSTRAINED_FACE + over_constrained_face.png + + + ICON_EQUAL_NODE + mesh_equal_node.png + + + ICON_EQUAL_EDGE + mesh_equal_edge.png + + + ICON_EQUAL_FACE + mesh_equal_face.png + + + ICON_EQUAL_VOLUME + mesh_equal_volume.png + ICON_WARP mesh_wrap.png ICON_WHAT_IS - mesh_whatis.png + mesh_elem_info.png ICON_WIRE @@ -441,5 +539,21 @@ ICON_UNDERLYING_ELEMS mesh_extractGroup.png + + ICON_2D_FROM_3D + mesh_2d_from_3d.png + + + ICON_SPLIT_TO_TETRA + split_into_tetra.png + + + ICON_MEASURE_MIN_DIST + mesh_min_dist.png + + + ICON_MEASURE_BND_BOX + mesh_bounding_box.png + diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index a93b7d1f6..2ac37e0f5 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -1,4045 +1,6592 @@ + - - - - @default - - AREA_ELEMENTS - Area - - - ASPECTRATIO_3D_ELEMENTS - Aspect Ratio 3D - - - ASPECTRATIO_ELEMENTS - Aspect Ratio - - - COL_ALGO_HEADER - Algorithm - - - COL_ERROR_HEADER - Error - - - COL_SHAPE_HEADER - SubShape - - - COMPERR_ALGO_FAILED - Algorithm failed - - - COMPERR_BAD_INPUT_MESH - Invalid input mesh - - - COMPERR_BAD_SHAPE - Unexpected geometry - - - COMPERR_EXCEPTION - Unknown exception - - - COMPERR_MEMORY_PB - Memory allocation problem - - - COMPERR_OCC_EXCEPTION - OCC exception - - - COMPERR_OK - No errors - - - COMPERR_SLM_EXCEPTION - SALOME exception - - - COMPERR_STD_EXCEPTION - std::exception - - - SMESH_GEOM - Geometry - - - DIRECT_GEOM_SELECTION - Direct geometry selection - - - ELEMENT_ID - Element ID - - - FREE_BORDERS - Free Borders - - - GEOMETRY_NAME - Geometry name - - - GEOM_BY_MESH_ELEM_SELECTION - Find geometry by mesh element selection - - - GLOBAL_ALGO - Global - - - INF_SELECT_OBJECT - Select an object - - - LENGTH2D_EDGES - Length 2D - - - LENGTH_EDGES - Length - - - LOCAL_ALGO - Local - - - MEN_ADD - Add - - - MEN_ADV_INFO - Advanced Mesh Infos - - - MEN_ALL - All - - - MEN_AREA - Area - - - MEN_ASPECT - Aspect Ratio - - - MEN_ASPECT_3D - Aspect Ratio 3D - - - MEN_AUTO_COLOR - Auto Color - - - MEN_AUTO_UPD - Automatic Update - - - MEN_BUILD_COMPOUND - Build Compound - - - MEN_CLIP - Clipping - - - MEN_COLORS - Colors / Size - - - MEN_COMPUTE - Compute - - - MEN_PRECOMPUTE - Preview - - - MEN_CONNECTION - Borders at Multi-Connection - - - MEN_CONNECTION_2D - Borders at Multi-Connection 2D - - - MEN_CONSTRUCT_GROUP - Construct Group - - - MEN_CONV_TO_QUAD - Convert to/from quadratic - - - MEN_CREATE_GROUP - Create Group - - - MEN_CREATE_GEO_GROUP - Create Groups from Geometry - - - MEN_CREATE_MESH - Create Mesh - - - MEN_CREATE_SUBMESH - Create Sub-mesh - - - MEN_CTRL - Controls - - - MEN_CUT - Cutting of Quadrangles - - - MEN_CUT_GROUP - Cut Groups - - - MEN_DAT - DAT File - - - MEN_DELETE - Delete - - - MEN_DEL_GROUP - Delete Groups - - - MEN_FACE_ORIENTATION - Orientation of Faces - - - MEN_DISABLE_AUTO_COLOR - Disable Auto Color - - - MEN_DISPLAY_ONLY - Show Only - - - MEN_DISPMODE - Display Mode - - - MEN_DISP_ENT - Display Entity - - - MEN_EDGE - Edge - - - MEN_EDGES - Edges - - - MEN_EDIT - Edit - - - MEN_EDIT_GROUP - Edit Group - - - MEN_EDIT_GEOMGROUP_AS_GROUP - Edit Group as Standalone - - - MEN_EDIT_HYPO - Edit Hypothesis - - - MEN_EDIT_MESHSUBMESH - Edit Mesh/Sub-mesh - - - MEN_EXPORT - Export - - - MEN_EXPORT_DAT - Export to DAT File - - - MEN_EXPORT_MED - Export to MED File - - - MEN_EXPORT_STL - Export to STL File - - - MEN_EXPORT_UNV - Export to UNV File - - - MEN_EXTRUSION - Extrusion - - - MEN_EXTRUSION_ALONG - Extrusion Along a Path - - - MEN_FACES - Faces - - - MEN_FILE - File - - - MEN_FREE_BORDER - Free Borders - - - MEN_FREE_EDGE - Free Edges - - - MEN_FREE_NODE - Free Nodes - - - MEN_FREE_FACES - Free Faces - - - MEN_GLOBAL_HYPO - Global Hypothesis - - - MEN_HEXA - Hexahedron - - - MEN_HIDE - Hide - - - MEN_HYPO - Hypotheses - - - MEN_IMPORT - Import - - - MEN_INT_GROUP - Intersect Groups - - - MEN_INV - Diagonal Inversion - - - MEN_LENGTH - Length - - - MEN_LENGTH_2D - Length 2D - - - MEN_MAP - Pattern Mapping - - - MEN_MED - MED file - - - MEN_MERGE - Merge Nodes - - - MEN_MERGE_ELEMENTS - Merge Elements - - - MEN_MESH - Mesh - - - MEN_MESH_THROU_POINT - Mesh to Pass Through a Point - - - MEN_MIN_ANG - Minimum Angle - - - MEN_MODIFY - Modification - - - MEN_MOVE - Move Node - - - MEN_NODE - Node - - - MEN_NODES - Nodes - - - MEN_NUM - Numbering - - - MEN_NUM_ELEMENTS - Display Elements # - - - MEN_NUM_NODES - Display Nodes # - - - MEN_ORIENT - Orientation - - - MEN_POLYGON - Polygon - - - MEN_POLYHEDRON - Polyhedron - - - MEN_PRECISION - Precision - - - MEN_PREF - Preferences - - - MEN_QUAD - Quadrangle - - - MEN_QUADRATIC_EDGE - Quadratic Edge - - - MEN_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - MEN_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - MEN_QUADRATIC_PYRAMID - Quadratic Pyramid - - - MEN_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - MEN_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - MEN_QUADRATIC_TRIANGLE - Quadratic Triangle - - - MEN_QUALITY - Quality Controls - - - MEN_REMOVE - Remove - - - MEN_REMOVE_ELEMENTS - Elements - - - MEN_REMOVE_NODES - Nodes - - - MEN_RENAME - Rename - - - MEN_RENUM - Renumbering - - - MEN_RENUM_ELEMENTS - Elements - - - MEN_RENUM_NODES - Nodes - - - MEN_RESET - Reset - - - MEN_REVOLUTION - Revolution - - - MEN_ROT - Rotation - - - MEN_SCALAR_BAR - Scalar Bar - - - MEN_SCALAR_BAR_PROP - Scalar Bar Properties - - - MEN_SELECTION - Selection - - - MEN_SEL_FILTER_LIB - Selection Filters Library - - - MEN_SEW - Sewing - - - MEN_SHADE - Shading - - - MEN_SHOW - Show - - - MEN_SHRINK - Shrink - - - MEN_SKEW - Skew - - - MEN_SMOOTH - Smoothing - - - MEN_STD_INFO - Standard Mesh Infos - - - MEN_STL - STL File - - - MEN_SYM - Symmetry - - - MEN_TAPER - Taper - - - MEN_TETRA - Tetrahedron - - - MEN_TOOLS - Tools - - - MEN_TRANS - Translation - - - MEN_TRANSF - Transformation - - - MEN_TRANSP - Transparency - - - MEN_TRIANGLE - Triangle - - - MEN_UNASSIGN - Unassign - - - MEN_UNION - Union of Triangles - - - MEN_UNION2 - Union of Two Triangles - - - MEN_UNV - UNV File - - - MEN_UN_GROUP - Union Groups - - - MEN_UNDERLYING_ELEMS - Group of underlying entities - - - MEN_UPDATE - Update - - - MEN_VIEW - View - - - MEN_VOLUMES - Volumes - - - MEN_VOLUME_3D - Volume - - - MEN_WARP - Warping Angle - - - MEN_WHAT_IS - Mesh Element Info - - - MEN_WIRE - Wireframe - - - MESHERS_FILE_CANT_OPEN - Can not open resource file - - - MESHERS_FILE_CHECK_VARIABLE - Check environment variable SMESH_MeshersList - - - MESHERS_FILE_NO_VARIABLE - Environment variable SMESH_MeshersList is not defined - - - MESH_IS_NOT_SELECTED - There is no selected mesh + + + @default + + SMESH_EXPORT_MESH + Export mesh + + + MED_FILES_FILTER + MED files + + + IDEAS_FILES_FILTER + IDEAS files + + + DAT_FILES_FILTER + DAT files + + + TEXT_FILES_FILTER + TXT files + + + MED_VX_FILES_FILTER + MED %1 files + + + STL_ASCII_FILES_FILTER + STL ASCII files + + + CGNS_FILES_FILTER + CGNS files + + + STL_BIN_FILES_FILTER + STL binary files + + + ALL_FILES_FILTER + All files + + + SMESH_AND + and + + + AREA_ELEMENTS + Area + + + ASPECTRATIO_3D_ELEMENTS + Aspect Ratio 3D + + + ASPECTRATIO_ELEMENTS + Aspect Ratio + + + NODE_POSITION + Position + + + U_POSITION + U + + + V_POSITION + V + + + COL_ALGO_HEADER + Algorithm + + + COL_ERROR_HEADER + Error + + + COL_SHAPE_HEADER + Sub-shape + + + COMPERR_ALGO_FAILED + Algorithm failed + + + COMPERR_BAD_INPUT_MESH + Invalid input mesh + + + COMPERR_BAD_SHAPE + Unexpected geometry + + + COMPERR_EXCEPTION + Unknown exception + + + COMPERR_MEMORY_PB + Memory allocation problem + + + COMPERR_OCC_EXCEPTION + OCC exception + + + COMPERR_OK + No errors + + + COMPERR_SLM_EXCEPTION + SALOME exception + + + COMPERR_STD_EXCEPTION + std::exception + + + COMPERR_UNKNOWN + Unknown error + + + COMPERR_CANCELED + Computation canceled + + + SMESH_GEOM + Geometry + + + DIRECT_GEOM_SELECTION + Direct geometry selection + + + ELEMENT_ID + Element ID + + + FREE_BORDERS + Free Borders + + + GEOMETRY_NAME + Geometry name + + + GEOM_BY_MESH_ELEM_SELECTION + Find geometry by mesh element selection + + + GLOBAL_ALGO + Global + + + INF_SELECT_OBJECT + Select an object + + + LENGTH2D_EDGES + Length 2D + + + LENGTH_EDGES + Length + + + LOCAL_ALGO + Local + + + MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + MEN_ADD + Add + + + MEN_ADV_INFO + Mesh Information + + + MEN_ALL + All + + + MEN_AREA + Area + + + MEN_ASPECT + Aspect Ratio + + + MEN_ASPECT_3D + Aspect Ratio 3D + + + MEN_AUTO_COLOR + Auto Color + + + MEN_AUTO_UPD + Automatic Update + + + MEN_BUILD_COMPOUND + Build Compound + + + MEN_COPY_MESH + Copy Mesh + + + MEN_CLIP + Clipping + + + MEN_COLORS + Properties + + + MEN_COMPUTE + Compute + + + MEN_PRECOMPUTE + Preview + + + MEN_EVALUATE + Evaluate + + + MEN_CONNECTION + Borders at Multi-Connection + + + MEN_CONNECTION_2D + Borders at Multi-Connection 2D + + + MEN_CONSTRUCT_GROUP + Construct Group + + + MEN_CONV_TO_QUAD + Convert to/from quadratic + + + MEN_2D_FROM_3D + Create boundary elements + + + MEN_MESH_ORDER + Change submesh priority + + + MEN_CREATE_GROUP + Create Group + + + MEN_CREATE_GEO_GROUP + Create Groups from Geometry + + + MEN_CREATE_MESH + Create Mesh + + + MEN_CREATE_SUBMESH + Create Sub-mesh + + + MEN_CTRL + Controls + + + MEN_NODE_CTRL + Node Controls + + + MEN_EDGE_CTRL + Edge Controls + + + MEN_FACE_CTRL + Face Controls + + + MEN_VOLUME_CTRL + Volume Controls + + + MEN_CUT + Cutting of Quadrangles + + + MEN_CUT_GROUP + Cut Groups + + + MEN_IMPORT_DAT + DAT File + + + MEN_DAT + DAT File + + + MEN_DELETE + Delete + + + MEN_DEL_GROUP + Delete Groups with Contents + + + MEN_FACE_ORIENTATION + Orientation of Faces + + + MEN_DISABLE_AUTO_COLOR + Disable Auto Color + + + MEN_DISPLAY_ONLY + Show Only + + + MEN_DISPMODE + Display Mode + + + MEN_DISP_ENT + Display Entity + + + MEN_ELEM0D + 0D Element + + + MEN_ELEMS0D + 0D Elements + + + MEN_BALL + Ball + + + MEN_BALLS + Balls + + + MEN_EDGE + Edge + + + MEN_EDGES + Edges + + + MEN_EDIT + Edit + + + MEN_EDIT_GROUP + Edit Group + + + MEN_EDIT_GEOMGROUP_AS_GROUP + Edit Group as Standalone + + + MEN_EDIT_HYPO + Edit Hypothesis + + + MEN_EDIT_MESHSUBMESH + Edit Mesh/Sub-mesh + + + MEN_EXPORT + Export + + + MEN_EXPORT_DAT + Export to DAT File + + + MEN_EXPORT_MED + Export to MED File + + + MEN_EXPORT_CGNS + Export to CGNS File + + + MEN_EXPORT_SAUV + Export to SAUV file + + + MEN_EXPORT_STL + Export to STL File + + + MEN_EXPORT_UNV + Export to UNV File + + + MEN_EXTRUSION + Extrusion + + + MEN_EXTRUSION_ALONG + Extrusion Along a Path + + + MEN_FACES + Faces + + + MEN_FILE + File + + + MEN_FIND_ELEM + Find Element by Point + + + TOP_REORIENT_2D + Reorient faces by vector + + + MEN_REORIENT_2D + Reorient faces by vector + + + STB_REORIENT_2D + Reorient faces by vector + + + TOP_FIND_ELEM + Find Element by Point + + + STB_FIND_ELEM + Find Element by Point + + + EQUAL_NODE + Double nodes + + + MEN_EQUAL_NODE + Double nodes + + + STB_EQUAL_NODE + Double nodes + + + TOP_EQUAL_NODE + Double nodes + + + EQUAL_EDGE + Double edges + + + MEN_EQUAL_EDGE + Double edges + + + STB_EQUAL_EDGE + Double edges + + + TOP_EQUAL_EDGE + Double edges + + + EQUAL_FACE + Double faces + + + MEN_EQUAL_FACE + Double faces + + + STB_EQUAL_FACE + Double faces + + + TOP_EQUAL_FACE + Double faces + + + EQUAL_VOLUME + Double volumes + + + MEN_EQUAL_VOLUME + Double volumes + + + STB_EQUAL_VOLUME + Double volumes + + + TOP_EQUAL_VOLUME + Double volumes + + + MEN_BARE_BORDER_VOLUME + Volumes with bare border + + + MEN_BARE_BORDER_FACE + Faces with bare border + + + MEN_OVER_CONSTRAINED_VOLUME + Over-constrained volumes + + + MEN_OVER_CONSTRAINED_FACE + Over-constrained faces + + + MEN_FREE_BORDER + Free Borders + + + MEN_FREE_EDGE + Free Edges + + + MEN_FREE_NODE + Free Nodes + + + MEN_FREE_FACES + Free Faces + + + MEN_GLOBAL_HYPO + Global Hypothesis + + + MEN_HEXA + Hexahedron + + + MEN_HIDE + Hide + + + MEN_HYPO + Hypotheses + + + MEN_IMPORT + Import + + + MEN_INT_GROUP + Intersect Groups + + + MEN_INV + Diagonal Inversion + + + MEN_LENGTH + Length + + + MEN_LENGTH_2D + Length 2D + + + MEN_MAP + Pattern Mapping + + + MEN_MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + MEN_MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + MEN_IMPORT_MED + MED file + + + MEN_MED + MED file + + + MEN_IMPORT_CGNS + CGNS file + + + MEN_CGNS + CGNS file + + + MEN_IMPORT_SAUV + SAUV file + + + MEN_SAUV + SAUV file + + + MEN_MERGE + Merge Nodes + + + MEN_MERGE_ELEMENTS + Merge Elements + + + MEN_MESH + Mesh + + + MEN_MESH_THROU_POINT + Move Node + + + MEN_MIN_ANG + Minimum Angle + + + MEN_MODIFY + Modification + + + MEN_MEASURE + Measurements + + + MEN_MEASURE_MIN_DIST + Minimum Distance + + + STB_MEASURE_MIN_DIST + Calculate minimum distance between two objects + + + TOP_MEASURE_MIN_DIST + Minimum distance + + + MEN_MEASURE_BND_BOX + Bounding Box + + + STB_MEASURE_BND_BOX + Calculate bounding box for the selected object(s) + + + TOP_MEASURE_BND_BOX + Bounding box + + + MEN_MOVE + Move Node + + + MEN_NODE + Node + + + MEN_NODES + Nodes + + + MEN_NUM + Numbering + + + MEN_NUM_ELEMENTS + Display Elements # + + + MEN_NUM_NODES + Display Nodes # + + + MEN_ORIENT + Orientation + + + MEN_POLYGON + Polygon + + + MEN_POLYHEDRON + Polyhedron + + + MEN_PRECISION + Precision + + + MEN_PREF + Preferences + + + MEN_QUAD + Quadrangle + + + MEN_QUADRATIC_EDGE + Quadratic Edge + + + MEN_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + MEN_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + MEN_QUADRATIC_PYRAMID + Quadratic Pyramid + + + MEN_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + MEN_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + MEN_QUADRATIC_TRIANGLE + Quadratic Triangle + + + MEN_QUALITY + Quality Controls + + + MEN_REMOVE + Remove + + + MEN_REMOVE_ELEMENTS + Elements + + + MEN_REMOVE_NODES + Nodes + + + MEN_REMOVE_ORPHAN_NODES + Orphan Nodes + + + MEN_RENAME + Rename + + + MEN_RENUM + Renumbering + + + MEN_RENUM_ELEMENTS + Elements + + + MEN_RENUM_NODES + Nodes + + + MEN_RESET + Reset + + + MEN_DISTRIBUTION_CTRL + Distribution + + + MEN_SAVE_DISTRIBUTION + Export ... + + + MEN_SHOW_DISTRIBUTION + Show + + + MEN_PLOT_DISTRIBUTION + Plot + + + DISTRIBUTION_NB_ENT + Number of entities + + + MEN_REVOLUTION + Revolution + + + MEN_ROT + Rotation + + + MEN_SCALAR_BAR + Scalar Bar + + + MEN_SCALAR_BAR_PROP + Scalar Bar Properties + + + MEN_SELECTION + Selection + + + MEN_SEL_FILTER_LIB + Selection Filters Library + + + MEN_SEW + Sewing + + + MEN_SHADE + Shading + + + MEN_QUADRATIC_REPRESENT + 2D Quadratic + + + MEN_LINE_REPRESENTATION + Lines + + + MEN_ARC_REPRESENTATION + Arcs + + + MEN_SHOW + Show + + + MEN_SHRINK + Shrink + + + MEN_SKEW + Skew + + + MEN_SMOOTH + Smoothing + + + MEN_STD_INFO + Standard Mesh Infos + + + MEN_IMPORT_STL + STL File + + + MEN_STL + STL File + + + MEN_SYM + Symmetry + + + MEN_TAPER + Taper + + + MEN_TETRA + Tetrahedron + + + MEN_TOOLS + Tools + + + MEN_TRANS + Translation + + + MEN_SCALE + Scale Transform + + + MEN_DUPLICATE_NODES + Duplicate Nodes + + + MEN_TRANSF + Transformation + + + MEN_TRANSP + Transparency + + + MEN_TRIANGLE + Triangle + + + MEN_UNASSIGN + Unassign + + + MEN_UNION + Union of Triangles + + + MEN_UNION2 + Union of Two Triangles + + + MEN_IMPORT_UNV + UNV File + + + MEN_UNV + UNV File + + + MEN_UN_GROUP + Union Groups + + + MEN_UNDERLYING_ELEMS + Group of underlying entities + + + MEN_UPDATE + Update + + + MEN_VIEW + View + + + MEN_VOLUMES + Volumes + + + MEN_VOLUME_3D + Volume + + + MEN_WARP + Warping Angle + + + MEN_WHAT_IS + Mesh Element Information + + + MEN_WIRE + Wireframe + + + MEN_SPLIT_TO_TETRA + Split into Tetrahedra + + + TOP_SPLIT_TO_TETRA + Split into Tetrahedra + + + STB_SPLIT_TO_TETRA + Split into Tetrahedra + + + MESHERS_FILE_CANT_OPEN + Can not open resource file + + + MESHERS_FILE_CHECK_VARIABLE + Check environment variable SMESH_MeshersList + + + MESHERS_FILE_NO_VARIABLE + Environment variable SMESH_MeshersList is not defined + + + MESH_IS_NOT_SELECTED + There is no selected mesh Please, select a mesh and try again - - - MESH_NODE - Node - - - MESH_NODE_TITLE - Add Node - - - MINIMUMANGLE_ELEMENTS - Minimum Angle - - - MULTI2D_BORDERS - Borders at Multi-Connections 2D - - - MULTI_BORDERS - Borders at Multi-Connections - - - NODE_ID - Node ID - - - NON_SMESH_OBJECTS_SELECTED - There are objects selected which do not belong to %1 component. - - - PREVIEW - Preview - - - SKEW_ELEMENTS - Skew - - - SMESHGUI_INVALID_PARAMETERS - Parameters are not correctly specified + + + MESH_NODE + Node + + + MESH_NODE_TITLE + Add Node + + + MINIMUMANGLE_ELEMENTS + Minimum Angle + + + MULTI2D_BORDERS + Borders at Multi-Connections 2D + + + MULTI_BORDERS + Borders at Multi-Connections + + + GROUP_NAME_IS_EMPTY + Name of group is not specified. +Please enter a name of new group to be created or choose an existing one. + + + MESH_STANDALONE_GRP_CHOSEN + Group on geometry is chosen: %1. +Do you want to convert it to the standalone group? + + + NODE_ID + Node ID + + + NON_SMESH_OBJECTS_SELECTED + There are objects selected which do not belong to %1 component. + + + PREVIEW + Preview + + + SKEW_ELEMENTS + Skew + + + SMESHGUI_INVALID_PARAMETERS + Parameters are not correctly specified Please enter correct values and try again - - - SMESH_ADD_ALGORITHM - Algorithms - - - SMESH_ADD_ALGORITHM_TITLE - Algorithms Assignation - - - SMESH_ADD_EDGE - Add Edge - - - SMESH_ADD_EDGE_TITLE - Add Edge - - - SMESH_ADD_HEXAS - Add Hexahedron - - - SMESH_ADD_HEXAS_TITLE - Add Hexahedron - - - SMESH_ADD_HYPOTHESIS - Hypothesis - - - SMESH_ADD_HYPOTHESIS_TITLE - Hypothesis Assignation - - - SMESH_ADD_HYP_WRN - "%1" assigned but: + + + SMESH_ADD_ALGORITHM + Algorithms + + + SMESH_ADD_ALGORITHM_TITLE + Algorithms Assignation + + + SMESH_ADD_ELEM0D + Add 0D Element + + + SMESH_ADD_ELEM0D_TITLE + Add 0D Element + + + SMESH_ADD_BALL + Add Ball Element + + + SMESH_ADD_BALL_TITLE + Add Ball Element + + + SMESH_ADD_EDGE + Add Edge + + + SMESH_ADD_EDGE_TITLE + Add Edge + + + SMESH_ADD_HEXAS + Add Hexahedron + + + SMESH_ADD_HEXAS_TITLE + Add Hexahedron + + + SMESH_ADD_HYPOTHESIS + Hypothesis + + + SMESH_ADD_HYPOTHESIS_TITLE + Hypothesis Assignation + + + SMESH_ADD_HYP_WRN + "%1" assigned but: + + + + SMESH_ADD_OCTA + Add hexagonal prism + + + SMESH_ADD_OCTA_TITLE + Add Hexagonal Prism + + + SMESH_ADD_POLYGON + Add polygon + + + SMESH_ADD_POLYGON_TITLE + Add Polygon + + + SMESH_ADD_PENTA + Add pentahedron + + + SMESH_ADD_PENTA_TITLE + Add Pentahedron + + + SMESH_ADD_PYRAMID + Add pyramid + + + SMESH_ADD_PYRAMID_TITLE + Add Pyramid + + + SMESH_ADD_QUADRANGLE + Add Quadrangle + + + SMESH_ADD_QUADRANGLE_TITLE + Add Quadrangle + + + SMESH_ADD_QUADRATIC_EDGE_TITLE + Add Quadratic Edge + + + SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE + Add Quadratic Hexahedron + + + SMESH_ADD_TRIQUADRATIC_HEXAHEDRON_TITLE + Add TriQuadratic Hexahedron + + + SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE + Add Quadratic Pentahedron + + + SMESH_ADD_QUADRATIC_PYRAMID_TITLE + Add Quadratic Pyramid + + + SMESH_ADD_BIQUADRATIC_QUADRANGLE_TITLE + Add BiQuadratic Quadrangle + + + SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE + Add Quadratic Quadrangle + + + SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE + Add Quadratic Tetrahedron + + + SMESH_ADD_QUADRATIC_TRIANGLE_TITLE + Add Quadratic Triangle + + + SMESH_ADD_SUBMESH + SubMesh Construction + + + SMESH_ADD_TETRAS + Add Tetrahedron + + + SMESH_ADD_TETRAS_TITLE + Add Tetrahedron + + + SMESH_ADD_TO_GROUP + Add to group + + + SMESH_ADD_TRIANGLE + Add Triangle + + + SMESH_ADD_TRIANGLE_TITLE + Add Triangle + + + SMESH_ANGLE + Angle + + + SMESH_ARGUMENTS + Arguments + + + SMESH_AUTO_GROUPS + Automatically create groups + + + SMESH_AVAILABLE + Available + + + SMESH_AVAILABLE_ALGORITHMS + Available algorithms + + + SMESH_AVAILABLE_HYPOTHESES + Available hypotheses + + + SMESH_AXIS + Axis + + + SMESH_BAD_SELECTION + No valid selection + + + SMESH_BAD_MESH_SELECTION + No valid mesh selection + + + SMESH_BOUNDARYEDGES + Boundary Edges + + + SMESH_BUILD_COMPOUND_TITLE + Create a Compound + + + SMESH_COPY_MESH_TITLE + Copy Mesh + + + SMESH_KEEP_IDS + Preserve IDs of elements + + + SMESH_BUT_ADD + A&dd + + + SMESH_BUT_APPLY + &Apply + + + SMESH_BUT_CANCEL + &Cancel + + + SMESH_BUT_CLOSE + &Close + + + SMESH_BUT_CREATE + Create + + + SMESH_BUT_DELETE + Delete + + + SMESH_BUT_FILTER + Set &Filter + + + SMESH_BUT_HELP + &Help + + + SMESH_BUT_NEW + New + + + SMESH_BUT_NO + &No + + + SMESH_BUT_OK + &Ok + + + SMESH_BUT_OVERWRITE + Over&write + + + SMESH_BUT_APPLY_AND_CLOSE + A&pply and Close + + + SMESH_BUT_REMOVE + &Remove + + + SMESH_BUT_SORT + &Sort List + + + SMESH_BUT_YES + &Yes + + + SMESH_CANT_ADD_HYP + Can not assign "%1": - - - SMESH_ADD_POLYGON - Add polygon - - - SMESH_ADD_POLYGON_TITLE - Add polygon - - - SMESH_ADD_QUADRANGLE - Add Quadrangle - - - SMESH_ADD_QUADRANGLE_TITLE - Add Quadrangle - - - SMESH_ADD_QUADRATIC_EDGE_TITLE - Add Quadratic Edge - - - SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE - Add Quadratic Hexahedron - - - SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE - Add Quadratic Pentahedron - - - SMESH_ADD_QUADRATIC_PYRAMID_TITLE - Add Quadratic Pyramid - - - SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE - Add Quadratic Quadrangle - - - SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE - Add Quadratic Tetrahedron - - - SMESH_ADD_QUADRATIC_TRIANGLE_TITLE - Add Quadratic Triangle - - - SMESH_ADD_SUBMESH - SubMesh Construction - - - SMESH_ADD_TETRAS - Add Tetrahedron - - - SMESH_ADD_TETRAS_TITLE - Add Tetrahedron - - - SMESH_ADD_TRIANGLE - Add Triangle - - - SMESH_ADD_TRIANGLE_TITLE - Add Triangle - - - SMESH_ANGLE - Angle - - - SMESH_ARGUMENTS - Arguments - - - SMESH_AUTO_GROUPS - Automatically create groups - - - SMESH_AVAILABLE - Available - - - SMESH_AVAILABLE_ALGORITHMS - Available algorithms - - - SMESH_AVAILABLE_HYPOTHESES - Available hypotheses - - - SMESH_AXIS - Axis - - - SMESH_BAD_SELECTION - No valid selection - - - SMESH_BAD_MESH_SELECTION - No valid mesh selection - - - SMESH_BOUNDARYEDGES - Boundary Edges - - - SMESH_BUILD_COMPOUND_TITLE - Create a Compound - - - SMESH_BUT_ADD - A&dd - - - SMESH_BUT_APPLY - &Apply - - - SMESH_BUT_CANCEL - &Cancel - - - SMESH_BUT_CLOSE - &Close - - - SMESH_BUT_CREATE - Create - - - SMESH_BUT_DELETE - Delete - - - SMESH_BUT_FILTER - Set &Filters - - - SMESH_BUT_HELP - &Help - - - SMESH_BUT_NEW - New - - - SMESH_BUT_NO - &No - - - SMESH_BUT_OK - &Ok - - - SMESH_BUT_APPLY_AND_CLOSE - A&pply and Close - - - SMESH_BUT_REMOVE - &Remove - - - SMESH_BUT_SORT - &Sort List - - - SMESH_BUT_YES - &Yes - - - SMESH_CANT_ADD_HYP - Can not assign "%1": + + + SMESH_CANT_RM_HYP + Can not unassign "%1": + + + + SMESH_CHECK_COLOR + Color + + + SMESH_CLIPPING_FROM + From <--- + + + SMESH_CLIPPING_INTO + ---> Into + + + SMESH_CLIPPING_TITLE + Change Clipping + + + SMESH_COMPUTE_SUCCEED + Mesh computation succeed + + + SMESH_EVALUATE_SUCCEED + Mesh evaluation succeed + + + SMESH_CONTENT + Content + + + SMESH_CONTINUE_MESH_VISUALIZATION + It seems that there is not enough memory to show the mesh +so that the application may crash. Do you wish to continue visualization? + + + SMESH_COORDINATES + Coordinates + + + SMESH_COPY_ELEMENTS + Copy Elements + + + SMESH_COPY_GROUPS + Copy groups + + + SMESH_CREATE_ALGORITHMS + Create algorithms + + + SMESH_CREATE_COPY + Create a copy + + + SMESH_CREATE_GROUP_TITLE + Create Group + + + SMESH_CREATE_GEO_GROUP + Create Groups from Geometry + + + SMESH_CREATE_HYPOTHESES + Create hypotheses + + + SMESH_CREATE_MESH + Create a new mesh + + + SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE + Create polyhedral volume + + + SMESH_DIAGONAL + Diagonal Inversion + + + SMESH_DIAGONAL_INVERSION_TITLE + Diagonal Inversion + + + SMESH_DISTANCE + Distance + + + SMESH_DRS_1 + MED file contains no mesh with the given name + + + SMESH_DRS_2 + MED file has overlapped ranges of element numbers, the numbers from the file are ignored + + + SMESH_DRS_3 + Some elements were skipped due to incorrect file data + + + SMESH_DRS_4 + The file is incorrect, some data is missed + + + SMESH_DRS_EMPTY + The file is empty, there is nothing to be published + + + SMESH_DX + dX + + + SMESH_DY + dY + + + SMESH_DZ + dZ + + + SMESH_ELEM0D + 0D Element + + + SMESH_ELEMS0D + 0D Elements + + + SMESH_BALL_ELEM + Ball + + + SMESH_BALL + Ball + + + SMESH_BALLS + Balls + + + SMESH_EDGE + Edge + + + SMESH_EDGES + Edges + + + SMESH_EDGES_CONNECTIVITY_TITLE + Edges Connectivity + + + SMESH_EDIT_GROUP_TITLE + Edit Group + + + SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE + Edit Group as Standalone + + + SMESH_EDIT_HYPOTHESES + Hypotheses Assignation + + + SMESH_EDIT_USED + Used + + + SMESH_ELEMENTS + Elements + + + SMESH_ELEMENTS_COLOR + Mesh Element Color + + + SMESH_ELEMENTS_TYPE + Elements Type + + + SMESH_ELEMENT_TYPE + Element Type + + + SMESH_ERROR + Error + + + SMESH_ERR_SCALARBAR_PARAMS + Warning! The parameters is incorrect + + + SMESH_EXPORT_FAILED + Mesh export failed. +Probably, there is not enough space on disk. + + + SMESH_EXPORT_MED_DUPLICATED_GRP + There are duplicated group names in mesh "%1". +You can cancel exporting and rename them, +otherwise some group names in the resulting file +will not match ones in the study. +Do you want to continue ? + + + SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES + There are some mesh objects with the same names in the selection. +The result file may be incorrect. +Do you want to continue ? + + + SMESH_EXPORT_MED_V2_1 + During export mesh with name - "%1" to MED 2.1 +polygons and polyhedrons elements will be missed +For correct export use MED 2.2 +Are you sure want to export to MED 2.1 ? + + + SMESH_EXPORT_MED_VERSION_COLLISION + MED version of the file "%1" +is unknown or doesn't match the selected version. +Overwrite the file? + + + SMESH_EXPORT_MED_MESH_NAMES_COLLISION + The selected file already contains +meshes with the following names: %1 +The result file may be incorrect. +Overwrite the file? + + + EXPORT_NOT_SUPPORTED + During export mesh with name "%1" to %2 +%3 will be missed. +Do you want to continue ? + + + SMESH_EXTRUSION + Extrusion + + + SMESH_EXTRUSION_TO_DISTANCE + Extrusion To Distance + + + SMESH_EXTRUSION_ALONG_VECTOR + Extrusion Along Vector + + + SMESH_FACE + Face + + + SMESH_FEATUREANGLE + Feature Angle + + + SMESH_FEATUREEDGES + Feature Edges + + + SMESH_FILE_EXISTS + The file "%1" already exists. +Do you want to overwrite it or +add the exported data to its contents? + + + SMESH_FONT_ARIAL + Arial + + + SMESH_FONT_BOLD + Bold + + + SMESH_FONT_COURIER + Courier + + + SMESH_FONT_ITALIC + Italic + + + SMESH_FONT_SCALARBAR + Font + + + SMESH_FONT_SHADOW + Shadow + + + SMESH_FONT_TIMES + Times + + + SMESH_GEOM_GROUP + Geometry group + + + SMESH_GROUP + Group + + + SMESH_GROUP_GEOMETRY + Group on geometry + + + SMESH_GROUP_FILTER + Group on filter + + + SMESH_GROUP_SELECTED + %1 Groups + + + SMESH_GROUP_STANDALONE + Standalone group + + + SMESH_GROUP_TYPE + Group type + + + SMESH_HEIGHT + Height: + + + SMESH_HEXAS + Hexahedron + + + SMESH_HEXAHEDRA + Hexahedrons + + + SMESH_HILIGHT_COLOR + Highlight Color + + + SMESH_HORIZONTAL + Horizontal + + + SMESH_HYPOTHESES + Hypotheses + + + SMESH_HYP_1 + Algorithm misses a hypothesis + + + SMESH_HYP_10 + Hypothesis and submesh dimensions mismatch + + + SMESH_HYP_11 + Shape is neither the main one, nor its sub-shape, nor a valid group + + + SMESH_HYP_12 + Geometry mismatches algorithm's expectation +Check algorithm documentation for supported geometry + + + SMESH_HYP_13 + Algorithm can't work without shape + + + SMESH_HYP_2 + There are concurrent hypotheses on a shape + + + SMESH_HYP_3 + Hypothesis has a bad parameter value + + + SMESH_HYP_4 + Submesh is ignored as there is another algorithm of upper dimension generating %1D elements + + + SMESH_HYP_5 + Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements + + + SMESH_HYP_6 + Unknown fatal error at hypothesis definition + + + SMESH_HYP_7 + Hypothesis is not suitable in the current context + + + SMESH_HYP_8 + Non-conform mesh is produced using applied hypotheses + + + SMESH_HYP_9 + Such dimention hypothesis is already assigned to the shape + + + SMESH_ID_DIAGONAL + Id Edges + + + SMESH_ID_ELEMENTS + Id Elements + + + SMESH_ID_FACES + Id Faces + + + SMESH_ID_NODES + Id Nodes + + + SMESH_INCORRECT_INPUT + Incorrect input data! + + + SMESH_INFORMATION + Information + + + SMESH_INIT + Mesh + + + SMESH_INIT_MESH + Mesh Construction + + + SMESH_INSUFFICIENT_DATA + Insufficient input value + + + SMESH_LABELS + Labels: + + + SMESH_LABELS_COLORS_SCALARBAR + Colors && Labels + + + SMESH_LENGTH + Length + + + SMESH_MAKE_GROUPS + Generate groups + + + SMESH_MANIFOLDEDGES + Manifold Edges + + + SMESH_MAX + Max + + + SMESH_MEN_ALGORITHMS + Algorithms + + + SMESH_MEN_APPLIED_ALGORIHTMS + Applied Algorithms + + + SMESH_MEN_APPLIED_HYPOTHESIS + Applied Hypotheses + + + SMESH_MEN_COMPONENT + SMESH + + + SMESH_MEN_HYPOTHESIS + Hypotheses + + + SMESH_MEN_SubMeshesOnCompound + SubMeshes On Compound + + + SMESH_MEN_SubMeshesOnEdge + SubMeshes On Edge + + + SMESH_MEN_SubMeshesOnFace + SubMeshes On Face + + + SMESH_MEN_SubMeshesOnSolid + SubMeshes On Solid + + + SMESH_MEN_SubMeshesOnVertex + SubMeshes On Vertex + + + SMESH_AUTOMATIC + Automatic + + + SMESH_MANUAL + Manual + + + SMESH_MERGE_ELEMENTS + Merge elements + + + SMESH_MODE + Mode + + + SMESH_MERGED_ELEMENTS + %1 elements successfully merged. + + + SMESH_MERGED_NODES + %1 nodes successfully merged. + + + SMESH_NO_ELEMENTS_DETECTED + There are no elements to merge. + + + SMESH_NO_NODES_DETECTED + There are no nodes to merge. + + + SMESH_MERGE_NODES + Merge nodes + + + SMESH_MESH + Mesh + + + SMESH_MESHINFO_0DELEMS + 0D Elements + + + SMESH_MESHINFO_BALLS + Balls + + + SMESH_MESHINFO_ALL_TYPES + Heterogenous + + + SMESH_MESHINFO_EDGES + Edges + + + SMESH_MESHINFO_ELEMENTS + Elements + + + SMESH_MESHINFO_ENTITIES + Entities + + + SMESH_MESHINFO_FACES + Faces + + + SMESH_MESHINFO_HEXAS + Hexahedrons + + + SMESH_MESHINFO_NAME + Name + + + SMESH_MESHINFO_NODES + Nodes + + + SMESH_MESHINFO_ORDER0 + Total + + + SMESH_MESHINFO_ORDER1 + Linear + + + SMESH_MESHINFO_ORDER2 + Quadratic + + + SMESH_MESHINFO_HEXAPRISM + Hexagonal prisms + + + SMESH_MESHINFO_POLYEDRES + Polyhedrons + + + SMESH_MESHINFO_POLYGONES + Polygons + + + SMESH_MESHINFO_PRISMS + Prisms + + + SMESH_MESHINFO_PYRAS + Pyramids + + + SMESH_MESHINFO_QUADRANGLES + Quadrangles + + + SMESH_MESHINFO_TETRAS + Tetrahedrons + + + SMESH_MESHINFO_TITLE + Mesh Infos + + + SMESH_MESHINFO_TOTAL + Total + + + SMESH_MESHINFO_TRIANGLES + Triangles + + + SMESH_MESHINFO_TYPE + Type + + + SMESH_MESHINFO_VOLUMES + Volumes + + + SMESH_MIN + Min + + + SMESH_MOVE + Move + + + SMESH_MOVE_ELEMENTS + Move Elements + + + SMESH_MOVE_NODES_TITLE + Move Node + + + SMESH_NAME + Name + + + SMESH_NODES + Nodes + + + SMESH_NONMANIFOLDEDGES + Non Manifold Edges + + + SMESH_NORMAL + Normal + + + SMESH_NO_MESH_VISUALIZATION + There is not enough memory to show the mesh + + + SMESH_NUMBEROFCOLORS + Nb of colors: + + + SMESH_NUMBEROFLABELS + Nb of labels: + + + SMESH_NUMBEROFSTEPS + Number of steps: + + + SMESH_OBJECTS_SELECTED + %1_objects + + + SMESH_OBJECT_ALGORITHM + Algorithm + + + SMESH_OBJECT_GEOM + Geometrical Object + + + SMESH_OBJECT_HYPOTHESIS + Hypothesis + + + SMESH_OBJECT_MESH + Mesh + + + SMESH_OBJECT_MESHorSUBMESH + Mesh or SubMesh + + + SMESH_OPERATION_FAILED + Operation failed + + + SMESH_OCTA + Octogonal prism + + + SMESH_OCTAHEDRA + Octogonal prisms + + + TOP_OCTA + Hexagonal prism + + + MEN_OCTA + Hexagonal prism + + + STB_OCTA + Hexagonal prism + + + SMESH_ORIENTATION + Orientation + + + SMESH_ORIENTATION_ELEMENTS_TITLE + Change Orientation + + + SMESH_OUTLINE_COLOR + Mesh Object Color + + + SMESH_PARAMETERS + Parameters + + + SMESH_PENTA + Pentahedron + + + SMESH_PENTAHEDRA + Pentahedrons + + + TOP_PENTA + Pentahedron + + + MEN_PENTA + Pentahedron + + + STB_PENTA + Pentahedron + + + SMESH_PLANE + Plane + + + SMESH_POINT + Point + + + SMESH_POINT_1 + Point 1 + + + SMESH_POINT_2 + Point 2 + + + SMESH_BASE_POINT + Base Point + + + SMESH_POLYEDRE_CREATE_ERROR + Polyedron creation error + + + SMESH_POLYEDRON + Polyhedron + + + SMESH_POLYEDRONS + Polyhedrons + + + SMESH_QUADRATIC_POLYEDRON + Quadratic Polyhedron + + + SMESH_QUADRATIC_POLYEDRONS + Quadratic Polyhedrons + + + SMESH_POLYGON + Polygon + + + SMESH_POLYGONS + Polygons + + + SMESH_QUADRATIC_POLYGON + Quadratic Polygon + + + SMESH_QUADRATIC_POLYGONS + Quadratic Polygons + + + SMESH_POSITION_SIZE_SCALARBAR + Origin && Size + + + SMESH_DISTRIBUTION_SCALARBAR + Distribution + + + SMESH_SHOW_DISTRIBUTION_SCALARBAR + Show Distribution + + + SMESH_PRECISION + Precision + + + SMESH_PREFERENCES_SCALARBAR + Scalar Bar Preferences + + + SMESH_PREF_SELECTION + Preferences - Selection + + + SMESH_PRESELECTION + Preselection + + + SMESH_PRISM + Prism + + + SMESH_PROPERTIES_SCALARBAR + Scalar Bar Properties + + + SMESH_PYRAMID + Pyramid + + + SMESH_PYRAMIDS + Pyramids + + + MEN_PYRAMID + Pyramid + + + TOP_PYRAMID + Pyramid + + + STB_PYRAMID + Pyramid + + + SMESH_QUADRANGLE + Quadrangle + + + SMESH_QUADRANGLES + Quadrangles + + + SMESH_QUADRATIC_EDGE + Quadratic Edge + + + SMESH_QUADRATIC_EDGES + Quadratic Edges + + + SMESH_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + SMESH_QUADRATIC_HEXAHEDRONS + Quadratic Hexahedrons + + + SMESH_TRIQUADRATIC_HEXAHEDRON + TriQuadratic Hexahedron + + + SMESH_TRIQUADRATIC_HEXAHEDRONS + TriQuadratic Hexahedrons + + + TOP_TRIQUADRATIC_HEXAHEDRON + TriQuadratic Hexahedron + + + MEN_TRIQUADRATIC_HEXAHEDRON + TriQuadratic Hexahedron + + + STB_TRIQUADRATIC_HEXAHEDRON + TriQuadratic Hexahedron + + + SMESH_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + SMESH_QUADRATIC_PENTAHEDRONS + Quadratic Pentahedrons + + + SMESH_QUADRATIC_PYRAMID + Quadratic Pyramid + + + SMESH_QUADRATIC_PYRAMIDS + Quadratic Pyramids + + + SMESH_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + SMESH_QUADRATIC_QUADRANGLES + Quadratic Quadrangles + + + SMESH_BIQUADRATIC_QUADRANGLE + BiQuadratic Quadrangle + + + SMESH_BIQUADRATIC_QUADRANGLES + BiQuadratic Quadrangles + + + MEN_BIQUADRATIC_QUADRANGLE + BiQuadratic Quadrangle + + + TOP_BIQUADRATIC_QUADRANGLE + BiQuadratic Quadrangle + + + STB_BIQUADRATIC_QUADRANGLE + BiQuadratic Quadrangle + + + SMESH_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + SMESH_QUADRATIC_TETRAHEDRONS + Quadratic Tetrahedrons + + + SMESH_QUADRATIC_TRIANGLE + Quadratic Triangle + + + SMESH_QUADRATIC_TRIANGLES + Quadratic Triangles + + + SMESH_RANGE_MAX + Max value: + + + SMESH_RANGE_MIN + Min value: + + + SMESH_RANGE_SCALARBAR + Scalar Range + + + SMESH_REALLY_DELETE + Do you really want to delete this %1 object(s)? : %2 + + + SMESH_REMOVE + Remove + + + SMESH_REMOVE_ELEMENTS_TITLE + Remove Elements + + + SMESH_REMOVE_NODES_TITLE + Remove Nodes + + + SMESH_RENUMBERING + Renumbering + + + SMESH_RENUMBERING_ELEMENTS_TITLE + Renumbering elements + + + SMESH_RENUMBERING_NODES_TITLE + Renumbering nodes + + + SMESH_REVERSE + Reverse + + + SMESH_REVOLUTION + Revolution + + + SMESH_RM_HYP_WRN + "%1" unassigned but: - - - SMESH_CANT_RM_HYP - Can not unassign "%1": + + + SMESH_ROTATION + Rotation + + + SMESH_ROTATION_TITLE + Rotation about an axis + + + SMESH_SCALARBAR + Scalar Bar + + + SMESH_SEGMENTS + Segments + + + SMESH_SELECTION + Selection + + + SMESH_SELECT_FROM + Select From + + + SMESH_SELECT_WHOLE_MESH + Select whole mesh, submesh or group + + + SMESH_SET_COLOR + Color group + + + SMESH_SEWING + Sewing + + + SMESH_SMOOTHING + Smoothing + + + SMESH_STANDARD_MESHINFO_TITLE + Standard Mesh Infos + + + SMESH_SUBMESH + SubMesh + + + SMESH_SUBMESH_SELECTED + %1 SubMeshes + + + SMESH_SYMMETRY + Symmetry + + + SMESH_TETRAS + Tetrahedron + + + SMESH_TETRAHEDRA + Tetrahedrons + + + SMESH_TITLE + Title: + + + SMESH_TOLERANCE + Tolerance + + + SMESH_TRANSLATION + Translation + + + SMESH_SCALE_TITLE + Scale Transform + + + SMESH_DUPLICATE_TITLE + Duplicate Nodes + + + SMESH_SCALE + Scale + + + SMESH_SCALE_FACTOR + Scale Factor : + + + SMESH_SCALE_FACTOR_X + Scale Factor X : + + + SMESH_SCALE_FACTOR_Y + Scale Factor Y : + + + SMESH_SCALE_FACTOR_Z + Scale Factor Z : + + + SMESH_TRANSPARENCY_OPAQUE + Opaque + + + SMESH_TRANSPARENCY_TITLE + Change Transparency + + + SMESH_TRANSPARENCY_TRANSPARENT + Transparent + + + SMESH_TRIANGLE + Triangle + + + SMESH_TRIANGLES + Triangles + + + SMESH_UPDATEVIEW + Update View + + + SMESH_VALUE + Value + + + SMESH_VECTOR + Vector + + + SMESH_VERTICAL + Vertical + + + SMESH_DISTRIBUTION_COLORING_TYPE + Coloring Type + + + SMESH_MONOCOLOR + Monocolor + + + SMESH_DISTRIBUTION_COLOR + Distribution color: + + + SMESH_MULTICOLOR + Multicolor + + + SMESH_VISU_PROBLEM + Mesh visualization failed, probably due to lack of memory + + + SMESH_VISU_PROBLEM_CLEAR + Mesh visualization failed, no memory even to show a message, +so all visual data have been removed to let the application live. +Consider saving your work before application crash + + + SMESH_VOLUME + Volume + + + SMESH_WARNING + Warning + + + SMESH_WHAT_IS_TITLE + Mesh Element Info + + + SMESH_WIDTH + Width: + + + SMESH_WRN_ALGORITHM_ALREADYEXIST + Algorithm already exists + + + SMESH_WRN_COMPUTE_FAILED + Mesh computation failed + + + SMESH_WRN_EVALUATE_FAILED + Mesh evaluation failed + + + SMESH_WRN_EMPTY_NAME + Empty name is not valid + + + SMESH_WRN_HYPOTHESIS_ALREADYEXIST + Hypothesis already exists + + + SMESH_WRN_HYPOTHESIS_NOTEXIST + Hypothesis or Algorithm not exists + + + SMESH_WRN_MISSING_PARAMETERS + Missing parameters + + + SMESH_WRN_NO_AVAILABLE_DATA + No available data in selection + + + SMESH_WRN_SELECTIONMODE_DIAGONAL + Activate Link Selection Mode + + + SMESH_WRN_SELECTIONMODE_ELEMENTS + Activate Elements Selection Mode + + + SMESH_WRN_SELECTIONMODE_NODES + Activate Nodes Selection Mode + + + SMESH_WRN_VIEWER_VTK + Study frame with VTK Viewer must be activated + + + SMESH_WRN_SIZE_LIMIT_EXCEEDED + No automatic update of the presentation has been done: new mesh size (%1 elements) exceeds current size limit (%2 elements). +Please check preferences of Mesh module. - - - SMESH_CHECK_COLOR - Color - - - SMESH_CLIPPING_FROM - From <--- - - - SMESH_CLIPPING_INTO - ---> Into - - - SMESH_CLIPPING_TITLE - Change Clipping - - - SMESH_COMPUTE_SUCCEED - Mesh computation succeed - - - SMESH_CONTENT - Content - - - SMESH_CONTINUE_MESH_VISUALIZATION - It seems that there is not enough memory to show the mesh -so that the application may crash. Do you wish to continue visualization? - - - SMESH_COORDINATES - Coordinates - - - SMESH_COPY_ELEMENTS - Copy Elements - - - SMESH_COPY_GROUPS - Copy groups - - - SMESH_CREATE_ALGORITHMS - Create algorithms - - - SMESH_CREATE_COPY - Create a copy - - - SMESH_CREATE_GROUP_TITLE - Create Group - - - SMESH_CREATE_GEO_GROUP - Create Groups from Geometry - - - SMESH_CREATE_HYPOTHESES - Create hypotheses - - - SMESH_CREATE_MESH - Create a new mesh - - - SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE - Create polyhedral volume - - - SMESH_DIAGONAL - Diagonal Inversion - - - SMESH_DIAGONAL_INVERSION_TITLE - Diagonal Inversion - - - SMESH_DISTANCE - Distance - - - SMESH_DRS_1 - MED file contains no mesh with the given name - - - SMESH_DRS_2 - MED file has overlapped ranges of element numbers, the numbers from the file are ignored - - - SMESH_DRS_3 - Some elements were skipped due to incorrect file data - - - SMESH_DRS_4 - The file is incorrect, some data is missed - - - SMESH_DRS_EMPTY - The file is empty, there is nothing to be published - - - SMESH_DX - dX - - - SMESH_DY - dY - - - SMESH_DZ - dZ - - - SMESH_EDGE - Edge - - - SMESH_EDGES_CONNECTIVITY_TITLE - Edges Connectivity - - - SMESH_EDIT_GROUP_TITLE - Edit Group - - - SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE - Edit Group as Standalone - - - SMESH_EDIT_HYPOTHESES - Hypotheses Assignation - - - SMESH_EDIT_USED - Used - - - SMESH_ELEMENTS - Elements - - - SMESH_ELEMENTS_COLOR - Mesh Element Color - - - SMESH_ELEMENTS_TYPE - Elements Type - - - SMESH_ELEMENT_TYPE - Element Type - - - SMESH_ERROR - Error - - - SMESH_ERR_SCALARBAR_PARAMS - Warning! The parameters is incorrect - - - SMESH_EXPORT_FAILED - Mesh export failed. -Probably, there is not enough space on disk. - - - SMESH_EXPORT_MED_DUPLICATED_GRP - There are duplicated group names in mesh "%1". -You can cancel exporting and rename them, -otherwise some group names in the resulting MED file -will not match ones in the study. -Do you want to continue ? - - - SMESH_EXPORT_MED_V2_1 - During export mesh with name - "%1" to MED 2.1 -polygons and polyhedrons elements will be missed -For correct export use MED 2.2 -Are you sure want to export to MED 2.1 ? - - - SMESH_EXPORT_STL1 - Mesh - "%1" does not contain triangles - - - SMESH_EXPORT_STL2 - Mesh - "%1" contains another than triangles elements, they are ignored during writing to STL - - - SMESH_EXPORT_UNV - During export mesh with name - "%1" to UNV - pyramid's elements will be missed - - - SMESH_EXTRUSION - Extrusion - - - SMESH_FACE - Face - - - SMESH_FEATUREANGLE - Feature Angle - - - SMESH_FEATUREEDGES - Feature Edges - - - SMESH_FONT_ARIAL - Arial - - - SMESH_FONT_BOLD - Bold - - - SMESH_FONT_COURIER - Courier - - - SMESH_FONT_ITALIC - Italic - - - SMESH_FONT_SCALARBAR - Font - - - SMESH_FONT_SHADOW - Shadow - - - SMESH_FONT_TIMES - Times - - - SMESH_GEOM_GROUP - Geometry group - - - SMESH_GROUP - Group - - - SMESH_GROUP_GEOMETRY - Group on geometry - - - SMESH_GROUP_SELECTED - %1 Groups - - - SMESH_GROUP_STANDALONE - Standalone group - - - SMESH_GROUP_TYPE - Group type - - - SMESH_HEIGHT - Height: - - - SMESH_HEXAS - Hexahedron - - - SMESH_HILIGHT_COLOR - Highlight Color - - - SMESH_HORIZONTAL - Horizontal - - - SMESH_HYPOTHESES - Hypotheses - - - SMESH_HYP_1 - Algorithm misses a hypothesis - - - SMESH_HYP_10 - Hypothesis and submesh dimensions mismatch - - - SMESH_HYP_11 - Shape is neither the main one, nor its subshape, nor a valid group - - - SMESH_HYP_12 - Geomerty mismatches algorithm's expectation - - - SMESH_HYP_13 - Algorithm can't work without shape - - - SMESH_HYP_2 - There are concurrent hypotheses on a shape - - - SMESH_HYP_3 - Hypothesis has a bad parameter value - - - SMESH_HYP_4 - Submesh is ignored as there is another algorithm of upper dimension generating %1D elements - - - SMESH_HYP_5 - Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements - - - SMESH_HYP_6 - Unknown fatal error at hypothesis definition - - - SMESH_HYP_7 - Hypothesis is not suitable in the current context - - - SMESH_HYP_8 - Non-conform mesh is produced using applied hypotheses - - - SMESH_HYP_9 - Such dimention hypothesis is already assigned to the shape - - - SMESH_ID_DIAGONAL - Id Edges - - - SMESH_ID_ELEMENTS - Id Elements - - - SMESH_ID_FACES - Id Faces - - - SMESH_ID_NODES - Id Nodes - - - SMESH_INCORRECT_INPUT - Incorrect input data! - - - SMESH_INFORMATION - Information - - - SMESH_INIT - Mesh - - - SMESH_INIT_MESH - Mesh Construction - - - SMESH_INSUFFICIENT_DATA - Insufficient input value - - - SMESH_LABELS - Labels: - - - SMESH_LABELS_COLORS_SCALARBAR - Colors && Labels - - - SMESH_LENGTH - Length - - - SMESH_MAKE_GROUPS - Generate groups - - - SMESH_MANIFOLDEDGES - Manifold Edges - - - SMESH_MAX - Max - - - SMESH_MEN_ALGORITHMS - Algorithms - - - SMESH_MEN_APPLIED_ALGORIHTMS - Applied Algorithms - - - SMESH_MEN_APPLIED_HYPOTHESIS - Applied Hypotheses - - - SMESH_MEN_COMPONENT - SMESH - - - SMESH_MEN_HYPOTHESIS - Hypotheses - - - SMESH_MEN_SubMeshesOnCompound - SubMeshes On Compound - - - SMESH_MEN_SubMeshesOnEdge - SubMeshes On Edge - - - SMESH_MEN_SubMeshesOnFace - SubMeshes On Face - - - SMESH_MEN_SubMeshesOnSolid - SubMeshes On Solid - - - SMESH_MEN_SubMeshesOnVertex - SubMeshes On Vertex - - - SMESH_MERGE_ELEMENTS - Merge elements - - - SMESH_MERGE_NODES - Merge nodes - - - SMESH_MESH - Mesh - - - SMESH_MESHINFO_ALL_TYPES - Heterogenous - - - SMESH_MESHINFO_EDGES - Edges - - - SMESH_MESHINFO_ELEMENTS - Elements - - - SMESH_MESHINFO_ENTITIES - Entities - - - SMESH_MESHINFO_FACES - Faces - - - SMESH_MESHINFO_HEXAS - Hexahedrons - - - SMESH_MESHINFO_NAME - Name - - - SMESH_MESHINFO_NODES - Nodes - - - SMESH_MESHINFO_ORDER0 - Total - - - SMESH_MESHINFO_ORDER1 - Linear - - - SMESH_MESHINFO_ORDER2 - Quadratic - - - SMESH_MESHINFO_POLYEDRES - Polyhedrons - - - SMESH_MESHINFO_POLYGONES - Polygons - - - SMESH_MESHINFO_PRISMS - Prisms - - - SMESH_MESHINFO_PYRAS - Pyramids - - - SMESH_MESHINFO_QUADRANGLES - Quadrangles - - - SMESH_MESHINFO_TETRAS - Tetrahedrons - - - SMESH_MESHINFO_TITLE - Mesh Infos - - - SMESH_MESHINFO_TOTAL - Total - - - SMESH_MESHINFO_TRIANGLES - Triangles - - - SMESH_MESHINFO_TYPE - Type - - - SMESH_MESHINFO_VOLUMES - Volumes - - - SMESH_MIN - Min - - - SMESH_MOVE - Move - - - SMESH_MOVE_ELEMENTS - Move Elements - - - SMESH_MOVE_NODES_TITLE - Move Node - - - SMESH_NAME - Name - - - SMESH_NODES - Nodes - - - SMESH_NONMANIFOLDEDGES - Non Manifold Edges - - - SMESH_NORMAL - Normal - - - SMESH_NO_MESH_VISUALIZATION - There is not enough memory to show the mesh - - - SMESH_NUMBEROFCOLORS - Nb of colors: - - - SMESH_NUMBEROFLABELS - Nb of labels: - - - SMESH_NUMBEROFSTEPS - Number of steps: - - - SMESH_OBJECTS_SELECTED - %1_objects - - - SMESH_OBJECT_ALGORITHM - Algorithm - - - SMESH_OBJECT_GEOM - Geometrical Object - - - SMESH_OBJECT_HYPOTHESIS - Hypothesis - - - SMESH_OBJECT_MESH - Mesh - - - SMESH_OBJECT_MESHorSUBMESH - Mesh or SubMesh - - - SMESH_OPERATION_FAILED - Operation failed - - - SMESH_ORIENTATION - Orientation - - - SMESH_ORIENTATION_ELEMENTS_TITLE - Change Orientation - - - SMESH_OUTLINE_COLOR - Mesh Object Color - - - SMESH_PARAMETERS - Parameters - - - SMESH_PLANE - Plane - - - SMESH_POINT - Point - - - SMESH_POINT_1 - Point 1 - - - SMESH_POINT_2 - Point 2 - - - SMESH_POLYEDRE_CREATE_ERROR - Polyedron creation error - - - SMESH_POLYEDRON - Polyhedron - - - SMESH_POLYGON - Polygon - - - SMESH_POSITION_SIZE_SCALARBAR - Origin && Size - - - SMESH_PRECISION - Precision - - - SMESH_PREFERENCES_SCALARBAR - Scalar Bar Preferences - - - SMESH_PREF_SELECTION - Preferences - Selection - - - SMESH_PRESELECTION - Preselection - - - SMESH_PRISM - Prism - - - SMESH_PROPERTIES_SCALARBAR - Scalar Bar Properties - - - SMESH_PYRAMID - Pyramid - - - SMESH_QUADRANGLE - Quadrangle - - - SMESH_QUADRATIC_EDGE - Quadratic Edge - - - SMESH_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - SMESH_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - SMESH_QUADRATIC_PYRAMID - Quadratic Pyramid - - - SMESH_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - SMESH_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - SMESH_QUADRATIC_TRIANGLE - Quadratic Triangle - - - SMESH_RANGE_MAX - Max value: - - - SMESH_RANGE_MIN - Min value: - - - SMESH_RANGE_SCALARBAR - Scalar Range - - - SMESH_REALLY_DELETE - Do you really want to delete this %1 object(s)? : %2 - - - SMESH_REMOVE - Remove - - - SMESH_REMOVE_ELEMENTS_TITLE - Remove Elements - - - SMESH_REMOVE_NODES_TITLE - Remove Nodes - - - SMESH_RENUMBERING - Renumbering - - - SMESH_RENUMBERING_ELEMENTS_TITLE - Renumbering elements - - - SMESH_RENUMBERING_NODES_TITLE - Renumbering nodes - - - SMESH_REVERSE - Reverse - - - SMESH_REVOLUTION - Revolution - - - SMESH_RM_HYP_WRN - "%1" unassigned but: + + + SMESH_WRN_WARNING + Warning + + + SMESH_X + X + + + SMESH_X_SCALARBAR + X: + + + SMESH_Y + Y + + + SMESH_Y_SCALARBAR + Y: + + + SMESH_Z + Z + + + STATE_ALGO_MISSING + %3 %2D algorithm is missing + + + STATE_HYP_BAD_GEOMETRY + %3 %2D algorithm "%1" is assigned to geometry mismatching its expectation + + + STATE_HYP_BAD_PARAMETER + Hypothesis of %3 %2D algorithm "%1" has a bad parameter value + + + STATE_HYP_MISSING + %3 %2D algorithm "%1" misses %4D hypothesis + + + STATE_HYP_NOTCONFORM + %3 %2D algorithm "%1" would produce not conform mesh: global "Not Conform Mesh Allowed" hypotesis is missing + + + STB_ADV_INFO + Show base information about the mesh object + + + STB_ALL + All + + + STB_AREA + Area + + + STB_ASPECT + Aspect Ratio + + + STB_ASPECT_3D + Aspect Ratio 3D + + + STB_AUTO_COLOR + Auto color + + + STB_AUTO_UPD + Automatic update + + + STB_BUILD_COMPOUND + Build Compound Mesh + + + STB_COPY_MESH + Copy Mesh + + + STB_CLIP + Clipping + + + STB_COLORS + Properties + + + STB_COMPUTE + Compute + + + STB_PRECOMPUTE + Preview + + + STB_EVALUATE + Evaluate + + + STB_CONNECTION + Borders at Multi-Connection + + + STB_CONNECTION_2D + Borders at Multi-Connection 2D + + + STB_CONSTRUCT_GROUP + Construct Group + + + STB_CONV_TO_QUAD + Convert to/from quadratic + + + STB_2D_FROM_3D + Create boundary elements + + + STB_MESH_ORDER + Change submesh priority + + + STB_CREATE_GROUP + Create Group + + + STB_CREATE_GEO_GROUP + Create Group from Geometry + + + STB_CREATE_MESH + Create Mesh + + + STB_CREATE_SUBMESH + Create Sub-mesh + + + STB_CUT + Cutting of quadrangles + + + STB_CUT_GROUP + Cut Groups + + + STB_DAT + Export DAT file + + + STB_IMPORT_DAT + Import DAT file + + + STB_DELETE + Delete + + + STB_DEL_GROUP + Delete Groups with Contents + + + STB_FACE_ORIENTATION + Orientation of faces + + + STB_DISABLE_AUTO_COLOR + Disable auto color + + + STB_DISPLAY_ONLY + Show only + + + STB_DISP_ENT + Display entity + + + STB_ELEM0D + 0D Element + + + STB_ELEMS0D + 0D Elements + + + STB_BALLS + Ball Elements + + + STB_BALL + Ball Element + + + STB_EDGE + Edge + + + STB_EDGES + Edges + + + STB_EDIT_GROUP + Edit Group + + + STB_EDIT_GEOMGROUP_AS_GROUP + Edit Group as Standalone + + + STB_EDIT_HYPO + Edit Hypothesis + + + STB_EDIT_MESHSUBMESH + Edit Mesh/Sub-mesh + + + STB_EXPORT_DAT + Export to DAT file + + + STB_EXPORT_MED + Export to MED file + + + STB_EXPORT_CGNS + Export to CGNS file + + + STB_EXPORT_SAUV + Export to SAUV file + + + STB_EXPORT_STL + Export to STL file + + + STB_EXPORT_UNV + Export to UNV file + + + STB_EXTRUSION + Extrusion + + + STB_EXTRUSION_ALONG + Extrusion along a path + + + STB_FACES + Faces + + + STB_BARE_BORDER_VOLUME + Volumes with bare border + + + STB_BARE_BORDER_FACE + Faces with bare border + + + STB_OVER_CONSTRAINED_VOLUME + Over-constrained volumes + + + STB_OVER_CONSTRAINED_FACE + Over-constrained faces + + + STB_FREE_BORDER + Free Borders + + + STB_FREE_EDGE + Free Edges + + + STB_FREE_NODE + Free Nodes + + + STB_FREE_FACES + Free Faces + + + STB_GLOBAL_HYPO + Global Hypothesis + + + STB_HEXA + Hexahedron + + + STB_HIDE + Hide + + + STB_INT_GROUP + Intersect Groups + + + STB_INV + Diagonal Inversion + + + STB_LENGTH + Length + + + STB_LENGTH_2D + Length 2D + + + STB_MAP + Pattern mapping + + + STB_MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + STB_MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + STB_IMPORT_MED + Import MED file + + + STB_MED + Export MED file + + + STB_IMPORT_STL + Import STL file + + + STB_STL + Export STL file + + + STB_IMPORT_CGNS + Import CGNS file + + + STB_CGNS + Export CGNS file + + + STB_IMPORT_SAUV + Import SAUV file + + + STB_SAUV + Export SAUV file + + + STB_MERGE + Merge nodes + + + STB_MERGE_ELEMENTS + Merge elements + + + STB_MESH_THROU_POINT + Move Node + + + STB_MIN_ANG + Minimum Angle + + + STB_MOVE + Move Node + + + STB_NODE + Node + + + STB_NODES + Nodes + + + STB_NUM_ELEMENTS + Display Elements + + + STB_NUM_NODES + Display Nodes + + + STB_ORIENT + Orientation + + + STB_POLYGON + Polygon + + + STB_POLYHEDRON + Polyhedron + + + STB_PRECISION + Precision + + + STB_QUAD + Quadrangle + + + STB_QUADRATIC_EDGE + Quadratic Edge + + + STB_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + STB_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + STB_QUADRATIC_PYRAMID + Quadratic Pyramid + + + STB_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + STB_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + STB_QUADRATIC_TRIANGLE + Quadratic Triangle + + + STB_REMOVE_ELEMENTS + Remove elements + + + STB_REMOVE_NODES + Remove nodes + + + STB_REMOVE_ORPHAN_NODES + Remove orphan nodes + + + STB_RENAME + Rename + + + STB_RENUM_ELEMENTS + Renumbering elements + + + STB_RENUM_NODES + Renumbering nodes + + + STB_RESET + Reset + + + STB_SAVE_DISTRIBUTION + Save distribution to the file + + + STB_SHOW_DISTRIBUTION + Show Distribution + + + STB_REVOLUTION + Revolution + + + STB_ROT + Rotation + + + STB_SCALAR_BAR + Scalar bar + + + STB_SCALAR_BAR_PROP + Scalar bar Properties + + + STB_SELECTION + Selection + + + STB_SEL_FILTER_LIB + Selection filters library + + + STB_SEW + Sewing + + + STB_SHADE + Shading + + + STB_SHOW + Show + + + STB_SHRINK + Shrink + + + STB_SKEW + Skew + + + STB_SMOOTH + Smoothing + + + STB_STD_INFO + Standard Mesh Infos + + + STB_SYM + Symmetry + + + STB_TAPER + Taper + + + STB_TETRA + Tetrahedron + + + STB_TRANS + Translation + + + STB_SCALE + Scale Transform + + + STB_DUPLICATE_NODES + Duplicate Nodes + + + STB_TRANSP + Transparency + + + STB_TRIANGLE + Triangle + + + STB_UNASSIGN + Unassign + + + STB_UNION + Union of triangles + + + STB_UNION2 + Union of two triangles + + + STB_IMPORT_UNV + Import UNV file + + + STB_UNV + Export UNV file + + + STB_UN_GROUP + Union Groups + + + STB_UNDERLYING_ELEMS + Create groups of entities from existing groups of superior dimensions + + + STB_UPDATE + Update + + + STB_VOLUMES + Volumes + + + STB_VOLUME_3D + Volume + + + STB_WARP + Warping angle + + + STB_WHAT_IS + Show information about the mesh node or element + + + STB_WIRE + Wireframe + + + TAPER_ELEMENTS + Taper + + + TB_ADD_REMOVE + Add/Remove Toolbar + + + TB_CTRL + Controls Toolbar + + + TB_DISP_MODE + Display Mode Toolbar + + + TB_HYPO + Hypotheses Toolbar + + + TB_MESH + Mesh Toolbar + + + TB_MODIFY + Modification Toolbar + + + TOP_ADV_INFO + Mesh Information + + + TOP_ALL + All + + + TOP_AREA + Area + + + TOP_ASPECT + Aspect Ratio + + + TOP_ASPECT_3D + Aspect Ratio 3D + + + TOP_AUTO_COLOR + Auto color + + + TOP_AUTO_UPD + Automatic update + + + TOP_BUILD_COMPOUND + Build Compound Mesh + + + TOP_COPY_MESH + Copy Mesh + + + TOP_CLIP + Clipping + + + TOP_COLORS + Properties + + + TOP_COMPUTE + Compute + + + TOP_PRECOMPUTE + Preview + + + TOP_EVALUATE + Evaluate + + + TOP_CONNECTION + Borders at Multi-Connection + + + TOP_CONNECTION_2D + Borders at Multi-Connection 2D + + + TOP_CONSTRUCT_GROUP + Construct Group + + + TOP_CONV_TO_QUAD + Convert to/from quadratic + + + TOP_2D_FROM_3D + Create boundary elements + + + TOP_MESH_ORDER + Change submesh priority + + + TOP_CREATE_GROUP + Create Group + + + TOP_CREATE_GEO_GROUP + Create Groups from Geometry + + + TOP_CREATE_MESH + Create Mesh + + + TOP_CREATE_SUBMESH + Create Sub-mesh + + + TOP_CUT + Cutting of quadrangles + + + TOP_CUT_GROUP + Cut Groups + + + TOP_IMPORT_DAT + Import DAT file + + + TOP_DAT + Export DAT file + + + TOP_DELETE + Delete + + + TOP_DEL_GROUP + Delete Groups with Contents + + + TOP_FACE_ORIENTATION + Orientation of faces + + + TOP_DISABLE_AUTO_COLOR + Disable auto color + + + TOP_DISPLAY_ONLY + Show only + + + TOP_DISP_ENT + Display entity + + + TOP_ELEM0D + 0D Element + + + TOP_ELEMS0D + 0D Elements + + + TOP_BALL + Ball + + + TOP_BALLS + Balls + + + TOP_EDGE + Edge + + + TOP_EDGES + Edges + + + TOP_EDIT_GROUP + Edit Group + + + TOP_EDIT_GEOMGROUP_AS_GROUP + Edit Group as Standalone + + + TOP_EDIT_HYPO + Edit Hypothesis + + + TOP_EDIT_MESHSUBMESH + Edit Mesh/Sub-mesh + + + TOP_EXPORT_DAT + Export to DAT file + + + TOP_EXPORT_MED + Export to MED file + + + TOP_EXPORT_SAUV + Export to SAUV file + + + TOP_EXPORT_STL + Export to STL file + + + TOP_EXPORT_UNV + Export to UNV file + + + TOP_EXTRUSION + Extrusion + + + TOP_EXTRUSION_ALONG + Extrusion along a path + + + TOP_FACES + Faces + + + TOP_BARE_BORDER_VOLUME + Volumes with bare border + + + TOP_BARE_BORDER_FACE + Faces with bare border + + + TOP_OVER_CONSTRAINED_VOLUME + Over-constrained volumes + + + TOP_OVER_CONSTRAINED_FACE + Over-constrained faces + + + TOP_FREE_BORDER + Free Borders + + + TOP_FREE_EDGE + Free Edges + + + TOP_FREE_NODE + Free Nodes + + + TOP_FREE_FACES + Free Faces + + + TOP_GLOBAL_HYPO + Global Hypothesis + + + TOP_HEXA + Hexahedron + + + TOP_HIDE + Hide + + + TOP_INT_GROUP + Intersect Groups + + + TOP_INV + Diagonal Inversion + + + TOP_LENGTH + Length + + + TOP_LENGTH_2D + Length 2D + + + TOP_MAP + Pattern mapping + + + TOP_MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + TOP_MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + TOP_IMPORT_MED + Import MED file + + + TOP_MED + Export MED file + + + TOP_IMPORT_STL + Import STL file + + + TOP_STL + Export STL file + + + TOP_IMPORT_CGNS + Import CGNS file + + + TOP_CGNS + Export CGNS file + + + TOP_IMPORT_SAUV + Import SAUV file + + + TOP_SAUV + Export SAUV file + + + TOP_MERGE + Merge nodes + + + TOP_MERGE_ELEMENTS + Merge elements + + + TOP_MESH_THROU_POINT + Move Node + + + TOP_MIN_ANG + Minimum Angle + + + TOP_MOVE + Move Node + + + TOP_NODE + Node + + + TOP_NODES + Nodes + + + TOP_NUM_ELEMENTS + Display Elements + + + TOP_NUM_NODES + Display Nodes + + + TOP_ORIENT + Orientation + + + TOP_POLYGON + Polygon + + + TOP_POLYHEDRON + Polyhedron + + + TOP_PRECISION + Precision + + + TOP_QUAD + Quadrangle + + + TOP_QUADRATIC_EDGE + Quadratic Edge + + + TOP_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + TOP_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + TOP_QUADRATIC_PYRAMID + Quadratic Pyramid + + + TOP_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + TOP_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + TOP_QUADRATIC_TRIANGLE + Quadratic Triangle + + + TOP_REMOVE_ELEMENTS + Remove elements + + + TOP_REMOVE_NODES + Remove nodes + + + TOP_REMOVE_ORPHAN_NODES + Remove orphan nodes + + + TOP_RENAME + Rename + + + TOP_RENUM_ELEMENTS + Renumbering elements + + + TOP_RENUM_NODES + Renumbering nodes + + + TOP_RESET + Reset + + + TOP_SAVE_DISTRIBUTION + Export distribution + + + TOP_SHOW_DISTRIBUTION + Show Distribution + + + TOP_REVOLUTION + Revolution + + + TOP_ROT + Rotation + + + TOP_SCALAR_BAR + Scalar bar + + + TOP_SCALAR_BAR_PROP + Scalar bar Properties + + + TOP_SELECTION + Selection + + + TOP_SEL_FILTER_LIB + Selection filters library + + + TOP_SEW + Sewing + + + TOP_SHADE + Shading + + + TOP_SHOW + Show + + + TOP_SHRINK + Shrink + + + TOP_SKEW + Skew + + + TOP_SMOOTH + Smoothing + + + TOP_STD_INFO + Standard Mesh Infos + + + TOP_SYM + Symmetry + + + TOP_TAPER + Taper + + + TOP_TETRA + Tetrahedron + + + TOP_TRANS + Translation + + + TOP_SCALE + Scale Transform + + + TOP_DUPLICATE_NODES + Duplicate Nodes + + + TOP_TRANSP + Transparency + + + TOP_TRIANGLE + Triangle + + + TOP_UNASSIGN + Unassign + + + TOP_UNION + Union of triangles + + + TOP_UNION2 + Union of two triangles + + + TOP_IMPORT_UNV + Import UNV file + + + TOP_UNV + Export UNV file + + + TOP_UN_GROUP + Union Groups + + + TOP_UNDERLYING_ELEMS + Create groups of entities from existing groups of superior dimensions + + + TOP_UPDATE + Update + + + TOP_VOLUMES + Volumes + + + TOP_VOLUME_3D + Volume + + + TOP_WARP + Warping angle + + + TOP_WHAT_IS + Mesh Element Information + + + TOP_WIRE + Wireframe + + + UNKNOWN_CONTROL + Unknown + + + VOLUME_3D_ELEMENTS + Volume + + + WARP_ELEMENTS + Warping + + + MEN_FILE_INFO + MED File Information + + + SMESH_WRN_NO_APPROPRIATE_SELECTION + No appropriate objects selected + + + MEN_CLEAR_MESH + Clear Mesh Data + + + TOP_CLEAR_MESH + Clear Mesh Data + + + STB_CLEAR_MESH + Clear Mesh Data + + + SMESH_IMPORT_MESH + Import mesh data from files + + + SMESH_ERR_NOT_SUPPORTED_FORMAT + Unsupported file format + + + SMESH_ERR_UNKNOWN_IMPORT_ERROR + Unknown error + + + SMESH_IMPORT_ERRORS + Import operation has finished with errors: + + + SMESH_DRS_SOME_EMPTY + One or more mesh files were empty, data has not been published + + + NO_MESH_SELECTED + No mesh selected + + + SMESH_PREF_def_precision + Default precision + + + SMESH_PREF_length_precision + Length precision + + + SMESH_PREF_angle_precision + Angular precision + + + SMESH_PREF_len_tol_precision + Length tolerance precision + + + SMESH_PREF_parametric_precision + Parametric precision + + + SMESH_PREF_area_precision + Area precision + + + FULL_RECOMPUTE_QUESTION + +The mesh has been edited since a last total re-compute +that may prevent successful computation. +Do you wish to re-compute the mesh totally to discard the modifications? - - - SMESH_ROTATION - Rotation - - - SMESH_ROTATION_TITLE - Rotation about an axis - - - SMESH_SCALARBAR - Scalar Bar - - - SMESH_SEGMENTS - Segments - - - SMESH_SELECTION - Selection - - - SMESH_SELECT_FROM - Select From - - - SMESH_SELECT_WHOLE_MESH - Select whole mesh, submesh or group - - - SMESH_SET_COLOR - Color group - - - SMESH_SEWING - Sewing - - - SMESH_SMOOTHING - Smoothing - - - SMESH_STANDARD_MESHINFO_TITLE - Standard Mesh Infos - - - SMESH_SUBMESH - SubMesh - - - SMESH_SUBMESH_SELECTED - %1 SubMeshes - - - SMESH_SYMMETRY - Symmetry - - - SMESH_TETRAS - Tetrahedron - - - SMESH_TITLE - Title: - - - SMESH_TOLERANCE - Tolerance - - - SMESH_TRANSLATION - Translation - - - SMESH_TRANSPARENCY_OPAQUE - ---> Opaque - - - SMESH_TRANSPARENCY_TITLE - Change Transparency - - - SMESH_TRANSPARENCY_TRANSPARENT - Transparent <--- - - - SMESH_TRIANGLE - Triangle - - - SMESH_UPDATEVIEW - Update View - - - SMESH_VALUE - Value - - - SMESH_VECTOR - Vector - - - SMESH_VERTICAL - Vertical - - - SMESH_VISU_PROBLEM - Mesh visualization failed, probably due to lack of memory - - - SMESH_VISU_PROBLEM_CLEAR - Mesh visualization failed, no memory even to show a message, -so all visual data have been removed to let the application live. -Consider saving your work before application crash - - - SMESH_VOLUME - Volume - - - SMESH_WARNING - Warning - - - SMESH_WHAT_IS_TITLE - Mesh Element Info - - - SMESH_WIDTH - Width: - - - SMESH_WRN_ALGORITHM_ALREADYEXIST - Algorithm already exists - - - SMESH_WRN_COMPUTE_FAILED - Mesh computation failed - - - SMESH_WRN_EMPTY_NAME - Empty name is not valid - - - SMESH_WRN_HYPOTHESIS_ALREADYEXIST - Hypothesis already exists - - - SMESH_WRN_HYPOTHESIS_NOTEXIST - Hypothesis or Algorithm not exists - - - SMESH_WRN_MISSING_PARAMETERS - Missing parameters - - - SMESH_WRN_NO_AVAILABLE_DATA - No available data in selection - - - SMESH_WRN_SELECTIONMODE_DIAGONAL - Activate Link Selection Mode - - - SMESH_WRN_SELECTIONMODE_ELEMENTS - Activate Elements Selection Mode - - - SMESH_WRN_SELECTIONMODE_NODES - Activate Nodes Selection Mode - - - SMESH_WRN_VIEWER_VTK - Study frame with VTK Viewer must be activated - - - SMESH_WRN_WARNING - Warning - - - SMESH_X - X - - - SMESH_X_SCALARBAR - X: - - - SMESH_Y - Y - - - SMESH_Y_SCALARBAR - Y: - - - SMESH_Z - Z - - - STATE_ALGO_MISSING - %3 %2D algorithm is missing - - - STATE_HYP_BAD_GEOMETRY - %3 %2D algorithm "%1" is assigned to geometry mismatching its expectation - - - STATE_HYP_BAD_PARAMETER - Hypothesis of %3 %2D algorithm "%1" has a bad parameter value - - - STATE_HYP_MISSING - %3 %2D algorithm "%1" misses %4D hypothesis - - - STATE_HYP_NOTCONFORM - %3 %2D algorithm "%1" would produce not conform mesh: global "Not Conform Mesh Allowed" hypotesis is missing - - - STB_ADV_INFO - Advanced Mesh Infos - - - STB_ALL - All - - - STB_AREA - Area - - - STB_ASPECT - Aspect Ratio - - - STB_ASPECT_3D - Aspect Ratio 3D - - - STB_AUTO_COLOR - Auto color - - - STB_AUTO_UPD - Automatic update - - - STB_BUILD_COMPOUND - Build Compound Mesh - - - STB_CLIP - Clipping - - - STB_COLORS - Colors / Size - - - STB_COMPUTE - Compute - - - STB_PRECOMPUTE - Preview - - - STB_CONNECTION - Borders at Multi-Connection - - - STB_CONNECTION_2D - Borders at Multi-Connection 2D - - - STB_CONSTRUCT_GROUP - Construct Group - - - STB_CONV_TO_QUAD - Convert to/from quadratic - - - STB_CREATE_GROUP - Create Group - - - STB_CREATE_GEO_GROUP - Create Groups from Geometry - - - STB_CREATE_MESH - Create Mesh - - - STB_CREATE_SUBMESH - Create Sub-mesh - - - STB_CUT - Cutting of quadrangles - - - STB_CUT_GROUP - Cut Groups - - - STB_DAT - Import DAT file - - - STB_DELETE - Delete - - - STB_DEL_GROUP - Delete Groups - - - STB_FACE_ORIENTATION - Orientation of faces - - - STB_DISABLE_AUTO_COLOR - Disable auto color - - - STB_DISPLAY_ONLY - Show only - - - STB_DISP_ENT - Display entity - - - STB_EDGE - Edge - - - STB_EDGES - Edges - - - STB_EDIT_GROUP - Edit Group - - - STB_EDIT_GEOMGROUP_AS_GROUP - Edit Group as Standalone - - - STB_EDIT_HYPO - Edit Hypothesis - - - STB_EDIT_MESHSUBMESH - Edit Mesh/Sub-mesh - - - STB_EXPORT_DAT - Export to DAT file - - - STB_EXPORT_MED - Export to MED file - - - STB_EXPORT_STL - Export to STL file - - - STB_EXPORT_UNV - Export to UNV file - - - STB_EXTRUSION - Extrusion - - - STB_EXTRUSION_ALONG - Extrusion along a path - - - STB_FACES - Faces - - - STB_FREE_BORDER - Free Borders - - - STB_FREE_EDGE - Free Edges - - - STB_FREE_NODE - Free Nodes - - - - - STB_FREE_FACES - Free Faces - - - STB_GLOBAL_HYPO - Global Hypothesis - - - STB_HEXA - Hexahedron - - - STB_HIDE - Hide - - - STB_INT_GROUP - Intersect Groups - - - STB_INV - Diagonal Inversion - - - STB_LENGTH - Length - - - STB_LENGTH_2D - Length 2D - - - STB_MAP - Pattern mapping - - - STB_MED - Import MED file - - - STB_MERGE - Merge nodes - - - STB_MERGE_ELEMENTS - Merge elements - - - STB_MESH_THROU_POINT - Mesh to pass through a point - - - STB_MIN_ANG - Minimum Angle - - - STB_MOVE - Move Node - - - STB_NODE - Node - - - STB_NODES - Nodes - - - STB_NUM_ELEMENTS - Display Elements - - - STB_NUM_NODES - Display Nodes - - - STB_ORIENT - Orientation - - - STB_POLYGON - Polygon - - - STB_POLYHEDRON - Polyhedron - - - STB_PRECISION - Precision - - - STB_QUAD - Quadrangle - - - STB_QUADRATIC_EDGE - Quadratic Edge - - - STB_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - STB_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - STB_QUADRATIC_PYRAMID - Quadratic Pyramid - - - STB_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - STB_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - STB_QUADRATIC_TRIANGLE - Quadratic Triangle - - - STB_REMOVE_ELEMENTS - Remove elements - - - STB_REMOVE_NODES - Remove nodes - - - STB_RENAME - Rename - - - STB_RENUM_ELEMENTS - Renumbering elements - - - STB_RENUM_NODES - Renumbering nodes - - - STB_RESET - Reset - - - STB_REVOLUTION - Revolution - - - STB_ROT - Rotation - - - STB_SCALAR_BAR - Scalar bar - - - STB_SCALAR_BAR_PROP - Scalar bar Properties - - - STB_SELECTION - Selection - - - STB_SEL_FILTER_LIB - Selection filters library - - - STB_SEW - Sewing - - - STB_SHADE - Shading - - - STB_SHOW - Show - - - STB_SHRINK - Shrink - - - STB_SKEW - Skew - - - STB_SMOOTH - Smoothing - - - STB_STD_INFO - Standard Mesh Infos - - - STB_SYM - Symmetry - - - STB_TAPER - Taper - - - STB_TETRA - Tetrahedron - - - STB_TRANS - Translation - - - STB_TRANSP - Transparency - - - STB_TRIANGLE - Triangle - - - STB_UNASSIGN - Unassign - - - STB_UNION - Union of triangles - - - STB_UNION2 - Union of two triangles - - - STB_UNV - Import UNV file - - - STB_UN_GROUP - Union Groups - - - STB_UNDERLYING_ELEMS - Create groups of entities from existing groups of superior dimensions - - - STB_UPDATE - Update - - - STB_VOLUMES - Volumes - - - STB_VOLUME_3D - Volume - - - STB_WARP - Warping angle - - - STB_WHAT_IS - Mesh Element Info - - - STB_WIRE - Wireframe - - - TAPER_ELEMENTS - Taper - - - TB_ADD_REMOVE - Add/Remove Toolbar - - - TB_CTRL - Controls Toolbar - - - TB_DISP_MODE - Display Mode Toolbar - - - TB_HYPO - Hypotheses Toolbar - - - TB_MESH - Mesh Toolbar - - - TB_MODIFY - Modification Toolbar - - - TOP_ADV_INFO - Advanced Mesh Infos - - - TOP_ALL - All - - - TOP_AREA - Area - - - TOP_ASPECT - Aspect Ratio - - - TOP_ASPECT_3D - Aspect Ratio 3D - - - TOP_AUTO_COLOR - Auto color - - - TOP_AUTO_UPD - Automatic update - - - TOP_BUILD_COMPOUND - Build Compound Mesh - - - TOP_CLIP - Clipping - - - TOP_COLORS - Colors / Size - - - TOP_COMPUTE - Compute - - - TOP_PRECOMPUTE - Preview - - - TOP_CONNECTION - Borders at Multi-Connection - - - TOP_CONNECTION_2D - Borders at Multi-Connection 2D - - - TOP_CONSTRUCT_GROUP - Construct Group - - - TOP_CONV_TO_QUAD - Convert to/from quadratic - - - TOP_CREATE_GROUP - Create Group - - - TOP_CREATE_GEO_GROUP - Create Groups from Geometry - - - TOP_CREATE_MESH - Create Mesh - - - TOP_CREATE_SUBMESH - Create Sub-mesh - - - TOP_CUT - Cutting of quadrangles - - - TOP_CUT_GROUP - Cut Groups - - - TOP_DAT - Import DAT file - - - TOP_DELETE - Delete - - - TOP_DEL_GROUP - Delete Groups - - - TOP_FACE_ORIENTATION - Orientation of faces - - - TOP_DISABLE_AUTO_COLOR - Disable auto color - - - TOP_DISPLAY_ONLY - Show only - - - TOP_DISP_ENT - Display entity - - - TOP_EDGE - Edge - - - TOP_EDGES - Edges - - - TOP_EDIT_GROUP - Edit Group - - - TOP_EDIT_GEOMGROUP_AS_GROUP - Edit Group as Standalone - - - TOP_EDIT_HYPO - Edit Hypothesis - - - TOP_EDIT_MESHSUBMESH - Edit Mesh/Sub-mesh - - - TOP_EXPORT_DAT - Export to DAT file - - - TOP_EXPORT_MED - Export to MED file - - - TOP_EXPORT_STL - Export to STL file - - - TOP_EXPORT_UNV - Export to UNV file - - - TOP_EXTRUSION - Extrusion - - - TOP_EXTRUSION_ALONG - Extrusion along a path - - - TOP_FACES - Faces - - - TOP_FREE_BORDER - Free Borders - - - TOP_FREE_EDGE - Free Edges - - - TOP_FREE_NODE - Free Nodes - - - - - TOP_FREE_FACES - Free Faces - - - TOP_GLOBAL_HYPO - Global Hypothesis - - - TOP_HEXA - Hexahedron - - - TOP_HIDE - Hide - - - TOP_INT_GROUP - Intersect Groups - - - TOP_INV - Diagonal Inversion - - - TOP_LENGTH - Length - - - TOP_LENGTH_2D - Length 2D - - - TOP_MAP - Pattern mapping - - - TOP_MED - Import MED file - - - TOP_MERGE - Merge nodes - - - TOP_MERGE_ELEMENTS - Merge elements - - - TOP_MESH_THROU_POINT - Mesh to pass through a point - - - TOP_MIN_ANG - Minimum Angle - - - TOP_MOVE - Move Node - - - TOP_NODE - Node - - - TOP_NODES - Nodes - - - TOP_NUM_ELEMENTS - Display Elements - - - TOP_NUM_NODES - Display Nodes - - - TOP_ORIENT - Orientation - - - TOP_POLYGON - Polygon - - - TOP_POLYHEDRON - Polyhedron - - - TOP_PRECISION - Precision - - - TOP_QUAD - Quadrangle - - - TOP_QUADRATIC_EDGE - Quadratic Edge - - - TOP_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - TOP_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - TOP_QUADRATIC_PYRAMID - Quadratic Pyramid - - - TOP_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - TOP_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - TOP_QUADRATIC_TRIANGLE - Quadratic Triangle - - - TOP_REMOVE_ELEMENTS - Remove elements - - - TOP_REMOVE_NODES - Remove nodes - - - TOP_RENAME - Rename - - - TOP_RENUM_ELEMENTS - Renumbering elements - - - TOP_RENUM_NODES - Renumbering nodes - - - TOP_RESET - Reset - - - TOP_REVOLUTION - Revolution - - - TOP_ROT - Rotation - - - TOP_SCALAR_BAR - Scalar bar - - - TOP_SCALAR_BAR_PROP - Scalar bar Properties - - - TOP_SELECTION - Selection - - - TOP_SEL_FILTER_LIB - Selection filters library - - - TOP_SEW - Sewing - - - TOP_SHADE - Shading - - - TOP_SHOW - Show - - - TOP_SHRINK - Shrink - - - TOP_SKEW - Skew - - - TOP_SMOOTH - Smoothing - - - TOP_STD_INFO - Standard Mesh Infos - - - TOP_SYM - Symmetry - - - TOP_TAPER - Taper - - - TOP_TETRA - Tetrahedron - - - TOP_TRANS - Translation - - - TOP_TRANSP - Transparency - - - TOP_TRIANGLE - Triangle - - - TOP_UNASSIGN - Unassign - - - TOP_UNION - Union of triangles - - - TOP_UNION2 - Union of two triangles - - - TOP_UNV - Import UNV file - - - TOP_UN_GROUP - Union Groups - - - TOP_UNDERLYING_ELEMS - Create groups of entities from existing groups of superior dimensions - - - TOP_UPDATE - Update - - - TOP_VOLUMES - Volumes - - - TOP_VOLUME_3D - Volume - - - TOP_WARP - Warping angle - - - TOP_WHAT_IS - Mesh Element Info - - - TOP_WIRE - Wireframe - - - VOLUME_3D_ELEMENTS - Area - - - WARP_ELEMENTS - Warping - - - MEN_FILE_INFO - MED File Information - - - SMESH_WRN_NO_APPROPRIATE_SELECTION - No appropriate objects selected - - - MEN_CLEAR_MESH - Clear Mesh Data - - - TOP_CLEAR_MESH - Clear Mesh Data - - - STB_CLEAR_MESH - Clear Mesh Data - - - SMESH_IMPORT_MESH - Import mesh data from files - - - SMESH_ERR_NOT_SUPPORTED_FORMAT - Unsupported file format - - - SMESH_ERR_UNKNOWN_IMPORT_ERROR - Unknown error - - - SMESH_IMPORT_ERRORS - Import operation has finished with errors: - - - SMESH_DRS_SOME_EMPTY - One or more mesh files were empty, data has not been published - - - - SMESHGUI - - NOT_A_VTK_VIEWER - This command is available in VTK viewer only + + + SMESH_PREF_vol_precision + Volume precision + + + SMESH_PRECISION_HINT + +Input value precision can be adjusted using +'%1' parameter in Mesh module preferences. + + + REMOVE_ORPHAN_NODES_QUESTION + Do you really want to remove all orphan nodes? + + + NB_NODES_REMOVED + Removed %1 node(s). + + + SMESH_SAVE_DISTRIBUTION + Export Distribution + + + SMESH_PLUGINS_OTHER + SMESH plugins + + + MESH_LOADING_MSG + Loading mesh %0 in progress, please wait... + + + MESH_LOADING_MSG_FINISHED + Mesh %0 loading done + + + BALL_DIAMETER + Diameter + + + BALL_ELEMENT + Ball + + + DEP_OBJECT + Selected object has been used to create another one. +It can't be deleted + + + + SMESHGUI_GroupDlg + + ALLOW_ELEM_LIST_MODIF + Enable manual edition + + + + SMESHGUI + + NOT_A_VTK_VIEWER + This command is available in VTK viewer only Please, create VTK viewer and try again - - - PREF_AUTO_GROUPS - Automatically create groups for MED export - - - PREF_GROUP_SEGMENT_LENGTH - Automatic parameters - - - PREF_SEGMENT_LENGTH - Ratio Bounding Box Diagonal / Max Size - - - PREF_NB_SEGMENTS - Default Number of Segments - - - PREF_AUTO_UPDATE - Automatic update - - - PREF_BACKFACE - Back face - - - PREF_COLOR - Color - - - PREF_ORIENTATION_COLOR - Color - - - PREF_ORIENTATION_3D_VECTORS - 3D vectors - - - PREF_ORIENTATION_SCALE - Scale - - - PREF_DISPLAY_ENTITY - Display entity - - - PREF_DISPLAY_MODE - Display mode - - - PREF_ELEMENTS - Elements - - - PREF_ELEMENT_COLOR - Element color - - - PREF_FILL - Fill - - - PREF_NOTIFY_MODE - Show a computation result notification - - - PREF_GROUP_ELEMENTS - Elements - - - PREF_GROUP_EXPORT - Mesh export - - - PREF_GROUP_FACES_ORIENTATION - Orientation of faces - - - PREF_GROUP_COMPUTE - Mesh computation - - - PREF_GROUP_NODES - Nodes - - - PREF_GROUP_PRECISION - Precision - - - PREF_GROUP_PRESELECTION - Preselection - - - PREF_GROUP_QUALITY - Quality controls - - - PREF_GROUP_SELECTION - Selection - - - PREF_GROUP_UPDATE - Update - - - PREF_HIGHLIGHT_COLOR - Highlight color - - - PREF_LABELS_COLOR - Labels color - - - PREF_NODES - Nodes - - - PREF_OBJECTS - Objects - - - PREF_OBJECT_COLOR - Object color - - - PREF_OUTLINE - Outline - - - PREF_PRECISION_USE - Use precision - - - PREF_PRECISION_VALUE - Number of digits after point - - - PREF_RENUMBER - Automatic renumbering - - - PREF_SHRINK_COEFF - Shrink coef. - - - PREF_SIZE - Size - - - PREF_TAB_GENERAL - General - - - PREF_TAB_MESH - Mesh - - - PREF_TAB_SELECTION - Selection - - - PREF_TITLE_COLOR - Title color - - - PREF_WIDTH - Width - - - - SMESHGUI_AddQuadraticElementDlg - - SMESH_ADD_QUADRATIC_EDGE - Add Quadratic Edge - - - SMESH_ADD_QUADRATIC_HEXAHEDRON - Add Quadratic Hexahedron - - - SMESH_ADD_QUADRATIC_PENTAHEDRON - Add Quadratic Pentahedron - - - SMESH_ADD_QUADRATIC_PYRAMID - Add Quadratic Pyramid - - - SMESH_ADD_QUADRATIC_QUADRANGLE - Add Quadratic Quadrangle - - - SMESH_ADD_QUADRATIC_TETRAHEDRON - Add Quadratic Tetrahedron - - - SMESH_ADD_QUADRATIC_TRIANGLE - Add Quadratic Triangle - - - SMESH_CORNER_NODES - Corner Nodes: - - - SMESH_FIRST - First - - - SMESH_LAST - Last - - - SMESH_MIDDLE - Middle - - - - SMESHGUI_BuildCompoundDlg - - COMPOUND - Compound - - - COMPOUND_MESH - Compound_Mesh - - - CREATE_COMMON_GROUPS - Create common groups for initial meshes - - - MERGE_NODES_AND_ELEMENTS - Merge coincident nodes and elements - - - MESHES - Meshes - - - PROCESSING_IDENTICAL_GROUPS - Processing identical groups - - - RENAME - Rename - - - RESULT_NAME - Result name - - - UNITE - Unite - - - - SMESHGUI_ChangeOrientationDlg - - CAPTION - Modification of orientation - - - - SMESHGUI_ComputeDlg - - CAPTION - Compute mesh failed - - - CONSTRUCTOR - Compute mesh - - - ERRORS - Errors - - - MEMORY_LACK - Memory allocation problem - - - PUBLISH_SHAPE - Publish SubShape - - - SHOW_SHAPE - Show SubShape - - - SHOW_BAD_MESH - Show bad Mesh - - - - SMESHGUI_PrecomputeDlg - - CAPTION - Preview and Compute mesh - - - PREVIEW - Preview - - - PREVIEW_1 - 1D Mesh - - - PREVIEW_2 - 2D Mesh - - - COMPUTE - Compute - - - - SMESHGUI_PrecomputeOp - - CLEAR_SUBMESH_QUESTION - A temporary submeshes on the selected geometry - created during preview operation. - Do you want to remove all this submeshes? - - - - SMESHGUI_ConvToQuadDlg - - CAPTION - Convert to/from quadratic - - - MEDIUMNDS - Medium nodes on geometry - - - MESH - Mesh - - - RADIOBTN_1 - Convert to quadratic - - - RADIOBTN_2 - Convert from quadratic - - - - SMESHGUI_ConvToQuadOp - - MESH_IS_NOT_SELECTED - Mesh is not selected + + + PREF_AUTO_GROUPS + Automatically create groups for MED export + + + PREF_GROUP_SEGMENT_LENGTH + Automatic parameters + + + PREF_SEGMENT_LENGTH + Ratio Bounding Box Diagonal / Max Size + + + PREF_NB_SEGMENTS + Default Number of Segments + + + SMESH_PREF_MESH_LOADING + Mesh loading + + + PREF_FORGET_MESH_AT_HYP_MODIF + No mesh loading from study file at hypothesis modification + + + PREF_AUTO_UPDATE + Automatic update + + + PREF_UPDATE_LIMIT + Size limit (elements) + + + PREF_UPDATE_LIMIT_NOLIMIT + No limit + + + PREF_BACKFACE + Back surface color + + + PREF_WIREFRAME + Wireframe color + + + PREF_SELECTION + Selection color + + + PREF_PRE_SELECTION + Pre-selection color + + + PREF_COLOR + Color + + + PREF_ORIENTATION_COLOR + Color + + + PREF_ORIENTATION_3D_VECTORS + 3D vectors + + + PREF_ORIENTATION_SCALE + Scale + + + PREF_DISPLAY_ENTITY + Display entity + + + QUADRATIC_REPRESENT_MODE + Representation of the 2D quadratic elements + + + MAX_ARC_ANGLE + Maximum angle + + + PREF_DISPLAY_MODE + Display mode + + + PREF_ELEMENTS + Elements + + + PREF_ELEMENT_COLOR + Element color + + + PREF_FILL + Surface color + + + PREF_NOTIFY_MODE + Show a computation result notification + + + PREF_NOTIFY_NEVER + Never + + + PREF_NOTIFY_ERROR + Errors only + + + PREF_NOTIFY_ALWAYS + Always + + + PREF_ELEM_INFO + Mesh element information + + + PREF_ELEM_INFO_SIMPLE + Simple + + + PREF_ELEM_INFO_TREE + Tree + + + PREF_GPP_NODES_LIMIT + Automatic nodes compute limit + + + SMESH_PREF_GROUP_PRECISION + Input fields precision + + + SMESH_PREF_GROUP_PREVIEW + Preview + + + PREF_GROUP_ELEMENTS + Elements + + + PREF_GROUP_EXPORT + Mesh export + + + PREF_GROUP_FACES_ORIENTATION + Orientation of faces + + + PREF_GROUP_COMPUTE + Mesh computation + + + PREF_GROUP_NODES + Nodes + + + PREF_GROUP_GROUPS + Groups + + + PREF_GRP_NAMES + Names color + + + PREF_GROUP_PRECISION + Precision + + + PREF_GROUP_PRESELECTION + Preselection + + + PREF_GROUP_QUALITY + Quality controls + + + PREF_GROUP_SELECTION + Selection + + + PREF_GROUP_INFO + Mesh information + + + PREF_HIGHLIGHT_COLOR + Highlight color + + + PREF_LABELS_COLOR + Labels color + + + PREF_MARKER_SCALE + Scale of marker + + + PREF_NODES + Nodes + + + PREF_OBJECTS + Objects + + + PREF_OBJECT_COLOR + Object color + + + PREF_OUTLINE + Outline color + + + PREF_PRECISION_USE + Use precision + + + PREF_PRECISION_VALUE + Number of digits after point + + + PREF_EQUAL_NODES_TOL + Double nodes tolerance + + + PREF_RENUMBER + Automatic renumbering + + + PREF_SHRINK_COEFF + Shrink coef. + + + PREF_PYTHON_DUMP + Python Dump + + + PREF_HISTORICAL_PYTHON_DUMP + Historical python dump + + + PREF_TAB_GENERAL + General + + + PREF_TAB_MESH + Mesh + + + PREF_TAB_SELECTION + Selection + + + PREF_TITLE_COLOR + Title color + + + PREF_TYPE_OF_MARKER + Type of marker + + + PREF_COLOR_0D + 0D elements + + + PREF_SIZE_0D + Size of 0D elements + + + PREF_BALL_COLOR + Balls + + + PREF_BALL_SIZE + Size of ball elements + + + PREF_WIDTH + Width + + + PREF_PREVIEW_CHUNK_SIZE + Sub-shapes preview chunk size + + + + SMESHGUI_AddQuadraticElementDlg + + SMESH_ADD_QUADRATIC_EDGE + Add Quadratic Edge + + + SMESH_ADD_QUADRATIC_HEXAHEDRON + Add Quadratic Hexahedron + + + SMESH_ADD_TRIQUADRATIC_HEXAHEDRON + Add TriQuadratic Hexahedron + + + SMESH_ADD_QUADRATIC_PENTAHEDRON + Add Quadratic Pentahedron + + + SMESH_ADD_QUADRATIC_PYRAMID + Add Quadratic Pyramid + + + SMESH_ADD_QUADRATIC_QUADRANGLE + Add Quadratic Quadrangle + + + SMESH_ADD_BIQUADRATIC_QUADRANGLE + Add BiQuadratic Quadrangle + + + SMESH_ADD_QUADRATIC_TETRAHEDRON + Add Quadratic Tetrahedron + + + SMESH_ADD_QUADRATIC_TRIANGLE + Add Quadratic Triangle + + + SMESH_CORNER_NODES + Corner Nodes: + + + SMESH_MIDFACE_NODES + Mid-face Nodes: + + + SMESH_CENTER_NODE + Center Node: + + + SMESH_FIRST + First + + + SMESH_LAST + Last + + + SMESH_MIDDLE + Middle + + + + SMESHGUI_BuildCompoundDlg + + COMPOUND + Compound + + + COMPOUND_MESH + Compound_Mesh + + + CREATE_COMMON_GROUPS + Create common groups for initial meshes + + + MERGE_NODES_AND_ELEMENTS + Merge coincident nodes and elements + + + MESHES + Meshes + + + PROCESSING_IDENTICAL_GROUPS + Processing identical groups + + + RENAME + Rename + + + RESULT_NAME + Result name + + + UNITE + Unite + + + + SMESHGUI_ChangeOrientationDlg + + CAPTION + Modification of orientation + + + + SMESHGUI_ComputeDlg + + CAPTION + Compute mesh failed + + + CONSTRUCTOR + Compute mesh + + + EVAL_DLG + Evaluate mesh + + + ERRORS + Errors + + + MEMORY_LACK + Memory allocation problem + + + COMPUTE_WARNING + The mesh seems to be OK but there are some errors reported + + + PUBLISH_SHAPE + Publish Sub-shape + + + SHOW_SHAPE + Show Sub-shape + + + SHOW_BAD_MESH + Show bad Mesh + + + + SMESHGUI_PrecomputeDlg + + CAPTION + Preview and Compute mesh + + + PREVIEW + Preview + + + PREVIEW_1 + 1D Mesh + + + PREVIEW_2 + 2D Mesh + + + COMPUTE + Compute + + + + SMESHGUI_PrecomputeOp + + CLEAR_SUBMESH_QUESTION + Temporary submeshes on the selected geometry +were created during preview operation. +Do you want to remove all these submeshes? + + + SMESH_WRN_NOTHING_PREVIEW + No mesh preview is available + + + SMESH_REJECT_MESH_ORDER + The submesh priority changed during preview operation. +Do you want to restore original submesh priority? + + + + SMESHGUI_ConvToQuadDlg + + CAPTION + Convert to/from quadratic + + + MEDIUMNDS + Medium nodes on geometry + + + MESH + Mesh or Sub-mesh + + + RADIOBTN_1 + Convert to quadratic + + + RADIOBTN_2 + Convert from quadratic + + + NON_CONFORM_WARNING + Warning: mesh can become non-conformal + + + + SMESHGUI_ConvToQuadOp + + MESH_IS_NOT_SELECTED + Mesh is not selected +Please specify it and try again + + + REF_IS_NULL + No valid mesh object selected + + + + SMESHGUI_CreatePatternDlg + + CAPTION + Pattern Creation + + + DEFAULT_2D + Pattern_2d + + + DEFAULT_3D + Pattern_3d + + + ERROR_OF_CREATION + Internal error occurs during pattern creation +Please verify validity of entered information + + + ERROR_OF_SAVING + Internal error occurs during pattern saving. Please verify +\free disk space and your write permission to this file + + + ERR_LOADF_CANT_PROJECT + Impossible to perform projection of nodes to the face + + + ERR_LOADF_CLOSED_FACE + It is impossible to create pattern from face having seam edge + + + ERR_LOADF_NARROW_FACE + It is impossible to create pattern from narrow face + + + ERR_LOADV_BAD_SHAPE + Pattern can be created from closed shell or solid with 6 faces only + + + ERR_LOADV_COMPUTE_PARAMS + It is impossible to compute point parameters + + + ERR_LOAD_EMPTY_SUBMESH + There are no elements to create pattern + + + MESH_OR_SUBMESH + Mesh or SubMesh + + + PATTERN + Pattern + + + PATTERN_FILT + Pattern files(*.smp) + + + PATTERN_NAME + Pattern name + + + PATTERN_TYPE + Pattern type + + + PROJECT + Project nodes on the face + + + SAVE + Save... + + + SAVE_PATTERN + Save Pattern + + + + SMESHGUI_CreatePolyhedralVolumeDlg + + FACES_BY_NODES + Faces by nodes + + + SMESH_POLYEDRE_CREATE_ERROR + Polyhedron creation error. + + + SMESH_POLYEDRE_PREVIEW + Polyhedron preview + + + + SMESHGUI_CuttingOfQuadsDlg + + CAPTION + Cutting of quadrangles + + + + SMESHGUI_DeleteGroupDlg + + CAPTION + Delete groups with contents + + + NO_SELECTED_GROUPS + There are no selected groups +Please select a group and try again + + + SELECTED_GROUPS + Selected groups + + + + SMESHGUI_MergeDlg + + COINCIDENT_ELEMENTS + Coincident elements + + + COINCIDENT_NODES + Coincident nodes + + + DETECT + Detect + + + EDIT_SELECTED_GROUP + Edit selected group + + + SELECT_ALL + Select all + + + EXCLUDE_GROUPS + Exclude Groups + + + + SMESHGUI_ExtrusionAlongPathDlg + + BAD_SHAPE_TYPE + The shape selected for the path is not edge + + + CANT_GET_TANGENT + Can't get tangent for one of the path nodes + + + EXTRUSION_0D + Extrusion of 0D elements + + + EXTRUSION_1D + Extrusion of 1D elements + + + EXTRUSION_2D + Extrusion of 2D elements + + + EXTRUSION_ALONG_PATH + Extrusion along a path + + + EXTR_BAD_STARTING_NODE + Wrong path starting node + + + LINEAR_ANGLES + Linear variation of the angles + + + NO_ELEMENTS_SELECTED + No mesh elements are selected for extrusion + + + SELECTED_PATH_IS_NOT_EDGE + Path mesh should be of edge type + + + SMESH_ANGLES + Rotation Angles + + + SMESH_BASE_POINT + Base Point + + + SMESH_PATH + Path + + + SMESH_PATH_MESH + Mesh or submesh + + + SMESH_PATH_SHAPE + Shape (edge) + + + SMESH_PATH_START + Start node + + + SMESH_USE_ANGLES + Use Angles + + + SMESH_USE_BASE_POINT + Use Base Point + + + WRONG_ANGLES_NUMBER + The number of angles should correspond to the number of path nodes + + + + SMESHGUI_ExtrusionDlg + + EXTRUSION_0D + Extrusion of nodes + + + EXTRUSION_1D + Extrusion of 1D elements + + + EXTRUSION_2D + Extrusion of 2D elements + + + EXTRUSION_ALONG_LINE + Extrusion along a line + + + + SMESHGUI_FilterDlg + + BAD_SHAPE_NAME + There is no "%1" geometrical object in the current study +Please select valid object and try again + + + CURRENT_DIALOG + Current Group + + + EDGES_TLT + Filter for Edges + + + FACES_TLT + Filter for Faces + + + MESH + Mesh + + + NODES_TLT + Filter for Nodes + + + SELECTION + Initial Selection + + + SET_IN_VIEWER + Insert filter in viewer + + + SHAPE_IS_NOT_A_CYLINDER + "%1" is not a cylinderical face +Please select a cylindrical face and try again + + + SHAPE_IS_NOT_A_FACE + "%1" is not a face +Please select a face and try again + + + SHAPE_IS_NOT_A_PLANE + "%1" is not a plane +Please select a plane and try again + + + FACE_ID_NOT_SELECTED + Mesh face is not selected +Please specify it and try again + + + NOT_FACE_ID + "%1" is not an ID of a mesh face. +Please select a face and try again + + + SOURCE + Source + + + TLT + Selection filter + + + VOLUMES_TLT + Filter for Volumes + + + + SMESHGUI_FilterLibraryDlg + + ADD + Add + + + ADD_TO_TLT + Add selection filter to library + + + ALL_FILES_FILTER + All Files (*.*) + + + ASSIGN_NEW_NAME + Library already contains filter with name "%1" +New name "%2" is assigned to added filter + + + COPY_FROM_TLT + Copy selection filter from library + + + DELETE + Delete + + + EDGE + Edge + + + EDIT_LIB_TLT + Selection filter library + + + ELEMENT + Element + + + EMPTY_FILTER_NAME + Name of the filter is empty +Please enter a non-empty name + + + ERROR_FILTER_NAME + Name of the filter is not unique +Please enter other name + + + ERROR_LOAD + It is impossible to load library +Please check library file name and attributes + + + ERROR_OF_ADDING + Internal error occurs during adiing new filter in library. +Please verify validity of entered information + + + ERROR_OF_COPYING + Internal error occurs during copying filter from library. +Please verify validity of entered information + + + ERROR_OF_DELETING + Internal error occurs during deleting filter from library. +Please verify validity of entered information + + + ERROR_OF_EDITING + Internal error occurs during editing filter library. +Please verify validity of entered information + + + ERROR_OF_SAVING + Internal error occurs during saving filter library +Please check input data and try again + + + FACE + Face + + + FILTER + Filter + + + FILTER_NAME + Filter name + + + FILTER_NAMES + Names of filters + + + LIBRARY_FILE + Library file name + + + LIBRARY_IS_NOT_LOADED + Library is not loaded. Please load library and try again + + + LIB_NAME + FilterLib.xml + + + NODE + Node + + + NO_PERMISSION + You do not have write permission to this file + + + OPEN_LIBRARY + Open library + + + SELECTION + Selection + + + VOLUME + Volume + + + XML_FILT + XML files(*.xml) + + + + SMESHGUI_FilterTable + + ADD + Add + + + ADDITIONAL_PARAMETERS + Additional parameters + + + ADD_TO + Add to... + + + AND + And + + + AREA + Area + + + ASPECT_RATIO + Aspect ratio + + + ASPECT_RATIO_3D + Aspect ratio 3D + + + BAD_ORIENTED_VOLUME + Bad oriented volume + + + BARE_BORDER_VOLUME + Volumes with bare border + + + BARE_BORDER_FACE + Faces with bare border + + + OVER_CONSTRAINED_VOLUME + Over-constrained volumes + + + OVER_CONSTRAINED_FACE + Over-constrained faces + + + BELONG_TO_CYLINDER + Belong to Cylinder + + + BELONG_TO_GENSURFACE + Belong to Surface + + + BELONG_TO_GEOM + Belong to Geom + + + BELONG_TO_PLANE + Belong to Plane + + + BINARY + Binary + + + CLEAR + Clear + + + COMPARE + Compare + + + COPLANAR_FACES + Coplanar faces + + + COPY_FROM + Copy from... + + + CRITERION + Criterion + + + BALLS + Balls + + + EDGES + Edges + + + ENTITY_TYPE + Entity type + + + EQUAL_TO + Equal to + + + ERROR + Threshold value is not correctly specified +Please enter correct value and try again + + + FACES + Faces + + + FILTER + Filter + + + FREE_BORDERS + Free borders + + + FREE_EDGES + Free edges + + + FREE_NODES + Free nodes + + + FREE_FACES + Free faces + + + ID + ID + + + INSERT + Insert + + + LENGTH + Length + + + LENGTH2D + Length 2D + + + LESS_THAN + Less than + + + LYING_ON_GEOM + Lying on Geom + + + MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + MINIMUM_ANGLE + Minimum angle + + + MORE_THAN + More than + + + MULTIEDGES_ERROR + Threshold value of borders at multi-connections can not be equal 1 +Please enter correct value and try again + + + GROUPCOLOR_ERROR + Color of group can not be undefied +Please enter correct value and try again + + + MULTI_BORDERS + Borders at multi-connections + + + NODES + Nodes + + + NOT + Not + + + OR + Or + + + RANGE_OF_IDS + Range of IDs + + + REMOVE + Remove + + + SKEW + Skew + + + TAPER + Taper + + + THRESHOLD_VALUE + Threshold value + + + UNARY + Unary + + + VOLUMES + Volumes + + + VOLUME_3D + Volume + + + WARPING + Warping + + + LINEAR + Linear + + + GROUP_COLOR + Color of Group + + + ELEMENTS + Elements + + + GEOM_TYPE + Geometry type + + + GEOM_TYPE_0 + Point + + + GEOM_TYPE_1 + Edge + + + GEOM_TYPE_2 + Triangle + + + GEOM_TYPE_3 + Quadrangle + + + GEOM_TYPE_4 + Polygon + + + GEOM_TYPE_5 + Tetrahedron + + + GEOM_TYPE_6 + Pyramid + + + GEOM_TYPE_7 + Hexahedron + + + GEOM_TYPE_8 + Pentahedron + + + GEOM_TYPE_9 + Hexagonal prism + + + GEOM_TYPE_10 + Polyhedra + + + GEOM_TYPE_11 + Ball + + + + SMESHGUI_GroupOpDlg + + ARGUMENTS + Arguments + + + DIFF_MESHES + Arguments of operation are not correctly specified +Groups correspond to a different meshes +Please specify valid arguments and try again + + + DIFF_TYPES + Arguments of operation are not correctly specified +Groups contain elements of different types +Please specify valid arguments and try again + + + EMPTY_NAME + Name of group to be created is not valid +Please specify non-empty name and try again + + + INCORRECT_ARGUMENTS + Arguments of operation are not specified +Please specify them and try again + + + NAME + Name + + + OBJECT_1 + Object 1 + + + OBJECT_2 + Object 2 + + + RESULT_NAME + Result name + + + TOOL_OBJECT + Tool object + + + UNION_OF_TWO_GROUPS + Union of two groups + + + + SMESHGUI_GroupDlg + + SELECT_ALL + Select All + + + + SMESHGUI_UnionGroupsDlg + + UNION_OF_GROUPS + Union of groups + + + + SMESHGUI_DimGroupDlg + + CREATE_GROUP_OF_UNDERLYING_ELEMS + Create group of underlying entities + + + ELEMENTS_TYPE + Elements type + + + NODE + Node + + + EDGE + Edge + + + FACE + Face + + + VOLUME + Volume + + + + SMESHGUI_IntersectGroupsDlg + + INTERSECTION_OF_GROUPS + Intersection of groups + + + + SMESHGUI_CutGroupsDlg + + CUT_OF_GROUPS + Cut of groups + + + MAIN_OBJECT + Main object + + + TOOL_OBJECT + Tool object + + + + SMESHGUI_MakeNodeAtPointDlg + + AUTO_SEARCH + Find closest to destination + + + CAPTION + Move node + + + DESTINATION + Destination + + + MOVE_NODE + Move node + + + METHOD + Method + + + NODE_2MOVE + Node to move + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MakeNodeAtPointOp + + INVALID_ID + Node ID is invalid + + + INVALID_MESH + Mesh to modify not selected + + + + SMESHGUI_FindElemByPointDlg + + MESH_GROUP + Mesh or group + + + CAPTION + Find Element by Point + + + CREATE_NEW_METHOD + Create a node + + + MESH_PASS_THROUGH_POINT + Make a node at point + + + METHOD + Method + + + MOVE_EXISTING_METHOD + Move a node + + + NODE_2MOVE + Node to move + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MeshDlg + + CREATE_MESH + Create mesh + + + CREATE_SUBMESH + Create sub-mesh + + + DIM_0D + 0D + + + DIM_1D + 1D + + + DIM_2D + 2D + + + DIM_3D + 3D + + + EDIT_MESH_SUBMESH + Edit mesh/sub-mesh + + + GEOMETRY + Geometry + + + HYPOTHESES_SETS + Assign a set of hypotheses + + + MESH + Mesh + + + NAME + Name + + + + SMESHGUI_MeshOp + + ALGORITHM_WITHOUT_HYPOTHESIS + Algorithm is defined for %1 dimension but hypothesis is not defined + + + EDIT_SUBMESH_QUESTION + A submesh on the selected geometry already exists. + Do you want to edit this submesh? + + + SUBMESH_NOT_ALLOWED + No sense in creating a submesh ignored by global algorithm "%1" + + + GEOMETRY_OBJECT_IS_NOT_DEFINED + Geometry object is not defined Please specify it and try again - - - REF_IS_NULL - No valid mesh object selected - - - - SMESHGUI_CreatePatternDlg - - CAPTION - Pattern Creation - - - DEFAULT_2D - Pattern_2d - - - DEFAULT_3D - Pattern_3d - - - ERROR_OF_CREATION - Internal error occurs during pattern creation -Please verify validity of entered information - - - ERROR_OF_SAVING - Internal error occurs during pattern saving. Please verify -\free disk space and your write permission to this file - - - ERR_LOADF_CANT_PROJECT - Impossible to perform projection of nodes to the face - - - ERR_LOADF_CLOSED_FACE - It is impossible to create pattern from face having seam edge - - - ERR_LOADF_NARROW_FACE - It is impossible to create pattern from narrow face - - - ERR_LOADV_BAD_SHAPE - Pattern can be created from closed shell or solid with 6 faces only - - - ERR_LOADV_COMPUTE_PARAMS - It is impossible to compute point parameters - - - ERR_LOAD_EMPTY_SUBMESH - There are no elements to create pattern - - - MESH_OR_SUBMESH - Mesh or SubMesh - - - PATTERN - Pattern - - - PATTERN_FILT - Pattern files(*.smp) - - - PATTERN_NAME - Pattern name - - - PATTERN_TYPE - Pattern type - - - PROJECT - Project nodes on the face - - - SAVE - Save... - - - SAVE_PATTERN - Save Pattern - - - - SMESHGUI_CreatePolyhedralVolumeDlg - - FACES_BY_NODES - Faces by nodes - - - SMESH_POLYEDRE_CREATE_ERROR - Polyhedron creation error. - - - SMESH_POLYEDRE_PREVIEW - Polyhedron preview - - - - SMESHGUI_CuttingOfQuadsDlg - - CAPTION - Cutting of quadrangles - - - - SMESHGUI_DeleteGroupDlg - - CAPTION - Delete groups with contents - - - NO_SELECTED_GROUPS - There are no selected groups -Please select a groups and try again - - - SELECTED_GROUPS - Selected groups - - - - SMESHGUI_EditMeshDlg - - COINCIDENT_ELEMENTS - Coincident elements - - - COINCIDENT_NODES - Coincident nodes - - - DETECT - Detect - - - EDIT_SELECTED_GROUP - Edit selected group - - - SELECT_ALL - Select all - - - - SMESHGUI_ExtrusionAlongPathDlg - - BAD_SHAPE_TYPE - The shape selected for the path is not edge - - - CANT_GET_TANGENT - Can't get tangent for one of the path nodes - - - EXTRUSION_1D - Extrusion of 1D elements - - - EXTRUSION_2D - Extrusion of 2D elements - - - EXTRUSION_ALONG_PATH - Extrusion along a path - - - EXTR_BAD_STARTING_NODE - Wrong path starting node - - - LINEAR_ANGLES - Linear variation of the angles - - - NO_ELEMENTS_SELECTED - No mesh elements are selected for extrusion - - - SELECTED_PATH_IS_NOT_EDGE - Path mesh should be of edge type - - - SMESH_ANGLES - Rotation Angles - - - SMESH_BASE_POINT - Base Point - - - SMESH_PATH - Path - - - SMESH_PATH_MESH - Mesh - - - SMESH_PATH_SHAPE - Shape (edge) - - - SMESH_PATH_START - Start node - - - SMESH_USE_ANGLES - Use Angles - - - SMESH_USE_BASE_POINT - Use Base Point - - - WRONG_ANGLES_NUMBER - The number of angles should correspond to the number of path nodes - - - - SMESHGUI_ExtrusionDlg - - EXTRUSION_1D - Extrusion of 1D elements - - - EXTRUSION_2D - Extrusion of 2D elements - - - EXTRUSION_ALONG_LINE - Extrusion along a line - - - - SMESHGUI_FilterDlg - - BAD_SHAPE_NAME - There is no "%1" geometrical object in the current study -Please select valid object and try again - - - CURRENT_DIALOG - Current Dialog - - - EDGES_TLT - Filter for Edges - - - FACES_TLT - Filter for Faces - - - MESH - Mesh - - - NODES_TLT - Filter for Nodes - - - SELECTION - Initial Selection - - - SET_IN_VIEWER - Insert filter in viewer - - - SHAPE_IS_NOT_A_CYLINDER - "%1" is not a cylinderical face -Please select a cylindrical face and try again - - - SHAPE_IS_NOT_A_FACE - "%1" is not a face -Please select a face and try again - - - SHAPE_IS_NOT_A_PLANE - "%1" is not a plane -Please select a plane and try again - - - SOURCE - Source - - - TLT - Selection filter - - - VOLUMES_TLT - Filter for Volumes - - - - SMESHGUI_FilterLibraryDlg - - ADD - Add - - - ADD_TO_TLT - Add selection filter to library - - - ALL_FILES_FILTER - All Files (*.*) - - - ASSIGN_NEW_NAME - Library already contains filter with name "%1" -New name "%2" is assigned to added filter - - - COPY_FROM_TLT - Copy selection filter from library - - - DELETE - Delete - - - EDGE - Edge - - - EDIT_LIB_TLT - Selection filter library - - - ELEMENT - Element - - - EMPTY_FILTER_NAME - Name of the filter is empty -Please enter a non-empty name - - - ERROR_FILTER_NAME - Name of the filter is not unique -Please enter other name - - - ERROR_LOAD - It is impossible to load library -Please check library file name and attributes - - - ERROR_OF_ADDING - Internal error occurs during adiing new filter in library. -Please verify validity of entered information - - - ERROR_OF_COPYING - Internal error occurs during copying filter from library. -Please verify validity of entered information - - - ERROR_OF_DELETING - Internal error occurs during deleting filter from library. -Please verify validity of entered information - - - ERROR_OF_EDITING - Internal error occurs during editing filter library. -Please verify validity of entered information - - - ERROR_OF_SAVING - Internal error occurs during saving filter library -Please check input data and try again - - - FACE - Face - - - FILTER - Filter - - - FILTER_NAME - Filter name - - - FILTER_NAMES - Names of filters - - - LIBRARY_FILE - Library file name - - - LIBRARY_IS_NOT_LOADED - Library is not loaded. Please load library and try again - - - LIB_NAME - FilterLib.xml - - - NODE - Node - - - NO_PERMISSION - You do not have write permission to this file - - - OPEN_LIBRARY - Open library - - - SELECTION - Selection - - - VOLUME - Volume - - - XML_FILT - XML files(*.xml) - - - - SMESHGUI_FilterTable - - ADD - Add - - - ADDITIONAL_PARAMETERS - Additional parameters - - - ADD_TO - Add to... - - - AND - And - - - AREA - Area - - - ASPECT_RATIO - Aspect ratio - - - ASPECT_RATIO_3D - Aspect ratio 3D - - - BAD_ORIENTED_VOLUME - Bad oriented volume - - - BELONG_TO_CYLINDER - Belong to Cylinder - - - BELONG_TO_GENSURFACE - Belong to Surface - - - BELONG_TO_GEOM - Belong to Geom - - - BELONG_TO_PLANE - Belong to Plane - - - BINARY - Binary - - - CLEAR - Clear - - - COMPARE - Compare - - - COPY_FROM - Copy from... - - - CRITERION - Criterion - - - EDGES - Edges - - - ENTITY_TYPE - Entity type - - - EQUAL_TO - Equal to - - - ERROR - Threshold value is not correctly specified -Please enter correct value and try again - - - FACES - Faces - - - FILTER - Filter - - - FREE_BORDERS - Free borders - - - FREE_EDGES - Free edges - - - FREE_NODES - Free nodes - - - - - FREE_FACES - Free faces - - - ID - ID - - - INSERT - Insert - - - LENGTH - Length - - - LENGTH2D - Length 2D - - - LESS_THAN - Less than - - - LYING_ON_GEOM - Lying on Geom - - - MINIMUM_ANGLE - Minimum angle - - - MORE_THAN - More than - - - MULTIEDGES_ERROR - Threshold value of borders at multi-connections can not be equal 1 -Please enter correct value and try again - - - GROUPCOLOR_ERROR - Color of group can not be undefied -Please enter correct value and try again - - - MULTI_BORDERS - Borders at multi-connections - - - NODES - Nodes - - - NOT - Not - - - OR - Or - - - RANGE_OF_IDS - Range of IDs - - - REMOVE - Remove - - - SKEW - Skew - - - TAPER - Taper - - - THRESHOLD_VALUE - Threshold value - - - UNARY - Unary - - - VOLUMES - Volumes - - - VOLUME_3D - Volume - - - WARPING - Warping - - - LINEAR - Linear - - - GROUP_COLOR - Color of Group - - - ELEMENTS - Elements - - - GEOM_TYPE - Geometry type - - - GEOM_TYPE_0 - - - - GEOM_TYPE_0 - Point - - - GEOM_TYPE_1 - Edge - - - GEOM_TYPE_2 - Triangle - - - GEOM_TYPE_3 - Quadrangle - - - GEOM_TYPE_4 - Polygon - - - GEOM_TYPE_5 - Tetrahedron - - - GEOM_TYPE_6 - Pyramid - - - GEOM_TYPE_7 - Hexahedron - - - GEOM_TYPE_8 - Pentahedron - - - GEOM_TYPE_9 - Polyhedra - - - - SMESHGUI_GroupOpDlg - - ARGUMENTS - Arguments - - - DIFF_MESHES - Arguments of operation are not correctly specified -Groups correspond to a different meshes -Please specify valid arguments and try again - - - DIFF_TYPES - Arguments of operation are not correctly specified -Groups contain elements of different types -Please specify valid arguments and try again - - - EMPTY_NAME - Name of group to be created is not valid -Please specify non-empty name and try again - - - INCORRECT_ARGUMENTS - Arguments of operation are not specified -Please specify them and try again - - - NAME - Name - - - OBJECT_1 - Object 1 - - - OBJECT_2 - Object 2 - - - RESULT_NAME - Result name - - - TOOL_OBJECT - Tool object - - - UNION_OF_TWO_GROUPS - Union of two groups - - - - SMESHGUI_UnionGroupsDlg - - UNION_OF_GROUPS - Union of groups - - - - SMESHGUI_DimGroupDlg - - CREATE_GROUP_OF_UNDERLYING_ELEMS - Create group of underlying entities - + + + GEOMETRY_OBJECT_IS_NULL + Geometry object is null + + + HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED + Hypotheses and algorithms are not defined + + + HYPOTHESIS_WITHOUT_ALGORITHM + Hypothesis is defined for %1 dimension but algorithm is not defined + + + IMPORTED_MESH + Mesh is not built on geometry + + + INVALID_SUBSHAPE + Geometry object is not a sub-shape of the shape to mesh + + + MESH_IS_NOT_DEFINED + Mesh is not defined +Please specify it and try again + + + MESH_IS_NULL + Mesh is null + + + NAME_OF_MESH_IS_EMPTY + Name of mesh is empty +Please enter valid name and try again + + + NAME_OF_SUBMESH_IS_EMPTY + Name of submesh is empty +Please enter valid name and try again + + + THERE_IS_NO_OBJECT_FOR_EDITING + There is no object for editing. Please +select mesh or sub-mesh and try again + + + + SMESHGUI_MeshPatternDlg + + 3D_BLOCK + 3D block + + + CAPTION + Pattern Mapping + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Create polyhedrons near boundary + + + CREATE_POLYGONS_NEAR_BOUNDARY + Create polygons near boundary + + + ERROR_OF_LOADING + Loading of pattern from file failed. Probably file +is corrupted or contains pattern of the other type + + + ERROR_OF_OPENING + It is impossible to open file. Please verify whether +file exists and your permission to this file + + + ERROR_OF_READING + It is impossible to load pattern +Please verify file's contents + + + ERR_READ_3D_COORD + It is impossible to load pattern +Coordinates of 3D points out of [0,1] range + + + ERR_READ_BAD_INDEX + It is impossible to load pattern +Invalid index of point detected + + + ERR_READ_BAD_KEY_POINT + It is impossible to load pattern +Key-point not on a boundary + + + ERR_READ_ELEM_POINTS + It is impossible to load pattern +invalid number of points in element + + + ERR_READ_NB_POINTS + It is impossible to load pattern +It is impossible to read number of points from file + + + ERR_READ_NO_ELEMS + It is impossible to load pattern +There are no elements in it + + + ERR_READ_NO_KEYPOINT + It is impossible to load pattern +There are no key-points in 2D one + + + ERR_READ_POINT_COORDS + It is impossible to load pattern +It is impossible to read point coordinates from file + + + ERR_READ_TOO_FEW_POINTS + It is impossible to load pattern. There are + too few points in the file for pattern loading + + + FACE + Face + + + LOAD_PATTERN + Load pattern + + + MESH_FACES + Mesh faces + + + MESH_VOLUMES + Mesh volumes + + + NEW + New... + + + NODE_1 + Node 1 + + + NODE_2 + Node 2 + + + PATTERN + Pattern + + + PATTERN_FILT + Pattern files(*.smp) + + + PATTERN_TYPE + Pattern type + + + PREVIEW + Preview + + + REFINE + Refine selected mesh elements + + + REVERSE + Reverse order of key-points + + + VERTEX + Vertex + + + VERTEX1 + Vertex 1 + + + VERTEX2 + Vertex 2 + + + + SMESHGUI_MeshTab + + ADD_HYPOTHESIS + Add. Hypothesis + + + ALGORITHM + Algorithm + + + HYPOTHESIS + Hypothesis + + + NONE + <None> + + + + SMESHGUI_MultiEditDlg + + ADD + Add + + + FILTER + Filter + + + REMOVE + Remove + + + SELECT_FROM + Select from + + + SORT_LIST + Sort list + + + SPLIT_JOIN_CRITERION + Criterion + + + TO_ALL + Apply to all + + + USE_DIAGONAL_1_3 + Use diagonal 1-3 + + + USE_DIAGONAL_2_4 + Use diagonal 2-4 + + + USE_NUMERIC_FUNC + Use numeric functor + + + + SMESHGUI_CuttingIntoTetraDlg + + CAPTION + Splitting volumes into tetrahedra + + + SPLIT_METHOD + Split hexahedron + + + SPLIT_HEX_TO_5_TETRA + Into 5 tetrahedra + + + SPLIT_HEX_TO_6_TETRA + Into 6 tetrahedra + + + SPLIT_HEX_TO_24_TETRA + Into 24 tetrahedra + + + + SMESHGUI_PrecisionDlg + + CAPTION + Precision for mesh quality controls + + + NOT_USE + Do not use + + + PRECISION + Number of digits after point + + + + SMESHGUI_RevolutionDlg + + ANGLE_BY_STEP + Angle by Step + + + PREVIEW + Preview + + + REVOLUTION_1D + Revolution of 1D elements + + + REVOLUTION_2D + Revolution of 2D elements + + + REVOLUTION_AROUND_AXIS + Revolution around an axis + + + TOTAL_ANGLE + Total Angle + + + MEN_POINT_SELECT + From Origin to selected Point + + + MEN_FACE_SELECT + Normal to selected Face + + + + SMESHGUI_SewingDlg + + BORDER + Border + + + BORDER_1 + Border 1 + + + BORDER_2 + Border 2 + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Replace affected volumes by polyedres + + + CREATE_POLYGONS_INSTEAD_SPLITTING + Create polygons instead of splitting + + + ERROR_1 + Free Border1 not found by the selected nodes + + + ERROR_2 + Free Border2 not found by the selected nodes + + + ERROR_3 + Free Border1 and Border2 not found by the selected nodes + + + ERROR_4 + No path from the first side node to the last side node have been found + + + ERROR_5 + Not allowed to splite volumes on the side! + + + ERROR_6 + Different number of elements selected on the sides + + + ERROR_7 + Element sets are topologically different or given nodes are inconvenient + + + ERROR_8 + Nodes on the side 1 are either not linked or not laying on the element set boundary + + + ERROR_9 + Nodes on the side 2 are either not linked or not laying on the element set boundary + + + FIRST_NODE_ID + First Node ID + + + LAST_NODE_ID + Last Node ID + + + MERGE_EQUAL_ELEMENTS + Merge equal elements + + + NODE1_TO_MERGE + Node 1 To Merge + + + NODE2_TO_MERGE + Node 2 To Merge + + + SECOND_NODE_ID + Second Node ID + + + SEW_BORDER_TO_SIDE + Sew Border To Side + + + SEW_CONFORM_FREE_BORDERS + Sew Conform Free Borders + + + SEW_FREE_BORDERS + Sew Free Borders + + + SEW_SIDE_ELEMENTS + Sew Side Elements + + + SIDE + Side + + + SIDE_1 + Side 1 + + + SIDE_2 + Side 2 + + + + SMESHGUI_ShapeByMeshDlg + + CAPTION + Find geometry by mesh element + + + + SMESHGUI_SingleEditDlg + + EDGE_BETWEEN + Edge between neighboring triangles + + + + SMESHGUI_SmoothingDlg + + CENTROIDAL + Centroidal + + + FIXED_NODES_IDS + Fixed nodes ids + + + IS_PARAMETRIC + in parametric space + + + ITERATION_LIMIT + Iteration limit + + + LAPLACIAN + Laplacian + + + MAX_ASPECT_RATIO + Max. aspect ratio + + + METHOD + Method + + + + SMESHGUI_TrianglesInversionDlg + + CAPTION + Diagonal inversion + + + + SMESHGUI_UnionOfTrianglesDlg + + CAPTION + Union of triangles + + + MAXIMUM_ANGLE + Maximum bending angle + + + + SMESHGUI_UnionOfTwoTrianglesDlg + + CAPTION + Union of two triangles + + + + SMESHGUI_FileInfoDlg + + CAPTION + File information + + + FILE_NAME + File name + + + FILE_SIZE + File size (bytes) + + + MED_VERSION + MED version + + + + SMESHGUI_GroupOnShapeDlg + + SMESH_CREATE_GROUP_FROM_GEOM + Create Groups from Geometry + + + + SMESHGUI_MeshOrderDlg + + SMESH_MESHORDER_TITLE + Order of submesh in meshing process + + + + SMESHGUI_MeshOrderOp + + SMESH_NO_CONCURENT_MESH + No concurent submeshes detected + + + + SMESHGUI_ClippingDlg + + CLIP_PLANES + Clipping planes + + + MESHES_SUBMESHES_GROUPS + Meshes, sub-meshes and groups + + + SELECT_ALL + Select all + + + ROTATION_AROUND_X_Y2Z + Rotation around X (Y to Z): + + + ROTATION_AROUND_Y_X2Z + Rotation around Y (X to Z): + + + ROTATION_AROUND_Z_Y2X + Rotation around Z (Y to X): + + + ROTATION_AROUND_X_Z2Y + Rotation around X (Z to Y): + + + ROTATION_AROUND_Y_Z2X + Rotation around Y (Z to X): + + + ROTATION_AROUND_Z_X2Y + Rotation around Z (X to Y): + + + SHOW_PREVIEW + Show preview + + + AUTO_APPLY + Auto Apply + + + ALONG_XY + || X-Y + + + ALONG_YZ + || Y-Z + + + ALONG_ZX + || Z-X + + + PLANE_NUM + Plane# %1 + + + NO_PLANES + No planes + + + + SMESHGUI_DuplicateNodesDlg + + DUPLICATION_MODE + Duplication mode + + + DUPLICATION_WITHOUT_ELEMS + Without duplication of border elements + + + GROUP_NODES_TO_DUPLICATE + Group of nodes to duplicate + + + GROUP_NODES_TO_REPLACE + Group of elements to replace nodes with new ones + + + DUPLICATION_WITH_ELEMS + With duplication of border elements + + + GROUP_ELEMS_TO_DUPLICATE + Group of elements to duplicate + + + GROUP_NODES_NOT_DUPLICATE + Group of nodes not to duplicate + + + GROUP_ELEMS_TO_REPLACE + Group of elements to replace nodes with new ones + + + CONSTRUCT_NEW_GROUP_NODES + Construct group with newly created nodes + + + CONSTRUCT_NEW_GROUP_ELEMENTS + Construct group with newly created elements + + + + SMESHGUI_Make2DFrom3DDlg + + CAPTION + Create boundary elements + + + Groups + Mesh or groups + + + MODE + Mode + + + 2D_FROM_3D + 2D from 3D + + + 1D_FROM_3D + 1D from 2D groups + + + 1D_FROM_2D + 1D from 2D + + + TARGET + Target + + + THIS_MESH + This mesh + + + NEW_MESH + New mesh + + + COPY_SRC + Copy source mesh + + + MISSING_ONLY + Copy missing elements only + + + CREATE_GROUP + Create group + + + + SMESHGUI_Make2DFrom3DOp + + NB_ADDED + %1 boundary elements have been added + + + WRONG_GROUPS + The following groups have not been processed +as they are of improper type: +%1 + + + SMESH_ERR_NO_INPUT_MESH + Source mesh is not specified + + + SMESH_TOO_MANY_MESHES + Only one mesh can be processed at once + + + SMESH_NOT_ONLY_GROUPS + Can't process meshes and groups at once + + + SMESH_ERR_NO_3D_ELEMENTS + The source objects do not contain 3D elements + + + SMESH_ERR_NO_2D_ELEMENTS + The source objects do not contain 2D elements + + + SMESH_ERR_MESH_NAME_NOT_SPECIFIED + New mesh name is not specified + + + SMESH_ERR_GRP_NAME_NOT_SPECIFIED + Group name is not specified + + + + SMESHGUI_MeshInfo + + NAME_LAB + Name: + + + OBJECT_LAB + Object: + + + NODES_LAB + Nodes: + + + ELEMENTS_LAB + Elements: + + + TOTAL_LAB + Total + + + LINEAR_LAB + Linear + + + QUADRATIC_LAB + Quadratic + + + 0D_LAB + 0D: + + + BALL_LAB + Balls: + + + 1D_LAB + 1D (edges): + + + 2D_LAB + 2D (faces): + + + TRIANGLES_LAB + Triangles: + + + QUADRANGLES_LAB + Quadrangles: + + + POLYGONS_LAB + Polygons: + + + 3D_LAB + 3D (volumes): + + + TETRAHEDRONS_LAB + Tetrahedrons: + + + HEXAHEDONRS_LAB + Hexahedrons: + + + PYRAMIDS_LAB + Pyramids: + + + PRISMS_LAB + Prisms: + + + HEX_PRISMS_LAB + Hexagonal Prisms: + + + POLYHEDRONS_LAB + Polyhedrons: + + + OBJECT_MESH + Mesh + + + OBJECT_SUBMESH + Sub-mesh + + + OBJECT_GROUP + Group + + + OBJECT_GROUP_NODES + Group of nodes + + + OBJECT_GROUP_EDGES + Group of edges + + + OBJECT_GROUP_FACES + Group of faces + + + OBJECT_GROUP_VOLUMES + Group of volumes + + + OBJECT_GROUP_0DELEMS + Group of 0D elements + + + OBJECT_GROUP_BALLS + Group of balls + + + BUT_LOAD_MESH + Load mesh from server + + + + SMESHGUI_MeshInfoDlg + + MESH_INFO + Mesh Information + + + BASE_INFO + Base Info + + + ELEM_INFO + Element Info + + + ADDITIONAL_INFO + Additional Info + + + NODE_MODE + Node + + + ELEM_MODE + Element + + + X_FROM_Y_ITEMS_SHOWN + %1-%2 from %3 items shown + + + + SMESHGUI_ElemInfo + + COORDINATES + COORDINATES + + + CONNECTIVITY + CONNECTIVITY + + + GRAVITY_CENTER + GRAVITY CENTER + + + NODE + NODE + + + 0D_ELEMENT + 0D ELEMENT + + + 0D_ELEMENTS + 0D ELEMENTS + + + BALL_ELEMENT + BALL ELEMENT + + + BALL_ELEMENTS + BALL ELEMENTS + + + EDGE + EDGE + + + EDGES + EDGES + + + FACE + FACE + - ELEMENTS_TYPE - Elements type - + FACES + FACES + + + VOLUME + VOLUME + + + VOLUMES + VOLUMES + + + FREE_NODE + Free node (no connectivity) + + + TYPE + TYPE + + + TRIANGLE + Triangle + + + QUADRANGLE + Quadrangle + + + POLYGON + Polygon + + + TETRAHEDRON + Tetrahedron + + + HEXAHEDRON + Hexahedron + + + PYRAMID + Pyramid + + + PRISM + Prism + + + HEX_PRISM + Hexagonal Prism + + + POLYHEDRON + Polyhedron + + + QUADRATIC + QUADRATIC + + + YES + Yes + + + NO + No + + + PROPERTY + Property + + + VALUE + Value + + + + SMESHGUI_AddInfo + + NAME + Name + + + GROUPS + Groups + + + GROUPS_1 + Nodes + + + GROUPS_2 + Edges + + + GROUPS_3 + Faces + + + GROUPS_4 + Volumes + + + GROUPS_5 + 0D elements + + + GROUPS_6 + Ball elements + + + PARENT_MESH + Parent mesh + + + TYPE + Type + + + STANDALONE_GROUP + Standalone group + + + GROUP_ON_GEOMETRY + Group on geometry + + + GROUP_ON_FILTER + Group on filter + + + GEOM_OBJECT + Shape + NODE Node - + EDGE Edge @@ -4052,662 +6599,360 @@ Please specify them and try again VOLUME Volume - - - SMESHGUI_IntersectGroupsDlg - - INTERSECTION_OF_GROUPS - Intersection of groups - - - - SMESHGUI_CutGroupsDlg - - CUT_OF_GROUPS - Cut of groups - - - MAIN_OBJECT - Main object - - - TOOL_OBJECT - Tool object - - - - SMESHGUI_MakeNodeAtPointDlg - - AUTO_SEARCH - Automatic search - - - CAPTION - Mesh to pass through a point - - - CREATE_NEW_METHOD - Create a node - - - MESH_PASS_THROUGH_POINT - Make a node at point - - - METHOD - Method - - - MOVE_EXISTING_METHOD - Move a node - - - NODE_2MOVE - Node to move - - - NODE_2MOVE_ID - ID - - - - SMESHGUI_MakeNodeAtPointOp - - INVALID_ID - Node ID is invalid - - - INVALID_MESH - Mesh to modify not selected - - - - SMESHGUI_MeshDlg - - CREATE_MESH - Create mesh - - - CREATE_SUBMESH - Create sub-mesh - - - DIM_0D - 0D - - - DIM_1D - 1D - - - DIM_2D - 2D - - - DIM_3D - 3D - - - EDIT_MESH_SUBMESH - Edit mesh/sub-mesh - - - GEOMETRY - Geometry - - - HYPOTHESES_SETS - Assign a set of hypotheses - - - MESH - Mesh - - - NAME - Name - - - - SMESHGUI_MeshOp - - ALGORITHM_WITHOUT_HYPOTHESIS - Algorithm is defined for %1 dimension but hypothesis is not defined - - - EDIT_SUBMESH_QUESTION - A submesh on the selected geometry already exists. - Do you want to edit this submesh? - - - SUBMESH_NOT_ALLOWED - No sense in creating a submesh ignored by global algorithm "%1" - - - GEOMETRY_OBJECT_IS_NOT_DEFINED - Geometry object is not defined -Please specify it and try again - - - GEOMETRY_OBJECT_IS_NULL - Geometry object is null - - - HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED - Hypotheses and algorithms are not defined - - - HYPOTHESIS_WITHOUT_ALGORITHM - Hypothesis is defined for %1 dimension but algorithm is not defined - - - IMPORTED_MESH - Mesh is not built on geometry - - - INVALID_SUBSHAPE - Geometry object is not a subshape of the shape to mesh - - - MESH_IS_NOT_DEFINED - Mesh is not defined -Please specify it and try again - - - MESH_IS_NULL - Mesh is null - - - NAME_OF_MESH_IS_EMPTY - Name of mesh is empty -Please enter valid name and try again - - - NAME_OF_SUBMESH_IS_EMPTY - Name of submesh is empty -Please enter valid name and try again - - - THERE_IS_NO_OBJECT_FOR_EDITING - There is no object for editing. Please -select mesh or sub-mesh and try again - - - - SMESHGUI_MeshPatternDlg - - 3D_BLOCK - 3D block - - - CAPTION - Pattern Mapping - - - CREATE_POLYEDRS_NEAR_BOUNDARY - Create polyhedrons near boundary - - - CREATE_POLYGONS_NEAR_BOUNDARY - Create polygons near boundary - - - ERROR_OF_LOADING - Loading of pattern from file failed. Probably file -is corrupted or contains pattern of the other type - - - ERROR_OF_OPENING - It is impossible to open file. Please verify whether -file exists and your permission to this file - - - ERROR_OF_READING - It is impossible to load pattern -Please verify file's contents - - - ERR_READ_3D_COORD - It is impossible to load pattern -Coordinates of 3D points out of [0,1] range - - - ERR_READ_BAD_INDEX - It is impossible to load pattern -Invalid index of point detected - - - ERR_READ_BAD_KEY_POINT - It is impossible to load pattern -Key-point not on a boundary - - - ERR_READ_ELEM_POINTS - It is impossible to load pattern -invalid number of points in element - - - ERR_READ_NB_POINTS - It is impossible to load pattern -It is impossible to read number of points from file - - - ERR_READ_NO_ELEMS - It is impossible to load pattern -There are no elements in it - - - ERR_READ_NO_KEYPOINT - It is impossible to load pattern -There are no key-points in 2D one - - - ERR_READ_POINT_COORDS - It is impossible to load pattern -It is impossible to read point coordinates from file - - - ERR_READ_TOO_FEW_POINTS - It is impossible to load pattern. There are - too few points in the file for pattern loading - - - FACE - Face - - - LOAD_PATTERN - Load pattern - - - MESH_FACES - Mesh faces - - - MESH_VOLUMES - Mesh volumes - - - NEW - New... - - - NODE_1 - Node 1 - - - NODE_2 - Node 2 - - - PATTERN - Pattern - - - PATTERN_FILT - Pattern files(*.smp) - - - PATTERN_TYPE - Pattern type - - - PREVIEW - Preview - - - REFINE - Refine selected mesh elements - - - REVERSE - Reverse order of key-points - - - VERTEX - Vertex - - - VERTEX1 - Vertex 1 - - - VERTEX2 - Vertex 2 - - - - SMESHGUI_MeshTab - - ADD_HYPOTHESIS - Add. Hypothesis - - - ALGORITHM - Algorithm - - - HYPOTHESIS - Hypothesis - - - NONE - <None> - - - - SMESHGUI_MoveNodesDlg - - CAPTION - Move node - - - NODE_ID_IS_NOT_DEFINED - Node ID is not defined - - - - SMESHGUI_MultiEditDlg - - ADD - Add - - - FILTER - Filter - - - REMOVE - Remove - - - SELECT_FROM - Select from - - - SORT_LIST - Sort list - - - SPLIT_JOIN_CRITERION - Criterion - - - TO_ALL - Apply to all - - - USE_DIAGONAL_1_3 - Use diagonal 1-3 - - - USE_DIAGONAL_2_4 - Use diagonal 2-4 - - - USE_NUMERIC_FUNC - Use numeric functor - - - - SMESHGUI_PrecisionDlg - - CAPTION - Precision for mesh quality controls - - - NOT_USE - Do not use - - - PRECISION - Number of digits after point - - - - SMESHGUI_RevolutionDlg - - ANGLE_BY_STEP - Angle by Step - - - PREVIEW - Preview - - - REVOLUTION_1D - Revolution of 1D elements - - - REVOLUTION_2D - Revolution of 2D elements - - - REVOLUTION_AROUND_AXIS - Revolution around an axis - - - TOTAL_ANGLE - Total Angle - - - MEN_POINT_SELECT - From Origin to selected Point - - - MEN_FACE_SELECT - Normal to selected Face - - - - SMESHGUI_SewingDlg - - BORDER - Border - - - BORDER_1 - Border 1 - - - BORDER_2 - Border 2 - - - CREATE_POLYEDRS_NEAR_BOUNDARY - Replace affected volumes by polyedres - - - CREATE_POLYGONS_INSTEAD_SPLITTING - Create polygons instead of splitting - - - ERROR_1 - Free Border1 not found by the selected nodes - - - ERROR_2 - Free Border2 not found by the selected nodes - - - ERROR_3 - Free Border1 and Border2 not found by the selected nodes - - - ERROR_4 - No path from the first side node to the last side node have been found - - - ERROR_5 - Not allowed to splite volumes on the side! - - - ERROR_6 - Different number of elements selected on the sides - - - ERROR_7 - Element sets are topologically different or given nodes are inconvenient - - - ERROR_8 - Nodes on the side 1 are either not linked or not laying on the element set boundary - - - ERROR_9 - Nodes on the side 2 are either not linked or not laying on the element set boundary - - - FIRST_NODE_ID - First Node ID - - - LAST_NODE_ID - Last Node ID - - - MERGE_EQUAL_ELEMENTS - Merge equal elements - - - NODE1_TO_MERGE - Node 1 To Merge - - - NODE2_TO_MERGE - Node 2 To Merge - - - SECOND_NODE_ID - Second Node ID - - - SEW_BORDER_TO_SIDE - Sew Border To Side - - - SEW_CONFORM_FREE_BORDERS - Sew Conform Free Borders - - - SEW_FREE_BORDERS - Sew Free Borders - - - SEW_SIDE_ELEMENTS - Sew Side Elements - - - SIDE - Side - - - SIDE_1 - Side 1 - - - SIDE_2 - Side 2 - - - - SMESHGUI_ShapeByMeshDlg - - CAPTION - Find geometry by mesh element - - - - SMESHGUI_SingleEditDlg - - EDGE_BETWEEN - Edge between neighboring triangles - - - - SMESHGUI_SmoothingDlg - - CENTROIDAL - Centroidal - - - FIXED_NODES_IDS - Fixed nodes ids - - - IS_PARAMETRIC - in parametric space - - - ITERATION_LIMIT - Iteration limit - - - LAPLACIAN - Laplacian - - - MAX_ASPECT_RATIO - Max. aspect ratio - - - METHOD - Method - - - - SMESHGUI_TrianglesInversionDlg - - CAPTION - Diagonal inversion - - - - SMESHGUI_UnionOfTrianglesDlg - - CAPTION - Union of triangles - - - MAXIMUM_ANGLE - Maximum bending angle - - - - SMESHGUI_UnionOfTwoTrianglesDlg - - CAPTION - Union of two triangles - - - - SMESHGUI_WhatIsDlg - - ENTITY_TYPE - Element type - - - GRAVITY_CENTER - Gravity center - - - - SMESHGUI_FileInfoDlg - - CAPTION - File information - - - FILE_NAME - File name - - - FILE_SIZE - File size (bytes) - - - MED_VERSION - MED version - - + + 0DELEM + 0D element + + + BALL_ELEMENT + ball + + + UNKNOWN + Unknown + + + ENTITY_TYPE + Entity type + + + SIZE + Size + + + COLOR + Color + + + NB_NODES + Underlying nodes + + + COMPUTE + Compute + + + LOAD + Load + + + MESH_ON_GEOMETRY + Based on geometry + + + MESH_FROM_FILE + Imported + + + FILE_NAME + File name + + + STANDALONE_MESH + Standalone + + + SUBMESHES + Sub-meshes + + + SUBMESHES_0 + Compound + + + SUBMESHES_2 + Solid + + + SUBMESHES_3 + Shell + + + SUBMESHES_4 + Face + + + SUBMESHES_5 + Wire + + + SUBMESHES_6 + Edge + + + SUBMESHES_7 + Vertex + + + + SMESHGUI_MinDistance + + FIRST_TARGET + First target + + + SECOND_TARGET + Second target + + + NODE + Node + + + ELEMENT + Element + + + OBJECT + Object + + + ORIGIN + Origin + + + COMPUTE + Compute + + + RESULT + Distance between targets + + + DISTANCE + Distance + + + + SMESHGUI_CopyMeshDlg + + OBJECT_NAME + Source Object + + + ELEM_IDS + Source Element IDs + + + NEW_NAME + New Mesh Name + + + + SMESHGUI_MeasureDlg + + MEASUREMENTS + Measurements + + + MIN_DIST + Minimum Distance + + + BND_BOX + Bounding Box + + + + SMESHGUI_BoundingBox + + SOURCE + Source + + + OBJECTS + Objects + + + NODES + Nodes + + + ELEMENTS + Elements + + + COMPUTE + Compute + + + RESULT + Bounding Box + + + SELECTED_NB_OBJ + %1 %2 selected + + + NB_NODES + nodes + + + NB_ELEMENTS + elements + + + + SMESHGUI_MeshLoadingProgress + + MESH_LOAD_PROGRESS_TITLE + Mesh Loading + + + + StdMeshersGUI_SubShapeSelectorWdg + + X_FROM_Y_ITEMS_SHOWN + %1-%2 from %3 items shown + + + + SMESHGUI_Preferences_ColorDlg + + DIALOG_TITLE + Properties (color, line width, shrink size, ...) + + + GRP_ELEMENTS + Elements + + + SURFACE_COLOR_LBL + Surface color + + + BACKSURFACE_COLOR_LBL + Back surface color + + + OUTLINE_COLOR_LBL + Outline color + + + WIREFRAME_COLOR_LBL + Wireframe color + + + 0D_ELEMENTS_COLOR_LBL + 0D elements + + + 0D_ELEMENTS_SIZE_LBL + Size of 0D elements + + + BALL_ELEMENTS_COLOR_LBL + Ball elements + + + BALL_ELEMENTS_SIZE_LBL + Size of balls + + + LINE_WIDTH_LBL + Line width + + + SHRINK_COEF_LBL + Shrink coef. + + + GRP_NODES + Nodes + + + NODES_COLOR_LBL + Color + + + NODES_MARKER_LBL + Marker + + + GRP_ORIENTATION + Orientation of faces + + + ORIENTATION_COLOR_LBL + Color + + + ORIENTATION_SCALE_LBL + Scale + + + 3D_VECTORS_LBL + 3D vectors + + + GRP_SELECTION + Selection + + + SELECTION_COLOR_LBL + Selection color + + + PRESELECTION_COLOR_LBL + Pre-selection color + + + + SMESHGUI_ReorientFacesDlg + + CAPTION + Reorient faces by vector + + + REORIENT_FACES + Reorient + + + DIRECTION + Direction + + + OBJECT + Object + + + POINT + Point + + + FACE + Face + + + FACES + Faces source + + + ORIENTATION + Orientation + + + + SMESHGUI_ReorientFacesOp + + NO_OBJECT_SELECTED + No object selected + + + NO_FACES + Object includes no faces + + + ZERO_SIZE_VECTOR + Zero size vector + + + INVALID_FACE + Not valid face + + + NB_REORIENTED + %1 faces reversed + + diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts new file mode 100755 index 000000000..1672f6fbc --- /dev/null +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -0,0 +1,6968 @@ + + + + + @default + + SMESH_EXPORT_MESH + Exporter le maillage + + + MED_FILES_FILTER + Fichiers MED + + + IDEAS_FILES_FILTER + Fichiers IDEAS + + + DAT_FILES_FILTER + Fichiers DAT + + + TEXT_FILES_FILTER + Fichiers TXT + + + MED_VX_FILES_FILTER + Fichiers MED %1 + + + STL_ASCII_FILES_FILTER + Fichiers STL ASCII + + + CGNS_FILES_FILTER + Fichiers CGNS + + + STL_BIN_FILES_FILTER + Fichiers STL binaires + + + ALL_FILES_FILTER + Tous les fichiers + + + SMESH_AND + et + + + AREA_ELEMENTS + Aire + + + ASPECTRATIO_3D_ELEMENTS + Rapport de forme 3D + + + ASPECTRATIO_ELEMENTS + Rapport de forme + + + NODE_POSITION + Position + + + U_POSITION + U + + + V_POSITION + V + + + COL_ALGO_HEADER + Algorithme + + + COL_ERROR_HEADER + Erreur + + + COL_SHAPE_HEADER + SousObjet + + + COMPERR_ALGO_FAILED + L'algorithme n'a pas abouti + + + COMPERR_BAD_INPUT_MESH + Le maillage d'entrée est invalide + + + COMPERR_BAD_SHAPE + Géométrie inattendue + + + COMPERR_EXCEPTION + Exception inconnue + + + COMPERR_MEMORY_PB + Problème d'affectation de la mémoire + + + COMPERR_OCC_EXCEPTION + Exception OCC + + + COMPERR_OK + Pas d'erreur + + + COMPERR_SLM_EXCEPTION + Exception SALOME + + + COMPERR_STD_EXCEPTION + std::exception + + + COMPERR_UNKNOWN + Erreur inconnue + + + COMPERR_CANCELED + Calcul annulé + + + SMESH_GEOM + Géométrie + + + DIRECT_GEOM_SELECTION + Sélection directe de la géométrie + + + ELEMENT_ID + ID de l'élément + + + FREE_BORDERS + Frontières libres + + + GEOMETRY_NAME + Nom de la géométrie + + + GEOM_BY_MESH_ELEM_SELECTION + Trouver la géométrie en choisissant l'élément de maillage + + + GLOBAL_ALGO + Global + + + INF_SELECT_OBJECT + Choisir un objet + + + LENGTH2D_EDGES + Longueur 2D + + + LENGTH_EDGES + Longueur + + + LOCAL_ALGO + Local + + + MAX_ELEMENT_LENGTH_2D + Diamètre d'éléments 2D + + + MAX_ELEMENT_LENGTH_3D + Diamètre d'éléments 3D + + + MEN_ADD + Ajouter + + + MEN_ADV_INFO + Informations sur le maillage + + + MEN_ALL + Tous + + + MEN_AREA + Aire + + + MEN_ASPECT + Rapport de forme + + + MEN_ASPECT_3D + Rapport de forme 3D + + + MEN_AUTO_COLOR + Couleur automatique + + + MEN_AUTO_UPD + Mise à jour automatique + + + MEN_BUILD_COMPOUND + Construire un assemblage + + + MEN_COPY_MESH + Copier le maillage + + + MEN_CLIP + Plan de coupe + + + MEN_COLORS + Paramètres d'affichage + + + MEN_COMPUTE + Calculer + + + MEN_PRECOMPUTE + Prévisualiser + + + MEN_EVALUATE + Evaluer + + + MEN_CONNECTION + Frontières sur connexions multiples + + + MEN_CONNECTION_2D + Frontières sur connexions multiples 2D + + + MEN_CONSTRUCT_GROUP + Construire un groupe + + + MEN_CONV_TO_QUAD + Convertir vers/de quadratique + + + MEN_2D_FROM_3D + Créer les éléments de frontière + + + MEN_MESH_ORDER + Changer la priorité des sous-maillages + + + MEN_CREATE_GROUP + Créer un groupe + + + MEN_CREATE_GEO_GROUP + Créer des groupes à partir de la géométrie + + + MEN_CREATE_MESH + Créer un maillage + + + MEN_CREATE_SUBMESH + Créer un sous-maillage + + + MEN_CTRL + Contrôles + + + MEN_NODE_CTRL + Contrôles des nœuds + + + MEN_EDGE_CTRL + Contrôles des arêtes + + + MEN_FACE_CTRL + Contrôles des faces + + + MEN_VOLUME_CTRL + Contrôles des volumes + + + MEN_CUT + Découpe des quadrangles + + + MEN_CUT_GROUP + Découpe des groupes + + + MEN_IMPORT_DAT + Fichier DAT + + + MEN_DAT + Fichier DAT + + + MEN_DELETE + Supprimer + + + MEN_DEL_GROUP + Supprimer les groupes et leur contenu + + + MEN_FACE_ORIENTATION + Orientation des faces + + + MEN_DISABLE_AUTO_COLOR + Désactiver la couleur automatique + + + MEN_DISPLAY_ONLY + Afficher uniquement + + + MEN_DISPMODE + Mode de visualisation + + + MEN_DISP_ENT + Montrer l'entité + + + MEN_ELEM0D + Elément 0D + + + MEN_ELEMS0D + Eléments 0D + + + MEN_BALL + Particulaire + + + MEN_BALLS + Particulaires + + + MEN_EDGE + Arête + + + MEN_EDGES + Arêtes + + + MEN_EDIT + Edition + + + MEN_EDIT_GROUP + Editer un groupe + + + MEN_EDIT_GEOMGROUP_AS_GROUP + Editer un groupe en tant qu'autonome + + + MEN_EDIT_HYPO + Editer une hypothèse + + + MEN_EDIT_MESHSUBMESH + Editer un maillage/sous-maillage + + + MEN_EXPORT + Exporter + + + MEN_EXPORT_DAT + Exporter au format DAT + + + MEN_EXPORT_MED + Exporter au format MED + + + MEN_EXPORT_CGNS + Exporter au format CGNS + + + MEN_EXPORT_SAUV + Exporter au format SAUV (ASCII) + + + MEN_EXPORT_STL + Exporter au format STL + + + MEN_EXPORT_UNV + Exporter au format UNV + + + MEN_EXTRUSION + Extrusion + + + MEN_EXTRUSION_ALONG + Extrusion suivant un chemin + + + MEN_FACES + Faces + + + MEN_FILE + Fichier + + + MEN_FIND_ELEM + Trouver un élément par un point + + + TOP_REORIENT_2D + Réorienter des faces selon un vecteur + + + MEN_REORIENT_2D + Réorienter des faces selon un vecteur + + + STB_REORIENT_2D + Réorienter des faces selon un vecteur + + + TOP_FIND_ELEM + Trouver un élément par un point + + + STB_FIND_ELEM + Trouver un élément par un point + + + EQUAL_NODE + Nœuds en double + + + MEN_EQUAL_NODE + Nœuds en double + + + STB_EQUAL_NODE + Nœuds en double + + + TOP_EQUAL_NODE + Nœuds en double + + + EQUAL_EDGE + Arêtes en double + + + MEN_EQUAL_EDGE + Arêtes en double + + + STB_EQUAL_EDGE + Arêtes en double + + + TOP_EQUAL_EDGE + Arêtes en double + + + EQUAL_FACE + Faces en double + + + MEN_EQUAL_FACE + Faces en double + + + STB_EQUAL_FACE + Faces en double + + + TOP_EQUAL_FACE + Faces en double + + + EQUAL_VOLUME + Volumes en double + + + MEN_EQUAL_VOLUME + Volumes en double + + + STB_EQUAL_VOLUME + Volumes en double + + + TOP_EQUAL_VOLUME + Volumes en double + + + MEN_BARE_BORDER_VOLUME + Volumes avec éléments de peau 2D manquants + + + MEN_BARE_BORDER_FACE + Faces avec éléments de peau 1D manquants + + + MEN_OVER_CONSTRAINED_VOLUME + Volumes sur-contraints + + + MEN_OVER_CONSTRAINED_FACE + Faces sur-contraintes + + + MEN_FREE_BORDER + Frontières libres + + + MEN_FREE_EDGE + Arêtes libres + + + MEN_FREE_NODE + Nœuds libres + + + MEN_FREE_FACES + Faces libres + + + MEN_GLOBAL_HYPO + Hypothèse globale + + + MEN_HEXA + Hexaèdre + + + MEN_HIDE + Cacher + + + MEN_HYPO + Hypothèses + + + MEN_IMPORT + Importer + + + MEN_INT_GROUP + Intersection des groupes + + + MEN_INV + Inversion de diagonale + + + MEN_LENGTH + Longueur + + + MEN_LENGTH_2D + Longueur 2D + + + MEN_MAP + Projection de motif + + + MEN_MAX_ELEMENT_LENGTH_2D + Diamètre des éléments 2D + + + MEN_MAX_ELEMENT_LENGTH_3D + Diamètre des éléments 3D + + + MEN_IMPORT_MED + Fichier MED + + + MEN_MED + Fichier MED + + + MEN_IMPORT_CGNS + Fichier CGNS + + + MEN_CGNS + Fichier CGNS + + + MEN_IMPORT_SAUV + Fichier SAUV (ASCII) + + + MEN_SAUV + Fichier SAUV (ASCII) + + + MEN_MERGE + Fusionner les nœuds + + + MEN_MERGE_ELEMENTS + Fusionner les éléments + + + MEN_MESH + Maillage + + + MEN_MESH_THROU_POINT + Déplacer un nœud + + + MEN_MIN_ANG + Angle minimal + + + MEN_MODIFY + Modification + + + MEN_MEASURE + Outils de mesure + + + MEN_MEASURE_MIN_DIST + Distance minimale + + + STB_MEASURE_MIN_DIST + Calcule la distance minimum entre deux objets + + + TOP_MEASURE_MIN_DIST + Distance minimum + + + MEN_MEASURE_BND_BOX + Boîte englobante + + + STB_MEASURE_BND_BOX + Calcule la boîte englobante pour le(s) objet(s) sélectionné(s) + + + TOP_MEASURE_BND_BOX + Boîte englobante + + + MEN_MOVE + Déplacer un nœud + + + MEN_NODE + Nœud + + + MEN_NODES + Nœuds + + + MEN_NUM + Numérotation + + + MEN_NUM_ELEMENTS + Montrer les n° des éléments + + + MEN_NUM_NODES + Montrer les n° des nœuds + + + MEN_ORIENT + Orientation + + + MEN_POLYGON + Polygone + + + MEN_POLYHEDRON + Polyèdre + + + MEN_PRECISION + Précision + + + MEN_PREF + Préférences + + + MEN_QUAD + Quadrangle + + + MEN_QUADRATIC_EDGE + Arête quadratique + + + MEN_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + MEN_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + MEN_QUADRATIC_PYRAMID + Pyramide quadratique + + + MEN_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + MEN_QUADRATIC_TETRAHEDRON + Tétraèdre quadratique + + + MEN_QUADRATIC_TRIANGLE + Triangle quadratique + + + MEN_QUALITY + Contrôles de qualité + + + MEN_REMOVE + Supprimer + + + MEN_REMOVE_ELEMENTS + Eléments + + + MEN_REMOVE_NODES + Nœuds + + + MEN_REMOVE_ORPHAN_NODES + Nœuds orphelins + + + MEN_RENAME + Renommer + + + MEN_RENUM + Renuméroter + + + MEN_RENUM_ELEMENTS + Eléments + + + MEN_RENUM_NODES + Nœuds + + + MEN_RESET + Restaurer + + + MEN_DISTRIBUTION_CTRL + Distribution + + + MEN_SAVE_DISTRIBUTION + Exporter la distribution... + + + MEN_SHOW_DISTRIBUTION + Afficher la distribution + + + MEN_PLOT_DISTRIBUTION + Tracer + + + DISTRIBUTION_NB_ENT + TODO + + + MEN_REVOLUTION + Révolution + + + MEN_ROT + Rotation + + + MEN_SCALAR_BAR + Barre scalaire + + + MEN_SCALAR_BAR_PROP + Propriétés de la barre scalaire + + + MEN_SELECTION + Sélection + + + MEN_SEL_FILTER_LIB + Librairie des filtres de sélection + + + MEN_SEW + Couture + + + MEN_SHADE + Ombrage + + + MEN_QUADRATIC_REPRESENT + Quadratique 2D + + + MEN_LINE_REPRESENTATION + Lignes + + + MEN_ARC_REPRESENTATION + Arcs + + + MEN_SHOW + Afficher + + + MEN_SHRINK + Contraction + + + MEN_SKEW + Inclinaison d'angle + + + MEN_SMOOTH + Lissage + + + MEN_STD_INFO + Informations sur le maillage + + + MEN_IMPORT_STL + Fichier STL + + + MEN_STL + Fichier STL + + + MEN_SYM + Symétrie + + + MEN_TAPER + Cône + + + MEN_TETRA + Tétraèdre + + + MEN_TOOLS + Outils + + + MEN_TRANS + Translation + + + MEN_SCALE + Transformation d'échelle + + + MEN_DUPLICATE_NODES + Dupliquer les nœuds + + + MEN_TRANSF + Transformation + + + MEN_TRANSP + Transparence + + + MEN_TRIANGLE + Triangle + + + MEN_UNASSIGN + Désassocier + + + MEN_UNION + Union des triangles + + + MEN_UNION2 + Union de deux triangles + + + MEN_IMPORT_UNV + Fichier UNV + + + MEN_UNV + Fichier UNV + + + MEN_UN_GROUP + Union des groupes + + + MEN_UNDERLYING_ELEMS + Groupe des entités sous-jacentes + + + MEN_UPDATE + Mettre à jour + + + MEN_VIEW + Affichage + + + MEN_VOLUMES + Volumes + + + MEN_VOLUME_3D + Volume + + + MEN_WARP + Angle de déformation + + + MEN_WHAT_IS + Information sur un élément de maillage + + + MEN_WIRE + Contours + + + MEN_SPLIT_TO_TETRA + Explosion en tétraèdres + + + TOP_SPLIT_TO_TETRA + Eclater en tétraèdres + + + STB_SPLIT_TO_TETRA + Eclater en tétraèdres + + + MESHERS_FILE_CANT_OPEN + Impossible d'ouvrir le fichier de ressource + + + MESHERS_FILE_CHECK_VARIABLE + Vérifier la variable d'environnement SMESH_MeshersList + + + MESHERS_FILE_NO_VARIABLE + La variable d'environnement SMESH_MeshersList n'est pas définie + + + MESH_IS_NOT_SELECTED + Il n'y a pas de maillage sélectionné. +Choisissez un maillage et essayez de nouveau + + + MESH_NODE + Nœud + + + MESH_NODE_TITLE + Ajouter un nœud + + + MINIMUMANGLE_ELEMENTS + Angle minimal + + + MULTI2D_BORDERS + Frontières sur multi-connexions 2D + + + MULTI_BORDERS + Frontières sur multi-connexions + + + GROUP_NAME_IS_EMPTY + Le nom du groupe n'est pas indiqué. +Indiquez le nom d'un nouveau groupe à créer ou choisissez un groupe existant. + + + MESH_STANDALONE_GRP_CHOSEN + Un groupe lié à la géométrie est choisi: %1. +Voulez-vous le convertir en un groupe autonome ? + + + NODE_ID + ID du nœud + + + NON_SMESH_OBJECTS_SELECTED + Certains objets sélectionnés n'appartiennent pas au composant %1. + + + PREVIEW + Prévisualiser + + + SKEW_ELEMENTS + Inclinaison d'angle + + + SMESHGUI_INVALID_PARAMETERS + Les paramètres spécifiés ne sont pas corrects. +Merci de les corriger, puis essayez de nouveau + + + SMESH_ADD_ALGORITHM + Algorithmes + + + SMESH_ADD_ALGORITHM_TITLE + Attribution des algorithmes + + + SMESH_ADD_ELEM0D + Ajouter un élément 0D + + + SMESH_ADD_ELEM0D_TITLE + Ajouter un élément 0D + + + SMESH_ADD_BALL + Ajouter un élément particulaire + + + SMESH_ADD_BALL_TITLE + Ajouter un élément particulaire + + + SMESH_ADD_EDGE + Ajouter une arête + + + SMESH_ADD_EDGE_TITLE + Ajouter une arête + + + SMESH_ADD_HEXAS + Ajouter un hexaèdre + + + SMESH_ADD_HEXAS_TITLE + Ajouter un hexaèdre + + + SMESH_ADD_HYPOTHESIS + Hypothèse + + + SMESH_ADD_HYPOTHESIS_TITLE + Attribution d'une hypothèse + + + SMESH_ADD_HYP_WRN + "%1" est attribué, mais: + + + + SMESH_ADD_OCTA + Ajouter un prisme hexagonale + + + SMESH_ADD_OCTA_TITLE + Ajouter un prisme hexagonale + + + SMESH_ADD_POLYGON + Ajouter un polygone + + + SMESH_ADD_POLYGON_TITLE + Ajouter un polygone + + + SMESH_ADD_PENTA + Ajouter un pentaèdre + + + SMESH_ADD_PENTA_TITLE + Ajouter un pentaèdre + + + SMESH_ADD_PYRAMID + Ajouter une pyramide + + + SMESH_ADD_PYRAMID_TITLE + Ajouter une pyramide + + + SMESH_ADD_QUADRANGLE + Ajouter un quadrangle + + + SMESH_ADD_QUADRANGLE_TITLE + Ajouter un quadrangle + + + SMESH_ADD_QUADRATIC_EDGE_TITLE + Ajouter une arête quadratique + + + SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE + Ajouter un hexaèdre quadratique + + + SMESH_ADD_TRIQUADRATIC_HEXAHEDRON_TITLE + Ajouter un hexaèdre triquadratique + + + SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE + Ajouter un pentaèdre quadratique + + + SMESH_ADD_QUADRATIC_PYRAMID_TITLE + Ajouter une pyramide quadratique + + + SMESH_ADD_BIQUADRATIC_QUADRANGLE_TITLE + Ajouter un quadrangle biquadratique + + + SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE + Ajouter un quadrangle quadratique + + + SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE + Ajouter un tétraèdre quadratique + + + SMESH_ADD_QUADRATIC_TRIANGLE_TITLE + Ajouter un triangle quadratique + + + SMESH_ADD_SUBMESH + Construction d'un sous-maillage + + + SMESH_ADD_TETRAS + Ajouter un tétraèdre + + + SMESH_ADD_TETRAS_TITLE + Ajouter un tétraèdre + + + SMESH_ADD_TO_GROUP + Ajouter à un groupe + + + SMESH_ADD_TRIANGLE + Ajouter un triangle + + + SMESH_ADD_TRIANGLE_TITLE + Ajouter un triangle + + + SMESH_ANGLE + Angle + + + SMESH_ARGUMENTS + Arguments + + + SMESH_AUTO_GROUPS + Créer les groupes automatiquement + + + SMESH_AVAILABLE + Disponible + + + SMESH_AVAILABLE_ALGORITHMS + Algorithmes disponibles + + + SMESH_AVAILABLE_HYPOTHESES + Hypothèses disponibles + + + SMESH_AXIS + Axe + + + SMESH_BAD_SELECTION + Pas de sélection valide + + + SMESH_BAD_MESH_SELECTION + La sélection du maillage n'est pas valide + + + SMESH_BOUNDARYEDGES + Arêtes frontières + + + SMESH_BUILD_COMPOUND_TITLE + Créer un assemblage + + + SMESH_COPY_MESH_TITLE + Copier le maillage + + + SMESH_KEEP_IDS + Conserver les IDs des éléments + + + SMESH_BUT_ADD + A&jouter + + + SMESH_BUT_APPLY + A&ppliquer + + + SMESH_BUT_CANCEL + A&nnuler + + + SMESH_BUT_CLOSE + &Fermer + + + SMESH_BUT_CREATE + &Créer + + + SMESH_BUT_DELETE + Eff&acer + + + SMESH_BUT_FILTER + Définir les fil&tres + + + SMESH_BUT_HELP + Ai&de + + + SMESH_BUT_NEW + Nou&veau + + + SMESH_BUT_NO + &Non + + + SMESH_BUT_OK + &Ok + + + SMESH_BUT_OVERWRITE + Réécr&ire + + + SMESH_BUT_APPLY_AND_CLOSE + App&liquer et fermer + + + SMESH_BUT_REMOVE + S&upprimer + + + SMESH_BUT_SORT + &Trier la liste + + + SMESH_BUT_YES + &Oui + + + SMESH_CANT_ADD_HYP + Impossible d'attribuer "%1": + + + + SMESH_CANT_RM_HYP + Impossible de désassigner "%1": + + + + SMESH_CHECK_COLOR + Couleur + + + SMESH_CLIPPING_FROM + De <--- + + + SMESH_CLIPPING_INTO + ---> En + + + SMESH_CLIPPING_TITLE + Changer le plan de coupe + + + SMESH_COMPUTE_SUCCEED + Le calcul du maillage a réussi + + + SMESH_EVALUATE_SUCCEED + L'évaluation du maillage a réussi + + + SMESH_CONTENT + Contenu + + + SMESH_CONTINUE_MESH_VISUALIZATION + La système semble manquer de mémoire pour visualiser le maillage, +ce qui peut faire planter l'application. Voulez-vous continuer la visualisation ? + + + SMESH_COORDINATES + Coordonnées + + + SMESH_COPY_ELEMENTS + Copier les éléments + + + SMESH_COPY_GROUPS + Copier les groupes + + + SMESH_CREATE_ALGORITHMS + Créer les algorithmes + + + SMESH_CREATE_COPY + Créer une copie + + + SMESH_CREATE_GROUP_TITLE + Créer un groupe + + + SMESH_CREATE_GEO_GROUP + Créer des groupes liés à la géométrie + + + SMESH_CREATE_HYPOTHESES + Créer une hypothèse + + + SMESH_CREATE_MESH + Créer un nouveau maillage + + + SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE + Créer un volume polyèdrique + + + SMESH_DIAGONAL + Inversion de diagonale + + + SMESH_DIAGONAL_INVERSION_TITLE + Inversion de diagonale + + + SMESH_DISTANCE + Distance + + + SMESH_DRS_1 + Le fichier MED contient pas de maillage avec ce nom + + + SMESH_DRS_2 + Le fichier MED contient des rangées de nombre d'éléments superposées, donc les nombres de ce fichier ne sont pas pris en compte + + + SMESH_DRS_3 + Quelques éléments ont été omis à cause du fichier de données incorrect + + + SMESH_DRS_4 + Le fichier n'est pas correct, des données sont manquantes + + + SMESH_DRS_EMPTY + Le fichier est vide, il n'y a rien à publier + + + SMESH_DX + dX + + + SMESH_DY + dY + + + SMESH_DZ + dZ + + + SMESH_ELEM0D + Elément 0D + + + SMESH_ELEMS0D + Eléments 0D + + + SMESH_BALL_ELEM + Particulaire + + + SMESH_BALL + Particulaire + + + SMESH_BALLS + Particulaires + + + SMESH_EDGE + Arête + + + SMESH_EDGES + Arêtes + + + SMESH_EDGES_CONNECTIVITY_TITLE + Connectivité des arêtes + + + SMESH_EDIT_GROUP_TITLE + Editer un groupe + + + SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE + Editer un groupe en tant qu'autonome + + + SMESH_EDIT_HYPOTHESES + Attribuer les hypothèses + + + SMESH_EDIT_USED + Utilisé + + + SMESH_ELEMENTS + Eléments + + + SMESH_ELEMENTS_COLOR + Couleur des éléments du maillage + + + SMESH_ELEMENTS_TYPE + Type des éléments + + + SMESH_ELEMENT_TYPE + Type de l'élément + + + SMESH_ERROR + Erreur + + + SMESH_ERR_SCALARBAR_PARAMS + Avertissement! Les paramètres ne sont pas corrects + + + SMESH_EXPORT_FAILED + Impossible d'exporter le maillage. +Vérifiez l'espace disponible sur le disque. + + + SMESH_EXPORT_MED_DUPLICATED_GRP + Il y a des noms de groupes dupliqués dans le maillage "%1". +Vous pouvez annuler l'exportation et les renommer, +si non des noms de groupes au fichier MED résultant +ne correspondront pas aux noms de l'étude. +Voulez-vous continuer ? + + + SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES + Il y a des maillages avec les mêmes noms dans la sélection. +Il est possible que le fichier résultant soit incorrect. +Voulez-vous continuer ? + + + SMESH_EXPORT_MED_V2_1 + Les éléments polygonaux et polyèdriques seront omis +dans le cas d'exportation du maillage "%1" à MED 2.1 +Utilisez MED 2.2 pour l'exportation correcte. +Voulez-vous effectuer l'exportation à MED 2.1 ? + + + SMESH_EXPORT_MED_VERSION_COLLISION + La version MED du fichier "%1" n'est pas connue +ou ne correspond pas à la version choisie. +Réécrire le fichier ? + + + SMESH_EXPORT_MED_MESH_NAMES_COLLISION + Le fichier choisi contient déjà +les maillages avec les noms suivants: %1 +Il est possible que le fichier résultant ne soit pas correct. +Réécrire le fichier ? + + + SMESH_EXPORT_STL1 + Le maillage - "%1" ne contient pas de triangles + + + SMESH_EXPORT_STL2 + Le maillage - "%1" contient d'autres éléments que les triangles, ils ne seront donc pas enregistrés dans le fichier STL + + + SMESH_EXPORT_UNV + Les éléments pyramides seront omis au cours de l'exportation +du maillage "%1" dans le fichier UNV + + + EXPORT_NOT_SUPPORTED + A l'export du maillage avec le nom "%1" vers %2 +%3 sera ignoré. +Voulez-vous continuer ? + + + SMESH_EXTRUSION + Extrusion + + + SMESH_EXTRUSION_TO_DISTANCE + Distance de l'extrusion + + + SMESH_EXTRUSION_ALONG_VECTOR + Extrusion le long du vecteur + + + SMESH_FACE + Face + + + SMESH_FEATUREANGLE + Montrer l'angle + + + SMESH_FEATUREEDGES + Montrer les arêtes + + + SMESH_FILE_EXISTS + Le fichier "%1" existe déjà. +Voulez-vous le réécrire ou y ajouter +les données exportées ? + + + SMESH_FONT_ARIAL + Arial + + + SMESH_FONT_BOLD + Gras + + + SMESH_FONT_COURIER + Courrier + + + SMESH_FONT_ITALIC + Italique + + + SMESH_FONT_SCALARBAR + Police + + + SMESH_FONT_SHADOW + Ombrage + + + SMESH_FONT_TIMES + Times + + + SMESH_GEOM_GROUP + Groupe géométrique + + + SMESH_GROUP + Groupe + + + SMESH_GROUP_GEOMETRY + Groupe lié à une géométrie + + + SMESH_GROUP_FILTER + Groupe lié à un filtre + + + SMESH_GROUP_SELECTED + %1 groupes + + + SMESH_GROUP_STANDALONE + Groupe autonome + + + SMESH_GROUP_TYPE + Type du groupe + + + SMESH_HEIGHT + Hauteur : + + + SMESH_HEXAS + Hexaèdre + + + SMESH_HEXAHEDRA + Hexaèdres + + + SMESH_HILIGHT_COLOR + Couleur de sélection + + + SMESH_HORIZONTAL + Horizontale + + + SMESH_HYPOTHESES + Hypothèses + + + SMESH_HYP_1 + Il manque une hypothèse à l'algorithme + + + SMESH_HYP_10 + L'hypothèse ne correspond pas aux dimensions du sous-maillage + + + SMESH_HYP_11 + La géométrie n'est ni la géométrie principale, ni un de ses sous-objets, ni un groupe valide + + + SMESH_HYP_12 + La géométrie ne correspond pas à l'algorithme +Référez-vous à la documentation sur l'algorithme et la géométrie supportée + + + SMESH_HYP_13 + L'algorithme ne peut pas opérer sans géométrie + + + SMESH_HYP_2 + Il y a des hypothèses concurrentes sur la géométrie + + + SMESH_HYP_3 + L'hypothèse contient une valeur de paramètre incorrecte + + + SMESH_HYP_4 + Le sous-maillage n'est pas pris en compte parce qu'il y a un algorithme de dimension supérieure pour générer les éléments %1D + + + SMESH_HYP_5 + L'algorithme l'emporte sur les algorithme(s) de dimensions inférieures en générant les éléments de toutes les dimensions + + + SMESH_HYP_6 + Erreur critique inconnue lors de la définition de l'hypothèse + + + SMESH_HYP_7 + L'hypothèse ne correspond pas à la situation actuelle + + + SMESH_HYP_8 + Un maillage non-conforme a été produit avec les hypothèses appliquées + + + SMESH_HYP_9 + L'hypothèse d'une telle dimension est déjà attribuée à la géométrie + + + SMESH_ID_DIAGONAL + IDs des arêtes + + + SMESH_ID_ELEMENTS + IDs des éléments + + + SMESH_ID_FACES + IDs des faces + + + SMESH_ID_NODES + IDs des nœuds + + + SMESH_INCORRECT_INPUT + Les données d'entrée ne sont pas correctes + + + SMESH_INFORMATION + Information + + + SMESH_INIT + Maillage + + + SMESH_INIT_MESH + Construction du maillage + + + SMESH_INSUFFICIENT_DATA + La valeur d'entrée n'est pas suffisante + + + SMESH_LABELS + Etiquettes : + + + SMESH_LABELS_COLORS_SCALARBAR + Couleurs && étiquettes + + + SMESH_LENGTH + Longueur + + + SMESH_MAKE_GROUPS + Générer les groupes + + + SMESH_MANIFOLDEDGES + Arêtes partagées + + + SMESH_MAX + Max + + + SMESH_MEN_ALGORITHMS + Algorithmes + + + SMESH_MEN_APPLIED_ALGORIHTMS + Algorithmes appliqués + + + SMESH_MEN_APPLIED_HYPOTHESIS + Hypothèses appliquées + + + SMESH_MEN_COMPONENT + SMESH + + + SMESH_MEN_HYPOTHESIS + Hypothèses + + + SMESH_MEN_SubMeshesOnCompound + Sous-maillages sur un assemblage + + + SMESH_MEN_SubMeshesOnEdge + Sous-maillages sur une arête + + + SMESH_MEN_SubMeshesOnFace + Sous-maillages sur une face + + + SMESH_MEN_SubMeshesOnSolid + Sous-maillages sur un solide + + + SMESH_MEN_SubMeshesOnVertex + Sous-maillages sur un point + + + SMESH_AUTOMATIC + Automatique + + + SMESH_MANUAL + Manuel + + + SMESH_MERGE_ELEMENTS + Fusionner les éléments + + + SMESH_MODE + Mode + + + SMESH_MERGED_ELEMENTS + %1 éléments fusionnés avec succès + + + SMESH_MERGED_NODES + %1 nœuds fusionnés avec succès + + + SMESH_NO_ELEMENTS_DETECTED + Il n'y a aucun élément à fusionner. + + + SMESH_NO_NODES_DETECTED + Il n'y a aucun nœud à fusionner + + + SMESH_MERGE_NODES + Fusionner les nœuds + + + SMESH_MESH + Maillage + + + SMESH_MESHINFO_0DELEMS + Eléments 0D + + + SMESH_MESHINFO_BALLS + Particulaires + + + SMESH_MESHINFO_ALL_TYPES + Hétérogène + + + SMESH_MESHINFO_EDGES + Arêtes + + + SMESH_MESHINFO_ELEMENTS + Eléments + + + SMESH_MESHINFO_ENTITIES + Entités + + + SMESH_MESHINFO_FACES + Faces + + + SMESH_MESHINFO_HEXAS + Hexaèdres + + + SMESH_MESHINFO_NAME + Nom + + + SMESH_MESHINFO_NODES + Nœuds + + + SMESH_MESHINFO_ORDER0 + Total + + + SMESH_MESHINFO_ORDER1 + Linéaire + + + SMESH_MESHINFO_ORDER2 + Quadratique + + + SMESH_MESHINFO_HEXAPRISM + Prismes hexagonaux + + + SMESH_MESHINFO_POLYEDRES + Polyèdres + + + SMESH_MESHINFO_POLYGONES + Polygones + + + SMESH_MESHINFO_PRISMS + Prismes + + + SMESH_MESHINFO_PYRAS + Pyramides + + + SMESH_MESHINFO_QUADRANGLES + Quadrangles + + + SMESH_MESHINFO_TETRAS + Tétraèdres + + + SMESH_MESHINFO_TITLE + Informations sur le maillage + + + SMESH_MESHINFO_TOTAL + Total + + + SMESH_MESHINFO_TRIANGLES + Triangles + + + SMESH_MESHINFO_TYPE + Type + + + SMESH_MESHINFO_VOLUMES + Volumes + + + SMESH_MIN + Min + + + SMESH_MOVE + Déplacer + + + SMESH_MOVE_ELEMENTS + Déplacer les éléments + + + SMESH_MOVE_NODES_TITLE + Déplacer un nœud + + + SMESH_NAME + Nom + + + SMESH_NODES + Nœuds + + + SMESH_NONMANIFOLDEDGES + Arêtes non-partagées + + + SMESH_NORMAL + Normal + + + SMESH_NO_MESH_VISUALIZATION + Il n'y a pas assez de mémoire pour visualiser le maillage + + + SMESH_NUMBEROFCOLORS + Nombre de couleurs : + + + SMESH_NUMBEROFLABELS + Nombre d'étiquettes : + + + SMESH_NUMBEROFSTEPS + Nombre de pas : + + + SMESH_OBJECTS_SELECTED + %1_objets + + + SMESH_OBJECT_ALGORITHM + Algorithme + + + SMESH_OBJECT_GEOM + Objet géométrique + + + SMESH_OBJECT_HYPOTHESIS + Hypothèse + + + SMESH_OBJECT_MESH + Maillage + + + SMESH_OBJECT_MESHorSUBMESH + Maillage ou sous-maillage + + + SMESH_OPERATION_FAILED + L'opération n'a pas abouti + + + SMESH_OCTA + Prisme Octogonal + + + SMESH_OCTAHEDRA + Prismes octogonaux + + + TOP_OCTA + Prisme hexagonal + + + MEN_OCTA + Prisme hexagonal + + + STB_OCTA + Prisme hexagonal + + + SMESH_ORIENTATION + Orientation + + + SMESH_ORIENTATION_ELEMENTS_TITLE + Changer l'orientation + + + SMESH_OUTLINE_COLOR + Couleur de l'objet maillage + + + SMESH_PARAMETERS + Paramètres + + + SMESH_PENTA + Pentaèdre + + + SMESH_PENTAHEDRA + Pentaèdres + + + TOP_PENTA + Pentaèdre + + + MEN_PENTA + Pentaèdre + + + STB_PENTA + Pentaèdre + + + SMESH_PLANE + Plan + + + SMESH_POINT + Point + + + SMESH_POINT_1 + Point 1 + + + SMESH_POINT_2 + Point 2 + + + SMESH_BASE_POINT + Point de base + + + SMESH_POLYEDRE_CREATE_ERROR + Erreur de création du polyèdre + + + SMESH_POLYEDRON + Polyèdre + + + SMESH_POLYEDRONS + Polyèdres + + + SMESH_QUADRATIC_POLYEDRON + Polyèdre quadratique + + + SMESH_QUADRATIC_POLYEDRONS + Polyèdres quadratiques + + + SMESH_POLYGON + Polygone + + + SMESH_POLYGONS + Polygones + + + SMESH_QUADRATIC_POLYGON + Polygone quadratique + + + SMESH_QUADRATIC_POLYGONS + Polygones quadratiques + + + SMESH_POSITION_SIZE_SCALARBAR + Origine && Taille + + + SMESH_DISTRIBUTION_SCALARBAR + Distribution + + + SMESH_SHOW_DISTRIBUTION_SCALARBAR + Afficher la distribution + + + SMESH_PRECISION + Précision + + + SMESH_PREFERENCES_SCALARBAR + Préférences de la barre d'échelle + + + SMESH_PREF_SELECTION + Préférences - Sélection + + + SMESH_PRESELECTION + Présélection + + + SMESH_PRISM + Prisme + + + SMESH_PROPERTIES_SCALARBAR + Propriétés de la barre d'échelle + + + SMESH_PYRAMID + Pyramide + + + SMESH_PYRAMIDS + Pyramides + + + MEN_PYRAMID + Pyramide + + + TOP_PYRAMID + Pyramide + + + STB_PYRAMID + Pyramide + + + SMESH_QUADRANGLE + Quadrangle + + + SMESH_QUADRANGLES + Quadrangles + + + SMESH_QUADRATIC_EDGE + Arête quadratique + + + SMESH_QUADRATIC_EDGES + Arêtes quadratiques + + + SMESH_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + SMESH_QUADRATIC_HEXAHEDRONS + Hexaèdres quadratiques + + + SMESH_TRIQUADRATIC_HEXAHEDRON + Hexaèdre triquadratique + + + SMESH_TRIQUADRATIC_HEXAHEDRONS + Hexaèdres triquadratiques + + + TOP_TRIQUADRATIC_HEXAHEDRON + Hexaèdre triquadratique + + + MEN_TRIQUADRATIC_HEXAHEDRON + Hexaèdre triquadratique + + + STB_TRIQUADRATIC_HEXAHEDRON + Hexaèdre triquadratique + + + SMESH_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + SMESH_QUADRATIC_PENTAHEDRONS + Pentaèdres quadratiques + + + SMESH_QUADRATIC_PYRAMID + Pyramide quadratique + + + SMESH_QUADRATIC_PYRAMIDS + Pyramides quadratiques + + + SMESH_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + SMESH_QUADRATIC_QUADRANGLES + Quadrangles quadratiques + + + SMESH_BIQUADRATIC_QUADRANGLE + Quadrangle biquadratique + + + SMESH_BIQUADRATIC_QUADRANGLES + Quadrangles biquadratiques + + + MEN_BIQUADRATIC_QUADRANGLE + Quadrangle biquadratique + + + TOP_BIQUADRATIC_QUADRANGLE + Quadrangle biquadratique + + + STB_BIQUADRATIC_QUADRANGLE + Quadrangle biquadratique + + + SMESH_QUADRATIC_TETRAHEDRON + Tétraèdre quadratique + + + SMESH_QUADRATIC_TETRAHEDRONS + Tétraèdres quadratiques + + + SMESH_QUADRATIC_TRIANGLE + Triangle quadratique + + + SMESH_QUADRATIC_TRIANGLES + Triangles quadratiques + + + SMESH_RANGE_MAX + Valeur maximale : + + + SMESH_RANGE_MIN + Valeur minimale : + + + SMESH_RANGE_SCALARBAR + Echelle de valeurs + + + SMESH_REALLY_DELETE + Voulez-vous vraiment supprimer ces %1 objets? : %2 + + + SMESH_REMOVE + Supprimer + + + SMESH_REMOVE_ELEMENTS_TITLE + Supprimer les éléments + + + SMESH_REMOVE_NODES_TITLE + Supprimer les nœuds + + + SMESH_RENUMBERING + Renuméroter + + + SMESH_RENUMBERING_ELEMENTS_TITLE + Renuméroter les éléments + + + SMESH_RENUMBERING_NODES_TITLE + Renuméroter les nœuds + + + SMESH_REVERSE + Inverser + + + SMESH_REVOLUTION + Révolution + + + SMESH_RM_HYP_WRN + "%1" n'est pas attribué, mais: + + + + SMESH_ROTATION + Rotation + + + SMESH_ROTATION_TITLE + Rotation autour d'un axe + + + SMESH_SCALARBAR + Barre d'échelle + + + SMESH_SEGMENTS + Segments + + + SMESH_SELECTION + Sélection + + + SMESH_SELECT_FROM + Sélectionner à partir de + + + SMESH_SELECT_WHOLE_MESH + Choisir un maillage entier, un sous-maillage ou un groupe + + + SMESH_SET_COLOR + Groupe de couleur + + + SMESH_SEWING + Couture + + + SMESH_SMOOTHING + Lissage + + + SMESH_STANDARD_MESHINFO_TITLE + Information de maillage + + + SMESH_SUBMESH + Sous-maillage + + + SMESH_SUBMESH_SELECTED + %1 sous-maillages + + + SMESH_SYMMETRY + Symétrie + + + SMESH_TETRAS + Tétraèdre + + + SMESH_TETRAHEDRA + Tétraèdres + + + SMESH_TITLE + Titre : + + + SMESH_TOLERANCE + Tolérance + + + SMESH_TRANSLATION + Translation + + + SMESH_SCALE_TITLE + Transformation d'échelle + + + SMESH_DUPLICATE_TITLE + Dupliquer les nœuds + + + SMESH_SCALE + Echelle + + + SMESH_SCALE_FACTOR + Facteur d'échelle : + + + SMESH_SCALE_FACTOR_X + Facteur d'échelle X : + + + SMESH_SCALE_FACTOR_Y + Facteur d'échelle Y : + + + SMESH_SCALE_FACTOR_Z + Facteur d'échelle Z : + + + SMESH_TRANSPARENCY_OPAQUE + Opaque + + + SMESH_TRANSPARENCY_TITLE + Changer la transparence + + + SMESH_TRANSPARENCY_TRANSPARENT + Transparent + + + SMESH_TRIANGLE + Triangle + + + SMESH_TRIANGLES + Triangles + + + SMESH_UPDATEVIEW + Mettre à jour la vue + + + SMESH_VALUE + Valeur + + + SMESH_VECTOR + Vecteur + + + SMESH_VERTICAL + Verticale + + + SMESH_DISTRIBUTION_COLORING_TYPE + Type de coloration + + + SMESH_MONOCOLOR + Monocouleur + + + SMESH_DISTRIBUTION_COLOR + Couleur de la distribution: + + + SMESH_MULTICOLOR + Multicouleur + + + SMESH_VISU_PROBLEM + Impossible de visualiser le maillage, probablement à cause d'un manque de mémoire + + + SMESH_VISU_PROBLEM_CLEAR + Impossible de visualiser le maillage, pas assez de la mémoire pour montrer le message, +donc toutes les données visuelles ont été supprimées pour ne pas planter l'application. +Enregistrez votre travail avant que l'application se plante + + + SMESH_VOLUME + Volume + + + SMESH_WARNING + Avertissement + + + SMESH_WHAT_IS_TITLE + Information sur un élément de maillage + + + SMESH_WIDTH + Largeur : + + + SMESH_WRN_ALGORITHM_ALREADYEXIST + L'algorithme existe déjà + + + SMESH_WRN_COMPUTE_FAILED + Impossible de calculer le maillage + + + SMESH_WRN_EVALUATE_FAILED + Impossible d'évaluer le maillage + + + SMESH_WRN_EMPTY_NAME + Un nom vide n'est pas valide + + + SMESH_WRN_HYPOTHESIS_ALREADYEXIST + L'hypothèse existe déjà + + + SMESH_WRN_HYPOTHESIS_NOTEXIST + L'hypothèse ou l'algorithme n'existent pas + + + SMESH_WRN_MISSING_PARAMETERS + Paramètres manquants + + + SMESH_WRN_NO_AVAILABLE_DATA + Pas de données disponibles dans la sélection + + + SMESH_WRN_SELECTIONMODE_DIAGONAL + Activer le mode de sélection des références + + + SMESH_WRN_SELECTIONMODE_ELEMENTS + Activer le mode de sélection des éléments + + + SMESH_WRN_SELECTIONMODE_NODES + Activer le mode de sélection des nœuds + + + SMESH_WRN_VIEWER_VTK + Il faut ouvrir la scène dans le visualisateur VTK + + + SMESH_WRN_SIZE_LIMIT_EXCEEDED + La présentation n'a pas été mise à jour automatiquement: la nouvelle taille du maillage (%1 éléments) dépasse la limite de taille actuelle (%2 éléments). +Vérifiez la limite dans les préférences du module Mesh. + + + + SMESH_WRN_WARNING + Avertissement + + + SMESH_X + X + + + SMESH_X_SCALARBAR + X : + + + SMESH_Y + Y + + + SMESH_Y_SCALARBAR + Y : + + + SMESH_Z + Z + + + STATE_ALGO_MISSING + Il manque l'algorithme %3 %2D + + + STATE_HYP_BAD_GEOMETRY + L'algorithme %3 %2D "%1" est attribué à une géométrie qui ne convient pas + + + STATE_HYP_BAD_PARAMETER + Il y a un paramètre incorrect dans l'hypothèse %3 %2D de l'algorithme "%1" + + + STATE_HYP_MISSING + L'hypothèse %4D manque à l'algorithme %3 %2D "%1" + + + STATE_HYP_NOTCONFORM + L'algorithme %3 %2D "%1" produit un maillage non-conforme: l'hypothèse globale "Maillage non conforme autorisé" doit être cochée + + + STB_ADV_INFO + Monter l'information de base sur le maillage + + + STB_ALL + Tous + + + STB_AREA + Aire + + + STB_ASPECT + Rapport de forme + + + STB_ASPECT_3D + Rapport de forme 3D + + + STB_AUTO_COLOR + Couleur automatique + + + STB_AUTO_UPD + Mise à jour automatique + + + STB_BUILD_COMPOUND + Construire un maillage assemblé + + + STB_COPY_MESH + Copie le maillage + + + STB_CLIP + Pan de coupe + + + STB_COLORS + Paramètres d'affichage + + + STB_COMPUTE + Calculer + + + STB_PRECOMPUTE + Prévisualiser + + + STB_EVALUATE + Evaluer + + + STB_CONNECTION + Frontières sur connexion multiples + + + STB_CONNECTION_2D + Frontières sur connexion multiples 2D + + + STB_CONSTRUCT_GROUP + Construire un groupe + + + STB_CONV_TO_QUAD + Convertir vers/de quadratique + + + STB_2D_FROM_3D + Créer les éléments de frontière + + + STB_MESH_ORDER + Changer la priorité des sous-maillages + + + STB_CREATE_GROUP + Créer un groupe + + + STB_CREATE_GEO_GROUP + Créer des groupes à partir de la géométrie + + + STB_CREATE_MESH + Créer un maillage + + + STB_CREATE_SUBMESH + Créer un sous-maillage + + + STB_CUT + Découpe des quadrangles + + + STB_CUT_GROUP + Découper les groupes + + + STB_IMPORT_DAT + Importer un fichier DAT + + + STB_DAT + Exporter un fichier DAT + + + STB_DELETE + Supprimer + + + STB_DEL_GROUP + Supprimer les groupes et leur contenu + + + STB_FACE_ORIENTATION + Orientation des faces + + + STB_DISABLE_AUTO_COLOR + Désactiver la couleur automatique + + + STB_DISPLAY_ONLY + Afficher uniquement + + + STB_DISP_ENT + Visualiser une entité + + + STB_ELEM0D + Elément 0D + + + STB_ELEMS0D + Eléments 0D + + + STB_BALLS + Eléments particulaires + + + STB_BALL + Elément particulaire + + + STB_EDGE + Arête + + + STB_EDGES + Arêtes + + + STB_EDIT_GROUP + Editer un groupe + + + STB_EDIT_GEOMGROUP_AS_GROUP + Editer un groupe en tant qu'autonome + + + STB_EDIT_HYPO + Editer une hypothèse + + + STB_EDIT_MESHSUBMESH + Editer un maillage/sous-maillage + + + STB_EXPORT_DAT + Exporter au format DAT + + + STB_EXPORT_MED + Exporter au format MED + + + STB_EXPORT_CGNS + Exporter au format CGNS + + + STB_EXPORT_SAUV + Exporter au format SAUV (ASCII) + + + STB_EXPORT_STL + Exporter au format STL + + + STB_EXPORT_UNV + Exporter au format UNV + + + STB_EXTRUSION + Extrusion + + + STB_EXTRUSION_ALONG + Extrusion suivant un chemin + + + STB_FACES + Faces + + + STB_BARE_BORDER_VOLUME + Volumes avec éléments de peau 2D manquants + + + STB_BARE_BORDER_FACE + Faces avec éléments de peau 1D manquants + + + STB_OVER_CONSTRAINED_VOLUME + Volumes sur-contraints + + + STB_OVER_CONSTRAINED_FACE + Faces sur-contraintes + + + STB_FREE_BORDER + Frontières libres + + + STB_FREE_EDGE + Arêtes libres + + + STB_FREE_NODE + Nœuds libres + + + STB_FREE_FACES + Faces libres + + + STB_GLOBAL_HYPO + Hypothèse globale + + + STB_HEXA + Hexaèdre + + + STB_HIDE + Cacher + + + STB_INT_GROUP + Intersection des groupes + + + STB_INV + Inversion de diagonale + + + STB_LENGTH + Longueur + + + STB_LENGTH_2D + Longueur 2D + + + STB_MAP + Projection de motif + + + STB_MAX_ELEMENT_LENGTH_2D + Diamètre de l'élément 2D + + + STB_MAX_ELEMENT_LENGTH_3D + Diamètre de l'élément 3D + + + STB_IMPORT_MED + Importer un fichier MED + + + STB_MED + Exporter un fichier MED + + + STB_IMPORT_STL + Importer un fichier STL + + + STB_STL + Exporter un fichier STL + + + STB_IMPORT_CGNS + Importer un fichier CGNS + + + STB_CGNS + Exporter un fichier CGNS + + + STB_IMPORT_SAUV + Importer un fichier SAUV (ASCII) + + + STB_SAUV + Exporter un fichier SAUV (ASCII) + + + STB_MERGE + Fusionner les nœuds + + + STB_MERGE_ELEMENTS + Fusionner les éléments + + + STB_MESH_THROU_POINT + Déplacer un nœud + + + STB_MIN_ANG + Angle minimal + + + STB_MOVE + Déplacer un nœud + + + STB_NODE + Nœud + + + STB_NODES + Nœuds + + + STB_NUM_ELEMENTS + Visualiser les éléments + + + STB_NUM_NODES + Visualiser les nœuds + + + STB_ORIENT + Orientation + + + STB_POLYGON + Polygone + + + STB_POLYHEDRON + Polyèdre + + + STB_PRECISION + Précision + + + STB_QUAD + Quadrangle + + + STB_QUADRATIC_EDGE + Arête quadratique + + + STB_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + STB_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + STB_QUADRATIC_PYRAMID + Pyramide quadratique + + + STB_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + STB_QUADRATIC_TETRAHEDRON + Tétraèdre quadratique + + + STB_QUADRATIC_TRIANGLE + Triangle quadratique + + + STB_REMOVE_ELEMENTS + Supprimer les éléments + + + STB_REMOVE_NODES + Supprimer les nœuds + + + STB_REMOVE_ORPHAN_NODES + Supprimer les nœuds orphelins + + + STB_RENAME + Renommer + + + STB_RENUM_ELEMENTS + Renuméroter les éléments + + + STB_RENUM_NODES + Renuméroter les nœuds + + + STB_RESET + Restaurer + + + STB_SAVE_DISTRIBUTION + Enregistrer la distribution dans un fichier + + + STB_SHOW_DISTRIBUTION + Afficher la distribution + + + STB_REVOLUTION + Révolution + + + STB_ROT + Rotation + + + STB_SCALAR_BAR + Barre d'échelle + + + STB_SCALAR_BAR_PROP + Propriétés de la barre d'échelle + + + STB_SELECTION + Sélection + + + STB_SEL_FILTER_LIB + Librairie des filtres de sélection + + + STB_SEW + Couture + + + STB_SHADE + Ombrage + + + STB_SHOW + Afficher + + + STB_SHRINK + Contraction + + + STB_SKEW + Inclinaison d'angle + + + STB_SMOOTH + Lissage + + + STB_STD_INFO + Informations sur le maillage + + + STB_SYM + Symétrie + + + STB_TAPER + Cône + + + STB_TETRA + Tétraèdre + + + STB_TRANS + Translation + + + STB_SCALE + Mise à l'échelle + + + STB_DUPLICATE_NODES + Dupliquer les nœuds + + + STB_TRANSP + Transparence + + + STB_TRIANGLE + Triangle + + + STB_UNASSIGN + Désassocier + + + STB_UNION + Union des triangles + + + STB_UNION2 + Union de deux triangles + + + STB_IMPORT_UNV + Importer un fichier UNV + + + STB_UNV + Exporter un fichier UNV + + + STB_UN_GROUP + Union des groupes + + + STB_UNDERLYING_ELEMS + Créer les groupes d'entités à partir des groupes existants de dimensions supérieures + + + STB_UPDATE + Mettre à jour + + + STB_VOLUMES + Volumes + + + STB_VOLUME_3D + Volume + + + STB_WARP + Angle de déformation + + + STB_WHAT_IS + Information sur un élément ou un nœud de maillage + + + STB_WIRE + Contour + + + TAPER_ELEMENTS + Cône + + + TB_ADD_REMOVE + Ajouter/supprimer la barre d'outils + + + TB_CTRL + Barre d'outils des contrôles + + + TB_DISP_MODE + Barre du mode de visualisation + + + TB_HYPO + Barre d'hypothèses + + + TB_MESH + Barre de maillage + + + TB_MODIFY + Barre des modifications + + + TOP_ADV_INFO + Informations sur le maillage + + + TOP_ALL + Tous + + + TOP_AREA + Aire + + + TOP_ASPECT + Rapport de forme + + + TOP_ASPECT_3D + Rapport de forme 3D + + + TOP_AUTO_COLOR + Couleur automatique + + + TOP_AUTO_UPD + Mise à jour automatique + + + TOP_BUILD_COMPOUND + Construire un maillage assemblé + + + TOP_COPY_MESH + Copier le maillage + + + TOP_CLIP + Plan de coupe + + + TOP_COLORS + Paramètres d'affichage + + + TOP_COMPUTE + Calculer + + + TOP_PRECOMPUTE + Prévisualiser + + + TOP_EVALUATE + Evaluer + + + TOP_CONNECTION + Frontières sur connexions multiples + + + TOP_CONNECTION_2D + Frontières sur connexions multiples 2D + + + TOP_CONSTRUCT_GROUP + Construire un groupe + + + TOP_CONV_TO_QUAD + Convertir vers/de quadratique + + + TOP_2D_FROM_3D + Créer les éléments de frontière + + + TOP_MESH_ORDER + Changer la priorité des sous-maillages + + + TOP_CREATE_GROUP + Créer un groupe + + + TOP_CREATE_GEO_GROUP + Créer des groupes liés à la géométrie + + + TOP_CREATE_MESH + Créer un maillage + + + TOP_CREATE_SUBMESH + Créer un sous-maillage + + + TOP_CUT + Découpe des quadrangles + + + TOP_CUT_GROUP + Découper les groupes + + + TOP_IMPORT_DAT + Importer un fichier DAT + + + TOP_DAT + Exporter un fichier DAT + + + TOP_DELETE + Supprimer + + + TOP_DEL_GROUP + Supprimer les groupes et leur contenu + + + TOP_FACE_ORIENTATION + Orientation des faces + + + TOP_DISABLE_AUTO_COLOR + Désactiver la couleur automatique + + + TOP_DISPLAY_ONLY + Afficher uniquement + + + TOP_DISP_ENT + Visualiser une entité + + + TOP_ELEM0D + Elément 0D + + + TOP_ELEMS0D + Eléments 0D + + + TOP_BALL + Particulaire + + + TOP_BALLS + Particulaires + + + TOP_EDGE + Arête + + + TOP_EDGES + Arêtes + + + TOP_EDIT_GROUP + Editer un groupe + + + TOP_EDIT_GEOMGROUP_AS_GROUP + Editer un groupe en tant qu'autonome + + + TOP_EDIT_HYPO + Editer l'hypothèse + + + TOP_EDIT_MESHSUBMESH + Editer un maillage/sous-maillage + + + TOP_EXPORT_DAT + Exporter au format DAT + + + TOP_EXPORT_MED + Exporter au format MED + + + TOP_EXPORT_SAUV + Exporter au format SAUV (ASCII) + + + TOP_EXPORT_STL + Exporter au format STL + + + TOP_EXPORT_UNV + Exporter au format UNV + + + TOP_EXTRUSION + Extrusion + + + TOP_EXTRUSION_ALONG + Extrusion suivant un chemin + + + TOP_FACES + Faces + + + TOP_BARE_BORDER_VOLUME + Volumes avec éléments de peau 2D manquants + + + TOP_BARE_BORDER_FACE + Faces avec éléments de peau 1D manquants + + + TOP_OVER_CONSTRAINED_VOLUME + Volumes sur-contraints + + + TOP_OVER_CONSTRAINED_FACE + Faces sur-contraintes + + + TOP_FREE_BORDER + Frontières libres + + + TOP_FREE_EDGE + Arêtes libres + + + TOP_FREE_NODE + Nœuds libres + + + TOP_FREE_FACES + Faces libres + + + TOP_GLOBAL_HYPO + Hypothèse globale + + + TOP_HEXA + Hexaèdre + + + TOP_HIDE + Cacher + + + TOP_INT_GROUP + Intersection de groupes + + + TOP_INV + Inversion de diagonale + + + TOP_LENGTH + Longueur + + + TOP_LENGTH_2D + Longueur 2D + + + TOP_MAP + Projection de motif + + + TOP_MAX_ELEMENT_LENGTH_2D + Diamètre des éléments 2D + + + TOP_MAX_ELEMENT_LENGTH_3D + Diamètre des éléments 3D + + + TOP_IMPORT_MED + Importer un fichier MED + + + TOP_MED + Exporter un fichier MED + + + TOP_IMPORT_STL + Importer un fichier STL + + + TOP_STL + Exporter un fichier STL + + + TOP_IMPORT_CGNS + Importer un fichier CGNS + + + TOP_CGNS + Exporter un fichier CGNS + + + TOP_IMPORT_SAUV + Importer un fichier SAUV (ASCII) + + + TOP_SAUV + Exporter un fichier SAUV (ASCII) + + + TOP_MERGE + Fusionner les nœuds + + + TOP_MERGE_ELEMENTS + Fusionner les éléments + + + TOP_MESH_THROU_POINT + Déplacer un nœud + + + TOP_MIN_ANG + Angle minimal + + + TOP_MOVE + Déplacer un nœud + + + TOP_NODE + Nœud + + + TOP_NODES + Nœuds + + + TOP_NUM_ELEMENTS + Visualiser les éléments + + + TOP_NUM_NODES + Visualiser les nœuds + + + TOP_ORIENT + Orientation + + + TOP_POLYGON + Polygone + + + TOP_POLYHEDRON + Polyèdre + + + TOP_PRECISION + Précision + + + TOP_QUAD + Quadrangle + + + TOP_QUADRATIC_EDGE + Arête quadratique + + + TOP_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + TOP_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + TOP_QUADRATIC_PYRAMID + Pyramide quadratique + + + TOP_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + TOP_QUADRATIC_TETRAHEDRON + Tétraèdre quadratique + + + TOP_QUADRATIC_TRIANGLE + Triangle quadratique + + + TOP_REMOVE_ELEMENTS + Supprimer les éléments + + + TOP_REMOVE_NODES + Supprimer les nœuds + + + TOP_REMOVE_ORPHAN_NODES + Supprimer les nœuds orphelins + + + TOP_RENAME + Renommer + + + TOP_RENUM_ELEMENTS + Renuméroter les éléments + + + TOP_RENUM_NODES + Renuméroter les nœuds + + + TOP_RESET + Restaurer + + + TOP_SAVE_DISTRIBUTION + Exporter la distribution + + + TOP_SHOW_DISTRIBUTION + Afficher la distribution + + + TOP_REVOLUTION + Révolution + + + TOP_ROT + Rotation + + + TOP_SCALAR_BAR + Barre d'échelle + + + TOP_SCALAR_BAR_PROP + Propriétés de la barre d'échelle + + + TOP_SELECTION + Sélection + + + TOP_SEL_FILTER_LIB + Librairie des filtres de sélection + + + TOP_SEW + Couture + + + TOP_SHADE + Ombrage + + + TOP_SHOW + Afficher + + + TOP_SHRINK + Contraction + + + TOP_SKEW + Inclinaison d'angle + + + TOP_SMOOTH + Lissage + + + TOP_STD_INFO + Informations sur le maillage + + + TOP_SYM + Symétrie + + + TOP_TAPER + Cône + + + TOP_TETRA + Tétraèdre + + + TOP_TRANS + Translation + + + TOP_SCALE + Mise à l'échelle + + + TOP_DUPLICATE_NODES + Dupliquer les nœuds + + + TOP_TRANSP + Transparence + + + TOP_TRIANGLE + Triangle + + + TOP_UNASSIGN + Désassocier + + + TOP_UNION + Union des triangles + + + TOP_UNION2 + Union de deux triangles + + + TOP_IMPORT_UNV + Importer un fichier UNV + + + TOP_UNV + Exporter un fichier UNV + + + TOP_UN_GROUP + Union des groupes + + + TOP_UNDERLYING_ELEMS + Créer les groupes d'entités à partir des groupes existants de dimensions supérieures + + + TOP_UPDATE + Mettre à jour + + + TOP_VOLUMES + Volumes + + + TOP_VOLUME_3D + Volume + + + TOP_WARP + Angle de déformation + + + TOP_WHAT_IS + Information sur l'élément de maillage + + + TOP_WIRE + Contours + + + UNKNOWN_CONTROL + Inconnu + + + VOLUME_3D_ELEMENTS + Volume + + + WARP_ELEMENTS + Déformation + + + MEN_FILE_INFO + Information du fichier MED + + + SMESH_WRN_NO_APPROPRIATE_SELECTION + Aucun objet sélectionné ne convient + + + MEN_CLEAR_MESH + Effacer les données du maillage + + + TOP_CLEAR_MESH + Effacer les données du maillage + + + STB_CLEAR_MESH + Effacer les données du maillage + + + SMESH_IMPORT_MESH + Importer les donnés du maillage à partir des fichiers + + + SMESH_ERR_NOT_SUPPORTED_FORMAT + Le format de fichier n'est pas supporté + + + SMESH_ERR_UNKNOWN_IMPORT_ERROR + Erreur inconnue + + + SMESH_IMPORT_ERRORS + L'importation s'est terminée avec des erreurs + + + SMESH_DRS_SOME_EMPTY + Un ou plusieurs fichiers de maillage sont vides, les données n'ont pas été publiées + + + NO_MESH_SELECTED + Aucun maillage sélectionné + + + SMESH_PREF_def_precision + Précision par défaut + + + SMESH_PREF_length_precision + Précision de la longueur + + + SMESH_PREF_angle_precision + Précision angulaire + + + SMESH_PREF_len_tol_precision + Précision de tolérance de la longueur + + + SMESH_PREF_parametric_precision + Précision paramétrique + + + SMESH_PREF_area_precision + Précision de l'aire + + + FULL_RECOMPUTE_QUESTION + +Le maillage a été édité après le dernier calcul complet, +ceci peut empêcher un calcul correct. +Voulez-vous recalculer le maillage entier pour rejeter les modifications ? + + + + SMESH_PREF_vol_precision + Précision du volume + + + SMESH_PRECISION_HINT + +Il est possible de modifier la précision de la valeur d'entrée +avec le paramètre '%1' des préférences du module Mesh. + + + REMOVE_ORPHAN_NODES_QUESTION + Voulez-vous supprimer tous les nœuds orphelins ? + + + NB_NODES_REMOVED + %1 nœud(s) supprimés. + + + SMESH_SAVE_DISTRIBUTION + Exporter la distribution + + + SMESH_PLUGINS_OTHER + Extensions SMESH + + + MESH_LOADING_MSG + Chargement du maillage %0 en cours, veuillez patienter... + + + MESH_LOADING_MSG_FINISHED + Chargement du maillage %0 terminé + + + BALL_DIAMETER + Diamètre + + + BALL_ELEMENT + Particulaire + + + DEP_OBJECT + L'objet sélectionné a été utilisé pour en créer un autre. +Il ne peut pas être supprimé. + + + + SMESHGUI_GroupDlg + + ALLOW_ELEM_LIST_MODIF + Edition manuelle + + + SELECT_ALL + Sélectionner tout + + + + SMESHGUI + + NOT_A_VTK_VIEWER + Cette commande n'est disponible qu'à partir d'une fenêtre VTK. +Ouvrez une fenêtre VTK et essayez de nouveau + + + PREF_AUTO_GROUPS + Créer les groupes automatiquement pour l'export MED + + + PREF_GROUP_SEGMENT_LENGTH + Paramètres automatiques + + + PREF_SEGMENT_LENGTH + Ratio de la diagonale de la boîte englobante / taille maximale + + + PREF_NB_SEGMENTS + Nombre de segments par défaut + + + SMESH_PREF_MESH_LOADING + Chargement de maillage + + + PREF_FORGET_MESH_AT_HYP_MODIF + Ne pas charger le maillage du fichier d'étude à la modification d'une hypothèse + + + PREF_AUTO_UPDATE + Mettre à jour automatiquement + + + PREF_UPDATE_LIMIT + Limite de taille (nombre d'éléments) + + + PREF_UPDATE_LIMIT_NOLIMIT + Sans limite + + + PREF_BACKFACE + Face arrière + + + PREF_WIREFRAME + Couleur de contour + + + PREF_SELECTION + Couleur de sélection + + + PREF_PRE_SELECTION + Couleur de pré-sélection + + + PREF_COLOR + Couleur + + + PREF_ORIENTATION_COLOR + Couleur + + + PREF_ORIENTATION_3D_VECTORS + Vecteurs 3D + + + PREF_ORIENTATION_SCALE + Echelle + + + PREF_DISPLAY_ENTITY + Eléments à visualiser + + + QUADRATIC_REPRESENT_MODE + Représentation des éléments quadratiques 2D + + + MAX_ARC_ANGLE + Angle maximal + + + PREF_DISPLAY_MODE + Mode de visualisation + + + PREF_ELEMENTS + Eléments + + + PREF_ELEMENT_COLOR + Couleur d'élément + + + PREF_FILL + Remplir + + + PREF_NOTIFY_MODE + Montrer la notification sur le résultat de calcul + + + PREF_NOTIFY_NEVER + Jamais + + + PREF_NOTIFY_ERROR + Erreurs uniquement + + + PREF_NOTIFY_ALWAYS + Toujours + + + PREF_ELEM_INFO + Information des éléments du maillage + + + PREF_ELEM_INFO_SIMPLE + Simple + + + PREF_ELEM_INFO_TREE + Arbre + + + PREF_GPP_NODES_LIMIT + Calcul automatique du nombre de nœuds: limite + + + SMESH_PREF_GROUP_PRECISION + Précision des champs d'entrée + + + SMESH_PREF_GROUP_PREVIEW + Prévisualisation + + + PREF_GROUP_ELEMENTS + Eléments + + + PREF_GROUP_EXPORT + Exporter un maillage + + + PREF_GROUP_FACES_ORIENTATION + Orientation des faces + + + PREF_GROUP_COMPUTE + Calculer le maillage + + + PREF_GROUP_NODES + Nœuds + + + PREF_GROUP_GROUPS + Groupes + + + PREF_GRP_NAMES + Couleur des noms + + + PREF_GROUP_PRECISION + Précision + + + PREF_GROUP_PRESELECTION + Présélection + + + PREF_GROUP_QUALITY + Contrôles de qualité + + + PREF_GROUP_SELECTION + Sélection + + + PREF_GROUP_INFO + Information du maillage + + + PREF_HIGHLIGHT_COLOR + Couleur de sélection + + + PREF_LABELS_COLOR + Couleur des étiquettes + + + PREF_MARKER_SCALE + Echelle du marqueur + + + PREF_NODES + Nœuds + + + PREF_OBJECTS + Objets + + + PREF_OBJECT_COLOR + Couleur d'objet + + + PREF_OUTLINE + Silhouette + + + PREF_PRECISION_USE + Utiliser la précision + + + PREF_PRECISION_VALUE + Nombre de chiffres après la virgule + + + PREF_EQUAL_NODES_TOL + Tolérance des nœuds doubles + + + PREF_RENUMBER + Renuméroter automatiquement + + + PREF_SHRINK_COEFF + Coefficient de contraction + + + PREF_PYTHON_DUMP + Dump Python + + + PREF_HISTORICAL_PYTHON_DUMP + Dump Python historique + + + PREF_TAB_GENERAL + Général + + + PREF_TAB_MESH + Maillage + + + PREF_TAB_SELECTION + Sélection + + + PREF_TITLE_COLOR + Couleur du titre + + + PREF_TYPE_OF_MARKER + Type de marqueur + + + PREF_COLOR_0D + Eléments 0D + + + PREF_SIZE_0D + Taille des éléments 0D + + + PREF_BALL_COLOR + Particulaires + + + PREF_BALL_SIZE + Taille des éléments particulaires + + + PREF_WIDTH + Epaisseur + + + PREF_PREVIEW_CHUNK_SIZE + Taille des blocs pour la prévisualisation des sous-shapes + + + + SMESHGUI_AddQuadraticElementDlg + + SMESH_ADD_QUADRATIC_EDGE + Ajouter une arête quadratique + + + SMESH_ADD_QUADRATIC_HEXAHEDRON + Ajouter un hexaèdre quadratique + + + SMESH_ADD_TRIQUADRATIC_HEXAHEDRON + Ajouter un hexaèdre triquadratique + + + SMESH_ADD_QUADRATIC_PENTAHEDRON + Ajouter un pentaèdre quadratique + + + SMESH_ADD_QUADRATIC_PYRAMID + Ajouter une pyramide quadratique + + + SMESH_ADD_QUADRATIC_QUADRANGLE + Ajouter un quadrangle quadratique + + + SMESH_ADD_BIQUADRATIC_QUADRANGLE + Ajouter un quadrangle biquadratique + + + SMESH_ADD_QUADRATIC_TETRAHEDRON + Ajouter un tétraèdre quadratique + + + SMESH_ADD_QUADRATIC_TRIANGLE + Ajouter un triangle quadratique + + + SMESH_CORNER_NODES + Nœuds angulaires: + + + SMESH_MIDFACE_NODES + Nœuds à mi-face : + + + SMESH_CENTER_NODE + Nœud central: + + + SMESH_FIRST + Premier + + + SMESH_LAST + Dernier + + + SMESH_MIDDLE + Milieu + + + + SMESHGUI_BuildCompoundDlg + + COMPOUND + Assemblage + + + COMPOUND_MESH + Maillage d'assemblage + + + CREATE_COMMON_GROUPS + Créer des groupes communs pour les maillages initiaux + + + MERGE_NODES_AND_ELEMENTS + Fusionner les nœuds et les éléments coïncidents + + + MESHES + Maillages + + + PROCESSING_IDENTICAL_GROUPS + Traitement des groupes identiques + + + RENAME + Renommer + + + RESULT_NAME + Nom du résultat + + + UNITE + Réunir + + + + SMESHGUI_ChangeOrientationDlg + + CAPTION + Modifier l'orientation + + + + SMESHGUI_ComputeDlg + + CAPTION + Le calcul du maillage a échoué + + + CONSTRUCTOR + Calculer le maillage + + + EVAL_DLG + Evaluer le maillage + + + ERRORS + Erreurs + + + MEMORY_LACK + Problème d'allocation de mémoire + + + COMPUTE_WARNING + Le maillage semble correct mais des erreurs sont apparues + + + PUBLISH_SHAPE + Publier un sous-objet + + + SHOW_SHAPE + Montrer un sous-objet + + + SHOW_BAD_MESH + Montrer le maillage incorrect + + + + SMESHGUI_PrecomputeDlg + + CAPTION + Prévisualiser et calculer le maillage + + + PREVIEW + Prévisualiser + + + PREVIEW_1 + Maillage 1D + + + PREVIEW_2 + Maillage 2D + + + COMPUTE + Calculer + + + + SMESHGUI_PrecomputeOp + + CLEAR_SUBMESH_QUESTION + Des sous-maillages temporaires ont été créés sur la géométrie sélectionnée +au cours de l'opération de prévisualisation. +Voulez-vous supprimer toutes ces sous-maillages ? + + + SMESH_WRN_NOTHING_PREVIEW + La prévisualisation du maillage n'est pas disponible + + + SMESH_REJECT_MESH_ORDER + La priorité des sous-maillages a été changée au cours de la prévisualisation. +Voulez-vous restaurer la priorité initiale ? + + + + SMESHGUI_ConvToQuadDlg + + CAPTION + Convertir vers/de quadratique + + + MEDIUMNDS + Nœuds milieux sur la géométrie + + + MESH + Maillage ou sous-maillage + + + RADIOBTN_1 + Convertir en éléments quadratiques + + + RADIOBTN_2 + Convertir à partir d'éléments quadratiques + + + NON_CONFORM_WARNING + Attention: le maillage généré sera a priori non-conforme + + + + SMESHGUI_ConvToQuadOp + + MESH_IS_NOT_SELECTED + Le maillage n'est pas sélectionné +Indiquez-le et essayez de nouveau + + + REF_IS_NULL + Aucun maillage valide n'est sélectionné + + + + SMESHGUI_CreatePatternDlg + + CAPTION + Projection de motif + + + DEFAULT_2D + Motif_2d + + + DEFAULT_3D + Motif_3d + + + ERROR_OF_CREATION + Une erreur interne s'est produite au cours de la création du motif +Vérifiez la validité des informations données + + + ERROR_OF_SAVING + Une erreur interne s'est produite au cours de l'enregistrement du motif. +Vérifiez l'espace de disque disponible et vos droits d'écriture dans ce fichier + + + ERR_LOADF_CANT_PROJECT + Impossible d'appliquer la projection des nœuds vers la face + + + ERR_LOADF_CLOSED_FACE + Impossible de créer un motif à partir d'une face avec une arête de couture + + + ERR_LOADF_NARROW_FACE + Impossible de créer un motif à partir d'une face étroite + + + ERR_LOADV_BAD_SHAPE + Il n'est possible de créer un motif que d'une coque fermée ou d'un solide avec 6 faces + + + ERR_LOADV_COMPUTE_PARAMS + Il est impossible de calculer les paramètres du point + + + ERR_LOAD_EMPTY_SUBMESH + Il n'y a pas d'éléments pour créer de motif + + + MESH_OR_SUBMESH + Maillage ou sous-maillage + + + PATTERN + Motif + + + PATTERN_FILT + Fichiers de motif (*.smp) + + + PATTERN_NAME + Nom du motif + + + PATTERN_TYPE + Type du motif + + + PROJECT + Projeter les nœuds sur la face + + + SAVE + Sauvegarder... + + + SAVE_PATTERN + Sauvegarder le motif + + + + SMESHGUI_CreatePolyhedralVolumeDlg + + FACES_BY_NODES + Faces par nœuds + + + SMESH_POLYEDRE_CREATE_ERROR + Erreur de création du polyèdre. + + + SMESH_POLYEDRE_PREVIEW + Prévisualiser le polyèdre + + + + SMESHGUI_CuttingOfQuadsDlg + + CAPTION + Découpe des quadrangles + + + + SMESHGUI_DeleteGroupDlg + + CAPTION + Supprimer les groupes et leur contenu + + + NO_SELECTED_GROUPS + Il n'y a aucun groupe sélectionné +Choisissez un groupe et essayez de nouveau + + + SELECTED_GROUPS + Groupes sélectionnés + + + + SMESHGUI_MergeDlg + + COINCIDENT_ELEMENTS + Eléments coïncidents + + + COINCIDENT_NODES + Nœuds coïncidents + + + DETECT + Détecter + + + EDIT_SELECTED_GROUP + Editer le groupe sélectionné + + + SELECT_ALL + Tout sélectionner + + + EXCLUDE_GROUPS + Exclure les groupes + + + + SMESHGUI_ExtrusionAlongPathDlg + + BAD_SHAPE_TYPE + La géométrie choisie en tant que chemin n'est pas une arête + + + CANT_GET_TANGENT + Impossible d'obtenir la tangente pour un des nœuds du chemin + + + EXTRUSION_0D + Extrusion des éléments 0D + + + EXTRUSION_1D + Extrusion des éléments 1D + + + EXTRUSION_2D + Extrusion des éléments 2D + + + EXTRUSION_ALONG_PATH + Extrusion suivant un chemin + + + EXTR_BAD_STARTING_NODE + Nœud de départ du chemin incorrect + + + LINEAR_ANGLES + Variation linéaire des angles + + + NO_ELEMENTS_SELECTED + Aucun élément de maillage n'est sélectionné pour l'extrusion + + + SELECTED_PATH_IS_NOT_EDGE + Le maillage du chemin doit être du type arête + + + SMESH_ANGLES + Angles de rotation + + + SMESH_BASE_POINT + Point de base + + + SMESH_PATH + Chemin + + + SMESH_PATH_MESH + Maillage ou sous-maillage + + + SMESH_PATH_SHAPE + Géométrie (arête) + + + SMESH_PATH_START + Nœud de début + + + SMESH_USE_ANGLES + Utiliser les angles + + + SMESH_USE_BASE_POINT + Utiliser le point de base + + + WRONG_ANGLES_NUMBER + Le nombre d'angles doit correspondre au nombre des nœuds du chemin + + + + SMESHGUI_ExtrusionDlg + + EXTRUSION_0D + Extrusion de noeuds + + + EXTRUSION_1D + Extrusion des éléments 1D + + + EXTRUSION_2D + Extrusion des éléments 2D + + + EXTRUSION_ALONG_LINE + Extrusion suivant une ligne + + + + SMESHGUI_FilterDlg + + BAD_SHAPE_NAME + Il n'y a pas d'objet géométrique "%1" dans l'étude actuelle +Sélectionnez un objet valide et essayez de nouveau + + + CURRENT_DIALOG + Groupe actuel + + + EDGES_TLT + Filtre d'arêtes + + + FACES_TLT + Filtre de faces + + + MESH + Maillage + + + NODES_TLT + Filtre de nœuds + + + SELECTION + Sélection initiale + + + SET_IN_VIEWER + Insérer le filtre dans la fenêtre 3D + + + SHAPE_IS_NOT_A_CYLINDER + "%1" n'est pas une face cylindrique +Sélectionnez une face cylindrique et essayez de nouveau + + + SHAPE_IS_NOT_A_FACE + "%1" n'est pas une face +Sélectionnez une face et essayez de nouveau + + + SHAPE_IS_NOT_A_PLANE + "%1" n'est pas un plan +Sélectionnez un plan et essayez de nouveau + + + FACE_ID_NOT_SELECTED + Aucune face de maillage n'est sélectionnée. +Indiquez-la et essayez de nouveau + + + NOT_FACE_ID + "%1" ne correspond à aucun ID valide d'une face du maillage. +Sélectionnez une face et essayez de nouveau + + + SOURCE + Source + + + TLT + Filtre de sélection + + + VOLUMES_TLT + Filtre de volumes + + + + SMESHGUI_FilterLibraryDlg + + ADD + Ajouter + + + ADD_TO_TLT + Ajouter le filtre de sélection à la librairie + + + ALL_FILES_FILTER + Tous les fichiers (*.*) + + + ASSIGN_NEW_NAME + La librairie déjà contient un filtre avec le nom "%1" +Le nouveau nom "%2" est attribué au filtre ajouté + + + COPY_FROM_TLT + Copier le filtre de la sélection de la librairie + + + DELETE + Supprimer + + + EDGE + Arête + + + EDIT_LIB_TLT + Librairie des filtres de sélection + + + ELEMENT + Elément + + + EMPTY_FILTER_NAME + Le nom du filtre est vide +Indiquez un nom non-vide + + + ERROR_FILTER_NAME + Le nom du filtre n'est pas unique +Indiquez un autre nom + + + ERROR_LOAD + Il est impossible de charger la librairie +Vérifiez le nom du fichier de la librairie et ses propriétés + + + ERROR_OF_ADDING + Une erreur interne s'est produite à l'addition d'un nouveau filtre dans la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_COPYING + Une erreur interne s'est produite à la copie d'un filtre depuis la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_DELETING + Une erreur interne s'est produite lors de la suppression d'un filtre depuis la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_EDITING + Une erreur interne s'est produite à l'édition d'un filtre dans la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_SAVING + Une erreur s'est produite à la sauvegarde de la librairie des filtres. +Vérifiez la validité des informations données + + + FACE + Face + + + FILTER + Filtre + + + FILTER_NAME + Nom du filtre + + + FILTER_NAMES + Noms des filtres + + + LIBRARY_FILE + Nom du fichier de librairie + + + LIBRARY_IS_NOT_LOADED + La librairie n'est pas ouverte. Ouvrez la librairie et essayez de nouveau + + + LIB_NAME + FilterLib.xml + + + NODE + Nœud + + + NO_PERMISSION + Vous n'avez pas la permission d'écrire dans ce fichier + + + OPEN_LIBRARY + Ouvrir la librairie + + + SELECTION + Sélection + + + VOLUME + Volume + + + XML_FILT + Fichiers XML (*.xml) + + + + SMESHGUI_FilterTable + + ADD + Ajouter + + + ADDITIONAL_PARAMETERS + Paramètres supplémentaires + + + ADD_TO + Ajouter à... + + + AND + Et + + + AREA + Aire + + + ASPECT_RATIO + Rapport de forme + + + ASPECT_RATIO_3D + Rapport de forme 3D + + + BAD_ORIENTED_VOLUME + Volume mal orienté + + + BARE_BORDER_VOLUME + Volumes avec éléments de peau 2D manquants + + + BARE_BORDER_FACE + Faces avec éléments de peau 1D manquants + + + OVER_CONSTRAINED_VOLUME + Volumes sur-contraints + + + OVER_CONSTRAINED_FACE + Faces sur-contraintes + + + BELONG_TO_CYLINDER + Appartient au cylindre + + + BELONG_TO_GENSURFACE + Appartient à la surface + + + BELONG_TO_GEOM + Appartient à la géométrie + + + BELONG_TO_PLANE + Appartient au plan + + + BINARY + Opérateur logique + + + CLEAR + Effacer + + + COMPARE + Comparer + + + COPLANAR_FACES + Faces coplanaires + + + COPY_FROM + Copier de... + + + CRITERION + Critère + + + BALLS + Particulaires + + + EDGES + Arêtes + + + ENTITY_TYPE + Type de l'entité + + + EQUAL_TO + Egal à + + + ERROR + La valeur du seuil n'est pas valide. +Entrez une valeur correcte et essayez de nouveau + + + FACES + Faces + + + FILTER + Filtre + + + FREE_BORDERS + Bords libres + + + FREE_EDGES + Arêtes libres + + + FREE_NODES + Nœuds isolés + + + FREE_FACES + Faces libres + + + ID + ID + + + INSERT + Insérer + + + LENGTH + Longueur + + + LENGTH2D + Longueur 2D + + + LESS_THAN + Inférieur à ... + + + LYING_ON_GEOM + Repose sur la géométrie + + + MAX_ELEMENT_LENGTH_2D + Diamètre d'éléments 2D + + + MAX_ELEMENT_LENGTH_3D + Diamètre d'éléments 3D + + + MINIMUM_ANGLE + Angle minimal + + + MORE_THAN + Supérieur à ... + + + MULTIEDGES_ERROR + La valeur de seuil des bords multi-connectés ne peut pas être égal à 1 +Entrez une valeur correcte et essayez de nouveau + + + GROUPCOLOR_ERROR + Impossible d'identifier la couleur du groupe +Entrez une valeur correcte et essayez de nouveau + + + MULTI_BORDERS + Bords multi-connectés + + + NODES + Nœuds + + + NOT + Non + + + OR + Ou + + + RANGE_OF_IDS + Liste d'IDs + + + REMOVE + Supprimer + + + SKEW + Inclinaison + + + TAPER + Cône + + + THRESHOLD_VALUE + Valeur du seuil + + + UNARY + Négation + + + VOLUMES + Volumes + + + VOLUME_3D + Volume + + + WARPING + Déformation + + + LINEAR + Linéaire + + + GROUP_COLOR + Couleur du groupe + + + ELEMENTS + Eléments + + + GEOM_TYPE + Type de géométrie + + + GEOM_TYPE_0 + Point + + + GEOM_TYPE_1 + Arête + + + GEOM_TYPE_2 + Triangle + + + GEOM_TYPE_3 + Quadrangle + + + GEOM_TYPE_4 + Polygone + + + GEOM_TYPE_5 + Tétraèdre + + + GEOM_TYPE_6 + Pyramide + + + GEOM_TYPE_7 + Hexaèdre + + + GEOM_TYPE_8 + Pentaèdre + + + GEOM_TYPE_9 + Prisme hexagonal + + + GEOM_TYPE_10 + Polyèdre + + + GEOM_TYPE_11 + Particulaire + + + + SMESHGUI_GroupOpDlg + + ARGUMENTS + Arguments + + + DIFF_MESHES + Les arguments de l'opération ne sont pas indiqués correctement +Les groupes correspondent à des maillages différents +Donnez des arguments valides et essayez de nouveau + + + DIFF_TYPES + Les arguments de l'opération ne sont pas indiqués correctement +Les groupes contiennent des éléments de types différents +Donnez des arguments valides et essayez de nouveau + + + EMPTY_NAME + Le nom du groupe est invalide +Indiquez un nom non-vide et essayez de nouveau + + + INCORRECT_ARGUMENTS + Les arguments de l'opération ne sont pas indiqués +Indiquez-les et essayez de nouveau + + + NAME + Nom + + + OBJECT_1 + Objet 1 + + + OBJECT_2 + Objet 2 + + + RESULT_NAME + Nom du résultat + + + TOOL_OBJECT + Outil + + + UNION_OF_TWO_GROUPS + Union de deux groupes + + + + SMESHGUI_UnionGroupsDlg + + UNION_OF_GROUPS + Union de groupes + + + + SMESHGUI_DimGroupDlg + + CREATE_GROUP_OF_UNDERLYING_ELEMS + Créer un groupe d'entités sous-jacentes + + + ELEMENTS_TYPE + Type d'éléments + + + NODE + Nœud + + + EDGE + Arête + + + FACE + Face + + + VOLUME + Volume + + + + SMESHGUI_IntersectGroupsDlg + + INTERSECTION_OF_GROUPS + Intersection de groupes + + + + SMESHGUI_CutGroupsDlg + + CUT_OF_GROUPS + Différence de groupes + + + MAIN_OBJECT + Objet principal + + + TOOL_OBJECT + Objet outil + + + + SMESHGUI_MakeNodeAtPointDlg + + AUTO_SEARCH + Trouver le nœud le plus proche de la destination + + + CAPTION + Déplacer un nœud + + + DESTINATION + Destination + + + MOVE_NODE + Déplacer un nœud + + + METHOD + Méthode + + + NODE_2MOVE + Nœud à déplacer + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MakeNodeAtPointOp + + INVALID_ID + L'ID du nœud est invalide + + + INVALID_MESH + Le maillage à modifier n'est pas sélectionné + + + + SMESHGUI_FindElemByPointDlg + + MESH_GROUP + Maillage ou groupe + + + CAPTION + Trouver un élément par un point + + + CREATE_NEW_METHOD + Créer un nœud + + + MESH_PASS_THROUGH_POINT + Créer un nœud au point + + + METHOD + Méthode + + + MOVE_EXISTING_METHOD + Déplacer un nœud + + + NODE_2MOVE + Nœud à déplacer + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MeshDlg + + CREATE_MESH + Créer un maillage + + + CREATE_SUBMESH + Créer un sous-maillage + + + DIM_0D + 0D + + + DIM_1D + 1D + + + DIM_2D + 2D + + + DIM_3D + 3D + + + EDIT_MESH_SUBMESH + Editer un maillage/sous-maillage + + + GEOMETRY + Géométrie + + + HYPOTHESES_SETS + Attribuer un jeu d'hypothèses + + + MESH + Maillage + + + NAME + Nom + + + + SMESHGUI_MeshOp + + ALGORITHM_WITHOUT_HYPOTHESIS + L'algorithme pour la dimension %1 est défini mais l'hypothèse ne l'est pas + + + EDIT_SUBMESH_QUESTION + Un sous-maillage existe déjà sur la géométrie choisie +Voulez-vous éditer ce sous-maillage? + + + SUBMESH_NOT_ALLOWED + Créer un sous-maillage ignoré par l'algorithme global n'a pas de sens "%1" + + + GEOMETRY_OBJECT_IS_NOT_DEFINED + L'objet géométrique n'est pas défini +Indiquez-le et essayez de nouveau + + + GEOMETRY_OBJECT_IS_NULL + L'objet géométrique est nul + + + HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED + Les hypothèses et les algorithmes ne sont pas définis + + + HYPOTHESIS_WITHOUT_ALGORITHM + L'hypothèse est définie pour la dimension %1 mais l'algorithme n'est pas défini + + + IMPORTED_MESH + Le maillage n'est pas construit sur une géométrie + + + INVALID_SUBSHAPE + L'objet géométrique n'est pas un sous-objet de l'objet maillé + + + MESH_IS_NOT_DEFINED + Le maillage n'est pas défini +Spécifiez-le et essayez de nouveau + + + MESH_IS_NULL + Le maillage est nul + + + NAME_OF_MESH_IS_EMPTY + Le nom du maillage est vide +Indiquez un nom valide et essayez de nouveau + + + NAME_OF_SUBMESH_IS_EMPTY + Le nom du sous-maillage est vide +Indiquez un nom valide et essayez de nouveau + + + THERE_IS_NO_OBJECT_FOR_EDITING + Il n'y a pas d'objet à éditer. +Sélectionnez un maillage ou un sous-maillage et essayez de nouveau + + + + SMESHGUI_MeshPatternDlg + + 3D_BLOCK + Bloc 3D + + + CAPTION + Projection de motif + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Créer des polyèdres près de la frontière + + + CREATE_POLYGONS_NEAR_BOUNDARY + Créer des polygones près de la frontière + + + ERROR_OF_LOADING + Impossible de charger le motif. +Il est probable que le fichier est corrompu ou contient un autre type de motif + + + ERROR_OF_OPENING + Il est impossible d'ouvrir le fichier. +Vérifiez s'il existe et si vous avez l'autorisation + + + ERROR_OF_READING + Il est impossible de charger le motif +Vérifiez le contenu du fichier + + + ERR_READ_3D_COORD + Il est impossible de charger le motif +Les coordonnées des points 3D sont en dehors de l'intervalle [0,1] + + + ERR_READ_BAD_INDEX + Il est impossible de charger le motif +Un index de point invalide a été detecté + + + ERR_READ_BAD_KEY_POINT + Il est impossible de charger le motif +Le point-clef n'est pas situé sur la frontière + + + ERR_READ_ELEM_POINTS + Il est impossible de charger le motif +Le nombre de points de l'élément est invalide + + + ERR_READ_NB_POINTS + Il est impossible de charger le motif +Il est impossible de lire le nombre de points dans le fichier + + + ERR_READ_NO_ELEMS + Il est impossible de charger le motif +Il ne contient pas d'éléments + + + ERR_READ_NO_KEYPOINT + Il est impossible de charger le motif +Le motif 2D n'a pas de point-clef + + + ERR_READ_POINT_COORDS + Il est impossible de charger le motif +Il est impossible de lire les coordonnées des points dans le fichier + + + ERR_READ_TOO_FEW_POINTS + Il est impossible de charger le motif. +Il y a trop peu de points dans le fichier + + + FACE + Face + + + LOAD_PATTERN + Charger un motif + + + MESH_FACES + Faces du maillage + + + MESH_VOLUMES + Volumes du maillage + + + NEW + Nouveau... + + + NODE_1 + Nœud 1 + + + NODE_2 + Nœud 2 + + + PATTERN + Motif + + + PATTERN_FILT + Fichiers de motif (*.smp) + + + PATTERN_TYPE + Type de motif + + + PREVIEW + Prévisualiser + + + REFINE + Raffiner les éléments de maillage sélectionnés + + + REVERSE + Inverser l'ordre des points-clefs + + + VERTEX + Sommet... + + + VERTEX1 + Sommet 1 + + + VERTEX2 + Sommet 2 + + + + SMESHGUI_MeshTab + + ADD_HYPOTHESIS + Ajouter l'hypothèse + + + ALGORITHM + Algorithme + + + HYPOTHESIS + Hypothèse + + + NONE + <None> + + + + SMESHGUI_MultiEditDlg + + ADD + Ajouter + + + FILTER + Filtre + + + REMOVE + Supprimer + + + SELECT_FROM + Sélectionner à partir de + + + SORT_LIST + Trier la liste + + + SPLIT_JOIN_CRITERION + Critère + + + TO_ALL + Appliquer à tous + + + USE_DIAGONAL_1_3 + Utiliser la diagonale 1-3 + + + USE_DIAGONAL_2_4 + Utiliser la diagonale 2-4 + + + USE_NUMERIC_FUNC + Utiliser le facteur numérique + + + + SMESHGUI_CuttingIntoTetraDlg + + CAPTION + Diviser les volumes en tétraèdres + + + SPLIT_METHOD + Diviser l'hexaèdre + + + SPLIT_HEX_TO_5_TETRA + En 5 tétraèdres + + + SPLIT_HEX_TO_6_TETRA + En 6 tétraèdres + + + SPLIT_HEX_TO_24_TETRA + En 24 tétraèdres + + + + SMESHGUI_PrecisionDlg + + CAPTION + Précision pour les contrôles de qualité du maillage + + + NOT_USE + Ne pas utiliser! + + + PRECISION + Nombre de chiffres après la virgule + + + + SMESHGUI_RevolutionDlg + + ANGLE_BY_STEP + Angle par pas + + + PREVIEW + Prévisualiser + + + REVOLUTION_1D + Révolution des éléments 1D + + + REVOLUTION_2D + Révolution des éléments 2D + + + REVOLUTION_AROUND_AXIS + Révolution autour d'un axe + + + TOTAL_ANGLE + Angle total + + + MEN_POINT_SELECT + De l'origine au point sélectionner + + + MEN_FACE_SELECT + Normale de la face sélectionnée + + + + SMESHGUI_SewingDlg + + BORDER + Frontière + + + BORDER_1 + Frontière 1 + + + BORDER_2 + Frontière 2 + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Remplacer les volumes concernés par des polyèdres + + + CREATE_POLYGONS_INSTEAD_SPLITTING + Créer des polygones au lieu de redécouper + + + ERROR_1 + La frontière Libre1 n'est pas trouvée avec les nœuds sélectionnés + + + ERROR_2 + La frontière Libre2 n'est pas trouvée avec les nœuds sélectionnés + + + ERROR_3 + Les frontières Libres 1 et 2 n'ont pas été trouvées avec les nœuds sélectionnés + + + ERROR_4 + Aucun chemin du premier au dernier nœud de la frontière n'est trouvé + + + ERROR_5 + Il n'est pas permis de découper les volumes de bord! + + + ERROR_6 + Le nombre d'éléments sélectionnés est différent de chaque côté + + + ERROR_7 + Les jeux d'éléments sont topologiquement différents ou les nœuds ne conviennent pas + + + ERROR_8 + Les nœuds du côté 1 soit ne sont pas connectés soit ne sont pas situés à la frontière du jeu d'éléments + + + ERROR_9 + Les nœuds du côté 2 soit ne sont pas connectés soit ne sont pas situés à la frontière de l'élément + + + FIRST_NODE_ID + ID du premier nœud + + + LAST_NODE_ID + ID du dernier nœud + + + MERGE_EQUAL_ELEMENTS + Fusionner les éléments égaux + + + NODE1_TO_MERGE + Nœud 1 à fusionner + + + NODE2_TO_MERGE + Nœud 2 à fusionner + + + SECOND_NODE_ID + ID du deuxième nœud + + + SEW_BORDER_TO_SIDE + Coudre la frontière au côté + + + SEW_CONFORM_FREE_BORDERS + Coudre les frontières libres conformes + + + SEW_FREE_BORDERS + Coudre les frontières libres + + + SEW_SIDE_ELEMENTS + Coudre les éléments de bord + + + SIDE + Bord + + + SIDE_1 + Bord 1 + + + SIDE_2 + Bord 2 + + + + SMESHGUI_ShapeByMeshDlg + + CAPTION + Trouver la géométrie par le maillage + + + + SMESHGUI_SingleEditDlg + + EDGE_BETWEEN + Arête entre des triangles voisins + + + + SMESHGUI_SmoothingDlg + + CENTROIDAL + Centroïdal + + + FIXED_NODES_IDS + IDs des nœuds fixes + + + IS_PARAMETRIC + dans l'espace paramétrique + + + ITERATION_LIMIT + Limite d'Itération + + + LAPLACIAN + Laplacien + + + MAX_ASPECT_RATIO + Rapport de forme maximal + + + METHOD + Méthode + + + + SMESHGUI_TrianglesInversionDlg + + CAPTION + Inversion de diagonale + + + + SMESHGUI_UnionOfTrianglesDlg + + CAPTION + Union des triangles + + + MAXIMUM_ANGLE + Angle maximal de pliage + + + + SMESHGUI_UnionOfTwoTrianglesDlg + + CAPTION + Union de deux triangles + + + + SMESHGUI_FileInfoDlg + + CAPTION + Informations sur le fichier + + + FILE_NAME + Nom du fichier + + + FILE_SIZE + Taille du fichier (bytes) + + + MED_VERSION + Version MED + + + + SMESHGUI_GroupOnShapeDlg + + SMESH_CREATE_GROUP_FROM_GEOM + Créer des groupes à partir de la géométrie + + + + SMESHGUI_MeshOrderDlg + + SMESH_MESHORDER_TITLE + Ordre des sous-maillages dans la procédure de maillage + + + + SMESHGUI_MeshOrderOp + + SMESH_NO_CONCURENT_MESH + Pas de sous-maillages concurrents détectés + + + + SMESHGUI_ClippingDlg + + CLIP_PLANES + Plans de découpe + + + MESHES_SUBMESHES_GROUPS + Maillages, sous-maillages et groupes + + + SELECT_ALL + Tout sélectionner + + + ROTATION_AROUND_X_Y2Z + Rotation autour de X (Y à Z): + + + ROTATION_AROUND_Y_X2Z + Rotation autour de Y (X à Z): + + + ROTATION_AROUND_Z_Y2X + Rotation autour de Z (Y à X): + + + ROTATION_AROUND_X_Z2Y + Rotation autour de X (Z à Y): + + + ROTATION_AROUND_Y_Z2X + Rotation autour de Y (Z à X): + + + ROTATION_AROUND_Z_X2Y + Rotation autour de Z (X à Y): + + + SHOW_PREVIEW + Prévisualiser + + + AUTO_APPLY + Appliquer automatiquement + + + ALONG_XY + || X-Y + + + ALONG_YZ + || Y-Z + + + ALONG_ZX + || Z-X + + + PLANE_NUM + Plan# %1 + + + NO_PLANES + Pas de plans + + + + SMESHGUI_DuplicateNodesDlg + + DUPLICATION_MODE + Mode de duplication + + + DUPLICATION_WITHOUT_ELEMS + Sans duplication des éléments de frontière + + + GROUP_NODES_TO_DUPLICATE + Groupe des nœuds à dupliquer + + + GROUP_NODES_TO_REPLACE + Groupe des éléments dont les nœuds sont à remplacer + + + DUPLICATION_WITH_ELEMS + Avec duplication des éléments de frontière + + + GROUP_ELEMS_TO_DUPLICATE + Groupe des éléments à dupliquer + + + GROUP_NODES_NOT_DUPLICATE + Groupe des nœuds à ne pas dupliquer + + + GROUP_ELEMS_TO_REPLACE + Groupe des éléments dont les nœuds sont à remplacer + + + CONSTRUCT_NEW_GROUP_NODES + Construire un groupe avec les nœuds nouvellement créés + + + CONSTRUCT_NEW_GROUP_ELEMENTS + Construire un groupe avec les éléments nouvellement créés + + + + SMESHGUI_Make2DFrom3DDlg + + CAPTION + Créer les éléments de frontière + + + Groups + Groupes 2D + + + MODE + Mode + + + 2D_FROM_3D + 2D à partir de 3D + + + 1D_FROM_3D + 1D à partir de groupes 2D + + + 1D_FROM_2D + 1D à partir de 2D + + + TARGET + Cible + + + THIS_MESH + Ce maillage + + + NEW_MESH + Nouveau maillage + + + COPY_SRC + Copier le maillage source + + + MISSING_ONLY + Copier seulement les éléments manquants + + + CREATE_GROUP + Créer un groupe + + + + SMESHGUI_Make2DFrom3DOp + + NB_ADDED + %1 éléments de bord ont été ajoutés + + + WRONG_GROUPS + Les groupes suivants n'ont pas été traités +en raison de leurs types incompatibles: +%1 + + + SMESH_ERR_NO_INPUT_MESH + Aucun maillage, sous-maillage ou groupe source n'est indiqué + + + SMESH_TOO_MANY_MESHES + Un seul maillage à la fois peut être traité + + + SMESH_NOT_ONLY_GROUPS + Impossible de traiter à la fois des maillages et des groupes + + + SMESH_ERR_NO_3D_ELEMENTS + L'objet source ne contient pas d'éléments 3D + + + SMESH_ERR_NO_2D_ELEMENTS + L'objet source ne contient pas d'éléments 2D + + + SMESH_ERR_MESH_NAME_NOT_SPECIFIED + Le nom du nouveau maillage n'est pas indiqué + + + SMESH_ERR_GRP_NAME_NOT_SPECIFIED + Le nom du groupe n'est pas indiqué + + + + SMESHGUI_MeshInfo + + NAME_LAB + Nom: + + + OBJECT_LAB + Objet: + + + NODES_LAB + Nœuds: + + + ELEMENTS_LAB + Eléments: + + + TOTAL_LAB + Total + + + LINEAR_LAB + Linéaire + + + QUADRATIC_LAB + Quadratique + + + 0D_LAB + 0D: + + + BALL_LAB + Particulaires: + + + 1D_LAB + 1D (arêtes): + + + 2D_LAB + 2D (faces): + + + TRIANGLES_LAB + Triangles: + + + QUADRANGLES_LAB + Quadrangles: + + + POLYGONS_LAB + Polygones: + + + 3D_LAB + 3D (volumes): + + + TETRAHEDRONS_LAB + Tétraèdres: + + + HEXAHEDONRS_LAB + Hexaèdres: + + + PYRAMIDS_LAB + Pyramides: + + + PRISMS_LAB + Prismes: + + + HEX_PRISMS_LAB + Prismes hexagonaux: + + + POLYHEDRONS_LAB + Polyèdres: + + + OBJECT_MESH + Maillage + + + OBJECT_SUBMESH + Sous-maillage + + + OBJECT_GROUP + Groupe + + + OBJECT_GROUP_NODES + Groupe de nœuds + + + OBJECT_GROUP_EDGES + Groupe d'arêtes + + + OBJECT_GROUP_FACES + Groupe de faces + + + OBJECT_GROUP_VOLUMES + Groupe de volumes + + + OBJECT_GROUP_0DELEMS + Groupe d'éléments 0D + + + OBJECT_GROUP_BALLS + Groupe d'éléments particulaires + + + BUT_LOAD_MESH + Charger un maillage depuis un serveur + + + + SMESHGUI_MeshInfoDlg + + MESH_INFO + Informations de maillage + + + BASE_INFO + Informations de base + + + ELEM_INFO + Infos sur les éléments + + + ADDITIONAL_INFO + Infos détaillées + + + NODE_MODE + Nœud + + + ELEM_MODE + Elément + + + X_FROM_Y_ITEMS_SHOWN + %1-%2 sur %3 éléments affichés + + + + SMESHGUI_ElemInfo + + COORDINATES + COORDONNÉES + + + CONNECTIVITY + CONNECTIVITÉ + + + GRAVITY_CENTER + CENTRE DE GRAVITÉ + + + NODE + Nœud + + + 0D_ELEMENT + ELÉMENTS 0D + + + 0D_ELEMENTS + ELÉMENTS 0D + + + BALL_ELEMENT + ELEMENT PARTICULAIRE + + + BALL_ELEMENTS + ELEMENTS PARTICULAIRES + + + EDGE + ARÊTE + + + EDGES + ARÊTES + + + FACE + FACE + + + FACES + FACES + + + VOLUME + VOLUME + + + VOLUMES + VOLUMES + + + FREE_NODE + Nœud libre (pas de connectivité) + + + TYPE + TYPE + + + TRIANGLE + Triangle + + + QUADRANGLE + Quadrangle + + + POLYGON + Polygone + + + TETRAHEDRON + Tétraèdre + + + HEXAHEDRON + Hexaèdre + + + PYRAMID + Pyramide + + + PRISM + Prisme + + + HEX_PRISM + Prisme hexagonal + + + POLYHEDRON + Polyèdre + + + QUADRATIC + QUADRATIQUE + + + YES + Oui + + + NO + Non + + + PROPERTY + Propriété + + + VALUE + Valeur + + + + SMESHGUI_AddInfo + + NAME + Nom + + + GROUPS + Groupes + + + GROUPS_1 + Nœuds + + + GROUPS_2 + Arêtes + + + GROUPS_3 + Faces + + + GROUPS_4 + Volumes + + + GROUPS_5 + Eléments 0D + + + GROUPS_6 + Eléments particulaires + + + PARENT_MESH + Maillage parent + + + TYPE + Type + + + STANDALONE_GROUP + Groupe autonome + + + GROUP_ON_GEOMETRY + Groupe lié à une géométrie + + + GROUP_ON_FILTER + Groupe lié à un filtre + + + GEOM_OBJECT + Shape + + + NODE + Nœud + + + EDGE + Arête + + + FACE + Face + + + VOLUME + Volume + + + 0DELEM + Elément 0D + + + BALL_ELEMENT + Elément particulaire + + + UNKNOWN + Inconnu + + + ENTITY_TYPE + Type de maille + + + SIZE + Taille + + + COLOR + Couleur + + + NB_NODES + Nœuds sous-jacents + + + COMPUTE + Calculer + + + LOAD + Charger + + + MESH_ON_GEOMETRY + Lié à une géométrie + + + MESH_FROM_FILE + Importé + + + FILE_NAME + Nom du fichier + + + STANDALONE_MESH + Autonome + + + SUBMESHES + Sous-maillages + + + SUBMESHES_0 + Assemblage + + + SUBMESHES_2 + Solide + + + SUBMESHES_3 + Coque + + + SUBMESHES_4 + Face + + + SUBMESHES_5 + Contour + + + SUBMESHES_6 + Arêtes + + + SUBMESHES_7 + Point + + + + SMESHGUI_MinDistance + + FIRST_TARGET + Premier élément + + + SECOND_TARGET + Deuxième élément + + + NODE + Nœud + + + ELEMENT + Elément + + + OBJECT + Objet + + + ORIGIN + Origine + + + COMPUTE + Calculer + + + RESULT + Distance entre les éléments + + + DISTANCE + Distance + + + + SMESHGUI_CopyMeshDlg + + OBJECT_NAME + Objet source + + + ELEM_IDS + IDs des éléments sources + + + NEW_NAME + Nom du nouveau maillage + + + + SMESHGUI_MeasureDlg + + MEASUREMENTS + Outils de mesure + + + MIN_DIST + Distance minimale + + + BND_BOX + Boîte englobante + + + + SMESHGUI_BoundingBox + + SOURCE + Source + + + OBJECTS + Objets + + + NODES + Nœuds + + + ELEMENTS + Eléments + + + COMPUTE + Calculer + + + RESULT + Boîte englobante + + + SELECTED_NB_OBJ + %1 %2 sélectionnés + + + NB_NODES + nœuds + + + NB_ELEMENTS + éléments + + + + SMESHGUI_MeshLoadingProgress + + MESH_LOAD_PROGRESS_TITLE + Chargement du maillage en cours + + + + StdMeshersGUI_SubShapeSelectorWdg + + X_FROM_Y_ITEMS_SHOWN + %1-%2 sur %3 éléments affichés + + + + SMESHGUI_Preferences_ColorDlg + + DIALOG_TITLE + Propriétés (couleur, épaisseur des traits, taille des éléments réduits, ...) + + + GRP_ELEMENTS + Eléments + + + SURFACE_COLOR_LBL + Couleur de surface + + + BACKSURFACE_COLOR_LBL + Couleur arrière + + + OUTLINE_COLOR_LBL + Couleur de contour + + + WIREFRAME_COLOR_LBL + Couleur en mode fil de fer + + + 0D_ELEMENTS_COLOR_LBL + Eléments 0D + + + 0D_ELEMENTS_SIZE_LBL + Taille des éléments 0D + + + BALL_ELEMENTS_COLOR_LBL + Eléments particulaires + + + BALL_ELEMENTS_SIZE_LBL + Taille des éléments particulaires + + + LINE_WIDTH_LBL + Epaisseur des traits + + + SHRINK_COEF_LBL + Coef. de contraction + + + GRP_NODES + Nœuds + + + NODES_COLOR_LBL + Couleur + + + NODES_MARKER_LBL + Marqueur + + + GRP_ORIENTATION + Orientation des faces + + + ORIENTATION_COLOR_LBL + Couleur + + + ORIENTATION_SCALE_LBL + Facteur d'échelle + + + 3D_VECTORS_LBL + Vecteurs 3D + + + GRP_SELECTION + Sélection + + + SELECTION_COLOR_LBL + Couleur de sélection + + + PRESELECTION_COLOR_LBL + Couleur de pré-sélection + + + + SMESHGUI_ReorientFacesDlg + + CAPTION + Réorienter des faces selon un vector + + + REORIENT_FACES + Réorienter + + + DIRECTION + Direction + + + OBJECT + Objet + + + POINT + Point + + + FACE + Face + + + FACES + Source des faces + + + ORIENTATION + Orientation + + + + SMESHGUI_ReorientFacesOp + + NO_OBJECT_SELECTED + Aucun objet sélectionné + + + NO_FACES + L'objet ne contient pas de faces + + + ZERO_SIZE_VECTOR + Vecteur de taille nulle + + + INVALID_FACE + Face non valide + + + NB_REORIENTED + %1 face(s) inversée(s) + + + diff --git a/src/SMESHUtils/Makefile.am b/src/SMESHUtils/Makefile.am new file mode 100644 index 000000000..0e5f87624 --- /dev/null +++ b/src/SMESHUtils/Makefile.am @@ -0,0 +1,57 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# File : Makefile.in +# Module : SMESH +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# header files +salomeinclude_HEADERS = \ + SMESH_Block.hxx \ + SMESH_TypeDefs.hxx \ + SMESH_Octree.hxx \ + SMESH_OctreeNode.hxx \ + SMESH_Comment.hxx \ + SMESH_ComputeError.hxx \ + SMESH_File.hxx \ + SMESH_Utils.hxx + +# Libraries targets + +lib_LTLIBRARIES = libSMESHUtils.la + +dist_libSMESHUtils_la_SOURCES = \ + SMESH_Block.cxx \ + SMESH_Octree.cxx \ + SMESH_OctreeNode.cxx \ + SMESH_File.cxx + +# additionnal information to compile and link file +libSMESHUtils_la_CPPFLAGS = \ + $(KERNEL_CXXFLAGS) \ + $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ + $(BOOST_CPPFLAGS) \ + -I$(srcdir)/../SMDS \ + -I$(srcdir)/../SMESHDS + +libSMESHUtils_la_LDFLAGS = \ + ../SMESHDS/libSMESHDS.la \ + $(CAS_LDPATH) -lTKShHealing -lTKPrim -lTKG2d -lTKG3d -lTKGeomBase diff --git a/src/SMESHUtils/SMESH_Block.cxx b/src/SMESHUtils/SMESH_Block.cxx new file mode 100644 index 000000000..b28dc7d67 --- /dev/null +++ b/src/SMESHUtils/SMESH_Block.cxx @@ -0,0 +1,1737 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_Pattern.hxx +// Created : Mon Aug 2 10:30:00 2004 +// Author : Edward AGAPOV (eap) +// +#include "SMESH_Block.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SMDS_MeshNode.hxx" +#include "SMDS_MeshVolume.hxx" +#include "SMDS_VolumeTool.hxx" +#include "utilities.h" + +#include + +using namespace std; + +//#define DEBUG_PARAM_COMPUTE + +//================================================================================ +/*! + * \brief Set edge data + * \param edgeID - block sub-shape ID + * \param curve - edge geometry + * \param isForward - is curve orientation coincides with edge orientation in the block + */ +//================================================================================ + +void SMESH_Block::TEdge::Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward ) +{ + myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID ); + if ( myC3d ) delete myC3d; + myC3d = curve; + myFirst = curve->FirstParameter(); + myLast = curve->LastParameter(); + if ( !isForward ) + std::swap( myFirst, myLast ); +} + +//================================================================================ +/*! + * \brief Set coordinates of nodes at edge ends to work with mesh block + * \param edgeID - block sub-shape ID + * \param node1 - coordinates of node with lower ID + * \param node2 - coordinates of node with upper ID + */ +//================================================================================ + +void SMESH_Block::TEdge::Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 ) +{ + myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID ); + myNodes[ 0 ] = node1; + myNodes[ 1 ] = node2; + + if ( myC3d ) delete myC3d; + myC3d = 0; +} + +//======================================================================= +//function : SMESH_Block::TEdge::GetU +//purpose : +//======================================================================= + +double SMESH_Block::TEdge::GetU( const gp_XYZ& theParams ) const +{ + double u = theParams.Coord( myCoordInd ); + if ( !myC3d ) // if mesh block + return u; + return ( 1 - u ) * myFirst + u * myLast; +} + +//======================================================================= +//function : SMESH_Block::TEdge::Point +//purpose : +//======================================================================= + +gp_XYZ SMESH_Block::TEdge::Point( const gp_XYZ& theParams ) const +{ + double u = GetU( theParams ); + if ( myC3d ) return myC3d->Value( u ).XYZ(); + // mesh block + return myNodes[0] * ( 1 - u ) + myNodes[1] * u; +} + +//================================================================================ +/*! + * \brief Destructor + */ +//================================================================================ + +SMESH_Block::TEdge::~TEdge() +{ + if ( myC3d ) delete myC3d; +} + +//================================================================================ +/*! + * \brief Set face data + * \param faceID - block sub-shape ID + * \param S - face surface geometry + * \param c2d - 4 pcurves in the order as returned by GetFaceEdgesIDs(faceID) + * \param isForward - orientation of pcurves comparing with block edge direction + */ +//================================================================================ + +void SMESH_Block::TFace::Set( const int faceID, + Adaptor3d_Surface* S, + Adaptor2d_Curve2d* c2D[4], + const bool isForward[4] ) +{ + if ( myS ) delete myS; + myS = S; + // pcurves + vector< int > edgeIdVec; + GetFaceEdgesIDs( faceID, edgeIdVec ); + for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges + { + myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] ); + if ( myC2d[ iE ]) delete myC2d[ iE ]; + myC2d[ iE ] = c2D[ iE ]; + myFirst[ iE ] = myC2d[ iE ]->FirstParameter(); + myLast [ iE ] = myC2d[ iE ]->LastParameter(); + if ( !isForward[ iE ]) + std::swap( myFirst[ iE ], myLast[ iE ] ); + } + // 2d corners + myCorner[ 0 ] = myC2d[ 0 ]->Value( myFirst[0] ).XY(); + myCorner[ 1 ] = myC2d[ 0 ]->Value( myLast[0] ).XY(); + myCorner[ 2 ] = myC2d[ 1 ]->Value( myLast[1] ).XY(); + myCorner[ 3 ] = myC2d[ 1 ]->Value( myFirst[1] ).XY(); +} + +//================================================================================ +/*! + * \brief Set face data to work with mesh block + * \param faceID - block sub-shape ID + * \param edgeU0 - filled data of edge u0 = GetFaceEdgesIDs(faceID)[ 0 ] + * \param edgeU1 - filled data of edge u1 = GetFaceEdgesIDs(faceID)[ 1 ] + */ +//================================================================================ + +void SMESH_Block::TFace::Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 ) +{ + vector< int > edgeIdVec; + GetFaceEdgesIDs( faceID, edgeIdVec ); + myNodes[ 0 ] = edgeU0.NodeXYZ( 1 ); + myNodes[ 1 ] = edgeU0.NodeXYZ( 0 ); + myNodes[ 2 ] = edgeU1.NodeXYZ( 0 ); + myNodes[ 3 ] = edgeU1.NodeXYZ( 1 ); + myCoordInd[ 0 ] = GetCoordIndOnEdge( edgeIdVec[ 0 ] ); + myCoordInd[ 1 ] = GetCoordIndOnEdge( edgeIdVec[ 1 ] ); + myCoordInd[ 2 ] = GetCoordIndOnEdge( edgeIdVec[ 2 ] ); + myCoordInd[ 3 ] = GetCoordIndOnEdge( edgeIdVec[ 3 ] ); + if ( myS ) delete myS; + myS = 0; +} + +//================================================================================ +/*! + * \brief Destructor + */ +//================================================================================ + +SMESH_Block::TFace::~TFace() +{ + if ( myS ) delete myS; + for ( int i = 0 ; i < 4; ++i ) + if ( myC2d[ i ]) delete myC2d[ i ]; +} + +//======================================================================= +//function : SMESH_Block::TFace::GetCoefs +//purpose : return coefficients for addition of [0-3]-th edge and vertex +//======================================================================= + +void SMESH_Block::TFace::GetCoefs(int iE, + const gp_XYZ& theParams, + double& Ecoef, + double& Vcoef ) const +{ + double dU = theParams.Coord( GetUInd() ); + double dV = theParams.Coord( GetVInd() ); + switch ( iE ) { + case 0: + Ecoef = ( 1 - dV ); // u0 + Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00 + case 1: + Ecoef = dV; // u1 + Vcoef = dU * ( 1 - dV ); break; // 10 + case 2: + Ecoef = ( 1 - dU ); // 0v + Vcoef = dU * dV ; break; // 11 + case 3: + Ecoef = dU ; // 1v + Vcoef = ( 1 - dU ) * dV ; break; // 01 + default: ASSERT(0); + } +} + +//======================================================================= +//function : SMESH_Block::TFace::GetUV +//purpose : +//======================================================================= + +gp_XY SMESH_Block::TFace::GetUV( const gp_XYZ& theParams ) const +{ + gp_XY uv(0.,0.); + for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges + { + double Ecoef = 0, Vcoef = 0; + GetCoefs( iE, theParams, Ecoef, Vcoef ); + // edge addition + double u = theParams.Coord( myCoordInd[ iE ] ); + u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ]; + uv += Ecoef * myC2d[ iE ]->Value( u ).XY(); + // corner addition + uv -= Vcoef * myCorner[ iE ]; + } + return uv; +} + +//======================================================================= +//function : SMESH_Block::TFace::Point +//purpose : +//======================================================================= + +gp_XYZ SMESH_Block::TFace::Point( const gp_XYZ& theParams ) const +{ + gp_XYZ p(0.,0.,0.); + if ( !myS ) // if mesh block + { + for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges + { + double Ecoef = 0, Vcoef = 0; + GetCoefs( iE, theParams, Ecoef, Vcoef ); + // edge addition + double u = theParams.Coord( myCoordInd[ iE ] ); + int i1 = 0, i2 = 1; + switch ( iE ) { + case 1: i1 = 3; i2 = 2; break; + case 2: i1 = 1; i2 = 2; break; + case 3: i1 = 0; i2 = 3; break; + } + p += Ecoef * ( myNodes[ i1 ] * ( 1 - u ) + myNodes[ i2 ] * u ); + // corner addition + p -= Vcoef * myNodes[ iE ]; + } + + } + else // shape block + { + gp_XY uv = GetUV( theParams ); + p = myS->Value( uv.X(), uv.Y() ).XYZ(); + } + return p; +} + +//======================================================================= +//function : GetShapeCoef +//purpose : +//======================================================================= + +double* SMESH_Block::GetShapeCoef (const int theShapeID) +{ + static double shapeCoef[][3] = { + // V000, V100, V010, V110 + { -1,-1,-1 }, { 1,-1,-1 }, { -1, 1,-1 }, { 1, 1,-1 }, + // V001, V101, V011, V111, + { -1,-1, 1 }, { 1,-1, 1 }, { -1, 1, 1 }, { 1, 1, 1 }, + // Ex00, Ex10, Ex01, Ex11, + { 0,-1,-1 }, { 0, 1,-1 }, { 0,-1, 1 }, { 0, 1, 1 }, + // E0y0, E1y0, E0y1, E1y1, + { -1, 0,-1 }, { 1, 0,-1 }, { -1, 0, 1 }, { 1, 0, 1 }, + // E00z, E10z, E01z, E11z, + { -1,-1, 0 }, { 1,-1, 0 }, { -1, 1, 0 }, { 1, 1, 0 }, + // Fxy0, Fxy1, Fx0z, Fx1z, F0yz, F1yz, + { 0, 0,-1 }, { 0, 0, 1 }, { 0,-1, 0 }, { 0, 1, 0 }, { -1, 0, 0 }, { 1, 0, 0 }, + // ID_Shell + { 0, 0, 0 } + }; + if ( theShapeID < ID_V000 || theShapeID > ID_F1yz ) + return shapeCoef[ ID_Shell - 1 ]; + + return shapeCoef[ theShapeID - 1 ]; +} + +//======================================================================= +//function : ShellPoint +//purpose : return coordinates of a point in shell +//======================================================================= + +bool SMESH_Block::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const +{ + thePoint.SetCoord( 0., 0., 0. ); + for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ ) + { + // coef + double* coefs = GetShapeCoef( shapeID ); + double k = 1; + for ( int iCoef = 0; iCoef < 3; iCoef++ ) { + if ( coefs[ iCoef ] != 0 ) { + if ( coefs[ iCoef ] < 0 ) + k *= ( 1. - theParams.Coord( iCoef + 1 )); + else + k *= theParams.Coord( iCoef + 1 ); + } + } + // add point on a shape + if ( fabs( k ) > DBL_MIN ) + { + gp_XYZ Ps; + if ( shapeID < ID_Ex00 ) // vertex + VertexPoint( shapeID, Ps ); + else if ( shapeID < ID_Fxy0 ) { // edge + EdgePoint( shapeID, theParams, Ps ); + k = -k; + } else // face + FacePoint( shapeID, theParams, Ps ); + + thePoint += k * Ps; + } + } + return true; +} + +//======================================================================= +//function : ShellPoint +//purpose : computes coordinates of a point in shell by points on sub-shapes; +// thePointOnShape[ subShapeID ] must be a point on a sub-shape +//======================================================================= + +bool SMESH_Block::ShellPoint(const gp_XYZ& theParams, + const vector& thePointOnShape, + gp_XYZ& thePoint ) +{ + if ( thePointOnShape.size() < ID_F1yz ) + return false; + + const double x = theParams.X(), y = theParams.Y(), z = theParams.Z(); + const double x1 = 1. - x, y1 = 1. - y, z1 = 1. - z; + const vector& p = thePointOnShape; + + thePoint = + x1 * p[ID_F0yz] + x * p[ID_F1yz] + + y1 * p[ID_Fx0z] + y * p[ID_Fx1z] + + z1 * p[ID_Fxy0] + z * p[ID_Fxy1] + + x1 * (y1 * (z1 * p[ID_V000] + z * p[ID_V001]) + + y * (z1 * p[ID_V010] + z * p[ID_V011])) + + x * (y1 * (z1 * p[ID_V100] + z * p[ID_V101]) + + y * (z1 * p[ID_V110] + z * p[ID_V111])); + thePoint -= + x1 * (y1 * p[ID_E00z] + y * p[ID_E01z]) + + x * (y1 * p[ID_E10z] + y * p[ID_E11z]) + + y1 * (z1 * p[ID_Ex00] + z * p[ID_Ex01]) + + y * (z1 * p[ID_Ex10] + z * p[ID_Ex11]) + + z1 * (x1 * p[ID_E0y0] + x * p[ID_E1y0]) + + z * (x1 * p[ID_E0y1] + x * p[ID_E1y1]); + + return true; +} + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= + +SMESH_Block::SMESH_Block(): + myNbIterations(0), + mySumDist(0.), + myTolerance(-1.) // to be re-initialized +{ +} + + +//======================================================================= +//function : NbVariables +//purpose : +//======================================================================= + +Standard_Integer SMESH_Block::NbVariables() const +{ + return 3; +} + +//======================================================================= +//function : NbEquations +//purpose : +//======================================================================= + +Standard_Integer SMESH_Block::NbEquations() const +{ + return 1; +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= + +Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theFxyz) +{ + gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) ); + if ( params.IsEqual( myParam, DBL_MIN )) { // same param + theFxyz( 1 ) = funcValue( myValues[ SQUARE_DIST ]); + } + else { + ShellPoint( params, P ); + gp_Vec dP( P - myPoint ); + theFxyz(1) = funcValue( dP.SquareMagnitude() ); + } + return true; +} + +//======================================================================= +//function : Derivatives +//purpose : +//======================================================================= + +Standard_Boolean SMESH_Block::Derivatives(const math_Vector& XYZ,math_Matrix& Df) +{ + math_Vector F(1,3); + return Values(XYZ,F,Df); +} + +//======================================================================= +//function : GetStateNumber +//purpose : +//======================================================================= + +Standard_Integer SMESH_Block::GetStateNumber () +{ + return 0; //myValues[0] < 1e-1; +} + +//======================================================================= +//function : Values +//purpose : +//======================================================================= + +Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ, + math_Vector& theFxyz, + math_Matrix& theDf) +{ + gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) ); + if ( params.IsEqual( myParam, DBL_MIN )) { // same param + theFxyz( 1 ) = funcValue( myValues[ SQUARE_DIST ] ); + theDf( 1, DRV_1 ) = myValues[ DRV_1 ]; + theDf( 1, DRV_2 ) = myValues[ DRV_2 ]; + theDf( 1, DRV_3 ) = myValues[ DRV_3 ]; + return true; + } +#ifdef DEBUG_PARAM_COMPUTE + MESSAGE ( "PARAM GUESS: " << params.X() << " "<< params.Y() << " "<< params.X() ); + myNbIterations++; // how many times call ShellPoint() +#endif + ShellPoint( params, P ); + + gp_Vec dP( myPoint, P ); + double sqDist = dP.SquareMagnitude(); + theFxyz(1) = funcValue( sqDist ); + + if ( sqDist < myTolerance * myTolerance ) { // a solution found + myParam = params; + myValues[ SQUARE_DIST ] = sqDist; + theFxyz(1) = theDf( 1,1 ) = theDf( 1,2 ) = theDf( 1,3 ) = 0; + return true; + } + + if ( sqDist < myValues[ SQUARE_DIST ] ) // a better guess + { + // 3 partial derivatives + gp_Vec drv[ 3 ]; // where we move with a small step in each direction + for ( int iP = 1; iP <= 3; iP++ ) { + if ( iP == myFaceIndex ) { + drv[ iP - 1 ] = gp_Vec(0,0,0); + continue; + } + gp_XYZ Pi; + bool onEdge = ( theXYZ( iP ) + 0.001 > 1. ); + if ( onEdge ) + params.SetCoord( iP, theXYZ( iP ) - 0.001 ); + else + params.SetCoord( iP, theXYZ( iP ) + 0.001 ); + ShellPoint( params, Pi ); + params.SetCoord( iP, theXYZ( iP ) ); // restore params + gp_Vec dPi ( P, Pi ); + if ( onEdge ) dPi *= -1.; + double mag = dPi.Magnitude(); + if ( mag > DBL_MIN ) + dPi /= mag; + drv[ iP - 1 ] = dPi; + } + for ( int iP = 0; iP < 3; iP++ ) { +#if 1 + theDf( 1, iP + 1 ) = dP * drv[iP]; +#else + // Distance from P to plane passing through myPoint and defined + // by the 2 other derivative directions: + // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P) + // where L is (P -> myPoint), P is defined by the 2 other derivative direction + int iPrev = ( iP ? iP - 1 : 2 ); + int iNext = ( iP == 2 ? 0 : iP + 1 ); + gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] ); + double Direc = plnNorm * drv[ iP ]; + if ( Abs(Direc) <= DBL_MIN ) + theDf( 1, iP + 1 ) = dP * drv[ iP ]; + else { + double Dis = plnNorm * P - plnNorm * myPoint; + theDf( 1, iP + 1 ) = Dis/Direc; + } +#endif + } +#ifdef DEBUG_PARAM_COMPUTE + MESSAGE ( "F = " << theFxyz(1) << " DRV: " << theDf(1,1) << " " << theDf(1,2) << " " << theDf(1,3) ); + myNbIterations +=3; // how many times call ShellPoint() +#endif + + // store better values + myParam = params; + myValues[SQUARE_DIST]= sqDist; + myValues[DRV_1] = theDf(1,DRV_1); + myValues[DRV_2] = theDf(1,DRV_2); + myValues[DRV_3] = theDf(1,DRV_3); + } + + return true; +} + +//============================================================================ +//function : computeParameters +//purpose : compute point parameters in the block using math_FunctionSetRoot +//============================================================================ + +bool SMESH_Block::computeParameters(const gp_Pnt& thePoint, + gp_XYZ& theParams, + const gp_XYZ& theParamsHint) +{ + myPoint = thePoint.XYZ(); + + myParam.SetCoord( -1,-1,-1 ); + myValues[ SQUARE_DIST ] = 1e100; + + math_Vector low ( 1, 3, 0.0 ); + math_Vector up ( 1, 3, 1.0 ); + math_Vector tol ( 1, 3, 1e-4 ); + math_Vector start( 1, 3, 0.0 ); + start( 1 ) = theParamsHint.X(); + start( 2 ) = theParamsHint.Y(); + start( 3 ) = theParamsHint.Z(); + + math_FunctionSetRoot paramSearch( *this, tol ); + + mySquareFunc = 0; // large approaching steps + //if ( hasHint ) mySquareFunc = 1; // small approaching steps + + double loopTol = 10 * myTolerance; + int nbLoops = 0; + while ( distance() > loopTol && nbLoops <= 3 ) + { + paramSearch.Perform ( *static_cast(this), + start, low, up ); + start( 1 ) = myParam.X(); + start( 2 ) = myParam.Y(); + start( 3 ) = myParam.Z(); + mySquareFunc = !mySquareFunc; + nbLoops++; + } +#ifdef DEBUG_PARAM_COMPUTE + mySumDist += distance(); + MESSAGE ( " ------ SOLUTION: ( "<< myParam.X() <<" "<< myParam.Y() <<" "<< myParam.Z() <<" )"< 0 ) + theParams.SetCoord( myFaceIndex, myFaceParam ); + + return true; +} + +//======================================================================= +//function : ComputeParameters +//purpose : compute point parameters in the block +//======================================================================= + +bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint, + gp_XYZ& theParams, + const int theShapeID, + const gp_XYZ& theParamsHint) +{ + if ( VertexParameters( theShapeID, theParams )) + return true; + + if ( IsEdgeID( theShapeID )) { + TEdge& e = myEdge[ theShapeID - ID_FirstE ]; + Adaptor3d_Curve* curve = e.GetCurve(); + Extrema_ExtPC anExtPC( thePoint, *curve, curve->FirstParameter(), curve->LastParameter() ); + int i, nb = anExtPC.IsDone() ? anExtPC.NbExt() : 0; + for ( i = 1; i <= nb; i++ ) { + if ( anExtPC.IsMin( i )) + return EdgeParameters( theShapeID, anExtPC.Point( i ).Parameter(), theParams ); + } + return false; + } + + const bool isOnFace = IsFaceID( theShapeID ); + double * coef = GetShapeCoef( theShapeID ); + + // Find the first guess paremeters + + gp_XYZ start(0, 0, 0); + + bool hasHint = ( 0 <= theParamsHint.X() && theParamsHint.X() <= 1 && + 0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 && + 0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 ); + if ( !hasHint && !myGridComputed ) + { + // define the first guess by thePoint projection on lines + // connecting vertices + bool needGrid = false; + gp_XYZ par000( 0, 0, 0 ), par111( 1, 1, 1 ); + double zero = DBL_MIN * DBL_MIN; + for ( int iEdge = 0, iParam = 1; iParam <= 3 && !needGrid; iParam++ ) + { + if ( isOnFace && coef[ iParam - 1 ] != 0 ) { + iEdge += 4; + continue; + } + double sumParam = 0; + for ( int iE = 0; iE < 4; iE++, iEdge++ ) { // loop on 4 parallel edges + gp_Pnt p0 = myEdge[ iEdge ].Point( par000 ); + gp_Pnt p1 = myEdge[ iEdge ].Point( par111 ); + gp_Vec v01( p0, p1 ), v0P( p0, thePoint ); + double len2 = v01.SquareMagnitude(); + double par = 0; + if ( len2 > zero ) { + par = v0P.Dot( v01 ) / len2; + if ( par < 0 || par > 1 ) { // projection falls out of line ends => needGrid + needGrid = true; + break; + } + } + sumParam += par; + } + start.SetCoord( iParam, sumParam / 4.); + } + if ( needGrid ) { + // compute nodes of 3 x 3 x 3 grid + int iNode = 0; + Bnd_Box box; + for ( double x = 0.25; x < 0.9; x += 0.25 ) + for ( double y = 0.25; y < 0.9; y += 0.25 ) + for ( double z = 0.25; z < 0.9; z += 0.25 ) { + TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ]; + prmPtn.first.SetCoord( x, y, z ); + ShellPoint( prmPtn.first, prmPtn.second ); + box.Add( gp_Pnt( prmPtn.second )); + } + myGridComputed = true; + myTolerance = sqrt( box.SquareExtent() ) * 1e-5; + } + } + + if ( hasHint ) + { + start = theParamsHint; + } + else if ( myGridComputed ) + { + double minDist = DBL_MAX; + gp_XYZ* bestParam = 0; + for ( int iNode = 0; iNode < 27; iNode++ ) { + TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ]; + double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus(); + if ( dist < minDist ) { + minDist = dist; + bestParam = & prmPtn.first; + } + } + start = *bestParam; + } + + myFaceIndex = -1; + myFaceParam = 0.; + if ( isOnFace ) { + // put a point on the face + for ( int iCoord = 0; iCoord < 3; iCoord++ ) + if ( coef[ iCoord ] ) { + myFaceIndex = iCoord + 1; + myFaceParam = ( coef[ iCoord ] < 0.5 ) ? 0.0 : 1.0; + start.SetCoord( myFaceIndex, myFaceParam ); + } + } + +#ifdef DEBUG_PARAM_COMPUTE + MESSAGE ( " #### POINT " < sqDistance ) { // solution get worse + if ( ++nbGetWorst > 2 ) + return computeParameters( thePoint, theParams, solution ); + } +#ifdef DEBUG_PARAM_COMPUTE + MESSAGE ( "PARAMS: ( " << params.X() <<" "<< params.Y() <<" "<< params.Z() <<" )" ); + MESSAGE ( "DIST: " << sqrt( sqDist ) ); +#endif + + if ( sqDist < sqDistance ) { // get better + sqDistance = sqDist; + solution = params; + nbGetWorst = 0; + if ( sqDistance < sqTolerance ) // a solution found + break; + } + + // look for a next better solution + for ( int iP = 1; iP <= 3; iP++ ) { + if ( iP == myFaceIndex ) + continue; + // see where we move with a small (=parDelta) step in this direction + gp_XYZ nearParams = params; + bool onEdge = ( params.Coord( iP ) + parDelta > 1. ); + if ( onEdge ) + nearParams.SetCoord( iP, params.Coord( iP ) - parDelta ); + else + nearParams.SetCoord( iP, params.Coord( iP ) + parDelta ); + ShellPoint( nearParams, Pi ); + gp_Vec dPi ( P, Pi ); + if ( onEdge ) dPi *= -1.; + // modify a parameter + double mag = dPi.Magnitude(); + if ( mag < DBL_MIN ) + continue; + gp_Vec dir = dPi / mag; // dir we move modifying the parameter + double dist = dir * dP; // where we should get to + double dPar = dist / mag * parDelta; // predict parameter change + double curPar = params.Coord( iP ); + double par = curPar - dPar; // new parameter value + while ( par > 1 || par < 0 ) { + dPar /= 2.; + par = curPar - dPar; + } + params.SetCoord( iP, par ); + } + + nbLoops++; + } +#ifdef DEBUG_PARAM_COMPUTE + myNbIterations += nbLoops*4; // how many times ShellPoint called + mySumDist += sqrt( sqDistance ); + MESSAGE ( " ------ SOLUTION: ( "< 0 ) + theParams.SetCoord( myFaceIndex, myFaceParam ); + + return true; +} + +//======================================================================= +//function : VertexParameters +//purpose : return parameters of a vertex given by TShapeID +//======================================================================= + +bool SMESH_Block::VertexParameters(const int theVertexID, gp_XYZ& theParams) +{ + switch ( theVertexID ) { + case ID_V000: theParams.SetCoord(0., 0., 0.); return true; + case ID_V100: theParams.SetCoord(1., 0., 0.); return true; + case ID_V110: theParams.SetCoord(1., 1., 0.); return true; + case ID_V010: theParams.SetCoord(0., 1., 0.); return true; + default:; + } + return false; +} + +//======================================================================= +//function : EdgeParameters +//purpose : return parameters of a point given by theU on edge +//======================================================================= + +bool SMESH_Block::EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams) +{ + if ( IsEdgeID( theEdgeID )) { + vector< int > vertexVec; + GetEdgeVertexIDs( theEdgeID, vertexVec ); + VertexParameters( vertexVec[0], theParams ); + TEdge& e = myEdge[ theEdgeID - ID_Ex00 ]; + double param = ( theU - e.EndParam(0) ) / ( e.EndParam(1) - e.EndParam(0) ); + theParams.SetCoord( e.CoordInd(), param ); + return true; + } + return false; +} + +//======================================================================= +//function : DumpShapeID +//purpose : debug an id of a block sub-shape +//======================================================================= + +#define CASEDUMP(id,strm) case id: strm << #id; break; + +ostream& SMESH_Block::DumpShapeID (const int id, ostream& stream) +{ + switch ( id ) { + CASEDUMP( ID_V000, stream ); + CASEDUMP( ID_V100, stream ); + CASEDUMP( ID_V010, stream ); + CASEDUMP( ID_V110, stream ); + CASEDUMP( ID_V001, stream ); + CASEDUMP( ID_V101, stream ); + CASEDUMP( ID_V011, stream ); + CASEDUMP( ID_V111, stream ); + CASEDUMP( ID_Ex00, stream ); + CASEDUMP( ID_Ex10, stream ); + CASEDUMP( ID_Ex01, stream ); + CASEDUMP( ID_Ex11, stream ); + CASEDUMP( ID_E0y0, stream ); + CASEDUMP( ID_E1y0, stream ); + CASEDUMP( ID_E0y1, stream ); + CASEDUMP( ID_E1y1, stream ); + CASEDUMP( ID_E00z, stream ); + CASEDUMP( ID_E10z, stream ); + CASEDUMP( ID_E01z, stream ); + CASEDUMP( ID_E11z, stream ); + CASEDUMP( ID_Fxy0, stream ); + CASEDUMP( ID_Fxy1, stream ); + CASEDUMP( ID_Fx0z, stream ); + CASEDUMP( ID_Fx1z, stream ); + CASEDUMP( ID_F0yz, stream ); + CASEDUMP( ID_F1yz, stream ); + CASEDUMP( ID_Shell, stream ); + default: stream << "ID_INVALID"; + } + return stream; +} + +//======================================================================= +//function : GetShapeIDByParams +//purpose : define an id of the block sub-shape by normlized point coord +//======================================================================= + +int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord ) +{ + // id ( 0 - 26 ) computation: + + // vertex ( 0 - 7 ) : id = 1*x + 2*y + 4*z + + // edge || X ( 8 - 11 ) : id = 8 + 1*y + 2*z + // edge || Y ( 12 - 15 ): id = 1*x + 12 + 2*z + // edge || Z ( 16 - 19 ): id = 1*x + 2*y + 16 + + // face || XY ( 20 - 21 ): id = 8 + 12 + 1*z - 0 + // face || XZ ( 22 - 23 ): id = 8 + 1*y + 16 - 2 + // face || YZ ( 24 - 25 ): id = 1*x + 12 + 16 - 4 + + static int iAddBnd[] = { 1, 2, 4 }; + static int iAddNotBnd[] = { 8, 12, 16 }; + static int iFaceSubst[] = { 0, 2, 4 }; + + int id = 0; + int iOnBoundary = 0; + for ( int iCoord = 0; iCoord < 3; iCoord++ ) + { + double val = theCoord.Coord( iCoord + 1 ); + if ( val == 0.0 ) + iOnBoundary++; + else if ( val == 1.0 ) + id += iAddBnd[ iOnBoundary++ ]; + else + id += iAddNotBnd[ iCoord ]; + } + if ( iOnBoundary == 1 ) // face + id -= iFaceSubst[ (id - 20) / 4 ]; + else if ( iOnBoundary == 0 ) // shell + id = 26; + + if ( id > 26 || id < 0 ) { + MESSAGE( "GetShapeIDByParams() = " << id + <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() ); + } + + return id + 1; // shape ids start at 1 +} + +//================================================================================ +/*! + * \brief Return number of wires and a list of oredered edges. + * \param theFace - the face to process + * \param theFirstVertex - the vertex of the outer wire to set first in the returned + * list ( theFirstVertex may be NULL ) + * \param theEdges - all ordered edges of theFace (outer edges goes first). + * \param theNbEdgesInWires - nb of edges (== nb of vertices in closed wire) in each wire + * \param theShapeAnalysisAlgo - if true, ShapeAnalysis::OuterWire() is used to find + * the outer wire else BRepTools::OuterWire() is used. + * \retval int - nb of wires + * + * Always try to set a seam edge first. + * BRepTools::OuterWire() fails e.g. in the case of issue 0020184, + * ShapeAnalysis::OuterWire() fails in the case of issue 0020452 + */ +//================================================================================ + +int SMESH_Block::GetOrderedEdges (const TopoDS_Face& theFace, + TopoDS_Vertex theFirstVertex, + list< TopoDS_Edge >& theEdges, + list< int > & theNbEdgesInWires, + const bool theShapeAnalysisAlgo) +{ + // put wires in a list, so that an outer wire comes first + list aWireList; + TopoDS_Wire anOuterWire = + theShapeAnalysisAlgo ? ShapeAnalysis::OuterWire( theFace ) : BRepTools::OuterWire( theFace ); + for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() ) + if ( wIt.Value().ShapeType() == TopAbs_WIRE ) // it can be internal vertex! + { + if ( !anOuterWire.IsSame( wIt.Value() )) + aWireList.push_back( TopoDS::Wire( wIt.Value() )); + else + aWireList.push_front( TopoDS::Wire( wIt.Value() )); + } + + // loop on edges of wires + theNbEdgesInWires.clear(); + list::iterator wlIt = aWireList.begin(); + for ( ; wlIt != aWireList.end(); wlIt++ ) + { + int iE; + BRepTools_WireExplorer wExp( *wlIt, theFace ); + for ( iE = 0; wExp.More(); wExp.Next(), iE++ ) + { + TopoDS_Edge edge = wExp.Current(); + // commented for issue 0020557, other related ones: 0020526, PAL19080 + // edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() )); + theEdges.push_back( edge ); + } + if ( iE == 0 ) // wExp returns nothing if e.g. the wire contains one internal edge + { // Issue 0020676 + for ( TopoDS_Iterator e( *wlIt ); e.More(); e.Next(), ++iE ) + theEdges.push_back( TopoDS::Edge( e.Value() )); + } + theNbEdgesInWires.push_back( iE ); + iE = 0; + if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire + // orient closed edges + list< TopoDS_Edge >::iterator eIt, eIt2; + for ( eIt = theEdges.begin(); eIt != theEdges.end(); eIt++ ) + { + TopoDS_Edge& edge = *eIt; + if ( TopExp::FirstVertex( edge ).IsSame( TopExp::LastVertex( edge ) )) + { + eIt2 = eIt; + bool isNext = ( eIt2 == theEdges.begin() ); + TopoDS_Edge edge2 = isNext ? *(++eIt2) : *(--eIt2); + double f1,l1,f2,l2; + Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( edge, theFace, f1,l1 ); + Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( edge2, theFace, f2,l2 ); + gp_Pnt2d pf = c1->Value( edge.Orientation() == TopAbs_FORWARD ? f1 : l1 ); + gp_Pnt2d pl = c1->Value( edge.Orientation() == TopAbs_FORWARD ? l1 : f1 ); + bool isFirst = ( edge2.Orientation() == TopAbs_FORWARD ? isNext : !isNext ); + gp_Pnt2d p2 = c2->Value( isFirst ? f2 : l2 ); + isFirst = ( p2.SquareDistance( pf ) < p2.SquareDistance( pl )); + if ( isNext ? isFirst : !isFirst ) + edge.Reverse(); + // to make a seam go first + if ( theFirstVertex.IsNull() ) + theFirstVertex = TopExp::FirstVertex( edge, true ); + } + } + // rotate theEdges until it begins from theFirstVertex + if ( ! theFirstVertex.IsNull() ) { + TopoDS_Vertex vv[2]; + TopExp::Vertices( theEdges.front(), vv[0], vv[1], true ); + // on closed face, make seam edge the first in the list + while ( !vv[0].IsSame( theFirstVertex ) || vv[0].IsSame( vv[1] )) + { + theEdges.splice(theEdges.end(), theEdges, + theEdges.begin(), ++theEdges.begin()); + TopExp::Vertices( theEdges.front(), vv[0], vv[1], true ); + if ( iE++ > theNbEdgesInWires.back() ) { +#ifdef _DEBUG_ + gp_Pnt p = BRep_Tool::Pnt( theFirstVertex ); + MESSAGE ( " : Warning : vertex "<< theFirstVertex.TShape().operator->() + << " ( " << p.X() << " " << p.Y() << " " << p.Z() << " )" + << " not found in outer wire of face "<< theFace.TShape().operator->() + << " with vertices: " ); + wExp.Init( *wlIt, theFace ); + for ( int i = 0; wExp.More(); wExp.Next(), i++ ) + { + TopoDS_Edge edge = wExp.Current(); + edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() )); + TopoDS_Vertex v = TopExp::FirstVertex( edge, true ); + gp_Pnt p = BRep_Tool::Pnt( v ); + MESSAGE_ADD ( i << " " << v.TShape().operator->() << " " + << p.X() << " " << p.Y() << " " << p.Z() << " " << std::endl ); + } +#endif + break; // break infinite loop + } + } + } + } // end outer wire + } + + return aWireList.size(); +} +//================================================================================ +/*! + * \brief Call it after geometry initialisation + */ +//================================================================================ + +void SMESH_Block::init() +{ + myNbIterations = 0; + mySumDist = 0; + myGridComputed = false; +} + +//======================================================================= +//function : LoadMeshBlock +//purpose : prepare to work with theVolume +//======================================================================= + +#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z()) + +bool SMESH_Block::LoadMeshBlock(const SMDS_MeshVolume* theVolume, + const int theNode000Index, + const int theNode001Index, + vector& theOrderedNodes) +{ + MESSAGE(" ::LoadMeshBlock()"); + init(); + + SMDS_VolumeTool vTool; + if (!vTool.Set( theVolume ) || vTool.NbNodes() != 8 || + !vTool.IsLinked( theNode000Index, theNode001Index )) { + MESSAGE(" Bad arguments "); + return false; + } + vTool.SetExternalNormal(); + // In terms of indices used for access to nodes and faces in SMDS_VolumeTool: + int V000, V100, V010, V110, V001, V101, V011, V111; // 8 vertices + int Fxy0, Fxy1; // bottom and top faces + // vertices of faces + vector vFxy0, vFxy1; + + V000 = theNode000Index; + V001 = theNode001Index; + + // get faces sharing V000 and V001 + list fV000, fV001; + int i, iF, iE, iN; + for ( iF = 0; iF < vTool.NbFaces(); ++iF ) { + const int* nid = vTool.GetFaceNodesIndices( iF ); + for ( iN = 0; iN < 4; ++iN ) + if ( nid[ iN ] == V000 ) { + fV000.push_back( iF ); + } else if ( nid[ iN ] == V001 ) { + fV001.push_back( iF ); + } + } + + // find the bottom (Fxy0), the top (Fxy1) faces + list::iterator fIt1, fIt2, Fxy0Pos; + for ( fIt1 = fV000.begin(); fIt1 != fV000.end(); fIt1++) { + fIt2 = std::find( fV001.begin(), fV001.end(), *fIt1 ); + if ( fIt2 != fV001.end() ) { // *fIt1 is in the both lists + fV001.erase( fIt2 ); // erase Fx0z or F0yz from fV001 + } else { // *fIt1 is in fV000 only + Fxy0Pos = fIt1; // points to Fxy0 + } + } + Fxy0 = *Fxy0Pos; + Fxy1 = fV001.front(); + const SMDS_MeshNode** nn = vTool.GetNodes(); + + // find bottom veritices, their order is that a face normal is external + vFxy0.resize(4); + const int* nid = vTool.GetFaceNodesIndices( Fxy0 ); + for ( i = 0; i < 4; ++i ) + if ( nid[ i ] == V000 ) + break; + for ( iN = 0; iN < 4; ++iN, ++i ) { + if ( i == 4 ) i = 0; + vFxy0[ iN ] = nid[ i ]; + } + // find top veritices, their order is that a face normal is external + vFxy1.resize(4); + nid = vTool.GetFaceNodesIndices( Fxy1 ); + for ( i = 0; i < 4; ++i ) + if ( nid[ i ] == V001 ) + break; + for ( iN = 0; iN < 4; ++iN, ++i ) { + if ( i == 4 ) i = 0; + vFxy1[ iN ] = nid[ i ]; + } + // find indices of the rest veritices + V100 = vFxy0[3]; + V010 = vFxy0[1]; + V110 = vFxy0[2]; + V101 = vFxy1[1]; + V011 = vFxy1[3]; + V111 = vFxy1[2]; + + // set points coordinates + myPnt[ ID_V000 - 1 ] = gpXYZ( nn[ V000 ] ); + myPnt[ ID_V100 - 1 ] = gpXYZ( nn[ V100 ] ); + myPnt[ ID_V010 - 1 ] = gpXYZ( nn[ V010 ] ); + myPnt[ ID_V110 - 1 ] = gpXYZ( nn[ V110 ] ); + myPnt[ ID_V001 - 1 ] = gpXYZ( nn[ V001 ] ); + myPnt[ ID_V101 - 1 ] = gpXYZ( nn[ V101 ] ); + myPnt[ ID_V011 - 1 ] = gpXYZ( nn[ V011 ] ); + myPnt[ ID_V111 - 1 ] = gpXYZ( nn[ V111 ] ); + + // fill theOrderedNodes + theOrderedNodes.resize( 8 ); + theOrderedNodes[ 0 ] = nn[ V000 ]; + theOrderedNodes[ 1 ] = nn[ V100 ]; + theOrderedNodes[ 2 ] = nn[ V010 ]; + theOrderedNodes[ 3 ] = nn[ V110 ]; + theOrderedNodes[ 4 ] = nn[ V001 ]; + theOrderedNodes[ 5 ] = nn[ V101 ]; + theOrderedNodes[ 6 ] = nn[ V011 ]; + theOrderedNodes[ 7 ] = nn[ V111 ]; + + // fill edges + vector< int > vertexVec; + for ( iE = 0; iE < NbEdges(); ++iE ) { + GetEdgeVertexIDs(( iE + ID_FirstE ), vertexVec ); + myEdge[ iE ].Set(( iE + ID_FirstE ), + myPnt[ vertexVec[0] - 1 ], + myPnt[ vertexVec[1] - 1 ]); + } + + // fill faces' corners + for ( iF = ID_Fxy0; iF < ID_Shell; ++iF ) + { + TFace& tFace = myFace[ iF - ID_FirstF ]; + vector< int > edgeIdVec(4, -1); + GetFaceEdgesIDs( iF, edgeIdVec ); + tFace.Set( iF, myEdge[ edgeIdVec [ 0 ] - ID_Ex00], myEdge[ edgeIdVec [ 1 ] - ID_Ex00]); + } + + return true; +} + +//======================================================================= +//function : LoadBlockShapes +//purpose : Initialize block geometry with theShell, +// add sub-shapes of theBlock to theShapeIDMap so that they get +// IDs acoording to enum TShapeID +//======================================================================= + +bool SMESH_Block::LoadBlockShapes(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theVertex000, + const TopoDS_Vertex& theVertex001, + TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) +{ + MESSAGE(" ::LoadBlockShapes()"); + return ( FindBlockShapes( theShell, theVertex000, theVertex001, theShapeIDMap ) && + LoadBlockShapes( theShapeIDMap )); +} + +//======================================================================= +//function : LoadBlockShapes +//purpose : add sub-shapes of theBlock to theShapeIDMap so that they get +// IDs acoording to enum TShapeID +//======================================================================= + +bool SMESH_Block::FindBlockShapes(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theVertex000, + const TopoDS_Vertex& theVertex001, + TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) +{ + MESSAGE(" ::FindBlockShapes()"); + + // 8 vertices + TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111; + // 12 edges + TopoDS_Shape Ex00, Ex10, Ex01, Ex11; + TopoDS_Shape E0y0, E1y0, E0y1, E1y1; + TopoDS_Shape E00z, E10z, E01z, E11z; + // 6 faces + TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz; + + // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape + // filled by TopExp::MapShapesAndAncestors() + const int NB_FACES_BY_VERTEX = 6; + + TopTools_IndexedDataMapOfShapeListOfShape vfMap; + TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_FACE, vfMap ); + if ( vfMap.Extent() != 8 ) { + MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() ); + return false; + } + + V000 = theVertex000; + V001 = theVertex001; + + if ( V000.IsNull() ) { + // find vertex 000 - the one with smallest coordinates + double minVal = DBL_MAX, minX, val; + for ( int i = 1; i <= 8; i++ ) { + const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i )); + gp_Pnt P = BRep_Tool::Pnt( v ); + val = P.X() + P.Y() + P.Z(); + if ( val < minVal || ( val == minVal && P.X() < minX )) { + V000 = v; + minVal = val; + minX = P.X(); + } + } + // find vertex 001 - the one on the most vertical edge passing through V000 + TopTools_IndexedDataMapOfShapeListOfShape veMap; + TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_EDGE, veMap ); + gp_Vec dir001 = gp::DZ(); + gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 )); + double maxVal = -DBL_MAX; + TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 )); + for ( ; eIt.More(); eIt.Next() ) { + const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() ); + TopoDS_Vertex v = TopExp::FirstVertex( e ); + if ( v.IsSame( V000 )) + v = TopExp::LastVertex( e ); + val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized(); + if ( val > maxVal ) { + V001 = v; + maxVal = val; + } + } + } + + // find the bottom (Fxy0), Fx0z and F0yz faces + + const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 ); + const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 ); + if (f000List.Extent() != NB_FACES_BY_VERTEX || + f001List.Extent() != NB_FACES_BY_VERTEX ) { + MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent()); + return false; + } + TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List ); + int i, j, iFound1, iFound2; + for ( j = 0; f000It.More(); f000It.Next(), j++ ) + { + if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice + const TopoDS_Shape& F = f000It.Value(); + for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { + if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice + if ( F.IsSame( f001It.Value() )) + break; + } + if ( f001It.More() ) // Fx0z or F0yz found + if ( Fx0z.IsNull() ) { + Fx0z = F; + iFound1 = i; + } else { + F0yz = F; + iFound2 = i; + } + else // F is the bottom face + Fxy0 = F; + } + if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) { + MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() ); + return false; + } + + // choose the top face (Fxy1) + for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { + if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice + if ( i != iFound1 && i != iFound2 ) + break; + } + Fxy1 = f001It.Value(); + if ( Fxy1.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + + // find bottom edges and veritices + list< TopoDS_Edge > eList; + list< int > nbVertexInWires; + GetOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires ); + if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + list< TopoDS_Edge >::iterator elIt = eList.begin(); + for ( i = 0; elIt != eList.end(); elIt++, i++ ) + switch ( i ) { + case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break; + case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break; + case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break; + case 3: Ex00 = *elIt; break; + default:; + } + if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) { + MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); + return false; + } + + + // find top edges and veritices + eList.clear(); + GetOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires ); + if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ ) + switch ( i ) { + case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break; + case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break; + case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break; + case 3: E0y1 = *elIt; break; + default:; + } + if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) { + MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); + return false; + } + + // swap Fx0z and F0yz if necessary + TopExp_Explorer exp( Fx0z, TopAbs_VERTEX ); + for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100 + if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() )) + break; // V101 or V100 found + if ( !exp.More() ) { // not found + std::swap( Fx0z, F0yz); + } + + // find Fx1z and F1yz faces + const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 ); + const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 ); + if (f111List.Extent() != NB_FACES_BY_VERTEX || + f110List.Extent() != NB_FACES_BY_VERTEX ) { + MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent()); + return false; + } + TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List); + for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) { + if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice + const TopoDS_Shape& F = f110It.Value(); + for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) { + if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice + if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found + if ( Fx1z.IsNull() ) + Fx1z = F; + else + F1yz = F; + } + } + } + if ( Fx1z.IsNull() || F1yz.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + + // swap Fx1z and F1yz if necessary + for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() ) + if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() )) + break; + if ( !exp.More() ) { + std::swap( Fx1z, F1yz); + } + + // find vertical edges + for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) { + const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); + const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); + if ( vFirst.IsSame( V001 )) + E00z = edge; + else if ( vFirst.IsSame( V100 )) + E10z = edge; + } + if ( E00z.IsNull() || E10z.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) { + const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); + const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); + if ( vFirst.IsSame( V111 )) + E11z = edge; + else if ( vFirst.IsSame( V010 )) + E01z = edge; + } + if ( E01z.IsNull() || E11z.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + + // load shapes in theShapeIDMap + + theShapeIDMap.Clear(); + + theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD )); + + theShapeIDMap.Add(Ex00); + theShapeIDMap.Add(Ex10); + theShapeIDMap.Add(Ex01); + theShapeIDMap.Add(Ex11); + + theShapeIDMap.Add(E0y0); + theShapeIDMap.Add(E1y0); + theShapeIDMap.Add(E0y1); + theShapeIDMap.Add(E1y1); + + theShapeIDMap.Add(E00z); + theShapeIDMap.Add(E10z); + theShapeIDMap.Add(E01z); + theShapeIDMap.Add(E11z); + + theShapeIDMap.Add(Fxy0); + theShapeIDMap.Add(Fxy1); + theShapeIDMap.Add(Fx0z); + theShapeIDMap.Add(Fx1z); + theShapeIDMap.Add(F0yz); + theShapeIDMap.Add(F1yz); + + theShapeIDMap.Add(theShell); + + return true; +} + +//================================================================================ +/*! + * \brief Initialize block geometry with shapes from theShapeIDMap + * \param theShapeIDMap - map of block sub-shapes + * \retval bool - is a success + */ +//================================================================================ + +bool SMESH_Block::LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) +{ + init(); + + // store shapes geometry + for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ ) + { + const TopoDS_Shape& S = theShapeIDMap( shapeID ); + switch ( S.ShapeType() ) + { + case TopAbs_VERTEX: { + + if ( !IsVertexID( ID_V111 )) return false; + myPnt[ shapeID - ID_V000 ] = BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ(); + break; + } + case TopAbs_EDGE: { + + if ( !IsEdgeID( shapeID )) return false; + const TopoDS_Edge& edge = TopoDS::Edge( S ); + TEdge& tEdge = myEdge[ shapeID - ID_FirstE ]; + tEdge.Set( shapeID, + new BRepAdaptor_Curve( edge ), + IsForwardEdge( edge, theShapeIDMap )); + break; + } + case TopAbs_FACE: { + + if ( !LoadFace( TopoDS::Face( S ), shapeID, theShapeIDMap )) + return false; + break; + } + default: break; + } + } // loop on shapes in theShapeIDMap + + return true; +} + +//================================================================================ +/*! + * \brief Load face geometry + * \param theFace - face + * \param theFaceID - face in-block ID + * \param theShapeIDMap - map of block sub-shapes + * \retval bool - is a success + * + * It is enough to compute params or coordinates on the face. + * Face sub-shapes must be loaded into theShapeIDMap before + */ +//================================================================================ + +bool SMESH_Block::LoadFace(const TopoDS_Face& theFace, + const int theFaceID, + const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) +{ + if ( !IsFaceID( theFaceID ) ) return false; + // pcurves + Adaptor2d_Curve2d* c2d[4]; + bool isForward[4]; + vector< int > edgeIdVec; + GetFaceEdgesIDs( theFaceID, edgeIdVec ); + for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges + { + if ( edgeIdVec[ iE ] > theShapeIDMap.Extent() ) + return false; + const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ])); + c2d[ iE ] = new BRepAdaptor_Curve2d( edge, theFace ); + isForward[ iE ] = IsForwardEdge( edge, theShapeIDMap ); + } + TFace& tFace = myFace[ theFaceID - ID_FirstF ]; + tFace.Set( theFaceID, new BRepAdaptor_Surface( theFace ), c2d, isForward ); + return true; +} + +//================================================================================ +/*! + * \brief/ Insert theShape into theShapeIDMap with theShapeID + * \param theShape - shape to insert + * \param theShapeID - shape in-block ID + * \param theShapeIDMap - map of block sub-shapes + */ +//================================================================================ + +bool SMESH_Block::Insert(const TopoDS_Shape& theShape, + const int theShapeID, + TopTools_IndexedMapOfOrientedShape& theShapeIDMap) +{ + if ( !theShape.IsNull() && theShapeID > 0 ) + { + if ( theShapeIDMap.Contains( theShape )) + return ( theShapeIDMap.FindIndex( theShape ) == theShapeID ); + + if ( theShapeID <= theShapeIDMap.Extent() ) { + theShapeIDMap.Substitute( theShapeID, theShape ); + } + else { + while ( theShapeIDMap.Extent() < theShapeID - 1 ) { + TopoDS_Compound comp; + BRep_Builder().MakeCompound( comp ); + theShapeIDMap.Add( comp ); + } + theShapeIDMap.Add( theShape ); + } + return true; + } + return false; +} + +//======================================================================= +//function : GetFaceEdgesIDs +//purpose : return edges IDs in the order u0, u1, 0v, 1v +// u0 means "|| u, v == 0" +//======================================================================= + +void SMESH_Block::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec ) +{ + edgeVec.resize( 4 ); + switch ( faceID ) { + case ID_Fxy0: + edgeVec[ 0 ] = ID_Ex00; + edgeVec[ 1 ] = ID_Ex10; + edgeVec[ 2 ] = ID_E0y0; + edgeVec[ 3 ] = ID_E1y0; + break; + case ID_Fxy1: + edgeVec[ 0 ] = ID_Ex01; + edgeVec[ 1 ] = ID_Ex11; + edgeVec[ 2 ] = ID_E0y1; + edgeVec[ 3 ] = ID_E1y1; + break; + case ID_Fx0z: + edgeVec[ 0 ] = ID_Ex00; + edgeVec[ 1 ] = ID_Ex01; + edgeVec[ 2 ] = ID_E00z; + edgeVec[ 3 ] = ID_E10z; + break; + case ID_Fx1z: + edgeVec[ 0 ] = ID_Ex10; + edgeVec[ 1 ] = ID_Ex11; + edgeVec[ 2 ] = ID_E01z; + edgeVec[ 3 ] = ID_E11z; + break; + case ID_F0yz: + edgeVec[ 0 ] = ID_E0y0; + edgeVec[ 1 ] = ID_E0y1; + edgeVec[ 2 ] = ID_E00z; + edgeVec[ 3 ] = ID_E01z; + break; + case ID_F1yz: + edgeVec[ 0 ] = ID_E1y0; + edgeVec[ 1 ] = ID_E1y1; + edgeVec[ 2 ] = ID_E10z; + edgeVec[ 3 ] = ID_E11z; + break; + default: + MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID ); + } +} + +//======================================================================= +//function : GetEdgeVertexIDs +//purpose : return vertex IDs of an edge +//======================================================================= + +void SMESH_Block::GetEdgeVertexIDs (const int edgeID, vector< int >& vertexVec ) +{ + vertexVec.resize( 2 ); + switch ( edgeID ) { + + case ID_Ex00: + vertexVec[ 0 ] = ID_V000; + vertexVec[ 1 ] = ID_V100; + break; + case ID_Ex10: + vertexVec[ 0 ] = ID_V010; + vertexVec[ 1 ] = ID_V110; + break; + case ID_Ex01: + vertexVec[ 0 ] = ID_V001; + vertexVec[ 1 ] = ID_V101; + break; + case ID_Ex11: + vertexVec[ 0 ] = ID_V011; + vertexVec[ 1 ] = ID_V111; + break; + + case ID_E0y0: + vertexVec[ 0 ] = ID_V000; + vertexVec[ 1 ] = ID_V010; + break; + case ID_E1y0: + vertexVec[ 0 ] = ID_V100; + vertexVec[ 1 ] = ID_V110; + break; + case ID_E0y1: + vertexVec[ 0 ] = ID_V001; + vertexVec[ 1 ] = ID_V011; + break; + case ID_E1y1: + vertexVec[ 0 ] = ID_V101; + vertexVec[ 1 ] = ID_V111; + break; + + case ID_E00z: + vertexVec[ 0 ] = ID_V000; + vertexVec[ 1 ] = ID_V001; + break; + case ID_E10z: + vertexVec[ 0 ] = ID_V100; + vertexVec[ 1 ] = ID_V101; + break; + case ID_E01z: + vertexVec[ 0 ] = ID_V010; + vertexVec[ 1 ] = ID_V011; + break; + case ID_E11z: + vertexVec[ 0 ] = ID_V110; + vertexVec[ 1 ] = ID_V111; + break; + default: + vertexVec.resize(0); + MESSAGE(" GetEdgeVertexIDs(), wrong edge ID: " << edgeID ); + } +} diff --git a/src/SMESHUtils/SMESH_Block.hxx b/src/SMESHUtils/SMESH_Block.hxx new file mode 100644 index 000000000..4971db99a --- /dev/null +++ b/src/SMESHUtils/SMESH_Block.hxx @@ -0,0 +1,391 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_Block.hxx +// Created : Tue Nov 30 12:42:18 2004 +// Author : Edward AGAPOV (eap) +// +#ifndef SMESH_Block_HeaderFile +#define SMESH_Block_HeaderFile + +#include "SMESH_Utils.hxx" + +//#include +//#include +//#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class SMDS_MeshVolume; +class SMDS_MeshNode; +class Adaptor3d_Surface; +class Adaptor2d_Curve2d; +class Adaptor3d_Curve; +class gp_Pnt; + +// ========================================================= +// class calculating coordinates of 3D points by normalized +// parameters inside the block and vice versa +// ========================================================= + +class SMESHUtils_EXPORT SMESH_Block: public math_FunctionSetWithDerivatives +{ + public: + enum TShapeID { + // ---------------------------- + // Ids of the block sub-shapes + // ---------------------------- + ID_NONE = 0, + + ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111, + + ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11, + ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1, + ID_E00z, ID_E10z, ID_E01z, ID_E11z, + + ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz, + + ID_Shell + }; + enum { // to use TShapeID for indexing certain type subshapes + + ID_FirstV = ID_V000, ID_FirstE = ID_Ex00, ID_FirstF = ID_Fxy0 + + }; + + + public: + // ------------------------------------------------- + // Block topology in terms of block sub-shapes' ids + // ------------------------------------------------- + + static int NbVertices() { return 8; } + static int NbEdges() { return 12; } + static int NbFaces() { return 6; } + static int NbSubShapes() { return ID_Shell; } + // to avoid magic numbers when allocating memory for subshapes + + static inline bool IsVertexID( int theShapeID ) + { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); } + + static inline bool IsEdgeID( int theShapeID ) + { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); } + + static inline bool IsFaceID( int theShapeID ) + { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); } + + static int ShapeIndex( int theShapeID ) + { + if ( IsVertexID( theShapeID )) return theShapeID - ID_V000; + if ( IsEdgeID( theShapeID )) return theShapeID - ID_Ex00; + if ( IsFaceID( theShapeID )) return theShapeID - ID_Fxy0; + return 0; + } + // return index [0-...] for each type of sub-shapes, + // for example : + // ShapeIndex( ID_Ex00 ) == 0 + // ShapeIndex( ID_Ex10 ) == 1 + + static void GetFaceEdgesIDs (const int faceID, std::vector< int >& edgeVec ); + // return edges IDs of a face in the order u0, u1, 0v, 1v + + static void GetEdgeVertexIDs (const int edgeID, std::vector< int >& vertexVec ); + // return vertex IDs of an edge + + static int GetCoordIndOnEdge (const int theEdgeID) + { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; } + // return an index of a coordinate which varies along the edge + + static double* GetShapeCoef (const int theShapeID); + // for theShapeID( TShapeID ), returns 3 coefficients used + // to compute an addition of an on-theShape point to coordinates + // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz), + // then the addition of a point P is computed as P*kx*ky*kz and ki is + // defined by the returned coef like this: + // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi + + static int GetShapeIDByParams ( const gp_XYZ& theParams ); + // define an id of the block sub-shape by point parameters + + static std::ostream& DumpShapeID (const int theBlockShapeID, std::ostream& stream); + // DEBUG: dump an id of a block sub-shape + + + public: + // --------------- + // Initialization + // --------------- + + SMESH_Block(); + + bool LoadBlockShapes(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theVertex000, + const TopoDS_Vertex& theVertex001, + TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); + // Initialize block geometry with theShell, + // add sub-shapes of theBlock to theShapeIDMap so that they get + // IDs acoording to enum TShapeID + + bool LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap); + // Initialize block geometry with shapes from theShapeIDMap + + bool LoadMeshBlock(const SMDS_MeshVolume* theVolume, + const int theNode000Index, + const int theNode001Index, + std::vector& theOrderedNodes); + // prepare to work with theVolume and + // return nodes in theVolume corners in the order of TShapeID enum + + bool LoadFace(const TopoDS_Face& theFace, + const int theFaceID, + const TopTools_IndexedMapOfOrientedShape& theShapeIDMap); + // Load face geometry. + // It is enough to compute params or coordinates on the face. + // Face subshapes must be loaded into theShapeIDMap before + + static bool Insert(const TopoDS_Shape& theShape, + const int theShapeID, + TopTools_IndexedMapOfOrientedShape& theShapeIDMap); + // Insert theShape into theShapeIDMap with theShapeID, + // Not yet set shapes preceding theShapeID are filled with compounds + // Return true if theShape was successfully bound to theShapeID + + static bool FindBlockShapes(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theVertex000, + const TopoDS_Vertex& theVertex001, + TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); + // add sub-shapes of theBlock to theShapeIDMap so that they get + // IDs acoording to enum TShapeID + +public: + // --------------------------------- + // Define coordinates by parameters + // --------------------------------- + + bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const { + if ( !IsVertexID( theVertexID )) return false; + thePoint = myPnt[ theVertexID - ID_FirstV ]; return true; + } + // return vertex coordinates, parameters are defined by theVertexID + + bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { + if ( !IsEdgeID( theEdgeID )) return false; + thePoint = myEdge[ theEdgeID - ID_FirstE ].Point( theParams ); return true; + } + // return coordinates of a point on edge + + bool EdgeU( const int theEdgeID, const gp_XYZ& theParams, double& theU ) const { + if ( !IsEdgeID( theEdgeID )) return false; + theU = myEdge[ theEdgeID - ID_FirstE ].GetU( theParams ); return true; + } + // return parameter on edge by in-block parameters + + bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { + if ( !IsFaceID ( theFaceID )) return false; + thePoint = myFace[ theFaceID - ID_FirstF ].Point( theParams ); return true; + } + // return coordinates of a point on face + + bool FaceUV( const int theFaceID, const gp_XYZ& theParams, gp_XY& theUV ) const { + if ( !IsFaceID ( theFaceID )) return false; + theUV = myFace[ theFaceID - ID_FirstF ].GetUV( theParams ); return true; + } + // return UV coordinates on a face by in-block parameters + + bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const; + // return coordinates of a point in shell + + static bool ShellPoint(const gp_XYZ& theParams, + const std::vector& thePointOnShape, + gp_XYZ& thePoint ); + // computes coordinates of a point in shell by points on sub-shapes + // and point parameters. + // thePointOnShape[ subShapeID ] must be a point on a subShape; + // thePointOnShape.size() == ID_Shell, thePointOnShape[0] not used + + + public: + // --------------------------------- + // Define parameters by coordinates + // --------------------------------- + + bool ComputeParameters (const gp_Pnt& thePoint, + gp_XYZ& theParams, + const int theShapeID = ID_Shell, + const gp_XYZ& theParamsHint = gp_XYZ(-1,-1,-1)); + // compute point parameters in the block. + // Note: for edges, it is better to use EdgeParameters() + + bool VertexParameters(const int theVertexID, gp_XYZ& theParams); + // return parameters of a vertex given by TShapeID + + bool EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams); + // return parameters of a point given by theU on edge + + + public: + // --------------- + // Block geomerty + // --------------- + + + + public: + // --------- + // Services + // --------- + + static bool IsForwardEdge (const TopoDS_Edge & theEdge, + const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) { + int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD )); + int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD )); + return ( v1ID < v2ID ); + } + // Return true if an in-block parameter increases along theEdge curve + + static int GetOrderedEdges (const TopoDS_Face& theFace, + TopoDS_Vertex theFirstVertex, + std::list< TopoDS_Edge >& theEdges, + std::list< int > & theNbEdgesInWires, + const bool theShapeAnalysisAlgo=false); + // Return nb wires and a list of oredered edges. + // It is used to assign indices to subshapes. + // theFirstVertex may be NULL. + // Always try to set a seam edge first + // if (theShapeAnalysisAlgo) then ShapeAnalysis::OuterWire() is used to find the outer + // wire else BRepTools::OuterWire() is used + + public: + // ----------------------------------------------------------- + // Methods of math_FunctionSetWithDerivatives used internally + // to define parameters by coordinates + // ----------------------------------------------------------- + Standard_Integer NbVariables() const; + Standard_Integer NbEquations() const; + Standard_Boolean Value(const math_Vector& X,math_Vector& F) ; + Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ; + Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ; + Standard_Integer GetStateNumber (); + + protected: + + /*! + * \brief Call it after geometry initialisation + */ + void init(); + + // 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 SMESHUtils_EXPORT TEdge { + int myCoordInd; + double myFirst; + double myLast; + Adaptor3d_Curve* myC3d; + // if mesh volume + gp_XYZ myNodes[2]; + public: + void Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward ); + void Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 ); + Adaptor3d_Curve* GetCurve() const { return myC3d; } + double EndParam(int i) const { return i ? myLast : myFirst; } + int CoordInd() const { return myCoordInd; } + const gp_XYZ& NodeXYZ(int i) const { return i ? myNodes[1] : myNodes[0]; } + gp_XYZ Point( const gp_XYZ& theParams ) const; // Return coord by params + double GetU( const gp_XYZ& theParams ) const; // Return U by params + TEdge(): myC3d(0) {} + ~TEdge(); + }; + + class SMESHUtils_EXPORT TFace { + // 4 edges in the order u0, u1, 0v, 1v + int myCoordInd[ 4 ]; + double myFirst [ 4 ]; + double myLast [ 4 ]; + Adaptor2d_Curve2d* myC2d [ 4 ]; + // 4 corner points in the order 00, 10, 11, 01 + gp_XY myCorner [ 4 ]; + // surface + Adaptor3d_Surface* myS; + // if mesh volume + gp_XYZ myNodes[4]; + public: + void Set( const int faceID, Adaptor3d_Surface* S, // must be in GetFaceEdgesIDs() order: + Adaptor2d_Curve2d* c2d[4], const bool isForward[4] ); + void Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 ); + gp_XY GetUV( const gp_XYZ& theParams ) const; + gp_XYZ Point( const gp_XYZ& theParams ) const; + int GetUInd() const { return myCoordInd[ 0 ]; } + int GetVInd() const { return myCoordInd[ 2 ]; } + void GetCoefs( int i, const gp_XYZ& theParams, double& eCoef, double& vCoef ) const; + TFace(): myS(0) { myC2d[0]=myC2d[1]=myC2d[2]=myC2d[3]=0; } + ~TFace(); + }; + + // geometry in the order as in TShapeID: + // 8 vertices + gp_XYZ myPnt[ 8 ]; + // 12 edges + TEdge myEdge[ 12 ]; + // 6 faces + TFace myFace[ 6 ]; + + // for param computation + + enum { SQUARE_DIST = 0, DRV_1, DRV_2, DRV_3 }; + double distance () const { return sqrt( myValues[ SQUARE_DIST ]); } + double funcValue(double sqDist) const { return mySquareFunc ? sqDist : sqrt(sqDist); } + bool computeParameters(const gp_Pnt& thePoint, gp_XYZ& theParams, const gp_XYZ& theParamsHint); + + int myFaceIndex; + double myFaceParam; + int myNbIterations; + double mySumDist; + double myTolerance; + bool mySquareFunc; + + gp_XYZ myPoint; // the given point + gp_XYZ myParam; // the best parameters guess + double myValues[ 4 ]; // values computed at myParam: square distance and 3 derivatives + + typedef std::pair TxyzPair; + TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess + bool myGridComputed; +}; + + +#endif diff --git a/src/SMESHUtils/SMESH_Comment.hxx b/src/SMESHUtils/SMESH_Comment.hxx new file mode 100644 index 000000000..0aa156511 --- /dev/null +++ b/src/SMESHUtils/SMESH_Comment.hxx @@ -0,0 +1,76 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// 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 +# include + +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() ); + } + + SMESH_Comment & operator=(const SMESH_Comment& c) { + _s << c.c_str() ; + this->string::operator=( _s.str() ); + return *this; + } + + template + SMESH_Comment( const T &anything ) { + _s << anything ; + this->string::operator=( _s.str() ); + } + + template + SMESH_Comment & operator<<( const T &anything ) { + _s << anything ; + this->string::operator=( _s.str() ); + return *this ; + } + + operator char*() const { + return (char*)c_str(); + } +}; + + +#endif diff --git a/src/SMESHUtils/SMESH_ComputeError.hxx b/src/SMESHUtils/SMESH_ComputeError.hxx new file mode 100644 index 000000000..204427f08 --- /dev/null +++ b/src/SMESHUtils/SMESH_ComputeError.hxx @@ -0,0 +1,108 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_Hypothesis.hxx +// Author : Edward AGAPOV (eap) +// Module : SMESH +// +#ifndef SMESH_ComputeError_HeaderFile +#define SMESH_ComputeError_HeaderFile + +#include +#include +#include + +class SMESH_Algo; +class SMDS_MeshElement; +struct SMESH_ComputeError; + +typedef boost::shared_ptr 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 + COMPERR_WARNING = -10, //!< algo reports error but sub-mesh is computed anyway + COMPERR_CANCELED = -11 //!< compute canceled +}; + +// ============================================================= +/*! + * \brief Contains an algorithm and description of an occured error + */ +// ============================================================= + +struct SMESH_ComputeError +{ + int myName; //!< SMESH_ComputeErrorName or anything algo specific + std::string myComment; + const SMESH_Algo* myAlgo; + + std::list myBadElements; //!< to explain COMPERR_BAD_INPUT_MESH + + 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 IsKO() { return myName != COMPERR_OK && myName != COMPERR_WARNING; } + 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 ); + _case2char(COMPERR_BAD_SHAPE ); + _case2char(COMPERR_WARNING ); + _case2char(COMPERR_CANCELED ); + default:; + } + return ""; +} + +#endif diff --git a/src/SMESHUtils/SMESH_File.cxx b/src/SMESHUtils/SMESH_File.cxx new file mode 100644 index 000000000..8a69d1cc0 --- /dev/null +++ b/src/SMESHUtils/SMESH_File.cxx @@ -0,0 +1,240 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_File.cxx +// Created : Wed Mar 10 11:23:25 2010 +// Author : Edward AGAPOV (eap) +// +#include "SMESH_File.hxx" +#include "utilities.h" + +#include +#include +#include +#include +#include + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#endif + +//================================================================================ +/*! + * \brief Creator opening the file for reading by default + */ +//================================================================================ + +SMESH_File::SMESH_File(const std::string& name, bool open) + :_name(name), _size(-1), _file(0), _map(0), _pos(0), _end(0) +{ + if ( open ) this->open(); +} + +//================================================================================ +/*! + * \brief Destructor closing the file + */ +//================================================================================ + +SMESH_File::~SMESH_File() +{ + close(); +} + +//================================================================================ +/*! + * \brief Open file for reading. Return true if there is something to read + */ +//================================================================================ + +bool SMESH_File::open() +{ + int length = size(); + if ( !_map && length > 0 ) + { +#ifdef WNT + _file = CreateFile(_name.data(), GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + bool ok = ( _file != INVALID_HANDLE_VALUE ); +#else + _file = ::open(_name.data(), O_RDONLY ); + bool ok = ( _file > 0 ); +#endif + if ( ok ) + { +#ifdef WNT + _mapObj = CreateFileMapping(_file, NULL, PAGE_READONLY, 0, (DWORD)length, NULL); + _map = (void*) MapViewOfFile( _mapObj, FILE_MAP_READ, 0, 0, 0 ); +#else + _map = ::mmap(0,length,PROT_READ,MAP_PRIVATE,_file,0); + if ( _map == MAP_FAILED ) _map = NULL; +#endif + if ( _map != NULL ) + { + _size = length; + _pos = (char*) _map; + _end = _pos + _size; + } + else + { +#ifdef WNT + CloseHandle(_mapObj); + CloseHandle(_file); +#else + ::close(_file); +#endif + } + } + } + return _pos; +} + +//================================================================================ +/*! + * \brief Close the file + */ +//================================================================================ + +void SMESH_File::close() +{ + if ( _map != NULL ) + { +#ifdef WNT + UnmapViewOfFile(_map); + CloseHandle(_mapObj); + CloseHandle(_file); +#else + ::munmap(_map, _size); + ::close(_file); +#endif + _map = NULL; + _pos = _end = 0; + _size = -1; + } +} + +//================================================================================ +/*! + * \brief Remove the file + */ +//================================================================================ + +bool SMESH_File::remove() +{ + close(); + try { + OSD_Path filePath(TCollection_AsciiString((char*)_name.data())); + OSD_File(filePath).Remove(); + } + catch ( Standard_ProgramError ) { + MESSAGE("Can't remove file: " << _name << " ; file does not exist or permission denied"); + return false; + } + return true; +} + +//================================================================================ +/*! + * \brief Return file size + */ +//================================================================================ + +int SMESH_File::size() const +{ + if ( _size >= 0 ) return _size; // size of open file + + int size = -1; + int file = ::open( _name.data(), O_RDONLY ); + if ( file > 0 ) + { + struct stat status; + int err = fstat( file, &status); + if ( !err ) + size = status.st_size; + ::close( file ); + } + return size; +} + +//================================================================================ +/*! + * \brief Set cursor to the given position + */ +//================================================================================ + +void SMESH_File::setPos(const char* pos) +{ + if ( pos > (const char*)_map && pos < _end ) + _pos = (char*) pos; +} + +//================================================================================ +/*! + * \brief Skip till current line end and return the skipped string + */ +//================================================================================ + +std::string SMESH_File::getLine() +{ + std::string line; + const char* p = _pos; + while ( !eof() ) + if ( *(++_pos) == '\n' ) + break; + line.append( p, _pos ); + if ( !eof() ) _pos++; + return line; +} + +//================================================================================ +/*! + * \brief Move cursor to the file beginning + */ +//================================================================================ + +void SMESH_File::rewind() +{ + _pos = (char*) _map; +} + +//================================================================================ +/*! + * \brief Fill vector by reading out integers from file. Vector size gives number + * of integers to read + */ +//================================================================================ + +bool SMESH_File::getInts(std::vector& ints) +{ + int i = 0; + while ( i < ints.size() ) + { + while ( !isdigit( *_pos ) && !eof()) ++_pos; + if ( eof() ) break; + if ( _pos[-1] == '-' ) --_pos; + ints[ i++ ] = strtol( _pos, (char**)&_pos, 10 ); + } + return ( i == ints.size() ); +} diff --git a/src/SMESHUtils/SMESH_File.hxx b/src/SMESHUtils/SMESH_File.hxx new file mode 100644 index 000000000..3734e96d6 --- /dev/null +++ b/src/SMESHUtils/SMESH_File.hxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_File.hxx +// Created : Wed Mar 10 10:33:04 2010 +// Author : Edward AGAPOV (eap) +// +#ifndef __SMESH_File_HXX__ +#define __SMESH_File_HXX__ + +#include "SMESH_Utils.hxx" + +#include +#include + +#ifdef WNT +#include +#else +#include +#endif + +/*! + * \brief High level util for effective file reading and other file operations + */ +class SMESHUtils_EXPORT SMESH_File +{ +public: + + SMESH_File(const std::string& name, bool open=true); + + ~SMESH_File(); + + std::string getName() const { return _name; } + + bool open(); + + void close(); + + bool remove(); + + int size() const; + + // ------------------------ + // Access to file contents + // ------------------------ + + operator const char*() const { return _pos; } + + bool operator++() { return ++_pos < _end; } + + void operator +=(int posDelta) { _pos+=posDelta; } + + bool eof() const { return _pos >= _end; } + + const char* getPos() const { return _pos; } + + void setPos(const char* pos); + + std::string getLine(); + + void rewind(); + + bool getInts(std::vector& ids); + +private: + + std::string _name; //!< file name + int _size; //!< file size +#ifdef WNT + HANDLE _file, _mapObj; +#else + int _file; +#endif + void* _map; + const char* _pos; //!< current position + const char* _end; //!< position after file end +}; + +#endif diff --git a/src/SMESHUtils/SMESH_Octree.cxx b/src/SMESHUtils/SMESH_Octree.cxx new file mode 100644 index 000000000..00778a729 --- /dev/null +++ b/src/SMESHUtils/SMESH_Octree.cxx @@ -0,0 +1,211 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_Octree : global Octree implementation +// File : SMESH_Octree.cxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurélien Motteux(OCC) +// Module : SMESH +// +#include "SMESH_Octree.hxx" + +//=========================================================================== +/*! + * Constructor. limit must be provided at tree root construction. + * limit will be deleted by SMESH_Octree. + */ +//=========================================================================== + +SMESH_Octree::SMESH_Octree (SMESH_Octree::Limit* limit): + myChildren(NULL), + myFather(NULL), + myIsLeaf( false ), + myLimit( limit ), + myLevel(0), + myBox(NULL) +{ +} + +//================================================================================ +/*! + * \brief Compute the Octree + */ +//================================================================================ + +void SMESH_Octree::compute() +{ + if ( myLevel==0 ) + { + myBox = buildRootBox(); + if ( myLimit->myMinBoxSize > 0. && maxSize() <= myLimit->myMinBoxSize ) + myIsLeaf = true; + else + buildChildren(); + } +} + +//====================================== +/*! + * \brief SMESH_Octree Destructor + */ +//====================================== + +SMESH_Octree::~SMESH_Octree () +{ + if(myChildren != NULL) + { + if(!isLeaf()) + { + for(int i = 0; i<8; i++) + delete myChildren[i]; + delete[] myChildren; + myChildren = 0; + } + } + if ( myBox ) + delete myBox; + myBox = 0; + if ( level() == 0 ) + delete myLimit; + myLimit = 0; +} + +//================================================================= +/*! + * \brief Build the 8 children boxes and call buildChildrenData() + */ +//================================================================= + +void SMESH_Octree::buildChildren() +{ + if ( isLeaf() ) return; + + myChildren = new SMESH_Octree*[8]; + + gp_XYZ min = myBox->CornerMin(); + gp_XYZ max = myBox->CornerMax(); + gp_XYZ HSize = (max - min)/2.; + gp_XYZ mid = min + HSize; + gp_XYZ childHsize = HSize/2.; + + // get the whole model size + double rootSize = 0; + { + SMESH_Octree* root = this; + while ( root->myLevel > 0 ) + root = root->myFather; + rootSize = root->maxSize(); + } + Standard_Real XminChild, YminChild, ZminChild; + gp_XYZ minChild; + for (int i = 0; i < 8; i++) + { + // We build the eight boxes, we need 2 points to do that: + // Min and Mid + // In binary, we can write i from 0 to 7 + // For instance : + // 5 is 101, it corresponds here in coordinates to ZYX + // If coordinate is 0 in Y-> box from Ymin to Ymid + // If coordinate is 1 in Y-> box from Ymid to Ymax + // Same scheme for X and Z + // I need the minChild to build the Bnd_B3d box. + + XminChild = (i%2==0)?min.X():mid.X(); + YminChild = ((i%4)/2==0)?min.Y():mid.Y(); + ZminChild = (i<4)?min.Z():mid.Z(); + minChild.SetCoord(XminChild, YminChild, ZminChild); + + // The child is of the same type than its father (For instance, a SMESH_OctreeNode) + // We allocate the memory we need for the child + myChildren[i] = allocateOctreeChild(); + // and we assign to him its box. + myChildren[i]->myFather = this; + myChildren[i]->myLimit = myLimit; + myChildren[i]->myLevel = myLevel + 1; + myChildren[i]->myBox = new Bnd_B3d(minChild+childHsize,childHsize); + myChildren[i]->myBox->Enlarge( rootSize * 1e-10 ); + if ( myLimit->myMinBoxSize > 0. && myChildren[i]->maxSize() <= myLimit->myMinBoxSize ) + myChildren[i]->myIsLeaf = true; + } + + // After building the 8 boxes, we put the data into the children. + buildChildrenData(); + + //After we pass to the next level of the Octree + for (int i = 0; i<8; i++) + myChildren[i]->buildChildren(); +} + +//================================================================================ +/*! + * \brief Tell if Octree is a leaf or not + * An inheriting class can influence it via myIsLeaf protected field + */ +//================================================================================ + +bool SMESH_Octree::isLeaf() const +{ + return myIsLeaf || ((myLimit->myMaxLevel > 0) ? (level() >= myLimit->myMaxLevel) : false ); +} + +//=========================================================================== +/*! + * \brief Compute the bigger dimension of my box + */ +//=========================================================================== + +double SMESH_Octree::maxSize() const +{ + if ( myBox && !myBox->IsVoid() ) + { + gp_XYZ min = myBox->CornerMin(); + gp_XYZ max = myBox->CornerMax(); + gp_XYZ Size = (max - min); + double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y(); + return (returnVal>Size.Z())?returnVal:Size.Z(); + } + return 0.; +} + +//================================================================================ +/*! + * \brief Return height of the tree, full or from this level to topest leaf + */ +//================================================================================ + +int SMESH_Octree::getHeight(const bool full) const +{ + if ( full && myFather ) + return myFather->getHeight( true ); + + if ( isLeaf() ) + return 1; + + int heigth = 0; + for (int i = 0; i<8; i++) + { + int h = myChildren[i]->getHeight( false ); + if ( h > heigth ) + heigth = h; + } + return heigth + 1; +} diff --git a/src/SMESHUtils/SMESH_Octree.hxx b/src/SMESHUtils/SMESH_Octree.hxx new file mode 100644 index 000000000..97d767a60 --- /dev/null +++ b/src/SMESHUtils/SMESH_Octree.hxx @@ -0,0 +1,127 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_Octree : global Octree implementation +// File : SMESH_Octree.hxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurélien Motteux (OCC) +// Module : SMESH +// +#ifndef _SMESH_OCTREE_HXX_ +#define _SMESH_OCTREE_HXX_ + +#include "SMESH_Utils.hxx" +#include + +class SMESHUtils_EXPORT SMESH_Octree { + +public: + + // Data limiting the tree height + struct Limit { + // MaxLevel of the Octree + int myMaxLevel; + // Minimal size of the Box + double myMinBoxSize; + + // Default: + // maxLevel-> 8^8 = 16777216 terminal trees + // minSize -> box size not checked + Limit(int maxLevel=8, double minSize=0.):myMaxLevel(maxLevel),myMinBoxSize(minSize) {} + virtual ~Limit() {} // it can be inherited + }; + + // Constructor. limit must be provided at tree root construction. + // limit will be deleted by SMESH_Octree + SMESH_Octree (Limit* limit=0); + + // Destructor + virtual ~SMESH_Octree (); + + // Compute the Octree. Must be called by constructor of inheriting class + void compute(); + + // Tell if Octree is a leaf or not. + // An inheriting class can influence it via myIsLeaf protected field + bool isLeaf() const; + + // Return its level + int level() const { return myLevel; } + + // Get box to the 3d Bounding Box of the Octree + const Bnd_B3d& getBox() const { return *myBox; } + + // Compute the bigger dimension of my box + double maxSize() const; + + // Return index of a child the given point is in + inline int getChildIndex(double x, double y, double z, const gp_XYZ& boxMiddle)const; + + // Return height of the tree, full or from this level to topest leaf + int getHeight(const bool full=true) const; + +protected: + // Return box of the whole tree + virtual Bnd_B3d* buildRootBox() = 0; + + // Constructor for children + virtual SMESH_Octree* allocateOctreeChild() const = 0; + + // Build the data in the 8 children + virtual void buildChildrenData() = 0; + + // members + + // Array of 8 Octree children + SMESH_Octree** myChildren; + + // Point the father, set to NULL for the level 0 + SMESH_Octree* myFather; + + // Tell us if the Octree is a leaf or not + bool myIsLeaf; + + // Tree limit + const Limit* myLimit; + +private: + // Build the 8 children boxes recursively + void buildChildren(); + + // Level of the Octree + int myLevel; + + Bnd_B3d* myBox; +}; + +//================================================================================ +/*! + * \brief Return index of a child the given point is in + */ +//================================================================================ + +inline int SMESH_Octree::getChildIndex(double x, double y, double z, const gp_XYZ& mid) const +{ + return (x > mid.X()) + ( y > mid.Y())*2 + (z > mid.Z())*4; +} + +#endif diff --git a/src/SMESHUtils/SMESH_OctreeNode.cxx b/src/SMESHUtils/SMESH_OctreeNode.cxx new file mode 100644 index 000000000..d14a50a24 --- /dev/null +++ b/src/SMESHUtils/SMESH_OctreeNode.cxx @@ -0,0 +1,437 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_OctreeNode : Octree with Nodes set +// inherites global class SMESH_Octree +// File : SMESH_OctreeNode.cxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurelien Motteux (OCC) +// Module : SMESH +// +#include "SMESH_OctreeNode.hxx" + +#include "SMDS_SetIterator.hxx" +#include + +using namespace std; + +//=============================================================== +/*! + * \brief Constructor : Build all the Octree using Compute() + * \param theNodes - Set of nodes, the Octree is built from this nodes + * \param maxLevel - Maximum level for the leaves + * \param maxNbNodes - Maximum number of nodes, a leaf can contain + * \param minBoxSize - Minimal size of the Octree Box + */ +//================================================================ +SMESH_OctreeNode::SMESH_OctreeNode (const TIDSortedNodeSet & theNodes, const int maxLevel, + const int maxNbNodes , const double minBoxSize ) + :SMESH_Octree( new SMESH_Octree::Limit( maxLevel,minBoxSize)), + myMaxNbNodes(maxNbNodes), + myNodes(theNodes) +{ + compute(); +} + +//================================================================================ +/*! + * \brief Constructor used to allocate a child + */ +//================================================================================ + +SMESH_OctreeNode::SMESH_OctreeNode (int maxNbNodes): + SMESH_Octree(), myMaxNbNodes(maxNbNodes) +{ +} + +//================================================================================== +/*! + * \brief Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren() + */ +//================================================================================== + +SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild() const +{ + return new SMESH_OctreeNode(myMaxNbNodes); +} + +//====================================== +/*! + * \brief Compute the first bounding box + * + * We take the max/min coord of the nodes + */ +//====================================== + +Bnd_B3d* SMESH_OctreeNode::buildRootBox() +{ + Bnd_B3d* box = new Bnd_B3d; + TIDSortedNodeSet::iterator it = myNodes.begin(); + for (; it != myNodes.end(); it++) { + const SMDS_MeshNode* n1 = *it; + gp_XYZ p1( n1->X(), n1->Y(), n1->Z() ); + box->Add(p1); + } + if ( myNodes.size() <= myMaxNbNodes ) + myIsLeaf = true; + + return box; +} + +//==================================================================================== +/*! + * \brief Tells us if Node is inside the current box with the precision "precision" + * \param Node - Node + * \param precision - The box is enlarged with this precision + * \retval bool - True if Node is in the box within precision + */ +//==================================================================================== + +const bool SMESH_OctreeNode::isInside (const gp_XYZ& p, const double precision) +{ + if (precision <= 0.) + return !(getBox().IsOut(p)); + Bnd_B3d BoxWithPrecision = getBox(); + BoxWithPrecision.Enlarge(precision); + return ! BoxWithPrecision.IsOut(p); +} + +//================================================ +/*! + * \brief Set the data of the children + * Shares the father's data with each of his child + */ +//================================================ +void SMESH_OctreeNode::buildChildrenData() +{ + gp_XYZ min = getBox().CornerMin(); + gp_XYZ max = getBox().CornerMax(); + gp_XYZ mid = (min + max)/2.; + + TIDSortedNodeSet::iterator it = myNodes.begin(); + while (it != myNodes.end()) + { + const SMDS_MeshNode* n1 = *it; + int ChildBoxNum = getChildIndex( n1->X(), n1->Y(), n1->Z(), mid ); + SMESH_OctreeNode* myChild = dynamic_cast (myChildren[ChildBoxNum]); + myChild->myNodes.insert(myChild->myNodes.end(),n1); + myNodes.erase( it ); + it = myNodes.begin(); + } + for (int i = 0; i < 8; i++) + { + SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); + if ( myChild->myNodes.size() <= myMaxNbNodes ) + myChild->myIsLeaf = true; + } +} + +//=================================================================== +/*! + * \brief Return in Result a list of Nodes potentials to be near Node + * \param Node - Node + * \param precision - precision used + * \param Result - list of Nodes potentials to be near Node + */ +//==================================================================== +void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node, + list* Result, + const double precision) +{ + gp_XYZ p(Node->X(), Node->Y(), Node->Z()); + if (isInside(p, precision)) + { + if (isLeaf()) + { + Result->insert(Result->end(), myNodes.begin(), myNodes.end()); + } + else + { + for (int i = 0; i < 8; i++) + { + SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); + myChild->NodesAround(Node, Result, precision); + } + } + } +} + +//================================================================================ +/*! + * \brief Return in dist2Nodes nodes mapped to their square distance from Node + * \param node - node to find nodes closest to + * \param dist2Nodes - map of found nodes and their distances + * \param precision - radius of a sphere to check nodes inside + * \retval bool - true if an exact overlapping found + */ +//================================================================================ + +bool SMESH_OctreeNode::NodesAround(const gp_XYZ &node, + map& dist2Nodes, + double precision) +{ + if ( !dist2Nodes.empty() ) + precision = min ( precision, sqrt( dist2Nodes.begin()->first )); + else if ( precision == 0. ) + precision = maxSize() / 2; + + //gp_XYZ p(node->X(), node->Y(), node->Z()); + if (isInside(node, precision)) + { + if (!isLeaf()) + { + // first check a child containing node + gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.; + int nodeChild = getChildIndex( node.X(), node.Y(), node.Z(), mid ); + if ( ((SMESH_OctreeNode*) myChildren[nodeChild])->NodesAround(node, dist2Nodes, precision)) + return true; + + for (int i = 0; i < 8; i++) + if ( i != nodeChild ) + if (((SMESH_OctreeNode*) myChildren[i])->NodesAround(node, dist2Nodes, precision)) + return true; + } + else if ( NbNodes() > 0 ) + { + double minDist = precision * precision; + gp_Pnt p1 ( node.X(), node.Y(), node.Z() ); + TIDSortedNodeSet::iterator nIt = myNodes.begin(); + for ( ; nIt != myNodes.end(); ++nIt ) + { + gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() ); + double dist2 = p1.SquareDistance( p2 ); + if ( dist2 < minDist ) + dist2Nodes.insert( make_pair( minDist = dist2, *nIt )); + } +// if ( dist2Nodes.size() > 1 ) // leave only closest node in dist2Nodes +// dist2Nodes.erase( ++dist2Nodes.begin(), dist2Nodes.end()); + + return ( sqrt( minDist) <= precision * 1e-12 ); + } + } + return false; +} + +//============================= +/*! + * \brief Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance + * Search for all the nodes in theSetOfNodes + * Static Method : no need to create an SMESH_OctreeNode + * \param theSetOfNodes - set of nodes we look at, modified during research + * \param theGroupsOfNodes - list of nodes closed to each other returned + * \param theTolerance - Precision used, default value is 0.00001 + * \param maxLevel - Maximum level for SMESH_OctreeNode constructed, default value is -1 (Infinite) + * \param maxNbNodes - maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5 + */ +//============================= +void SMESH_OctreeNode::FindCoincidentNodes (TIDSortedNodeSet& theSetOfNodes, + list< list< const SMDS_MeshNode*> >* theGroupsOfNodes, + const double theTolerance, + const int maxLevel, + const int maxNbNodes) +{ + // VSR 14/10/2011: limit max number of the levels in order to avoid endless recursing + const int MAX_LEVEL = 10; + SMESH_OctreeNode theOctreeNode(theSetOfNodes, maxLevel < 0 ? MAX_LEVEL : maxLevel, maxNbNodes, theTolerance); + theOctreeNode.FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes); +} + +//============================= +/*! + * \brief Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance + * Search for all the nodes in theSetOfNodes + * \note The Octree itself is also modified by this method + * \param theSetOfNodes - set of nodes we look at, modified during research + * \param theTolerance - Precision used + * \param theGroupsOfNodes - list of nodes closed to each other returned + */ +//============================= +void SMESH_OctreeNode::FindCoincidentNodes ( TIDSortedNodeSet* theSetOfNodes, + const double theTolerance, + list< list< const SMDS_MeshNode*> >* theGroupsOfNodes) +{ + TIDSortedNodeSet::iterator it1 = theSetOfNodes->begin(); + list::iterator it2; + + while (it1 != theSetOfNodes->end()) + { + const SMDS_MeshNode * n1 = *it1; + + list ListOfCoincidentNodes;// Initialize the lists via a declaration, it's enough + + list * groupPtr = 0; + + // Searching for Nodes around n1 and put them in ListofCoincidentNodes. + // Found nodes are also erased from theSetOfNodes + FindCoincidentNodes(n1, theSetOfNodes, &ListOfCoincidentNodes, theTolerance); + + // We build a list {n1 + his neigbours} and add this list in theGroupsOfNodes + for (it2 = ListOfCoincidentNodes.begin(); it2 != ListOfCoincidentNodes.end(); it2++) + { + const SMDS_MeshNode* n2 = *it2; + if ( !groupPtr ) + { + theGroupsOfNodes->push_back( list() ); + groupPtr = & theGroupsOfNodes->back(); + groupPtr->push_back( n1 ); + } + if (groupPtr->front() > n2) + groupPtr->push_front( n2 ); + else + groupPtr->push_back( n2 ); + } + if (groupPtr != 0) + groupPtr->sort(); + + theSetOfNodes->erase(it1); + it1 = theSetOfNodes->begin(); + } +} + +//====================================================================================== +/*! + * \brief Return a list of nodes closed to Node and remove it from SetOfNodes + * \note The Octree itself is also modified by this method + * \param Node - We're searching the nodes next to him. + * \param SetOfNodes - set of nodes in which we erase the found nodes + * \param Result - list of nodes closed to Node + * \param precision - Precision used + */ +//====================================================================================== +void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node, + TIDSortedNodeSet* SetOfNodes, + list* Result, + const double precision) +{ + gp_XYZ p(Node->X(), Node->Y(), Node->Z()); + bool isInsideBool = isInside(p, precision); + + if (isInsideBool) + { + // I'm only looking in the leaves, since all the nodes are stored there. + if (isLeaf()) + { + gp_Pnt p1 (Node->X(), Node->Y(), Node->Z()); + + TIDSortedNodeSet myNodesCopy = myNodes; + TIDSortedNodeSet::iterator it = myNodesCopy.begin(); + double tol2 = precision * precision; + bool squareBool; + + while (it != myNodesCopy.end()) + { + const SMDS_MeshNode* n2 = *it; + // We're only looking at nodes with a superior Id. + // JFA: Why? + //if (Node->GetID() < n2->GetID()) + if (Node->GetID() != n2->GetID()) // JFA: for bug 0020185 + { + gp_Pnt p2 (n2->X(), n2->Y(), n2->Z()); + // Distance optimized computation + squareBool = (p1.SquareDistance( p2 ) <= tol2); + + // If n2 inside the SquareDistance, we add it in Result and remove it from SetOfNodes and myNodes + if (squareBool) + { + Result->insert(Result->begin(), n2); + SetOfNodes->erase( n2 ); + myNodes.erase( n2 ); + } + } + //myNodesCopy.erase( it ); + //it = myNodesCopy.begin(); + it++; + } + if (Result->size() > 0) + myNodes.erase(Node); // JFA: for bug 0020185 + } + else + { + // If I'm not a leaf, I'm going to see my children ! + for (int i = 0; i < 8; i++) + { + SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); + myChild->FindCoincidentNodes(Node, SetOfNodes, Result, precision); + } + } + } +} + +//================================================================================ +/*! + * \brief Update data according to node movement + */ +//================================================================================ + +void SMESH_OctreeNode::UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt ) +{ + if ( isLeaf() ) + { + TIDSortedNodeSet::iterator pNode = myNodes.find( node ); + bool nodeInMe = ( pNode != myNodes.end() ); + + bool pointInMe = isInside( toPnt.Coord(), 1e-10 ); + + if ( pointInMe != nodeInMe ) + { + if ( pointInMe ) + myNodes.insert( node ); + else + myNodes.erase( node ); + } + } + else if ( myChildren ) + { + gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.; + int nodeChild = getChildIndex( node->X(), node->Y(), node->Z(), mid ); + int pointChild = getChildIndex( toPnt.X(), toPnt.Y(), toPnt.Z(), mid ); + if ( nodeChild != pointChild ) + { + ((SMESH_OctreeNode*) myChildren[ nodeChild ])->UpdateByMoveNode( node, toPnt ); + ((SMESH_OctreeNode*) myChildren[ pointChild ])->UpdateByMoveNode( node, toPnt ); + } + } +} + +//================================================================================ +/*! + * \brief Return iterator over children + */ +//================================================================================ +SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator() +{ + return SMESH_OctreeNodeIteratorPtr + ( new SMDS_SetIterator< SMESH_OctreeNode*, SMESH_Octree** > + ( myChildren, (( isLeaf() || !myChildren ) ? myChildren : &myChildren[ 8 ] ))); +} + +//================================================================================ +/*! + * \brief Return nodes iterator + */ +//================================================================================ +SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator() +{ + return SMDS_NodeIteratorPtr + ( new SMDS_SetIterator< SMDS_pNode, TIDSortedNodeSet::const_iterator > + ( myNodes.begin(), myNodes.size() ? myNodes.end() : myNodes.begin())); +} diff --git a/src/SMESHUtils/SMESH_OctreeNode.hxx b/src/SMESHUtils/SMESH_OctreeNode.hxx new file mode 100644 index 000000000..cc66a275b --- /dev/null +++ b/src/SMESHUtils/SMESH_OctreeNode.hxx @@ -0,0 +1,137 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_OctreeNode : Octree with Nodes set +// inherites global class SMESH_Octree +// File : SMESH_OctreeNode.hxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurelien Motteux (OCC) +// Module : SMESH +// +#ifndef _SMESH_OCTREENODE_HXX_ +#define _SMESH_OCTREENODE_HXX_ + +#include "SMESH_Utils.hxx" +#include "SMESH_Octree.hxx" +#include +#include "SMDS_MeshNode.hxx" + +#include +#include +#include + +#include "SMDS_ElemIterator.hxx" + +//forward declaration +class SMDS_MeshNode; +class SMESH_OctreeNode; + +typedef SMDS_Iterator SMESH_OctreeNodeIterator; +typedef boost::shared_ptr SMESH_OctreeNodeIteratorPtr; +typedef std::set< const SMDS_MeshNode*, TIDCompare > TIDSortedNodeSet; + +class SMESHUtils_EXPORT SMESH_OctreeNode : public SMESH_Octree { + +public: + + // Constructor + SMESH_OctreeNode (const TIDSortedNodeSet& theNodes, const int maxLevel = 8, + const int maxNbNodes = 5, const double minBoxSize = 0.); + +//============================= +/*! + * \brief Empty destructor + */ +//============================= + virtual ~SMESH_OctreeNode () {}; + + // Tells us if Node is inside the current box with the precision "precision" + virtual const bool isInside(const gp_XYZ& p, const double precision = 0.); + + // Return in Result a list of Nodes potentials to be near Node + void NodesAround(const SMDS_MeshNode * Node, + std::list* Result, + const double precision = 0.); + + // Return in dist2Nodes nodes mapped to their square distance from Node + bool NodesAround(const gp_XYZ& node, + std::map& dist2Nodes, + double precision); + + // Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance + // Search for all the nodes in nodes + void FindCoincidentNodes ( TIDSortedNodeSet* nodes, + const double theTolerance, + std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes); + + // Static method that return in theGroupsOfNodes a list of group of nodes close to each other within + // theTolerance search for all the nodes in nodes + static void FindCoincidentNodes ( TIDSortedNodeSet& nodes, + std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes, + const double theTolerance = 0.00001, + const int maxLevel = -1, + const int maxNbNodes = 5); + /*! + * \brief Update data according to node movement + */ + void UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt ); + /*! + * \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 myNodes.size(); } + +protected: + + SMESH_OctreeNode (int maxNbNodes ); + + // Compute the bounding box of the whole set of nodes myNodes + virtual Bnd_B3d* buildRootBox(); + + // Shares the father's data with each of his child + virtual void buildChildrenData(); + + // Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren() + virtual SMESH_Octree* allocateOctreeChild() const; + + // Return in result a list of nodes closed to Node and remove it from SetOfNodes + void FindCoincidentNodes( const SMDS_MeshNode * Node, + TIDSortedNodeSet* SetOfNodes, + std::list* Result, + const double precision); + + // The max number of nodes a leaf box can contain + int myMaxNbNodes; + + // The set of nodes inside the box of the Octree (Empty if Octree is not a leaf) + TIDSortedNodeSet myNodes; + +}; + +#endif diff --git a/src/SMESHUtils/SMESH_TypeDefs.hxx b/src/SMESHUtils/SMESH_TypeDefs.hxx new file mode 100644 index 000000000..edb0f247f --- /dev/null +++ b/src/SMESHUtils/SMESH_TypeDefs.hxx @@ -0,0 +1,184 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_TypeDefs.hxx +// Created : Thu Jan 27 18:38:33 2011 +// Author : Edward AGAPOV (eap) + + +#ifndef __SMESH_TypeDefs_HXX__ +#define __SMESH_TypeDefs_HXX__ + +#include "SMESH_Utils.hxx" + +#include + +#include + +#include +#include +#include +#include + +typedef std::map > TElemOfElemListMap; +typedef std::map TNodeNodeMap; + +//!< Set of elements sorted by ID, to be used to assure predictability of edition +typedef std::set< const SMDS_MeshElement*, TIDCompare > TIDSortedElemSet; +typedef std::set< const SMDS_MeshNode*, TIDCompare > TIDSortedNodeSet; + +typedef std::pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink; + + +namespace SMESHUtils +{ + /*! + * \brief Enforce freeing memory allocated by std::vector + */ + template + void FreeVector(TVECTOR& vec) + { + TVECTOR v2; + vec.swap( v2 ); + } + template + void CompactVector(TVECTOR& vec) + { + TVECTOR v2( vec ); + vec.swap( v2 ); + } +} + +//======================================================================= +/*! + * \brief A sorted pair of nodes + */ +//======================================================================= + +struct SMESH_TLink: public NLink +{ + SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 ) + { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); } + SMESH_TLink(const NLink& link ):NLink( link ) + { if ( first->GetID() < second->GetID() ) std::swap( first, second ); } + const SMDS_MeshNode* node1() const { return first; } + const SMDS_MeshNode* node2() const { return second; } +}; + +//======================================================================= +/*! + * \brief SMESH_TLink knowing its orientation + */ +//======================================================================= + +struct SMESH_OrientedLink: public SMESH_TLink +{ + bool _reversed; + SMESH_OrientedLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ) + : SMESH_TLink( n1, n2 ), _reversed( n1 != node1() ) {} +}; + +//------------------------------------------ +/*! + * \brief SMDS_MeshNode -> gp_XYZ convertor + */ +//------------------------------------------ +struct SMESH_TNodeXYZ : public gp_XYZ +{ + const SMDS_MeshNode* _node; + double _xyz[3]; + SMESH_TNodeXYZ( const SMDS_MeshElement* e):gp_XYZ(0,0,0),_node(0) { + if (e) { + assert( e->GetType() == SMDSAbs_Node ); + _node = static_cast(e); + _node->GetXYZ(_xyz); // - thread safe getting coords + SetCoord( _xyz[0], _xyz[1], _xyz[2] ); + } + } + double Distance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).Modulus(); } + double SquareDistance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).SquareModulus(); } + bool operator==(const SMESH_TNodeXYZ& other) const { return _node == other._node; } +}; + +// -------------------------------------------------------------------------------- +// class SMESH_SequenceOfElemPtr +#include + +class SMDS_MeshElement; + +typedef const SMDS_MeshElement* SMDS_MeshElementPtr; + +DEFINE_BASECOLLECTION (SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr) +DEFINE_SEQUENCE (SMESH_SequenceOfElemPtr, SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr) + + +// -------------------------------------------------------------------------------- +// class SMESH_SequenceOfNode +typedef const SMDS_MeshNode* SMDS_MeshNodePtr; + +DEFINE_BASECOLLECTION (SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr) +DEFINE_SEQUENCE(SMESH_SequenceOfNode, + SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr) + +// -------------------------------------------------------------------------------- +// #include "SMESHDS_DataMapOfShape.hxx" + +// #include + +// #include + +/// Class SMESH_IndexedMapOfShape + +// DEFINE_BASECOLLECTION (SMESH_BaseCollectionShape, TopoDS_Shape) +// DEFINE_INDEXEDMAP (SMESH_IndexedMapOfShape, SMESH_BaseCollectionShape, TopoDS_Shape) + +/// Class SMESH_IndexedDataMapOfShapeIndexedMapOfShape + +// DEFINE_BASECOLLECTION (SMESH_BaseCollectionIndexedMapOfShape, SMESH_IndexedMapOfShape) +// DEFINE_INDEXEDDATAMAP (SMESH_IndexedDataMapOfShapeIndexedMapOfShape, +// SMESH_BaseCollectionIndexedMapOfShape, TopoDS_Shape, +// SMESH_IndexedMapOfShape) + +// -------------------------------------------------------------------------------- +// class SMESH_DataMapOfElemPtrSequenceOfElemPtr + +// SMESHUtils_EXPORT +// inline Standard_Integer HashCode(SMDS_MeshElementPtr theElem, +// const Standard_Integer theUpper) +// { +// void* anElem = (void*) theElem; +// return HashCode(anElem,theUpper); +// } + +// SMESHUtils_EXPORT +// inline Standard_Boolean IsEqual(SMDS_MeshElementPtr theOne, +// SMDS_MeshElementPtr theTwo) +// { +// return theOne == theTwo; +// } + +// DEFINE_BASECOLLECTION (SMESH_BaseCollectionSequenceOfElemPtr, SMESH_SequenceOfElemPtr) +// DEFINE_DATAMAP (SMESH_DataMapOfElemPtrSequenceOfElemPtr, +// SMESH_BaseCollectionSequenceOfElemPtr, +// SMDS_MeshElementPtr, SMESH_SequenceOfElemPtr) + +#endif diff --git a/src/SMESHUtils/SMESH_Utils.hxx b/src/SMESHUtils/SMESH_Utils.hxx new file mode 100755 index 000000000..45c4a2c52 --- /dev/null +++ b/src/SMESHUtils/SMESH_Utils.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : SMESH_Utils.hxx +// Author : Alexander A. BORODIN +// Module : SMESH +// +#ifndef _SMESH_Utils_hxx_ +#define _SMESH_Utils_hxx_ + +#ifdef WNT + #if defined SMESHUtils_EXPORTS + #define SMESHUtils_EXPORT __declspec( dllexport ) + #else + #define SMESHUtils_EXPORT __declspec( dllimport ) + #endif +#else + #define SMESHUtils_EXPORT +#endif + +#endif diff --git a/src/SMESH_I/Makefile.am b/src/SMESH_I/Makefile.am index 2a15a44df..2f748f7da 100644 --- a/src/SMESH_I/Makefile.am +++ b/src/SMESH_I/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses # File : Makefile.in # Author : Paul RASCLE, EDF @@ -48,6 +46,8 @@ salomeinclude_HEADERS = \ SMESH_Pattern_i.hxx \ SMESH_2smeshpy.hxx \ SMESH_NoteBook.hxx \ + SMESH_Measurements_i.hxx \ + SMESH_PreMeshInfo.hxx \ SMESH.hxx # Scripts to be installed. @@ -78,7 +78,9 @@ dist_libSMESHEngine_la_SOURCES = \ SMESH_Group_i.cxx \ SMESH_Pattern_i.cxx \ SMESH_2smeshpy.cxx \ - SMESH_NoteBook.cxx + SMESH_NoteBook.cxx \ + SMESH_Measurements_i.cxx \ + SMESH_PreMeshInfo.cxx # Executables targets bin_PROGRAMS = SMESHEngine @@ -92,6 +94,7 @@ libSMESHEngine_la_CPPFLAGS = \ $(CORBA_INCLUDES) \ $(CAS_CPPFLAGS) \ @HDF5_INCLUDES@ \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ $(KERNEL_CXXFLAGS) \ $(GUI_CXXFLAGS) \ @@ -102,14 +105,16 @@ libSMESHEngine_la_CPPFLAGS = \ -I$(srcdir)/../SMESHDS \ -I$(srcdir)/../Driver \ -I$(srcdir)/../DriverMED \ + -I$(srcdir)/../DriverCGNS \ -I$(srcdir)/../SMESH \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix - + -I$(srcdir)/../SMESHUtils \ + -I$(top_builddir)/idl libSMESHEngine_la_LDFLAGS = \ ../../idl/libSalomeIDLSMESH.la \ ../SMESH/libSMESHimpl.la \ + ../SMDS/libSMDS.la \ + ../SMESHDS/libSMESHDS.la \ ../Controls/libSMESHControls.la \ $(KERNEL_LDFLAGS) \ -lSalomeContainer \ @@ -119,7 +124,10 @@ libSMESHEngine_la_LDFLAGS = \ -lSalomeLifeCycleCORBA \ -lTOOLSDS \ -lSalomeGenericObj \ + -lSalomeIDLKernel \ + -lSALOMELocalTrace \ $(MED_LDFLAGS) \ + -lMEDWrapper \ -lMEDWrapper_V2_2 \ -lSalomeIDLMED \ $(CAS_LDPATH) \ @@ -127,7 +135,8 @@ libSMESHEngine_la_LDFLAGS = \ -lTKBO \ -lTKShHealing \ $(GEOM_LDFLAGS) \ - -lGEOMClient + -lGEOMClient \ + -lSalomeIDLGEOM SMESHEngine_CPPFLAGS = \ $(libSMESHEngine_la_CPPFLAGS) diff --git a/src/SMESH_I/SMESH.hxx b/src/SMESH_I/SMESH.hxx index 0bd99b692..579ae9127 100644 --- a/src/SMESH_I/SMESH.hxx +++ b/src/SMESH_I/SMESH.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : // File : SMESH.hxx // Author : Michael ZORIN @@ -29,7 +30,7 @@ #define _SMESH_I_SMESH_HXX_ #ifdef WNT - #if defined SMESH_I_EXPORTS + #if defined SMESH_I_EXPORTS || defined SMESHEngine_EXPORTS #define SMESH_I_EXPORT __declspec( dllexport ) #else #define SMESH_I_EXPORT __declspec( dllimport ) diff --git a/src/SMESH_I/SMESHEngine.cxx b/src/SMESH_I/SMESHEngine.cxx index 0c8d3bd60..5034d2cdd 100644 --- a/src/SMESH_I/SMESHEngine.cxx +++ b/src/SMESH_I/SMESHEngine.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + int main(int argc, char** argv) { return 1; diff --git a/src/SMESH_I/SMESH_0D_Algo_i.cxx b/src/SMESH_I/SMESH_0D_Algo_i.cxx index cd8247ba9..84f9067d5 100644 --- a/src/SMESH_I/SMESH_0D_Algo_i.cxx +++ b/src/SMESH_I/SMESH_0D_Algo_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_0D_Algo_i.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_0D_Algo_i.hxx b/src/SMESH_I/SMESH_0D_Algo_i.hxx index 401feed17..dd23a1c1c 100644 --- a/src/SMESH_I/SMESH_0D_Algo_i.hxx +++ b/src/SMESH_I/SMESH_0D_Algo_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_0D_Algo_i.hxx // Module : SMESH diff --git a/src/SMESH_I/SMESH_1D_Algo_i.cxx b/src/SMESH_I/SMESH_1D_Algo_i.cxx index e5da53f79..9dcf746ac 100644 --- a/src/SMESH_I/SMESH_1D_Algo_i.cxx +++ b/src/SMESH_I/SMESH_1D_Algo_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_1D_Algo_i.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_1D_Algo_i.hxx b/src/SMESH_I/SMESH_1D_Algo_i.hxx index 4ae7b0ea5..b8c912e62 100644 --- a/src/SMESH_I/SMESH_1D_Algo_i.hxx +++ b/src/SMESH_I/SMESH_1D_Algo_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_1D_Algo_i.hxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_2D_Algo_i.cxx b/src/SMESH_I/SMESH_2D_Algo_i.cxx index 7fcf5a86d..37d228f76 100644 --- a/src/SMESH_I/SMESH_2D_Algo_i.cxx +++ b/src/SMESH_I/SMESH_2D_Algo_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_2D_Algo_i.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_2D_Algo_i.hxx b/src/SMESH_I/SMESH_2D_Algo_i.hxx index 2579278fb..43277ccf5 100644 --- a/src/SMESH_I/SMESH_2D_Algo_i.hxx +++ b/src/SMESH_I/SMESH_2D_Algo_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_2D_Algo_i.hxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index be494755b..88e7ba182 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -1,26 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_2smeshpy.cxx // Created : Fri Nov 18 13:20:10 2005 // Author : Edward AGAPOV (eap) @@ -30,34 +29,52 @@ #include "utilities.h" #include "SMESH_PythonDump.hxx" #include "SMESH_NoteBook.hxx" -#include "Resource_DataMapOfAsciiStringAsciiString.hxx" +#include "SMESH_Filter_i.hxx" + +#include +#include #include "SMESH_Gen_i.hxx" -/* SALOME headers that include CORBA headers that include windows.h +/* SALOME headers that include CORBA headers that include windows.h * that defines GetObject symbol as GetObjectA should stand before SALOME headers * that declare methods named GetObject - to apply the same rules of GetObject renaming * and thus to avoid mess with GetObject symbol on Windows */ +#include + +#ifdef WNT +#include +#else +#include +#endif + + IMPLEMENT_STANDARD_HANDLE (_pyObject ,Standard_Transient); IMPLEMENT_STANDARD_HANDLE (_pyCommand ,Standard_Transient); +IMPLEMENT_STANDARD_HANDLE (_pyHypothesisReader,Standard_Transient); IMPLEMENT_STANDARD_HANDLE (_pyGen ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pyMesh ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pySubMesh ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pyHypothesis ,_pyObject); -IMPLEMENT_STANDARD_HANDLE (_pyFilterManager ,_pyObject); +IMPLEMENT_STANDARD_HANDLE (_pySelfEraser ,_pyObject); +IMPLEMENT_STANDARD_HANDLE (_pyGroup ,_pyObject); +IMPLEMENT_STANDARD_HANDLE (_pyFilter ,_pyObject); IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis); IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis); IMPLEMENT_STANDARD_HANDLE (_pyNumberOfSegmentsHyp,_pyHypothesis); IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient); IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient); +IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient); IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pyFilterManager ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject); +IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject); IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis); IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis); IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis); @@ -106,6 +123,166 @@ namespace { return find( name ) != end(); } }; + + //================================================================================ + /*! + * \brief Returns a mesh by object + */ + //================================================================================ + + Handle(_pyMesh) ObjectToMesh( const Handle( _pyObject )& obj ) + { + if ( !obj.IsNull() ) + { + if ( obj->IsKind( STANDARD_TYPE( _pyMesh ))) + return Handle(_pyMesh)::DownCast( obj ); + else if ( obj->IsKind( STANDARD_TYPE( _pySubMesh ))) + return Handle(_pySubMesh)::DownCast( obj )->GetMesh(); + else if ( obj->IsKind( STANDARD_TYPE( _pyGroup ))) + return Handle(_pyGroup)::DownCast( obj )->GetMesh(); + } + return Handle(_pyMesh)(); + } + + //================================================================================ + /*! + * \brief Check if objects used as args have been created by previous commands + */ + //================================================================================ + + void CheckObjectPresence( const Handle(_pyCommand)& cmd, set<_pyID> & presentObjects) + { + for ( int iArg = cmd->GetNbArgs(); iArg; --iArg ) + { + const _pyID& arg = cmd->GetArg( iArg ); + if ( arg.IsEmpty() || arg.Value( 1 ) == '"' || arg.Value( 1 ) == '\'' ) + continue; + list< _pyID > idList = cmd->GetStudyEntries( arg ); + list< _pyID >::iterator id = idList.begin(); + for ( ; id != idList.end(); ++id ) + if ( !theGen->IsGeomObject( *id ) && !presentObjects.count( *id )) + { + cmd->Comment(); + cmd->GetString() += " ### " ; + cmd->GetString() += *id + " has not been yet created"; + return; + } + } + const _pyID& obj = cmd->GetObject(); + if ( !obj.IsEmpty() && cmd->IsStudyEntry( obj ) && !presentObjects.count( obj )) + { + cmd->Comment(); + cmd->GetString() += " ### not created object" ; + } + const _pyID& result = cmd->GetResultValue(); + if ( result.IsEmpty() || result.Value( 1 ) == '"' || result.Value( 1 ) == '\'' ) + return; + list< _pyID > idList = cmd->GetStudyEntries( result ); + list< _pyID >::iterator id = idList.begin(); + for ( ; id != idList.end(); ++id ) + presentObjects.insert( *id ); + } + + //================================================================================ + /*! + * \brief Fix SMESH::FunctorType arguments of SMESH::Filter::Criterion() + */ + //================================================================================ + + void fixFunctorType( TCollection_AsciiString& Type, + TCollection_AsciiString& Compare, + TCollection_AsciiString& UnaryOp, + TCollection_AsciiString& BinaryOp ) + { + // The problem is that dumps of old studies created using filters becomes invalid + // when new items are inserted in the enum SMESH::FunctorType since values + // of this enum are dumped as integer values. + // This function corrects enum values of old studies given as args (Type,Compare,...) + // We can find out how to correct them by value of BinaryOp which can have only two + // values: FT_Undefined or FT_LogicalNOT. + // Hereafter is the history of the enum SMESH::FunctorType since v3.0.0 + // where PythonDump appeared + // v 3.0.0: FT_Undefined == 25 + // v 3.1.0: FT_Undefined == 26, new items: + // - FT_Volume3D = 7 + // v 4.1.2: FT_Undefined == 27, new items: + // - FT_BelongToGenSurface = 17 + // v 5.1.1: FT_Undefined == 32, new items: + // - FT_FreeNodes = 10 + // - FT_FreeFaces = 11 + // - FT_LinearOrQuadratic = 23 + // - FT_GroupColor = 24 + // - FT_ElemGeomType = 25 + // v 5.1.5: FT_Undefined == 33, new items: + // - FT_CoplanarFaces = 26 + // v 6.2.0: FT_Undefined == 39, new items: + // - FT_MaxElementLength2D = 8 + // - FT_MaxElementLength3D = 9 + // - FT_BareBorderVolume = 25 + // - FT_BareBorderFace = 26 + // - FT_OverConstrainedVolume = 27 + // - FT_OverConstrainedFace = 28 + // v 6.5.0: FT_Undefined == 43, new items: + // - FT_EqualNodes = 14 + // - FT_EqualEdges = 15 + // - FT_EqualFaces = 16 + // - FT_EqualVolumes = 17 + // v 6.6.0: FT_Undefined == 44, new items: + // - FT_BallDiameter = 37 + // + // It's necessary to continue recording this history and to fill + // undef2newItems (see below) accordingly. + + typedef map< int, vector< int > > TUndef2newItems; + static TUndef2newItems undef2newItems; + if ( undef2newItems.empty() ) + { + undef2newItems[ 26 ].push_back( 7 ); + undef2newItems[ 27 ].push_back( 17 ); + { int items[] = { 10, 11, 23, 24, 25 }; + undef2newItems[ 32 ].assign( items, items+5 ); } + undef2newItems[ 33 ].push_back( 26 ); + { int items[] = { 8, 9, 25, 26, 27, 28 }; + undef2newItems[ 39 ].assign( items, items+6 ); } + { int items[] = { 14, 15, 16, 17 }; + undef2newItems[ 43 ].assign( items, items+4 ); } + { int items[] = { 37 }; + undef2newItems[ 44 ].assign( items, items+1 ); } + } + + int iType = Type.IntegerValue(); + int iCompare = Compare.IntegerValue(); + int iUnaryOp = UnaryOp.IntegerValue(); + int iBinaryOp = BinaryOp.IntegerValue(); + + // find out integer value of FT_Undefined at the moment of dump + int oldUndefined = iBinaryOp; + if ( iBinaryOp < iUnaryOp ) // BinaryOp was FT_LogicalNOT + oldUndefined += 3; + + // apply history to args + TUndef2newItems::const_iterator undef_items = + undef2newItems.upper_bound( oldUndefined ); + if ( undef_items != undef2newItems.end() ) + { + int* pArg[4] = { &iType, &iCompare, &iUnaryOp, &iBinaryOp }; + for ( ; undef_items != undef2newItems.end(); ++undef_items ) + { + const vector< int > & addedItems = undef_items->second; + for ( size_t i = 0; i < addedItems.size(); ++i ) + for ( int iArg = 0; iArg < 4; ++iArg ) + { + int& arg = *pArg[iArg]; + if ( arg >= addedItems[i] ) + arg++; + } + } + Type = TCollection_AsciiString( iType ); + Compare = TCollection_AsciiString( iCompare ); + UnaryOp = TCollection_AsciiString( iUnaryOp ); + BinaryOp = TCollection_AsciiString( iBinaryOp ); + } + } } //================================================================================ @@ -113,22 +290,26 @@ namespace { * \brief Convert python script using commands of smesh.py * \param theScript - Input script * \retval TCollection_AsciiString - Convertion result + * \param theToKeepAllCommands - to keep all commands or + * to exclude commands relating to objects removed from study * * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx */ //================================================================================ TCollection_AsciiString -SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, +SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, - Resource_DataMapOfAsciiStringAsciiString& theObjectNames) + Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + SALOMEDS::Study_ptr& theStudy, + const bool theToKeepAllCommands) { - theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames ); + theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames, theStudy, theToKeepAllCommands ); // split theScript into separate commands SMESH_NoteBook * aNoteBook = new SMESH_NoteBook(); - + int from = 1, end = theScript.Length(), to; while ( from < end && ( to = theScript.Location( "\n", from, end ))) { @@ -137,13 +318,13 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, aNoteBook->AddCommand( theScript.SubString( from, to - 1 )); from = to + 1; } - + aNoteBook->ReplaceVariables(); TCollection_AsciiString aNoteScript = aNoteBook->GetResultScript(); delete aNoteBook; aNoteBook = 0; - + // split theScript into separate commands from = 1, end = aNoteScript.Length(); while ( from < end && ( to = aNoteScript.Location( "\n", from, end ))) @@ -160,6 +341,9 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, MESSAGE_BEGIN ( std::endl << " ######## RESULT ######## " << std::endl<< std::endl ); #endif + // clean commmands of removed objects depending on myIsPublished flag + theGen->ClearCommands(); + // reorder commands after conversion list< Handle(_pyCommand) >::iterator cmd; bool orderChanges; @@ -169,21 +353,25 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, if ( (*cmd)->SetDependentCmdsAfter() ) orderChanges = true; } while ( orderChanges ); - + // concat commands back into a script - TCollection_AsciiString aScript; + TCollection_AsciiString aScript, aPrevCmd; + set<_pyID> createdObjects; for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd ) { #ifdef DUMP_CONVERSION MESSAGE_ADD ( "## COM " << (*cmd)->GetOrderNb() << ": "<< (*cmd)->GetString() << std::endl ); #endif - if ( !(*cmd)->IsEmpty() ) { + if ( !(*cmd)->IsEmpty() && aPrevCmd != (*cmd)->GetString()) { + CheckObjectPresence( *cmd, createdObjects ); + aPrevCmd = (*cmd)->GetString(); aScript += "\n"; - aScript += (*cmd)->GetString(); + aScript += aPrevCmd; } } aScript += "\n"; + theGen->Free(); theGen.Nullify(); return aScript; @@ -196,15 +384,49 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript, //================================================================================ _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, - Resource_DataMapOfAsciiStringAsciiString& theObjectNames) - : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )), + Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + SALOMEDS::Study_ptr& theStudy, + const bool theToKeepAllCommands) + : _pyObject( new _pyCommand( "", 0 )), + myNbCommands( 0 ), myID2AccessorMethod( theEntry2AccessorMethod ), - myObjectNames( theObjectNames ) + myObjectNames( theObjectNames ), + myNbFilters( 0 ), + myToKeepAllCommands( theToKeepAllCommands ), + myStudy( SALOMEDS::Study::_duplicate( theStudy )), + myGeomIDNb(0), myGeomIDIndex(-1) { - myNbCommands = 0; - myHasPattern = false; // make that GetID() to return TPythonDump::SMESHGenName() + GetCreationCmd()->Clear(); + GetCreationCmd()->GetString() = TPythonDump::SMESHGenName(); GetCreationCmd()->GetString() += "="; + + // Find 1st digit of study entry by which a GEOM object differs from a SMESH object + if ( !theObjectNames.IsEmpty() && !CORBA::is_nil( theStudy )) + { + // find a GEOM entry + _pyID geomID; + SALOMEDS::SComponent_var geomComp = theStudy->FindComponent("GEOM"); + if ( geomComp->_is_nil() ) return; + CORBA::String_var entry = geomComp->GetID(); + geomID = entry.in(); + + // find a SMESH entry + _pyID smeshID; + Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString e2n( theObjectNames ); + for ( ; e2n.More() && smeshID.IsEmpty(); e2n.Next() ) + if ( _pyCommand::IsStudyEntry( e2n.Key() )) + smeshID = e2n.Key(); + + // find 1st difference between smeshID and geomID + if ( !geomID.IsEmpty() && !smeshID.IsEmpty() ) + for ( int i = 1; i <= geomID.Length() && i <= smeshID.Length(); ++i ) + if ( geomID.Value( i ) != smeshID.Value( i )) + { + myGeomIDNb = geomID.Value( i ); + myGeomIDIndex = i; + } + } } //================================================================================ @@ -235,74 +457,146 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand MESSAGE ( "## COM " << myNbCommands << ": "<< aCommand->GetString() ); #endif - _pyID objID = aCommand->GetObject(); + const _pyID& objID = aCommand->GetObject(); if ( objID.IsEmpty() ) return aCommand; + // Prevent moving a command creating a sub-mesh to the end of the script + // if the sub-mesh is used in theCommand as argument + if ( _pySubMesh::CanBeArgOfMethod( aCommand->GetMethod() )) + { + PlaceSubmeshAfterItsCreation( aCommand ); + } + + // Find an object to process theCommand + // SMESH_Gen method? - if ( objID == this->GetID() ) { + if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName()) + { this->Process( aCommand ); return aCommand; } - - // SMESH_subMesh method? - map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.find( objID ); - if ( id_subMesh != mySubMeshes.end() ) { - id_subMesh->second->Process( aCommand ); - return aCommand; - } // SMESH_Mesh method? map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID ); - if ( id_mesh != myMeshes.end() ) { + if ( id_mesh != myMeshes.end() ) + { + //id_mesh->second->AddProcessedCmd( aCommand ); + // check for mesh editor object if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation _pyID editorID = aCommand->GetResultValue(); Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand ); myMeshEditors.insert( make_pair( editorID, editor )); return aCommand; - } + } // check for SubMesh objects else if ( aCommand->GetMethod() == "GetSubMesh" ) { // SubMesh creation _pyID subMeshID = aCommand->GetResultValue(); Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand ); - mySubMeshes.insert( make_pair( subMeshID, subMesh )); + myObjects.insert( make_pair( subMeshID, subMesh )); } - id_mesh->second->Process( aCommand ); - return aCommand; - } - //SMESH_FilterManager method? - if ( theCommand.Search( "aFilterManager" ) != -1 ) { - if ( theCommand.Search( "CreateFilterManager" ) != -1 ) - myFilterManager = new _pyFilterManager( aCommand ); - else if ( !myFilterManager.IsNull() ) - myFilterManager->Process( aCommand ); + id_mesh->second->Process( aCommand ); + id_mesh->second->AddProcessedCmd( aCommand ); return aCommand; } // SMESH_MeshEditor method? map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID ); - if ( id_editor != myMeshEditors.end() ) { + if ( id_editor != myMeshEditors.end() ) + { + const TCollection_AsciiString& method = aCommand->GetMethod(); + + // some commands of SMESH_MeshEditor create meshes and groups + _pyID meshID, groups; + if ( method.Search("MakeMesh") != -1 ) + meshID = aCommand->GetResultValue(); + else if ( method == "MakeBoundaryMesh") + meshID = aCommand->GetResultValue(1); + else if ( method == "MakeBoundaryElements") + meshID = aCommand->GetResultValue(2); + + if ( method.Search("MakeGroups") != -1 || + method == "ExtrusionAlongPathX" || + method == "ExtrusionAlongPathObjX" || + method == "DoubleNodeGroupNew" || + method == "DoubleNodeGroupsNew" || + method == "DoubleNodeElemGroupNew" || + method == "DoubleNodeElemGroupsNew"|| + method == "DoubleNodeElemGroup2New"|| + method == "DoubleNodeElemGroups2New" + ) + groups = aCommand->GetResultValue(); + else if ( method == "MakeBoundaryMesh" ) + groups = aCommand->GetResultValue(2); + else if ( method == "MakeBoundaryElements") + groups = aCommand->GetResultValue(3); + id_editor->second->Process( aCommand ); - TCollection_AsciiString processedCommand = aCommand->GetString(); - // some commands of SMESH_MeshEditor create meshes - if ( aCommand->GetMethod().Search("MakeMesh") != -1 ) { - Handle(_pyMesh) mesh = new _pyMesh( aCommand, aCommand->GetResultValue() ); + id_editor->second->AddProcessedCmd( aCommand ); + + if ( !meshID.IsEmpty() && + !myMeshes.count( meshID ) && + aCommand->IsStudyEntry( meshID )) + { + TCollection_AsciiString processedCommand = aCommand->GetString(); + Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID ); + myMeshes.insert( make_pair( meshID, mesh )); + aCommand->Clear(); aCommand->GetString() = processedCommand; // discard changes made by _pyMesh - myMeshes.insert( make_pair( mesh->GetID(), mesh )); + } + if ( !groups.IsEmpty() ) + { + if ( !aCommand->IsStudyEntry( meshID )) + meshID = id_editor->second->GetMesh(); + Handle(_pyMesh) mesh = myMeshes[ meshID ]; + + list< _pyID > idList = aCommand->GetStudyEntries( groups ); + list< _pyID >::iterator grID = idList.begin(); + for ( ; grID != idList.end(); ++grID ) + if ( !myObjects.count( *grID )) + { + Handle(_pyGroup) group = new _pyGroup( aCommand, *grID ); + AddObject( group ); + if ( !mesh.IsNull() ) mesh->AddGroup( group ); + } } return aCommand; - } + } // SMESH_MeshEditor methods + // SMESH_Hypothesis method? list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); for ( ; hyp != myHypos.end(); ++hyp ) if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) { (*hyp)->Process( aCommand ); + (*hyp)->AddProcessedCmd( aCommand ); return aCommand; } + // aFilterManager.CreateFilter() ? + if ( aCommand->GetMethod() == "CreateFilter" ) + { + // Set a more human readable name to a filter + // aFilter0x7fbf6c71cfb0 -> aFilter_nb + _pyID newID, filterID = aCommand->GetResultValue(); + int pos = filterID.Search( "0x" ); + if ( pos > 1 ) + newID = (filterID.SubString(1,pos-1) + "_") + _pyID( ++myNbFilters ); + + Handle(_pyObject) filter( new _pyFilter( aCommand, newID )); + AddObject( filter ); + } + + // other object method? + map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.find( objID ); + if ( id_obj != myObjects.end() ) { + id_obj->second->Process( aCommand ); + id_obj->second->AddProcessedCmd( aCommand ); + return aCommand; + } + // Add access to a wrapped mesh AddMeshAccessorMethod( aCommand ); @@ -312,7 +606,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand // 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)) // TypeError: __init__() takes exactly 11 arguments (10 given) - char wrongCommand[] = "SMESH.Filter.Criterion("; + const char wrongCommand[] = "SMESH.Filter.Criterion("; if ( int beg = theCommand.Location( wrongCommand, 1, theCommand.Length() )) { _pyCommand tmpCmd( theCommand.SubString( beg, theCommand.Length() ), -1); @@ -326,13 +620,86 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand aCommand->GetString().Trunc( beg - 1 ); aCommand->GetString() += tmpCmd.GetString(); } + // IMP issue 0021014 + // set GetCriterion(elementType,CritType,Compare,Treshold,UnaryOp,BinaryOp,Tolerance) + // 1 2 3 4 5 6 7 + // instead of "SMESH.Filter.Criterion( + // Type,Compare,Threshold,ThresholdStr,ThresholdID,UnaryOp,BinaryOp,Tolerance,TypeOfElement,Precision) + // 1 2 3 4 5 6 7 8 9 10 + // in order to avoid the problem of type mismatch of long and FunctorType + const TCollection_AsciiString + SMESH("SMESH."), dfltFunctor = "SMESH.FT_Undefined", dftlTol = "1e-07", dftlPreci = "-1"; + TCollection_AsciiString + Type = aCommand->GetArg(1), // long + Compare = aCommand->GetArg(2), // long + Threshold = aCommand->GetArg(3), // double + ThresholdStr = aCommand->GetArg(4), // string + ThresholdID = aCommand->GetArg(5), // string + UnaryOp = aCommand->GetArg(6), // long + BinaryOp = aCommand->GetArg(7), // long + Tolerance = aCommand->GetArg(8), // double + TypeOfElement = aCommand->GetArg(9), // ElementType + Precision = aCommand->GetArg(10); // long + fixFunctorType( Type, Compare, UnaryOp, BinaryOp ); + Type = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Type.IntegerValue() )); + Compare = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Compare.IntegerValue() )); + UnaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( UnaryOp.IntegerValue() )); + BinaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( BinaryOp.IntegerValue() )); + + aCommand->RemoveArgs(); + aCommand->SetObject( SMESH_2smeshpy::GenName() ); + aCommand->SetMethod( "GetCriterion" ); + + aCommand->SetArg( 1, TypeOfElement ); + aCommand->SetArg( 2, Type ); + aCommand->SetArg( 3, Compare ); + + if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() ) + { + // set SMESH.GeometryType instead of a numerical Threshold + const char* types[SMESH::Geom_BALL+1] = { + "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON", + "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_HEXAGONAL_PRISM", + "Geom_POLYHEDRA", "Geom_BALL" + }; + int iGeom = Threshold.IntegerValue(); + if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 ) + Threshold = SMESH + types[ iGeom ]; + } + if ( ThresholdID.Length() != 2 && ThresholdStr.Length() != 2) // not '' or "" + aCommand->SetArg( 4, ThresholdID.SubString( 2, ThresholdID.Length()-1 )); // shape entry + else if ( ThresholdStr.Length() != 2 ) + aCommand->SetArg( 4, ThresholdStr ); + else if ( ThresholdID.Length() != 2 ) + aCommand->SetArg( 4, ThresholdID ); + else + aCommand->SetArg( 4, Threshold ); + // find the last not default arg + int lastDefault = 8; + if ( Tolerance == dftlTol ) { + lastDefault = 7; + if ( BinaryOp == dfltFunctor ) { + lastDefault = 6; + if ( UnaryOp == dfltFunctor ) + lastDefault = 5; + } + } + if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp ); + if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp ); + if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance ); + if ( Precision != dftlPreci ) + { + TCollection_AsciiString crit = aCommand->GetResultValue(); + aCommand->GetString() += "; "; + aCommand->GetString() += crit + ".Precision = " + Precision; + } } return aCommand; } //================================================================================ /*! - * \brief Convert the command or remember it for later conversion + * \brief Convert the command or remember it for later conversion * \param theCommand - The python command calling a method of SMESH_Gen */ //================================================================================ @@ -344,6 +711,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) // Concatenate( [mesh1, ...], ... ) // CreateHypothesis( theHypType, theLibName ) // Compute( mesh, geom ) + // Evaluate( mesh, geom ) // mesh creation TCollection_AsciiString method = theCommand->GetMethod(); @@ -353,18 +721,23 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) myMeshes.insert( make_pair( mesh->GetID(), mesh )); return; } - if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL") + if ( method == "CreateMeshesFromUNV" || + method == "CreateMeshesFromSTL" || + method == "CreateMeshesFromCGNS" || + method == "CopyMesh" ) { Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() ); myMeshes.insert( make_pair( mesh->GetID(), mesh )); return; } - if( method == "CreateMeshesFromMED") + if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV") { for(int ind = 0;indGetNbResultValues();ind++) { - Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind)); - myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh )); + _pyID meshID = theCommand->GetResultValue(ind+1); + if ( !theCommand->IsStudyEntry( meshID ) ) continue; + Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind+1)); + myMeshes.insert( make_pair( mesh->GetID(), mesh )); } } @@ -392,22 +765,38 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) if ( id_mesh != myMeshes.end() ) { theCommand->SetObject( meshID ); theCommand->RemoveArgs(); - id_mesh->second->Flush(); + id_mesh->second->Process( theCommand ); + id_mesh->second->AddProcessedCmd( theCommand ); return; } } - // leave only one smeshgen.GetPattern() in the script - if ( method == "GetPattern" ) { - if ( myHasPattern ) { - theCommand->Clear(); + // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom) + if ( method == "Evaluate" ) + { + const _pyID& meshID = theCommand->GetArg( 1 ); + map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID ); + if ( id_mesh != myMeshes.end() ) { + theCommand->SetObject( meshID ); + _pyID geom = theCommand->GetArg( 2 ); + theCommand->RemoveArgs(); + theCommand->SetArg( 1, geom ); + id_mesh->second->AddProcessedCmd( theCommand ); return; } - myHasPattern = true; } + // objects erasing creation command if no more it's commands invoked: + // SMESH_Pattern, FilterManager + if ( method == "GetPattern" || + method == "CreateFilterManager" || + method == "CreateMeasurements" ) { + Handle(_pyObject) obj = new _pySelfEraser( theCommand ); + if ( !myObjects.insert( make_pair( obj->GetID(), obj )).second ) + theCommand->Clear(); // already created + } // Concatenate( [mesh1, ...], ... ) - if ( method == "Concatenate" || method == "ConcatenateWithGroups") + else if ( method == "Concatenate" || method == "ConcatenateWithGroups") { if ( method == "ConcatenateWithGroups" ) { theCommand->SetMethod( "Concatenate" ); @@ -417,6 +806,14 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) myMeshes.insert( make_pair( mesh->GetID(), mesh )); AddMeshAccessorMethod( theCommand ); } + else if ( method == "SetName" ) // SetName(obj,name) + { + // store theCommand as one of object commands to erase it along with the object + const _pyID& objID = theCommand->GetArg( 1 ); + Handle(_pyObject) obj = FindObject( objID ); + if ( !obj.IsNull() ) + obj->AddProcessedCmd( theCommand ); + } // Replace name of SMESH_Gen @@ -445,19 +842,45 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) void _pyGen::Flush() { - // create empty command + // create an empty command myLastCommand = new _pyCommand(); - if ( !myFilterManager.IsNull() ) - myFilterManager->Flush(); + map< _pyID, Handle(_pyMesh) >::iterator id_mesh; + map< _pyID, Handle(_pyObject) >::iterator id_obj; + list< Handle(_pyHypothesis) >::iterator hyp; - map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin(); - for ( ; id_mesh != myMeshes.end(); ++id_mesh ) + if ( IsToKeepAllCommands() ) // historical dump + { + // set myIsPublished = true to all objects + for ( id_mesh = myMeshes.begin(); id_mesh != myMeshes.end(); ++id_mesh ) + id_mesh->second->SetRemovedFromStudy( false ); + for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp ) + (*hyp)->SetRemovedFromStudy( false ); + for ( id_obj = myObjects.begin(); id_obj != myObjects.end(); ++id_obj ) + id_obj->second->SetRemovedFromStudy( false ); + } + else + { + // let hypotheses find referred objects in order to prevent clearing + // not published referred hyps (it's needed for hyps like "LayerDistribution") + list< Handle(_pyMesh) > fatherMeshes; + for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp ) + if ( !hyp->IsNull() ) + (*hyp)->GetReferredMeshesAndGeom( fatherMeshes ); + } + // set myIsPublished = false to all objects depending on + // meshes built on a removed geometry + for ( id_mesh = myMeshes.begin(); id_mesh != myMeshes.end(); ++id_mesh ) + if ( id_mesh->second->IsNotGeomPublished() ) + id_mesh->second->SetRemovedFromStudy( true ); + + // Flush meshes + for ( id_mesh = myMeshes.begin(); id_mesh != myMeshes.end(); ++id_mesh ) if ( ! id_mesh->second.IsNull() ) id_mesh->second->Flush(); - list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); - for ( ; hyp != myHypos.end(); ++hyp ) + // Flush hyps + for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp ) if ( !hyp->IsNull() ) { (*hyp)->Flush(); // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis() @@ -465,15 +888,97 @@ void _pyGen::Flush() (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() ); } - map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.begin(); - for ( ; id_subMesh != mySubMeshes.end(); ++id_subMesh ) - if ( ! id_subMesh->second.IsNull() ) - id_subMesh->second->Flush(); + // Flush other objects + for ( id_obj = myObjects.begin(); id_obj != myObjects.end(); ++id_obj ) + if ( ! id_obj->second.IsNull() ) + id_obj->second->Flush(); myLastCommand->SetOrderNb( ++myNbCommands ); myCommands.push_back( myLastCommand ); } +//================================================================================ +/*! + * \brief Prevent moving a command creating a sub-mesh to the end of the script + * if the sub-mesh is used in theCmdUsingSubmesh as argument + */ +//================================================================================ + +void _pyGen::PlaceSubmeshAfterItsCreation( Handle(_pyCommand) theCmdUsingSubmesh ) const +{ + map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.begin(); + for ( ; id_obj != myObjects.end(); ++id_obj ) + { + if ( !id_obj->second->IsKind( STANDARD_TYPE( _pySubMesh ))) continue; + for ( int iArg = theCmdUsingSubmesh->GetNbArgs(); iArg; --iArg ) + { + const _pyID& arg = theCmdUsingSubmesh->GetArg( iArg ); + if ( arg.IsEmpty() || arg.Value( 1 ) == '"' || arg.Value( 1 ) == '\'' ) + continue; + list< _pyID > idList = theCmdUsingSubmesh->GetStudyEntries( arg ); + list< _pyID >::iterator id = idList.begin(); + for ( ; id != idList.end(); ++id ) + if ( id_obj->first == *id ) + // _pySubMesh::Process() does what we need + Handle(_pySubMesh)::DownCast( id_obj->second )->Process( theCmdUsingSubmesh ); + } + } +} + +//================================================================================ +/*! + * \brief Clean commmands of removed objects depending on myIsPublished flag + */ +//================================================================================ + +void _pyGen::ClearCommands() +{ + map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin(); + for ( ; id_mesh != myMeshes.end(); ++id_mesh ) + id_mesh->second->ClearCommands(); + + list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); + for ( ; hyp != myHypos.end(); ++hyp ) + if ( !hyp->IsNull() ) + (*hyp)->ClearCommands(); + + map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin(); + for ( ; id_obj != myObjects.end(); ++id_obj ) + id_obj->second->ClearCommands(); +} + +//================================================================================ +/*! + * \brief Release mutual handles of objects + */ +//================================================================================ + +void _pyGen::Free() +{ + map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin(); + for ( ; id_mesh != myMeshes.end(); ++id_mesh ) + id_mesh->second->Free(); + myMeshes.clear(); + + map< _pyID, Handle(_pyMeshEditor) >::iterator id_ed = myMeshEditors.begin(); + for ( ; id_ed != myMeshEditors.end(); ++id_ed ) + id_ed->second->Free(); + myMeshEditors.clear(); + + map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin(); + for ( ; id_obj != myObjects.end(); ++id_obj ) + id_obj->second->Free(); + myObjects.clear(); + + list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); + for ( ; hyp != myHypos.end(); ++hyp ) + if ( !hyp->IsNull() ) + (*hyp)->Free(); + myHypos.clear(); + + myFile2ExportedMesh.clear(); +} + //================================================================================ /*! * \brief Add access method to mesh that is an argument @@ -548,7 +1053,7 @@ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMe if ( !hyp->IsNull() && (*hyp)->IsAlgo() && theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) && - (*hyp)->GetGeom() == theGeom && + (*hyp)->GetGeom() == theGeom && (*hyp)->GetMesh() == theMesh ) return *hyp; return 0; @@ -564,12 +1069,9 @@ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMe Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID ) { - map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.begin(); - for ( ; id_subMesh != mySubMeshes.end(); ++id_subMesh ) { - Handle(_pySubMesh) sm = id_subMesh->second; - if ( !id_subMesh->second.IsNull() && theSubMeshID == id_subMesh->second->GetID() ) - return sm; - } + map< _pyID, Handle(_pyObject) >::iterator id_subMesh = myObjects.find(theSubMeshID); + if ( id_subMesh != myObjects.end() ) + return Handle(_pySubMesh)::DownCast( id_subMesh->second ); return Handle(_pySubMesh)(); } @@ -634,8 +1136,8 @@ void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) the //================================================================================ void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd, - Handle(_pyCommand)& theOtherCmd, - const bool theIsAfter ) + Handle(_pyCommand)& theOtherCmd, + const bool theIsAfter ) { list< Handle(_pyCommand) >::iterator pos; pos = find( myCommands.begin(), myCommands.end(), theCmd ); @@ -688,114 +1190,216 @@ _pyID _pyGen::GenerateNewID( const _pyID& theID ) aNewID = theID + _pyID( ":" ) + _pyID( index++ ); } while ( myObjectNames.IsBound( aNewID ) ); - - myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID ) - ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 )) - : _pyID( "A" ) + aNewID ); + + myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID ) + ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 )) + : _pyID( "A" ) + aNewID ); return aNewID; } //================================================================================ /*! - * \brief Find out type of geom group - * \param grpID - The geom group entry - * \retval int - The type - */ -//================================================================================ - -static bool sameGroupType( const _pyID& grpID, - const TCollection_AsciiString& theType) -{ - // define group type as smesh.Mesh.Group() does - int type = -1; - SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); - SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() ); - if ( !aSObj->_is_nil() ) { - GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() ); - if ( !aGeomObj->_is_nil() ) { - switch ( aGeomObj->GetShapeType() ) { - case GEOM::VERTEX: type = SMESH::NODE; break; - case GEOM::EDGE: type = SMESH::EDGE; break; - case GEOM::FACE: type = SMESH::FACE; break; - case GEOM::SOLID: - case GEOM::SHELL: type = SMESH::VOLUME; break; - case GEOM::COMPOUND: { - GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine(); - if ( !aGeomGen->_is_nil() ) { - GEOM::GEOM_IGroupOperations_var aGrpOp = - aGeomGen->GetIGroupOperations( study->StudyId() ); - if ( !aGrpOp->_is_nil() ) { - switch ( aGrpOp->GetType( aGeomObj )) { - case TopAbs_VERTEX: type = SMESH::NODE; break; - case TopAbs_EDGE: type = SMESH::EDGE; break; - case TopAbs_FACE: type = SMESH::FACE; break; - case TopAbs_SOLID: type = SMESH::VOLUME; break; - default:; - } - } - } - } - default:; - } - } + * \brief Stores theObj in myObjects + */ +//================================================================================ + +void _pyGen::AddObject( Handle(_pyObject)& theObj ) +{ + if ( theObj.IsNull() ) return; + + if ( theObj->IsKind( STANDARD_TYPE( _pyMesh ))) + myMeshes.insert( make_pair( theObj->GetID(), Handle(_pyMesh)::DownCast( theObj ))); + + else if ( theObj->IsKind( STANDARD_TYPE( _pyMeshEditor ))) + myMeshEditors.insert( make_pair( theObj->GetID(), Handle(_pyMeshEditor)::DownCast( theObj ))); + + else + myObjects.insert( make_pair( theObj->GetID(), theObj )); +} + +//================================================================================ +/*! + * \brief Re-register an object with other ID to make it Process() commands of + * other object having this ID + */ +//================================================================================ + +void _pyGen::SetProxyObject( const _pyID& theID, Handle(_pyObject)& theObj ) +{ + if ( theObj.IsNull() ) return; + + if ( theObj->IsKind( STANDARD_TYPE( _pyMesh ))) + myMeshes.insert( make_pair( theID, Handle(_pyMesh)::DownCast( theObj ))); + + else if ( theObj->IsKind( STANDARD_TYPE( _pyMeshEditor ))) + myMeshEditors.insert( make_pair( theID, Handle(_pyMeshEditor)::DownCast( theObj ))); + + else + myObjects.insert( make_pair( theID, theObj )); +} + +//================================================================================ +/*! + * \brief Finds a _pyObject by ID + */ +//================================================================================ + +Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID ) const +{ + { + map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.find( theObjID ); + if ( id_obj != myObjects.end() ) + return id_obj->second; } - if ( type < 0 ) { - MESSAGE("Type of the group " << grpID << " not found"); - return false; + { + map< _pyID, Handle(_pyMesh) >::const_iterator id_obj = myMeshes.find( theObjID ); + if ( id_obj != myMeshes.end() ) + return id_obj->second; } - if ( theType.IsIntegerValue() ) - return type == theType.IntegerValue(); + // { + // map< _pyID, Handle(_pyMeshEditor) >::const_iterator id_obj = myMeshEditors.find( theObjID ); + // if ( id_obj != myMeshEditors.end() ) + // return id_obj->second; + // } + return Handle(_pyObject)(); +} + +//================================================================================ +/*! + * \brief Check if a study entry is under GEOM component + */ +//================================================================================ - switch ( type ) { - case SMESH::NODE: return theType.Location( "NODE", 1, theType.Length() ); - case SMESH::EDGE: return theType.Location( "EDGE", 1, theType.Length() ); - case SMESH::FACE: return theType.Location( "FACE", 1, theType.Length() ); - case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() ); - default:; +bool _pyGen::IsGeomObject(const _pyID& theObjID) const +{ + if ( myGeomIDNb ) + { + return ( myGeomIDIndex <= theObjID.Length() && + int( theObjID.Value( myGeomIDIndex )) == myGeomIDNb && + _pyCommand::IsStudyEntry( theObjID )); } return false; } //================================================================================ /*! - * \brief - * \param theCreationCmd - + * \brief Returns true if an object is not present in a study + */ +//================================================================================ + +bool _pyGen::IsNotPublished(const _pyID& theObjID) const +{ + if ( theObjID.IsEmpty() ) return false; + + if ( myObjectNames.IsBound( theObjID )) + return false; // SMESH object is in study + + // either the SMESH object is not in study or it is a GEOM object + if ( IsGeomObject( theObjID )) + { + SALOMEDS::SObject_var so = myStudy->FindObjectID( theObjID.ToCString() ); + if ( so->_is_nil() ) return true; + CORBA::Object_var obj = so->GetObject(); + return CORBA::is_nil( obj ); + } + return true; // SMESH object not in study +} + +//================================================================================ +/*! + * \brief Return reader of hypotheses of plugins + */ +//================================================================================ + +Handle( _pyHypothesisReader ) _pyGen::GetHypothesisReader() const +{ + if (myHypReader.IsNull() ) + ((_pyGen*) this)->myHypReader = new _pyHypothesisReader; + + return myHypReader; +} + + +//================================================================================ +/*! + * \brief Mesh created by SMESH_Gen */ //================================================================================ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd) - : _pyObject(theCreationCmd), myHasEditor(false) + : _pyObject( theCreationCmd ), myGeomNotInStudy( false ) { - // convert my creation command + if ( theCreationCmd->GetMethod() == "CreateMesh" && theGen->IsNotPublished( GetGeom() )) + myGeomNotInStudy = true; + + // convert my creation command --> smeshpy.Mesh(...) Handle(_pyCommand) creationCmd = GetCreationCmd(); - //TCollection_AsciiString str = creationCmd->GetMethod(); -// if(str != "CreateMeshesFromUNV" && -// str != "CreateMeshesFromMED" && -// str != "CreateMeshesFromSTL") - creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); + creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); creationCmd->SetMethod( "Mesh" ); - - theGen->SetAccessorMethod( GetID(), "GetMesh()" ); + theGen->SetAccessorMethod( GetID(), _pyMesh::AccessorMethod() ); } //================================================================================ /*! - * \brief - * \param theCreationCmd - + * \brief Mesh created by SMESH_MeshEditor */ //================================================================================ -_pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id): - _pyObject(theCreationCmd), myHasEditor(false) + +_pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID& meshId): + _pyObject(theCreationCmd,meshId), myGeomNotInStudy(false ) { + if ( theCreationCmd->MethodStartsFrom( "CreateMeshesFrom" )) + { + // this mesh depends on the exported mesh + const TCollection_AsciiString& file = theCreationCmd->GetArg( 1 ); + if ( !file.IsEmpty() ) + { + ExportedMeshData& exportData = theGen->FindExportedMesh( file ); + addFatherMesh( exportData.myMesh ); + if ( !exportData.myLastComputeCmd.IsNull() ) + { + // restore cleared Compute() by which the exported mesh was generated + exportData.myLastComputeCmd->GetString() = exportData.myLastComputeCmdString; + // protect that Compute() cmd from clearing + if ( exportData.myMesh->myLastComputeCmd == exportData.myLastComputeCmd ) + exportData.myMesh->myLastComputeCmd.Nullify(); + } + } + } + else if ( theCreationCmd->MethodStartsFrom( "Concatenate" )) + { + // this mesh depends on concatenated meshes + const TCollection_AsciiString& meshIDs = theCreationCmd->GetArg( 1 ); + list< _pyID > idList = theCreationCmd->GetStudyEntries( meshIDs ); + list< _pyID >::iterator meshID = idList.begin(); + for ( ; meshID != idList.end(); ++meshID ) + addFatherMesh( *meshID ); + } + else if ( theCreationCmd->GetMethod() == "CopyMesh" ) + { + // this mesh depends on a copied IdSource + const _pyID& objID = theCreationCmd->GetArg( 1 ); + addFatherMesh( objID ); + } + else if ( theCreationCmd->GetMethod().Search("MakeMesh") != -1 || + theCreationCmd->GetMethod() == "MakeBoundaryMesh" || + theCreationCmd->GetMethod() == "MakeBoundaryElements" ) + { + // this mesh depends on a source mesh + // (theCreationCmd is already Process()ed by _pyMeshEditor) + const _pyID& meshID = theCreationCmd->GetObject(); + addFatherMesh( meshID ); + } + // convert my creation command Handle(_pyCommand) creationCmd = GetCreationCmd(); - creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); - theGen->SetAccessorMethod( id, "GetMesh()" ); + creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); + theGen->SetAccessorMethod( meshId, _pyMesh::AccessorMethod() ); } //================================================================================ /*! - * \brief Convert a IDL API command of SMESH::Mesh to a method call of python Mesh + * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh * \param theCommand - Engine method called for this mesh */ //================================================================================ @@ -815,15 +1419,69 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) // --> in Mesh.ExportMED( f, auto_groups, version ) // 5. etc - const TCollection_AsciiString method = theCommand->GetMethod(); - // ---------------------------------------------------------------------- - if ( method == "GetSubMesh" ) { - Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() ); - if ( !subMesh.IsNull() ) { - subMesh->SetCreator( this ); - mySubmeshes.push_back( subMesh ); - } - } + const TCollection_AsciiString& method = theCommand->GetMethod(); + // ---------------------------------------------------------------------- + if ( method == "Compute" ) // in snapshot mode, clear the previous Compute() + { + if ( !theGen->IsToKeepAllCommands() ) // !historical + { + list< Handle(_pyHypothesis) >::iterator hyp; + if ( !myLastComputeCmd.IsNull() ) + { + for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp ) + (*hyp)->ComputeDiscarded( myLastComputeCmd ); + + myLastComputeCmd->Clear(); + } + myLastComputeCmd = theCommand; + + for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp ) + (*hyp)->MeshComputed( myLastComputeCmd ); + } + Flush(); + } + // ---------------------------------------------------------------------- + else if ( method == "Clear" ) // in snapshot mode, clear all previous commands + { + if ( !theGen->IsToKeepAllCommands() ) // !historical + { + int untilCmdNb = + myChildMeshes.empty() ? 0 : myChildMeshes.back()->GetCreationCmd()->GetOrderNb(); + // list< Handle(_pyCommand) >::reverse_iterator cmd = myProcessedCmds.rbegin(); + // for ( ; cmd != myProcessedCmds.rend() && (*cmd)->GetOrderNb() > untilCmdNb; ++cmd ) + // (*cmd)->Clear(); + if ( !myLastComputeCmd.IsNull() ) + { + list< Handle(_pyHypothesis) >::iterator hyp; + for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp ) + (*hyp)->ComputeDiscarded( myLastComputeCmd ); + + myLastComputeCmd->Clear(); + } + + list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin(); + for ( ; e != myEditors.end(); ++e ) + { + list< Handle(_pyCommand)>& cmds = (*e)->GetProcessedCmds(); + list< Handle(_pyCommand) >::reverse_iterator cmd = cmds.rbegin(); + for ( ; cmd != cmds.rend() && (*cmd)->GetOrderNb() > untilCmdNb; ++cmd ) + if ( !(*cmd)->IsEmpty() ) + { + if ( (*cmd)->GetStudyEntries( (*cmd)->GetResultValue() ).empty() ) // no object created + (*cmd)->Clear(); + } + } + myLastComputeCmd = theCommand; // to clear Clear() the same way as Compute() + } + } + // ---------------------------------------------------------------------- + else if ( method == "GetSubMesh" ) { // collect submeshes of the mesh + Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() ); + if ( !subMesh.IsNull() ) { + subMesh->SetCreator( this ); + mySubmeshes.push_back( subMesh ); + } + } // ---------------------------------------------------------------------- else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO ) myAddHypCmds.push_back( theCommand ); @@ -837,30 +1495,46 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) } } // ---------------------------------------------------------------------- - else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp) - _pyID grp = theCommand->GetArg( 3 ); - if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp) - theCommand->SetMethod( "Group" ); - theCommand->RemoveArgs(); - theCommand->SetArg( 1, grp ); - } - else { - _pyID type = theCommand->GetArg( 1 ); - _pyID name = theCommand->GetArg( 2 ); - theCommand->SetMethod( "GroupOnGeom" ); - theCommand->RemoveArgs(); - theCommand->SetArg( 1, grp ); - theCommand->SetArg( 2, name ); - theCommand->SetArg( 3, type ); - } - } - // ---------------------------------------------------------------------- - else if ( method == "ExportToMED" ) { // ExportToMED() --> ExportMED() - theCommand->SetMethod( "ExportMED" ); + else if ( method == "CreateGroup" || + method == "CreateGroupFromGEOM" || + method == "CreateGroupFromFilter" ) + { + Handle(_pyGroup) group = new _pyGroup( theCommand ); + myGroups.push_back( group ); + theGen->AddObject( group ); } // ---------------------------------------------------------------------- - else if ( method == "CreateGroup" ) { // CreateGroup() --> CreateEmptyGroup() - theCommand->SetMethod( "CreateEmptyGroup" ); + else if ( theCommand->MethodStartsFrom( "Export" )) + { + if ( method == "ExportToMED" || // ExportToMED() --> ExportMED() + method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED() + theCommand->SetMethod( "ExportMED" ); + } + else if ( method == "ExportCGNS" ) + { // ExportCGNS(part, ...) -> ExportCGNS(..., part) + _pyID partID = theCommand->GetArg( 1 ); + int nbArgs = theCommand->GetNbArgs(); + for ( int i = 2; i <= nbArgs; ++i ) + theCommand->SetArg( i-1, theCommand->GetArg( i )); + theCommand->SetArg( nbArgs, partID ); + } + else if ( theCommand->MethodStartsFrom( "ExportPartTo" )) + { // ExportPartTo*(part, ...) -> Export*(..., part) + // + // remove "PartTo" from the method + TCollection_AsciiString newMethod = method; + newMethod.Remove( 7, 6 ); + theCommand->SetMethod( newMethod ); + // make the 1st arg be the last one + _pyID partID = theCommand->GetArg( 1 ); + int nbArgs = theCommand->GetNbArgs(); + for ( int i = 2; i <= nbArgs; ++i ) + theCommand->SetArg( i-1, theCommand->GetArg( i )); + theCommand->SetArg( nbArgs, partID ); + } + // remember file name + theGen->AddExportedMesh( theCommand->GetArg( 1 ), + ExportedMeshData( this, myLastComputeCmd )); } // ---------------------------------------------------------------------- else if ( method == "RemoveHypothesis" ) // (geom, hyp) @@ -895,6 +1569,40 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) // remove hyp from myHypos myHypos.remove( hyp ); } + // check for SubMesh order commands + else if ( method == "GetMeshOrder" || method == "SetMeshOrder" ) + { + // make commands GetSubMesh() returning sub-meshes be before using sub-meshes + // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh() + // commands are moved at the end of the script + TCollection_AsciiString subIDs = + ( method == "SetMeshOrder" ) ? theCommand->GetArg(1) : theCommand->GetResultValue(); + list< _pyID > idList = theCommand->GetStudyEntries( subIDs ); + list< _pyID >::iterator subID = idList.begin(); + for ( ; subID != idList.end(); ++subID ) + { + Handle(_pySubMesh) subMesh = theGen->FindSubMesh( *subID ); + if ( !subMesh.IsNull() ) + subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand + } + } + // update list of groups + else if ( method == "GetGroups" ) + { + TCollection_AsciiString grIDs = theCommand->GetResultValue(); + list< _pyID > idList = theCommand->GetStudyEntries( grIDs ); + list< _pyID >::iterator grID = idList.begin(); + for ( ; grID != idList.end(); ++grID ) + { + Handle(_pyObject) obj = theGen->FindObject( *grID ); + if ( obj.IsNull() ) + { + Handle(_pyGroup) group = new _pyGroup( theCommand, *grID ); + theGen->AddObject( group ); + myGroups.push_back( group ); + } + } + } // add accessor method if necessary else { @@ -912,12 +1620,12 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) { - // names of SMESH_Mesh methods fully equal to methods of class Mesh, so - // no conversion is needed for them at all: + // names of SMESH_Mesh methods fully equal to methods of python class Mesh, + // so no conversion is needed for them at all: static TStringSet sameMethods; if ( sameMethods.empty() ) { const char * names[] = - { "ExportDAT","ExportUNV","ExportSTL", "RemoveGroup","RemoveGroupWithContents", + { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents", "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog", "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements", "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles", @@ -929,7 +1637,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes", "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces", "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor", - "Clear", "ConvertToStandalone" + "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder" ,"" }; // <- mark of end sameMethods.Insert( names ); } @@ -945,6 +1653,23 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) void _pyMesh::Flush() { + { + // get the meshes this mesh depends on via hypotheses + list< Handle(_pyMesh) > fatherMeshes; + list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); + for ( ; hyp != myHypos.end(); ++hyp ) + if ( ! (*hyp)->GetReferredMeshesAndGeom( fatherMeshes )) + myGeomNotInStudy = true; + + list< Handle(_pyMesh) >::iterator m = fatherMeshes.begin(); + for ( ; m != fatherMeshes.end(); ++m ) + addFatherMesh( *m ); + // if ( removedGeom ) + // SetRemovedFromStudy(); // as reffered geometry not in study + } + if ( myGeomNotInStudy ) + return; + list < Handle(_pyCommand) >::iterator cmd; // try to convert algo addition like this: @@ -961,30 +1686,34 @@ void _pyMesh::Flush() // check and create new algorithm instance if it is already wrapped if ( algo->IsWrapped() ) { _pyID localAlgoID = theGen->GenerateNewID( algoID ); - TCollection_AsciiString aNewCmdStr = localAlgoID + - TCollection_AsciiString( " = " ) + theGen->GetID() + - TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() + - TCollection_AsciiString( "\" )" ); - + TCollection_AsciiString aNewCmdStr = addCmd->GetIndentation() + localAlgoID + + TCollection_AsciiString( " = " ) + theGen->GetID() + + TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() + + TCollection_AsciiString( "\" )" ); + Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr ); Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID )); if ( !newAlgo.IsNull() ) { - newAlgo->Assign( algo, this->GetID() ); - newAlgo->SetCreationCmd( newCmd ); - algo = newAlgo; - // set algorithm creation - theGen->SetCommandBefore( newCmd, addCmd ); + newAlgo->Assign( algo, this->GetID() ); + newAlgo->SetCreationCmd( newCmd ); + algo = newAlgo; + // set algorithm creation + theGen->SetCommandBefore( newCmd, addCmd ); + myHypos.push_back( newAlgo ); + if ( !myLastComputeCmd.IsNull() && + newCmd->GetOrderNb() == myLastComputeCmd->GetOrderNb() + 1) + newAlgo->MeshComputed( myLastComputeCmd ); } else - newCmd->Clear(); + newCmd->Clear(); } _pyID geom = addCmd->GetArg( 1 ); bool isLocalAlgo = ( geom != GetGeom() ); - + // try to convert if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK { - // wrapped algo is created atfer mesh creation + // wrapped algo is created after mesh creation GetCreationCmd()->AddDependantCmd( addCmd ); if ( isLocalAlgo ) { @@ -992,14 +1721,14 @@ void _pyMesh::Flush() addCmd->SetArg( addCmd->GetNbArgs() + 1, TCollection_AsciiString( "geom=" ) + geom ); // sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh() - list < Handle(_pySubMesh) >::iterator smIt; + list < Handle(_pySubMesh) >::iterator smIt; for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) { - Handle(_pySubMesh) subMesh = *smIt; + Handle(_pySubMesh) subMesh = *smIt; Handle(_pyCommand) subCmd = subMesh->GetCreationCmd(); if ( geom == subCmd->GetArg( 1 )) { subCmd->SetObject( algo->GetID() ); subCmd->RemoveArgs(); - subMesh->SetCreator( algo ); + subMesh->SetCreator( algo ); } } } @@ -1034,21 +1763,126 @@ void _pyMesh::Flush() } } - // sm = mesh.GetSubMesh(geom, name) --> sm = mesh.GetMesh().GetSubMesh(geom, name) -// for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) { -// Handle(_pyCommand) subCmd = *cmd; -// if ( subCmd->GetNbArgs() > 0 ) -// AddMeshAccess( subCmd ); -// } myAddHypCmds.clear(); mySubmeshes.clear(); // flush hypotheses list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin(); - for ( ; hyp != myHypos.end(); ++hyp ) + for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp ) (*hyp)->Flush(); } +//================================================================================ +/*! + * \brief Sets myIsPublished of me and of all objects depending on me. + */ +//================================================================================ + +void _pyMesh::SetRemovedFromStudy(const bool isRemoved) +{ + _pyObject::SetRemovedFromStudy(isRemoved); + + list< Handle(_pySubMesh) >::iterator sm = mySubmeshes.begin(); + for ( ; sm != mySubmeshes.end(); ++sm ) + (*sm)->SetRemovedFromStudy(isRemoved); + + list< Handle(_pyGroup) >::iterator gr = myGroups.begin(); + for ( ; gr != myGroups.end(); ++gr ) + (*gr)->SetRemovedFromStudy(isRemoved); + + list< Handle(_pyMesh) >::iterator m = myChildMeshes.begin(); + for ( ; m != myChildMeshes.end(); ++m ) + (*m)->SetRemovedFromStudy(isRemoved); + + list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin(); + for ( ; e != myEditors.end(); ++e ) + (*e)->SetRemovedFromStudy(isRemoved); +} + +//================================================================================ +/*! + * \brief Return true if none of myChildMeshes is in study + */ +//================================================================================ + +bool _pyMesh::CanClear() +{ + if ( IsInStudy() ) + return false; + + list< Handle(_pyMesh) >::iterator m = myChildMeshes.begin(); + for ( ; m != myChildMeshes.end(); ++m ) + if ( !(*m)->CanClear() ) + return false; + + return true; +} + +//================================================================================ +/*! + * \brief Clear my commands and commands of mesh editor + */ +//================================================================================ + +void _pyMesh::ClearCommands() +{ + if ( !CanClear() ) + { + if ( !IsInStudy() ) + { + // mark all sub-objects as not removed, except child meshes + list< Handle(_pyMesh) > children; + children.swap( myChildMeshes ); + SetRemovedFromStudy( false ); + children.swap( myChildMeshes ); + } + return; + } + _pyObject::ClearCommands(); + + list< Handle(_pySubMesh) >::iterator sm = mySubmeshes.begin(); + for ( ; sm != mySubmeshes.end(); ++sm ) + (*sm)->ClearCommands(); + + list< Handle(_pyGroup) >::iterator gr = myGroups.begin(); + for ( ; gr != myGroups.end(); ++gr ) + (*gr)->ClearCommands(); + + list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin(); + for ( ; e != myEditors.end(); ++e ) + (*e)->ClearCommands(); +} + +//================================================================================ +/*! + * \brief Add a father mesh by ID + */ +//================================================================================ + +void _pyMesh::addFatherMesh( const _pyID& meshID ) +{ + if ( !meshID.IsEmpty() ) + addFatherMesh( Handle(_pyMesh)::DownCast( theGen->FindObject( meshID ))); +} + +//================================================================================ +/*! + * \brief Add a father mesh + */ +//================================================================================ + +void _pyMesh::addFatherMesh( const Handle(_pyMesh)& mesh ) +{ + if ( !mesh.IsNull() ) + { + //myFatherMeshes.push_back( mesh ); + mesh->myChildMeshes.push_back( this ); + + // protect last Compute() from clearing by the next Compute() + mesh->myLastComputeCmd.Nullify(); + } +} + //================================================================================ /*! * \brief MeshEditor convert its commands to ones of mesh @@ -1061,6 +1895,10 @@ _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd): myMesh = theCreationCmd->GetObject(); myCreationCmdStr = theCreationCmd->GetString(); theCreationCmd->Clear(); + + Handle(_pyMesh) mesh = ObjectToMesh( theGen->FindObject( myMesh )); + if ( !mesh.IsNull() ) + mesh->AddEditor( this ); } //================================================================================ @@ -1071,34 +1909,36 @@ _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd): void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) { - // names of SMESH_MeshEditor methods fully equal to methods of class Mesh, so + // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so // commands calling this methods are converted to calls of methods of Mesh static TStringSet sameMethods; if ( sameMethods.empty() ) { const char * names[] = { - "RemoveElements","RemoveNodes","AddNode","AddEdge","AddFace","AddPolygonalFace", + "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall", "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint", "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject", "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject", "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements", "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D", "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D", - "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D", + "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX", + "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D", "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject", - "FindCoincidentNodes","FindCoincidentNodesOnPart","MergeNodes","FindEqualElements", + "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements", "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders", "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes", "GetLastCreatedElems", "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh", - "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh" + "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh", + "MakeBoundaryElements", "SplitVolumesIntoTetra" ,"" }; // <- mark of the end sameMethods.Insert( names ); } // names of SMESH_MeshEditor methods which differ from methods of class Mesh - // only last two arguments + // only by last two arguments static TStringSet diffLastTwoArgsMethods; - if (diffLastTwoArgsMethods.empty() ){ + if (diffLastTwoArgsMethods.empty() ) { const char * names[] = { "MirrorMakeGroups","MirrorObjectMakeGroups", "TranslateMakeGroups","TranslateObjectMakeGroups", @@ -1107,54 +1947,162 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) diffLastTwoArgsMethods.Insert( names ); } - if ( sameMethods.Contains( theCommand->GetMethod() )) { - theCommand->SetObject( myMesh ); - - // meshes made by *MakeMesh() methods are not wrapped by _pyMesh, - // so let _pyMesh care of it (TMP?) -// if ( theCommand->GetMethod().Search("MakeMesh") != -1 ) -// _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod() - } - else { - - //Replace SMESH_MeshEditor "MakeGroups" functions on the Mesh + const TCollection_AsciiString & method = theCommand->GetMethod(); + bool isPyMeshMethod = sameMethods.Contains( method ); + if ( !isPyMeshMethod ) + { + //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh //functions with the flag "theMakeGroups = True" like: //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True) - int pos = theCommand->GetMethod().Search("MakeGroups"); - if( pos != -1) { + int pos = method.Search("MakeGroups"); + if( pos != -1) + { + isPyMeshMethod = true; + bool is0DmethId = ( method == "ExtrusionSweepMakeGroups0D" ); + bool is0DmethObj = ( method == "ExtrusionSweepObject0DMakeGroups"); + // 1. Remove "MakeGroups" from the Command TCollection_AsciiString aMethod = theCommand->GetMethod(); int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1; + + if(is0DmethObj) + pos = pos-2; //Remove "0D" from the Command too aMethod.Trunc(pos-1); theCommand->SetMethod(aMethod); - // 2. Set Mesh object instead of SMESH_MeshEditor - theCommand->SetObject( myMesh ); - - // 3. And add last "True" argument + // 2. And add last "True" argument(s) while(nbArgsToAdd--) - theCommand->SetArg(theCommand->GetNbArgs()+1,"True "); + theCommand->SetArg(theCommand->GetNbArgs()+1,"True"); + if( is0DmethId || is0DmethObj ) + theCommand->SetArg(theCommand->GetNbArgs()+1,"True"); } - else { - // editor creation command is needed only if any editor function is called - theGen->AddMeshAccessorMethod( theCommand ); // for *Object() - if ( !myCreationCmdStr.IsEmpty() ) { - GetCreationCmd()->GetString() = myCreationCmdStr; - myCreationCmdStr.Clear(); - } + } + + // ExtrusionSweep0D() -> ExtrusionSweep() + // ExtrusionSweepObject0D() -> ExtrusionSweepObject() + if ( !isPyMeshMethod && ( method == "ExtrusionSweep0D" || + method == "ExtrusionSweepObject0D" )) + { + isPyMeshMethod = true; + theCommand->SetMethod( method.SubString( 1, method.Length()-2)); + theCommand->SetArg(theCommand->GetNbArgs()+1,"False"); //sets flag "MakeGroups = False" + theCommand->SetArg(theCommand->GetNbArgs()+1,"True"); //sets flag "IsNode = True" + } + // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()" + if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX") + { + isPyMeshMethod = true; + theCommand->SetMethod("ExtrusionAlongPathX"); + } + + // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()" + if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut") + { + isPyMeshMethod = true; + theCommand->SetMethod("FindCoincidentNodesOnPart"); + } + // DoubleNode...New(...) -> DoubleNode...(...,True) + if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew" || + method == "DoubleNodeElemGroupsNew" || + method == "DoubleNodeGroupNew" || + method == "DoubleNodeGroupsNew" || + method == "DoubleNodeElemGroup2New" || + method == "DoubleNodeElemGroups2New")) + { + isPyMeshMethod = true; + const int excessLen = 3 + int( method.Value( method.Length()-3 ) == '2' ); + theCommand->SetMethod( method.SubString( 1, method.Length()-excessLen)); + if ( excessLen == 3 ) + { + theCommand->SetArg(theCommand->GetNbArgs()+1,"True"); + } + else if ( theCommand->GetArg(4) == "0" || + theCommand->GetArg(5) == "0" ) + { + // [ nothing, Group ] = DoubleNodeGroup2New(,,,False, True) -> + // Group = DoubleNodeGroup2New(,,,False, True) + _pyID groupID = theCommand->GetResultValue( 1 + int( theCommand->GetArg(4) == "0")); + theCommand->SetResultValue( groupID ); + } + } + // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj) + // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj) + if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" || + method == "ConvertFromQuadraticObject" )) + { + isPyMeshMethod = true; + theCommand->SetMethod( method.SubString( 1, method.Length()-6)); + } + // FindAmongElementsByPoint(meshPart, x, y, z, elementType) -> + // FindElementsByPoint(x, y, z, elementType, meshPart) + if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" ) + { + isPyMeshMethod = true; + theCommand->SetMethod( "FindElementsByPoint" ); + // make the 1st arg be the last one + _pyID partID = theCommand->GetArg( 1 ); + int nbArgs = theCommand->GetNbArgs(); + for ( int i = 2; i <= nbArgs; ++i ) + theCommand->SetArg( i-1, theCommand->GetArg( i )); + theCommand->SetArg( nbArgs, partID ); + } + // Reorient2D( mesh, dir, face, point ) -> Reorient2D( mesh, dir, faceORpoint ) + if ( !isPyMeshMethod && method == "Reorient2D" ) + { + isPyMeshMethod = true; + _AString mesh = theCommand->GetArg( 1 ); + _AString dir = theCommand->GetArg( 2 ); + _AString face = theCommand->GetArg( 3 ); + _AString point = theCommand->GetArg( 4 ); + theCommand->RemoveArgs(); + theCommand->SetArg( 1, mesh ); + theCommand->SetArg( 2, dir ); + if ( face.Value(1) == '-' || face.Value(1) == '0' ) // invalid: face <= 0 + theCommand->SetArg( 3, point ); + else + theCommand->SetArg( 3, face ); + } + + // meshes made by *MakeMesh() methods are not wrapped by _pyMesh, + // so let _pyMesh care of it (TMP?) + // if ( theCommand->GetMethod().Search("MakeMesh") != -1 ) + // _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod() + if ( isPyMeshMethod ) + { + theCommand->SetObject( myMesh ); + } + else + { + // editor creation command is needed only if any editor function is called + theGen->AddMeshAccessorMethod( theCommand ); // for *Object() + if ( !myCreationCmdStr.IsEmpty() ) { + GetCreationCmd()->GetString() = myCreationCmdStr; + myCreationCmdStr.Clear(); } } } +//================================================================================ +/*! + * \brief Return true if my mesh can be removed + */ +//================================================================================ + +bool _pyMeshEditor::CanClear() +{ + Handle(_pyMesh) mesh = ObjectToMesh( theGen->FindObject( myMesh )); + return mesh.IsNull() ? true : mesh->CanClear(); +} + //================================================================================ /*! * \brief _pyHypothesis constructor - * \param theCreationCmd - + * \param theCreationCmd - */ //================================================================================ _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd): - _pyObject( theCreationCmd ) + _pyObject( theCreationCmd ), myCurCrMethod(0) { myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false; } @@ -1185,178 +2133,66 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th algo = new _pyAlgorithm( theCreationCmd ); hyp = new _pyHypothesis( theCreationCmd ); - // 1D Regular_1D ---------- - if ( hypType == "Regular_1D" ) { - // 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" ) { - // 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()" - hyp->AddArgMethod( "SetLength" ); - } - else if ( hypType == "MaxLength" ) { - // set algo's method creating hyp, and algo type - hyp->SetConvMethodAndType( "MaxSize", "Regular_1D"); - // set method whose 1 arg will become the 1-st arg of hyp creation command - // i.e. convertion result will be "maxsize = regular1d.MaxSize()" - hyp->AddArgMethod( "SetLength" ); - } - else if ( hypType == "NumberOfSegments" ) { + if ( hypType == "NumberOfSegments" ) { hyp = new _pyNumberOfSegmentsHyp( theCreationCmd ); 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->SetConvMethodAndType( "Arithmetic1D", "Regular_1D"); - } - else if ( hypType == "StartEndLength" ) { - hyp = new _pyComplexParamHypo( theCreationCmd ); - hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D"); - } - else if ( hypType == "Deflection1D" ) { - hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D"); - hyp->AddArgMethod( "SetDeflection" ); - } - else if ( hypType == "Propagation" ) { - hyp->SetConvMethodAndType( "Propagation", "Regular_1D"); - } - else if ( hypType == "QuadraticMesh" ) { - hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D"); - } - else if ( hypType == "AutomaticLength" ) { - hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D"); - hyp->AddArgMethod( "SetFineness"); + hyp->AddArgMethod( "SetReversedEdges" ); + // same for ""CompositeSegment_1D: + hyp->SetConvMethodAndType( "NumberOfSegments", "CompositeSegment_1D"); + hyp->AddArgMethod( "SetNumberOfSegments" ); + hyp->AddArgMethod( "SetScaleFactor" ); + hyp->AddArgMethod( "SetReversedEdges" ); } else if ( hypType == "SegmentLengthAroundVertex" ) { hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd ); hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" ); hyp->AddArgMethod( "SetLength" ); + // same for ""CompositeSegment_1D: + hyp->SetConvMethodAndType( "LengthNearVertex", "CompositeSegment_1D"); + hyp->AddArgMethod( "SetLength" ); } - // 1D Python_1D ---------- - else if ( hypType == "Python_1D" ) { - algo->SetConvMethodAndType( "Segment", hypType.ToCString()); - algo->myArgs.Append( "algo=smesh.PYTHON"); - } - else if ( hypType == "PythonSplit1D" ) { - hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D"); - hyp->AddArgMethod( "SetNumberOfSegments"); - hyp->AddArgMethod( "SetPythonLog10RatioFunction"); - } - // MEFISTO_2D ---------- - else if ( hypType == "MEFISTO_2D" ) { // MEFISTO_2D - algo->SetConvMethodAndType( "Triangle", hypType.ToCString()); - } - else if ( hypType == "MaxElementArea" ) { - hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D"); - hyp->SetConvMethodAndType( "MaxElementArea", "NETGEN_2D_ONLY"); - hyp->AddArgMethod( "SetMaxElementArea"); - } - else if ( hypType == "LengthFromEdges" ) { - hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D"); - hyp->SetConvMethodAndType( "LengthFromEdges", "NETGEN_2D_ONLY"); - } - // Quadrangle_2D ---------- - else if ( hypType == "Quadrangle_2D" ) { - algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString()); - } - else if ( hypType == "QuadranglePreference" ) { - hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D"); - hyp->SetConvMethodAndType( "QuadranglePreference", "NETGEN_2D_ONLY"); - } - else if ( hypType == "TrianglePreference" ) { - hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D"); - } - // NETGEN ---------- -// else if ( hypType == "NETGEN_2D") { // 1D-2D -// algo->SetConvMethodAndType( "Triangle" , hypType.ToCString()); -// algo->myArgs.Append( "algo=smesh.NETGEN" ); -// } - else if ( hypType == "NETGEN_2D_ONLY") { // 2D - algo->SetConvMethodAndType( "Triangle" , hypType.ToCString()); - algo->myArgs.Append( "algo=smesh.NETGEN_2D" ); - } - else if ( hypType == "NETGEN_3D") { // 3D - algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString()); - algo->myArgs.Append( "algo=smesh.NETGEN" ); - } - else if ( hypType == "MaxElementVolume") { - hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D"); - hyp->AddArgMethod( "SetMaxElementVolume" ); - } - // GHS3D_3D ---------- - else if ( hypType == "GHS3D_3D" ) { - algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString()); - algo->myArgs.Append( "algo=smesh.GHS3D" ); - } - // Hexa_3D --------- - else if ( hypType == "Hexa_3D" ) { - algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString()); - } - // Repetitive Projection_1D --------- - else if ( hypType == "Projection_1D" ) { - algo->SetConvMethodAndType( "Projection1D", hypType.ToCString()); - } - else if ( hypType == "ProjectionSource1D" ) { - 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 ); - } - // Projection_2D --------- - else if ( hypType == "Projection_2D" ) { - algo->SetConvMethodAndType( "Projection2D", hypType.ToCString()); - } - else if ( hypType == "ProjectionSource2D" ) { - hyp->SetConvMethodAndType( "SourceFace", "Projection_2D"); - hyp->AddArgMethod( "SetSourceFace"); - hyp->AddArgMethod( "SetSourceMesh"); - hyp->AddArgMethod( "SetVertexAssociation", 4 ); - } - // Projection_3D --------- - else if ( hypType == "Projection_3D" ) { - algo->SetConvMethodAndType( "Projection3D", hypType.ToCString()); - } - else if ( hypType == "ProjectionSource3D" ) { - hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D"); - hyp->AddArgMethod( "SetSource3DShape"); - hyp->AddArgMethod( "SetSourceMesh"); - hyp->AddArgMethod( "SetVertexAssociation", 4 ); - } - // Prism_3D --------- - else if ( hypType == "Prism_3D" ) { - algo->SetConvMethodAndType( "Prism", hypType.ToCString()); - } - // RadialPrism_3D --------- - else if ( hypType == "RadialPrism_3D" ) { - algo->SetConvMethodAndType( "Prism", hypType.ToCString()); - } - else if ( hypType == "NumberOfLayers" ) { - hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D"); - hyp->AddArgMethod( "SetNumberOfLayers" ); + else if ( hypType == "LayerDistribution2D" ) { + hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get2DHypothesis" ); + hyp->SetConvMethodAndType( "LayerDistribution", "RadialQuadrangle_1D2D"); } else if ( hypType == "LayerDistribution" ) { - hyp = new _pyLayerDistributionHypo( theCreationCmd ); + hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" ); hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D"); } + else if ( hypType == "CartesianParameters3D" ) { + hyp = new _pyComplexParamHypo( theCreationCmd ); + hyp->SetConvMethodAndType( "SetGrid", "Cartesian_3D"); + for ( int iArg = 0; iArg < 4; ++iArg ) + hyp->setCreationArg( iArg+1, "[]"); + } + else + { + hyp = theGen->GetHypothesisReader()->GetHypothesis( hypType, theCreationCmd ); + } + + return algo->IsValid() ? algo : hyp; +} - if ( algo->IsValid() ) { - return algo; +//================================================================================ +/*! + * \brief Returns true if addition of this hypothesis to a given mesh can be + * wrapped into hypothesis creation + */ +//================================================================================ + +bool _pyHypothesis::IsWrappable(const _pyID& theMesh) const +{ + if ( !myIsWrapped && myMesh == theMesh && IsInStudy() ) + { + Handle(_pyObject) pyMesh = theGen->FindObject( myMesh ); + if ( !pyMesh.IsNull() && pyMesh->IsInStudy() ) + return true; } - return hyp; + return false; } //================================================================================ @@ -1394,20 +2230,20 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, theCmd->SetResultValue( GetID() ); theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID()); theCmd->SetMethod( IsAlgo() ? GetAlgoCreationMethod() : GetCreationMethod( algo->GetAlgoType() )); - // set args + // set args (geom will be set by _pyMesh calling this method) theCmd->RemoveArgs(); - for ( int i = 1; i <= myArgs.Length(); ++i ) { - if ( !myArgs( i ).IsEmpty() ) - theCmd->SetArg( i, myArgs( i )); + for ( size_t i = 0; i < myCurCrMethod->myArgs.size(); ++i ) { + if ( !myCurCrMethod->myArgs[ i ].IsEmpty() ) + theCmd->SetArg( i+1, myCurCrMethod->myArgs[ i ]); else - theCmd->SetArg( i, "[]"); + theCmd->SetArg( i+1, "[]"); } // set a new creation command GetCreationCmd()->Clear(); // replace creation command by wrapped instance // please note, that hypothesis attaches to algo creation command (see upper) SetCreationCmd( theCmd ); - + // clear commands setting arg values list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin(); @@ -1416,8 +2252,8 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, // set unknown arg commands after hypo creation Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd(); - list::iterator cmd = myUnknownCommands.begin(); - for ( ; cmd != myUnknownCommands.end(); ++cmd ) { + list::iterator cmd = myUnusedCommands.begin(); + for ( ; cmd != myUnusedCommands.end(); ++cmd ) { afterCmd->AddDependantCmd( *cmd ); } @@ -1434,20 +2270,27 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd, void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand) { ASSERT( !myIsAlgo ); + if ( !theGen->IsToKeepAllCommands() ) + rememberCmdOfParameter( theCommand ); // set args - int nbArgs = 0; - for ( int i = 1; i <= myArgMethods.Length(); ++i ) { - if ( myArgMethods( i ) == theCommand->GetMethod() ) { - while ( myArgs.Length() < nbArgs + myNbArgsByMethod( i )) - myArgs.Append( "[]" ); - for ( int iArg = 1; iArg <= myNbArgsByMethod( i ); ++iArg ) - myArgs( nbArgs + iArg ) = theCommand->GetArg( iArg ); // arg value - myArgCommands.push_back( theCommand ); - return; + bool usedCommand = false; + TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin(); + for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth ) + { + CreationMethod& crMethod = type2meth->second; + for ( size_t i = 0; i < crMethod.myArgMethods.size(); ++i ) { + if ( crMethod.myArgMethods[ i ] == theCommand->GetMethod() ) { + if ( !usedCommand ) + myArgCommands.push_back( theCommand ); + usedCommand = true; + while ( crMethod.myArgs.size() < i+1 ) + crMethod.myArgs.push_back( "[]" ); + crMethod.myArgs[ i ] = theCommand->GetArg( crMethod.myArgNb[i] ); + } } - nbArgs += myNbArgsByMethod( i ); } - myUnknownCommands.push_back( theCommand ); + if ( !usedCommand ) + myUnusedCommands.push_back( theCommand ); } //================================================================================ @@ -1458,9 +2301,8 @@ void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand) void _pyHypothesis::Flush() { - if ( IsWrapped() ) { - } - else { + if ( !IsAlgo() ) + { list < Handle(_pyCommand) >::iterator cmd = myArgCommands.begin(); for ( ; cmd != myArgCommands.end(); ++cmd ) { // Add access to a wrapped mesh @@ -1468,8 +2310,8 @@ void _pyHypothesis::Flush() // Add access to a wrapped algorithm theGen->AddAlgoAccessorMethod( *cmd ); } - cmd = myUnknownCommands.begin(); - for ( ; cmd != myUnknownCommands.end(); ++cmd ) { + cmd = myUnusedCommands.begin(); + for ( ; cmd != myUnusedCommands.end(); ++cmd ) { // Add access to a wrapped mesh theGen->AddMeshAccessorMethod( *cmd ); // Add access to a wrapped algorithm @@ -1478,7 +2320,7 @@ void _pyHypothesis::Flush() } // forget previous hypothesis modifications myArgCommands.clear(); - myUnknownCommands.clear(); + myUnusedCommands.clear(); } //================================================================================ @@ -1493,8 +2335,8 @@ void _pyHypothesis::ClearAllCommands() list::iterator cmd = myArgCommands.begin(); for ( ; cmd != myArgCommands.end(); ++cmd ) ( *cmd )->Clear(); - cmd = myUnknownCommands.begin(); - for ( ; cmd != myUnknownCommands.end(); ++cmd ) + cmd = myUnusedCommands.begin(); + for ( ; cmd != myUnusedCommands.end(); ++cmd ) ( *cmd )->Clear(); } @@ -1506,144 +2348,426 @@ void _pyHypothesis::ClearAllCommands() //================================================================================ void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther, - const _pyID& theMesh ) + const _pyID& theMesh ) { - myIsWrapped = false; - myMesh = theMesh; - // myCreationCmd = theOther->myCreationCmd; - myIsAlgo = theOther->myIsAlgo; - myGeom = theOther->myGeom; - myType2CreationMethod = theOther->myType2CreationMethod; - myArgs = theOther->myArgs; - myArgMethods = theOther->myArgMethods; - myNbArgsByMethod = theOther->myNbArgsByMethod; - myArgCommands = theOther->myArgCommands; - myUnknownCommands = theOther->myUnknownCommands; + myIsAlgo = theOther->myIsAlgo; + myIsWrapped = false; + myGeom = theOther->myGeom; + myMesh = theMesh; + myAlgoType2CreationMethod = theOther->myAlgoType2CreationMethod; + //myArgCommands = theOther->myArgCommands; + //myUnusedCommands = theOther->myUnusedCommands; + // init myCurCrMethod + GetCreationMethod( theOther->GetAlgoType() ); } //================================================================================ /*! - * \brief Remember hypothesis parameter values - * \param theCommand - The called hypothesis method + * \brief Analyze my erasability depending on myReferredObjs */ //================================================================================ -void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand) +bool _pyHypothesis::CanClear() { - // ex: hyp.SetLength(start, 1) - // hyp.SetLength(end, 0) - ASSERT(( theCommand->GetMethod() == "SetLength" )); - ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() )); - int i = 2 - theCommand->GetArg( 2 ).IntegerValue(); - while ( myArgs.Length() < i ) - myArgs.Append( "[]" ); - myArgs( i ) = theCommand->GetArg( 1 ); // arg value - myArgCommands.push_back( theCommand ); + if ( IsInStudy() ) + { + list< Handle(_pyObject) >::iterator obj = myReferredObjs.begin(); + for ( ; obj != myReferredObjs.end(); ++obj ) + if ( (*obj)->CanClear() ) + return true; + return false; + } + return true; } //================================================================================ /*! - * \brief Convert methods of 1D hypotheses to my own methods - * \param theCommand - The called hypothesis method + * \brief Clear my commands depending on usage by meshes */ //================================================================================ -void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand) +void _pyHypothesis::ClearCommands() { - if ( theCommand->GetMethod() != "SetLayerDistribution" ) - return; + // if ( !theGen->IsToKeepAllCommands() ) + // { + // bool isUsed = false; + // int lastComputeOrder = 0; + // list::iterator cmd = myComputeCmds.begin(); + // for ( ; cmd != myComputeCmds.end(); ++cmd ) + // if ( ! (*cmd)->IsEmpty() ) + // { + // isUsed = true; + // if ( (*cmd)->GetOrderNb() > lastComputeOrder ) + // lastComputeOrder = (*cmd)->GetOrderNb(); + // } + // if ( !isUsed ) + // { + // SetRemovedFromStudy( true ); + // } + // else + // { + // // clear my commands invoked after lastComputeOrder + // // map >::iterator m2c; + // // for ( m2c = myMeth2Commands.begin(); m2c != myMeth2Commands.end(); ++m2c ) + // // { + // // list< Handle(_pyCommand)> & cmds = m2c->second; + // // if ( !cmds.empty() && cmds.back()->GetOrderNb() > lastComputeOrder ) + // // cmds.back()->Clear(); + // // } + // } + // } + _pyObject::ClearCommands(); +} - _pyID newName; // name for 1D hyp = "HypType" + "_Distribution" +//================================================================================ +/*! + * \brief Find arguments that are objects like mesh, group, geometry + * \param meshes - referred meshes (directly or indirrectly) + * \retval bool - false if a referred geometry is not in the study + */ +//================================================================================ - const _pyID& hyp1dID = theCommand->GetArg( 1 ); - Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID ); - if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration - hyp1d = my1dHyp; - else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() ) { - // 1D hypo is already set, so distribution changes and the old - // 1D hypo is thrown away - my1dHyp->ClearAllCommands(); - } - my1dHyp = hyp1d; - if ( my1dHyp.IsNull() ) - return; // something wrong :( +bool _pyHypothesis::GetReferredMeshesAndGeom( list< Handle(_pyMesh) >& meshes ) +{ + if ( IsAlgo() ) return true; - // make a new name for 1D hyp = "HypType" + "_Distribution" - if ( my1dHyp->GetCreationCmd()->GetMethod() == "CreateHypothesis" ) { - // not yet converted creation cmd - TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1); - TCollection_AsciiString hypType = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 ); - newName = hypType + "_Distribution"; - my1dHyp->GetCreationCmd()->SetResultValue( newName ); + bool geomPublished = true; + vector< _AString > args; + TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin(); + for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth ) + { + CreationMethod& crMethod = type2meth->second; + args.insert( args.end(), crMethod.myArgs.begin(), crMethod.myArgs.end()); } - else { - // already converted creation cmd - newName = my1dHyp->GetCreationCmd()->GetResultValue(); + list::iterator cmd = myUnusedCommands.begin(); + for ( ; cmd != myUnusedCommands.end(); ++cmd ) { + for ( int nb = (*cmd)->GetNbArgs(); nb; --nb ) + args.push_back( (*cmd)->GetArg( nb )); } - // as creation of 1D hyp was written later then it's edition, - // we need to find all it's edition calls and process them - list< Handle(_pyCommand) >& cmds = theGen->GetCommands(); - list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin(); - for ( ; cmdIt != cmds.end(); ++cmdIt ) { - const _pyID& objID = (*cmdIt)->GetObject(); - if ( objID == hyp1dID ) { - my1dHyp->Process( *cmdIt ); - my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt ); - ( *cmdIt )->SetObject( newName ); - } - } - if ( !myArgCommands.empty() ) - myArgCommands.front()->Clear(); - theCommand->SetArg( 1, newName ); - myArgCommands.push_back( theCommand ); - // copy hyp1d's creation method and args -// myCreationMethod = hyp1d->GetCreationMethod(); -// myArgs = hyp1d->GetArgs(); -// // make them cleared at conversion -// myArgCommands = hyp1d->GetArgCommands(); - -// // to be cleared at convertion only -// myArgCommands.push_back( theCommand ); + for ( size_t i = 0; i < args.size(); ++i ) + { + list< _pyID > idList = _pyCommand::GetStudyEntries( args[ i ]); + if ( idList.empty() && !args[ i ].IsEmpty() ) + idList.push_back( args[ i ]); + list< _pyID >::iterator id = idList.begin(); + for ( ; id != idList.end(); ++id ) + { + Handle(_pyObject) obj = theGen->FindObject( *id ); + if ( obj.IsNull() ) obj = theGen->FindHyp( *id ); + if ( obj.IsNull() ) + { + if ( theGen->IsGeomObject( *id ) && theGen->IsNotPublished( *id )) + geomPublished = false; + } + else + { + myReferredObjs.push_back( obj ); + Handle(_pyMesh) mesh = ObjectToMesh( obj ); + if ( !mesh.IsNull() ) + meshes.push_back( mesh ); + // prevent clearing not published hyps referred e.g. by "LayerDistribution" + else if ( obj->IsKind( STANDARD_TYPE( _pyHypothesis )) && this->IsInStudy() ) + obj->SetRemovedFromStudy( false ); + } + } + } + return geomPublished; } //================================================================================ /*! - * \brief - * \param theAdditionCmd - command to be converted - * \param theMesh - mesh instance - * \retval bool - status + * \brief Remember theCommand setting a parameter */ //================================================================================ -bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, - const _pyID& theMesh) +void _pyHypothesis::rememberCmdOfParameter( const Handle(_pyCommand) & theCommand ) { - myIsWrapped = false; + // parameters are discriminated by method name + TCollection_AsciiString method = theCommand->GetMethod(); - if ( my1dHyp.IsNull() ) - return false; + // discriminate commands setting different parameters via one method + // by passing parameter names like e.g. SetOption("size", "0.2") + if ( theCommand->GetString().FirstLocationInSet( "'\"", 1, theCommand->Length() ) && + theCommand->GetNbArgs() > 1 ) + { + // mangle method by appending a 1st textual arg + for ( int iArg = 1; iArg <= theCommand->GetNbArgs(); ++iArg ) + { + const TCollection_AsciiString& arg = theCommand->GetArg( iArg ); + if ( arg.Value(1) != '\"' && arg.Value(1) != '\'' ) continue; + if ( !isalpha( arg.Value(2))) continue; + method += arg; + break; + } + } + // parameters are discriminated by method name + list< Handle(_pyCommand)>& cmds = myMeth2Commands[ theCommand->GetMethod() ]; + if ( !cmds.empty() && !isCmdUsedForCompute( cmds.back() )) + { + cmds.back()->Clear(); // previous parameter value has not been used + cmds.back() = theCommand; + } + else + { + cmds.push_back( theCommand ); + } +} - // set "SetLayerDistribution()" after addition cmd - theAdditionCmd->AddDependantCmd( myArgCommands.front() ); +//================================================================================ +/*! + * \brief Return true if a setting parameter command ha been used to compute mesh + */ +//================================================================================ - _pyID geom = theAdditionCmd->GetArg( 1 ); +bool _pyHypothesis::isCmdUsedForCompute( const Handle(_pyCommand) & cmd, + _pyCommand::TAddr avoidComputeAddr ) const +{ + bool isUsed = false; + map< _pyCommand::TAddr, list >::const_iterator addr2cmds = + myComputeAddr2Cmds.begin(); + for ( ; addr2cmds != myComputeAddr2Cmds.end() && !isUsed; ++addr2cmds ) + { + if ( addr2cmds->first == avoidComputeAddr ) continue; + const list & cmds = addr2cmds->second; + isUsed = ( std::find( cmds.begin(), cmds.end(), cmd ) != cmds.end() ); + } + return isUsed; +} + +//================================================================================ +/*! + * \brief Save commands setting parameters as they are used for a mesh computation + */ +//================================================================================ + +void _pyHypothesis::MeshComputed( const Handle(_pyCommand)& theComputeCmd ) +{ + myComputeCmds.push_back( theComputeCmd ); + list& savedCmds = myComputeAddr2Cmds[ theComputeCmd->GetAddress() ]; + + map >::iterator m2c; + for ( m2c = myMeth2Commands.begin(); m2c != myMeth2Commands.end(); ++m2c ) + savedCmds.push_back( m2c->second.back() ); +} + +//================================================================================ +/*! + * \brief Clear commands setting parameters as a mesh computed using them is cleared + */ +//================================================================================ + +void _pyHypothesis::ComputeDiscarded( const Handle(_pyCommand)& theComputeCmd ) +{ + list& savedCmds = myComputeAddr2Cmds[ theComputeCmd->GetAddress() ]; + + list::iterator cmd = savedCmds.begin(); + for ( ; cmd != savedCmds.end(); ++cmd ) + { + // check if a cmd has been used to compute another mesh + if ( isCmdUsedForCompute( *cmd, theComputeCmd->GetAddress() )) + continue; + // check if a cmd is a sole command setting its parameter; + // don't use method name for search as it can change + map >::iterator + m2cmds = myMeth2Commands.begin(); + for ( ; m2cmds != myMeth2Commands.end(); ++m2cmds ) + { + list< Handle(_pyCommand)>& cmds = m2cmds->second; + list< Handle(_pyCommand)>::iterator cmdIt = std::find( cmds.begin(), cmds.end(), *cmd ); + if ( cmdIt != cmds.end() ) + { + if ( cmds.back() != *cmd ) + { + cmds.erase( cmdIt ); + (*cmd)->Clear(); + } + break; + } + } + } + myComputeAddr2Cmds.erase( theComputeCmd->GetAddress() ); +} + +//================================================================================ +/*! + * \brief Sets an argNb-th argument of current creation command + * \param argNb - argument index countered from 1 + */ +//================================================================================ + +void _pyHypothesis::setCreationArg( const int argNb, const _AString& arg ) +{ + if ( myCurCrMethod ) + { + while ( myCurCrMethod->myArgs.size() < argNb ) + myCurCrMethod->myArgs.push_back( "None" ); + if ( arg.IsEmpty() ) + myCurCrMethod->myArgs[ argNb-1 ] = "None"; + else + myCurCrMethod->myArgs[ argNb-1 ] = arg; + } +} + + +//================================================================================ +/*! + * \brief Remember hypothesis parameter values + * \param theCommand - The called hypothesis method + */ +//================================================================================ + +void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand) +{ + if ( GetAlgoType() == "Cartesian_3D" ) + { + // CartesianParameters3D hyp + + if ( theCommand->GetMethod() == "SetSizeThreshold" ) + { + setCreationArg( 4, theCommand->GetArg( 1 )); + myArgCommands.push_back( theCommand ); + return; + } + if ( theCommand->GetMethod() == "SetGrid" || + theCommand->GetMethod() == "SetGridSpacing" ) + { + TCollection_AsciiString axis = theCommand->GetArg( theCommand->GetNbArgs() ); + int iArg = axis.Value(1) - '0'; + if ( theCommand->GetMethod() == "SetGrid" ) + { + setCreationArg( 1+iArg, theCommand->GetArg( 1 )); + } + else + { + myCurCrMethod->myArgs[ iArg ] = "[ "; + myCurCrMethod->myArgs[ iArg ] += theCommand->GetArg( 1 ); + myCurCrMethod->myArgs[ iArg ] += ", "; + myCurCrMethod->myArgs[ iArg ] += theCommand->GetArg( 2 ); + myCurCrMethod->myArgs[ iArg ] += "]"; + } + myArgCommands.push_back( theCommand ); + rememberCmdOfParameter( theCommand ); + return; + } + } + + if( theCommand->GetMethod() == "SetLength" ) + { + // NOW it is OBSOLETE + // ex: hyp.SetLength(start, 1) + // hyp.SetLength(end, 0) + ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() )); + int i = 1 - theCommand->GetArg( 2 ).IntegerValue(); + TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin(); + for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth ) + { + CreationMethod& crMethod = type2meth->second; + while ( crMethod.myArgs.size() < i+1 ) + crMethod.myArgs.push_back( "[]" ); + crMethod.myArgs[ i ] = theCommand->GetArg( 1 ); // arg value + } + myArgCommands.push_back( theCommand ); + } + else + { + _pyHypothesis::Process( theCommand ); + } +} +//================================================================================ +/*! + * \brief Clear SetObjectEntry() as it is called by methods of Mesh_Segment + */ +//================================================================================ + +void _pyComplexParamHypo::Flush() +{ + if ( IsWrapped() ) + { + list < Handle(_pyCommand) >::iterator cmd = myUnusedCommands.begin(); + for ( ; cmd != myUnusedCommands.end(); ++cmd ) + if ((*cmd)->GetMethod() == "SetObjectEntry" ) + (*cmd)->Clear(); + } +} + +//================================================================================ +/*! + * \brief Convert methods of 1D hypotheses to my own methods + * \param theCommand - The called hypothesis method + */ +//================================================================================ + +void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand) +{ + if ( theCommand->GetMethod() != "SetLayerDistribution" ) + return; + + const _pyID& hyp1dID = theCommand->GetArg( 1 ); + // Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID ); + // if ( hyp1d.IsNull() && ! my1dHyp.IsNull()) // apparently hypId changed at study restoration + // { + // TCollection_AsciiString cmd = + // my1dHyp->GetCreationCmd()->GetIndentation() + hyp1dID + " = " + my1dHyp->GetID(); + // Handle(_pyCommand) newCmd = theGen->AddCommand( cmd ); + // theGen->SetCommandAfter( newCmd, my1dHyp->GetCreationCmd() ); + // hyp1d = my1dHyp; + // } + // else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() ) + // { + // // 1D hypo is already set, so distribution changes and the old + // // 1D hypo is thrown away + // my1dHyp->ClearAllCommands(); + // } + // my1dHyp = hyp1d; + // //my1dHyp->SetRemovedFromStudy( false ); + + // if ( !myArgCommands.empty() ) + // myArgCommands.back()->Clear(); + myCurCrMethod->myArgs.push_back( hyp1dID ); + myArgCommands.push_back( theCommand ); +} + +//================================================================================ +/*! + * \brief + * \param theAdditionCmd - command to be converted + * \param theMesh - mesh instance + * \retval bool - status + */ +//================================================================================ - my1dHyp->SetMesh( theMesh ); - if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh )) +bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, + const _pyID& theMesh) +{ + myIsWrapped = false; + + if ( my1dHyp.IsNull() ) return false; - // clear "SetLayerDistribution()" cmd - myArgCommands.front()->Clear(); + // set "SetLayerDistribution()" after addition cmd + theAdditionCmd->AddDependantCmd( myArgCommands.front() ); - // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis() + _pyID geom = theAdditionCmd->GetArg( 1 ); - // find RadialPrism algo created on for theMesh Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this ); - if ( !algo.IsNull() ) { + if ( !algo.IsNull() ) + { + my1dHyp->SetMesh( theMesh ); + my1dHyp->SetConvMethodAndType(my1dHyp->GetAlgoCreationMethod().ToCString(), + algo->GetAlgoType().ToCString()); + if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh )) + return false; + + // clear "SetLayerDistribution()" cmd + myArgCommands.back()->Clear(); + + // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis() + + // find RadialPrism algo created on for theMesh GetCreationCmd()->SetObject( algo->GetID() ); - GetCreationCmd()->SetMethod( "Get3DHypothesis" ); + GetCreationCmd()->SetMethod( myAlgoMethod ); GetCreationCmd()->RemoveArgs(); theAdditionCmd->AddDependantCmd( GetCreationCmd() ); myIsWrapped = true; @@ -1653,14 +2777,60 @@ bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theA //================================================================================ /*! - * \brief + * \brief */ //================================================================================ void _pyLayerDistributionHypo::Flush() { - //my1dHyp.Nullify(); - //_pyHypothesis::Flush(); + // as creation of 1D hyp was written later then it's edition, + // we need to find all it's edition calls and process them + list< Handle(_pyCommand) >::iterator cmd = myArgCommands.begin(); + _pyID prevNewName; + for ( cmd = myArgCommands.begin(); cmd != myArgCommands.end(); ++cmd ) + { + const _pyID& hyp1dID = (*cmd)->GetArg( 1 ); + if ( hyp1dID.IsEmpty() ) continue; + + Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID ); + + // make a new name for 1D hyp = "HypType" + "_Distribution" + _pyID newName; + if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration + { + if ( prevNewName.IsEmpty() ) continue; + newName = prevNewName; + } + else + { + if ( hyp1d->IsWrapped() ) { + newName = hyp1d->GetCreationCmd()->GetMethod(); + } + else { + TCollection_AsciiString hypTypeQuoted = hyp1d->GetCreationCmd()->GetArg(1); + newName = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 ); + } + newName += "_Distribution"; + prevNewName = newName; + + hyp1d->GetCreationCmd()->SetResultValue( newName ); + } + list< Handle(_pyCommand) >& cmds = theGen->GetCommands(); + list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin(); + for ( ; cmdIt != cmds.end(); ++cmdIt ) { + const _pyID& objID = (*cmdIt)->GetObject(); + if ( objID == hyp1dID ) { + if ( !hyp1d.IsNull() ) + { + hyp1d->Process( *cmdIt ); + hyp1d->GetCreationCmd()->AddDependantCmd( *cmdIt ); + } + ( *cmdIt )->SetObject( newName ); + } + } + // Set new hyp name to SetLayerDistribution(hyp1dID) cmd + (*cmd)->SetArg( 1, newName ); + } } //================================================================================ @@ -1675,11 +2845,11 @@ void _pyLayerDistributionHypo::Flush() bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd, const _pyID& theMesh) { - if ( IsWrappable( theMesh ) && myArgs.Length() > 1 ) { + if ( IsWrappable( theMesh ) && myCurCrMethod->myArgs.size() > 1 ) { // scale factor (2-nd arg) is provided: clear SetDistrType(1) command bool scaleDistrType = false; - list::reverse_iterator cmd = myUnknownCommands.rbegin(); - for ( ; cmd != myUnknownCommands.rend(); ++cmd ) { + list::reverse_iterator cmd = myUnusedCommands.rbegin(); + for ( ; cmd != myUnusedCommands.rend(); ++cmd ) { if ( (*cmd)->GetMethod() == "SetDistrType" ) { if ( (*cmd)->GetArg( 1 ) == "1" ) { scaleDistrType = true; @@ -1687,7 +2857,13 @@ bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd } else if ( !scaleDistrType ) { // distribution type changed: remove scale factor from args - myArgs.Remove( 2, myArgs.Length() ); + TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin(); + for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth ) + { + CreationMethod& crMethod = type2meth->second; + if ( crMethod.myArgs.size() == 2 ) + crMethod.myArgs.pop_back(); + } break; } } @@ -1705,14 +2881,16 @@ bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd void _pyNumberOfSegmentsHyp::Flush() { // find number of the last SetDistrType() command - list::reverse_iterator cmd = myUnknownCommands.rbegin(); + list::reverse_iterator cmd = myUnusedCommands.rbegin(); int distrTypeNb = 0; - for ( ; !distrTypeNb && cmd != myUnknownCommands.rend(); ++cmd ) + for ( ; !distrTypeNb && cmd != myUnusedCommands.rend(); ++cmd ) if ( (*cmd)->GetMethod() == "SetDistrType" ) distrTypeNb = (*cmd)->GetOrderNb(); + else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" ) + (*cmd)->Clear(); // clear commands before the last SetDistrType() - list * cmds[2] = { &myArgCommands, &myUnknownCommands }; + list * cmds[2] = { &myArgCommands, &myUnusedCommands }; for ( int i = 0; i < 2; ++i ) { set uniqueMethods; list & cmdList = *cmds[i]; @@ -1740,7 +2918,7 @@ void _pyNumberOfSegmentsHyp::Flush() * \retval bool - false if the command cant be converted */ //================================================================================ - + bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd, const _pyID& theMeshID) { @@ -1764,8 +2942,8 @@ bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand theCmd->SetArg( 1, geom ); // set vertex as a second arg - if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :( - myArgs.Append( vertex ); + if ( myCurCrMethod->myArgs.size() < 1) setCreationArg( 1, "1" ); // :( + setCreationArg( 2, vertex ); // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) --> // theMeshID.LengthNearVertex( length, vertex ) @@ -1791,11 +2969,11 @@ _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd) /*! * \brief Convert the command adding an algorithm to mesh * \param theCmd - The command like mesh.AddHypothesis( geom, algo ) - * \param theMesh - The mesh needing this algo + * \param theMesh - The mesh needing this algo * \retval bool - false if the command cant be converted */ //================================================================================ - + bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd, const _pyID& theMeshID) { @@ -1867,12 +3045,20 @@ const TCollection_AsciiString & _pyCommand::GetResultValue() { if ( GetBegPos( RESULT_IND ) == UNKNOWN ) { - int begPos = myString.Location( "=", 1, Length() ); - if ( begPos ) - myRes = GetWord( myString, begPos, false ); - else - begPos = EMPTY; - SetBegPos( RESULT_IND, begPos ); + SetBegPos( RESULT_IND, EMPTY ); + int begPos, endPos = myString.Location( "=", 1, Length() ); + if ( endPos ) + { + begPos = 1; + while ( begPos < endPos && isspace( myString.Value( begPos ))) ++begPos; + if ( begPos < endPos ) + { + SetBegPos( RESULT_IND, begPos ); + --endPos; + while ( begPos < endPos && isspace( myString.Value( endPos ))) --endPos; + myRes = myString.SubString( begPos, endPos ); + } + } } return myRes; } @@ -1902,22 +3088,25 @@ const int _pyCommand::GetNbResultValues() //================================================================================ /*! * \brief Return substring of python command looking like - * ResultValue1 , ResultValue1,... = Obj.Meth() with res index + * ResultValue1 , ResultValue2,... = Obj.Meth() with res index * \retval const TCollection_AsciiString & - ResultValue with res index substring */ //================================================================================ -const TCollection_AsciiString & _pyCommand::GetResultValue(int res) +TCollection_AsciiString _pyCommand::GetResultValue(int res) { int begPos = 1; - int Nb=0; + if ( SkipSpaces( myString, begPos ) && myString.Value( begPos ) == '[' ) + ++begPos; // skip [, else the whole list is returned int endPos = myString.Location( "=", 1, Length() ); + int Nb=0; while ( begPos < endPos) { - myRes = GetWord( myString, begPos, true ); - begPos = begPos + myRes.Length(); + _AString result = GetWord( myString, begPos, true ); + begPos = begPos + result.Length(); Nb++; - if(res == Nb){ - myRes.RemoveAll('[');myRes.RemoveAll(']'); - return myRes; + if(res == Nb) { + result.RemoveAll('['); + result.RemoveAll(']'); + return result; } if(Nb>res) break; @@ -1944,18 +3133,38 @@ const TCollection_AsciiString & _pyCommand::GetObject() int nb1 = 0; // number of ' character at the left of = int nb2 = 0; // number of " character at the left of = for ( int i = 1; i < begPos-1; i++ ) { - if ( IsEqual(myString.Value( i ), "'" ) ) - nb1 += 1; - else if ( IsEqual( myString.Value( i ), '"' ) ) - nb2 += 1; + if ( myString.Value( i )=='\'' ) + nb1 += 1; + else if ( myString.Value( i )=='"' ) + nb2 += 1; } // if number of ' or " is not divisible by 2, // then get an object at the start of the command if ( nb1 % 2 != 0 || nb2 % 2 != 0 ) - begPos = 1; + begPos = 1; } - // store myObj = GetWord( myString, begPos, true ); + // check if object is complex, + // so far consider case like "smesh.smesh.Method()" + if ( int bracketPos = myString.Location( "(", begPos, Length() )) { + //if ( bracketPos==0 ) bracketPos = Length(); + int dotPos = begPos+myObj.Length(); + while ( dotPos+1 < bracketPos ) { + if ( int pos = myString.Location( ".", dotPos+1, bracketPos )) + dotPos = pos; + else + break; + } + if ( dotPos > begPos+myObj.Length() ) + myObj = myString.SubString( begPos, dotPos-1 ); + } + // 1st word after '=' is an object + // else // no method -> no object + // { + // myObj.Clear(); + // begPos = EMPTY; + // } + // store SetBegPos( OBJECT_IND, begPos ); } //SCRUTE(myObj); @@ -1999,32 +3208,71 @@ const TCollection_AsciiString & _pyCommand::GetArg( int index ) { if ( GetBegPos( ARG1_IND ) == UNKNOWN ) { - // find all args - int begPos = GetBegPos( METHOD_IND ) + myMeth.Length(); - if ( begPos < 1 ) - begPos = myString.Location( "(", 1, Length() ) + 1; - - int i = 0, prevLen = 0, nbNestings = 0; - while ( begPos != EMPTY ) { - begPos += prevLen; - if( myString.Value( begPos ) == '(' ) - nbNestings++; - // check if we are looking at the closing parenthesis - while ( begPos <= Length() && isspace( myString.Value( begPos ))) - ++begPos; - if ( begPos > Length() ) - break; - if ( myString.Value( begPos ) == ')' ) { - nbNestings--; - if( nbNestings == 0 ) - break; + // Find all args + + int pos = GetBegPos( METHOD_IND ) + myMeth.Length(); + if ( pos < 1 ) + pos = myString.Location( "(", 1, Length() ); + else + --pos; + + // we are at or before '(', skip it if present + if ( pos > 0 ) { + while ( pos <= Length() && myString.Value( pos ) != '(' ) ++pos; + if ( pos > Length() ) + pos = 0; + } + if ( pos < 1 ) { + SetBegPos( ARG1_IND, 0 ); // even no '(' + return theEmptyString; + } + ++pos; + + list< TCollection_AsciiString > separatorStack( 1, ",)"); + bool ignoreNesting = false; + int prevPos = pos; + while ( pos <= Length() ) + { + const char chr = myString.Value( pos ); + + if ( separatorStack.back().Location( chr, 1, separatorStack.back().Length())) + { + if ( separatorStack.size() == 1 ) // a comma dividing args or a terminal ')' found + { + while ( pos-1 >= prevPos && isspace( myString.Value( prevPos ))) + ++prevPos; + TCollection_AsciiString arg; + if ( pos-1 >= prevPos ) { + arg = myString.SubString( prevPos, pos-1 ); + arg.RightAdjust(); // remove spaces + arg.LeftAdjust(); + } + if ( !arg.IsEmpty() || chr == ',' ) + { + SetBegPos( ARG1_IND + myArgs.Length(), prevPos ); + myArgs.Append( arg ); + } + if ( chr == ')' ) + break; + prevPos = pos+1; + } + else // end of nesting args found + { + separatorStack.pop_back(); + ignoreNesting = false; + } } - myArgs.Append( GetWord( myString, begPos, true, true )); - SetBegPos( ARG1_IND + i, begPos ); - prevLen = myArgs.Last().Length(); - if ( prevLen == 0 ) - myArgs.Remove( myArgs.Length() ); // no more args - i++; + else if ( !ignoreNesting ) + { + switch ( chr ) { + case '(' : separatorStack.push_back(")"); break; + case '[' : separatorStack.push_back("]"); break; + case '\'': separatorStack.push_back("'"); ignoreNesting=true; break; + case '"' : separatorStack.push_back("\""); ignoreNesting=true; break; + default:; + } + } + ++pos; } } if ( myArgs.Length() < index ) @@ -2074,9 +3322,19 @@ TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & the return theEmptyString; // no word found // end end = beg + 1; - while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord)) - ++end; - --end; + char begChar = theString.Value( beg ); + if ( begChar == '"' || begChar == '\'' || begChar == '[') { + char endChar = ( begChar == '[' ) ? ']' : begChar; + // end is at the corresponding quoting mark or bracket + while ( end < theString.Length() && + ( theString.Value( end ) != endChar || theString.Value( end-1 ) == '\\')) + ++end; + } + else { + while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord)) + ++end; + --end; + } } else { // search backward // end @@ -2085,23 +3343,77 @@ TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & the if ( end == 0 ) return theEmptyString; // no word found beg = end - 1; - while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord)) - --beg; - ++beg; + char endChar = theString.Value( end ); + if ( endChar == '"' || endChar == '\'' || endChar == ']') { + char begChar = ( endChar == ']' ) ? '[' : endChar; + // beg is at the corresponding quoting mark + while ( beg > 1 && + ( theString.Value( beg ) != begChar || theString.Value( beg-1 ) == '\\')) + --beg; + } + else { + while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord)) + --beg; + ++beg; + } } theStartPos = beg; //cout << theString << " ---- " << beg << " - " << end << endl; return theString.SubString( beg, end ); } +//================================================================================ +/*! + * \brief Returns true if the string looks like a study entry + */ +//================================================================================ + +bool _pyCommand::IsStudyEntry( const TCollection_AsciiString& str ) +{ + if ( str.Length() < 5 ) return false; + + int nbColons = 0, isColon; + for ( int i = 1; i <= str.Length(); ++i ) + { + char c = str.Value(i); + if (!( isColon = (c == ':')) && ( c < '0' || c > '9' )) + return false; + nbColons += isColon; + } + return nbColons > 2 && str.Length()-nbColons > 2; +} + +//================================================================================ +/*! + * \brief Finds entries in a sting + */ +//================================================================================ + +std::list< _pyID > _pyCommand::GetStudyEntries( const TCollection_AsciiString& str ) +{ + std::list< _pyID > resList; + int pos = 0; + while ( ++pos <= str.Length() ) + { + if ( !isdigit( str.Value( pos ))) continue; + if ( pos != 1 && ( isalpha( str.Value( pos-1 ) || str.Value( pos-1 ) == ':'))) continue; + + int end = pos; + while ( ++end <= str.Length() && ( isdigit( str.Value( end )) || str.Value( end ) == ':' )); + _pyID entry = str.SubString( pos, end-1 ); + pos = end; + if ( IsStudyEntry( entry )) + resList.push_back( entry ); + } + return resList; +} + //================================================================================ /*! * \brief Look for position where not space char is - * \param theString - The string + * \param theString - The string * \param thePos - The position to search from and which returns result * \retval bool - false if there are only space after thePos in theString - * - * */ //================================================================================ @@ -2141,7 +3453,7 @@ void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePar case METHOD_IND: seperator = "()"; break; default:; } - } + } myString.Remove( pos, theOldPart.Length() ); if ( !seperator.IsEmpty() ) myString.Insert( pos , seperator ); @@ -2215,6 +3527,30 @@ void _pyCommand::RemoveArgs() myBegPos.Remove( ARG1_IND, myBegPos.Length() ); } +//================================================================================ +/*! + * \brief Comment a python command + */ +//================================================================================ + +void _pyCommand::Comment() +{ + if ( IsEmpty() ) return; + + int i = 1; + while ( i <= Length() && isspace( myString.Value(i) )) ++i; + if ( i <= Length() ) + { + myString.Insert( i, "#" ); + for ( int iPart = 0; iPart < myBegPos.Length(); ++iPart ) + { + int begPos = GetBegPos( iPart ); + if ( begPos != UNKNOWN ) + SetBegPos( iPart, begPos + 1 ); + } + } +} + //================================================================================ /*! * \brief Set dependent commands after this one @@ -2280,6 +3616,49 @@ bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod return added; } +//================================================================================ +/*! + * \brief Creates pyObject + */ +//================================================================================ + +_pyObject::_pyObject(const Handle(_pyCommand)& theCreationCmd, const _pyID& theID) + : myID(theID), myCreationCmd(theCreationCmd), myIsPublished(false) +{ + setID( theID ); +} + +//================================================================================ +/*! + * \brief Set up myID and myIsPublished + */ +//================================================================================ + +void _pyObject::setID(const _pyID& theID) +{ + myID = theID; + myIsPublished = !theGen->IsNotPublished( GetID() ); +} + +//================================================================================ +/*! + * \brief Clear myCreationCmd and myProcessedCmds + */ +//================================================================================ + +void _pyObject::ClearCommands() +{ + if ( !CanClear() ) + return; + + if ( !myCreationCmd.IsNull() ) + myCreationCmd->Clear(); + + list< Handle(_pyCommand) >::iterator cmd = myProcessedCmds.begin(); + for ( ; cmd != myProcessedCmds.end(); ++cmd ) + (*cmd)->Clear(); +} + //================================================================================ /*! * \brief Return method name giving access to an interaface object wrapped by python class @@ -2307,14 +3686,69 @@ _pyID _pyObject::FatherID(const _pyID & childID) //================================================================================ /*! - * \brief FilterManager creates only if at least one command invoked + * \brief SelfEraser erases creation command if no more it's commands invoked */ //================================================================================ -_pyFilterManager::_pyFilterManager(const Handle(_pyCommand)& theCreationCmd): - _pyObject( theCreationCmd ), - myCmdCount( 0 ) +void _pySelfEraser::Flush() { + if ( GetNbCalls() == 0 ) + GetCreationCmd()->Clear(); +} + +//================================================================================ +/*! + * \brief _pySubMesh constructor + */ +//================================================================================ + +_pySubMesh::_pySubMesh(const Handle(_pyCommand)& theCreationCmd): + _pyObject(theCreationCmd) +{ + myMesh = ObjectToMesh( theGen->FindObject( theCreationCmd->GetObject() )); +} + +//================================================================================ +/*! + * \brief Return true if a sub-mesh can be used as argument of the given method + */ +//================================================================================ + +bool _pySubMesh::CanBeArgOfMethod(const _AString& theMethodName) +{ + // names of all methods where a sub-mesh can be used as argument + static TStringSet methods; + if ( methods.empty() ) { + const char * names[] = { + // methods of SMESH_Gen + "CopyMesh", + // methods of SMESH_Group + "AddFrom", + // methods of SMESH_Measurements + "MinDistance", + // methods of SMESH_Mesh + "ExportPartToMED","ExportCGNS","ExportPartToDAT","ExportPartToUNV","ExportPartToSTL", + "RemoveSubMesh", + // methods of SMESH_MeshEditor + "ReorientObject","Reorient2D","TriToQuadObject","QuadToTriObject","SplitQuadObject", + "SplitVolumesIntoTetra","SmoothObject","SmoothParametricObject","ConvertFromQuadraticObject", + "RotationSweepObject","RotationSweepObjectMakeGroups","RotationSweepObject1D", + "RotationSweepObject1DMakeGroups","RotationSweepObject2D","RotationSweepObject2DMakeGroups", + "ExtrusionSweepObject","ExtrusionSweepObjectMakeGroups","ExtrusionSweepObject0D", + "ExtrusionSweepObject0DMakeGroups","ExtrusionSweepObject1D","ExtrusionSweepObject2D", + "ExtrusionSweepObject1DMakeGroups","ExtrusionSweepObject2DMakeGroups", + "ExtrusionAlongPathObjX","ExtrusionAlongPathObject","ExtrusionAlongPathObjectMakeGroups", + "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject1DMakeGroups", + "ExtrusionAlongPathObject2D","ExtrusionAlongPathObject2DMakeGroups","MirrorObject", + "MirrorObjectMakeGroups","MirrorObjectMakeMesh","TranslateObject","Scale", + "TranslateObjectMakeGroups","TranslateObjectMakeMesh","ScaleMakeGroups","ScaleMakeMesh", + "RotateObject","RotateObjectMakeGroups","RotateObjectMakeMesh","FindCoincidentNodesOnPart", + "FindCoincidentNodesOnPartBut","FindEqualElements","FindAmongElementsByPoint", + "MakeBoundaryMesh", + "" }; // <- mark of end + methods.Insert( names ); + } + return methods.Contains( theMethodName ); } //================================================================================ @@ -2323,59 +3757,452 @@ _pyFilterManager::_pyFilterManager(const Handle(_pyCommand)& theCreationCmd): */ //================================================================================ -void _pyFilterManager::Process( const Handle(_pyCommand)& /*theCommand*/) +void _pySubMesh::Process( const Handle(_pyCommand)& theCommand ) +{ + _pyObject::Process(theCommand); // count calls of Process() + GetCreationCmd()->AddDependantCmd( theCommand ); +} + +//================================================================================ +/*! + * \brief Move creation command depending on invoked commands + */ +//================================================================================ + +void _pySubMesh::Flush() +{ + if ( GetNbCalls() == 0 ) // move to the end of all commands + theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() ); + else if ( !myCreator.IsNull() ) + // move to be just after creator + myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() ); +} + +//================================================================================ +/*! + * \brief Creates _pyGroup + */ +//================================================================================ + +_pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id) + :_pySubMesh(theCreationCmd) { - myCmdCount++; + if ( !id.IsEmpty() ) + setID( id ); + + myCanClearCreationCmd = true; + + const _AString& method = theCreationCmd->GetMethod(); + if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup() + { + theCreationCmd->SetMethod( "CreateEmptyGroup" ); + } + // ---------------------------------------------------------------------- + else if ( method == "CreateGroupFromGEOM" ) // (type, name, grp) + { + _pyID geom = theCreationCmd->GetArg( 3 ); + // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump + // next if(){...} section is commented + //if ( sameGroupType( geom, theCreationCmd->GetArg( 1 )) ) { // --> Group(geom) + // theCreationCmd->SetMethod( "Group" ); + // theCreationCmd->RemoveArgs(); + // theCreationCmd->SetArg( 1, geom ); + //} + //else { + // ------------------------->>>>> GroupOnGeom( geom, name, typ ) + _pyID type = theCreationCmd->GetArg( 1 ); + _pyID name = theCreationCmd->GetArg( 2 ); + theCreationCmd->SetMethod( "GroupOnGeom" ); + theCreationCmd->RemoveArgs(); + theCreationCmd->SetArg( 1, geom ); + theCreationCmd->SetArg( 2, name ); + theCreationCmd->SetArg( 3, type ); + //} + } + else if ( method == "CreateGroupFromFilter" ) + { + // -> GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1) + theCreationCmd->SetMethod( "GroupOnFilter" ); + + _pyID filterID = theCreationCmd->GetArg(3); + Handle(_pyFilter) filter = Handle(_pyFilter)::DownCast( theGen->FindObject( filterID )); + if ( !filter.IsNull()) + { + if ( !filter->GetNewID().IsEmpty() ) + theCreationCmd->SetArg( 3, filter->GetNewID() ); + filter->AddUser( this ); + } + myFilter = filter; + } + else + { + // theCreationCmd does something else apart from creation of this group + // and thus it can't be cleared if this group is removed + myCanClearCreationCmd = false; + } } //================================================================================ /*! - * \brief Clear creatin command if no commands invoked + * \brief To convert creation of a group by filter */ //================================================================================ -void _pyFilterManager::Flush() +void _pyGroup::Process( const Handle(_pyCommand)& theCommand) { - if ( !myCmdCount ) + // Convert the following set of commands into mesh.MakeGroupByFilter(groupName, theFilter) + // group = mesh.CreateEmptyGroup( elemType, groupName ) + // aFilter.SetMesh(mesh) + // nbAdd = group.AddFrom( aFilter ) + Handle(_pyFilter) filter; + if ( theCommand->GetMethod() == "AddFrom" ) + { + _pyID idSource = theCommand->GetArg(1); + // check if idSource is a filter + filter = Handle(_pyFilter)::DownCast( theGen->FindObject( idSource )); + if ( !filter.IsNull() ) + { + // find aFilter.SetMesh(mesh) to clear it, it should be just before theCommand + list< Handle(_pyCommand) >::reverse_iterator cmdIt = theGen->GetCommands().rbegin(); + while ( *cmdIt != theCommand ) ++cmdIt; + while ( (*cmdIt)->GetOrderNb() != 1 ) + { + const Handle(_pyCommand)& setMeshCmd = *(++cmdIt); + if ((setMeshCmd->GetObject() == idSource || + setMeshCmd->GetObject() == filter->GetNewID() ) + && + setMeshCmd->GetMethod() == "SetMesh") + { + setMeshCmd->Clear(); + break; + } + } + // replace 3 commands by one + theCommand->Clear(); + const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd(); + TCollection_AsciiString name = makeGroupCmd->GetArg( 2 ); + if ( !filter->GetNewID().IsEmpty() ) + idSource = filter->GetNewID(); + makeGroupCmd->SetMethod( "MakeGroupByFilter" ); + makeGroupCmd->SetArg( 1, name ); + makeGroupCmd->SetArg( 2, idSource ); + } + } + else if ( theCommand->GetMethod() == "SetFilter" ) + { + // set new name of a filter or clear the command if the same filter is set + _pyID filterID = theCommand->GetArg(1); + filter = Handle(_pyFilter)::DownCast( theGen->FindObject( filterID )); + if ( !myFilter.IsNull() && filter == myFilter ) + theCommand->Clear(); + else if ( !filter.IsNull() && !filter->GetNewID().IsEmpty() ) + theCommand->SetArg( 1, filter->GetNewID() ); + myFilter = filter; + } + else if ( theCommand->GetMethod() == "GetFilter" ) + { + // GetFilter() returns a filter with other ID, make myFilter process + // calls of the returned filter + if ( !myFilter.IsNull() ) + { + theGen->SetProxyObject( theCommand->GetResultValue(), myFilter ); + theCommand->Clear(); + } + } + + if ( !filter.IsNull() ) + filter->AddUser( this ); + + theGen->AddMeshAccessorMethod( theCommand ); +} + +//================================================================================ +/*! + * \brief Prevent clearing "DoubleNode...() command if a group created by it is removed + * + * + */ +//================================================================================ + +void _pyGroup::Flush() +{ + if ( !theGen->IsToKeepAllCommands() && + myCreationCmd && !myCanClearCreationCmd ) + { + myCreationCmd.Nullify(); // this way myCreationCmd won't be cleared + } +} + +//================================================================================ +/*! + * \brief Constructor of _pyFilter + */ +//================================================================================ + +_pyFilter::_pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID/*=""*/) + :_pyObject(theCreationCmd), myNewID( newID ) +{ +} + +//================================================================================ +/*! + * \brief To convert creation of a filter by criteria and + * to replace an old name by a new one + */ +//================================================================================ + +void _pyFilter::Process( const Handle(_pyCommand)& theCommand) +{ + if ( theCommand->GetObject() == GetID() ) + _pyObject::Process(theCommand); // count commands + + if ( !myNewID.IsEmpty() ) + theCommand->SetObject( myNewID ); + + // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria) + // aFilter0x2aaab0487080 = aFilterManager.CreateFilter() + // aFilter0x2aaab0487080.SetCriteria(aCriteria) + if ( GetNbCalls() == 1 && // none method was called before this SetCriteria() call + theCommand->GetMethod() == "SetCriteria") + { + // aFilter.SetCriteria(aCriteria) -> + // aFilter = smesh.GetFilterFromCriteria(criteria) + if ( myNewID.IsEmpty() ) + theCommand->SetResultValue( GetID() ); + else + theCommand->SetResultValue( myNewID ); + theCommand->SetObject( SMESH_2smeshpy::GenName() ); + theCommand->SetMethod( "GetFilterFromCriteria" ); + + // Clear aFilterManager.CreateFilter() GetCreationCmd()->Clear(); + } + else if ( theCommand->GetMethod() == "SetMesh" ) + { + if ( myMesh == theCommand->GetArg( 1 )) + theCommand->Clear(); + else + myMesh = theCommand->GetArg( 1 ); + theGen->AddMeshAccessorMethod( theCommand ); + } } +//================================================================================ +/*! + * \brief Set new filter name to the creation command + */ +//================================================================================ + +void _pyFilter::Flush() +{ + if ( !myNewID.IsEmpty() && !GetCreationCmd()->IsEmpty() ) + GetCreationCmd()->SetResultValue( myNewID ); +} //================================================================================ /*! - * \brief SubMesh creation can be moved to the end of engine commands + * \brief Return true if all my users can be cleared */ //================================================================================ -_pySubMesh::_pySubMesh(const Handle(_pyCommand)& theCreationCmd): - _pyObject( theCreationCmd ), - myCmdCount( 0 ) +bool _pyFilter::CanClear() { + list< Handle(_pyObject) >::iterator obj = myUsers.begin(); + for ( ; obj != myUsers.end(); ++obj ) + if ( !(*obj)->CanClear() ) + return false; + + return true; } //================================================================================ /*! - * \brief count invoked commands + * \brief Reads _pyHypothesis'es from resource files of mesher Plugins */ //================================================================================ -void _pySubMesh::Process( const Handle(_pyCommand)& theCommand ) +_pyHypothesisReader::_pyHypothesisReader() { - myCmdCount++; - GetCreationCmd()->AddDependantCmd( theCommand ); + // Get paths to xml files of plugins + vector< string > xmlPaths; + string sep; + if ( const char* meshersList = getenv("SMESH_MeshersList") ) + { + string meshers = meshersList, plugin; + string::size_type from = 0, pos; + while ( from < meshers.size() ) + { + // cut off plugin name + pos = meshers.find( ':', from ); + if ( pos != string::npos ) + plugin = meshers.substr( from, pos-from ); + else + plugin = meshers.substr( from ), pos = meshers.size(); + from = pos + 1; + + // get PLUGIN_ROOT_DIR path + string rootDirVar, pluginSubDir = plugin; + if ( plugin == "StdMeshers" ) + rootDirVar = "SMESH", pluginSubDir = "smesh"; + else + for ( pos = 0; pos < plugin.size(); ++pos ) + rootDirVar += toupper( plugin[pos] ); + rootDirVar += "_ROOT_DIR"; + + const char* rootDir = getenv( rootDirVar.c_str() ); + if ( !rootDir || strlen(rootDir) == 0 ) + { + rootDirVar = plugin + "_ROOT_DIR"; // HexoticPLUGIN_ROOT_DIR + rootDir = getenv( rootDirVar.c_str() ); + if ( !rootDir || strlen(rootDir) == 0 ) continue; + } + + // get a separator from rootDir + for ( pos = strlen( rootDir )-1; pos >= 0 && sep.empty(); --pos ) + if ( rootDir[pos] == '/' || rootDir[pos] == '\\' ) + { + sep = rootDir[pos]; + break; + } +#ifdef WNT + if (sep.empty() ) sep = "\\"; +#else + if (sep.empty() ) sep = "/"; +#endif + + // get a path to resource file + string xmlPath = rootDir; + if ( xmlPath[ xmlPath.size()-1 ] != sep[0] ) + xmlPath += sep; + xmlPath += "share" + sep + "salome" + sep + "resources" + sep; + for ( pos = 0; pos < pluginSubDir.size(); ++pos ) + xmlPath += tolower( pluginSubDir[pos] ); + xmlPath += sep + plugin + ".xml"; + bool fileOK; +#ifdef WNT + fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES); +#else + fileOK = (access(xmlPath.c_str(), F_OK) == 0); +#endif + if ( fileOK ) + xmlPaths.push_back( xmlPath ); + } + } + + // Read xml files + LDOMParser xmlParser; + for ( size_t i = 0; i < xmlPaths.size(); ++i ) + { + bool error = xmlParser.parse( xmlPaths[i].c_str() ); + if ( error ) + { + _AString data; + INFOS( xmlParser.GetError(data) ); + continue; + } + // + // + // Regular_1D=Segment() + // LocalLength=LocalLength(SetLength(1),,SetPrecision(1)) + // + LDOM_Document xmlDoc = xmlParser.getDocument(); + LDOM_NodeList algoNodeList = xmlDoc.getElementsByTagName( "algorithm" ); + for ( int i = 0; i < algoNodeList.getLength(); ++i ) + { + LDOM_Node algoNode = algoNodeList.item( i ); + LDOM_Element& algoElem = (LDOM_Element&) algoNode; + LDOM_NodeList pyAlgoNodeList = algoElem.getElementsByTagName( "algo" ); + if ( pyAlgoNodeList.getLength() < 1 ) continue; + + _AString text, algoType, method, arg; + for ( int iA = 0; iA < pyAlgoNodeList.getLength(); ++iA ) + { + LDOM_Node pyAlgoNode = pyAlgoNodeList.item( iA ); + LDOM_Node textNode = pyAlgoNode.getFirstChild(); + text = textNode.getNodeValue(); + Handle(_pyCommand) algoCmd = new _pyCommand( text ); + algoType = algoCmd->GetResultValue(); + method = algoCmd->GetMethod(); + arg = algoCmd->GetArg(1); + if ( !algoType.IsEmpty() && !method.IsEmpty() ) + { + Handle(_pyAlgorithm) algo = new _pyAlgorithm( algoCmd ); + algo->SetConvMethodAndType( method, algoType ); + if ( !arg.IsEmpty() ) + algo->setCreationArg( 1, arg ); + + myType2Hyp[ algoType ] = algo; + break; + } + } + if ( algoType.IsEmpty() ) continue; + + LDOM_NodeList pyHypoNodeList = algoElem.getElementsByTagName( "hypo" ); + _AString hypType; + Handle( _pyHypothesis ) hyp; + for ( int iH = 0; iH < pyHypoNodeList.getLength(); ++iH ) + { + LDOM_Node pyHypoNode = pyHypoNodeList.item( iH ); + LDOM_Node textNode = pyHypoNode.getFirstChild(); + text = textNode.getNodeValue(); + Handle(_pyCommand) hypoCmd = new _pyCommand( text ); + hypType = hypoCmd->GetResultValue(); + method = hypoCmd->GetMethod(); + if ( !hypType.IsEmpty() && !method.IsEmpty() ) + { + map<_AString, Handle(_pyHypothesis)>::iterator type2hyp = myType2Hyp.find( hypType ); + if ( type2hyp == myType2Hyp.end() ) + hyp = new _pyHypothesis( hypoCmd ); + else + hyp = type2hyp->second; + hyp->SetConvMethodAndType( method, algoType ); + for ( int iArg = 1; iArg <= hypoCmd->GetNbArgs(); ++iArg ) + { + _pyCommand argCmd( hypoCmd->GetArg( iArg )); + _AString argMethod = argCmd.GetMethod(); + _AString argNbText = argCmd.GetArg( 1 ); + if ( argMethod.IsEmpty() && !argCmd.IsEmpty() ) + hyp->setCreationArg( 1, argCmd.GetString() ); // e.g. Parameters(smesh.SIMPLE) + else + hyp->AddArgMethod( argMethod, + argNbText.IsIntegerValue() ? argNbText.IntegerValue() : 1 ); + } + myType2Hyp[ hypType ] = hyp; + } + } + } + } } //================================================================================ /*! - * \brief Clear creatin command if no commands invoked + * \brief Returns a new hypothesis initialized according to the read information */ //================================================================================ -void _pySubMesh::Flush() +Handle(_pyHypothesis) +_pyHypothesisReader::GetHypothesis(const _AString& hypType, + const Handle(_pyCommand)& creationCmd) const { - if ( !myCmdCount ) // move to the end of all commands - theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() ); - else if ( !myCreator.IsNull() ) - // move to be just after creator - myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() ); + Handle(_pyHypothesis) resHyp, sampleHyp; + + map<_AString, Handle(_pyHypothesis)>::const_iterator type2hyp = myType2Hyp.find( hypType ); + if ( type2hyp != myType2Hyp.end() ) + sampleHyp = type2hyp->second; + + if ( sampleHyp.IsNull() ) + { + resHyp = new _pyHypothesis(creationCmd); + } + else + { + if ( sampleHyp->IsAlgo() ) + resHyp = new _pyAlgorithm( creationCmd ); + else + resHyp = new _pyHypothesis(creationCmd); + resHyp->Assign( sampleHyp, _pyID() ); + } + return resHyp; } diff --git a/src/SMESH_I/SMESH_2smeshpy.hxx b/src/SMESH_I/SMESH_2smeshpy.hxx index eac87deca..f92c285b4 100644 --- a/src/SMESH_I/SMESH_2smeshpy.hxx +++ b/src/SMESH_I/SMESH_2smeshpy.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_smesh.hxx // Created : Fri Nov 18 12:05:18 2005 // Author : Edward AGAPOV (eap) @@ -35,6 +36,10 @@ #include #include +#include + +#include +#include CORBA_CLIENT_HEADER(SALOMEDS) // =========================================================================================== /*! @@ -47,9 +52,6 @@ * * Everything here is for internal usage by SMESH_2smeshpy::ConvertScript() * declared in SMESH_PythonDump.hxx - * - * See comments to _pyHypothesis class to know how to assure convertion of a new - * type of hypothesis */ // =========================================================================================== @@ -68,19 +70,21 @@ class _pyMesh; class _pySubMesh; class _pyHypothesis; class _pyAlgorithm; -class _pyFilterManager; - -DEFINE_STANDARD_HANDLE (_pyCommand ,Standard_Transient); -DEFINE_STANDARD_HANDLE (_pyObject ,Standard_Transient); -DEFINE_STANDARD_HANDLE (_pyGen ,_pyObject); -DEFINE_STANDARD_HANDLE (_pyMesh ,_pyObject); -DEFINE_STANDARD_HANDLE (_pySubMesh ,_pyObject); -DEFINE_STANDARD_HANDLE (_pyMeshEditor,_pyObject); -DEFINE_STANDARD_HANDLE (_pyHypothesis,_pyObject); -DEFINE_STANDARD_HANDLE (_pyFilterManager,_pyObject); -DEFINE_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis); +class _pyHypothesisReader; + +DEFINE_STANDARD_HANDLE (_pyCommand ,Standard_Transient); +DEFINE_STANDARD_HANDLE (_pyObject ,Standard_Transient); +DEFINE_STANDARD_HANDLE (_pyHypothesisReader,Standard_Transient); +DEFINE_STANDARD_HANDLE (_pyGen ,_pyObject); +DEFINE_STANDARD_HANDLE (_pyMesh ,_pyObject); +DEFINE_STANDARD_HANDLE (_pySubMesh ,_pyObject); +DEFINE_STANDARD_HANDLE (_pyGroup ,_pySubMesh); +DEFINE_STANDARD_HANDLE (_pyMeshEditor ,_pyObject); +DEFINE_STANDARD_HANDLE (_pyHypothesis ,_pyObject); +DEFINE_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis); typedef TCollection_AsciiString _pyID; +typedef TCollection_AsciiString _AString; // =========================================================== /*! @@ -92,50 +96,54 @@ typedef TCollection_AsciiString _pyID; class _pyCommand: public Standard_Transient { int myOrderNb; //!< position within the script - TCollection_AsciiString myString; //!< command text - TCollection_AsciiString myRes, myObj, myMeth; //!< found parts of command + _AString myString; //!< command text + _AString myRes, myObj, myMeth; //!< found parts of command TColStd_SequenceOfAsciiString myArgs; //!< found arguments TColStd_SequenceOfInteger myBegPos; //!< where myRes, myObj, ... begin std::list< Handle(_pyCommand) > myDependentCmds; //!< commands that sould follow me in the script enum { UNKNOWN=-1, EMPTY=0, RESULT_IND, OBJECT_IND, METHOD_IND, ARG1_IND }; - int GetBegPos( int thePartIndex ); + int GetBegPos( int thePartIndex ); void SetBegPos( int thePartIndex, int thePosition ); - void SetPart( int thePartIndex, const TCollection_AsciiString& theNewPart, - TCollection_AsciiString& theOldPart); + void SetPart( int thePartIndex, const _AString& theNewPart, _AString& theOldPart); void FindAllArgs() { GetArg(1); } public: _pyCommand() {}; - _pyCommand( const TCollection_AsciiString& theString, int theNb ) + _pyCommand( const _AString& theString, int theNb=-1 ) : myString( theString ), myOrderNb( theNb ) {}; - TCollection_AsciiString & GetString() { return myString; } + _AString & GetString() { return myString; } int GetOrderNb() const { return myOrderNb; } void SetOrderNb( int theNb ) { myOrderNb = theNb; } + typedef void* TAddr; + TAddr GetAddress() const { return (void*) this; } int Length() { return myString.Length(); } - void Clear() { myString.Clear(); myBegPos.Clear(); } + void Clear() { myString.Clear(); myBegPos.Clear(); myArgs.Clear(); } bool IsEmpty() const { return myString.IsEmpty(); } - TCollection_AsciiString GetIndentation(); - const TCollection_AsciiString & GetResultValue(); + _AString GetIndentation(); + const _AString & GetResultValue(); const int GetNbResultValues(); - const TCollection_AsciiString & GetResultValue(int res); - const TCollection_AsciiString & GetObject(); - const TCollection_AsciiString & GetMethod(); - const TCollection_AsciiString & GetArg( int index ); + _AString GetResultValue(int res); + const _AString & GetObject(); + const _AString & GetMethod(); + const _AString & GetArg( int index ); int GetNbArgs() { FindAllArgs(); return myArgs.Length(); } - //Handle(TColStd_HSequenceOfAsciiString) GetArgs(); - void SetResultValue( const TCollection_AsciiString& theResult ) + bool MethodStartsFrom(const _AString& beg) + { GetMethod(); return ( myMeth.Location( beg, 1, myMeth.Length() ) == 1 ); } + void SetResultValue( const _AString& theResult ) { GetResultValue(); SetPart( RESULT_IND, theResult, myRes ); } - void SetObject(const TCollection_AsciiString& theObject) + void SetObject(const _AString& theObject) { GetObject(); SetPart( OBJECT_IND, theObject, myObj ); } - void SetMethod(const TCollection_AsciiString& theMethod) + void SetMethod(const _AString& theMethod) { GetMethod(); SetPart( METHOD_IND, theMethod, myMeth ); } - void SetArg( int index, const TCollection_AsciiString& theArg); + void SetArg( int index, const _AString& theArg); void RemoveArgs(); - static bool SkipSpaces( const TCollection_AsciiString & theSring, int & thePos ); - static TCollection_AsciiString GetWord( const TCollection_AsciiString & theSring, - int & theStartPos, const bool theForward, - const bool dotIsWord = false); + void Comment(); + static bool SkipSpaces( const _AString & theSring, int & thePos ); + static _AString GetWord( const _AString & theSring, int & theStartPos, + const bool theForward, const bool dotIsWord = false); + static bool IsStudyEntry( const _AString& str ); + static std::list< _pyID > GetStudyEntries( const _AString& str ); void AddDependantCmd( Handle(_pyCommand) cmd, bool prepend = false) { if (prepend) myDependentCmds.push_front( cmd ); else myDependentCmds.push_back( cmd ); } bool SetDependentCmdsAfter() const; @@ -147,27 +155,62 @@ public: // ------------------------------------------------------------------------------------- /*! - * \brief Root of all objects + * \brief Root of all objects. It counts calls of Process() */ // ------------------------------------------------------------------------------------- class _pyObject: public Standard_Transient { +protected: + _pyID myID; Handle(_pyCommand) myCreationCmd; + std::list< Handle(_pyCommand) > myProcessedCmds; + bool myIsPublished; + + void setID(const _pyID& theID); public: - _pyObject(const Handle(_pyCommand)& theCreationCmd): myCreationCmd(theCreationCmd) {} - const _pyID& GetID() { return myCreationCmd->GetResultValue(); } + _pyObject(const Handle(_pyCommand)& theCreationCmd, const _pyID& theID=_pyID()); + const _pyID& GetID() { return myID.IsEmpty() ? myCreationCmd->GetResultValue() : myID; } static _pyID FatherID(const _pyID & childID); const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; } - void SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; } + int GetNbCalls() const { return myProcessedCmds.size(); } + bool IsInStudy() const { return myIsPublished; } + virtual void SetRemovedFromStudy(const bool isRemoved) { myIsPublished = !isRemoved; } + void SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; } int GetCommandNb() { return myCreationCmd->GetOrderNb(); } - virtual void Process(const Handle(_pyCommand) & theCommand) = 0; + void AddProcessedCmd( const Handle(_pyCommand) & cmd ) + { if (myProcessedCmds.empty() || myProcessedCmds.back()!=cmd) myProcessedCmds.push_back( cmd );} + std::list< Handle(_pyCommand) >& GetProcessedCmds() { return myProcessedCmds; } + virtual void Process(const Handle(_pyCommand) & cmd) { AddProcessedCmd(cmd); } virtual void Flush() = 0; virtual const char* AccessorMethod() const; + virtual bool CanClear() { return !myIsPublished; } + virtual void ClearCommands(); + virtual void Free() {} DEFINE_STANDARD_RTTI (_pyObject) }; +// ------------------------------------------------------------------------------------- +/*! + * \brief Data used to restore cleared Compute() command of an exported mesh + * when an imported mesh is created + */ +// ------------------------------------------------------------------------------------- +struct ExportedMeshData +{ + Handle(_pyMesh) myMesh; + Handle(_pyCommand) myLastComputeCmd; + _AString myLastComputeCmdString; + ExportedMeshData() {} + ExportedMeshData( const Handle(_pyMesh)& mesh, Handle(_pyCommand) computeCmd): + myMesh( mesh ), myLastComputeCmd( computeCmd ) + { + if ( !myLastComputeCmd.IsNull()) + myLastComputeCmdString = myLastComputeCmd->GetString(); + } +}; + // ------------------------------------------------------------------------------------- /*! * \brief Class corresponding to SMESH_Gen. It holds info on existing @@ -178,25 +221,45 @@ class _pyGen: public _pyObject { public: _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, - Resource_DataMapOfAsciiStringAsciiString& theObjectNames); - //~_pyGen(); - Handle(_pyCommand) AddCommand( const TCollection_AsciiString& theCommand ); - void Process( const Handle(_pyCommand)& theCommand ); - void Flush(); - Handle(_pyHypothesis) FindHyp( const _pyID& theHypID ); - Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh, - const Handle(_pyHypothesis)& theHypothesis); - Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID ); + Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + SALOMEDS::Study_ptr& theStudy, + const bool theToKeepAllCommands); + Handle(_pyCommand) AddCommand( const _AString& theCommand ); void ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 ); void SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd ); void SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd ); Handle(_pyCommand)& GetLastCommand(); std::list< Handle(_pyCommand) >& GetCommands() { return myCommands; } + void PlaceSubmeshAfterItsCreation( Handle(_pyCommand) theCmdUsingSubmesh ) const; + + _pyID GenerateNewID( const _pyID& theID ); + void AddObject( Handle(_pyObject)& theObj ); + void SetProxyObject( const _pyID& theID, Handle(_pyObject)& theObj ); + Handle(_pyObject) FindObject( const _pyID& theObjID ) const; + Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID ); + Handle(_pyHypothesis) FindHyp( const _pyID& theHypID ); + Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh, + const Handle(_pyHypothesis)& theHypothesis); + void SetAccessorMethod(const _pyID& theID, const char* theMethod ); bool AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const; bool AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const; - const char* AccessorMethod() const; - _pyID GenerateNewID( const _pyID& theID ); + virtual const char* AccessorMethod() const; + + bool IsGeomObject(const _pyID& theObjID) const; + bool IsNotPublished(const _pyID& theObjID) const; + bool IsToKeepAllCommands() const { return myToKeepAllCommands; } + void AddExportedMesh(const _AString& file, const ExportedMeshData& mesh ) + { myFile2ExportedMesh[ file ] = mesh; } + ExportedMeshData& FindExportedMesh( const _AString& file ) + { return myFile2ExportedMesh[ file ]; } + + virtual void Process( const Handle(_pyCommand)& theCommand ); + virtual void Flush(); + virtual void ClearCommands(); + virtual void Free(); + + Handle( _pyHypothesisReader ) GetHypothesisReader() const; private: void setNeighbourCommand( Handle(_pyCommand)& theCmd, @@ -205,16 +268,20 @@ private: private: std::map< _pyID, Handle(_pyMesh) > myMeshes; - std::map< _pyID, Handle(_pySubMesh) > mySubMeshes; std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors; + std::map< _pyID, Handle(_pyObject) > myObjects; std::list< Handle(_pyHypothesis) > myHypos; std::list< Handle(_pyCommand) > myCommands; int myNbCommands; - bool myHasPattern; Resource_DataMapOfAsciiStringAsciiString& myID2AccessorMethod; Resource_DataMapOfAsciiStringAsciiString& myObjectNames; Handle(_pyCommand) myLastCommand; - Handle(_pyFilterManager) myFilterManager; + int myNbFilters; + bool myToKeepAllCommands; + SALOMEDS::Study_var myStudy; + int myGeomIDNb, myGeomIDIndex; + std::map< _AString, ExportedMeshData > myFile2ExportedMesh; + Handle( _pyHypothesisReader ) myHypReader; DEFINE_STANDARD_RTTI (_pyGen) }; @@ -228,22 +295,35 @@ private: class _pyMesh: public _pyObject { std::list< Handle(_pyHypothesis) > myHypos; - std::list< Handle(_pyCommand) > myAddHypCmds; - std::list< Handle(_pySubMesh) > mySubmeshes; - bool myHasEditor; + std::list< Handle(_pyCommand) > myAddHypCmds; + std::list< Handle(_pySubMesh) > mySubmeshes; + std::list< Handle(_pyGroup) > myGroups; + std::list< Handle(_pyMeshEditor)> myEditors; + //d::list< Handle(_pyMesh) > myFatherMeshes; // this mesh depends on + std::list< Handle(_pyMesh) > myChildMeshes; // depending on me + bool myGeomNotInStudy; + Handle(_pyCommand) myLastComputeCmd; public: _pyMesh(const Handle(_pyCommand) creationCmd); - _pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString & id); + _pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID & id); const _pyID& GetGeom() { return GetCreationCmd()->GetArg(1); } - void Process( const Handle(_pyCommand)& theCommand); - void Flush(); - const char* AccessorMethod() const { return _pyMesh_ACCESS_METHOD; } + void AddGroup( const Handle(_pyGroup)& g ) { myGroups.push_back( g ); } + void AddEditor( const Handle(_pyMeshEditor)& e ) { myEditors.push_back( e ); } + bool IsNotGeomPublished() { return myGeomNotInStudy; } + virtual void Process( const Handle(_pyCommand)& theCommand); + virtual void Flush(); + virtual void SetRemovedFromStudy(const bool isRemoved); + virtual bool CanClear(); + virtual void ClearCommands(); + virtual void Free() { /*myFatherMeshes.clear();*/ myChildMeshes.clear(); } + virtual const char* AccessorMethod() const { return _pyMesh_ACCESS_METHOD; } private: + void addFatherMesh( const Handle(_pyMesh)& mesh ); + void addFatherMesh( const _pyID& meshID ); static bool NeedMeshAccess( const Handle(_pyCommand)& theCommand ); static void AddMeshAccess( const Handle(_pyCommand)& theCommand ) { theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); } - //friend class _pyMeshEditor; DEFINE_STANDARD_RTTI (_pyMesh) }; #undef _pyMesh_ACCESS_METHOD @@ -255,12 +335,14 @@ private: // ------------------------------------------------------------------------------------- class _pyMeshEditor: public _pyObject { - _pyID myMesh; - TCollection_AsciiString myCreationCmdStr; + _pyID myMesh; + _AString myCreationCmdStr; public: _pyMeshEditor(const Handle(_pyCommand)& theCreationCmd); - void Process( const Handle(_pyCommand)& theCommand); + _pyID GetMesh() const { return myMesh; } + virtual void Process( const Handle(_pyCommand)& theCommand); virtual void Flush() {} + virtual bool CanClear(); DEFINE_STANDARD_RTTI (_pyMesh) }; @@ -268,64 +350,80 @@ public: // ------------------------------------------------------------------------------------- /*! * \brief Root class for hypothesis - * - * HOWTO assure convertion of a new type of hypothesis - * In _pyHypothesis::NewHypothesis(): - * 1. add a case for the name of the new hypothesis - * 2. use SetConvMethodAndType() to set - * . for algo: algorithm name and method of Mesh creating the algo - * . for hypo: name of the algorithm and method creating the hypothesis - * 3. append to myArgMethods interface methods setting param values in the - * order they are used when creation method is called. If arguments of - * the creation method can't be easily got from calls of hypothesis methods, you are - * to derive a specific class from _pyHypothesis that would redefine Process(), - * see _pyComplexParamHypo for example */ // ------------------------------------------------------------------------------------- class _pyHypothesis: public _pyObject { + friend class _pyHypothesisReader; protected: bool myIsAlgo, myIsWrapped; _pyID myGeom, myMesh; - // a hypothesis can be used and created by different algos by different methods - std::map myType2CreationMethod; - //TCollection_AsciiString myCreationMethod, myType; - TColStd_SequenceOfAsciiString myArgs; // creation arguments - TColStd_SequenceOfAsciiString myArgMethods; // hypo methods setting myArgs - TColStd_SequenceOfInteger myNbArgsByMethod; // nb args set by each method - std::list myArgCommands; - std::list myUnknownCommands; + struct CreationMethod { + _AString myMethod; // method of algo or mesh creating a hyp + // myArgNb(i)-th arg of myArgMethods(i) of hyp becomes an i-th arg of myAlgoMethod + std::vector<_AString> myArgMethods; + std::vector myArgNb; // arg nb countered from 1 + std::vector<_AString> myArgs; // creation arguments + }; + void setCreationArg( const int argNb, const _AString& arg ); + // a hypothesis can be created by different algos by different methods + typedef std::map<_AString, CreationMethod > TType2CrMethod; + TType2CrMethod myAlgoType2CreationMethod; + CreationMethod* myCurCrMethod; // used for adding to myAlgoType2CreationMethod + std::list myArgCommands; + std::list myUnusedCommands; + std::list myReferredObjs; + // maps used to clear commands setting parameters if result of setting is + // discared (e.g. by mesh.Clear()) + std::map<_AString, std::list > myMeth2Commands; + std::map< _pyCommand::TAddr, std::list > myComputeAddr2Cmds; + std::list myComputeCmds; + void rememberCmdOfParameter( const Handle(_pyCommand) & cmd ); + bool isCmdUsedForCompute( const Handle(_pyCommand) & cmd, + _pyCommand::TAddr avoidComputeAddr=NULL ) const; public: _pyHypothesis(const Handle(_pyCommand)& theCreationCmd); - void SetConvMethodAndType(const char* creationMethod, const char* type) - { myType2CreationMethod[ (char*)type ] = (char*)creationMethod; } - void AddArgMethod(const char* method, const int nbArgs = 1) - { myArgMethods.Append( (char*)method ); myNbArgsByMethod.Append( nbArgs ); } - const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; } + void SetConvMethodAndType(const _AString& creationMethod, const _AString& type) + { myCurCrMethod = &myAlgoType2CreationMethod[ type ]; + myCurCrMethod->myMethod = creationMethod; } + void AddArgMethod(const _AString& method, const int argNb = 1) + { myCurCrMethod->myArgMethods.push_back( method ); + myCurCrMethod->myArgNb.push_back( argNb ); } + //const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; } const std::list& GetArgCommands() const { return myArgCommands; } void ClearAllCommands(); virtual bool IsAlgo() const { return myIsAlgo; } - bool IsValid() const { return !myType2CreationMethod.empty(); } + bool IsValid() const { return !myAlgoType2CreationMethod.empty(); } bool IsWrapped() const { return myIsWrapped; } const _pyID & GetGeom() const { return myGeom; } void SetMesh( const _pyID& theMeshId) { if ( myMesh.IsEmpty() ) myMesh = theMeshId; } const _pyID & GetMesh() const { return myMesh; } - const TCollection_AsciiString& GetAlgoType() const - { return myType2CreationMethod.begin()->first; } - const TCollection_AsciiString& GetAlgoCreationMethod() const - { return myType2CreationMethod.begin()->second; } - bool CanBeCreatedBy(const TCollection_AsciiString& algoType ) const - { return myType2CreationMethod.find( algoType ) != myType2CreationMethod.end(); } - const TCollection_AsciiString& GetCreationMethod(const TCollection_AsciiString& algoType) const - { return myType2CreationMethod.find( algoType )->second; } - virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped && myMesh == theMesh; } + const _AString& GetAlgoType() const + { return myAlgoType2CreationMethod.begin()->first; } + const _AString& GetAlgoCreationMethod() const + { return myAlgoType2CreationMethod.begin()->second.myMethod; } + bool CanBeCreatedBy(const _AString& algoType ) const + { return myAlgoType2CreationMethod.find( algoType ) != myAlgoType2CreationMethod.end(); } + const _AString& GetCreationMethod(const _AString& algoType) + { return ( myCurCrMethod = & myAlgoType2CreationMethod[ algoType ])->myMethod; } + static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd); + + virtual bool IsWrappable(const _pyID& theMesh) const; virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, const _pyID& theMesh); - static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd); - void Process( const Handle(_pyCommand)& theCommand); - void Flush(); + virtual void Process( const Handle(_pyCommand)& theCommand); + virtual void Flush(); + virtual void Free() { myReferredObjs.clear(); } virtual void Assign( const Handle(_pyHypothesis)& theOther, - const _pyID& theMesh ); + const _pyID& theMesh ); + virtual bool CanClear(); + virtual void ClearCommands(); + virtual bool GetReferredMeshesAndGeom( std::list< Handle(_pyMesh) >& meshes ); + + void MeshComputed ( const Handle(_pyCommand)& theComputeCommand ); + void ComputeDiscarded( const Handle(_pyCommand)& theComputeCommand ); + //void ComputeSaved ( const Handle(_pyCommand)& theComputeCommand ); + DEFINE_STANDARD_RTTI (_pyHypothesis) }; @@ -341,7 +439,7 @@ public: _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd); virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, const _pyID& theMesh); - const char* AccessorMethod() const { return "GetAlgorithm()"; } + virtual const char* AccessorMethod() const { return "GetAlgorithm()"; } virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped; } DEFINE_STANDARD_RTTI (_pyAlgorithm) @@ -356,7 +454,8 @@ class _pyComplexParamHypo: public _pyHypothesis { public: _pyComplexParamHypo(const Handle(_pyCommand)& theCreationCmd): _pyHypothesis(theCreationCmd) {} - void Process( const Handle(_pyCommand)& theCommand); + virtual void Process( const Handle(_pyCommand)& theCommand); + virtual void Flush(); DEFINE_STANDARD_RTTI (_pyComplexParamHypo) }; @@ -370,13 +469,15 @@ DEFINE_STANDARD_HANDLE (_pyComplexParamHypo, _pyHypothesis); class _pyLayerDistributionHypo: public _pyHypothesis { Handle(_pyHypothesis) my1dHyp; + _AString myAlgoMethod; public: - _pyLayerDistributionHypo(const Handle(_pyCommand)& theCreationCmd): - _pyHypothesis(theCreationCmd) {} - void Process( const Handle(_pyCommand)& theCommand); - void Flush(); - bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, - const _pyID& theMesh); + _pyLayerDistributionHypo(const Handle(_pyCommand)& theCreationCmd, const char* algoMethod): + _pyHypothesis(theCreationCmd), myAlgoMethod((char*)algoMethod) {} + virtual void Process( const Handle(_pyCommand)& theCommand); + virtual void Flush(); + virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd, + const _pyID& theMesh); + virtual void Free() { my1dHyp.Nullify(); } DEFINE_STANDARD_RTTI (_pyLayerDistributionHypo) }; @@ -416,20 +517,19 @@ DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis); // ------------------------------------------------------------------------------------- /*! - * \brief FilterManager creates only if at least one command invoked + * \brief SelfEraser erases creation command if no more it's commands invoked */ // ------------------------------------------------------------------------------------- -class _pyFilterManager: public _pyObject +class _pySelfEraser: public _pyObject { public: - _pyFilterManager(const Handle(_pyCommand)& theCreationCmd); - void Process( const Handle(_pyCommand)& theCommand); + _pySelfEraser(const Handle(_pyCommand)& theCreationCmd) + :_pyObject(theCreationCmd) { myIsPublished = true; } virtual void Flush(); - DEFINE_STANDARD_RTTI (_pyFilterManager) -private: - int myCmdCount; + DEFINE_STANDARD_RTTI (_pySelfEraser) }; +DEFINE_STANDARD_HANDLE (_pySelfEraser, _pyObject); // ------------------------------------------------------------------------------------- /*! @@ -438,16 +538,72 @@ private: // ------------------------------------------------------------------------------------- class _pySubMesh: public _pyObject { + Handle(_pyObject) myCreator; + Handle(_pyMesh) myMesh; public: _pySubMesh(const Handle(_pyCommand)& theCreationCmd); - void Process( const Handle(_pyCommand)& theCommand); + virtual void Process( const Handle(_pyCommand)& theCommand); virtual void Flush(); + virtual Handle(_pyMesh) GetMesh() { return myMesh; } + virtual void Free() { myCreator.Nullify(); myMesh.Nullify(); } void SetCreator( const Handle(_pyObject)& theCreator ) { myCreator = theCreator; } + static bool CanBeArgOfMethod(const _AString& theMethodName); - DEFINE_STANDARD_RTTI (_pyFilterManager) -private: - int myCmdCount; - Handle(_pyObject) myCreator; + DEFINE_STANDARD_RTTI (_pySubMesh) +}; +// ------------------------------------------------------------------------------------- +/*! + * \brief A filter sets a human readable name to self + */ +// ------------------------------------------------------------------------------------- +class _pyFilter: public _pyObject +{ + _pyID myNewID, myMesh; + std::list< Handle(_pyObject) > myUsers; +public: + _pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID=""); + void AddUser( const Handle(_pyObject)& user) { myUsers.push_back( user ); } + virtual void Process( const Handle(_pyCommand)& theCommand); + virtual void Flush(); + virtual bool CanClear(); + virtual void Free() { myUsers.clear(); } + const _pyID& GetNewID() const { return myNewID; } + + DEFINE_STANDARD_RTTI (_pyFilter) +}; +DEFINE_STANDARD_HANDLE (_pyFilter, _pyObject); + +// ------------------------------------------------------------------------------------- +/*! + * \brief To convert creation of a group by filter + */ +// ------------------------------------------------------------------------------------- +class _pyGroup: public _pySubMesh +{ + Handle(_pyFilter) myFilter; + bool myCanClearCreationCmd; +public: + _pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id=_pyID()); + virtual void Process( const Handle(_pyCommand)& theCommand); + virtual void Flush(); + virtual void Free() { myFilter.Nullify(); } + + DEFINE_STANDARD_RTTI (_pyGroup) +}; + +// ------------------------------------------------------------------------------------- +/*! + * \brief Class reading _pyHypothesis'es from resource files of mesher Plugins + */ +// ------------------------------------------------------------------------------------- +class _pyHypothesisReader: public Standard_Transient +{ + std::map<_AString, Handle(_pyHypothesis)> myType2Hyp; +public: + _pyHypothesisReader(); + Handle(_pyHypothesis) GetHypothesis(const _AString& hypType, + const Handle(_pyCommand)& creationCmd) const; + DEFINE_STANDARD_RTTI (_pyHypothesisReader) }; #endif diff --git a/src/SMESH_I/SMESH_3D_Algo_i.cxx b/src/SMESH_I/SMESH_3D_Algo_i.cxx index 8aa242ba6..9a73a538f 100644 --- a/src/SMESH_I/SMESH_3D_Algo_i.cxx +++ b/src/SMESH_I/SMESH_3D_Algo_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_3D_Algo_i.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_3D_Algo_i.hxx b/src/SMESH_I/SMESH_3D_Algo_i.hxx index 4352e7296..d798b9e41 100644 --- a/src/SMESH_I/SMESH_3D_Algo_i.hxx +++ b/src/SMESH_I/SMESH_3D_Algo_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_3D_Algo_i.hxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_Algo_i.cxx b/src/SMESH_I/SMESH_Algo_i.cxx index e567a15d6..13caf98e0 100644 --- a/src/SMESH_I/SMESH_Algo_i.cxx +++ b/src/SMESH_I/SMESH_Algo_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Algo_i.cxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_Algo_i.hxx b/src/SMESH_I/SMESH_Algo_i.hxx index cfcfc5347..34491582d 100644 --- a/src/SMESH_I/SMESH_Algo_i.hxx +++ b/src/SMESH_I/SMESH_Algo_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Algo_i.hxx // Author : Paul RASCLE, EDF diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx index ad409b786..0544cb091 100644 --- a/src/SMESH_I/SMESH_DumpPython.cxx +++ b/src/SMESH_I/SMESH_DumpPython.cxx @@ -1,30 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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_Gen_i_DumpPython.cxx -// Created : Thu Mar 24 17:17:59 2005 -// Author : Julia DOROVSKIKH -// Module : SMESH -// $Header : $ +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESH_DumpPython.cxx +// Created : Thu Mar 24 17:17:59 2005 +// Author : Julia DOROVSKIKH +// Module : SMESH + #include "SMESH_PythonDump.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Filter_i.hxx" @@ -33,6 +32,7 @@ #include #include +#include #ifdef _DEBUG_ @@ -51,8 +51,17 @@ namespace SMESH size_t TPythonDump::myCounter = 0; + TVar::TVar(CORBA::Double value):myVals(1) { myVals[0] = SMESH_Comment(value); } + TVar::TVar(CORBA::Long value):myVals(1) { myVals[0] = SMESH_Comment(value); } + TVar::TVar(CORBA::Short value):myVals(1) { myVals[0] = SMESH_Comment(value); } + TVar::TVar(const SMESH::double_array& value):myVals(value.length()) + { + for ( size_t i = 0; i < value.length(); i++) + myVals[i] = SMESH_Comment(value[i]); + } + TPythonDump:: - TPythonDump() + TPythonDump():myVarsCounter(0) { ++myCounter; } @@ -65,48 +74,82 @@ namespace SMESH TCollection_AsciiString aCollection(Standard_CString(aString.c_str())); SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); if(!aStudy->_is_nil() && !aCollection.IsEmpty()){ - aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection); - if(MYDEBUG) MESSAGE(aString); + aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection); + if(MYDEBUG) MESSAGE(aString); + aSMESHGen->UpdateParameters(""); // prevent misuse of already treated variables } } } - TPythonDump& + TPythonDump& //!< to store a variable value + TPythonDump:: + operator<<(const TVar& theVarValue) + { + if ( theVarValue.myVals.empty() ) return *this; + + const std::vector< std::string >& varNames = SMESH_Gen_i::GetSMESHGen()->GetLastParameters(); + if ( theVarValue.myVals.size() > 1 ) + { + myStream << "[ "; + for ( size_t i = 1; i <= theVarValue.myVals.size(); ++i ) + { + if ( myVarsCounter < varNames.size() && !varNames[ myVarsCounter ].empty() ) + myStream << TVar::Quote() << varNames[ myVarsCounter ] << TVar::Quote(); + else + myStream << theVarValue.myVals[i-1]; + if ( i < theVarValue.myVals.size() ) + myStream << ", "; + ++myVarsCounter; + } + myStream << " ]"; + } + else + { + if ( myVarsCounter < varNames.size() && !varNames[ myVarsCounter ].empty() ) + myStream << TVar::Quote() << varNames[ myVarsCounter ] << TVar::Quote(); + else + myStream << theVarValue.myVals[0]; + ++myVarsCounter; + } + return *this; + } + + TPythonDump& TPythonDump:: operator<<(long int theArg){ myStream< - void DumpArray(const TArray& theArray, std::ostringstream & theStream) + void DumpArray(const TArray& theArray, TPythonDump & theStream) { theStream << "[ "; for (int i = 1; i <= theArray.length(); i++) { @@ -141,21 +209,34 @@ namespace SMESH theStream << " ]"; } - TPythonDump& + TPythonDump& TPythonDump::operator<<(const SMESH::long_array& theArg) { - DumpArray( theArg, myStream ); + DumpArray( theArg, *this ); return *this; } - TPythonDump& + TPythonDump& TPythonDump::operator<<(const SMESH::double_array& theArg) { - DumpArray( theArg, myStream ); + DumpArray( theArg, *this ); return *this; } - TPythonDump& + TPythonDump& + TPythonDump::operator<<(const SMESH::string_array& theArray) + { + myStream << "[ "; + for (int i = 1; i <= theArray.length(); i++) { + myStream << "'" << theArray[i-1] << "'"; + if ( i < theArray.length() ) + myStream << ", "; + } + myStream << " ]"; + return *this; + } + + TPythonDump& TPythonDump:: operator<<(SALOMEDS::SObject_ptr aSObject) { @@ -166,15 +247,16 @@ namespace SMESH return *this; } - TPythonDump& + TPythonDump& TPythonDump:: operator<<(CORBA::Object_ptr theArg) { SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg); if(!aSObject->_is_nil()) { - myStream << aSObject->GetID(); + CORBA::String_var id = aSObject->GetID(); + myStream << id; } else if ( !CORBA::is_nil(theArg)) { if ( aSMESHGen->CanPublishInStudy( theArg )) // not published SMESH object myStream << "smeshObj_" << size_t(theArg); @@ -186,7 +268,44 @@ namespace SMESH return *this; } - TPythonDump& + TPythonDump& + TPythonDump:: + operator<<(SMESH::SMESH_Hypothesis_ptr theArg) + { + SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg); + if(aSObject->_is_nil() && !CORBA::is_nil(theArg)) + myStream << "hyp_" << theArg->GetId(); + else + *this << CORBA::Object_ptr( theArg ); + return *this; + } + + TPythonDump& + TPythonDump:: + operator<<(SMESH::SMESH_IDSource_ptr theArg) + { + if ( CORBA::is_nil( theArg ) ) + return *this << "None"; + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); + SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg); + if(!aSObject->_is_nil()) + return *this << aSObject; + if ( SMESH::Filter_i* filter = SMESH::DownCast( theArg )) + return *this << filter; + SMESH::SMESH_Mesh_var mesh = theArg->GetMesh(); + if ( !theArg->_is_equivalent( mesh )) + { + SMESH::long_array_var anElementsId = theArg->GetIDs(); + SMESH::array_of_ElementType_var types = theArg->GetTypes(); + SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL; + return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")"; + } + return *this; + } + + TPythonDump& TPythonDump:: operator<<(SMESH::FilterLibrary_i* theArg) { @@ -194,7 +313,7 @@ namespace SMESH return *this; } - TPythonDump& + TPythonDump& TPythonDump:: operator<<(SMESH::FilterManager_i* theArg) { @@ -202,7 +321,7 @@ namespace SMESH return *this; } - TPythonDump& + TPythonDump& TPythonDump:: operator<<(SMESH::Filter_i* theArg) { @@ -210,47 +329,69 @@ namespace SMESH return *this; } - TPythonDump& + TPythonDump& TPythonDump:: operator<<(SMESH::Functor_i* theArg) { if ( theArg ) { FunctorType aFunctorType = theArg->GetFunctorType(); switch(aFunctorType){ - case FT_AspectRatio: myStream<< "anAspectRatio"; break; - case FT_AspectRatio3D: myStream<< "anAspectRatio3D"; break; - case FT_Warping: myStream<< "aWarping"; break; - case FT_MinimumAngle: myStream<< "aMinimumAngle"; break; - case FT_Taper: myStream<< "aTaper"; break; - case FT_Skew: myStream<< "aSkew"; break; - case FT_Area: myStream<< "aArea"; break; - case FT_FreeBorders: myStream<< "aFreeBorders"; break; - case FT_FreeEdges: myStream<< "aFreeEdges"; break; - case FT_FreeNodes: myStream<< "aFreeNodes"; break; - case FT_MultiConnection: myStream<< "aMultiConnection"; break; - case FT_MultiConnection2D:myStream<< "aMultiConnection2D";break; - case FT_Length: myStream<< "aLength"; break; - case FT_Length2D: myStream<< "aLength"; break; - case FT_BelongToGeom: myStream<< "aBelongToGeom"; break; - case FT_BelongToPlane: myStream<< "aBelongToPlane"; break; - case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break; - case FT_BelongToGenSurface:myStream<<"aBelongToGenSurface";break; - case FT_LyingOnGeom: myStream<< "aLyingOnGeom"; break; - case FT_RangeOfIds: myStream<< "aRangeOfIds"; break; - case FT_BadOrientedVolume:myStream<< "aBadOrientedVolume";break; - case FT_LessThan: myStream<< "aLessThan"; break; - case FT_MoreThan: myStream<< "aMoreThan"; break; - case FT_EqualTo: myStream<< "anEqualTo"; break; - case FT_LogicalNOT: myStream<< "aLogicalNOT"; break; - case FT_LogicalAND: myStream<< "aLogicalAND"; break; - case FT_LogicalOR: myStream<< "aLogicalOR"; break; - case FT_Undefined: myStream<< "anUndefined"; break; + case FT_AspectRatio: myStream<< "anAspectRatio"; break; + case FT_AspectRatio3D: myStream<< "anAspectRatio3D"; break; + case FT_Warping: myStream<< "aWarping"; break; + case FT_MinimumAngle: myStream<< "aMinimumAngle"; break; + case FT_Taper: myStream<< "aTaper"; break; + case FT_Skew: myStream<< "aSkew"; break; + case FT_Area: myStream<< "aArea"; break; + case FT_Volume3D: myStream<< "aVolume3D"; break; + case FT_MaxElementLength2D: myStream<< "aMaxElementLength2D"; break; + case FT_MaxElementLength3D: myStream<< "aMaxElementLength3D"; break; + case FT_FreeBorders: myStream<< "aFreeBorders"; break; + case FT_FreeEdges: myStream<< "aFreeEdges"; break; + case FT_FreeNodes: myStream<< "aFreeNodes"; break; + case FT_FreeFaces: myStream<< "aFreeFaces"; break; + case FT_MultiConnection: myStream<< "aMultiConnection"; break; + case FT_MultiConnection2D: myStream<< "aMultiConnection2D"; break; + case FT_Length: myStream<< "aLength"; break; + case FT_Length2D: myStream<< "aLength2D"; break; + case FT_BelongToGeom: myStream<< "aBelongToGeom"; break; + case FT_BelongToPlane: myStream<< "aBelongToPlane"; break; + case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break; + case FT_BelongToGenSurface: myStream<< "aBelongToGenSurface"; break; + case FT_LyingOnGeom: myStream<< "aLyingOnGeom"; break; + case FT_CoplanarFaces: myStream<< "aCoplanarFaces"; break; + case FT_RangeOfIds: myStream<< "aRangeOfIds"; break; + case FT_BadOrientedVolume: myStream<< "aBadOrientedVolume"; break; + case FT_BareBorderVolume: myStream<< "aBareBorderVolume"; break; + case FT_BareBorderFace: myStream<< "aBareBorderFace"; break; + case FT_OverConstrainedVolume: myStream<< "aOverConstrainedVolume"; break; + case FT_OverConstrainedFace: myStream<< "aOverConstrainedFace"; break; + case FT_LinearOrQuadratic: myStream<< "aLinearOrQuadratic"; break; + case FT_GroupColor: myStream<< "aGroupColor"; break; + case FT_ElemGeomType: myStream<< "anElemGeomType"; break; + case FT_LessThan: myStream<< "aLessThan"; break; + case FT_MoreThan: myStream<< "aMoreThan"; break; + case FT_EqualTo: myStream<< "anEqualTo"; break; + case FT_LogicalNOT: myStream<< "aLogicalNOT"; break; + case FT_LogicalAND: myStream<< "aLogicalAND"; break; + case FT_LogicalOR: myStream<< "aLogicalOR"; break; + case FT_Undefined: + default: myStream<< "anUndefined"; break; } myStream<length() > 0 ) { - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); - myStream << "["; - int aListLen = theList->length(); - for(int i = 0 ; i < aListLen; i++){ - SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,(*theList)[i]); - if(!aSObject->_is_nil()) { - myStream << aSObject->GetID(); - i < (aListLen - 1) ? myStream<<", " : myStream<<"]"; - } - - } - } + TPythonDump& TPythonDump::operator<<(const SMESH::PointStruct & P) + { + *this << "SMESH.PointStruct ( " + << TVar( P.x ) << ", " + << TVar( P.y ) << ", " + << TVar( P.z ) << " )"; + return *this; + } + + TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups& theList) + { + DumpArray( theList, *this ); + return *this; + } + TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups * theList) + { + DumpArray( *theList, *this ); + return *this; + } + TPythonDump& TPythonDump::operator<<(const SMESH::ListOfIDSources& theList) + { + DumpArray( theList, *this ); return *this; } @@ -322,10 +470,10 @@ namespace SMESH //================================================================================ /*! - * \brief Return marker of long string literal beginning - * \param type - a name of functionality producing the string literal - * \retval TCollection_AsciiString - the marker string to be written into - * a raw python script + * \brief Return marker of long string literal beginning + * \param type - a name of functionality producing the string literal + * \retval TCollection_AsciiString - the marker string to be written into + * a raw python script */ //================================================================================ @@ -359,7 +507,7 @@ namespace SMESH * \param theLongString - the retrieved literal * \param theStringType - a name of functionality produced the literal * \retval bool - true if a string literal found - * + * * The literal is removed from theText; theFrom points position right after * the removed literal */ @@ -413,11 +561,31 @@ namespace SMESH } //======================================================================= -//function : DumpPython +//function : RemoveTabulation //purpose : //======================================================================= +void RemoveTabulation( TCollection_AsciiString& theScript ) +{ + std::string aString( theScript.ToCString() ); + std::string::size_type aPos = 0; + while( aPos < aString.length() ) + { + aPos = aString.find( "\n\t", aPos ); + if( aPos == std::string::npos ) + break; + aString.replace( aPos, 2, "\n" ); + aPos++; + } + theScript = aString.c_str(); +} + +//======================================================================= +//function : DumpPython +//purpose : +//======================================================================= Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy, CORBA::Boolean isPublished, + CORBA::Boolean isMultiFile, CORBA::Boolean& isValidScript) { SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy); @@ -456,22 +624,21 @@ Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy, TCollection_AsciiString aSavedTrace (oldValue); // Add trace of API methods calls and replace study entries by names - TCollection_AsciiString aScript = - "### This file is generated by SALOME automatically by dump python functionality of SMESH component\n\n"; - aScript += DumpPython_impl(aStudy, aMap, aMapNames, - isPublished, isValidScript, aSavedTrace); + TCollection_AsciiString aScript; + aScript += DumpPython_impl(aStudy, aMap, aMapNames, isPublished, isMultiFile, + myIsHistoricalPythonDump, isValidScript, aSavedTrace); - int aLen = aScript.Length(); + int aLen = aScript.Length(); unsigned char* aBuffer = new unsigned char[aLen+1]; strcpy((char*)aBuffer, aScript.ToCString()); CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer; - Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1); + Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1); bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen); isValidScript = isValidScript && !hasNotPublishedObjects; - return aStreamFile._retn(); + return aStreamFile._retn(); } //============================================================================= @@ -502,7 +669,7 @@ void SMESH_Gen_i::RemoveLastFromPythonScript (int theStudyID) //======================================================================= //function : SavePython -//purpose : +//purpose : //======================================================================= void SMESH_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy) { @@ -555,11 +722,11 @@ Handle(TColStd_HSequenceOfInteger) FindEntries (TCollection_AsciiString& theStri int c = (int)arr[i]; j = i+1; if ( isdigit( c )) { //Is digit? - + isFound = Standard_False; while((j < aLen) && ( isdigit(c) || c == ':' )) { //Check if it is an entry - c = (int)arr[j++]; - if(c == ':') isFound = Standard_True; + c = (int)arr[j++]; + if(c == ':') isFound = Standard_True; } if (isFound) { @@ -595,20 +762,28 @@ namespace { const TCollection_AsciiString allowedChars = "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_"; bool isValidName = true; - int p=1; // replace not allowed chars with underscore + int nbUnderscore = 0; + int p=1; // replace not allowed chars by underscore while (p <= aName.Length() && (p = aName.FirstLocationNotInSet(allowedChars, p, aName.Length()))) { if ( p == 1 || p == aName.Length() || aName.Value(p-1) == '_') - aName.Remove( p, 1 ); // remove double _ and from the start and the end + aName.Remove( p, 1 ); // remove double _ from the start and the end else - aName.SetValue(p, '_'); + aName.SetValue(p, '_'), nbUnderscore++; isValidName = false; } if ( aName.IsIntegerValue() ) { // aName must not start with a digit aName.Insert( 1, 'a' ); isValidName = false; } + // shorten names like CartesianParameters3D_400_400_400_1000000_1 + if ( aName.Length() > 20 && nbUnderscore > 2 ) + { + p = aName.Location( "_", 20, aName.Length()); + if ( p > 1 ) + aName.Trunc( p-1 ); + } return isValidName; } } @@ -619,10 +794,12 @@ namespace { */ //============================================================================= TCollection_AsciiString SMESH_Gen_i::DumpPython_impl - (SALOMEDS::Study_ptr theStudy, + (SALOMEDS::Study_ptr theStudy, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, Resource_DataMapOfAsciiStringAsciiString& theNames, - bool isPublished, + bool isPublished, + bool isMultiFile, + bool isHistoricalDump, bool& aValidScript, const TCollection_AsciiString& theSavedTrace) { @@ -634,8 +811,11 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl TCollection_AsciiString anOldGen( SMESH::TPythonDump::SMESHGenName() ); TCollection_AsciiString aScript; - aScript = "def RebuildData(theStudy):\n\t"; + if( isMultiFile ) + aScript += "def RebuildData(theStudy):"; + aScript += "\n\t"; aScript += helper + "aFilterManager = " + aSMESHGen + ".CreateFilterManager()\n\t"; + aScript += helper + "aMeasurements = " + aSMESHGen + ".CreateMeasurements()\n\t"; if ( isPublished ) aScript += aSMESHGen + ".SetCurrentStudy(theStudy)"; else @@ -687,13 +867,22 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl // Some objects are wrapped with python classes and // Resource_DataMapOfAsciiStringAsciiString holds methods returning wrapped objects Resource_DataMapOfAsciiStringAsciiString anEntry2AccessorMethod; - aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod, theObjectNames ); + if ( !getenv("NO_2smeshpy_conversion")) + aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod, + theObjectNames, theStudy, isHistoricalDump ); + + // Replace characters used instead of quote marks to quote notebook variables + { + int pos = 1; + while (( pos = aScript.Location( 1, SMESH::TVar::Quote(), pos, aScript.Length() ))) + aScript.SetValue( pos, '"' ); + } // Find entries to be replaced by names Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript); Standard_Integer aLen = aSeq->Length(); - if (aLen == 0) + if (aLen == 0 && isMultiFile) return aScript; // Replace entries by the names @@ -703,7 +892,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl Standard_Integer objectCounter = 0, aStart = 1, aScriptLength = aScript.Length(); TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("smeshObj_"); - // Collect names of GEOM objects to exclude same names for SMESH objects + // Collect names of GEOM objects to exclude same names of SMESH objects GEOM::string_array_var aGeomNames = geom->GetAllDumpNames(); int ign = 0, nbgn = aGeomNames->length(); for (; ign < nbgn; ign++) { @@ -757,67 +946,23 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl } // set initial part of aSript - TCollection_AsciiString initPart = "import salome, SMESH\n"; - initPart += helper + "import " + aSmeshpy + "\n\n"; - if ( importGeom ) + TCollection_AsciiString initPart = "import "; + if ( isMultiFile ) + initPart += helper + "salome, "; + initPart += aSmeshpy + ", SMESH, SALOMEDS\n"; + if ( importGeom && isMultiFile ) { - initPart += ("## import GEOM dump file ## \n" + initPart += ("\n## import GEOM dump file ## \n" "import string, os, sys, re\n" "sys.path.insert( 0, os.path.dirname(__file__) )\n" - "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n\n"); + "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n"); } anUpdatedScript.Insert ( 1, initPart ); // add final part of aScript - if (aSeq->Value(aLen) < aScriptLength) + if (aLen && aSeq->Value(aLen) < aScriptLength) anUpdatedScript += aScript.SubString(aSeq->Value(aLen) + 1, aScriptLength); - - //SMESH_Gen_i* aSMESHGenI = SMESH_Gen_i::GetSMESHGen(); - if( !CORBA::is_nil(theStudy) ) - { - SALOMEDS::SObject_var aComp = theStudy->FindComponent(ComponentDataType()); - if( !CORBA::is_nil(aComp) ) - { - SALOMEDS::ChildIterator_var Itr = theStudy->NewChildIterator(aComp); - for( Itr->InitEx(true); Itr->More(); Itr->Next() ) - { - SALOMEDS::SObject_var aSObj = Itr->Value(); - CORBA::String_var aName = aSObj->GetName(); - - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH_Gen_i::SObjectToObject( aSObj ) ); - if( !CORBA::is_nil(aMesh) ) - { - bool isAutoColor = aMesh->GetAutoColor(); - if( isAutoColor ) - { - anUpdatedScript += "\n\t"; - anUpdatedScript += (char*)aName.in(); - anUpdatedScript += ".SetAutoColor(1)"; - } - } - - SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH_Gen_i::SObjectToObject( aSObj ) ); - if( !CORBA::is_nil(aGroup) ) - { - SALOMEDS::Color aColor = aGroup->GetColor(); - if ( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ) - { - anUpdatedScript += "\n\t"; - anUpdatedScript += (char*)aName.in(); - anUpdatedScript += ".SetColor(SALOMEDS.Color("; - anUpdatedScript += aColor.R; - anUpdatedScript += ","; - anUpdatedScript += aColor.G; - anUpdatedScript += ","; - anUpdatedScript += aColor.B; - anUpdatedScript += "))"; - } - } - } - } - } - // Remove removed objects if ( seqRemoved.Length() > 0 ) { anUpdatedScript += "\n\t## some objects were removed"; @@ -859,8 +1004,10 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl anUpdatedScript += helper + ", '" + aGUIName + "')"; } } - anUpdatedScript += "\n\tif salome.sg.hasDesktop():"; - anUpdatedScript += "\n\t\tsalome.sg.updateObjBrowser(0)"; + + // Issue 0021249: removed (a similar block is dumped by SALOMEDSImpl_Study) + //anUpdatedScript += "\n\tif salome.sg.hasDesktop():"; + //anUpdatedScript += "\n\t\tsalome.sg.updateObjBrowser(0)"; // ----------------------------------------------------------------- // store visual properties of displayed objects @@ -876,7 +1023,13 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl CORBA::string_free(script); } } - anUpdatedScript += "\n\n\tpass\n"; + + if( isMultiFile ) + anUpdatedScript += "\n\tpass"; + anUpdatedScript += "\n"; + + if( !isMultiFile ) // remove unnecessary tabulation + RemoveTabulation( anUpdatedScript ); // ----------------------------------------------------------------- // put string literals describing patterns into separate functions @@ -916,7 +1069,18 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl do functionName = aFunctionType + "_" + ( nb++ ) + "()"; while ( !functionNameSet.insert( functionName.ToCString() ).second ); - anUpdatedScript += helper + "\n\ndef " + functionName + aLongString; // define function + // define function + TCollection_AsciiString funDef = helper + "def " + functionName + aLongString; + if ( isMultiFile ) + { + anUpdatedScript += helper + "\n\n" + funDef; + } + else + { + funDef += "\n\n"; + anUpdatedScript.Insert( 1, funDef); + where += funDef.Length(); + } } anUpdatedScript.InsertBefore( where, functionName ); // call function } diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index 189e6cbcc..fc5314b8c 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Filter_i.cxx // Author : Alexey Petrov, OCC @@ -32,6 +33,7 @@ #include "SMDS_Mesh.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_MeshElement.hxx" +#include "SMDS_ElemIterator.hxx" #include "SMESHDS_Mesh.hxx" @@ -122,7 +124,7 @@ void Controls::BelongToGeom::init() { if (!myMeshDS || myShape.IsNull()) return; - // is subshape of main shape? + // is sub-shape of main shape? TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh(); if (aMainShape.IsNull()) { myIsSubshape = false; @@ -278,7 +280,7 @@ void Controls::LyingOnGeom::init() { if (!myMeshDS || myShape.IsNull()) return; - // is subshape of main shape? + // is sub-shape of main shape? TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh(); if (aMainShape.IsNull()) { myIsSubshape = false; @@ -485,21 +487,16 @@ static TopoDS_Shape getShapeByName( const char* theName ) { if ( theName != 0 ) { - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); - if (!CORBA::is_nil(aStudy)) + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { - SALOMEDS::Study::ListOfSObject_var aList = - aStudy->FindObjectByName( theName, "GEOM" ); + SALOMEDS::Study::ListOfSObject_var aList = aStudy->FindObjectByName( theName, "GEOM" ); if ( aList->length() > 0 ) { - GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aList[ 0 ]->GetObject() ); - if ( !aGeomObj->_is_nil() ) - { - GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine(); - TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj ); - return aLocShape; - } + CORBA::Object_var anObj = aList[ 0 ]->GetObject(); + GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( anObj ); + return aSMESHGen->GeomObjectToShape( aGeomObj ); } } } @@ -508,48 +505,35 @@ static TopoDS_Shape getShapeByName( const char* theName ) static TopoDS_Shape getShapeByID (const char* theID) { - if (theID != 0 && theID != "") { - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); - if (aStudy != 0) { + if ( theID && strlen( theID ) > 0 ) { + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID); - SALOMEDS::GenericAttribute_var anAttr; - if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) { - SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); - CORBA::String_var aVal = anIOR->Value(); - CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal); + if ( !aSObj->_is_nil() ) { + CORBA::Object_var obj = aSObj->GetObject(); GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(obj); - - if (!aGeomObj->_is_nil()) { - GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine(); - TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj ); - return aLocShape; - } + return aSMESHGen->GeomObjectToShape( aGeomObj ); } } } return TopoDS_Shape(); } -static char* getShapeNameByID (const char* theID) +static std::string getShapeNameByID (const char* theID) { - char* aName = ""; - - if (theID != 0 && theID != "") { - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); - if (aStudy != 0) { - //SALOMEDS::SObject_var aSObj = aStudy->FindObjectIOR( theID ); + if ( theID && strlen( theID ) > 0 ) { + SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID); - SALOMEDS::GenericAttribute_var anAttr; - if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeName")) { - SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow(anAttr); - aName = aNameAttr->Value(); + if ( !aSObj->_is_nil() ) { + CORBA::String_var name = aSObj->GetName(); + return name.in(); } } } - - return aName; + return ""; } /* @@ -570,7 +554,7 @@ Functor_i::Functor_i(): Functor_i::~Functor_i() { - //TPythonDump()<GetValue( theId ); } +SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals) +{ + std::vector nbEvents; + std::vector funValues; + std::vector elements; + myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements); + +#ifdef WIN32 + nbIntervals = CORBA::Short( min( nbEvents.size(), funValues.size() - 1)); +#else + nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1)); +#endif + SMESH::Histogram_var histogram = new SMESH::Histogram; + if ( nbIntervals > 0 ) + { + histogram->length( nbIntervals ); + for ( int i = 0; i < nbIntervals; ++i ) + { + HistogramRectangle& rect = histogram[i]; + rect.nbEvents = nbEvents[i]; + rect.min = funValues[i]; + rect.max = funValues[i+1]; + } + } + return histogram._retn(); +} + void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision ) { myNumericalFunctorPtr->SetPrecision( thePrecision ); @@ -736,6 +747,36 @@ FunctorType Volume3D_i::GetFunctorType() return SMESH::FT_Volume3D; } +/* + Class : MaxElementLength2D_i + Description : Functor for calculating maximum length of 2D element +*/ +MaxElementLength2D_i::MaxElementLength2D_i() +{ + myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType MaxElementLength2D_i::GetFunctorType() +{ + return SMESH::FT_MaxElementLength2D; +} + +/* + Class : MaxElementLength3D_i + Description : Functor for calculating maximum length of 3D element +*/ +MaxElementLength3D_i::MaxElementLength3D_i() +{ + myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType MaxElementLength3D_i::GetFunctorType() +{ + return SMESH::FT_MaxElementLength3D; +} + /* Class : Length_i Description : Functor for calculating length off edge @@ -770,11 +811,12 @@ SMESH::Length2D::Values* Length2D_i::GetValues() { INFOS("Length2D_i::GetValues"); SMESH::Controls::Length2D::TValues aValues; - myLength2DPtr->GetValues( aValues ); + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); long i = 0, iEnd = aValues.size(); SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd); + aResult->length(iEnd); SMESH::Controls::Length2D::TValues::const_iterator anIter; for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) @@ -806,6 +848,21 @@ FunctorType MultiConnection_i::GetFunctorType() return SMESH::FT_MultiConnection; } +/* + Class : BallDiameter_i + Description : Functor returning diameter of a ball element +*/ +BallDiameter_i::BallDiameter_i() +{ + myNumericalFunctorPtr.reset( new Controls::BallDiameter() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType BallDiameter_i::GetFunctorType() +{ + return SMESH::FT_BallDiameter; +} + /* Class : MultiConnection2D_i Description : Functor for calculating number of faces conneted to the edge @@ -825,11 +882,12 @@ SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues() { INFOS("MultiConnection2D_i::GetValues"); SMESH::Controls::MultiConnection2D::MValues aValues; - myMulticonnection2DPtr->GetValues( aValues ); - + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + long i = 0, iEnd = aValues.size(); SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd); + aResult->length(iEnd); SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter; for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) @@ -881,6 +939,66 @@ FunctorType BadOrientedVolume_i::GetFunctorType() return SMESH::FT_BadOrientedVolume; } +/* + Class : BareBorderVolume_i + Description : Verify whether a mesh volume has a free facet without a face on it +*/ +BareBorderVolume_i::BareBorderVolume_i() +{ + Controls::PredicatePtr control( new Controls::BareBorderVolume() ); + myFunctorPtr = myPredicatePtr = control; +}; + +FunctorType BareBorderVolume_i::GetFunctorType() +{ + return SMESH::FT_BareBorderVolume; +} + +/* + Class : BareBorderFace_i + Description : Verify whether a mesh face has a free border without an edge on it +*/ +BareBorderFace_i::BareBorderFace_i() +{ + Controls::PredicatePtr control( new Controls::BareBorderFace() ); + myFunctorPtr = myPredicatePtr = control; +}; + +FunctorType BareBorderFace_i::GetFunctorType() +{ + return SMESH::FT_BareBorderFace; +} + +/* + Class : OverConstrainedVolume_i + Description : Verify whether a mesh volume has only one facet shared with other volumes +*/ +OverConstrainedVolume_i::OverConstrainedVolume_i() +{ + Controls::PredicatePtr control( new Controls::OverConstrainedVolume() ); + myFunctorPtr = myPredicatePtr = control; +}; + +FunctorType OverConstrainedVolume_i::GetFunctorType() +{ + return SMESH::FT_OverConstrainedVolume; +} + +/* + Class : OverConstrainedFace_i + Description : Verify whether a mesh face has only one border shared with other faces +*/ +OverConstrainedFace_i::OverConstrainedFace_i() +{ + Controls::PredicatePtr control( new Controls::OverConstrainedFace() ); + myFunctorPtr = myPredicatePtr = control; +}; + +FunctorType OverConstrainedFace_i::GetFunctorType() +{ + return SMESH::FT_OverConstrainedFace; +} + /* Class : BelongToGeom_i Description : Predicate for selection on geometrical support @@ -943,7 +1061,7 @@ void BelongToGeom_i::SetShape( const char* theID, const char* theName ) else myShapeID = 0; - if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 ) + if ( myShapeID && myShapeName == getShapeNameByID(myShapeID)) myBelongToGeomPtr->SetGeom( getShapeByID(myShapeID) ); else myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) ); @@ -1028,7 +1146,7 @@ void BelongToSurface_i::SetShape( const char* theID, const char* theName, Eleme else myShapeID = 0; - if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 ) + if ( myShapeID && myShapeName == getShapeNameByID(myShapeID)) myElementsOnSurfacePtr->SetSurface( getShapeByID(myShapeID), (SMDSAbs_ElementType)theType ); else myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType ); @@ -1198,7 +1316,7 @@ void LyingOnGeom_i::SetShape( const char* theID, const char* theName ) else myShapeID = 0; - if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 ) + if ( myShapeID && myShapeName == getShapeNameByID(myShapeID)) myLyingOnGeomPtr->SetGeom( getShapeByID(myShapeID) ); else myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) ); @@ -1311,6 +1429,77 @@ FunctorType FreeNodes_i::GetFunctorType() return SMESH::FT_FreeNodes; } +/* + Class : EqualNodes_i + Description : Predicate for Equal nodes +*/ +EqualNodes_i::EqualNodes_i() +{ + myCoincidentNodesPtr.reset(new Controls::CoincidentNodes()); + myFunctorPtr = myPredicatePtr = myCoincidentNodesPtr; +} + +FunctorType EqualNodes_i::GetFunctorType() +{ + return SMESH::FT_EqualNodes; +} + +void EqualNodes_i::SetTolerance( double tol ) +{ + myCoincidentNodesPtr->SetTolerance( tol ); +} + +double EqualNodes_i::GetTolerance() +{ + return myCoincidentNodesPtr->GetTolerance(); +} + +/* + Class : EqualEdges_i + Description : Predicate for Equal Edges +*/ +EqualEdges_i::EqualEdges_i() +{ + myPredicatePtr.reset(new Controls::CoincidentElements1D()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType EqualEdges_i::GetFunctorType() +{ + return SMESH::FT_EqualEdges; +} + +/* + Class : EqualFaces_i + Description : Predicate for Equal Faces +*/ +EqualFaces_i::EqualFaces_i() +{ + myPredicatePtr.reset(new Controls::CoincidentElements2D()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType EqualFaces_i::GetFunctorType() +{ + return SMESH::FT_EqualFaces; +} + +/* + Class : EqualVolumes_i + Description : Predicate for Equal Volumes +*/ +EqualVolumes_i::EqualVolumes_i() +{ + myPredicatePtr.reset(new Controls::CoincidentElements3D()); + myFunctorPtr = myPredicatePtr; +} + +FunctorType EqualVolumes_i::GetFunctorType() +{ + return SMESH::FT_EqualVolumes; +} + + /* Class : RangeOfIds_i Description : Predicate for Range of Ids. @@ -1439,7 +1628,7 @@ void ElemGeomType_i::SetGeometryType(GeometryType theType) GeometryType ElemGeomType_i::GetGeometryType() const { - return (GeometryType)myElemGeomTypePtr->GetGeomType();; + return (GeometryType)myElemGeomTypePtr->GetGeomType(); } FunctorType ElemGeomType_i::GetFunctorType() @@ -1447,6 +1636,49 @@ FunctorType ElemGeomType_i::GetFunctorType() return SMESH::FT_ElemGeomType; } +/* + Class : CoplanarFaces_i + Description : Returns true if a mesh face is a coplanar neighbour to a given one +*/ +CoplanarFaces_i::CoplanarFaces_i() +{ + myCoplanarFacesPtr.reset(new Controls::CoplanarFaces()); + myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr; +} + +void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID ) +{ + myCoplanarFacesPtr->SetFace(theFaceID); + TPythonDump()<SetTolerance(theToler); + TPythonDump()<GetFace(); +} + +char* CoplanarFaces_i::GetFaceAsString () const +{ + TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace())); + return CORBA::string_dup( str.ToCString() ); +} + +CORBA::Double CoplanarFaces_i::GetTolerance() const +{ + return myCoplanarFacesPtr->GetTolerance(); +} + +FunctorType CoplanarFaces_i::GetFunctorType() +{ + return SMESH::FT_CoplanarFaces; +} + /* Class : Comparator_i Description : Base class for comparators @@ -1458,7 +1690,7 @@ Comparator_i::Comparator_i(): Comparator_i::~Comparator_i() { if ( myNumericalFunctor ) - myNumericalFunctor->Destroy(); + myNumericalFunctor->UnRegister(); } void Comparator_i::SetMargin( CORBA::Double theValue ) @@ -1475,7 +1707,7 @@ CORBA::Double Comparator_i::GetMargin() void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct ) { if ( myNumericalFunctor ) - myNumericalFunctor->Destroy(); + myNumericalFunctor->UnRegister(); myNumericalFunctor = DownCast(theFunct); @@ -1570,13 +1802,13 @@ LogicalNOT_i::LogicalNOT_i() LogicalNOT_i::~LogicalNOT_i() { if ( myPredicate ) - myPredicate->Destroy(); + myPredicate->UnRegister(); } void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate ) { if ( myPredicate ) - myPredicate->Destroy(); + myPredicate->UnRegister(); myPredicate = SMESH::GetPredicate(thePredicate); @@ -1610,10 +1842,10 @@ LogicalBinary_i::LogicalBinary_i() LogicalBinary_i::~LogicalBinary_i() { if ( myPredicate1 ) - myPredicate1->Destroy(); + myPredicate1->UnRegister(); if ( myPredicate2 ) - myPredicate2->Destroy(); + myPredicate2->UnRegister(); } void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh ) @@ -1628,7 +1860,7 @@ void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh ) void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate ) { if ( myPredicate1 ) - myPredicate1->Destroy(); + myPredicate1->UnRegister(); myPredicate1 = SMESH::GetPredicate(thePredicate); @@ -1642,7 +1874,7 @@ void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate ) void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate ) { if ( myPredicate2 ) - myPredicate2->Destroy(); + myPredicate2->UnRegister(); myPredicate2 = SMESH::GetPredicate(thePredicate); @@ -1715,7 +1947,7 @@ FilterManager_i::FilterManager_i() FilterManager_i::~FilterManager_i() { - //TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); - TPythonDump()<Destroy(); + myPredicate->UnRegister(); if(!CORBA::is_nil(myMesh)) - myMesh->Destroy(); + myMesh->UnRegister(); - //TPythonDump()<Destroy(); + myPredicate->UnRegister(); myPredicate = SMESH::GetPredicate(thePredicate); @@ -2071,8 +2399,13 @@ void Filter_i::SetPredicate( Predicate_ptr thePredicate ) { myFilter.SetPredicate( myPredicate->GetPredicate() ); myPredicate->Register(); + if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh)) + myPredicate->GetPredicate()->SetMesh( aMesh ); TPythonDump()<::iterator i = myWaiters.begin(); + for ( ; i != myWaiters.end(); ++i ) + (*i)->PredicateChanged(); } //======================================================================= @@ -2096,10 +2429,14 @@ SetMesh( SMESH_Mesh_ptr theMesh ) theMesh->Register(); if(!CORBA::is_nil(myMesh)) - myMesh->Destroy(); + myMesh->UnRegister(); - myMesh = theMesh; + myMesh = SMESH_Mesh::_duplicate( theMesh ); TPythonDump()<GetPredicate()->SetMesh( aMesh ); } SMESH::long_array* @@ -2150,6 +2487,119 @@ GetElementsId( SMESH_Mesh_ptr theMesh ) return anArray._retn(); } +template +static void collectMeshInfo(const TIterator& theItr, + TPredicate& thePred, + SMESH::long_array& theRes) +{ + if (!theItr) + return; + while (theItr->more()) { + const SMDS_MeshElement* anElem = theItr->next(); + if ( thePred->IsSatisfy( anElem->GetID() ) ) + theRes[ anElem->GetEntityType() ]++; + } +} + +//============================================================================= +/*! + * \brief Returns statistic of mesh elements + */ +//============================================================================= +SMESH::long_array* ::Filter_i::GetMeshInfo() +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + + if(!CORBA::is_nil(myMesh) && myPredicate) { + const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); + SMDS_ElemIteratorPtr it; + switch( GetElementType() ) + { + case SMDSAbs_Node: + collectMeshInfo(aMesh->nodesIterator(),myPredicate,aRes); + break; + case SMDSAbs_Edge: + collectMeshInfo(aMesh->edgesIterator(),myPredicate,aRes); + break; + case SMDSAbs_Face: + collectMeshInfo(aMesh->facesIterator(),myPredicate,aRes); + break; + case SMDSAbs_Volume: + collectMeshInfo(aMesh->volumesIterator(),myPredicate,aRes); + break; + case SMDSAbs_All: + default: + collectMeshInfo(aMesh->elementsIterator(),myPredicate,aRes); + break; + } + } + + return aRes._retn(); +} + +//================================================================================ +/*! + * \brief Return GetElementType() within an array + * Implement SMESH_IDSource interface + */ +//================================================================================ + +SMESH::array_of_ElementType* Filter_i::GetTypes() +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + // check if any element passes through the filter + if ( !CORBA::is_nil(myMesh) && myPredicate ) + { + const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh); + SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() )); + bool satisfies = false; + while ( !satisfies && it->more() ) + satisfies = myPredicate->IsSatisfy( it->next()->GetID() ); + if ( satisfies ) { + types->length( 1 ); + types[0] = GetElementType(); + } + } + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : Returns mesh +//======================================================================= + +SMESH::SMESH_Mesh_ptr Filter_i::GetMesh() +{ + return SMESH_Mesh::_duplicate( myMesh ); +} + +//================================================================================ +/*! + * \brief Stores an object to be notified on change of predicate + */ +//================================================================================ + +void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter ) +{ + if ( waiter ) + myWaiters.push_back( waiter ); +} + +//================================================================================ +/*! + * \brief Removes an object to be notified on change of predicate + */ +//================================================================================ + +void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter ) +{ + myWaiters.remove( waiter ); +} + //======================================================================= // name : getCriteria // Purpose : Retrieve criterions from predicate @@ -2166,6 +2616,14 @@ static inline bool getCriteria( Predicate_i* thePred, case FT_FreeFaces: case FT_LinearOrQuadratic: case FT_FreeNodes: + case FT_EqualEdges: + case FT_EqualFaces: + case FT_EqualVolumes: + case FT_BadOrientedVolume: + case FT_BareBorderVolume: + case FT_BareBorderFace: + case FT_OverConstrainedVolume: + case FT_OverConstrainedFace: { CORBA::ULong i = theCriteria->length(); theCriteria->length( i + 1 ); @@ -2189,6 +2647,7 @@ static inline bool getCriteria( Predicate_i* thePred, theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); theCriteria[ i ].ThresholdID = aPred->GetShapeID(); theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); return true; } @@ -2224,34 +2683,51 @@ static inline bool getCriteria( Predicate_i* thePred, theCriteria[ i ].ThresholdStr = aPred->GetShapeName(); theCriteria[ i ].ThresholdID = aPred->GetShapeID(); theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].Tolerance = aPred->GetTolerance(); return true; } - case FT_RangeOfIds: + case FT_CoplanarFaces: { - RangeOfIds_i* aPred = dynamic_cast( thePred ); + CoplanarFaces_i* aPred = dynamic_cast( thePred ); CORBA::ULong i = theCriteria->length(); theCriteria->length( i + 1 ); theCriteria[ i ] = createCriterion(); + CORBA::String_var faceId = aPred->GetFaceAsString(); - theCriteria[ i ].Type = FT_RangeOfIds; - theCriteria[ i ].ThresholdStr = aPred->GetRangeStr(); - theCriteria[ i ].TypeOfElement = aPred->GetElementType(); + theCriteria[ i ].Type = FT_CoplanarFaces; + theCriteria[ i ].ThresholdID = faceId; + theCriteria[ i ].Tolerance = aPred->GetTolerance(); return true; } - case FT_BadOrientedVolume: + case FT_EqualNodes: + { + EqualNodes_i* aPred = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + + theCriteria[ i ].Type = FT_EqualNodes; + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + + return true; + } + case FT_RangeOfIds: { - BadOrientedVolume_i* aPred = dynamic_cast( thePred ); + RangeOfIds_i* aPred = dynamic_cast( thePred ); CORBA::ULong i = theCriteria->length(); theCriteria->length( i + 1 ); theCriteria[ i ] = createCriterion(); - theCriteria[ i ].Type = FT_BadOrientedVolume; + theCriteria[ i ].Type = FT_RangeOfIds; + theCriteria[ i ].ThresholdStr = aPred->GetRangeStr(); theCriteria[ i ].TypeOfElement = aPred->GetElementType(); return true; @@ -2350,7 +2826,7 @@ CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria ) CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria ) { if ( myPredicate != 0 ) - myPredicate->Destroy(); + myPredicate->UnRegister(); SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i(); FilterManager_ptr aFilterMgr = aFilter->_this(); @@ -2376,16 +2852,20 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria { TPythonDump pd; - pd << "aCriterion = SMESH.Filter.Criterion(" << aCriterion << "," << aCompare - << "," << aThreshold << ",'" << aThresholdStr; - if (aThresholdID) - pd << "',salome.ObjectToID(" << aThresholdID - << ")," << aUnary << "," << aBinary << "," << aTolerance - << "," << aTypeOfElem << "," << aPrecision << ")"; - else - pd << "',''," << aUnary << "," << aBinary << "," << aTolerance - << "," << aTypeOfElem << "," << aPrecision << ")"; + pd << "aCriterion = SMESH.Filter.Criterion(" + << aCriterion << ", " + << aCompare << ", " + << aThreshold << ", '" + << aThresholdStr << "', '"; + if (aThresholdID) pd << aThresholdID; + pd << "', " + << aUnary << ", " + << aBinary << ", " + << aTolerance << ", " + << aTypeOfElem << ", " + << aPrecision << ")"; } + TPythonDump pd; SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil(); SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil(); @@ -2430,6 +2910,15 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria case SMESH::FT_Volume3D: aFunctor = aFilterMgr->CreateVolume3D(); break; + case SMESH::FT_MaxElementLength2D: + aFunctor = aFilterMgr->CreateMaxElementLength2D(); + break; + case SMESH::FT_MaxElementLength3D: + aFunctor = aFilterMgr->CreateMaxElementLength3D(); + break; + case SMESH::FT_BallDiameter: + aFunctor = aFilterMgr->CreateBallDiameter(); + break; // Predicates @@ -2445,11 +2934,28 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria case SMESH::FT_FreeNodes: aPredicate = aFilterMgr->CreateFreeNodes(); break; + case SMESH::FT_EqualNodes: + { + SMESH::EqualNodes_ptr pred = aFilterMgr->CreateEqualNodes(); + pred->SetTolerance( aTolerance ); + aPredicate = pred; + break; + } + case SMESH::FT_EqualEdges: + aPredicate = aFilterMgr->CreateEqualEdges(); + break; + case SMESH::FT_EqualFaces: + aPredicate = aFilterMgr->CreateEqualFaces(); + break; + case SMESH::FT_EqualVolumes: + aPredicate = aFilterMgr->CreateEqualVolumes(); + break; case SMESH::FT_BelongToGeom: { SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom(); tmpPred->SetElementType( aTypeOfElem ); tmpPred->SetShape( aThresholdID, aThresholdStr ); + tmpPred->SetTolerance( aTolerance ); aPredicate = tmpPred; } break; @@ -2475,7 +2981,8 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria { SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom(); tmpPred->SetElementType( aTypeOfElem ); - tmpPred->SetShape( aThresholdID, aThresholdStr ); + tmpPred->SetShape( aThresholdID, aThresholdStr ); + tmpPred->SetTolerance( aTolerance ); aPredicate = tmpPred; } break; @@ -2492,6 +2999,26 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria aPredicate = aFilterMgr->CreateBadOrientedVolume(); } break; + case SMESH::FT_BareBorderVolume: + { + aPredicate = aFilterMgr->CreateBareBorderVolume(); + } + break; + case SMESH::FT_BareBorderFace: + { + aPredicate = aFilterMgr->CreateBareBorderFace(); + } + break; + case SMESH::FT_OverConstrainedVolume: + { + aPredicate = aFilterMgr->CreateOverConstrainedVolume(); + } + break; + case SMESH::FT_OverConstrainedFace: + { + aPredicate = aFilterMgr->CreateOverConstrainedFace(); + } + break; case SMESH::FT_LinearOrQuadratic: { SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic(); @@ -2511,7 +3038,15 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria { SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType(); tmpPred->SetElementType( aTypeOfElem ); - tmpPred->SetGeometryType( (GeometryType)(aThreshold + 0.5) ); + tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) ); + aPredicate = tmpPred; + break; + } + case SMESH::FT_CoplanarFaces: + { + SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces(); + tmpPred->SetFace( atol (aThresholdID )); + tmpPred->SetTolerance( aTolerance ); aPredicate = tmpPred; break; } @@ -2559,10 +3094,10 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria // logical op aPredicates.push_back( aPredicate ); aBinaries.push_back( aBinary ); - TPythonDump()<<"aCriteria.append(aCriterion)"; + pd <<"aCriteria.append(aCriterion)"; } // end of for - TPythonDump()<_this(); + // if ( SMESH::Functor_i* fun = SMESH::DownCast( anObj )) + // TPythonDump() << fun << " = " << this << ".GetPredicate()"; return anObj._retn(); } } @@ -2717,19 +3254,29 @@ static inline LDOMString toString( CORBA::Long theType ) case FT_Skew : return "Skew"; case FT_Area : return "Area"; case FT_Volume3D : return "Volume3D"; + case FT_MaxElementLength2D: return "Max element length 2D"; + case FT_MaxElementLength3D: return "Max element length 3D"; case FT_BelongToGeom : return "Belong to Geom"; case FT_BelongToPlane : return "Belong to Plane"; case FT_BelongToCylinder: return "Belong to Cylinder"; case FT_BelongToGenSurface: return "Belong to Generic Surface"; case FT_LyingOnGeom : return "Lying on Geom"; - case FT_BadOrientedVolume: return "Bad Oriented Volume"; + case FT_BadOrientedVolume:return "Bad Oriented Volume"; + case FT_BareBorderVolume: return "Volumes with bare border"; + case FT_BareBorderFace : return "Faces with bare border"; + case FT_OverConstrainedVolume: return "Over-constrained Volumes"; + case FT_OverConstrainedFace : return "Over-constrained Faces"; case FT_RangeOfIds : return "Range of IDs"; case FT_FreeBorders : return "Free borders"; case FT_FreeEdges : return "Free edges"; case FT_FreeFaces : return "Free faces"; case FT_FreeNodes : return "Free nodes"; + case FT_EqualNodes : return "Equal nodes"; + case FT_EqualEdges : return "Equal edges"; + case FT_EqualFaces : return "Equal faces"; + case FT_EqualVolumes : return "Equal volumes"; case FT_MultiConnection : return "Borders at multi-connections"; - case FT_MultiConnection2D: return "Borders at multi-connections 2D"; + case FT_MultiConnection2D:return "Borders at multi-connections 2D"; case FT_Length : return "Length"; case FT_Length2D : return "Length 2D"; case FT_LessThan : return "Less than"; @@ -2759,6 +3306,8 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) else if ( theStr.equals( "Skew" ) ) return FT_Skew; else if ( theStr.equals( "Area" ) ) return FT_Area; else if ( theStr.equals( "Volume3D" ) ) return FT_Volume3D; + else if ( theStr.equals( "Max element length 2D" ) ) return FT_MaxElementLength2D; + else if ( theStr.equals( "Max element length 3D" ) ) return FT_MaxElementLength3D; else if ( theStr.equals( "Belong to Geom" ) ) return FT_BelongToGeom; else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane; else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder; @@ -2768,12 +3317,20 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) else if ( theStr.equals( "Free edges" ) ) return FT_FreeEdges; else if ( theStr.equals( "Free faces" ) ) return FT_FreeFaces; else if ( theStr.equals( "Free nodes" ) ) return FT_FreeNodes; + else if ( theStr.equals( "Equal nodes" ) ) return FT_EqualNodes; + else if ( theStr.equals( "Equal edges" ) ) return FT_EqualEdges; + else if ( theStr.equals( "Equal faces" ) ) return FT_EqualFaces; + else if ( theStr.equals( "Equal volumes" ) ) return FT_EqualVolumes; else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection; // else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D; else if ( theStr.equals( "Length" ) ) return FT_Length; // else if ( theStr.equals( "Length2D" ) ) return FT_Length2D; else if ( theStr.equals( "Range of IDs" ) ) return FT_RangeOfIds; else if ( theStr.equals( "Bad Oriented Volume" ) ) return FT_BadOrientedVolume; + else if ( theStr.equals( "Volumes with bare border" ) ) return FT_BareBorderVolume; + else if ( theStr.equals( "Faces with bare border" ) ) return FT_BareBorderFace; + else if ( theStr.equals( "Over-constrained Volumes" ) ) return FT_OverConstrainedVolume; + else if ( theStr.equals( "Over-constrained Faces" ) ) return FT_OverConstrainedFace; else if ( theStr.equals( "Less than" ) ) return FT_LessThan; else if ( theStr.equals( "More than" ) ) return FT_MoreThan; else if ( theStr.equals( "Equal to" ) ) return FT_EqualTo; @@ -3000,7 +3557,7 @@ FilterLibrary_i::FilterLibrary_i() FilterLibrary_i::~FilterLibrary_i() { delete myFileName; - //TPythonDump()<(theFilter)) - TPythonDump()< SMESH::FT_Undefined ) + return "FT_Undefined"; + return getFunctNames()[ ft ]; +} + +//================================================================================ +/*! + * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString() + */ +//================================================================================ + +SMESH::FunctorType SMESH::StringToFunctorType(const char* str) +{ + std::string name( str + 3 ); // skip "FT_" + const char** functNames = getFunctNames(); + int ft = 0; + for ( ; ft < SMESH::FT_Undefined; ++ft ) + if ( name == ( functNames[ft] + 3 )) + break; + + //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 ); + + return SMESH::FunctorType( ft ); +} diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx index 3b654e880..cb82aa6d5 100644 --- a/src/SMESH_I/SMESH_Filter_i.hxx +++ b/src/SMESH_I/SMESH_Filter_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Filter_i.hxx // Author : Alexey Petrov, OCC @@ -38,11 +39,14 @@ #include "SALOME_GenericObj_i.hh" #include "SMESH_ControlsDef.hxx" +#include + class SMESHDS_Mesh; namespace SMESH { + // ================================================================================ namespace Controls { @@ -107,10 +111,10 @@ namespace SMESH double GetTolerance(); virtual bool Contains( const SMESHDS_Mesh* theMeshDS, - const TopoDS_Shape& theShape, - const SMDS_MeshElement* theElem, - TopAbs_ShapeEnum theFindShapeEnum, - TopAbs_ShapeEnum theAvoidShapeEnum = TopAbs_SHAPE ); + const TopoDS_Shape& theShape, + const SMDS_MeshElement* theElem, + TopAbs_ShapeEnum theFindShapeEnum, + TopAbs_ShapeEnum theAvoidShapeEnum = TopAbs_SHAPE ); private: virtual void init(); @@ -122,8 +126,10 @@ namespace SMESH Controls::ElementsOnShapePtr myElementsOnShapePtr; // only if myIsSubshape == false }; typedef boost::shared_ptr LyingOnGeomPtr; - } - + + } // namespace Controls + + // ================================================================================ /* FUNCTORS */ @@ -133,7 +139,7 @@ namespace SMESH Description : An abstact class for all functors */ class SMESH_I_EXPORT Functor_i: public virtual POA_SMESH::Functor, - public virtual SALOME::GenericObj_i + public virtual SALOME::GenericObj_i { public: void SetMesh( SMESH_Mesh_ptr theMesh ); @@ -152,10 +158,11 @@ namespace SMESH Description : Base class for numerical functors */ class SMESH_I_EXPORT NumericalFunctor_i: public virtual POA_SMESH::NumericalFunctor, - public virtual Functor_i + public virtual Functor_i { public: CORBA::Double GetValue( CORBA::Long theElementId ); + SMESH::Histogram* GetHistogram(CORBA::Short nbIntervals); void SetPrecision( CORBA::Long thePrecision ); CORBA::Long GetPrecision(); Controls::NumericalFunctorPtr GetNumericalFunctor(); @@ -170,7 +177,7 @@ namespace SMESH Description : Functor for calculation of minimum angle */ class SMESH_I_EXPORT MinimumAngle_i: public virtual POA_SMESH::MinimumAngle, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: MinimumAngle_i(); @@ -183,7 +190,7 @@ namespace SMESH Description : Functor for calculating aspect ratio */ class SMESH_I_EXPORT AspectRatio_i: public virtual POA_SMESH::AspectRatio, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: AspectRatio_i(); @@ -196,7 +203,7 @@ namespace SMESH Description : Functor for calculating aspect ratio for 3D */ class SMESH_I_EXPORT AspectRatio3D_i: public virtual POA_SMESH::AspectRatio3D, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: AspectRatio3D_i(); @@ -209,7 +216,7 @@ namespace SMESH Description : Functor for calculating warping */ class SMESH_I_EXPORT Warping_i: public virtual POA_SMESH::Warping, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: Warping_i(); @@ -222,7 +229,7 @@ namespace SMESH Description : Functor for calculating taper */ class SMESH_I_EXPORT Taper_i: public virtual POA_SMESH::Taper, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: Taper_i(); @@ -235,7 +242,7 @@ namespace SMESH Description : Functor for calculating skew in degrees */ class SMESH_I_EXPORT Skew_i: public virtual POA_SMESH::Skew, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: Skew_i(); @@ -248,7 +255,7 @@ namespace SMESH Description : Functor for calculating area */ class SMESH_I_EXPORT Area_i: public virtual POA_SMESH::Area, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: Area_i(); @@ -261,7 +268,7 @@ namespace SMESH Description : Functor for calculating volume of 3D element */ class SMESH_I_EXPORT Volume3D_i: public virtual POA_SMESH::Volume3D, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: Volume3D_i(); @@ -269,12 +276,38 @@ namespace SMESH }; + /* + Class : MaxElementLength2D_i + Description : Functor for calculating maximum length of 2D element + */ + class SMESH_I_EXPORT MaxElementLength2D_i: public virtual POA_SMESH::MaxElementLength2D, + public virtual NumericalFunctor_i + { + public: + MaxElementLength2D_i(); + FunctorType GetFunctorType(); + }; + + + /* + Class : MaxElementLength3D_i + Description : Functor for calculating maximum length of 3D element + */ + class SMESH_I_EXPORT MaxElementLength3D_i: public virtual POA_SMESH::MaxElementLength3D, + public virtual NumericalFunctor_i + { + public: + MaxElementLength3D_i(); + FunctorType GetFunctorType(); + }; + + /* Class : Length_i Description : Functor for calculating length of edge */ class SMESH_I_EXPORT Length_i: public virtual POA_SMESH::Length, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: Length_i(); @@ -286,7 +319,7 @@ namespace SMESH Description : Functor for calculating length of edge */ class SMESH_I_EXPORT Length2D_i: public virtual POA_SMESH::Length2D, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: Length2D_i(); @@ -303,7 +336,7 @@ namespace SMESH Description : Functor for calculating number of faces conneted to the edge */ class SMESH_I_EXPORT MultiConnection_i: public virtual POA_SMESH::MultiConnection, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: MultiConnection_i(); @@ -315,7 +348,7 @@ namespace SMESH Description : Functor for calculating number of faces conneted to the edge */ class SMESH_I_EXPORT MultiConnection2D_i: public virtual POA_SMESH::MultiConnection2D, - public virtual NumericalFunctor_i + public virtual NumericalFunctor_i { public: MultiConnection2D_i(); @@ -326,6 +359,18 @@ namespace SMESH Controls::MultiConnection2DPtr myMulticonnection2DPtr; }; + /* + Class : BallDiameter_i + Description : Functor returning diameter of a ball element + */ + class SMESH_I_EXPORT BallDiameter_i: public virtual POA_SMESH::BallDiameter, + public virtual NumericalFunctor_i + { + public: + BallDiameter_i(); + FunctorType GetFunctorType(); + }; + /* PREDICATES @@ -335,7 +380,7 @@ namespace SMESH Description : Base class for all predicates */ class SMESH_I_EXPORT Predicate_i: public virtual POA_SMESH::Predicate, - public virtual Functor_i + public virtual Functor_i { public: CORBA::Boolean IsSatisfy( CORBA::Long theElementId ); @@ -352,19 +397,67 @@ namespace SMESH the point of view of MED convention */ class SMESH_I_EXPORT BadOrientedVolume_i: public virtual POA_SMESH::BadOrientedVolume, - public virtual Predicate_i + public virtual Predicate_i { public: BadOrientedVolume_i(); FunctorType GetFunctorType(); }; + /* + Class : BareBorderVolume_i + Description : Verify whether a mesh volume has a free facet without a face on it + */ + class SMESH_I_EXPORT BareBorderVolume_i: public virtual POA_SMESH::BareBorderVolume, + public virtual Predicate_i + { + public: + BareBorderVolume_i(); + FunctorType GetFunctorType(); + }; + + /* + Class : BareBorderFace_i + Description : Verify whether a mesh face has a free border without an edge on it + */ + class SMESH_I_EXPORT BareBorderFace_i: public virtual POA_SMESH::BareBorderFace, + public virtual Predicate_i + { + public: + BareBorderFace_i(); + FunctorType GetFunctorType(); + }; + + /* + Class : OverConstrainedVolume_i + Description : Verify whether a mesh volume has only one facet shared with other volumes + */ + class SMESH_I_EXPORT OverConstrainedVolume_i: public virtual POA_SMESH::OverConstrainedVolume, + public virtual Predicate_i + { + public: + OverConstrainedVolume_i(); + FunctorType GetFunctorType(); + }; + + /* + Class : OverConstrainedFace_i + Description : Verify whether a mesh face has only one border shared with other faces + */ + class SMESH_I_EXPORT OverConstrainedFace_i: public virtual POA_SMESH::OverConstrainedFace, + public virtual Predicate_i + { + public: + OverConstrainedFace_i(); + FunctorType GetFunctorType(); + }; + /* Class : BelongToGeom_i Description : Predicate for selection on geometrical support */ class SMESH_I_EXPORT BelongToGeom_i: public virtual POA_SMESH::BelongToGeom, - public virtual Predicate_i + public virtual Predicate_i { public: BelongToGeom_i(); @@ -395,7 +488,7 @@ namespace SMESH Description : Verify whether mesh element lie in pointed Geom planar object */ class SMESH_I_EXPORT BelongToSurface_i: public virtual POA_SMESH::BelongToSurface, - public virtual Predicate_i + public virtual Predicate_i { public: BelongToSurface_i( const Handle(Standard_Type)& ); @@ -426,7 +519,7 @@ namespace SMESH Description : Verify whether mesh element lie in pointed Geom planar object */ class SMESH_I_EXPORT BelongToPlane_i: public virtual POA_SMESH::BelongToPlane, - public virtual BelongToSurface_i + public virtual BelongToSurface_i { public: BelongToPlane_i(); @@ -439,7 +532,7 @@ namespace SMESH Description : Verify whether mesh element lie in pointed Geom cylindrical object */ class SMESH_I_EXPORT BelongToCylinder_i: public virtual POA_SMESH::BelongToCylinder, - public virtual BelongToSurface_i + public virtual BelongToSurface_i { public: BelongToCylinder_i(); @@ -465,7 +558,7 @@ namespace SMESH Description : Predicate for selection on geometrical support(lying or partially lying) */ class SMESH_I_EXPORT LyingOnGeom_i: public virtual POA_SMESH::LyingOnGeom, - public virtual Predicate_i + public virtual Predicate_i { public: LyingOnGeom_i(); @@ -496,7 +589,7 @@ namespace SMESH Description : Predicate for free borders */ class SMESH_I_EXPORT FreeBorders_i: public virtual POA_SMESH::FreeBorders, - public virtual Predicate_i + public virtual Predicate_i { public: FreeBorders_i(); @@ -509,7 +602,7 @@ namespace SMESH Description : Predicate for free edges */ class SMESH_I_EXPORT FreeEdges_i: public virtual POA_SMESH::FreeEdges, - public virtual Predicate_i + public virtual Predicate_i { public: FreeEdges_i(); @@ -526,7 +619,7 @@ namespace SMESH Description : Predicate for free faces */ class SMESH_I_EXPORT FreeFaces_i: public virtual POA_SMESH::FreeFaces, - public virtual Predicate_i + public virtual Predicate_i { public: FreeFaces_i(); @@ -539,7 +632,7 @@ namespace SMESH Description : Predicate for free nodes */ class SMESH_I_EXPORT FreeNodes_i: public virtual POA_SMESH::FreeNodes, - public virtual Predicate_i + public virtual Predicate_i { public: FreeNodes_i(); @@ -547,12 +640,63 @@ namespace SMESH }; + /* + Class : EqualNodes_i + Description : Predicate for equal nodes + */ + class SMESH_I_EXPORT EqualNodes_i: public virtual POA_SMESH::EqualNodes, + public virtual Predicate_i + { + public: + EqualNodes_i(); + FunctorType GetFunctorType(); + void SetTolerance( double ); + double GetTolerance(); + + private: + Controls::CoincidentNodesPtr myCoincidentNodesPtr; + }; + /* + Class : EqualEdges_i + Description : Predicate for equal edges + */ + class SMESH_I_EXPORT EqualEdges_i: public virtual POA_SMESH::EqualEdges, + public virtual Predicate_i + { + public: + EqualEdges_i(); + FunctorType GetFunctorType(); + }; + /* + Class : EqualFaces_i + Description : Predicate for equal Faces + */ + class SMESH_I_EXPORT EqualFaces_i: public virtual POA_SMESH::EqualFaces, + public virtual Predicate_i + { + public: + EqualFaces_i(); + FunctorType GetFunctorType(); + }; + /* + Class : EqualVolumes_i + Description : Predicate for equal Volumes + */ + class SMESH_I_EXPORT EqualVolumes_i: public virtual POA_SMESH::EqualVolumes, + public virtual Predicate_i + { + public: + EqualVolumes_i(); + FunctorType GetFunctorType(); + }; + + /* Class : RangeOfIds_i Description : Predicate for Range of Ids */ class SMESH_I_EXPORT RangeOfIds_i: public virtual POA_SMESH::RangeOfIds, - public virtual Predicate_i + public virtual Predicate_i { public: RangeOfIds_i(); @@ -572,7 +716,7 @@ namespace SMESH Description : Verify whether a mesh element is linear */ class SMESH_I_EXPORT LinearOrQuadratic_i: public virtual POA_SMESH::LinearOrQuadratic, - public virtual Predicate_i + public virtual Predicate_i { public: LinearOrQuadratic_i(); @@ -588,7 +732,7 @@ namespace SMESH Description : Functor for check color of group to whic mesh element belongs to */ class SMESH_I_EXPORT GroupColor_i: public virtual POA_SMESH::GroupColor, - public virtual Predicate_i + public virtual Predicate_i { public: GroupColor_i(); @@ -607,7 +751,7 @@ namespace SMESH Description : Functor for check element geometry type */ class SMESH_I_EXPORT ElemGeomType_i: public virtual POA_SMESH::ElemGeomType, - public virtual Predicate_i + public virtual Predicate_i { public: ElemGeomType_i(); @@ -621,12 +765,32 @@ namespace SMESH Controls::ElemGeomTypePtr myElemGeomTypePtr; }; + /* + Class : CoplanarFaces_i + Description : Returns true if a mesh face is a coplanar neighbour to a given one + */ + class SMESH_I_EXPORT CoplanarFaces_i: public virtual POA_SMESH::CoplanarFaces, + public virtual Predicate_i + { + public: + CoplanarFaces_i(); + FunctorType GetFunctorType(); + + void SetFace ( CORBA::Long theFaceID ); + void SetTolerance( CORBA::Double theToler ); + char* GetFaceAsString () const; + CORBA::Long GetFace () const; + CORBA::Double GetTolerance () const; + private: + Controls::CoplanarFacesPtr myCoplanarFacesPtr; + }; + /* Class : Comparator_i Description : Base class for comparators */ class SMESH_I_EXPORT Comparator_i: public virtual POA_SMESH::Comparator, - public virtual Predicate_i + public virtual Predicate_i { public: virtual ~Comparator_i(); @@ -651,7 +815,7 @@ namespace SMESH Description : Comparator "<" */ class SMESH_I_EXPORT LessThan_i: public virtual POA_SMESH::LessThan, - public virtual Comparator_i + public virtual Comparator_i { public: LessThan_i(); @@ -664,7 +828,7 @@ namespace SMESH Description : Comparator ">" */ class SMESH_I_EXPORT MoreThan_i: public virtual POA_SMESH::MoreThan, - public virtual Comparator_i + public virtual Comparator_i { public: MoreThan_i(); @@ -677,7 +841,7 @@ namespace SMESH Description : Comparator "=" */ class SMESH_I_EXPORT EqualTo_i: public virtual POA_SMESH::EqualTo, - public virtual Comparator_i + public virtual Comparator_i { public: EqualTo_i(); @@ -695,7 +859,7 @@ namespace SMESH Description : Logical NOT predicate */ class SMESH_I_EXPORT LogicalNOT_i: public virtual POA_SMESH::LogicalNOT, - public virtual Predicate_i + public virtual Predicate_i { public: LogicalNOT_i(); @@ -716,7 +880,7 @@ namespace SMESH Description : Base class for binary logical predicate */ class SMESH_I_EXPORT LogicalBinary_i: public virtual POA_SMESH::LogicalBinary, - public virtual Predicate_i + public virtual Predicate_i { public: virtual ~LogicalBinary_i(); @@ -742,7 +906,7 @@ namespace SMESH Description : Logical AND */ class SMESH_I_EXPORT LogicalAND_i: public virtual POA_SMESH::LogicalAND, - public virtual LogicalBinary_i + public virtual LogicalBinary_i { public: LogicalAND_i(); @@ -755,7 +919,7 @@ namespace SMESH Description : Logical OR */ class SMESH_I_EXPORT LogicalOR_i: public virtual POA_SMESH::LogicalOR, - public virtual LogicalBinary_i + public virtual LogicalBinary_i { public: LogicalOR_i(); @@ -767,7 +931,7 @@ namespace SMESH FILTER */ class SMESH_I_EXPORT Filter_i: public virtual POA_SMESH::Filter, - public virtual SALOME::GenericObj_i + public virtual SALOME::GenericObj_i { public: Filter_i(); @@ -781,20 +945,16 @@ namespace SMESH void SetMesh( SMESH_Mesh_ptr ); - virtual - SMESH::long_array* - GetIDs(); - static void GetElementsId( Predicate_i*, - const SMDS_Mesh*, - Controls::Filter::TIdSequence& ); + const SMDS_Mesh*, + Controls::Filter::TIdSequence& ); static void GetElementsId( Predicate_i*, - SMESH_Mesh_ptr, - Controls::Filter::TIdSequence& ); + SMESH_Mesh_ptr, + Controls::Filter::TIdSequence& ); virtual long_array* @@ -818,10 +978,31 @@ namespace SMESH Predicate_i* GetPredicate_i(); + // ========================= + // SMESH_IDSource interface + // ========================= + virtual SMESH::long_array* GetIDs(); + virtual SMESH::long_array* GetMeshInfo(); + virtual SMESH::array_of_ElementType* GetTypes(); + virtual SMESH::SMESH_Mesh_ptr GetMesh(); + virtual bool IsMeshInfoCorrect() { return true; } + + /*! + * \brief Object notified on change of predicate + */ + struct TPredicateChangeWaiter + { + virtual void PredicateChanged() = 0; + }; + void AddWaiter( TPredicateChangeWaiter* waiter ); + void RemoveWaiter( TPredicateChangeWaiter* waiter ); + private: Controls::Filter myFilter; Predicate_i* myPredicate; SMESH_Mesh_var myMesh; + + std::list myWaiters; }; @@ -829,7 +1010,7 @@ namespace SMESH FILTER LIBRARY */ class SMESH_I_EXPORT FilterLibrary_i: public virtual POA_SMESH::FilterLibrary, - public virtual SALOME::GenericObj_i + public virtual SALOME::GenericObj_i { public: FilterLibrary_i( const char* theFileName ); @@ -842,8 +1023,8 @@ namespace SMESH CORBA::Boolean AddEmpty( const char* theFilterName, ElementType theType ); CORBA::Boolean Delete ( const char* theFilterName ); CORBA::Boolean Replace ( const char* theFilterName, - const char* theNewName, - Filter_ptr theFilter ); + const char* theNewName, + Filter_ptr theFilter ); CORBA::Boolean Save(); CORBA::Boolean SaveAs( const char* aFileName ); @@ -867,7 +1048,7 @@ namespace SMESH */ class SMESH_I_EXPORT FilterManager_i: public virtual POA_SMESH::FilterManager, - public virtual SALOME::GenericObj_i + public virtual SALOME::GenericObj_i { public: FilterManager_i(); @@ -881,10 +1062,13 @@ namespace SMESH Skew_ptr CreateSkew(); Area_ptr CreateArea(); Volume3D_ptr CreateVolume3D(); + MaxElementLength2D_ptr CreateMaxElementLength2D(); + MaxElementLength3D_ptr CreateMaxElementLength3D(); Length_ptr CreateLength(); Length2D_ptr CreateLength2D(); MultiConnection_ptr CreateMultiConnection(); MultiConnection2D_ptr CreateMultiConnection2D(); + BallDiameter_ptr CreateBallDiameter(); BelongToGeom_ptr CreateBelongToGeom(); BelongToPlane_ptr CreateBelongToPlane(); @@ -897,15 +1081,22 @@ namespace SMESH FreeEdges_ptr CreateFreeEdges(); FreeNodes_ptr CreateFreeNodes(); FreeFaces_ptr CreateFreeFaces(); - + + EqualNodes_ptr CreateEqualNodes(); + EqualEdges_ptr CreateEqualEdges(); + EqualFaces_ptr CreateEqualFaces(); + EqualVolumes_ptr CreateEqualVolumes(); + RangeOfIds_ptr CreateRangeOfIds(); - BadOrientedVolume_ptr CreateBadOrientedVolume(); + BareBorderFace_ptr CreateBareBorderFace(); + BareBorderVolume_ptr CreateBareBorderVolume(); + OverConstrainedFace_ptr CreateOverConstrainedFace(); + OverConstrainedVolume_ptr CreateOverConstrainedVolume(); LinearOrQuadratic_ptr CreateLinearOrQuadratic(); - GroupColor_ptr CreateGroupColor(); - ElemGeomType_ptr CreateElemGeomType(); + CoplanarFaces_ptr CreateCoplanarFaces(); LessThan_ptr CreateLessThan(); MoreThan_ptr CreateMoreThan(); @@ -925,6 +1116,9 @@ namespace SMESH Predicate_i* GetPredicate( SMESH::Predicate_ptr thePredicate ); + + const char* FunctorTypeToString(SMESH::FunctorType ft); + SMESH::FunctorType StringToFunctorType(const char* str); } diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index e90e690f7..24b30bb62 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Gen_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #include #include #include @@ -46,14 +45,9 @@ #include #include -#include "Utils_CorbaException.hxx" - -#include "utilities.h" -#include -#include - #ifdef WNT #include + #include #else #include #endif @@ -70,28 +64,28 @@ #define UnLoadLib( handle ) dlclose( handle ); #endif -#include - #include "SMESH_Gen_i.hxx" -#include "SMESH_Mesh_i.hxx" -#include "SMESH_Hypothesis_i.hxx" -#include "SMESH_Algo_i.hxx" -#include "SMESH_Group_i.hxx" -#include "SMESH_PythonDump.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_SpacePosition.hxx" +#include "SMDS_VertexPosition.hxx" #include "SMESHDS_Document.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_GroupOnGeom.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_Hypothesis.hxx" +#include "SMESH_Algo_i.hxx" +#include "SMESH_File.hxx" #include "SMESH_Group.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_Hypothesis.hxx" +#include "SMESH_Hypothesis_i.hxx" +#include "SMESH_Mesh.hxx" #include "SMESH_MeshEditor.hxx" - -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" -#include "SMDS_VertexPosition.hxx" -#include "SMDS_SpacePosition.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMESH_Mesh_i.hxx" +#include "SMESH_PreMeshInfo.hxx" +#include "SMESH_PythonDump.hxx" #include CORBA_SERVER_HEADER(SMESH_Group) #include CORBA_SERVER_HEADER(SMESH_Filter) @@ -99,22 +93,35 @@ #include "DriverMED_W_SMESHDS_Mesh.h" #include "DriverMED_R_SMESHDS_Mesh.h" +#ifdef WITH_CGNS +#include "DriverCGNS_Read.hxx" +#endif +#include "memoire.h" -#include "SALOMEDS_Tool.hxx" -#include "SALOME_NamingService.hxx" -#include "SALOME_LifeCycleCORBA.hxx" -#include "Utils_SINGLETON.hxx" -#include "OpUtil.hxx" +#include -#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "GEOM_Client.hxx" -#include "Utils_ExceptHandlers.hxx" +#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include CORBA_CLIENT_HEADER(SALOME_Session) #include +#include +#include using namespace std; using SMESH::TPythonDump; +using SMESH::TVar; #define NUM_TMP_FILES 2 @@ -150,9 +157,9 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb try { PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject ); return aServant; - } + } catch (...) { - INFOS( "GetServant - Unknown exception was caught!!!" ); + INFOS( "GetServant - Unknown exception was caught!!!" ); return NULL; } } @@ -172,11 +179,11 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject if ( !theSObject->_is_nil() ) { try { if( theSObject->FindAttribute( anAttr, "AttributeIOR" ) ) { - SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr ); - CORBA::String_var aValue = anIOR->Value(); - if( strcmp( aValue, "" ) != 0 ) - anObj = GetORB()->string_to_object( aValue ); - } + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr ); + CORBA::String_var aValue = anIOR->Value(); + if( strcmp( aValue, "" ) != 0 ) + anObj = GetORB()->string_to_object( aValue ); + } } catch( ... ) { INFOS( "SObjectToObject - Unknown exception was caught!!!" ); @@ -189,7 +196,7 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject /*! * GetNS [ static ] * - * Get SALOME_NamingService object + * Get SALOME_NamingService object */ //============================================================================= @@ -209,7 +216,7 @@ SALOME_NamingService* SMESH_Gen_i::GetNS() * * Get SALOME_LifeCycleCORBA object */ -//============================================================================= +//============================================================================= SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { if ( myLCC == NULL ) { myLCC = new SALOME_LifeCycleCORBA( GetNS() ); @@ -224,14 +231,14 @@ SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { * * Get GEOM::GEOM_Gen reference */ -//============================================================================= +//============================================================================= GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() { //CCRT GEOM::GEOM_Gen_var aGeomEngine = //CCRT GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") ); //CCRT return aGeomEngine._retn(); if(CORBA::is_nil(myGeomGen)) { - Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); + Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); myGeomGen=GEOM::GEOM_Gen::_narrow(temp); } return myGeomGen; @@ -252,16 +259,16 @@ SMESH_Gen_i::SMESH_Gen_i() //============================================================================= /*! - * SMESH_Gen_i::SMESH_Gen_i + * SMESH_Gen_i::SMESH_Gen_i * * Standard constructor, used with Container */ //============================================================================= SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId* contId, - const char* instanceName, + PortableServer::POA_ptr poa, + PortableServer::ObjectId* contId, + const char* instanceName, const char* interfaceName ) : Engines_Component_i( orb, poa, contId, instanceName, interfaceName ) { @@ -269,16 +276,40 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, myOrb = CORBA::ORB::_duplicate(orb); myPoa = PortableServer::POA::_duplicate(poa); - + _thisObj = this ; _id = myPoa->activate_object( _thisObj ); - + myIsEmbeddedMode = false; myShapeReader = NULL; // shape reader mySMESHGen = this; + myIsHistoricalPythonDump = true; + myToForgetMeshDataOnHypModif = false; // set it in standalone mode only //OSD::SetSignal( true ); + + // 0020605: EDF 1190 SMESH: Display performance. 80 seconds for 52000 cells. + // find out mode (embedded or standalone) here else + // meshes created before calling SMESH_Client::GetSMESHGen(), which calls + // SMESH_Gen_i::SetEmbeddedMode(), have wrong IsEmbeddedMode flag + if ( SALOME_NamingService* ns = GetNS() ) + { + CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; + if ( !session->_is_nil() ) + { + CORBA::String_var str_host = session->getHostname(); + CORBA::Long s_pid = session->getPID(); + string my_host = Kernel_Utils::GetHostname(); +#ifdef WNT + long my_pid = (long)_getpid(); +#else + long my_pid = (long) getpid(); +#endif + SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() ); + } + } } //============================================================================= @@ -291,7 +322,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, SMESH_Gen_i::~SMESH_Gen_i() { - INFOS( "SMESH_Gen_i::~SMESH_Gen_i" ); + MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" ); // delete hypothesis creators map::iterator itHyp; @@ -308,10 +339,10 @@ SMESH_Gen_i::~SMESH_Gen_i() } myStudyContextMap.clear(); // delete shape reader - if ( !myShapeReader ) + if ( !myShapeReader ) delete myShapeReader; } - + //============================================================================= /*! * SMESH_Gen_i::createHypothesis @@ -349,7 +380,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName } else { - //try to use new format + //try to use new format #ifdef WNT aPlatformLibName = new char[ libNameLen + 5 ]; aPlatformLibName[0] = '\0'; @@ -435,7 +466,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName // activate the CORBA servant of hypothesis hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() ); int nextId = RegisterObject( hypothesis_i ); - if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId ); + if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId ); return hypothesis_i._retn(); } @@ -458,6 +489,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() // create a new mesh object servant, store it in a map in study context SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() ); // create a new mesh object + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode )); // activate the CORBA servant of Mesh @@ -482,7 +514,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() GEOM_Client* SMESH_Gen_i::GetShapeReader() { // create shape reader if necessary - if ( !myShapeReader ) + if ( !myShapeReader ) myShapeReader = new GEOM_Client(GetContainerRef()); ASSERT( myShapeReader ); return myShapeReader; @@ -515,6 +547,7 @@ void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo ) void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode ) { myIsEmbeddedMode = theMode; + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); if ( !myIsEmbeddedMode ) { //PAL10867: disable signals catching with "noexcepthandler" option @@ -559,25 +592,43 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode() void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy ) { - //if(MYDEBUG) - //MESSAGE( "SMESH_Gen_i::SetCurrentStudy" ); + setCurrentStudy( theStudy ); +} + +void SMESH_Gen_i::setCurrentStudy( SALOMEDS::Study_ptr theStudy, + bool theStudyIsBeingClosed) +{ + int curStudyId = GetCurrentStudyID(); myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy ); // create study context, if it doesn't exist and set current study int studyId = GetCurrentStudyID(); - if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SetCurrentStudy: study Id = " << studyId ); if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) { - myStudyContextMap[ studyId ] = new StudyContext; + myStudyContextMap[ studyId ] = new StudyContext; } // myCurrentStudy may be nil - if ( !CORBA::is_nil( myCurrentStudy ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + if ( !theStudyIsBeingClosed && !CORBA::is_nil( myCurrentStudy ) ) { + SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() ) aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() ); - // set current study for geom engine - //if ( !CORBA::is_nil( GetGeomEngine() ) ) - // GetGeomEngine()->GetCurrentStudy( myCurrentStudy->StudyId() ); + // NPAL16168, issue 0020210 + // Let meshes update their data depending on GEOM groups that could change + if ( curStudyId != studyId ) + { + //SALOMEDS::SComponent_var me = PublishComponent( myCurrentStudy ); + SALOMEDS::SComponent_var me = SALOMEDS::SComponent::_narrow + ( myCurrentStudy->FindComponent( ComponentDataType() ) ); + if ( !me->_is_nil() ) { + SALOMEDS::ChildIterator_var anIter = myCurrentStudy->NewChildIterator( me ); + for ( ; anIter->More(); anIter->Next() ) { + SALOMEDS::SObject_var so = anIter->Value(); + CORBA::Object_var ior = SObjectToObject( so ); + if ( SMESH_Mesh_i* mesh = SMESH::DownCast( ior )) + mesh->CheckGeomGroupModif(); + } + } + } } } @@ -597,7 +648,7 @@ SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy() //============================================================================= /*! - * SMESH_Gen_i::GetCurrentStudyContext + * SMESH_Gen_i::GetCurrentStudyContext * * Get current study context */ @@ -613,7 +664,7 @@ StudyContext* SMESH_Gen_i::GetCurrentStudyContext() //============================================================================= /*! - * SMESH_Gen_i::CreateHypothesis + * SMESH_Gen_i::CreateHypothesis * * Create hypothesis/algorothm of given type and publish it in the study */ @@ -711,7 +762,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, } } - // let the temporary hypothesis find out some how parameter values by mesh + // let the temporary hypothesis find out somehow parameter values by mesh if ( hyp->SetParametersByMesh( mesh, shape )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); } @@ -724,6 +775,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, ::SMESH_Hypothesis::TDefaults dflts; dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation(); dflts._nbSegments = myGen.GetDefaultNbSegments(); + dflts._shape = &shape; // let the temporary hypothesis initialize it's values if ( hyp->SetParametersByDefaults( dflts, mesh )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); @@ -755,12 +807,69 @@ void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long theNbSegments ) void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments) throw ( SALOME::SALOME_Exception ) { - if ( theNbSegments ) + if ( theNbSegments > 0 ) myGen.SetDefaultNbSegments( int(theNbSegments) ); else THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM ); } +//============================================================================= +/*! + Set an option value +*/ +//============================================================================= + +void SMESH_Gen_i::SetOption(const char* name, const char* value) +{ + if ( name && value && strlen( value ) > 0 ) + { + string msgToGUI; + if ( strcmp(name, "historical_python_dump") == 0 ) + { + myIsHistoricalPythonDump = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true + msgToGUI = "preferences/SMESH/historical_python_dump/"; + msgToGUI += myIsHistoricalPythonDump ? "true" : "false"; + } + else if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 ) + { + myToForgetMeshDataOnHypModif = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true + msgToGUI = "preferences/SMESH/forget_mesh_on_hyp_modif/"; + msgToGUI += myToForgetMeshDataOnHypModif ? "true" : "false"; + } + + // update preferences in case if SetOption() is invoked from python console + if ( !msgToGUI.empty() ) + { + CORBA::Object_var obj = SMESH_Gen_i::GetNS()->Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ); + if ( !CORBA::is_nil( session ) ) + session->emitMessageOneWay(msgToGUI.c_str()); + } + } +} + +//============================================================================= +/*! + Return an option value +*/ +//============================================================================= + +char* SMESH_Gen_i::GetOption(const char* name) +{ + if ( name ) + { + if ( strcmp(name, "historical_python_dump") == 0 ) + { + return CORBA::string_dup( myIsHistoricalPythonDump ? "true" : "false" ); + } + if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 ) + { + return CORBA::string_dup( myToForgetMeshDataOnHypModif ? "true" : "false" ); + } + } + return CORBA::string_dup( "" ); +} + //============================================================================= /*! * SMESH_Gen_i::CreateMesh @@ -851,7 +960,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV('" << theFileName << "')"; + TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV(r'" << theFileName << "')"; } } @@ -860,8 +969,9 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName aServant->ImportUNVFile( theFileName ); // Dump creation of groups - aServant->GetGroups(); + SMESH::ListOfGroups_var groups = aServant->GetGroups(); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } @@ -873,13 +983,11 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName */ //============================================================================= -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus) - throw ( SALOME::SALOME_Exception ) +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus, + const char* theCommandNameForPython, + const char* theFileNameForPython) { - Unexpect aCatch(SALOME_SalomeException); - if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" ); - // Retrieve mesh names from the file DriverMED_R_SMESHDS_Mesh myReader; myReader.SetFile( theFileName ); @@ -894,23 +1002,21 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, // Python Dump TPythonDump aPythonDump; aPythonDump << "(["; - //TCollection_AsciiString aStr ("(["); if (theStatus == SMESH::DRS_OK) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction aResult->length( aNames.size() ); int i = 0; - + // Iterate through all meshes and create mesh objects for ( list::iterator it = aNames.begin(); it != aNames.end(); it++ ) { // Python Dump - //if (i > 0) aStr += ", "; if (i > 0) aPythonDump << ", "; // create mesh SMESH::SMESH_Mesh_var mesh = createMesh(); - + // publish mesh in the study SALOMEDS::SObject_var aSO; if ( CanPublishInStudy( mesh ) ) @@ -918,37 +1024,85 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, if ( !aSO->_is_nil() ) { // Python Dump aPythonDump << aSO; - //aStr += aSO->GetID(); } else { // Python Dump aPythonDump << "mesh_" << i; -// aStr += "mesh_"; -// aStr += TCollection_AsciiString(i); } // Read mesh data (groups are published automatically by ImportMEDFile()) SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); ASSERT( meshServant ); SMESH::DriverMED_ReadStatus status1 = - meshServant->ImportMEDFile( theFileName, (*it).c_str() ); + meshServant->ImportMEDFile( theFileName, (*it).c_str() ); if (status1 > theStatus) - theStatus = status1; + theStatus = status1; aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); + meshServant->GetImpl().GetMeshDS()->Modified(); } aStudyBuilder->CommitCommand(); } // Update Python script - aPythonDump << "], status) = " << this << ".CreateMeshesFromMED('" << theFileName << "')"; + aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')"; } // Dump creation of groups for ( int i = 0; i < aResult->length(); ++i ) - aResult[ i ]->GetGroups(); + SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups(); return aResult._retn(); } +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" ); + SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, "CreateMeshesFromMED", theFileName); + return result; +} + +//============================================================================= +/*! + * SMESH_Gen_i::CreateMeshFromSAUV + * + * Create mesh and import data from SAUV file + */ +//============================================================================= + +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromSAUV" ); + std::string sauvfilename(theFileName); + std::string medfilename(theFileName); + medfilename += ".med"; + std::string cmd; +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')"; + cmd += "\""; + system(cmd.c_str()); + SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), theStatus, "CreateMeshesFromSAUV", sauvfilename.c_str()); +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; + cmd += "\""; + system(cmd.c_str()); + return result; +} + //============================================================================= /*! * SMESH_Gen_i::CreateMeshFromSTL @@ -974,16 +1128,100 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL('" << theFileName << "')"; + TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')"; } } SMESH_Mesh_i* aServant = dynamic_cast( GetServant( aMesh ).in() ); ASSERT( aServant ); aServant->ImportSTLFile( theFileName ); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } +//================================================================================ +/*! + * \brief Create meshes and import data from the CGSN file + */ +//================================================================================ + +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + SMESH::mesh_array_var aResult = new SMESH::mesh_array(); + +#ifdef WITH_CGNS + // Retrieve nb meshes from the file + DriverCGNS_Read myReader; + myReader.SetFile( theFileName ); + Driver_Mesh::Status aStatus; + int nbMeshes = myReader.GetNbMeshes(aStatus); + theStatus = (SMESH::DriverMED_ReadStatus)aStatus; + + aResult->length( nbMeshes ); + + { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() + + // Python Dump + TPythonDump aPythonDump; + aPythonDump << "(["; + + if (theStatus == SMESH::DRS_OK) + { + SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + + int i = 0; + + // Iterate through all meshes and create mesh objects + for ( ; i < nbMeshes; ++i ) + { + // Python Dump + if (i > 0) aPythonDump << ", "; + + // create mesh + SMESH::SMESH_Mesh_var mesh = createMesh(); + aResult[i] = SMESH::SMESH_Mesh::_duplicate( mesh ); + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); + ASSERT( meshServant ); + string meshName; + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportCGNSFile( theFileName, i, meshName ); + if (status1 > theStatus) + theStatus = status1; + + meshServant->GetImpl().GetMeshDS()->Modified(); + // publish mesh in the study + SALOMEDS::SObject_var aSO; + if ( CanPublishInStudy( mesh ) ) + aSO = PublishMesh( myCurrentStudy, mesh.in(), meshName.c_str() ); + + // Python Dump + if ( !aSO->_is_nil() ) + aPythonDump << aSO; + else + aPythonDump << "mesh_" << i; + } + aStudyBuilder->CommitCommand(); + } + + aPythonDump << "], status) = " << this << ".CreateMeshesFromCGNS(r'" << theFileName << "')"; + } + // Dump creation of groups + for ( int i = 0; i < aResult->length(); ++i ) + SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups(); +#else + THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); +#endif + + return aResult._retn(); +} + //============================================================================= /*! * SMESH_Gen_i::IsReadyToCompute @@ -1000,7 +1238,7 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" ); if ( CORBA::is_nil( theShapeObject ) ) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1068,7 +1306,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo) */ //================================================================================ -SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, +SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) throw ( SALOME::SALOME_Exception ) { @@ -1090,7 +1328,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr shape = GeomObjectToShape( theSubObject ); else shape = SMESH_Mesh::PseudoShape(); - + ::SMESH_Mesh& mesh = meshServant->GetImpl(); error_array->length( mesh.GetMeshDS()->MaxShapeIndex() ); @@ -1130,7 +1368,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr return error_array._retn(); } -// +// //================================================================================ /*! * \brief Return mesh elements preventing computation of a subshape @@ -1225,7 +1463,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, */ //================================================================================ -SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, +SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) throw ( SALOME::SALOME_Exception ) { @@ -1248,7 +1486,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes myLocShape = GeomObjectToShape( theSubObject ); else myLocShape = SMESH_Mesh::PseudoShape(); - + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); list< ::SMESH_Gen::TAlgoStateError > error_list; list< ::SMESH_Gen::TAlgoStateError >::iterator error; @@ -1285,7 +1523,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes //============================================================================= SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject, - const SMESH::object_array& theListOfSubShapeObject ) + const SMESH::object_array& theListOfSubShapeObject ) throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); @@ -1301,47 +1539,47 @@ SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainSha try { TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject); - TopTools_IndexedMapOfShape myIndexToShape; + TopTools_IndexedMapOfShape myIndexToShape; TopExp::MapShapes(myMainShape,myIndexToShape); for ( int i = 0; i < theListOfSubShapeObject.length(); i++ ) - { - GEOM::GEOM_Object_var aShapeObject - = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]); - if ( CORBA::is_nil( aShapeObject ) ) - THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \ - SALOME::BAD_PARAM ); - - TopoDS_Shape locShape = GeomObjectToShape(aShapeObject); - for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next()) - { - const TopoDS_Face& F = TopoDS::Face(exp.Current()); - setId.insert(myIndexToShape.FindIndex(F)); - if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(F)); - } - for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next()) - { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - setId.insert(myIndexToShape.FindIndex(E)); - if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(E)); - } - for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next()) - { - const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); - setId.insert(myIndexToShape.FindIndex(V)); - if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V)); - } - } + { + GEOM::GEOM_Object_var aShapeObject + = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]); + if ( CORBA::is_nil( aShapeObject ) ) + THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \ + SALOME::BAD_PARAM ); + + TopoDS_Shape locShape = GeomObjectToShape(aShapeObject); + for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next()) + { + const TopoDS_Face& F = TopoDS::Face(exp.Current()); + setId.insert(myIndexToShape.FindIndex(F)); + if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(F)); + } + for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next()) + { + const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); + setId.insert(myIndexToShape.FindIndex(E)); + if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(E)); + } + for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next()) + { + const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); + setId.insert(myIndexToShape.FindIndex(V)); + if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V)); + } + } shapesId->length(setId.size()); set::iterator iind; int i=0; for (iind = setId.begin(); iind != setId.end(); iind++) - { - if(MYDEBUG) SCRUTE((*iind)); - shapesId[i] = (*iind); - if(MYDEBUG) SCRUTE(shapesId[i]); - i++; - } + { + if(MYDEBUG) SCRUTE((*iind)); + shapesId[i] = (*iind); + if(MYDEBUG) SCRUTE(shapesId[i]); + i++; + } } catch (SALOME_Exception& S_ex) { @@ -1363,11 +1601,12 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ) { + MEMOSTAT; Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" ); if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1381,6 +1620,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + meshServant->Load(); ASSERT( meshServant ); if ( meshServant ) { // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" @@ -1393,7 +1633,13 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, myLocShape = SMESH_Mesh::PseudoShape(); // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); - return myGen.Compute( myLocMesh, myLocShape); +#ifdef WITH_SMESH_CANCEL_COMPUTE + myGen.PrepareCompute( myLocMesh, myLocShape); +#endif + bool ok = myGen.Compute( myLocMesh, myLocShape); + meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) + myLocMesh.GetMeshDS()->Modified(); + return ok; } } catch ( std::bad_alloc ) { @@ -1408,6 +1654,29 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, return false; } +//============================================================================= +/*! + * SMESH_Gen_i::CancelCompute + * + * Cancel Compute mesh on a shape + */ +//============================================================================= + +void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject ) +{ +#ifdef WITH_SMESH_CANCEL_COMPUTE + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + TopoDS_Shape myLocShape; + if(theMesh->HasShapeToMesh()) + myLocShape = GeomObjectToShape( theShapeObject ); + else + myLocShape = SMESH_Mesh::PseudoShape(); + myGen.CancelCompute( myLocMesh, myLocShape); +#endif +} + //============================================================================= /*! * SMESH_Gen_i::Precompute @@ -1417,16 +1686,16 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, //============================================================================= SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh, - GEOM::GEOM_Object_ptr theShapeObject, - SMESH::Dimension theDimension, - SMESH::long_array& theShapesId) + GEOM::GEOM_Object_ptr theShapeObject, + SMESH::Dimension theDimension, + SMESH::long_array& theShapesId) throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" ); if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1437,6 +1706,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + meshServant->Load(); ASSERT( meshServant ); if ( meshServant ) { // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" @@ -1446,7 +1716,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh if(theMesh->HasShapeToMesh()) myLocShape = GeomObjectToShape( theShapeObject ); else - return result._retn();; + return result._retn();; // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); @@ -1454,132 +1724,132 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh ::MeshDimension aDim = (MeshDimension)theDimension; if ( myGen.Compute( myLocMesh, myLocShape, false, aDim, &shapeIds ) ) { - int nbShapeId = shapeIds.size(); - theShapesId.length( nbShapeId ); - // iterates on shapes and collect mesh entities into mesh preview - TSetOfInt::const_iterator idIt = shapeIds.begin(); - TSetOfInt::const_iterator idEnd = shapeIds.end(); - std::map< int, int > mapOfShIdNb; - std::set< SMESH_TLink > setOfEdge; - std::list< SMDSAbs_ElementType > listOfElemType; - typedef map TNode2LocalIDMap; - typedef TNode2LocalIDMap::iterator TNodeLocalID; - TNode2LocalIDMap mapNode2LocalID; - list< TNodeLocalID > connectivity; - int i, nbConnNodes = 0; - std::set< const SMESH_subMesh* > setOfVSubMesh; - // iterates on shapes - for ( ; idIt != idEnd; idIt++ ) - { - if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() ) - continue; - SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt); - if ( !sm || !sm->IsMeshComputed() ) - continue; - - const TopoDS_Shape& aSh = sm->GetSubShape(); - const int shDim = myGen.GetShapeDim( aSh ); - if ( shDim < 1 || shDim > theDimension ) - continue; - - mapOfShIdNb[ *idIt ] = 0; - theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt; - - SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); - if ( !smDS ) continue; - - if ( theDimension == SMESH::DIM_2D ) - { - SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); - while ( faceIt->more() ) - { - const SMDS_MeshElement* face = faceIt->next(); - int aNbNode = face->NbNodes(); - if ( aNbNode > 4 ) - aNbNode /= 2; // do not take into account additional middle nodes - - SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 1 ); - for ( int nIndx = 1; nIndx <= aNbNode; nIndx++ ) - { - SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx < aNbNode ? nIndx+1 : 1 ); - if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second ) - { - listOfElemType.push_back( SMDSAbs_Edge ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first ); - } - node1 = node2; - } - } - } - else if ( theDimension == SMESH::DIM_1D ) - { - SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes(); - while ( nodeIt->more() ) - { - listOfElemType.push_back( SMDSAbs_Node ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); - } - // add corner nodes by first vertex from edge - SMESH_subMeshIteratorPtr edgeSmIt = - sm->getDependsOnIterator(/*includeSelf*/false, - /*complexShapeFirst*/false); - while ( edgeSmIt->more() ) - { - SMESH_subMesh* vertexSM = edgeSmIt->next(); - // check that vertex is not already treated - if ( !setOfVSubMesh.insert( vertexSM ).second ) - continue; - if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX ) - continue; - - const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS(); - SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes(); - while ( nodeIt->more() ) - { - listOfElemType.push_back( SMDSAbs_Node ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); - } - } - } - } - - // fill node coords and assign local ids to the nodes - int nbNodes = mapNode2LocalID.size(); - result->nodesXYZ.length( nbNodes ); - TNodeLocalID node2ID = mapNode2LocalID.begin(); - for ( i = 0; i < nbNodes; ++i, ++node2ID ) { - node2ID->second = i; - const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first; - result->nodesXYZ[i].x = node->X(); - result->nodesXYZ[i].y = node->Y(); - result->nodesXYZ[i].z = node->Z(); - } - // fill connectivity - result->elementConnectivities.length( nbConnNodes ); - list< TNodeLocalID >::iterator connIt = connectivity.begin(); - for ( i = 0; i < nbConnNodes; ++i, ++connIt ) { - result->elementConnectivities[i] = (*connIt)->second; - } - - // fill element types - result->elementTypes.length( listOfElemType.size() ); - std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin(); - std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end(); - for ( i = 0; typeIt != typeEnd; ++i, ++typeIt ) + int nbShapeId = shapeIds.size(); + theShapesId.length( nbShapeId ); + // iterates on shapes and collect mesh entities into mesh preview + TSetOfInt::const_iterator idIt = shapeIds.begin(); + TSetOfInt::const_iterator idEnd = shapeIds.end(); + std::map< int, int > mapOfShIdNb; + std::set< SMESH_TLink > setOfEdge; + std::list< SMDSAbs_ElementType > listOfElemType; + typedef map TNode2LocalIDMap; + typedef TNode2LocalIDMap::iterator TNodeLocalID; + TNode2LocalIDMap mapNode2LocalID; + list< TNodeLocalID > connectivity; + int i, nbConnNodes = 0; + std::set< const SMESH_subMesh* > setOfVSubMesh; + // iterates on shapes + for ( ; idIt != idEnd; idIt++ ) + { + if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() ) + continue; + SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt); + if ( !sm || !sm->IsMeshComputed() ) + continue; + + const TopoDS_Shape& aSh = sm->GetSubShape(); + const int shDim = myGen.GetShapeDim( aSh ); + if ( shDim < 1 || shDim > theDimension ) + continue; + + mapOfShIdNb[ *idIt ] = 0; + theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt; + + SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + if ( !smDS ) continue; + + if ( theDimension == SMESH::DIM_2D ) + { + SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); + while ( faceIt->more() ) + { + const SMDS_MeshElement* face = faceIt->next(); + int aNbNode = face->NbNodes(); + if ( aNbNode > 4 ) + aNbNode /= 2; // do not take into account additional middle nodes + + SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 0 ); + for ( int nIndx = 0; nIndx < aNbNode; nIndx++ ) + { + SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx+1 < aNbNode ? nIndx+1 : 0 ); + if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second ) + { + listOfElemType.push_back( SMDSAbs_Edge ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first ); + } + node1 = node2; + } + } + } + else if ( theDimension == SMESH::DIM_1D ) + { + SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes(); + while ( nodeIt->more() ) + { + listOfElemType.push_back( SMDSAbs_Node ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); + } + // add corner nodes by first vertex from edge + SMESH_subMeshIteratorPtr edgeSmIt = + sm->getDependsOnIterator(/*includeSelf*/false, + /*complexShapeFirst*/false); + while ( edgeSmIt->more() ) + { + SMESH_subMesh* vertexSM = edgeSmIt->next(); + // check that vertex is not already treated + if ( !setOfVSubMesh.insert( vertexSM ).second ) + continue; + if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX ) + continue; + + const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS(); + SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes(); + while ( nodeIt->more() ) + { + listOfElemType.push_back( SMDSAbs_Node ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); + } + } + } + } + + // fill node coords and assign local ids to the nodes + int nbNodes = mapNode2LocalID.size(); + result->nodesXYZ.length( nbNodes ); + TNodeLocalID node2ID = mapNode2LocalID.begin(); + for ( i = 0; i < nbNodes; ++i, ++node2ID ) { + node2ID->second = i; + const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first; + result->nodesXYZ[i].x = node->X(); + result->nodesXYZ[i].y = node->Y(); + result->nodesXYZ[i].z = node->Z(); + } + // fill connectivity + result->elementConnectivities.length( nbConnNodes ); + list< TNodeLocalID >::iterator connIt = connectivity.begin(); + for ( i = 0; i < nbConnNodes; ++i, ++connIt ) { + result->elementConnectivities[i] = (*connIt)->second; + } + + // fill element types + result->elementTypes.length( listOfElemType.size() ); + std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin(); + std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end(); + for ( i = 0; typeIt != typeEnd; ++i, ++typeIt ) { - SMDSAbs_ElementType elemType = *typeIt; - result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType; - result->elementTypes[i].isPoly = false; - result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1; - } - - // correct number of shapes - theShapesId.length( mapOfShIdNb.size() ); + SMDSAbs_ElementType elemType = *typeIt; + result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType; + result->elementTypes[i].isPoly = false; + result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1; + } + + // correct number of shapes + theShapesId.length( mapOfShIdNb.size() ); } } } @@ -1595,38 +1865,125 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh return result._retn(); } -//================================================================================ + +//============================================================================= /*! - * \brief Return geometrical object the given element is built on - * \param theMesh - the mesh the element is in - * \param theElementID - the element ID - * \param theGeomName - the name of the result geom object if it is not yet published - * \retval GEOM::GEOM_Object_ptr - the found or just published geom object + * SMESH_Gen_i::Evaluate + * + * Evaluate mesh on a shape */ -//================================================================================ +//============================================================================= -GEOM::GEOM_Object_ptr -SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, - CORBA::Long theElementID, - const char* theGeomName) - throw ( SALOME::SALOME_Exception ) +SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject) +// SMESH::long_array& theNbElems) + throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); - - GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID); - if ( !geom->_is_nil() ) { - GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh(); - GEOM::GEOM_Gen_ptr geomGen = GetGeomEngine(); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" ); - // try to find the corresponding SObject - SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() ); - 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 ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) + 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::long_array_var nbels = new SMESH::long_array; + nbels->length(SMESH::Entity_Last); + int i = SMESH::Entity_Node; + for (; i < SMESH::Entity_Last; i++) + nbels[i] = 0; + + // Update Python script + TPythonDump() << "theNbElems = " << this << ".Evaluate( " + << theMesh << ", " << theShapeObject << ")"; + + try { + // get mesh servant + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + ASSERT( meshServant ); + if ( meshServant ) { + // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + meshServant->CheckGeomGroupModif(); + // get local TopoDS_Shape + TopoDS_Shape myLocShape; + if(theMesh->HasShapeToMesh()) + myLocShape = GeomObjectToShape( theShapeObject ); + else + myLocShape = SMESH_Mesh::PseudoShape(); + // call implementation compute + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + MapShapeNbElems aResMap; + /*CORBA::Boolean ret =*/ myGen.Evaluate( myLocMesh, myLocShape, aResMap); + MapShapeNbElemsItr anIt = aResMap.begin(); + for(; anIt!=aResMap.end(); anIt++) { + const vector& aVec = (*anIt).second; + for(i = SMESH::Entity_Node; i < aVec.size(); i++) { + int nbElem = aVec[i]; + if ( nbElem < 0 ) // algo failed, check that it has reported a message + { + SMESH_subMesh* sm = anIt->first; + SMESH_ComputeErrorPtr& error = sm->GetComputeError(); + const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape()); + if ( (algo && !error.get()) || error->IsOK() ) + error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo)); + } + else + { + nbels[i] += aVec[i]; + } + } + } + return nbels._retn(); + } + } + catch ( std::bad_alloc ) { + INFOS( "Evaluate(): lack of memory" ); + } + catch ( SALOME_Exception& S_ex ) { + INFOS( "Evaluate(): catch exception "<< S_ex.what() ); + } + catch ( ... ) { + INFOS( "Evaluate(): unknown exception " ); + } + + return nbels._retn(); +} + +//================================================================================ +/*! + * \brief Return geometrical object the given element is built on + * \param theMesh - the mesh the element is in + * \param theElementID - the element ID + * \param theGeomName - the name of the result geom object if it is not yet published + * \retval GEOM::GEOM_Object_ptr - the found or just published geom object + */ +//================================================================================ + +GEOM::GEOM_Object_ptr +SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, + CORBA::Long theElementID, + const char* theGeomName) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID); + if ( !geom->_is_nil() ) { + GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh(); + GEOM::GEOM_Gen_ptr geomGen = GetGeomEngine(); + + // try to find the corresponding SObject + SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() ); + 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() ) { @@ -1716,7 +2073,7 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, } if ( !geom->_is_nil() ) { GeomObjectToShape( geom ); // let geom client remember the found shape - return geom._retn(); + return geom._retn(); } } } @@ -1733,16 +2090,16 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, //================================================================================ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance) + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, + CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ) { return ConcatenateCommon(theMeshesArray, - theUniteIdenticalGroups, - theMergeNodesAndElements, - theMergeTolerance, - false); + theUniteIdenticalGroups, + theMergeNodesAndElements, + theMergeTolerance, + false); } //================================================================================ @@ -1756,8 +2113,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshe SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ) { @@ -1765,7 +2122,7 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, theUniteIdenticalGroups, theMergeNodesAndElements, theMergeTolerance, - true); + true); } //================================================================================ @@ -1778,10 +2135,10 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance, - CORBA::Boolean theCommonGroups) + CORBA::Boolean theCommonGroups) throw ( SALOME::SALOME_Exception ) { typedef map TIDsMap; @@ -1789,16 +2146,18 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, typedef map< pair, TListOfNewGroups > TGroupsMap; typedef std::set TGroups; - TPythonDump aPythonDump; // prevent dump of called methods + TPythonDump* pPythonDump = new TPythonDump; + TPythonDump& aPythonDump = *pPythonDump; // prevent dump of called methods // create mesh SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh(); - + + SMESHDS_Mesh* aNewMeshDS = 0; if ( !aNewMesh->_is_nil() ) { SMESH_Mesh_i* aNewImpl = dynamic_cast( GetServant( aNewMesh ).in() ); if ( aNewImpl ) { ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl(); - SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS(); + aNewMeshDS = aLocMesh.GetMeshDS(); TGroupsMap aGroupsMap; TListOfNewGroups aListOfNewGroups; @@ -1807,240 +2166,280 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, // 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( 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; - - int anNbNodes = 0; - int anNbEdges = 0; - int anNbFaces = 0; - int anNbVolumes = 0; - - SMESH::long_array_var anIDsNodes = new SMESH::long_array(); - SMESH::long_array_var anIDsEdges = new SMESH::long_array(); - SMESH::long_array_var anIDsFaces = new SMESH::long_array(); - SMESH::long_array_var anIDsVolumes = new SMESH::long_array(); - - if( theCommonGroups ) { - anIDsNodes->length( anInitMeshDS->NbNodes() ); - anIDsEdges->length( anInitMeshDS->NbEdges() ); - anIDsFaces->length( anInitMeshDS->NbFaces() ); - anIDsVolumes->length( anInitMeshDS->NbVolumes() ); - } - - for ( int j = 0; itElems->more(); j++) { - anElem = itElems->next(); - SMDSAbs_ElementType anElemType = anElem->GetType(); - anElemNbNodes = anElem->NbNodes(); - std::vector 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(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()) ); - if( theCommonGroups ) - anIDsNodes[anNbNodes++] = 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 (anElem); - if ( aVolume ) { - aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, - aVolume->GetQuanities()); - elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); - if( theCommonGroups ) - anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); - } - } - else { - - aNewElem = aNewEditor.AddElement(aNodesArray, - anElemType, - anElem->IsPoly()); - elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); - if( theCommonGroups ) { - if( anElemType == SMDSAbs_Edge ) - anIDsEdges[anNbEdges++] = aNewElem->GetID(); - else if( anElemType == SMDSAbs_Face ) - anIDsFaces[anNbFaces++] = aNewElem->GetID(); - else if( anElemType == SMDSAbs_Volume ) - anIDsVolumes[anNbVolumes++] = 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; - - SMESH::ElementType aGroupType; - CORBA::String_var aGroupName; - if ( theCommonGroups ) { - for(aGroupType=SMESH::NODE;aGroupType<=SMESH::VOLUME;aGroupType=(SMESH::ElementType)(aGroupType+1)) { - string str = "Gr"; - SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh ); - if(aMeshSObj) - str += aMeshSObj->GetName(); - str += "_"; - - int anLen = 0; - - switch(aGroupType) { - case SMESH::NODE: - str += "Nodes"; - anIDsNodes->length(anNbNodes); - anLen = anNbNodes; - break; - case SMESH::EDGE: - str += "Edges"; - anIDsEdges->length(anNbEdges); - anLen = anNbEdges; - break; - case SMESH::FACE: - str += "Faces"; - anIDsFaces->length(anNbFaces); - anLen = anNbFaces; - break; - case SMESH::VOLUME: - str += "Volumes"; - anIDsVolumes->length(anNbVolumes); - anLen = anNbVolumes; - break; - default: - break; - } - - if(anLen) { - aGroupName = str.c_str(); - - // add a new group in the mesh - aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); - - switch(aGroupType) { - case SMESH::NODE: - aNewGroup->Add( anIDsNodes ); - break; - case SMESH::EDGE: - aNewGroup->Add( anIDsEdges ); - break; - case SMESH::FACE: - aNewGroup->Add( anIDsFaces ); - break; - case SMESH::VOLUME: - aNewGroup->Add( anIDsVolumes ); - break; - default: - break; - } - - aListOfNewGroups.clear(); - aListOfNewGroups.push_back(aNewGroup); - aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); - } - } - } - - // check that current group name and type don't have identical ones in union mesh - for (int i = 0; i < aListOfGroups->length(); i++) { - aGroup = aListOfGroups[i]; - aListOfNewGroups.clear(); - aGroupType = aGroup->GetType(); - 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 - } - } + SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i]; + if ( !anInitMesh->_is_nil() ) { + SMESH_Mesh_i* anInitImpl = dynamic_cast( 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; + + int anNbNodes = 0; + int anNbEdges = 0; + int anNbFaces = 0; + int anNbVolumes = 0; + int aNbBalls = 0; + + SMESH::long_array_var anIDsNodes = new SMESH::long_array(); + SMESH::long_array_var anIDsEdges = new SMESH::long_array(); + SMESH::long_array_var anIDsFaces = new SMESH::long_array(); + SMESH::long_array_var anIDsVolumes = new SMESH::long_array(); + SMESH::long_array_var anIDsBalls = new SMESH::long_array(); + + if( theCommonGroups ) { + anIDsNodes->length( anInitMeshDS->NbNodes() ); + anIDsEdges->length( anInitMeshDS->NbEdges() ); + anIDsFaces->length( anInitMeshDS->NbFaces() ); + anIDsVolumes->length( anInitMeshDS->NbVolumes() ); + anIDsBalls->length( anInitMeshDS->NbBalls() ); + } + + for ( int j = 0; itElems->more(); j++) { + anElem = itElems->next(); + SMDSAbs_ElementType anElemType = anElem->GetType(); + anElemNbNodes = anElem->NbNodes(); + std::vector 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(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()) ); + if( theCommonGroups ) + anIDsNodes[anNbNodes++] = 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 + switch ( anElem->GetEntityType() ) { + case SMDSEntity_Polyhedra: + if ( const SMDS_VtkVolume* aVolume = + dynamic_cast (anElem)) + { + aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, + aVolume->GetQuantities()); + elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); + if( theCommonGroups ) + anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); + } + break; + case SMDSEntity_Ball: + if ( const SMDS_BallElement* aBall = + dynamic_cast (anElem)) + { + aNewElem = aNewEditor.AddElement(aNodesArray, SMDSAbs_Ball, + /*isPoly=*/false, /*id=*/0, + aBall->GetDiameter() ); + elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); + if( theCommonGroups ) + anIDsBalls[aNbBalls++] = aNewElem->GetID(); + } + break; + default: + { + aNewElem = aNewEditor.AddElement(aNodesArray, + anElemType, + anElem->IsPoly()); + elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); + if( theCommonGroups ) { + if( anElemType == SMDSAbs_Edge ) + anIDsEdges[anNbEdges++] = aNewElem->GetID(); + else if( anElemType == SMDSAbs_Face ) + anIDsFaces[anNbFaces++] = aNewElem->GetID(); + else if( anElemType == SMDSAbs_Volume ) + anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); + } + } + } + }//elems loop + + // copy orphan nodes + SMDS_NodeIteratorPtr itNodes = anInitMeshDS->nodesIterator(); + while ( itNodes->more() ) + { + const SMDS_MeshNode* aNode = itNodes->next(); + if ( aNode->NbInverseElements() == 0 ) + { + const SMDS_MeshNode* aNewNode = + aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z()); + nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) ); + if( theCommonGroups ) + anIDsNodes[anNbNodes++] = aNewNode->GetID(); + } + } + + + aListOfGroups = anInitImpl->GetGroups(); + SMESH::SMESH_GroupBase_ptr aGroup; + + // 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; + + SMESH::ElementType aGroupType; + CORBA::String_var aGroupName; + if ( theCommonGroups ) { + for(aGroupType=SMESH::NODE;aGroupType<=SMESH::BALL;aGroupType=(SMESH::ElementType)(aGroupType+1)) { + string str = "Gr"; + SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh ); + if(aMeshSObj) + str += aMeshSObj->GetName(); + str += "_"; + + int anLen = 0; + + switch(aGroupType) { + case SMESH::NODE: + str += "Nodes"; + anIDsNodes->length(anNbNodes); + anLen = anNbNodes; + break; + case SMESH::EDGE: + str += "Edges"; + anIDsEdges->length(anNbEdges); + anLen = anNbEdges; + break; + case SMESH::FACE: + str += "Faces"; + anIDsFaces->length(anNbFaces); + anLen = anNbFaces; + break; + case SMESH::VOLUME: + str += "Volumes"; + anIDsVolumes->length(anNbVolumes); + anLen = anNbVolumes; + break; + case SMESH::BALL: + str += "Balls"; + anIDsBalls->length(aNbBalls); + anLen = aNbBalls; + break; + default: + break; + } + + if(anLen) { + aGroupName = str.c_str(); + + // add a new group in the mesh + aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); + + switch(aGroupType) { + case SMESH::NODE: + aNewGroup->Add( anIDsNodes ); + break; + case SMESH::EDGE: + aNewGroup->Add( anIDsEdges ); + break; + case SMESH::FACE: + aNewGroup->Add( anIDsFaces ); + break; + case SMESH::VOLUME: + aNewGroup->Add( anIDsVolumes ); + break; + case SMESH::BALL: + aNewGroup->Add( anIDsBalls ); + break; + default: + break; + } + + aListOfNewGroups.clear(); + aListOfNewGroups.push_back(aNewGroup); + aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); + } + } + } + + // check that current group name and type don't have identical ones in union mesh + for (int i = 0; i < aListOfGroups->length(); i++) { + aGroup = aListOfGroups[i]; + aListOfNewGroups.clear(); + aGroupType = aGroup->GetType(); + 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 aMeshNodes; // no input nodes - SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes; - aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes ); - aNewEditor.MergeNodes( aGroupsOfNodes ); - // merge elements - aNewEditor.MergeEqualElements(); + // merge nodes + TIDSortedNodeSet 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; if( !theCommonGroups ) @@ -2054,12 +2453,309 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, } aPythonDump << "], "; aPythonDump << theUniteIdenticalGroups << ", " - << theMergeNodesAndElements << ", " - << theMergeTolerance << ")"; + << theMergeNodesAndElements << ", " + << TVar( theMergeTolerance ) << ")"; + + delete pPythonDump; // enable python dump from GetGroups() + + // 0020577: EDF 1164 SMESH: Bad dump of concatenate with create common groups + if ( !aNewMesh->_is_nil() ) + { + SMESH::ListOfGroups_var groups = aNewMesh->GetGroups(); + } + // IPAL21468 Change icon of compound because it need not be computed. + SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh ); + SetPixMap( aMeshSObj, "ICON_SMESH_TREE_MESH" ); + + if (aNewMeshDS) + aNewMeshDS->Modified(); return aNewMesh._retn(); } +//================================================================================ +/*! + * \brief Create a mesh by copying a part of another mesh + * \param meshPart - a part of mesh to copy + * \param toCopyGroups - to create in the new mesh groups + * the copied elements belongs to + * \param toKeepIDs - to preserve IDs of the copied elements or not + * \retval SMESH::SMESH_Mesh_ptr - the new mesh + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, + const char* meshName, + CORBA::Boolean toCopyGroups, + CORBA::Boolean toKeepIDs) +{ + Unexpect aCatch(SALOME_SalomeException); + + TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh() + + // 1. Get source mesh + + if ( CORBA::is_nil( meshPart )) + THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM ); + + SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh(); + SMESH_Mesh_i* srcMesh_i = SMESH::DownCast( srcMesh ); + if ( !srcMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM ); + + SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS(); + + // 2. Make a new mesh + + SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil()); + SMESH_Mesh_i* newMesh_i = SMESH::DownCast( newMesh ); + if ( !newMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR ); + SALOMEDS::SObject_var meshSO = ObjectToSObject(myCurrentStudy, newMesh ); + if ( !meshSO->_is_nil() ) + { + SetName( meshSO, meshName, "Mesh" ); + SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED"); + } + SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS(); + ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() ); + + // 3. Get elements to copy + + SMDS_ElemIteratorPtr srcElemIt; SMDS_NodeIteratorPtr srcNodeIt; + TIDSortedElemSet srcElems; + SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes(); + if ( SMESH::DownCast( meshPart )) + { + srcElemIt = srcMeshDS->elementsIterator(); + srcNodeIt = srcMeshDS->nodesIterator(); + } + else + { + SMESH::long_array_var ids = meshPart->GetIDs(); + if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes + { + for (int i=0; i < ids->length(); i++) + if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] )) + srcElems.insert( elem ); + } + else + { + for (int i=0; i < ids->length(); i++) + if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] )) + srcElems.insert( elem ); + } + if ( srcElems.empty() ) + return newMesh._retn(); + + typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter; + srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() )); + } + + // 4. Copy elements + + typedef map TE2EMap; + TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ]; + TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ]; + int iN; + const SMDS_MeshNode *nSrc, *nTgt; + vector< const SMDS_MeshNode* > nodes; + while ( srcElemIt->more() ) + { + const SMDS_MeshElement * elem = srcElemIt->next(); + // find / add nodes + nodes.resize( elem->NbNodes()); + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + if ( toKeepIDs ) { + for ( iN = 0; nIt->more(); ++iN ) + { + nSrc = static_cast( nIt->next() ); + nTgt = newMeshDS->FindNode( nSrc->GetID()); + if ( !nTgt ) + nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + nodes[ iN ] = nTgt; + } + } + else { + for ( iN = 0; nIt->more(); ++iN ) + { + nSrc = static_cast( nIt->next() ); + TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first; + if ( !n2n->second ) + n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() ); + nodes[ iN ] = (const SMDS_MeshNode*) n2n->second; + } + } + // add elements + if ( elem->GetType() != SMDSAbs_Node ) + { + int ID = toKeepIDs ? elem->GetID() : 0; + const SMDS_MeshElement * newElem; + switch ( elem->GetEntityType() ) { + case SMDSEntity_Polyhedra: + newElem = editor.GetMeshDS()-> + AddPolyhedralVolumeWithID( nodes, + static_cast(elem)->GetQuantities(), + ID); + break; + case SMDSEntity_Ball: + newElem = editor.AddElement( nodes, SMDSAbs_Ball, false, ID, + static_cast(elem)->GetDiameter()); + break; + default: + newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID); + + if ( toCopyGroups && !toKeepIDs ) + e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem )); + } + } + } // while ( srcElemIt->more() ) + + // 4(b). Copy free nodes + + if ( srcNodeIt && srcMeshDS->NbNodes() != newMeshDS->NbNodes() ) + { + while ( srcNodeIt->more() ) + { + nSrc = srcNodeIt->next(); + if ( nSrc->NbInverseElements() == 0 ) + { + if ( toKeepIDs ) + nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + else + n2nMap[ nSrc ] = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() ); + } + } + } + + // 5. Copy groups + + int nbNewGroups = 0; + if ( toCopyGroups ) + { + SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups(); + while ( gIt->more() ) + { + SMESH_Group* group = gIt->next(); + const SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + + // Check group type. We copy nodal groups containing nodes of copied element + SMDSAbs_ElementType groupType = groupDS->GetType(); + if ( groupType != SMDSAbs_Node && + newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 ) + continue; // group type differs from types of meshPart + + // Find copied elements in the group + vector< const SMDS_MeshElement* > groupElems; + SMDS_ElemIteratorPtr eIt = groupDS->GetElements(); + if ( toKeepIDs ) + { + const SMDS_MeshElement* foundElem; + if ( groupType == SMDSAbs_Node ) + { + while ( eIt->more() ) + if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() ))) + groupElems.push_back( foundElem ); + } + else + { + while ( eIt->more() ) + if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() ))) + groupElems.push_back( foundElem ); + } + } + else + { + TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ]; + if ( e2eMap.empty() ) continue; + int minID = e2eMap.begin()->first->GetID(); + int maxID = e2eMap.rbegin()->first->GetID(); + TE2EMap::iterator e2e; + while ( eIt->more() && groupElems.size() < e2eMap.size()) + { + const SMDS_MeshElement* e = eIt->next(); + if ( e->GetID() < minID || e->GetID() > maxID ) continue; + if ((e2e = e2eMap.find( e )) != e2eMap.end()) + groupElems.push_back( e2e->second ); + } + } + // Make a new group + if ( !groupElems.empty() ) + { + SMESH::SMESH_Group_var newGroupObj = + newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() ); + if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast( newGroupObj)) + { + SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS(); + SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup(); + for ( unsigned i = 0; i < groupElems.size(); ++i ) + smdsGroup.Add( groupElems[i] ); + + nbNewGroups++; + } + } + } + } + + newMeshDS->Modified(); + + *pyDump << newMesh << " = " << this + << ".CopyMesh( " << meshPart << ", " + << "'" << meshName << "', " + << toCopyGroups << ", " + << toKeepIDs << ")"; + + delete pyDump; pyDump = 0; // allow dump in GetGroups() + + if ( nbNewGroups > 0 ) // dump created groups + SMESH::ListOfGroups_var groups = newMesh->GetGroups(); + + return newMesh._retn(); +} + +//================================================================================ +/*! + * SMESH_Gen_i::GetMEDVersion + * + * Get MED version of the file by its name + */ +//================================================================================ +CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName, + SMESH::MED_VERSION& theVersion) +{ + theVersion = SMESH::MED_V2_1; + MED::EVersion aVersion = MED::GetVersionId( theFileName ); + switch( aVersion ) { + case MED::eV2_1 : theVersion = SMESH::MED_V2_1; return true; + case MED::eV2_2 : theVersion = SMESH::MED_V2_2; return true; + case MED::eVUnknown : return false; + } + return false; +} + +//================================================================================ +/*! + * SMESH_Gen_i::GetMeshNames + * + * Get names of meshes defined in file with the specified name + */ +//================================================================================ +SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName) +{ + SMESH::string_array_var aResult = new SMESH::string_array(); + MED::PWrapper aMed = MED::CrWrapper( theFileName ); + MED::TErr anErr; + MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr ); + if( anErr >= 0 ) { + aResult->length( aNbMeshes ); + for( MED::TInt i = 0; i < aNbMeshes; i++ ) { + MED::PMeshInfo aMeshInfo = aMed->GetPMeshInfo( i+1 ); + aResult[i] = CORBA::string_dup( aMeshInfo->GetName().c_str() ); + } + } + return aResult._retn(); +} + //============================================================================= /*! * SMESH_Gen_i::Save @@ -2076,7 +2772,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() ) // san -- in case differs from theComponent's study, // use that of the component - if ( myCurrentStudy->_is_nil() || + if ( myCurrentStudy->_is_nil() || theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() ) SetCurrentStudy( theComponent->GetStudy() ); @@ -2097,7 +2793,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aFileSeq->length( NUM_TMP_FILES ); TCollection_AsciiString aStudyName( "" ); - if ( isMultiFile ) + if ( isMultiFile ) aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() ); // Set names of temporary files @@ -2136,6 +2832,41 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, DriverMED_W_SMESHDS_Mesh myWriter; myWriter.SetFile( meshfile.ToCString() ); + // IMP issue 20918 + // SetStoreName() to groups before storing hypotheses to let them refer to + // groups using "store name", which is "Group " + { + SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent ); + for ( ; itBig->More(); itBig->Next() ) { + SALOMEDS::SObject_var gotBranch = itBig->Value(); + if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) { + CORBA::Object_var anObject = SObjectToObject( gotBranch ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ; + if ( !myMesh->_is_nil() ) { + myMesh->Load(); // load from study file if not yet done + TPythonDump pd; // not to dump GetGroups() + SMESH::ListOfGroups_var groups = myMesh->GetGroups(); + pd << ""; // to avoid optimizing pd out + for ( int i = 0; i < groups->length(); ++i ) + { + SMESH_GroupBase_i* grImpl = SMESH::DownCast( groups[i]); + if ( grImpl ) + { + CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() ); + int anId = myStudyContext->findId( string( objStr.in() ) ); + char grpName[ 30 ]; + sprintf( grpName, "Group %d", anId ); + SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS(); + aGrpBaseDS->SetStoreName( grpName ); + } + } + } + } + } + } + } + // Write data // ---> create HDF file aFile = new HDFfile( (char*) filename.ToCString() ); @@ -2319,17 +3050,33 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( ( char* )( strHasData.c_str() ) ); aDataset->CloseOnDisk(); - // ouv : NPAL12872 + // ouv : NPAL12872 // for each mesh open the HDF group basing on its auto color parameter - char meshAutoColorName[ 30 ]; - sprintf( meshAutoColorName, "AutoColorMesh %d", id ); - int anAutoColor[1]; - anAutoColor[0] = myImpl->GetAutoColor(); - aSize[ 0 ] = 1; - aDataset = new HDFdataset( meshAutoColorName, aTopGroup, HDF_INT32, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( anAutoColor ); - aDataset->CloseOnDisk(); + char meshAutoColorName[ 30 ]; + sprintf( meshAutoColorName, "AutoColorMesh %d", id ); + int anAutoColor[1]; + anAutoColor[0] = myImpl->GetAutoColor(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( meshAutoColorName, aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( anAutoColor ); + aDataset->CloseOnDisk(); + + // issue 0020693. Store _isModified flag + int isModified = myLocMesh.GetIsModified(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &isModified ); + aDataset->CloseOnDisk(); + + // issue 20918. Store Persistent Id of SMESHDS_Mesh + int meshPersistentId = mySMESHDSMesh->GetPersistentId(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "meshPersistentId", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &meshPersistentId ); + aDataset->CloseOnDisk(); // write reference on a shape if exists SALOMEDS::SObject_var myRef; @@ -2370,7 +3117,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( ok ) { // san - it is impossible to recover applied hypotheses // using their entries within Load() method, - // for there are no AttributeIORs in the study when Load() is working. + // for there are no AttributeIORs in the study when Load() is working. // Hence, it is better to store persistent IDs of hypotheses as references to them //string myRefOnObject = myRefOnHyp->GetID(); @@ -2413,7 +3160,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, if ( ok ) { // san - it is impossible to recover applied algorithms // using their entries within Load() method, - // for there are no AttributeIORs in the study when Load() is working. + // for there are no AttributeIORs in the study when Load() is working. // Hence, it is better to store persistent IDs of algorithms as references to them //string myRefOnObject = myRefOnAlgo->GetID(); @@ -2563,382 +3310,430 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, //} } } - aSubSubGroup->CloseOnDisk(); - } + aSubSubGroup->CloseOnDisk(); + } + + // write applied algorithms if exist + SALOMEDS::SObject_var mySubAlgoBranch; + found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch ); + if ( found ) { + aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); + aSubSubGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch ); + int algoNb = 0; + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySubSObject = it->Value(); + SALOMEDS::SObject_var myRefOnAlgo; + bool ok = mySubSObject->ReferencedObject( myRefOnAlgo ); + if ( ok ) { + //string myRefOnObject = myRefOnAlgo->GetID(); + CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo ); + CORBA::String_var objStr = GetORB()->object_to_string( anObject ); + int id = myStudyContext->findId( string( objStr.in() ) ); + //if ( myRefOnObject.length() > 0 ) { + //aSize[ 0 ] = myRefOnObject.length() + 1; + char algoName[ 30 ], algoId[ 30 ]; + sprintf( algoName, "Algo %d", ++algoNb ); + sprintf( algoId, "%d", id ); + aSize[ 0 ] = strlen( algoId ) + 1; + aDataset = new HDFdataset( algoName, aSubSubGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->WriteOnDisk( algoId ); + aDataset->CloseOnDisk(); + //} + } + } + aSubSubGroup->CloseOnDisk(); + } + // close submesh HDF group + aSubGroup->CloseOnDisk(); + } + } + // close container of submeshes by type HDF group + aGroup->CloseOnDisk(); + } + } + // All sub-meshes will be stored in MED file + // .. will NOT (PAL 12992) + //if ( shapeRefFound ) + //myWriter.AddAllSubMeshes(); + + // store submesh order if any + const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder(); + if ( theOrderIds.size() ) { + char order_list[ 30 ]; + strcpy( order_list, "Mesh Order" ); + // count number of submesh ids + int nbIDs = 0; + TListOfListOfInt::const_iterator idIt = theOrderIds.begin(); + for ( ; idIt != theOrderIds.end(); idIt++ ) + nbIDs += (*idIt).size(); + // number of values = number of IDs + + // number of lists (for separators) - 1 + int* smIDs = new int [ nbIDs + theOrderIds.size() - 1 ]; + idIt = theOrderIds.begin(); + for ( int i = 0; idIt != theOrderIds.end(); idIt++ ) { + const TListOfInt& idList = *idIt; + if (idIt != theOrderIds.begin()) // not first list + smIDs[ i++ ] = -1/* *idList.size()*/; // separator between lists + // dump submesh ids from current list + TListOfInt::const_iterator id_smId = idList.begin(); + for( ; id_smId != idList.end(); id_smId++ ) + smIDs[ i++ ] = *id_smId; + } + // write HDF group + aSize[ 0 ] = nbIDs + theOrderIds.size() - 1; + + aDataset = new HDFdataset( order_list, aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( smIDs ); + aDataset->CloseOnDisk(); + // + delete[] smIDs; + } + + // groups root sub-branch + SALOMEDS::SObject_var myGroupsBranch; + for ( int i = GetNodeGroupsTag(); i <= GetBallElementsGroupsTag(); i++ ) { + found = gotBranch->FindSubObject( i, myGroupsBranch ); + if ( found ) { + char name_group[ 30 ]; + if ( i == GetNodeGroupsTag() ) + strcpy( name_group, "Groups of Nodes" ); + else if ( i == GetEdgeGroupsTag() ) + strcpy( name_group, "Groups of Edges" ); + else if ( i == GetFaceGroupsTag() ) + strcpy( name_group, "Groups of Faces" ); + else if ( i == GetVolumeGroupsTag() ) + strcpy( name_group, "Groups of Volumes" ); + else if ( i == Get0DElementsGroupsTag() ) + strcpy( name_group, "Groups of 0D Elements" ); + else if ( i == GetBallElementsGroupsTag() ) + strcpy( name_group, "Groups of Balls" ); + + aGroup = new HDFgroup( name_group, aTopGroup ); + aGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch ); + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_var mySObject = it->Value(); + CORBA::Object_var aSubObject = SObjectToObject( mySObject ); + if ( !CORBA::is_nil( aSubObject ) ) { + SMESH_GroupBase_i* myGroupImpl = + dynamic_cast( GetServant( aSubObject ).in() ); + if ( !myGroupImpl ) + continue; + SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS(); + if ( !aGrpBaseDS ) + continue; + + CORBA::String_var objStr = GetORB()->object_to_string( aSubObject ); + int anId = myStudyContext->findId( string( objStr.in() ) ); + + // For each group, create a dataset named "Group " + // and store the group's user name into it + const char* grpName = aGrpBaseDS->GetStoreName(); + char* aUserName = myGroupImpl->GetName(); + aSize[ 0 ] = strlen( aUserName ) + 1; + + aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aUserName ); + aDataset->CloseOnDisk(); + + // ouv : NPAL12872 + // For each group, create a dataset named "Group Color" + // and store the group's color into it + char grpColorName[ 30 ]; + sprintf( grpColorName, "ColorGroup %d", anId ); + SALOMEDS::Color aColor = myGroupImpl->GetColor(); + double anRGB[3]; + anRGB[ 0 ] = aColor.R; + anRGB[ 1 ] = aColor.G; + anRGB[ 2 ] = aColor.B; + aSize[ 0 ] = 3; + aDataset = new HDFdataset( grpColorName, aGroup, HDF_FLOAT64, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( anRGB ); + aDataset->CloseOnDisk(); + + // Pass SMESHDS_Group to MED writer + SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); + if ( aGrpDS ) + myWriter.AddGroup( aGrpDS ); + + // write reference on a shape if exists + SMESHDS_GroupOnGeom* aGeomGrp = + dynamic_cast( aGrpBaseDS ); + if ( aGeomGrp ) { + SALOMEDS::SObject_var mySubRef, myShape; + if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) && + mySubRef->ReferencedObject( myShape ) && + !CORBA::is_nil( myShape->GetObject() )) + { + string myRefOnObject = myShape->GetID(); + if ( myRefOnObject.length() > 0 ) { + char aRefName[ 30 ]; + sprintf( aRefName, "Ref on shape %d", anId); + aSize[ 0 ] = myRefOnObject.length() + 1; + aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->CloseOnDisk(); + } + } + else // shape ref is invalid: + { + // save a group on geometry as ordinary group + myWriter.AddGroup( aGeomGrp ); + } + } + else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = + dynamic_cast( myGroupImpl )) + { + std::string str = aFilterGrp_i->FilterToString(); + std::string hdfGrpName = "Filter " + SMESH_Comment(anId); + aSize[ 0 ] = str.length() + 1; + aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup, HDF_STRING, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( str.c_str() ) ); + aDataset->CloseOnDisk(); + } + } + } + aGroup->CloseOnDisk(); + } + } // loop on groups + + if ( strcmp( strHasData.c_str(), "1" ) == 0 ) + { + // Flush current mesh information into MED file + myWriter.Perform(); + + // save info on nb of elements + SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile ); + + // maybe a shape was deleted in the study + if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) { + TopoDS_Shape nullShape; + myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data + } + + if ( !mySMESHDSMesh->SubMeshes().empty() ) + { + // Store submeshes + // ---------------- + aGroup = new HDFgroup( "Submeshes", aTopGroup ); + aGroup->CreateOnDisk(); + + // each element belongs to one or none submesh, + // so for each node/element, we store a submesh ID + + // Make maps of submesh IDs of elements sorted by element IDs + typedef int TElemID; + typedef int TSubMID; + map< TElemID, TSubMID > eId2smId, nId2smId; + map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint + const map& aSubMeshes = mySMESHDSMesh->SubMeshes(); + map::const_iterator itSubM ( aSubMeshes.begin() ); + SMDS_NodeIteratorPtr itNode; + SMDS_ElemIteratorPtr itElem; + for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) + { + TSubMID aSubMeID = itSubM->first; + SMESHDS_SubMesh* aSubMesh = itSubM->second; + if ( aSubMesh->IsComplexSubmesh() ) + continue; // submesh containing other submeshs + // nodes + hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh + for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint) + hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID )); + // elements + hint = eId2smId.begin(); + for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint) + hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID )); + } + + // Care of elements that are not on submeshes + if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) { + for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); ) + /* --- stl_map.h says : */ + /* A %map relies on unique keys and thus a %pair is only inserted if its */ + /* first element (the key) is not already present in the %map. */ + nId2smId.insert( make_pair( itNode->next()->GetID(), 0 )); + } + int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes(); + if ( nbElems != eId2smId.size() ) { + for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); ) + eId2smId.insert( make_pair( itElem->next()->GetID(), 0 )); + } + + // Store submesh IDs + for ( int isNode = 0; isNode < 2; ++isNode ) + { + map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId; + if ( id2smId.empty() ) continue; + map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin(); + // make and fill array of submesh IDs + int* smIDs = new int [ id2smId.size() ]; + for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i ) + smIDs[ i ] = id_smId->second; + // write HDF group + aSize[ 0 ] = id2smId.size(); + string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); + aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( smIDs ); + aDataset->CloseOnDisk(); + // + delete[] smIDs; + } + + aGroup->CloseOnDisk(); + + // Store node positions on sub-shapes (SMDS_Position): + // ---------------------------------------------------- + + aGroup = new HDFgroup( "Node Positions", aTopGroup ); + aGroup->CreateOnDisk(); + + // in aGroup, create 5 datasets to contain: + // "Nodes on Edges" - ID of node on edge + // "Edge positions" - U parameter on node on edge + // "Nodes on Faces" - ID of node on face + // "Face U positions" - U parameter of node on face + // "Face V positions" - V parameter of node on face + + // Find out nb of nodes on edges and faces + // Collect corresponing sub-meshes + int nbEdgeNodes = 0, nbFaceNodes = 0; + list aEdgeSM, aFaceSM; + // loop on SMESHDS_SubMesh'es + for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) + { + SMESHDS_SubMesh* aSubMesh = (*itSubM).second; + if ( aSubMesh->IsComplexSubmesh() ) + continue; // submesh containing other submeshs + int nbNodes = aSubMesh->NbNodes(); + if ( nbNodes == 0 ) continue; + + int aShapeID = (*itSubM).first; + if ( aShapeID < 1 || aShapeID > mySMESHDSMesh->MaxShapeIndex() ) + continue; + int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType(); + // write only SMDS_FacePosition and SMDS_EdgePosition + switch ( aShapeType ) { + case TopAbs_FACE: + nbFaceNodes += nbNodes; + aFaceSM.push_back( aSubMesh ); + break; + case TopAbs_EDGE: + nbEdgeNodes += nbNodes; + aEdgeSM.push_back( aSubMesh ); + break; + default: + continue; + } + } + // Treat positions on edges or faces + for ( int onFace = 0; onFace < 2; onFace++ ) + { + // Create arrays to store in datasets + int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes ); + if (!nbNodes) continue; + int* aNodeIDs = new int [ nbNodes ]; + double* aUPos = new double [ nbNodes ]; + double* aVPos = ( onFace ? new double[ nbNodes ] : 0 ); + + // Fill arrays + // loop on sub-meshes + list * pListSM = ( onFace ? &aFaceSM : &aEdgeSM ); + list::iterator itSM = pListSM->begin(); + for ( ; itSM != pListSM->end(); itSM++ ) + { + SMESHDS_SubMesh* aSubMesh = (*itSM); + + SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes(); + // loop on nodes in aSubMesh + while ( itNode->more() ) + { + //node ID + const SMDS_MeshNode* node = itNode->next(); + aNodeIDs [ iNode ] = node->GetID(); + + // Position + const SMDS_PositionPtr pos = node->GetPosition(); + if ( onFace ) { // on FACE + const SMDS_FacePosition* fPos = + dynamic_cast( pos ); + if ( fPos ) { + aUPos[ iNode ] = fPos->GetUParameter(); + aVPos[ iNode ] = fPos->GetVParameter(); + iNode++; + } + else + nbNodes--; + } + else { // on EDGE + const SMDS_EdgePosition* ePos = + dynamic_cast( pos ); + if ( ePos ) { + aUPos[ iNode ] = ePos->GetUParameter(); + iNode++; + } + else + nbNodes--; + } + } // loop on nodes in aSubMesh + } // loop on sub-meshes - // write applied algorithms if exist - SALOMEDS::SObject_var mySubAlgoBranch; - found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch ); - if ( found ) { - aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); - aSubSubGroup->CreateOnDisk(); + // Write datasets + if ( nbNodes ) + { + aSize[ 0 ] = nbNodes; + // IDS + string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges"); + aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aNodeIDs ); + aDataset->CloseOnDisk(); - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch ); - int algoNb = 0; - for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySubSObject = it->Value(); - SALOMEDS::SObject_var myRefOnAlgo; - bool ok = mySubSObject->ReferencedObject( myRefOnAlgo ); - if ( ok ) { - //string myRefOnObject = myRefOnAlgo->GetID(); - CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo ); - CORBA::String_var objStr = GetORB()->object_to_string( anObject ); - int id = myStudyContext->findId( string( objStr.in() ) ); - //if ( myRefOnObject.length() > 0 ) { - //aSize[ 0 ] = myRefOnObject.length() + 1; - char algoName[ 30 ], algoId[ 30 ]; - sprintf( algoName, "Algo %d", ++algoNb ); - sprintf( algoId, "%d", id ); - aSize[ 0 ] = strlen( algoId ) + 1; - aDataset = new HDFdataset( algoName, aSubSubGroup, HDF_STRING, aSize, 1 ); - aDataset->CreateOnDisk(); - //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); - aDataset->WriteOnDisk( algoId ); - aDataset->CloseOnDisk(); - //} - } - } - aSubSubGroup->CloseOnDisk(); + // U Positions + aDSName = ( onFace ? "Face U positions" : "Edge positions"); + aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aUPos ); + aDataset->CloseOnDisk(); + // V Positions + if ( onFace ) { + aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aVPos ); + aDataset->CloseOnDisk(); } - // close submesh HDF group - aSubGroup->CloseOnDisk(); } - } - // close container of submeshes by type HDF group + delete [] aNodeIDs; + delete [] aUPos; + if ( aVPos ) delete [] aVPos; + + } // treat positions on edges or faces + + // close "Node Positions" group aGroup->CloseOnDisk(); - } - } - // All sub-meshes will be stored in MED file - // .. will NOT (PAL 12992) - //if ( shapeRefFound ) - //myWriter.AddAllSubMeshes(); - // groups root sub-branch - SALOMEDS::SObject_var myGroupsBranch; - for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) { - found = gotBranch->FindSubObject( i, myGroupsBranch ); - if ( found ) { - char name_group[ 30 ]; - if ( i == GetNodeGroupsTag() ) - strcpy( name_group, "Groups of Nodes" ); - else if ( i == GetEdgeGroupsTag() ) - strcpy( name_group, "Groups of Edges" ); - else if ( i == GetFaceGroupsTag() ) - strcpy( name_group, "Groups of Faces" ); - else if ( i == GetVolumeGroupsTag() ) - strcpy( name_group, "Groups of Volumes" ); - - aGroup = new HDFgroup( name_group, aTopGroup ); - aGroup->CreateOnDisk(); - - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch ); - for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySObject = it->Value(); - CORBA::Object_var aSubObject = SObjectToObject( mySObject ); - if ( !CORBA::is_nil( aSubObject ) ) { - SMESH_GroupBase_i* myGroupImpl = - dynamic_cast( GetServant( aSubObject ).in() ); - if ( !myGroupImpl ) - continue; - - CORBA::String_var objStr = GetORB()->object_to_string( aSubObject ); - int anId = myStudyContext->findId( string( objStr.in() ) ); - - // For each group, create a dataset named "Group " - // and store the group's user name into it - char grpName[ 30 ]; - sprintf( grpName, "Group %d", anId ); - char* aUserName = myGroupImpl->GetName(); - aSize[ 0 ] = strlen( aUserName ) + 1; - - aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aUserName ); - aDataset->CloseOnDisk(); - - // ouv : NPAL12872 - // For each group, create a dataset named "Group Color" - // and store the group's color into it - char grpColorName[ 30 ]; - sprintf( grpColorName, "ColorGroup %d", anId ); - SALOMEDS::Color aColor = myGroupImpl->GetColor(); - double anRGB[3]; - anRGB[ 0 ] = aColor.R; - anRGB[ 1 ] = aColor.G; - anRGB[ 2 ] = aColor.B; - aSize[ 0 ] = 3; - aDataset = new HDFdataset( grpColorName, aGroup, HDF_FLOAT64, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( anRGB ); - aDataset->CloseOnDisk(); - - // Store the group contents into MED file - if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) { - - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = " - << grpName << " to MED file" ); - SMESHDS_GroupBase* aGrpBaseDS = - myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS(); - aGrpBaseDS->SetStoreName( grpName ); - - // Pass SMESHDS_Group to MED writer - SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); - if ( aGrpDS ) - myWriter.AddGroup( aGrpDS ); - - // write reference on a shape if exists - SMESHDS_GroupOnGeom* aGeomGrp = - dynamic_cast( aGrpBaseDS ); - if ( aGeomGrp ) { - SALOMEDS::SObject_var mySubRef, myShape; - if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) && - mySubRef->ReferencedObject( myShape ) && - !CORBA::is_nil( myShape->GetObject() )) - { - string myRefOnObject = myShape->GetID(); - if ( myRefOnObject.length() > 0 ) { - char aRefName[ 30 ]; - sprintf( aRefName, "Ref on shape %d", anId); - aSize[ 0 ] = myRefOnObject.length() + 1; - aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); - aDataset->CloseOnDisk(); - } - } - else // shape ref is invalid: - { - // save a group on geometry as ordinary group - myWriter.AddGroup( aGeomGrp ); - } - } - } - } - } - aGroup->CloseOnDisk(); - } - } // loop on groups - - if ( strcmp( strHasData.c_str(), "1" ) == 0 ) - { - // Flush current mesh information into MED file - myWriter.Perform(); - - // maybe a shape was deleted in the study - if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) { - TopoDS_Shape nullShape; - myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data - } - - if ( !mySMESHDSMesh->SubMeshes().empty() ) - { - // Store submeshes - // ---------------- - aGroup = new HDFgroup( "Submeshes", aTopGroup ); - aGroup->CreateOnDisk(); - - // each element belongs to one or none submesh, - // so for each node/element, we store a submesh ID - - // Make maps of submesh IDs of elements sorted by element IDs - typedef int TElemID; - typedef int TSubMID; - map< TElemID, TSubMID > eId2smId, nId2smId; - map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint - const map& aSubMeshes = mySMESHDSMesh->SubMeshes(); - map::const_iterator itSubM ( aSubMeshes.begin() ); - SMDS_NodeIteratorPtr itNode; - SMDS_ElemIteratorPtr itElem; - for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) - { - TSubMID aSubMeID = itSubM->first; - SMESHDS_SubMesh* aSubMesh = itSubM->second; - if ( aSubMesh->IsComplexSubmesh() ) - continue; // submesh containing other submeshs - // nodes - hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh - for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint) - hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID )); - // elements - hint = eId2smId.begin(); - for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint) - hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID )); - } - - // Care of elements that are not on submeshes - if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) { - for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); ) - /* --- stl_map.h says : */ - /* A %map relies on unique keys and thus a %pair is only inserted if its */ - /* first element (the key) is not already present in the %map. */ - nId2smId.insert( make_pair( itNode->next()->GetID(), 0 )); - } - int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes(); - if ( nbElems != eId2smId.size() ) { - for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); ) - eId2smId.insert( make_pair( itElem->next()->GetID(), 0 )); - } - - // Store submesh IDs - for ( int isNode = 0; isNode < 2; ++isNode ) - { - map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId; - if ( id2smId.empty() ) continue; - map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin(); - // make and fill array of submesh IDs - int* smIDs = new int [ id2smId.size() ]; - for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i ) - smIDs[ i ] = id_smId->second; - // write HDF group - aSize[ 0 ] = id2smId.size(); - string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); - aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( smIDs ); - aDataset->CloseOnDisk(); - // - delete smIDs; - } - - // Store node positions on sub-shapes (SMDS_Position): - // ---------------------------------------------------- - - aGroup = new HDFgroup( "Node Positions", aTopGroup ); - aGroup->CreateOnDisk(); - - // in aGroup, create 5 datasets to contain: - // "Nodes on Edges" - ID of node on edge - // "Edge positions" - U parameter on node on edge - // "Nodes on Faces" - ID of node on face - // "Face U positions" - U parameter of node on face - // "Face V positions" - V parameter of node on face - - // Find out nb of nodes on edges and faces - // Collect corresponing sub-meshes - int nbEdgeNodes = 0, nbFaceNodes = 0; - list aEdgeSM, aFaceSM; - // loop on SMESHDS_SubMesh'es - for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) - { - SMESHDS_SubMesh* aSubMesh = (*itSubM).second; - if ( aSubMesh->IsComplexSubmesh() ) - continue; // submesh containing other submeshs - int nbNodes = aSubMesh->NbNodes(); - if ( nbNodes == 0 ) continue; - - int aShapeID = (*itSubM).first; - int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType(); - // write only SMDS_FacePosition and SMDS_EdgePosition - switch ( aShapeType ) { - case TopAbs_FACE: - nbFaceNodes += nbNodes; - aFaceSM.push_back( aSubMesh ); - break; - case TopAbs_EDGE: - nbEdgeNodes += nbNodes; - aEdgeSM.push_back( aSubMesh ); - break; - default: - continue; - } - } - // Treat positions on edges or faces - for ( int onFace = 0; onFace < 2; onFace++ ) - { - // Create arrays to store in datasets - int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes ); - if (!nbNodes) continue; - int* aNodeIDs = new int [ nbNodes ]; - double* aUPos = new double [ nbNodes ]; - double* aVPos = ( onFace ? new double[ nbNodes ] : 0 ); - - // Fill arrays - // loop on sub-meshes - list * pListSM = ( onFace ? &aFaceSM : &aEdgeSM ); - list::iterator itSM = pListSM->begin(); - for ( ; itSM != pListSM->end(); itSM++ ) - { - SMESHDS_SubMesh* aSubMesh = (*itSM); - - SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes(); - // loop on nodes in aSubMesh - while ( itNode->more() ) - { - //node ID - const SMDS_MeshNode* node = itNode->next(); - aNodeIDs [ iNode ] = node->GetID(); - - // Position - const SMDS_PositionPtr pos = node->GetPosition(); - if ( onFace ) { // on FACE - const SMDS_FacePosition* fPos = - dynamic_cast( pos.get() ); - if ( fPos ) { - aUPos[ iNode ] = fPos->GetUParameter(); - aVPos[ iNode ] = fPos->GetVParameter(); - iNode++; - } - else - nbNodes--; - } - else { // on EDGE - const SMDS_EdgePosition* ePos = - dynamic_cast( pos.get() ); - if ( ePos ) { - aUPos[ iNode ] = ePos->GetUParameter(); - iNode++; - } - else - nbNodes--; - } - } // loop on nodes in aSubMesh - } // loop on sub-meshes - - // Write datasets - if ( nbNodes ) - { - aSize[ 0 ] = nbNodes; - // IDS - string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges"); - aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aNodeIDs ); - aDataset->CloseOnDisk(); - - // U Positions - aDSName = ( onFace ? "Face U positions" : "Edge positions"); - aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aUPos ); - aDataset->CloseOnDisk(); - // V Positions - if ( onFace ) { - aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aVPos ); - aDataset->CloseOnDisk(); - } - } - delete [] aNodeIDs; - delete [] aUPos; - if ( aVPos ) delete [] aVPos; - - } // treat positions on edges or faces - - // close "Node Positions" group - aGroup->CloseOnDisk(); - - } // if ( there are submeshes in SMESHDS_Mesh ) - } // if ( hasData ) - - // close mesh HDF group - aTopGroup->CloseOnDisk(); - } - } + } // if ( there are submeshes in SMESHDS_Mesh ) + } // if ( hasData ) + + // close mesh HDF group + aTopGroup->CloseOnDisk(); + } + } } } } - + // close HDF file aFile->CloseOnDisk(); delete aFile; @@ -2947,7 +3742,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile ); // Remove temporary files and directory - if ( !isMultiFile ) + if ( !isMultiFile ) SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); INFOS( "SMESH_Gen_i::Save() completed" ); @@ -2963,8 +3758,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, //============================================================================= SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent, - const char* theURL, - bool isMultiFile ) { + const char* theURL, + bool isMultiFile ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SaveASCII" ); SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile ); return aStreamFile._retn(); @@ -2974,12 +3769,12 @@ SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent int size = aStreamFile.in().length(); _CORBA_Octet* buffer = new _CORBA_Octet[size*3+1]; for ( int i = 0; i < size; i++ ) - sprintf( (char*)&(buffer[i*3]), "|%02x", (char*)(aStreamFile[i]) ); + sprintf( (char*)&(buffer[i*3]), "|%02x", aStreamFile[i] ); buffer[size * 3] = '\0'; SALOMEDS::TMPFile_var anAsciiStreamFile = new SALOMEDS::TMPFile(size*3, size*3, buffer, 1); - + return anAsciiStreamFile._retn(); } @@ -3000,34 +3795,9 @@ void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot ) if ( aStudy->_is_nil() ) return; - SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() ); } -//============================================================================= -/*! - * \brief Creates SMDS_Position according to shape type - */ -//============================================================================= - -class PositionCreator { -public: - SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) { - return (this->*myFuncTable[ type ])(); - } - PositionCreator() { - myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition ); - myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition; - myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition; - myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition; - } -private: - SMDS_PositionPtr edgePosition() const { return SMDS_PositionPtr( new SMDS_EdgePosition ); } - SMDS_PositionPtr facePosition() const { return SMDS_PositionPtr( new SMDS_FacePosition ); } - SMDS_PositionPtr vertexPosition() const { return SMDS_PositionPtr( new SMDS_VertexPosition); } - SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition(); } - typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const; - vector myFuncTable; -}; //============================================================================= /*! @@ -3038,13 +3808,13 @@ private: //============================================================================= bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile ) + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ) { INFOS( "SMESH_Gen_i::Load" ); - if ( myCurrentStudy->_is_nil() || + if ( myCurrentStudy->_is_nil() || theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() ) SetCurrentStudy( theComponent->GetStudy() ); @@ -3060,7 +3830,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // Get temporary files location TCollection_AsciiString tmpDir = isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str(); - + INFOS( "THE URL++++++++++++++" ) INFOS( theURL ); INFOS( "THE TMP PATH+++++++++" ); @@ -3069,9 +3839,9 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // Convert the stream into sequence of files to process SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream, tmpDir.ToCString(), - isMultiFile ); + isMultiFile ); TCollection_AsciiString aStudyName( "" ); - if ( isMultiFile ) + if ( isMultiFile ) aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() ); // Set names of temporary files @@ -3097,8 +3867,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, return false; } - DriverMED_R_SMESHDS_Mesh myReader; - myReader.SetFile( meshfile.ToCString() ); + TPythonDump pd; // prevent dump during loading + + // DriverMED_R_SMESHDS_Mesh myReader; + // myReader.SetFile( meshfile.ToCString() ); // For PAL13473 ("Repetitive mesh") implementation. // New dependencies between SMESH objects are established: @@ -3114,99 +3886,99 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, list< pair< SMESH_Mesh_i*, HDFgroup* > > meshGroupList; // get total number of top-level groups - int aNbGroups = aFile->nInternalObjects(); + int aNbGroups = aFile->nInternalObjects(); if ( aNbGroups > 0 ) { // --> in first turn we should read&create hypotheses if ( aFile->ExistInternalObject( "Hypotheses" ) ) { // open hypotheses root HDF group - aTopGroup = new HDFgroup( "Hypotheses", aFile ); + aTopGroup = new HDFgroup( "Hypotheses", aFile ); aTopGroup->OpenOnDisk(); // get number of hypotheses - int aNbObjects = aTopGroup->nInternalObjects(); + int aNbObjects = aTopGroup->nInternalObjects(); for ( int j = 0; j < aNbObjects; j++ ) { - // try to identify hypothesis - char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; + // try to identify hypothesis + char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; aTopGroup->InternalObjectIndentify( j, hypGrpName ); - if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) { - // open hypothesis group - aGroup = new HDFgroup( hypGrpName, aTopGroup ); - aGroup->OpenOnDisk(); - - // --> get hypothesis id - int id = atoi( string( hypGrpName ).substr( 10 ).c_str() ); - string hypname; - string libname; - string hypdata; - - // get number of datasets - int aNbSubObjects = aGroup->nInternalObjects(); - for ( int k = 0; k < aNbSubObjects; k++ ) { - // identify dataset - char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( k, name_of_subgroup ); - // --> get hypothesis name - if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypname_str = new char[ size ]; - aDataset->ReadFromDisk( hypname_str ); - hypname = string( hypname_str ); - delete [] hypname_str; - aDataset->CloseOnDisk(); - } - // --> get hypothesis plugin library name - if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* libname_str = new char[ size ]; - aDataset->ReadFromDisk( libname_str ); - if(MYDEBUG) SCRUTE( libname_str ); - libname = string( libname_str ); - delete [] libname_str; - aDataset->CloseOnDisk(); - } - // --> get hypothesis data - if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypdata_str = new char[ size ]; - aDataset->ReadFromDisk( hypdata_str ); - hypdata = string( hypdata_str ); - delete [] hypdata_str; - aDataset->CloseOnDisk(); - } - } - // close hypothesis HDF group - aGroup->CloseOnDisk(); - - // --> restore hypothesis from data - if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty - if(MYDEBUG) MESSAGE("VSR - load hypothesis : id = " << id << + if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) { + // open hypothesis group + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->OpenOnDisk(); + + // --> get hypothesis id + int id = atoi( string( hypGrpName ).substr( 10 ).c_str() ); + string hypname; + string libname; + string hypdata; + + // get number of datasets + int aNbSubObjects = aGroup->nInternalObjects(); + for ( int k = 0; k < aNbSubObjects; k++ ) { + // identify dataset + char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( k, name_of_subgroup ); + // --> get hypothesis name + if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypname_str = new char[ size ]; + aDataset->ReadFromDisk( hypname_str ); + hypname = string( hypname_str ); + delete [] hypname_str; + aDataset->CloseOnDisk(); + } + // --> get hypothesis plugin library name + if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* libname_str = new char[ size ]; + aDataset->ReadFromDisk( libname_str ); + if(MYDEBUG) SCRUTE( libname_str ); + libname = string( libname_str ); + delete [] libname_str; + aDataset->CloseOnDisk(); + } + // --> get hypothesis data + if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypdata_str = new char[ size ]; + aDataset->ReadFromDisk( hypdata_str ); + hypdata = string( hypdata_str ); + delete [] hypdata_str; + aDataset->CloseOnDisk(); + } + } + // close hypothesis HDF group + aGroup->CloseOnDisk(); + + // --> restore hypothesis from data + if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty + if(MYDEBUG) MESSAGE("VSR - load hypothesis : id = " << id << ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str()); SMESH::SMESH_Hypothesis_var myHyp; - try { // protect persistence mechanism against exceptions - myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); - } - catch (...) { - INFOS( "Exception during hypothesis creation" ); - } + try { // protect persistence mechanism against exceptions + myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); + } + catch (...) { + INFOS( "Exception during hypothesis creation" ); + } - SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); - if ( myImpl ) { - // myImpl->LoadFrom( hypdata.c_str() ); + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + // myImpl->LoadFrom( hypdata.c_str() ); hypDataList.push_back( make_pair( myImpl, hypdata )); - string iorString = GetORB()->object_to_string( myHyp ); - int newId = myStudyContext->findId( iorString ); - myStudyContext->mapOldToNew( id, newId ); - } - else - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); + string iorString = GetORB()->object_to_string( myHyp ); + int newId = myStudyContext->findId( iorString ); + myStudyContext->mapOldToNew( id, newId ); + } + else + if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); } } } @@ -3218,95 +3990,95 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // --> then we should read&create algorithms if ( aFile->ExistInternalObject( "Algorithms" ) ) { // open algorithms root HDF group - aTopGroup = new HDFgroup( "Algorithms", aFile ); + aTopGroup = new HDFgroup( "Algorithms", aFile ); aTopGroup->OpenOnDisk(); // get number of algorithms - int aNbObjects = aTopGroup->nInternalObjects(); + int aNbObjects = aTopGroup->nInternalObjects(); for ( int j = 0; j < aNbObjects; j++ ) { - // try to identify algorithm - char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; + // try to identify algorithm + char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; aTopGroup->InternalObjectIndentify( j, hypGrpName ); - if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) { - // open algorithm group - aGroup = new HDFgroup( hypGrpName, aTopGroup ); - aGroup->OpenOnDisk(); - - // --> get algorithm id - int id = atoi( string( hypGrpName ).substr( 9 ).c_str() ); - string hypname; - string libname; - string hypdata; - - // get number of datasets - int aNbSubObjects = aGroup->nInternalObjects(); - for ( int k = 0; k < aNbSubObjects; k++ ) { - // identify dataset - char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( k, name_of_subgroup ); - // --> get algorithm name - if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypname_str = new char[ size ]; - aDataset->ReadFromDisk( hypname_str ); - hypname = string( hypname_str ); - delete [] hypname_str; - aDataset->CloseOnDisk(); - } - // --> get algorithm plugin library name - if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* libname_str = new char[ size ]; - aDataset->ReadFromDisk( libname_str ); - if(MYDEBUG) SCRUTE( libname_str ); - libname = string( libname_str ); - delete [] libname_str; - aDataset->CloseOnDisk(); - } - // --> get algorithm data - if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypdata_str = new char[ size ]; - aDataset->ReadFromDisk( hypdata_str ); - if(MYDEBUG) SCRUTE( hypdata_str ); - hypdata = string( hypdata_str ); - delete [] hypdata_str; - aDataset->CloseOnDisk(); - } - } - // close algorithm HDF group - aGroup->CloseOnDisk(); - - // --> restore algorithm from data - if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty - if(MYDEBUG) MESSAGE("VSR - load algo : id = " << id << + if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) { + // open algorithm group + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->OpenOnDisk(); + + // --> get algorithm id + int id = atoi( string( hypGrpName ).substr( 9 ).c_str() ); + string hypname; + string libname; + string hypdata; + + // get number of datasets + int aNbSubObjects = aGroup->nInternalObjects(); + for ( int k = 0; k < aNbSubObjects; k++ ) { + // identify dataset + char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( k, name_of_subgroup ); + // --> get algorithm name + if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypname_str = new char[ size ]; + aDataset->ReadFromDisk( hypname_str ); + hypname = string( hypname_str ); + delete [] hypname_str; + aDataset->CloseOnDisk(); + } + // --> get algorithm plugin library name + if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* libname_str = new char[ size ]; + aDataset->ReadFromDisk( libname_str ); + if(MYDEBUG) SCRUTE( libname_str ); + libname = string( libname_str ); + delete [] libname_str; + aDataset->CloseOnDisk(); + } + // --> get algorithm data + if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypdata_str = new char[ size ]; + aDataset->ReadFromDisk( hypdata_str ); + if(MYDEBUG) SCRUTE( hypdata_str ); + hypdata = string( hypdata_str ); + delete [] hypdata_str; + aDataset->CloseOnDisk(); + } + } + // close algorithm HDF group + aGroup->CloseOnDisk(); + + // --> restore algorithm from data + if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty + if(MYDEBUG) MESSAGE("VSR - load algo : id = " << id << ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str()); SMESH::SMESH_Hypothesis_var myHyp; - try { // protect persistence mechanism against exceptions - myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); - } - catch (...) { - INFOS( "Exception during hypothesis creation" ); - } + try { // protect persistence mechanism against exceptions + myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); + } + catch (...) { + INFOS( "Exception during hypothesis creation" ); + } - SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); - if ( myImpl ) { - //myImpl->LoadFrom( hypdata.c_str() ); + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + //myImpl->LoadFrom( hypdata.c_str() ); hypDataList.push_back( make_pair( myImpl, hypdata )); - string iorString = GetORB()->object_to_string( myHyp ); - int newId = myStudyContext->findId( iorString ); - myStudyContext->mapOldToNew( id, newId ); - } - else - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); + string iorString = GetORB()->object_to_string( myHyp ); + int newId = myStudyContext->findId( iorString ); + myStudyContext->mapOldToNew( id, newId ); + } + else + if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); } } } @@ -3322,44 +4094,44 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aFile->InternalObjectIndentify( i, meshName ); if ( string( meshName ).substr( 0, 4 ) == string( "Mesh" ) ) { - // --> get mesh id - int id = atoi( string( meshName ).substr( 4 ).c_str() ); - if ( id <= 0 ) - continue; - - // open mesh HDF group - aTopGroup = new HDFgroup( meshName, aFile ); - aTopGroup->OpenOnDisk(); - - // get number of child HDF objects - int aNbObjects = aTopGroup->nInternalObjects(); - if ( aNbObjects > 0 ) { - // create mesh - if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id ); - SMESH::SMESH_Mesh_var myNewMesh = this->createMesh(); - SMESH_Mesh_i* myNewMeshImpl = dynamic_cast( GetServant( myNewMesh ).in() ); + // --> get mesh id + int id = atoi( string( meshName ).substr( 4 ).c_str() ); + if ( id <= 0 ) + continue; + + // open mesh HDF group + aTopGroup = new HDFgroup( meshName, aFile ); + aTopGroup->OpenOnDisk(); + + // get number of child HDF objects + int aNbObjects = aTopGroup->nInternalObjects(); + if ( aNbObjects > 0 ) { + // create mesh + if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id ); + SMESH::SMESH_Mesh_var myNewMesh = this->createMesh(); + SMESH_Mesh_i* myNewMeshImpl = dynamic_cast( GetServant( myNewMesh ).in() ); if ( !myNewMeshImpl ) - continue; + continue; meshGroupList.push_back( make_pair( myNewMeshImpl, aTopGroup )); - string iorString = GetORB()->object_to_string( myNewMesh ); - int newId = myStudyContext->findId( iorString ); - myStudyContext->mapOldToNew( id, newId ); - - // ouv : NPAL12872 - // try to read and set auto color flag - char aMeshAutoColorName[ 30 ]; - sprintf( aMeshAutoColorName, "AutoColorMesh %d", id); - if( aTopGroup->ExistInternalObject( aMeshAutoColorName ) ) - { - aDataset = new HDFdataset( aMeshAutoColorName, aTopGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - int* anAutoColor = new int[ size ]; - aDataset->ReadFromDisk( anAutoColor ); - aDataset->CloseOnDisk(); - myNewMeshImpl->SetAutoColor( (bool)anAutoColor[0] ); - } + string iorString = GetORB()->object_to_string( myNewMesh ); + int newId = myStudyContext->findId( iorString ); + myStudyContext->mapOldToNew( id, newId ); + + // ouv : NPAL12872 + // try to read and set auto color flag + char aMeshAutoColorName[ 30 ]; + sprintf( aMeshAutoColorName, "AutoColorMesh %d", id); + if( aTopGroup->ExistInternalObject( aMeshAutoColorName ) ) + { + aDataset = new HDFdataset( aMeshAutoColorName, aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* anAutoColor = new int[ size ]; + aDataset->ReadFromDisk( anAutoColor ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().SetAutoColor( (bool)anAutoColor[0] ); + } // try to read and set reference to shape GEOM::GEOM_Object_var aShapeObject; @@ -3386,9 +4158,32 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } + // issue 0020693. Restore _isModified flag + if( aTopGroup->ExistInternalObject( "_isModified" ) ) + { + aDataset = new HDFdataset( "_isModified", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* isModified = new int[ size ]; + aDataset->ReadFromDisk( isModified ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified)); + } + + // issue 20918. Restore Persistent Id of SMESHDS_Mesh + if( aTopGroup->ExistInternalObject( "meshPersistentId" ) ) + { + aDataset = new HDFdataset( "meshPersistentId", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* meshPersistentId = new int[ size ]; + aDataset->ReadFromDisk( meshPersistentId ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId ); + } } } - } + } // reading MESHes // As all object that can be referred by hypothesis are created, // we can restore hypothesis data @@ -3408,8 +4203,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, { aTopGroup = meshi_group->second; SMESH_Mesh_i* myNewMeshImpl = meshi_group->first; - ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); - SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); + //::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + //SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh(); bool hasData = false; @@ -3430,19 +4225,20 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); if ( strcmp( strHasData, "1") == 0 ) { // read mesh data from MED file - myReader.SetMesh( mySMESHDSMesh ); - myReader.SetMeshId( id ); - myReader.Perform(); + // myReader.SetMesh( mySMESHDSMesh ); + // myReader.SetMeshId( id ); + // myReader.Perform(); hasData = true; } } - // try to get applied algorithms + // Try to get applied ALGORITHMS (mesh is not cleared by algo addition because + // nodes and elements are not yet put into sub-meshes) if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) { aGroup = new HDFgroup( "Applied Algorithms", aTopGroup ); aGroup->OpenOnDisk(); // get number of applied algorithms - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); if(MYDEBUG) MESSAGE( "VSR - number of applied algos " << aNbSubObjects ); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; @@ -3455,9 +4251,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, char* refFromFile = new char[ size ]; aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - // san - it is impossible to recover applied algorithms using their entries within Load() method - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); @@ -3481,7 +4275,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup ); aGroup->OpenOnDisk(); // get number of applied hypotheses - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aGroup->InternalObjectIndentify( j, name_dataset ); @@ -3493,9 +4287,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, char* refFromFile = new char[ size ]; aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - // san - it is impossible to recover applied hypotheses using their entries within Load() method - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); @@ -3514,7 +4306,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->CloseOnDisk(); } - // --> try to find submeshes containers for each type of submesh + // --> try to find SUB-MESHES containers for each type of submesh for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) { char name_meshgroup[ 30 ]; if ( j == GetSubMeshOnVertexTag() ) @@ -3539,7 +4331,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->OpenOnDisk(); // get number of submeshes - int aNbSubMeshes = aGroup->nInternalObjects(); + int aNbSubMeshes = aGroup->nInternalObjects(); for ( int k = 0; k < aNbSubMeshes; k++ ) { // identify submesh char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ]; @@ -3585,28 +4377,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( aSubMesh->_is_nil() ) continue; - // VSR: Get submesh data from MED convertor - // int anInternalSubmeshId = aSubMesh->GetId(); // this is not a persistent ID, it's an internal one computed from sub-shape - // if (myNewMeshImpl->_mapSubMesh.find(anInternalSubmeshId) != myNewMeshImpl->_mapSubMesh.end()) { - // if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): loading from MED file submesh with ID = " << - // subid << " for subshape # " << anInternalSubmeshId); - // SMESHDS_SubMesh* aSubMeshDS = - // myNewMeshImpl->_mapSubMesh[anInternalSubmeshId]->CreateSubMeshDS(); - // if ( !aSubMeshDS ) { - // if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): FAILED to create a submesh for subshape # " << - // anInternalSubmeshId << " in current mesh!"); - // } - // else - // myReader.GetSubMesh( aSubMeshDS, subid ); - // } - // try to get applied algorithms if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) { // open "applied algorithms" HDF group aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); aSubSubGroup->OpenOnDisk(); // get number of applied algorithms - int aNbSubObjects = aSubSubGroup->nInternalObjects(); + int aNbSubObjects = aSubSubGroup->nInternalObjects(); for ( int l = 0; l < aNbSubObjects; l++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aSubSubGroup->InternalObjectIndentify( l, name_dataset ); @@ -3619,8 +4396,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { @@ -3643,7 +4418,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup ); aSubSubGroup->OpenOnDisk(); // get number of applied hypotheses - int aNbSubObjects = aSubSubGroup->nInternalObjects(); + int aNbSubObjects = aSubSubGroup->nInternalObjects(); for ( int l = 0; l < aNbSubObjects; l++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aSubSubGroup->InternalObjectIndentify( l, name_dataset ); @@ -3656,8 +4431,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { @@ -3670,222 +4443,21 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } - // close "applied hypotheses" HDF group + // close "APPLIED HYPOTHESES" hdf group aSubSubGroup->CloseOnDisk(); } - // close submesh HDF group + // close SUB-MESH hdf group aSubGroup->CloseOnDisk(); } } - // close submeshes containers HDF group + // close SUB-MESHES containers hdf group aGroup->CloseOnDisk(); } } - if(hasData) { - - // Read sub-meshes from MED - // ------------------------- - if(MYDEBUG) MESSAGE("Create all sub-meshes"); - bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" )); - if ( submeshesInFamilies ) - { - // old way working before fix of PAL 12992 - myReader.CreateAllSubMeshes(); - } - else - { - // open a group - aGroup = new HDFgroup( "Submeshes", aTopGroup ); - aGroup->OpenOnDisk(); - - int maxID = mySMESHDSMesh->MaxShapeIndex(); - vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 ); - vector< TopAbs_ShapeEnum > smType ( maxID + 1, TopAbs_SHAPE ); - - PositionCreator aPositionCreator; - - SMDS_NodeIteratorPtr nIt = mySMESHDSMesh->nodesIterator(); - SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator(); - for ( int isNode = 0; isNode < 2; ++isNode ) - { - string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); - if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() )) - { - aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup ); - aDataset->OpenOnDisk(); - // read submesh IDs for all elements sorted by ID - int nbElems = aDataset->GetSize(); - int* smIDs = new int [ nbElems ]; - aDataset->ReadFromDisk( smIDs ); - aDataset->CloseOnDisk(); - - // get elements sorted by ID - TIDSortedElemSet elemSet; - if ( isNode ) - while ( nIt->more() ) elemSet.insert( nIt->next() ); - else - while ( eIt->more() ) elemSet.insert( eIt->next() ); - ASSERT( elemSet.size() == nbElems ); - - // add elements to submeshes - TIDSortedElemSet::iterator iE = elemSet.begin(); - for ( int i = 0; i < nbElems; ++i, ++iE ) - { - int smID = smIDs[ i ]; - if ( smID == 0 ) continue; - ASSERT( smID <= maxID ); - const SMDS_MeshElement* elem = *iE; - // get or create submesh - SMESHDS_SubMesh* & sm = subMeshes[ smID ]; - if ( ! sm ) { - sm = mySMESHDSMesh->NewSubMesh( smID ); - smType[ smID ] = mySMESHDSMesh->IndexToShape( smID ).ShapeType(); - } - // add - if ( isNode ) { - SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]); - pos->SetShapeId( smID ); - SMDS_MeshNode* node = const_cast( static_cast( elem )); - node->SetPosition( pos ); - sm->AddNode( node ); - } else { - sm->AddElement( elem ); - } - } - delete [] smIDs; - } - } - } // end reading submeshes - - // Read node positions on sub-shapes (SMDS_Position) - - if ( aTopGroup->ExistInternalObject( "Node Positions" )) - { - // There are 5 datasets to read: - // "Nodes on Edges" - ID of node on edge - // "Edge positions" - U parameter on node on edge - // "Nodes on Faces" - ID of node on face - // "Face U positions" - U parameter of node on face - // "Face V positions" - V parameter of node on face - const char* aEid_DSName = "Nodes on Edges"; - const char* aEu_DSName = "Edge positions"; - const char* aFu_DSName = "Face U positions"; - //char* aFid_DSName = "Nodes on Faces"; - //char* aFv_DSName = "Face V positions"; - - // data to retrieve - int nbEids = 0, nbFids = 0; - int *aEids = 0, *aFids = 0; - double *aEpos = 0, *aFupos = 0, *aFvpos = 0; - - // open a group - aGroup = new HDFgroup( "Node Positions", aTopGroup ); - aGroup->OpenOnDisk(); - - // loop on 5 data sets - int aNbObjects = aGroup->nInternalObjects(); - for ( int i = 0; i < aNbObjects; i++ ) - { - // identify dataset - char aDSName[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( i, aDSName ); - // read data - aDataset = new HDFdataset( aDSName, aGroup ); - aDataset->OpenOnDisk(); - if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions - { - double* pos = new double [ aDataset->GetSize() ]; - aDataset->ReadFromDisk( pos ); - // which one? - if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 ) - aEpos = pos; - else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 ) - aFupos = pos; - else - aFvpos = pos; - } - else // NODE IDS - { - int aSize = aDataset->GetSize(); - - // for reading files, created from 18.07.2005 till 10.10.2005 - if (aDataset->GetType() == HDF_STRING) - aSize /= sizeof(int); - - int* ids = new int [aSize]; - aDataset->ReadFromDisk( ids ); - // on face or nodes? - if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) { - aEids = ids; - nbEids = aSize; - } - else { - aFids = ids; - nbFids = aSize; - } - } - aDataset->CloseOnDisk(); - } // loop on 5 datasets - - // Set node positions on edges or faces - for ( int onFace = 0; onFace < 2; onFace++ ) - { - int nbNodes = ( onFace ? nbFids : nbEids ); - if ( nbNodes == 0 ) continue; - int* aNodeIDs = ( onFace ? aFids : aEids ); - double* aUPos = ( onFace ? aFupos : aEpos ); - double* aVPos = ( onFace ? aFvpos : 0 ); - // loop on node IDs - for ( int iNode = 0; iNode < nbNodes; iNode++ ) - { - const SMDS_MeshNode* node = mySMESHDSMesh->FindNode( aNodeIDs[ iNode ]); - ASSERT( node ); - SMDS_PositionPtr aPos = node->GetPosition(); - ASSERT( aPos ) - if ( onFace ) { - ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ); - SMDS_FacePosition* fPos = const_cast - ( static_cast( aPos.get() )); - fPos->SetUParameter( aUPos[ iNode ]); - fPos->SetVParameter( aVPos[ iNode ]); - } - else { - ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ); - SMDS_EdgePosition* fPos = const_cast - ( static_cast( aPos.get() )); - fPos->SetUParameter( aUPos[ iNode ]); - } - } - } - if ( aEids ) delete [] aEids; - if ( aFids ) delete [] aFids; - if ( aEpos ) delete [] aEpos; - if ( aFupos ) delete [] aFupos; - if ( aFvpos ) delete [] aFvpos; - - aGroup->CloseOnDisk(); - - } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) ) - } // if ( hasData ) - - // Recompute State (as computed sub-meshes are restored from MED) - if ( !aShapeObject->_is_nil() || !myNewMeshImpl->HasShapeToMesh()) { - MESSAGE("Compute State Engine ..."); - TopoDS_Shape myLocShape; - if(myNewMeshImpl->HasShapeToMesh()) - myLocShape = GeomObjectToShape( aShapeObject ); - else - myLocShape = SMESH_Mesh::PseudoShape(); - - myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine - (SMESH_subMesh::SUBMESH_RESTORED); - MESSAGE("Compute State Engine finished"); - } - - // try to get groups - for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) { + // try to get GROUPS + for ( int ii = GetNodeGroupsTag(); ii <= GetBallElementsGroupsTag(); ii++ ) { char name_group[ 30 ]; if ( ii == GetNodeGroupsTag() ) strcpy( name_group, "Groups of Nodes" ); @@ -3895,12 +4467,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, strcpy( name_group, "Groups of Faces" ); else if ( ii == GetVolumeGroupsTag() ) strcpy( name_group, "Groups of Volumes" ); + else if ( ii == Get0DElementsGroupsTag() ) + strcpy( name_group, "Groups of 0D Elements" ); + else if ( ii == GetBallElementsGroupsTag() ) + strcpy( name_group, "Groups of Balls" ); if ( aTopGroup->ExistInternalObject( name_group ) ) { aGroup = new HDFgroup( name_group, aTopGroup ); aGroup->OpenOnDisk(); // get number of groups - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aGroup->InternalObjectIndentify( j, name_dataset ); @@ -3941,11 +4517,29 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } + // Try to read a filter of SMESH_GroupOnFilter + SMESH::Filter_var filter; + SMESH_PredicatePtr predicate; + std::string hdfGrpName = "Filter " + SMESH_Comment(subid); + if ( aGroup->ExistInternalObject( hdfGrpName.c_str() )) + { + aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* persistStr = new char[ size ]; + aDataset->ReadFromDisk( persistStr ); + aDataset->CloseOnDisk(); + if ( strlen( persistStr ) > 0 ) { + filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr ); + predicate = SMESH_GroupOnFilter_i::GetPredicate( filter ); + } + } + // Create group servant SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1); SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate - ( myNewMeshImpl->createGroup( type, nameFromFile, aShape ) ); - // Obtain a SMESHDS_Group object + ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) ); + // Obtain a SMESHDS_Group object if ( aNewGroup->_is_nil() ) continue; @@ -3953,55 +4547,126 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, int newSubId = myStudyContext->findId( iorSubString ); myStudyContext->mapOldToNew( subid, newSubId ); - SMESH_GroupBase_i* aGroupImpl = - dynamic_cast( GetServant( aNewGroup ).in() ); + SMESH_GroupBase_i* aGroupImpl = SMESH::DownCast< SMESH_GroupBase_i*>( aNewGroup ); if ( !aGroupImpl ) continue; - SMESH_Group* aLocalGroup = myLocMesh.GetGroup( aGroupImpl->GetLocalID() ); - if ( !aLocalGroup ) + if ( SMESH_GroupOnFilter_i* aFilterGroup = + dynamic_cast< SMESH_GroupOnFilter_i*>( aGroupImpl )) + aFilterGroup->SetFilter( filter ); + + SMESHDS_GroupBase* aGroupBaseDS = aGroupImpl->GetGroupDS(); + if ( !aGroupBaseDS ) continue; - SMESHDS_GroupBase* aGroupBaseDS = aLocalGroup->GetGroupDS(); aGroupBaseDS->SetStoreName( name_dataset ); - // ouv : NPAL12872 - // Read color of the group + // ouv : NPAL12872 + // Read color of the group char aGroupColorName[ 30 ]; sprintf( aGroupColorName, "ColorGroup %d", subid); if ( aGroup->ExistInternalObject( aGroupColorName ) ) - { - aDataset = new HDFdataset( aGroupColorName, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - double* anRGB = new double[ size ]; - aDataset->ReadFromDisk( anRGB ); - aDataset->CloseOnDisk(); - Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB ); - aGroupBaseDS->SetColor( aColor ); - } + { + aDataset = new HDFdataset( aGroupColorName, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + double* anRGB = new double[ size ]; + aDataset->ReadFromDisk( anRGB ); + aDataset->CloseOnDisk(); + Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB ); + aGroupBaseDS->SetColor( aColor ); + } // Fill group with contents from MED file - SMESHDS_Group* aGrp = dynamic_cast( aGroupBaseDS ); - if ( aGrp ) - myReader.GetGroup( aGrp ); + // SMESHDS_Group* aGrp = dynamic_cast( aGroupBaseDS ); + // if ( aGrp ) + // myReader.GetGroup( aGrp ); } } aGroup->CloseOnDisk(); } + } // reading GROUPs + + // instead of reading mesh data, we read only brief information of all + // objects: mesh, groups, sub-meshes (issue 0021208 ) + if ( hasData ) + { + SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id, + meshfile.ToCString(), filename.ToCString(), + !isMultiFile ); + } + + // read Sub-Mesh ORDER if any + if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) { + aDataset = new HDFdataset( "Mesh Order", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* smIDs = new int[ size ]; + aDataset->ReadFromDisk( smIDs ); + aDataset->CloseOnDisk(); + TListOfListOfInt anOrderIds; + anOrderIds.push_back( TListOfInt() ); + for ( int i = 0; i < size; i++ ) + if ( smIDs[ i ] < 0 ) // is separator + anOrderIds.push_back( TListOfInt() ); + else + anOrderIds.back().push_back(smIDs[ i ]); + + myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); } + } // loop on meshes + + // update hyps needing full mesh data restored (issue 20918) + for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data ) + { + SMESH_Hypothesis_i* hyp = hyp_data->first; + hyp->UpdateAsMeshesRestored(); + } + + // notify algos on completed restoration to set sub-mesh event listeners + for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group ) + { + SMESH_Mesh_i* myNewMeshImpl = meshi_group->first; + ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + + TopoDS_Shape myLocShape; + if(myLocMesh.HasShapeToMesh()) + myLocShape = myLocMesh.GetShapeToMesh(); + else + myLocShape = SMESH_Mesh::PseudoShape(); + + myLocMesh.GetSubMesh(myLocShape)-> + ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED); } + // close mesh group if(aTopGroup) - aTopGroup->CloseOnDisk(); + aTopGroup->CloseOnDisk(); } // close HDF file aFile->CloseOnDisk(); delete aFile; // Remove temporary files created from the stream - if ( !isMultiFile ) - SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + if ( !isMultiFile ) + { + SMESH_File meshFile( meshfile.ToCString() ); + if ( !meshFile ) // no meshfile exists + { + SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + } + else + { + Engines::Container_var container = GetContainerRef(); + if ( Engines_Container_i* container_i = SMESH::DownCast( container )) + { + container_i->registerTemporaryFile( filename.ToCString() ); + container_i->registerTemporaryFile( meshfile.ToCString() ); + container_i->registerTemporaryFile( tmpDir.ToCString() ); + } + } + } + pd << ""; // prevent optimizing pd out INFOS( "SMESH_Gen_i::Load completed" ); return true; @@ -4016,9 +4681,9 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, //============================================================================= bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile ) { + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LoadASCII" ); return Load( theComponent, theStream, theURL, isMultiFile ); @@ -4042,7 +4707,7 @@ bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent, } SALOMEDS::TMPFile_var aRealStreamFile = new SALOMEDS::TMPFile(real_size, real_size, buffer, 1); - + return Load( theComponent, *(aRealStreamFile._retn()), theURL, isMultiFile ); } @@ -4059,8 +4724,9 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" ); // set correct current study - if (theComponent->GetStudy()->StudyId() != GetCurrentStudyID()) - SetCurrentStudy(theComponent->GetStudy()); + SALOMEDS::Study_var study = theComponent->GetStudy(); + if ( study->StudyId() != GetCurrentStudyID()) + setCurrentStudy( study, /*IsBeingClosed=*/true ); // Clear study contexts data int studyId = GetCurrentStudyID(); @@ -4078,7 +4744,7 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) // printf( "--------------------------- SMESH_Gen_i::Close, delete aGroup = %p \n", i_mesh->second ); // delete i_mesh->second; // } - + // delete SMESHDS_Mesh's // it's too long on big meshes @@ -4086,14 +4752,18 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) // delete context->myDocument; // context->myDocument = 0; // } - + + // remove the tmp files meshes are loaded from + SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD( theComponent ); + + myCurrentStudy = SALOMEDS::Study::_nil(); return; } //============================================================================= /*! * SMESH_Gen_i::ComponentDataType - * + * * Get component data type */ //============================================================================= @@ -4104,23 +4774,23 @@ char* SMESH_Gen_i::ComponentDataType() return CORBA::string_dup( "SMESH" ); } - + //============================================================================= /*! * SMESH_Gen_i::IORToLocalPersistentID - * + * * Transform data from transient form to persistent */ //============================================================================= char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/, - const char* IORString, - CORBA::Boolean /*isMultiFile*/, - CORBA::Boolean /*isASCII*/ ) + const char* IORString, + CORBA::Boolean /*isMultiFile*/, + CORBA::Boolean /*isASCII*/ ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" ); StudyContext* myStudyContext = GetCurrentStudyContext(); - + if ( myStudyContext && strcmp( IORString, "" ) != 0 ) { int anId = myStudyContext->findId( IORString ); if ( anId ) { @@ -4142,9 +4812,9 @@ char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/, //============================================================================= char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/, - const char* aLocalPersistentID, - CORBA::Boolean /*isMultiFile*/, - CORBA::Boolean /*isASCII*/ ) + const char* aLocalPersistentID, + CORBA::Boolean /*isMultiFile*/, + CORBA::Boolean /*isASCII*/ ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID ); StudyContext* myStudyContext = GetCurrentStudyContext(); @@ -4158,7 +4828,7 @@ char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/, //======================================================================= //function : RegisterObject -//purpose : +//purpose : //======================================================================= int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject) @@ -4208,21 +4878,26 @@ void SMESH_Gen_i::SetName(const char* theIOR, } } +int SMESH_Gen_i::GetCurrentStudyID() +{ + return myCurrentStudy->_is_nil() || myCurrentStudy->_non_existent() ? -1 : myCurrentStudy->StudyId(); +} + //============================================================================= -/*! +/*! * SMESHEngine_factory * - * C factory, accessible with dlsym, after dlopen + * C factory, accessible with dlsym, after dlopen */ //============================================================================= extern "C" { SMESH_I_EXPORT PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId* contId, - const char* instanceName, - const char* interfaceName ) + PortableServer::POA_ptr poa, + PortableServer::ObjectId* contId, + const char* instanceName, + const char* interfaceName ) { if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" ); if(MYDEBUG) SCRUTE(interfaceName); diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 836e585c7..a72c466f3 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Gen_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #ifndef _SMESH_GEN_I_HXX_ #define _SMESH_GEN_I_HXX_ @@ -64,8 +63,8 @@ public: // constructor StudyContext() {} // destructor - ~StudyContext() - { + ~StudyContext() + { mapIdToIOR.clear(); mapIdToId.clear(); } @@ -113,7 +112,7 @@ public: } return 0; } - + private: // get next free object identifier int getNextId() @@ -133,7 +132,7 @@ private: // ========================================================== class SMESH_I_EXPORT SMESH_Gen_i: public virtual POA_SMESH::SMESH_Gen, - public virtual Engines_Component_i + public virtual Engines_Component_i { public: // Get last created instance of the class @@ -159,14 +158,14 @@ public: GEOM::GEOM_Object_ptr ShapeToGeomObject (const TopoDS_Shape& theShape ); // Get TopoDS_Shape correspoding to GEOM_Object TopoDS_Shape GeomObjectToShape(GEOM::GEOM_Object_ptr theGeomObject); - + // Default constructor SMESH_Gen_i(); // Standard constructor SMESH_Gen_i( CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, - PortableServer::ObjectId* contId, - const char* instanceName, + PortableServer::ObjectId* contId, + const char* instanceName, const char* interfaceName ); // Destructor virtual ~SMESH_Gen_i(); @@ -176,7 +175,7 @@ public: // ***************************************** // Set a new Mesh object name void SetName(const char* theIOR, - const char* theName); + const char* theName); //GEOM::GEOM_Gen_ptr SetGeomEngine( const char* containerLoc ); void SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo ); @@ -195,7 +194,7 @@ public: SMESH::SMESH_Hypothesis_ptr CreateHypothesis (const char* theHypType, const char* theLibName) throw ( SALOME::SALOME_Exception ); - + // Return hypothesis of given type holding parameter values of the existing mesh SMESH::SMESH_Hypothesis_ptr GetHypothesisParameterValues (const char* theHypType, const char* theLibName, @@ -203,7 +202,9 @@ public: GEOM::GEOM_Object_ptr theGeom, CORBA::Boolean byMesh) throw ( SALOME::SALOME_Exception ); - + + // Preferences + // ------------ /*! * Sets number of segments per diagonal of boundary box of geometry by which * default segment length of appropriate 1D hypotheses is defined @@ -214,6 +215,21 @@ public: */ void SetDefaultNbSegments(CORBA::Long theNbSegments) throw ( SALOME::SALOME_Exception ); + /*! + Set an option value + */ + virtual void SetOption(const char*, const char*); + /*! + Return an option value + */ + virtual char* GetOption(const char*); + + /*! + * To load full mesh data from study at hyp modification or not + */ + bool ToForgetMeshDataOnHypModif() const { return myToForgetMeshDataOnHypModif; } + + // Create empty mesh on a shape SMESH::SMESH_Mesh_ptr CreateMesh( GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ); @@ -222,7 +238,7 @@ public: SMESH::SMESH_Mesh_ptr CreateEmptyMesh() throw ( SALOME::SALOME_Exception ); - // Create mesh(es) and import data from UNV file + // Create mesh(es) and import data from UNV fileter SMESH::SMESH_Mesh_ptr CreateMeshesFromUNV( const char* theFileName ) throw ( SALOME::SALOME_Exception ); @@ -231,14 +247,35 @@ public: SMESH::DriverMED_ReadStatus& theStatus ) throw ( SALOME::SALOME_Exception ); + // Create mesh(es) and import data from MED file + SMESH::mesh_array* CreateMeshesFromSAUV( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus ) + throw ( SALOME::SALOME_Exception ); + // Create mesh(es) and import data from STL file SMESH::SMESH_Mesh_ptr CreateMeshesFromSTL( const char* theFileName ) throw ( SALOME::SALOME_Exception ); + // Create mesh(es) and import data from CGNS file + SMESH::mesh_array* CreateMeshesFromCGNS( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus ) + throw ( SALOME::SALOME_Exception ); + + // Copy a part of mesh + SMESH::SMESH_Mesh_ptr CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, + const char* meshName, + CORBA::Boolean toCopyGroups, + CORBA::Boolean toKeepIDs); + // Compute mesh on a shape CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ); + + // Cancel Compute mesh on a shape + void CancelCompute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject ); + /*! * \brief Return errors of mesh computation */ @@ -246,24 +283,33 @@ public: GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ); + /*! + * Evaluate mesh on a shape and + * returns statistic of mesh elements + * Result array of number enityties + */ + SMESH::long_array* Evaluate(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::Boolean IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ); - + /*! * Calculate Mesh as preview till indicated dimension on shape * First, verify list of hypothesis associated with the subShape. * Return mesh preview structure */ SMESH::MeshPreviewStruct* Precompute( SMESH::SMESH_Mesh_ptr theMesh, - GEOM::GEOM_Object_ptr theSubObject, - SMESH::Dimension theDimension, - SMESH::long_array& theShapesId ) + GEOM::GEOM_Object_ptr theSubObject, + SMESH::Dimension theDimension, + SMESH::long_array& theShapesId ) throw ( SALOME::SALOME_Exception ); // Returns errors of hypotheses definintion - SMESH::algo_error_array* GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, + SMESH::algo_error_array* GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) throw ( SALOME::SALOME_Exception ); @@ -285,54 +331,61 @@ public: // Return geometrical object the given element is built on. Don't publish it in study. GEOM::GEOM_Object_ptr FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, - CORBA::Long theElementID) + CORBA::Long theElementID) throw ( SALOME::SALOME_Exception ); // Concatenate the given meshes into one mesh - SMESH::SMESH_Mesh_ptr ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance, - CORBA::Boolean theCommonGroups) + SMESH::SMESH_Mesh_ptr ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, + CORBA::Double theMergeTolerance, + CORBA::Boolean theCommonGroups) 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) + SMESH::SMESH_Mesh_ptr Concatenate(const SMESH::mesh_array& theMeshesArray, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, + CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ); // Concatenate the given meshes into one mesh // Create the groups of all elements from initial meshes - SMESH::SMESH_Mesh_ptr ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance) + SMESH::SMESH_Mesh_ptr ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, + CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ); + // Get MED version of the file by its name + CORBA::Boolean GetMEDVersion(const char* theFileName, + SMESH::MED_VERSION& theVersion); + + // Get names of meshes defined in file with the specified name + SMESH::string_array* GetMeshNames(const char* theFileName); + // **************************************************** // Interface inherited methods (from SALOMEDS::Driver) // **************************************************** // Save SMESH data SALOMEDS::TMPFile* Save( SALOMEDS::SComponent_ptr theComponent, - const char* theURL, - bool isMultiFile ); + const char* theURL, + bool isMultiFile ); // Load SMESH data bool Load( SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile ); + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ); // Save SMESH data in ASCII format SALOMEDS::TMPFile* SaveASCII( SALOMEDS::SComponent_ptr theComponent, - const char* theURL, - bool isMultiFile ); + const char* theURL, + bool isMultiFile ); // Load SMESH data in ASCII format bool LoadASCII( SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile ); + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ); // Create filter manager SMESH::FilterManager_ptr CreateFilterManager(); @@ -340,30 +393,33 @@ public: // Return a pattern mesher SMESH::SMESH_Pattern_ptr GetPattern(); + // Create measurement instance + SMESH::Measurements_ptr CreateMeasurements(); + // Clears study-connected data when it is closed void Close( SALOMEDS::SComponent_ptr theComponent ); - + // Get component data type char* ComponentDataType(); - + // Transform data from transient form to persistent char* IORToLocalPersistentID( SALOMEDS::SObject_ptr theSObject, - const char* IORString, - CORBA::Boolean isMultiFile, - CORBA::Boolean isASCII ); + const char* IORString, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII ); // Transform data from persistent form to transient char* LocalPersistentIDToIOR( SALOMEDS::SObject_ptr theSObject, - const char* aLocalPersistentID, - CORBA::Boolean isMultiFile, - CORBA::Boolean isASCII ); + const char* aLocalPersistentID, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII ); // Returns true if object can be published in the study bool CanPublishInStudy( CORBA::Object_ptr theIOR ); // Publish object in the study SALOMEDS::SObject_ptr PublishInStudy( SALOMEDS::Study_ptr theStudy, - SALOMEDS::SObject_ptr theSObject, - CORBA::Object_ptr theObject, - const char* theName ) + SALOMEDS::SObject_ptr theSObject, + CORBA::Object_ptr theObject, + const char* theName ) throw ( SALOME::SALOME_Exception ); // Copy-paste methods - returns true if object can be copied to the clipboard @@ -374,8 +430,8 @@ public: CORBA::Boolean CanPaste( const char* theComponentName, CORBA::Long theObjectID ) { return false; } // Copy-paste methods - paste object from the clipboard SALOMEDS::SObject_ptr PasteInto( const SALOMEDS::TMPFile& theStream, - CORBA::Long theObjectID, - SALOMEDS::SObject_ptr theObject ) { + CORBA::Long theObjectID, + SALOMEDS::SObject_ptr theObject ) { SALOMEDS::SObject_var aResultSO; return aResultSO._retn(); } @@ -384,9 +440,10 @@ public: // Dump python // ============ - virtual Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy, - CORBA::Boolean isPublished, - CORBA::Boolean& isValidScript); + virtual Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy, + CORBA::Boolean isPublished, + CORBA::Boolean isMultiFile, + CORBA::Boolean& isValidScript); void AddToPythonScript (int theStudyID, const TCollection_AsciiString& theString); @@ -394,10 +451,12 @@ public: void SavePython (SALOMEDS::Study_ptr theStudy); - TCollection_AsciiString DumpPython_impl (SALOMEDS::Study_ptr theStudy, + TCollection_AsciiString DumpPython_impl (SALOMEDS::Study_ptr theStudy, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, Resource_DataMapOfAsciiStringAsciiString& theNames, - bool isPublished, + bool isPublished, + bool isMultiFile, + bool isHistoricalDump, bool& aValidScript, const TCollection_AsciiString& theSavedTrace); @@ -413,7 +472,7 @@ public: // Get shape reader GEOM_Client* GetShapeReader(); - // Tags definition + // Tags definition static long GetHypothesisRootTag(); static long GetAlgorithmsRootTag(); static long GetRefOnShapeTag(); @@ -430,6 +489,8 @@ public: static long GetEdgeGroupsTag(); static long GetFaceGroupsTag(); static long GetVolumeGroupsTag(); + static long Get0DElementsGroupsTag(); + static long GetBallElementsGroupsTag(); // publishing methods SALOMEDS::SComponent_ptr PublishComponent(SALOMEDS::Study_ptr theStudy); @@ -443,7 +504,7 @@ public: SMESH::SMESH_Mesh_ptr theMesh, SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Object_ptr theShapeObject, - const char* theName = 0); + const char* theName = 0); SALOMEDS::SObject_ptr PublishGroup (SALOMEDS::Study_ptr theStudy, SMESH::SMESH_Mesh_ptr theMesh, SMESH::SMESH_GroupBase_ptr theGroup, @@ -464,6 +525,9 @@ public: const char* theName, const char* theDefaultName = 0); + static void SetPixMap(SALOMEDS::SObject_ptr theSObject, + const char* thePixMap); + // Get study context StudyContext* GetCurrentStudyContext(); @@ -474,7 +538,7 @@ public: CORBA::Long GetObjectId(CORBA::Object_ptr theObject); // Return an object that previously had an oldID - template + template typename TInterface::_var_type GetObjectByOldId( const int oldID ) { if ( StudyContext* myStudyContext = GetCurrentStudyContext() ) { @@ -486,31 +550,38 @@ public: } // Get current study ID - int GetCurrentStudyID() - { return myCurrentStudy->_is_nil() ? -1 : myCurrentStudy->StudyId(); } + int GetCurrentStudyID(); /*! * \brief Find SObject for an algo */ SALOMEDS::SObject_ptr GetAlgoSO(const ::SMESH_Algo* algo); - void UpdateParameters(CORBA::Object_ptr theObject, const char* theParameters); + void UpdateParameters(/*CORBA::Object_ptr theObject,*/ const char* theParameters); char* GetParameters(CORBA::Object_ptr theObject); char* ParseParameters(const char* theParameters); - - + const std::vector< std::string >& GetLastParameters() const { return myLastParameters; } + private: // Create hypothesis of given type SMESH::SMESH_Hypothesis_ptr createHypothesis( const char* theHypName, const char* theLibName) throw ( SALOME::SALOME_Exception ); - + // Create empty mesh on shape SMESH::SMESH_Mesh_ptr createMesh() throw ( SALOME::SALOME_Exception ); static void loadGeomData( SALOMEDS::SComponent_ptr theCompRoot ); - + + SMESH::mesh_array* CreateMeshesFromMEDorSAUV( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus, + const char* theCommandNameForPython, + const char* theFileNameForPython); + + void setCurrentStudy( SALOMEDS::Study_ptr theStudy, + bool theStudyIsBeingClosed=false); + private: static GEOM::GEOM_Gen_var myGeomGen; static CORBA::ORB_var myOrb; // ORB reference @@ -518,7 +589,7 @@ private: static SALOME_NamingService* myNS; // Naming Service static SALOME_LifeCycleCORBA* myLCC; // Life Cycle CORBA static SMESH_Gen_i* mySMESHGen; // Point to last created instance of the class - ::SMESH_Gen myGen; // SMESH_Gen local implementation + ::SMESH_Gen myGen; // SMESH_Gen local implementation // hypotheses managing map myHypCreatorMap; @@ -529,8 +600,13 @@ private: SALOMEDS::Study_var myCurrentStudy; // Current study CORBA::Boolean myIsEmbeddedMode; // Current mode + // To load full mesh data from study at hyp modification or not + bool myToForgetMeshDataOnHypModif; + // Dump Python: trace of API methods calls std::map < int, Handle(TColStd_HSequenceOfAsciiString) > myPythonScripts; + bool myIsHistoricalPythonDump; + std::vector< std::string > myLastParameters; }; diff --git a/src/SMESH_I/SMESH_Gen_i_1.cxx b/src/SMESH_I/SMESH_Gen_i_1.cxx index b0701ea59..1638083b5 100644 --- a/src/SMESH_I/SMESH_Gen_i_1.cxx +++ b/src/SMESH_I/SMESH_Gen_i_1.cxx @@ -1,31 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses -// File : SMESH_Gen_i_1.cxx -// Created : Thu Oct 21 17:24:06 2004 -// Author : Edward AGAPOV (eap) -// Module : SMESH -// $Header: +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESH_Gen_i_1.cxx +// Created : Thu Oct 21 17:24:06 2004 +// Author : Edward AGAPOV (eap) +// Module : SMESH + #include "SMESH_Gen_i.hxx" #include "SMESH_Mesh_i.hxx" @@ -40,13 +38,14 @@ #include "Utils_ExceptHandlers.hxx" #include +#include #ifdef _DEBUG_ static int MYDEBUG = 0; -static int VARIABLE_DEBUG = 0; +//static int VARIABLE_DEBUG = 0; #else static int MYDEBUG = 0; -static int VARIABLE_DEBUG = 0; +//static int VARIABLE_DEBUG = 0; #endif //============================================================================= @@ -137,6 +136,16 @@ long SMESH_Gen_i::GetVolumeGroupsTag() return SMESH::Tag_VolumeGroups; } +long SMESH_Gen_i::Get0DElementsGroupsTag() +{ + return SMESH::Tag_0DElementsGroups; +} + +long SMESH_Gen_i::GetBallElementsGroupsTag() +{ + return SMESH::Tag_BallElementsGroups; +} + //============================================================================= /*! * SMESH_Gen_i::CanPublishInStudy @@ -210,8 +219,10 @@ GEOM::GEOM_Object_ptr SMESH_Gen_i::ShapeToGeomObject (const TopoDS_Shape& theSha GEOM_Client* aClient = GetShapeReader(); TCollection_AsciiString IOR; if ( aClient && aClient->Find( theShape, IOR )) - aShapeObj = GEOM::GEOM_Object::_narrow - ( GetORB()->string_to_object( IOR.ToCString() ) ); + { + CORBA::Object_var obj = GetORB()->string_to_object( IOR.ToCString() ); + aShapeObj = GEOM::GEOM_Object::_narrow ( obj ); + } } return aShapeObj._retn(); } @@ -262,7 +273,8 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr theStudy, } if ( thePixMap ) { anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributePixMap" ); - SALOMEDS::AttributePixMap::_narrow( anAttr )->SetPixMap( thePixMap ); + SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr ); + pm->SetPixMap( thePixMap ); } if ( !theSelectable ) { anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeSelectable" ); @@ -298,6 +310,25 @@ void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject, } } +//======================================================================= +//function : SetPixMap +//purpose : +//======================================================================= + +void SMESH_Gen_i::SetPixMap(SALOMEDS::SObject_ptr theSObject, + const char* thePixMap) +{ + if ( !theSObject->_is_nil() && thePixMap && strlen( thePixMap )) + { + SALOMEDS::Study_var aStudy = theSObject->GetStudy(); + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::GenericAttribute_var anAttr = + aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributePixMap" ); + SALOMEDS::AttributePixMap_var aPMAttr = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPMAttr->SetPixMap( thePixMap ); + } +} + //======================================================================= //function : addReference //purpose : @@ -349,9 +380,9 @@ static void addReference (SALOMEDS::Study_ptr theStudy, //============================================================================= SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, - SALOMEDS::SObject_ptr theSObject, - CORBA::Object_ptr theIOR, - const char* theName) + SALOMEDS::SObject_ptr theSObject, + CORBA::Object_ptr theIOR, + const char* theName) throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -446,9 +477,9 @@ static long findMaxChildTag( SALOMEDS::SObject_ptr theSObject ) if ( !aStudy->_is_nil() ) { SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator( theSObject ); for ( ; anIter->More(); anIter->Next() ) { - long nTag = anIter->Value()->Tag(); - if ( nTag > aTag ) - aTag = nTag; + long nTag = anIter->Value()->Tag(); + if ( nTag > aTag ) + aTag = nTag; } } } @@ -499,13 +530,12 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr theStudy, // Publish global hypotheses - SMESH::ListOfHypothesis * hypList = theMesh->GetHypothesisList( aShapeObject ); - if ( hypList ) - for ( int i = 0; i < hypList->length(); i++ ) { - SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( (*hypList)[ i ]); - PublishHypothesis( theStudy, aHyp ); - AddHypothesisToShape( theStudy, theMesh, aShapeObject, aHyp ); - } + SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( aShapeObject ); + for ( int i = 0; i < hypList->length(); i++ ) { + SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]); + PublishHypothesis( theStudy, aHyp ); + AddHypothesisToShape( theStudy, theMesh, aShapeObject, aHyp ); + } } // Publish submeshes @@ -569,7 +599,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr theS } // Find submesh sub-tree tag long aRootTag; - char* aRootName = ""; + const char* aRootName = ""; switch ( theShapeObject->GetShapeType() ) { case GEOM::VERTEX: aRootTag = GetSubMeshOnVertexTag(); @@ -607,7 +637,10 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr theS SetName( aRootSO, aRootName ); // Add new submesh to corresponding sub-tree - aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, "ICON_SMESH_TREE_MESH_WARN"); + SMESH::array_of_ElementType_var elemTypes = theSubMesh->GetTypes(); + const int isEmpty = ( elemTypes->length() == 0 ); + const char* pm[2] = { "ICON_SMESH_TREE_MESH", "ICON_SMESH_TREE_MESH_WARN" }; + aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, pm[isEmpty] ); if ( aSubMeshSO->_is_nil() ) return aSubMeshSO._retn(); } @@ -655,21 +688,36 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr theStudy } int aType = (int)theGroup->GetType(); const char* aRootNames[] = { - "Compound Groups", "Groups of Nodes", - "Groups of Edges", "Groups of Faces", "Groups of Volumes" }; + "Compound Groups", "Groups of Nodes", "Groups of Edges", + "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements", + "Groups of Balls" }; // Currently, groups with heterogenous content are not supported - if ( aType != SMESH::ALL ) { + if ( aType != SMESH::ALL ) + { long aRootTag = GetNodeGroupsTag() + aType - 1; // Find or create groups root SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(), aMeshSO, aRootTag, 0, false ); - if ( aType < 5 ) + if ( aType < sizeof(aRootNames)/sizeof(char*) ) SetName( aRootSO, aRootNames[aType] ); // Add new group to corresponding sub-tree - aGroupSO = publish (theStudy, theGroup, aRootSO, 0, "ICON_SMESH_TREE_GROUP" ); + SMESH::array_of_ElementType_var elemTypes = theGroup->GetTypes(); + int isEmpty = ( elemTypes->length() == 0 ); + std::string pm[2] = { "ICON_SMESH_TREE_GROUP", "ICON_SMESH_TREE_MESH_WARN" }; + if ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )) + { + pm[0] = "ICON_SMESH_TREE_GROUP_ON_FILTER"; + } + else if ( SMESH::DownCast< SMESH_Group_i* > ( theGroup )) + { + SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes(); + for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i ) + isEmpty = ( allElemTypes[i] != theGroup->GetType() ); + } + aGroupSO = publish (theStudy, theGroup, aRootSO, 0, pm[isEmpty].c_str() ); } if ( aGroupSO->_is_nil() ) return aGroupSO._retn(); @@ -869,71 +917,146 @@ bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr theStudy //function : UpdateParameters //purpose : //======================================================================= -void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theParameters) +void SMESH_Gen_i::UpdateParameters(/*CORBA::Object_ptr theObject,*/ const char* theParameters) { - - if(VARIABLE_DEBUG) - cout<<"UpdateParameters : "<_is_nil() || CORBA::is_nil(theObject)) - return; - - SALOMEDS::SObject_var aSObj = ObjectToSObject(aStudy,theObject); - if(aSObj->_is_nil()) + if ( aStudy->_is_nil() ) return; - - SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); - - SALOMEDS::GenericAttribute_var aFindAttr; - bool hasAttr = aSObj->FindAttribute(aFindAttr, "AttributeString"); - if(VARIABLE_DEBUG) - cout<<"Find Attribute "<FindOrCreateAttribute( aSObj, "AttributeString"); - SALOMEDS::AttributeString_var aStringAttr = SALOMEDS::AttributeString::_narrow(anAttr); - - TCollection_AsciiString aNewParams; - TCollection_AsciiString aOldParameters(aStringAttr->Value()); - TCollection_AsciiString anInputParams(ParseParameters(theParameters)); - - if(!hasAttr) - aNewParams = anInputParams; - else - aNewParams = aOldParameters+"|"+anInputParams; - - if(VARIABLE_DEBUG) + myLastParameters.clear(); + int pos = 0, prevPos = 0, len = strlen( theParameters ); + if ( len == 0 ) return; + while ( pos <= len ) + { + if ( pos == len || theParameters[pos] == ':' ) { - cout<<"Input Parameters : "<IsVariable( val.c_str() )) + val.clear(); + myLastParameters.push_back( val ); + } + else + { + myLastParameters.push_back(""); + } + prevPos = pos+1; } - - - aStringAttr->SetValue( aNewParams.ToCString() ); + ++pos; + } + return; + + // OLD VARIANT + + // if(VARIABLE_DEBUG) + // cout<<"UpdateParameters : "<_is_nil() || CORBA::is_nil(theObject)) + // return; + + // SALOMEDS::SObject_var aSObj = ObjectToSObject(aStudy,theObject); + // if(aSObj->_is_nil()) + // return; + + // SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + + // SALOMEDS::GenericAttribute_var aFindAttr; + // bool hasAttr = aSObj->FindAttribute(aFindAttr, "AttributeString"); + // if(VARIABLE_DEBUG) + // cout<<"Find Attribute "<FindOrCreateAttribute( aSObj, "AttributeString"); + // SALOMEDS::AttributeString_var aStringAttr = SALOMEDS::AttributeString::_narrow(anAttr); + + // CORBA::String_var oldparVar = aStringAttr->Value(); + // CORBA::String_var inpparVar = ParseParameters(theParameters); + // TCollection_AsciiString aNewParams; + // TCollection_AsciiString aOldParameters(oldparVar.inout()); + // TCollection_AsciiString anInputParams(inpparVar.inout()); + // if(!hasAttr) + // aNewParams = anInputParams; + // else + // { + // int pos = aOldParameters.SearchFromEnd("|"); + // if(pos==-1) pos = 0; + // TCollection_AsciiString previousParamFull(aOldParameters.Split(pos)); + // TCollection_AsciiString previousParam(previousParamFull); + // TCollection_AsciiString theRepet("1"); + // pos = previousParam.SearchFromEnd(";*="); + // if(pos >= 0) + // { + // theRepet = previousParam.Split(pos+2); + // pos = pos-1; + // if(pos==-1) pos = 0; + // previousParam.Split(pos); + // } + // if(previousParam == anInputParams) + // { + // theRepet = theRepet.IntegerValue()+1; + // aNewParams = aOldParameters + previousParam + ";*=" + theRepet; + // } + // else + // { + // aNewParams = aOldParameters + previousParamFull + "|" + anInputParams; + // } + // } + + // if(VARIABLE_DEBUG) + // { + // cout<<"Input Parameters : "<SetValue( aNewParams.ToCString() ); } //======================================================================= //function : ParseParameters -//purpose : +//purpose : Replace variables by their values //======================================================================= char* SMESH_Gen_i::ParseParameters(const char* theParameters) { - const char* aParameters = CORBA::string_dup(theParameters); + //const char* aParameters = theParameters; +// const char* aParameters = CORBA::string_dup(theParameters); TCollection_AsciiString anInputParams; - SALOMEDS::Study_ptr aStudy = GetCurrentStudy(); + SALOMEDS::Study_var aStudy = GetCurrentStudy(); if( !aStudy->_is_nil() ) { - SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); - for(int j=0;jlength();j++) { - SALOMEDS::ListOfStrings aVars= aSections[j]; - for(int i=0;iIsVariable(aVars[i].in()) ? - TCollection_AsciiString(aVars[i].in()) : TCollection_AsciiString(""); - if(i != aVars.length()-1) - anInputParams+=":"; +// SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(theParameters); +// for(int j=0;jlength();j++) { +// SALOMEDS::ListOfStrings aVars= aSections[j]; +// for(int i=0;iIsVariable(aVars[i].in()) ? +// TCollection_AsciiString(aVars[i].in()) : TCollection_AsciiString(""); +// if(i != aVars.length()-1) +// anInputParams+=":"; +// } +// if(j!=aSections->length()-1) +// anInputParams+="|"; +// } + TCollection_AsciiString paramStr( theParameters ); + static TCollection_AsciiString separators(":|"); + int beg = 0, end; + char sep, *pParams = (char*)paramStr.ToCString(); + while ( beg < paramStr.Length() ) + { + end = beg-1; + while ( ++end < paramStr.Length() ) + if ( pParams[end] == ':' || pParams[end] == '|') + break; + if ( end < paramStr.Length()) + { + sep = pParams[end]; + pParams[end] = '\0'; } - if(j!=aSections->length()-1) - anInputParams+="|"; + if ( aStudy->IsVariable( pParams+beg )) + anInputParams += pParams+beg; + if ( end < paramStr.Length() ) + anInputParams += sep; + else + break; + beg = end + 1; } } return CORBA::string_dup(anInputParams.ToCString()); diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx index 045e691b9..1b99653c6 100644 --- a/src/SMESH_I/SMESH_Group_i.cxx +++ b/src/SMESH_I/SMESH_Group_i.cxx @@ -1,39 +1,45 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : SMESH_Group_i.cxx // Author : Sergey ANIKIN, OCC // Module : SMESH // #include "SMESH_Group_i.hxx" -#include "SMESH_Mesh_i.hxx" -#include "SMESH_Gen_i.hxx" -#include "SMESH_Group.hxx" + +#include "SMDSAbs_ElementType.hxx" #include "SMESHDS_Group.hxx" +#include "SMESHDS_GroupOnFilter.hxx" #include "SMESHDS_GroupOnGeom.hxx" -#include "SMDSAbs_ElementType.hxx" - +#include "SMESH_Comment.hxx" #include "SMESH_Filter_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_Mesh_i.hxx" #include "SMESH_PythonDump.hxx" +#include "SMESH_PreMeshInfo.hxx" + +#include CORBA_SERVER_HEADER(SMESH_Filter) #include "utilities.h" @@ -45,30 +51,48 @@ using namespace SMESH; */ //============================================================================= -SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID ) +SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA, + SMESH_Mesh_i* theMeshServant, + const int theLocalID ) : SALOME::GenericObj_i( thePOA ), myMeshServant( theMeshServant ), - myLocalID( theLocalID ) + myLocalID( theLocalID ), + myNbNodes(-1), + myGroupDSTic(0), + myPreMeshInfo(NULL) { // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i, // servant activation is performed by SMESH_Mesh_i::createGroup() // thePOA->activate_object( this ); } -SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID ) +SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA, + SMESH_Mesh_i* theMeshServant, + const int theLocalID ) : SALOME::GenericObj_i( thePOA ), SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID ) { //MESSAGE("SMESH_Group_i; this = "<FullLoadFromFile(); + SMESHDS_GroupBase* aGroupDS = GetGroupDS(); if (aGroupDS) return aGroupDS->Contains(theID); @@ -251,6 +291,9 @@ CORBA::Boolean SMESH_GroupBase_i::Contains( CORBA::Long theID ) CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs ) { + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + // Update Python script TPythonDump() << "nbAdd = " << _this() << ".Add( " << theIDs << " )"; @@ -277,6 +320,9 @@ CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs ) CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs ) { + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + // Update Python script TPythonDump() << "nbDel = " << _this() << ".Remove( " << theIDs << " )"; @@ -305,8 +351,8 @@ typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int); CORBA::Long ChangeByPredicate( SMESH::Predicate_i* thePredicate, - SMESHDS_GroupBase* theGroupBase, - TFunChangeGroup theFun) + SMESHDS_GroupBase* theGroupBase, + TFunChangeGroup theFun) { CORBA::Long aNb = 0; if(SMESHDS_Group* aGroupDS = dynamic_cast(theGroupBase)){ @@ -317,7 +363,7 @@ ChangeByPredicate( SMESH::Predicate_i* thePredicate, CORBA::Long i = 0, iEnd = aSequence.size(); for(; i < iEnd; i++) if((aGroupDS->*theFun)(aSequence[i])) - aNb++; + aNb++; return aNb; } return aNb; @@ -327,6 +373,9 @@ CORBA::Long SMESH_Group_i:: AddByPredicate( SMESH::Predicate_ptr thePredicate ) { + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){ TPythonDump()<<_this()<<".AddByPredicate("<FullLoadFromFile(); + if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){ TPythonDump()<<_this()<<".RemoveByPredicate("<FullLoadFromFile(); + + TPythonDump pd; + long nbAdd = 0; + SMESHDS_Group* aGroupDS = dynamic_cast( GetGroupDS() ); + if (aGroupDS) { + SMESH::long_array_var anIds; + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theSource); + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow(theSource); + SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(theSource); + SMESH::Filter_var filter = SMESH::Filter::_narrow(theSource); + if ( !group->_is_nil()) + anIds = group->GetType()==GetType() ? theSource->GetIDs() : new SMESH::long_array(); + else if ( !mesh->_is_nil() ) + anIds = mesh->GetElementsByType( GetType() ); + else if ( !submesh->_is_nil()) + anIds = submesh->GetElementsByType( GetType() ); + else if ( !filter->_is_nil() ) { + filter->SetMesh( GetMeshServant()->_this() ); + anIds = filter->GetElementType()==GetType() ? theSource->GetIDs() : new SMESH::long_array(); + } + else + anIds = theSource->GetIDs(); + for ( int i = 0, total = anIds->length(); i < total; i++ ) { + if ( aGroupDS->Add((int)anIds[i]) ) nbAdd++; + } + } + + // Update Python script + pd << "nbAdd = " << _this() << ".AddFrom( " << theSource << " )"; + + return nbAdd; +} + //============================================================================= /*! * @@ -353,6 +442,9 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate ) CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex ) { + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + SMESHDS_GroupBase* aGroupDS = GetGroupDS(); if (aGroupDS) return aGroupDS->GetID(theIndex); @@ -368,30 +460,113 @@ CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex ) SMESH::long_array* SMESH_GroupBase_i::GetListOfID() { + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aRes = new SMESH::long_array(); SMESHDS_GroupBase* aGroupDS = GetGroupDS(); - if (aGroupDS) { + if (aGroupDS) + { int aSize = aGroupDS->Extent(); aRes->length(aSize); for (int i = 0; i < aSize; i++) aRes[i] = aGroupDS->GetID(i+1); - return aRes._retn(); + + if ( 0 < aSize && aSize < 100 ) // for comfortable testing ;) + std::sort( &aRes[0], &aRes[0]+aSize ); } MESSAGE("get list of IDs of a vague group"); return aRes._retn(); } -//============================================================================= +namespace +{ + //================================================================================ + /*! + * \brief return nodes of elements pointered by iterator + */ + //================================================================================ + + void getNodesOfElements(SMDS_ElemIteratorPtr elemIt, + set& nodes) + { + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + nodes.insert( e->begin_nodes(), e->end_nodes() ); + } + } +} + +//================================================================================ /*! - * + * \brief return the number of nodes of cells included to the group */ -//============================================================================= -SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh() +//================================================================================ + +CORBA::Long SMESH_GroupBase_i::GetNumberOfNodes() { - SMESH::SMESH_Mesh_var aMesh; - if ( myMeshServant ) - aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() ); - return aMesh._retn(); + if ( GetType() == SMESH::NODE ) + return Size(); + + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + + if ( SMESHDS_GroupBase* g = GetGroupDS()) + { + if ( myNbNodes < 0 || g->GetTic() != myGroupDSTic ) + { + set nodes; + getNodesOfElements( g->GetElements(), nodes ); + myNbNodes = nodes.size(); + myGroupDSTic = g->GetTic(); + } + } + return myNbNodes; +} + +//================================================================================ +/*! + * \brief Return true if GetNumberOfNodes() won't take a long time for computation + */ +//================================================================================ + +CORBA::Boolean SMESH_GroupBase_i::IsNodeInfoAvailable() +{ + if ( GetType() == SMESH::NODE/* || Size() < 100000 */) + return true; + if ( myPreMeshInfo ) + return false; + if ( SMESHDS_GroupBase* g = GetGroupDS()) + return ( myNbNodes > -1 && g->GetTic() == myGroupDSTic); + return false; +} + +//================================================================================ +/*! + * \brief Return IDs of nodes of cells included to the group + */ +//================================================================================ + +SMESH::long_array* SMESH_GroupBase_i::GetNodeIDs() +{ + if ( GetType() == SMESH::NODE ) + return GetListOfID(); + + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + + SMESH::long_array_var aRes = new SMESH::long_array(); + if ( SMESHDS_GroupBase* g = GetGroupDS()) + { + set nodes; + getNodesOfElements( g->GetElements(), nodes ); + aRes->length( nodes.size() ); + set::iterator nIt = nodes.begin(), nEnd = nodes.end(); + for ( int i = 0; nIt != nEnd; ++nIt, ++i ) + aRes[i] = (*nIt)->GetID(); + } + return aRes._retn(); } //============================================================================= @@ -399,10 +574,12 @@ SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh() * */ //============================================================================= -SMESH::long_array* SMESH_GroupBase_i::GetIDs() +SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh() { - SMESH::long_array_var aResult = GetListOfID(); - return aResult._retn(); + SMESH::SMESH_Mesh_var aMesh; + if ( myMeshServant ) + aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() ); + return aMesh._retn(); } //======================================================================= @@ -454,10 +631,13 @@ void SMESH_GroupBase_i::SetColor(const SALOMEDS::Color& color) if (aGroupDS) { Quantity_Color aQColor( color.R, color.G, color.B, Quantity_TOC_RGB ); - return aGroupDS->SetColor(aQColor); + Quantity_Color oldColor = aGroupDS->GetColor(); + if ( oldColor != aQColor ) + { + aGroupDS->SetColor(aQColor); + TPythonDump()<<_this()<<".SetColor( SALOMEDS.Color( "<SetColorGroup(color); + { + aGroupDS->SetColorGroup(color); + TPythonDump()<<_this()<<".SetColorNumber( "<GetMeshInfo(); + + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + + if ( SMESHDS_GroupBase* g = GetGroupDS()) + { + if ( g->GetType() == SMDSAbs_Node || ( myNbNodes > -1 && g->GetTic() == myGroupDSTic)) + aRes[ SMDSEntity_Node ] = GetNumberOfNodes(); + + if ( g->GetType() != SMDSAbs_Node ) + SMESH_Mesh_i::CollectMeshInfo( g->GetElements(), aRes); + } + + return aRes._retn(); +} + +//======================================================================= +//function : GetIDs +//purpose : Returns ids of members +//======================================================================= + +SMESH::long_array* SMESH_GroupBase_i::GetIDs() +{ + return GetListOfID(); +} + +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_GroupBase_i::GetTypes() +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + if ( !IsEmpty() ) + { + types->length( 1 ); + types[0] = GetType(); + } + return types._retn(); +} + +//======================================================================= +//function : IsMeshInfoCorrect +//purpose : * Returns false if GetMeshInfo() returns incorrect information that may +// * happen if mesh data is not yet fully loaded from the file of study. +//======================================================================= + +bool SMESH_GroupBase_i::IsMeshInfoCorrect() +{ + return myPreMeshInfo ? myPreMeshInfo->IsMeshInfoCorrect() : true; +} + +//================================================================================ +/*! + * \brief Retrieves the predicate from the filter + */ +//================================================================================ + +SMESH_PredicatePtr SMESH_GroupOnFilter_i::GetPredicate( SMESH::Filter_ptr filter ) +{ + SMESH_PredicatePtr predicate; + + if ( SMESH::Filter_i* filt_i = SMESH::DownCast< SMESH::Filter_i* >( filter )) + if ( SMESH::Predicate_i* predic_i= filt_i->GetPredicate_i() ) + predicate = predic_i->GetPredicate(); + + return predicate; +} + +//================================================================================ +/*! + * \brief Sets the filter defining group contents + */ +//================================================================================ + +void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter) +{ + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + + if ( ! myFilter->_is_nil() ) + myFilter->UnRegister(); + + myFilter = SMESH::Filter::_duplicate( theFilter ); + + if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() )) + grDS->SetPredicate( GetPredicate( myFilter )); + + TPythonDump()<< _this() <<".SetFilter( "<Register(); + SMESH::DownCast< SMESH::Filter_i* >( myFilter )->AddWaiter( this ); + } +} + +//================================================================================ +/*! + * \brief Returns the filter defining group contents + */ +//================================================================================ + +SMESH::Filter_ptr SMESH_GroupOnFilter_i::GetFilter() +{ + SMESH::Filter_var f = myFilter; + TPythonDump() << f << " = " << _this() << ".GetFilter()"; + return f._retn(); +} + +#define SEPAR '^' + +//================================================================================ +/*! + * \brief Return a string to be used to store group definition in the study + */ +//================================================================================ + +std::string SMESH_GroupOnFilter_i::FilterToString() const +{ + SMESH_Comment result; + SMESH::Filter::Criteria_var criteria; + if ( !myFilter->_is_nil() && myFilter->GetCriteria( criteria.out() )) + { + result << criteria->length() << SEPAR; + for ( unsigned i = 0; i < criteria->length(); ++i ) + { + // write FunctorType as string but not as number to assure correct + // persistence if enum FunctorType is modified by insertion in the middle + SMESH::Filter::Criterion& crit = criteria[ i ]; + result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Type )) << SEPAR; + result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Compare )) << SEPAR; + result << crit.Threshold << SEPAR; + result << crit.ThresholdStr << SEPAR; + result << crit.ThresholdID << SEPAR; + result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.UnaryOp )) << SEPAR; + result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.BinaryOp ))<< SEPAR; + result << crit.Tolerance << SEPAR; + result << crit.TypeOfElement << SEPAR; + result << crit.Precision << SEPAR; + } + } + return result; +} + +//================================================================================ +/*! + * \brief Restore the filter by the persistent string + */ +//================================================================================ + +SMESH::Filter_ptr SMESH_GroupOnFilter_i::StringToFilter(const std::string& thePersistStr ) +{ + SMESH::Filter_var filter; + + // divide thePersistStr into sub-strings + std::vector< std::string > strVec; + std::string::size_type from = 0, to; + while ( from < thePersistStr.size() ) + { + to = thePersistStr.find( SEPAR, from ); + if ( to == std::string::npos ) + break; + strVec.push_back( thePersistStr.substr( from, to-from )); + from = to+1; + } + if ( strVec.empty() || strVec[0] == "0" ) + return filter._retn(); +#undef SEPAR + + // create Criteria + int nbCrit = atoi( strVec[0].c_str() ); + SMESH::Filter::Criteria_var criteria = new SMESH::Filter::Criteria; + criteria->length( nbCrit ); + int nbStrPerCrit = ( strVec.size() - 1 ) / nbCrit; + for ( int i = 0; i < nbCrit; ++i ) + { + SMESH::Filter::Criterion& crit = criteria[ i ]; + int iStr = 1 + i * nbStrPerCrit; + crit.Type = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() ); + crit.Compare = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() ); + crit.Threshold = atof( strVec[ iStr++ ].c_str() ); + crit.ThresholdStr = strVec[ iStr++ ].c_str(); + crit.ThresholdID = strVec[ iStr++ ].c_str(); + crit.UnaryOp = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() ); + crit.BinaryOp = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() ); + crit.Tolerance = atof( strVec[ iStr++ ].c_str() ); + crit.TypeOfElement= SMESH::ElementType( atoi( strVec[ iStr++ ].c_str() )); + crit.Precision = atoi( strVec[ iStr++ ].c_str() ); + } + + // create a filter + TPythonDump pd; + SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i(); + filter = aFilterMgr->CreateFilter(); + filter->SetCriteria( criteria.inout() ); + + aFilterMgr->UnRegister(); + + pd << ""; // to avoid optimizing pd out + + return filter._retn(); +} + +//================================================================================ +/*! + * \brief Destructor of SMESH_GroupOnFilter_i + */ +//================================================================================ + +SMESH_GroupOnFilter_i::~SMESH_GroupOnFilter_i() +{ + if ( ! myFilter->_is_nil() ) + { + SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveWaiter( this ); + myFilter->UnRegister(); + } +} + +//================================================================================ +/*! + * \brief Method calleds when a predicate of myFilter changes + */ +//================================================================================ + +void SMESH_GroupOnFilter_i::PredicateChanged() +{ + if ( myPreMeshInfo ) + myPreMeshInfo->FullLoadFromFile(); + + if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() )) + grDS->SetPredicate( GetPredicate( myFilter )); +} diff --git a/src/SMESH_I/SMESH_Group_i.hxx b/src/SMESH_I/SMESH_Group_i.hxx index 8e6e33f9f..dcb441057 100644 --- a/src/SMESH_I/SMESH_Group_i.hxx +++ b/src/SMESH_I/SMESH_Group_i.hxx @@ -1,34 +1,36 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : SMESH_Group_i.hxx // Author : Sergey ANIKIN, OCC // Module : SMESH -// $Header$ // #ifndef SMESH_Group_i_HeaderFile #define SMESH_Group_i_HeaderFile #include "SMESH.hxx" +#include "SMESH_Mesh_i.hxx" +#include "SMESH_Filter_i.hxx" #include #include CORBA_SERVER_HEADER(SMESH_Group) @@ -37,9 +39,9 @@ #include "SALOME_GenericObj_i.hh" -class SMESH_Mesh_i; class SMESH_Group; class SMESHDS_GroupBase; +class SMESH_PreMeshInfo; // =========== // Group Base @@ -50,8 +52,8 @@ class SMESH_I_EXPORT SMESH_GroupBase_i: { public: SMESH_GroupBase_i(PortableServer::POA_ptr thePOA, - SMESH_Mesh_i* theMeshServant, - const int theLocalID ); + SMESH_Mesh_i* theMeshServant, + const int theLocalID ); virtual ~SMESH_GroupBase_i(); // CORBA interface implementation @@ -63,11 +65,33 @@ class SMESH_I_EXPORT SMESH_GroupBase_i: CORBA::Boolean Contains(CORBA::Long elem_id); CORBA::Long GetID(CORBA::Long elem_index); SMESH::long_array* GetListOfID(); - SMESH::SMESH_Mesh_ptr GetMesh(); + SMESH::long_array* GetNodeIDs(); + CORBA::Long GetNumberOfNodes(); + CORBA::Boolean IsNodeInfoAvailable(); // for gui + + virtual SMESH::SMESH_Mesh_ptr GetMesh(); + + /*! + * Returns statistic of mesh elements + * Result array of number enityties + * Inherited from SMESH_IDSource + */ + virtual SMESH::long_array* GetMeshInfo(); // Inherited from SMESH_IDSource interface virtual SMESH::long_array* GetIDs(); + /*! + * Returns types of elements it contains + * Inherited from SMESH_IDSource interface + */ + virtual SMESH::array_of_ElementType* GetTypes(); + /*! + * Returns false if GetMeshInfo() returns incorrect information that may + * happen if mesh data is not yet fully loaded from the file of study. + */ + virtual bool IsMeshInfoCorrect(); + // Internal C++ interface int GetLocalID() const { return myLocalID; } SMESH_Mesh_i* GetMeshServant() const { return myMeshServant; } @@ -80,9 +104,20 @@ class SMESH_I_EXPORT SMESH_GroupBase_i: void SetColorNumber(CORBA::Long color); CORBA::Long GetColorNumber(); +protected: + + SMESH_PreMeshInfo* & changePreMeshInfo() { return myPreMeshInfo; } + SMESH_PreMeshInfo* myPreMeshInfo; // mesh info before full loading from study file + friend class SMESH_PreMeshInfo; + private: SMESH_Mesh_i* myMeshServant; int myLocalID; + + void changeLocalId(int localId) { myLocalID = localId; } + friend class SMESH_Mesh_i; + + int myNbNodes, myGroupDSTic; }; // ====== @@ -94,8 +129,9 @@ class SMESH_I_EXPORT SMESH_Group_i: public SMESH_GroupBase_i { public: - SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID ); - + SMESH_Group_i( PortableServer::POA_ptr thePOA, + SMESH_Mesh_i* theMeshServant, + const int theLocalID ); // CORBA interface implementation void Clear(); CORBA::Long Add( const SMESH::long_array& theIDs ); @@ -103,6 +139,8 @@ class SMESH_I_EXPORT SMESH_Group_i: CORBA::Long AddByPredicate( SMESH::Predicate_ptr thePredicate ); CORBA::Long RemoveByPredicate( SMESH::Predicate_ptr thePredicate ); + + CORBA::Long AddFrom( SMESH::SMESH_IDSource_ptr theSource ); }; // ========================= @@ -114,9 +152,42 @@ class SMESH_I_EXPORT SMESH_GroupOnGeom_i: public SMESH_GroupBase_i { public: - SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID ); - + SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA, + SMESH_Mesh_i* theMeshServant, + const int theLocalID ); // CORBA interface implementation GEOM::GEOM_Object_ptr GetShape(); }; + +// ========================= +// Group deined by filter +// ========================= + +class SMESH_I_EXPORT SMESH_GroupOnFilter_i: + public virtual POA_SMESH::SMESH_GroupOnFilter, + public SMESH_GroupBase_i, + public SMESH::Filter_i::TPredicateChangeWaiter +{ + public: + SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA, + SMESH_Mesh_i* theMeshServant, + const int theLocalID ); + ~SMESH_GroupOnFilter_i(); + + // Persistence + static SMESH::Filter_ptr StringToFilter(const std::string& thePersistentString ); + std::string FilterToString() const; + + static SMESH_PredicatePtr GetPredicate( SMESH::Filter_ptr ); + + // CORBA interface implementation + void SetFilter(SMESH::Filter_ptr theFilter); + SMESH::Filter_ptr GetFilter(); + + // method of SMESH::Filter_i::TPredicateChangeWaiter + virtual void PredicateChanged(); + + private: + SMESH::Filter_var myFilter; +}; #endif diff --git a/src/SMESH_I/SMESH_Hypothesis_i.cxx b/src/SMESH_I/SMESH_Hypothesis_i.cxx index b677e647b..96131044b 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.cxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Hypothesis_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include #include @@ -138,6 +138,78 @@ bool SMESH_Hypothesis_i::IsPublished(){ return res; } +//================================================================================ +/*! + * \brief Set the pramIndex-th parameter + */ +//================================================================================ + +void SMESH_Hypothesis_i::SetVarParameter (const char* theParameter, + const char* theMethod) +{ + if ( SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen() ) + { + gen->UpdateParameters(theParameter); + + const std::vector< std::string >& pars = gen->GetLastParameters(); + if ( !pars.empty() ) + myMethod2VarParams[ theMethod ] = pars[0]; + } +} + +//================================================================================ +/*! + * \brief Return the pramIndex-th variable parameter used for Hypothesis creation + */ +//================================================================================ + +char* SMESH_Hypothesis_i::GetVarParameter (const char* theMethod) +{ + if ( myMethod2VarParams.count("needs update by old study")) + { + // restore myMethod2VarParams by old study + myMethod2VarParams.clear(); + if ( SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen() ) + { + CORBA::String_var oldparVar = gen->GetParameters( _this() ); + setOldParameters( oldparVar.in() ); + } + } + std::map< std::string, std::string >::iterator meth_param = myMethod2VarParams.find( theMethod ); + if ( meth_param != myMethod2VarParams.end() ) + return CORBA::string_dup( meth_param->second.c_str() ); + + return CORBA::string_dup(""); +} + +//================================================================================ +/*! + * \brief Restore myMethod2VarParams by parameters stored in an old study + */ +//================================================================================ + +void SMESH_Hypothesis_i::setOldParameters (const char* theParameters) +{ + if ( SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen() ) + { + TCollection_AsciiString aOldParameters(theParameters); + int pos = aOldParameters.SearchFromEnd("|"); + if ( pos >= 0 ) aOldParameters = aOldParameters.Split(pos); + pos = aOldParameters.SearchFromEnd(";*="); + if ( pos >= 0 ) aOldParameters.Split(pos-1); + gen->UpdateParameters( aOldParameters.ToCString() ); + + myMethod2VarParams.clear(); + const std::vector< std::string >& pars = gen->GetLastParameters(); + for ( size_t i = 0; i < pars.size(); ++i ) + { + std::string meth = getMethodOfParameter( i, pars.size() ); + myMethod2VarParams[ meth ] = pars[i]; + } + gen->UpdateParameters(""); // clear params + } +} + //============================================================================= /*! * SMESH_Hypothesis_i::SetParameters() @@ -147,14 +219,15 @@ bool SMESH_Hypothesis_i::IsPublished(){ void SMESH_Hypothesis_i::SetParameters(const char* theParameters) { SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen(); - char * aParameters = CORBA::string_dup(theParameters); + //char * aParameters = CORBA::string_dup(theParameters); if(gen){ - if(IsPublished()) { - SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Hypothesis::_narrow(_this()),aParameters); - } - else { - myBaseImpl->SetParameters(gen->ParseParameters(aParameters)); - } + gen->UpdateParameters(theParameters); + // if(IsPublished()) { + // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Hypothesis::_narrow(_this()),aParameters); + // } + // else { + // myBaseImpl->SetParameters(gen->ParseParameters(aParameters)); + // } } } @@ -230,9 +303,10 @@ void SMESH_Hypothesis_i::SetLastParameters(const char* theParameters) //============================================================================= void SMESH_Hypothesis_i::ClearParameters() { - if(!IsPublished()) { - myBaseImpl->ClearParameters(); - } + myMethod2VarParams.clear(); + // if(!IsPublished()) { + // myBaseImpl->ClearParameters(); + // } } //============================================================================= @@ -245,7 +319,6 @@ void SMESH_Hypothesis_i::ClearParameters() ::SMESH_Hypothesis* SMESH_Hypothesis_i::GetImpl() { - //MESSAGE( "SMESH_Hypothesis_i::GetImpl" ); return myBaseImpl; } @@ -259,8 +332,18 @@ void SMESH_Hypothesis_i::ClearParameters() char* SMESH_Hypothesis_i::SaveTo() { - MESSAGE( "SMESH_Hypothesis_i::SaveTo" ); std::ostringstream os; + + // assure that parameters are loaded from an old study + CORBA::String_var p = GetVarParameter(""); + + os << "VARS " << myMethod2VarParams.size() << " "; + std::map< std::string, std::string >::iterator meth_param = myMethod2VarParams.begin(); + for ( ; meth_param != myMethod2VarParams.end(); ++meth_param ) + os << meth_param->first << " " + << meth_param->second.size() << " " + << meth_param->second << " "; + myBaseImpl->SaveTo( os ); return CORBA::string_dup( os.str().c_str() ); } @@ -275,7 +358,44 @@ char* SMESH_Hypothesis_i::SaveTo() void SMESH_Hypothesis_i::LoadFrom( const char* theStream ) { - MESSAGE( "SMESH_Hypothesis_i::LoadFrom" ); std::istringstream is( theStream ); + if ( strncmp( theStream, "VARS", 4 ) == 0 ) + { + int nbVars, len; + char str[256]; + std::string meth; + is >> str >> nbVars; + for ( int i = 0; i < nbVars; ++i ) + { + is >> meth >> len; + if ( len < 256 ) + { + is.get( str, len + 2 ); // 2 - to read at least 1 white space + if ( len > 0 ) + myMethod2VarParams[ meth ] = std::string( str+1, len ); + } + } + } + else + { + // we can't restore myMethod2VarParams by old study here because SObject + // isn't yet bound to _this() + myMethod2VarParams["needs update by old study"] = "yes"; + } + myBaseImpl->LoadFrom( is ); + + // let listeners know about loading (issue 0020918) + myBaseImpl->NotifySubMeshesHypothesisModification(); +} + +//================================================================================ +/*! + * \brief This mesthod is called after completion of loading a study + */ +//================================================================================ + +void SMESH_Hypothesis_i::UpdateAsMeshesRestored() +{ + // for hyps needing full data restored } diff --git a/src/SMESH_I/SMESH_Hypothesis_i.hxx b/src/SMESH_I/SMESH_Hypothesis_i.hxx index 13bd7742f..593ed85ca 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.hxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Hypothesis_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_HYPOTHESIS_I_HXX_ #define _SMESH_HYPOTHESIS_I_HXX_ @@ -38,6 +38,11 @@ #include "SMESH_Gen.hxx" +#include +#include + +class TCollection_AsciiString; + // ====================================================== // Generic hypothesis // ====================================================== @@ -65,6 +70,14 @@ public: // Get unique id of hypothesis CORBA::Long GetId(); + // Set the variable parameter; method is a name of method setting this parameter. + // This method must be called by the hypothesis creator just before calling hyp->method() + void SetVarParameter (const char* parameter, const char* method); + + // Return the variable parameter used for Hypothesis creation by name of method + // setting this parameter + char* GetVarParameter (const char* methodName); + // Set list of parameters separated by ":" symbol, used for Hypothesis creation void SetParameters (const char* theParameters); @@ -90,9 +103,27 @@ public: // Persistence virtual char* SaveTo(); virtual void LoadFrom( const char* theStream ); - + virtual void UpdateAsMeshesRestored(); // for hyps needing full data restored + protected: - ::SMESH_Hypothesis* myBaseImpl; // base hypothesis implementation + ::SMESH_Hypothesis* myBaseImpl; // base hypothesis implementation + + std::map< std::string, std::string > myMethod2VarParams; // variable parameters + + + public: + // Methods for backward compatibility of notebook variables + + // restore myMethod2VarParams by parameters stored in an old study + virtual void setOldParameters (const char* theParameters); + + // method used to convert variable parameters stored in an old study + // into myMethod2VarParams. It should return a method name for an index of + // variable parameters. Index is countered from zero + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const { return ""; } + + // method intended to remove explicit treatment of Netgen hypotheses from SMESH_NoteBook + virtual int getParamIndex(const TCollection_AsciiString& method, int nbVars) const { return -1; } }; // ====================================================== diff --git a/src/SMESH_I/SMESH_MEDFamily_i.cxx b/src/SMESH_I/SMESH_MEDFamily_i.cxx index 35bacddc3..3218fd486 100644 --- a/src/SMESH_I/SMESH_MEDFamily_i.cxx +++ b/src/SMESH_I/SMESH_MEDFamily_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MEDFamily_i.cxx // Module : SMESH @@ -77,7 +78,7 @@ SMESH_MEDFamily_i::~SMESH_MEDFamily_i() */ //============================================================================= SMESH_MEDFamily_i::SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm, - string name, string description, SALOME_MED::medEntityMesh entity): + string name, string description, SALOME_MED::medEntityMesh entity): SMESH_MEDSupport_i( sm, name, description, entity ), _subMesh_i(sm), @@ -101,9 +102,9 @@ SMESH_MEDFamily_i::SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm, CORBA::Long SMESH_MEDFamily_i::getIdentifier() throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); return _identifier; } @@ -115,9 +116,9 @@ throw (SALOME::SALOME_Exception) CORBA::Long SMESH_MEDFamily_i::getNumberOfAttributes() throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); return _numberOfAttribute; } //============================================================================= @@ -125,20 +126,20 @@ throw (SALOME::SALOME_Exception) * CORBA: Accessor for attributes identifiers */ //============================================================================= -SALOME_MED::long_array* SMESH_MEDFamily_i::getAttributesIdentifiers() +SALOME_TYPES::ListOfLong* SMESH_MEDFamily_i::getAttributesIdentifiers() throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); if (_numberOfAttribute == 0) { MESSAGE("Les familles SMESH n ont pas d attribut"); THROW_SALOME_CORBA_EXCEPTION("No attributes"\ - ,SALOME::BAD_PARAM); + ,SALOME::BAD_PARAM); }; - SALOME_MED::long_array_var myseq= new SALOME_MED::long_array; + SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong; myseq->length(_numberOfAttribute); for (int i=0;i<_numberOfAttribute;i++) { @@ -155,17 +156,17 @@ throw (SALOME::SALOME_Exception) CORBA::Long SMESH_MEDFamily_i::getAttributeIdentifier(CORBA::Long i) throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); MESSAGE("Les familles SMESH n ont pas d attribut"); THROW_SALOME_CORBA_EXCEPTION("No attributes"\ - ,SALOME::BAD_PARAM); + ,SALOME::BAD_PARAM); if (_numberOfAttribute == 0) { MESSAGE("Les familles SMESH n ont pas d attribut"); THROW_SALOME_CORBA_EXCEPTION("No attributes"\ - ,SALOME::BAD_PARAM); + ,SALOME::BAD_PARAM); }; ASSERT (i <= _numberOfAttribute); return _attributeIdentifier[i]; @@ -175,21 +176,21 @@ CORBA::Long SMESH_MEDFamily_i::getAttributeIdentifier(CORBA::Long i) * CORBA: Accessor for attributes values */ //============================================================================= -SALOME_MED::long_array* SMESH_MEDFamily_i::getAttributesValues() +SALOME_TYPES::ListOfLong* SMESH_MEDFamily_i::getAttributesValues() throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); if (_numberOfAttribute == 0) { MESSAGE("Les familles SMESH n ont pas d attribut"); THROW_SALOME_CORBA_EXCEPTION("No attributes"\ - ,SALOME::BAD_PARAM); + ,SALOME::BAD_PARAM); }; - SALOME_MED::long_array_var myseq= new SALOME_MED::long_array; + SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong; myseq->length(_numberOfAttribute); for (int i=0;i<_numberOfAttribute;i++) { @@ -205,14 +206,14 @@ SALOME_MED::long_array* SMESH_MEDFamily_i::getAttributesValues() CORBA::Long SMESH_MEDFamily_i::getAttributeValue(CORBA::Long i) throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); if (_numberOfAttribute == 0) { MESSAGE("Les familles SMESH n ont pas d attribut"); THROW_SALOME_CORBA_EXCEPTION("No attributes"\ - ,SALOME::BAD_PARAM); + ,SALOME::BAD_PARAM); } ASSERT (i <= _numberOfAttribute); @@ -223,19 +224,19 @@ CORBA::Long SMESH_MEDFamily_i::getAttributeValue(CORBA::Long i) * CORBA: Accessor for attributes desriptions */ //============================================================================= -SALOME_MED::string_array * SMESH_MEDFamily_i::getAttributesDescriptions() +SALOME_TYPES::ListOfString * SMESH_MEDFamily_i::getAttributesDescriptions() throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); if (_numberOfAttribute == 0) { MESSAGE("Les familles SMESH n ont pas d attribut"); THROW_SALOME_CORBA_EXCEPTION("No attributes"\ - ,SALOME::BAD_PARAM); + ,SALOME::BAD_PARAM); } - SALOME_MED::string_array_var myseq = new SALOME_MED::string_array; + SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString; for (int i=0;i<_numberOfAttribute;i++) { myseq[i]=CORBA::string_dup(_attributeDescription[i].c_str()); @@ -250,14 +251,14 @@ SALOME_MED::string_array * SMESH_MEDFamily_i::getAttributesDescriptions() char * SMESH_MEDFamily_i::getAttributeDescription( CORBA::Long i) throw (SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) + if (_subMesh==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Family",\ - SALOME::INTERNAL_ERROR); + SALOME::INTERNAL_ERROR); if (_numberOfAttribute == 0) { MESSAGE("Les familles SMESH n ont pas d attribut"); THROW_SALOME_CORBA_EXCEPTION("No attributes"\ - ,SALOME::BAD_PARAM); + ,SALOME::BAD_PARAM); } ASSERT (i <= _numberOfAttribute); return CORBA::string_dup(_attributeDescription[i].c_str()); @@ -291,7 +292,7 @@ char * SMESH_MEDFamily_i::getGroupName( CORBA::Long i) * CORBA: Accessor for all the groups name */ //============================================================================= -SALOME_MED::string_array* SMESH_MEDFamily_i::getGroupsNames() +SALOME_TYPES::ListOfString* SMESH_MEDFamily_i::getGroupsNames() throw (SALOME::SALOME_Exception) { MESSAGE("!!! NOT YET IMPLEMENTED !!!!"); diff --git a/src/SMESH_I/SMESH_MEDFamily_i.hxx b/src/SMESH_I/SMESH_MEDFamily_i.hxx index 2b850fc8a..c96df39c0 100644 --- a/src/SMESH_I/SMESH_MEDFamily_i.hxx +++ b/src/SMESH_I/SMESH_MEDFamily_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MEDFamily_i.hxx // Module : SMESH @@ -56,7 +57,7 @@ public : // Constructors and associated internal methods SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm, - std::string name, std::string description, SALOME_MED::medEntityMesh entity ); + std::string name, std::string description, SALOME_MED::medEntityMesh entity ); SMESH_MEDFamily_i(const SMESH_MEDFamily_i & f); // IDL Methods @@ -69,15 +70,15 @@ public : throw (SALOME::SALOME_Exception); CORBA::Long getNumberOfAttributes() throw (SALOME::SALOME_Exception); - SALOME_MED::long_array* getAttributesIdentifiers() + SALOME_TYPES::ListOfLong* getAttributesIdentifiers() throw (SALOME::SALOME_Exception); CORBA::Long getAttributeIdentifier(CORBA::Long i) throw (SALOME::SALOME_Exception); - SALOME_MED::long_array* getAttributesValues() + SALOME_TYPES::ListOfLong* getAttributesValues() throw (SALOME::SALOME_Exception); CORBA::Long getAttributeValue(CORBA::Long i) throw (SALOME::SALOME_Exception); - SALOME_MED::string_array* getAttributesDescriptions() + SALOME_TYPES::ListOfString* getAttributesDescriptions() throw (SALOME::SALOME_Exception); char* getAttributeDescription( CORBA::Long i) throw (SALOME::SALOME_Exception); @@ -85,7 +86,7 @@ public : throw (SALOME::SALOME_Exception); char * getGroupName( CORBA::Long i) throw (SALOME::SALOME_Exception); - SALOME_MED::string_array* getGroupsNames() + SALOME_TYPES::ListOfString* getGroupsNames() throw (SALOME::SALOME_Exception); }; #endif /* MED_FAMILY_I_HXX_ */ diff --git a/src/SMESH_I/SMESH_MEDMesh_i.cxx b/src/SMESH_I/SMESH_MEDMesh_i.cxx index 9ee46fda3..823c8a037 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.cxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.cxx @@ -1,29 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MEDMesh_i.cxx // Module : SMESH // #include "SMESH_MEDMesh_i.hxx" +#include "SMESH_Gen_i.hxx" #include "SMESH_Mesh_i.hxx" #include "SMESHDS_Mesh.hxx" @@ -69,8 +71,8 @@ using namespace std; // PN Est-ce un const ? SMESH_MEDMesh_i::SMESH_MEDMesh_i() { - BEGIN_OF("Default Constructor SMESH_MEDMesh_i"); - END_OF("Default Constructor SMESH_MEDMesh_i"); + BEGIN_OF("Default Constructor SMESH_MEDMesh_i"); + END_OF("Default Constructor SMESH_MEDMesh_i"); } //============================================================================= @@ -88,18 +90,18 @@ SMESH_MEDMesh_i::~SMESH_MEDMesh_i() */ //============================================================================= SMESH_MEDMesh_i::SMESH_MEDMesh_i(::SMESH_Mesh_i * m_i):_meshId(""), - _compte(false), - _creeFamily(false), - _famIdent(0), - _indexElts(0), - _indexEnts(0) + _compte(false), + _creeFamily(false), + _famIdent(0), + _indexElts(0), + _indexEnts(0) { - BEGIN_OF("Constructor SMESH_MEDMesh_i"); + BEGIN_OF("Constructor SMESH_MEDMesh_i"); - _mesh_i = m_i; - _meshDS = _mesh_i->GetImpl().GetMeshDS(); + _mesh_i = m_i; + _meshDS = _mesh_i->GetImpl().GetMeshDS(); - END_OF("Constructor SMESH_MEDMesh_i"); + END_OF("Constructor SMESH_MEDMesh_i"); } //============================================================================= @@ -109,22 +111,28 @@ SMESH_MEDMesh_i::SMESH_MEDMesh_i(::SMESH_Mesh_i * m_i):_meshId(""), //============================================================================= char *SMESH_MEDMesh_i::getName() throw(SALOME::SALOME_Exception) { - if (_meshDS == NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - - try - { - // A COMPLETER PAR LE NOM DU MAILLAGE - //return CORBA::string_dup(_mesh_i->getName().c_str()); - return CORBA::string_dup("toto"); - } - catch(...) - { - MESSAGE("Exception en accedant au nom"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } + if (_meshDS == NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + + try + { + SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var study = gen->GetCurrentStudy(); + SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, _mesh_i->_this()); + if ( meshSO->_is_nil() ) + return CORBA::string_dup("toto"); + + CORBA::String_var name = meshSO->GetName(); + return CORBA::string_dup( name.in() ); + } + catch(...) + { + MESSAGE("Exception en accedant au nom"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } + return 0; } //============================================================================= @@ -134,8 +142,8 @@ char *SMESH_MEDMesh_i::getName() throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_MEDMesh_i::getCorbaIndex()throw(SALOME::SALOME_Exception) { - MESSAGE("Non Implemente"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + MESSAGE("Non Implemente"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); } //============================================================================= @@ -145,11 +153,11 @@ CORBA::Long SMESH_MEDMesh_i::getCorbaIndex()throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_MEDMesh_i::getSpaceDimension()throw(SALOME::SALOME_Exception) { - // PN : Il semblerait que la dimension soit fixee a 3 - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - return 3; + // PN : Il semblerait que la dimension soit fixee a 3 + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + return 3; } //============================================================================= @@ -159,14 +167,14 @@ CORBA::Long SMESH_MEDMesh_i::getSpaceDimension()throw(SALOME::SALOME_Exception) //============================================================================= CORBA::Long SMESH_MEDMesh_i::getMeshDimension()throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - // PN : Il semblerait que la dimension soit fixee a 3 - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - return 3; + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + // PN : Il semblerait que la dimension soit fixee a 3 + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + return 3; } //============================================================================= /*! @@ -188,7 +196,7 @@ CORBA::Boolean SMESH_MEDMesh_i::getIsAGrid() throw (SALOME::SALOME_Exception) //============================================================================= CORBA::Boolean SMESH_MEDMesh_i::existConnectivity(SALOME_MED::medConnectivity connectivityType, - SALOME_MED::medEntityMesh entity) + SALOME_MED::medEntityMesh entity) throw (SALOME::SALOME_Exception) { MESSAGE("!!!!!! IMPLEMENTED BUT ONLY PARTIALLY !!!!!!"); @@ -218,21 +226,21 @@ CORBA::Double SMESH_MEDMesh_i::getCoordinate(CORBA::Long Number, CORBA::Long Axi //============================================================================= char *SMESH_MEDMesh_i::getCoordinatesSystem() throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - // PN : En dur. Non encore prevu - try - { - string systcoo = "CARTESIEN"; - return CORBA::string_dup(systcoo.c_str()); - } - catch(...) - { - MESSAGE("Exception en accedant au maillage"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + // PN : En dur. Non encore prevu + try + { + string systcoo = "CARTESIEN"; + return CORBA::string_dup(systcoo.c_str()); + } + catch(...) + { + MESSAGE("Exception en accedant au maillage"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } } //============================================================================= @@ -240,56 +248,56 @@ char *SMESH_MEDMesh_i::getCoordinatesSystem() throw(SALOME::SALOME_Exception) * CORBA: Accessor for Coordinates */ //============================================================================= -SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates( - SALOME_MED::medModeSwitch typeSwitch) throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfDouble * SMESH_MEDMesh_i::getCoordinates +(SALOME_MED::medModeSwitch typeSwitch) throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - SALOME_MED::double_array_var myseq = new SALOME_MED::double_array; - try - { - // PN : En dur - int spaceDimension = 3; - int nbNodes = _meshDS->NbNodes(); - SCRUTE(nbNodes); - myseq->length(nbNodes * spaceDimension); - int i = 0; - - SMDS_NodeIteratorPtr itNodes=_meshDS->nodesIterator(); - while(itNodes->more()) - { - const SMDS_MeshNode* node = itNodes->next(); - - if (typeSwitch == SALOME_MED::MED_FULL_INTERLACE) - { - myseq[i * 3] = node->X(); - myseq[i * 3 + 1] = node->Y(); - myseq[i * 3 + 2] = node->Z(); - SCRUTE(myseq[i * 3]); - SCRUTE(myseq[i * 3 + 1]); - SCRUTE(myseq[i * 3 + 2]); - } - else - { - ASSERT(typeSwitch == SALOME_MED::MED_NO_INTERLACE); - myseq[i] = node->X(); - myseq[i + nbNodes] = node->Y(); - myseq[i + (nbNodes * 2)] = node->Z(); - SCRUTE(myseq[i]); - SCRUTE(myseq[i + nbNodes]); - SCRUTE(myseq[i + (nbNodes * 2)]); - } - i++; - } - } - catch(...) - { - MESSAGE("Exception en accedant aux coordonnees"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } - return myseq._retn(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + SALOME_TYPES::ListOfDouble_var myseq = new SALOME_TYPES::ListOfDouble; + try + { + // PN : En dur + int spaceDimension = 3; + int nbNodes = _meshDS->NbNodes(); + SCRUTE(nbNodes); + myseq->length(nbNodes * spaceDimension); + int i = 0; + + SMDS_NodeIteratorPtr itNodes=_meshDS->nodesIterator(); + while(itNodes->more()) + { + const SMDS_MeshNode* node = itNodes->next(); + + if (typeSwitch == SALOME_MED::MED_FULL_INTERLACE) + { + myseq[i * 3] = node->X(); + myseq[i * 3 + 1] = node->Y(); + myseq[i * 3 + 2] = node->Z(); + SCRUTE(myseq[i * 3]); + SCRUTE(myseq[i * 3 + 1]); + SCRUTE(myseq[i * 3 + 2]); + } + else + { + ASSERT(typeSwitch == SALOME_MED::MED_NO_INTERLACE); + myseq[i] = node->X(); + myseq[i + nbNodes] = node->Y(); + myseq[i + (nbNodes * 2)] = node->Z(); + SCRUTE(myseq[i]); + SCRUTE(myseq[i + nbNodes]); + SCRUTE(myseq[i + (nbNodes * 2)]); + } + i++; + } + } + catch(...) + { + MESSAGE("Exception en accedant aux coordonnees"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } + return myseq._retn(); } //============================================================================= @@ -297,29 +305,29 @@ SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates( * CORBA: Accessor for Coordinates Names */ //============================================================================= -SALOME_MED::string_array * - SMESH_MEDMesh_i::getCoordinatesNames()throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfString * +SMESH_MEDMesh_i::getCoordinatesNames()throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - SALOME_MED::string_array_var myseq = new SALOME_MED::string_array; - try - { - // PN : en dur - int spaceDimension = 3; - myseq->length(spaceDimension); - myseq[0] = CORBA::string_dup("x"); - myseq[1] = CORBA::string_dup("y"); - myseq[2] = CORBA::string_dup("z"); - } - catch(...) - { - MESSAGE("Exception en accedant aux noms des coordonnees"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } - return myseq._retn(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString; + try + { + // PN : en dur + int spaceDimension = 3; + myseq->length(spaceDimension); + myseq[0] = CORBA::string_dup("x"); + myseq[1] = CORBA::string_dup("y"); + myseq[2] = CORBA::string_dup("z"); + } + catch(...) + { + MESSAGE("Exception en accedant aux noms des coordonnees"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } + return myseq._retn(); } @@ -328,29 +336,29 @@ SALOME_MED::string_array * * CORBA: Accessor for Coordinates Units */ //============================================================================= -SALOME_MED::string_array * - SMESH_MEDMesh_i::getCoordinatesUnits()throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfString * +SMESH_MEDMesh_i::getCoordinatesUnits()throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - SALOME_MED::string_array_var myseq = new SALOME_MED::string_array; - try - { - // PN : en dur - int spaceDimension = 3; - myseq->length(spaceDimension); - myseq[0] = CORBA::string_dup("m"); - myseq[1] = CORBA::string_dup("m"); - myseq[2] = CORBA::string_dup("m"); - } - catch(...) - { - MESSAGE("Exception en accedant aux unites des coordonnees"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } - return myseq._retn(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString; + try + { + // PN : en dur + int spaceDimension = 3; + myseq->length(spaceDimension); + myseq[0] = CORBA::string_dup("m"); + myseq[1] = CORBA::string_dup("m"); + myseq[2] = CORBA::string_dup("m"); + } + catch(...) + { + MESSAGE("Exception en accedant aux unites des coordonnees"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } + return myseq._retn(); } //============================================================================= @@ -360,19 +368,19 @@ SALOME_MED::string_array * //============================================================================= CORBA::Long SMESH_MEDMesh_i::getNumberOfNodes()throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - try - { - return _meshDS->NbNodes(); - } - catch(...) - { - MESSAGE("Exception en accedant au nombre de noeuds"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + try + { + return _meshDS->NbNodes(); + } + catch(...) + { + MESSAGE("Exception en accedant au nombre de noeuds"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } } //============================================================================= @@ -381,119 +389,119 @@ CORBA::Long SMESH_MEDMesh_i::getNumberOfNodes()throw(SALOME::SALOME_Exception) */ //============================================================================= CORBA::Long SMESH_MEDMesh_i::getNumberOfTypes(SALOME_MED::medEntityMesh entity) -throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - try - { - if (!_compte) - calculeNbElts(); - int retour = 0; - if (_mapNbTypes.find(entity) != _mapNbTypes.end()) - retour = _mapNbTypes[entity]; - return retour; - } - catch(...) - { - MESSAGE("Exception en accedant au nombre de Types"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + try + { + if (!_compte) + calculeNbElts(); + int retour = 0; + if (_mapNbTypes.find(entity) != _mapNbTypes.end()) + retour = _mapNbTypes[entity]; + return retour; + } + catch(...) + { + MESSAGE("Exception en accedant au nombre de Types"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } } //============================================================================= /*! * CORBA: Accessor for existing geometry element types - * Not implemented for MED_ALL_ENTITIES + * Not implemented for MED_ALL_ENTITIES */ //============================================================================= SALOME_MED::medGeometryElement_array * - SMESH_MEDMesh_i::getTypes(SALOME_MED::medEntityMesh entity) throw(SALOME:: - SALOME_Exception) +SMESH_MEDMesh_i::getTypes(SALOME_MED::medEntityMesh entity) throw(SALOME:: + SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - if (entity == SALOME_MED::MED_ALL_ENTITIES) - THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ENTITIES", - SALOME::BAD_PARAM); - if (!_compte) - calculeNbElts(); - SALOME_MED::medGeometryElement_array_var myseq = - new SALOME_MED::medGeometryElement_array; - try - { - if (_mapNbTypes.find(entity) == _mapNbTypes.end()) - THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh", - SALOME::BAD_PARAM); - int nbTypes = _mapNbTypes[entity]; - - myseq->length(nbTypes); - - if (_mapIndToVectTypes.find(entity) == _mapIndToVectTypes.end()) - THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh", - SALOME::INTERNAL_ERROR); - - int index = _mapIndToVectTypes[entity]; - ASSERT(_TypesId[index].size() != 0); - int i = 0; - vector < SALOME_MED::medGeometryElement >::iterator it; - for (it = _TypesId[index].begin(); it != _TypesId[index].end(); it++) - { - myseq[i++] = *it; - }; - } - catch(...) - { - MESSAGE("Exception en accedant aux differents types"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } - return myseq._retn(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + if (entity == SALOME_MED::MED_ALL_ENTITIES) + THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ENTITIES", + SALOME::BAD_PARAM); + if (!_compte) + calculeNbElts(); + SALOME_MED::medGeometryElement_array_var myseq = + new SALOME_MED::medGeometryElement_array; + try + { + if (_mapNbTypes.find(entity) == _mapNbTypes.end()) + THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh", + SALOME::BAD_PARAM); + int nbTypes = _mapNbTypes[entity]; + + myseq->length(nbTypes); + + if (_mapIndToVectTypes.find(entity) == _mapIndToVectTypes.end()) + THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh", + SALOME::INTERNAL_ERROR); + + int index = _mapIndToVectTypes[entity]; + ASSERT(_TypesId[index].size() != 0); + int i = 0; + vector < SALOME_MED::medGeometryElement >::iterator it; + for (it = _TypesId[index].begin(); it != _TypesId[index].end(); it++) + { + myseq[i++] = *it; + }; + } + catch(...) + { + MESSAGE("Exception en accedant aux differents types"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } + return myseq._retn(); } //============================================================================= /*! * CORBA: Returns number of elements of type medGeometryElement - * Not implemented for MED_ALL_ELEMENTS - * implemented for MED_ALL_ENTITIES + * Not implemented for MED_ALL_ELEMENTS + * implemented for MED_ALL_ENTITIES * * Dans cette implementation, il n est pas prevu de tenir compte du entity * qui ne doit pas pouvoir avoir deux valeurs differentes pour un geomElement */ //============================================================================= CORBA::Long SMESH_MEDMesh_i::getNumberOfElements(SALOME_MED:: - medEntityMesh entity, - SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) + medEntityMesh entity, + SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - if (geomElement == SALOME_MED::MED_ALL_ELEMENTS) - THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ELEMENTS", - SALOME::BAD_PARAM); - if (!_compte) - calculeNbElts(); - - try - { - int retour = 0; - if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end()) - { - int index = _mapIndToSeqElts[geomElement]; - - retour = _seq_elemId[index]->length(); - } - return retour; - } - catch(...) - { - MESSAGE("Exception en accedant au nombre d élements"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", - SALOME::INTERNAL_ERROR); - } + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + if (geomElement == SALOME_MED::MED_ALL_ELEMENTS) + THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ELEMENTS", + SALOME::BAD_PARAM); + if (!_compte) + calculeNbElts(); + + try + { + int retour = 0; + if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end()) + { + int index = _mapIndToSeqElts[geomElement]; + + retour = _seq_elemId[index]->length(); + } + return retour; + } + catch(...) + { + MESSAGE("Exception en accedant au nombre d élements"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object", + SALOME::INTERNAL_ERROR); + } } //============================================================================= @@ -501,31 +509,30 @@ CORBA::Long SMESH_MEDMesh_i::getNumberOfElements(SALOME_MED:: * CORBA: Accessor for connectivities */ //============================================================================= -SALOME_MED::long_array * -SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medModeSwitch typeSwitch, - SALOME_MED::medConnectivity mode, - SALOME_MED::medEntityMesh entity, - SALOME_MED::medGeometryElement geomElement) +SALOME_TYPES::ListOfLong * +SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medConnectivity mode, + SALOME_MED::medEntityMesh entity, + SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - if (mode != SALOME_MED::MED_NODAL) - THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM); - if (typeSwitch == SALOME_MED::MED_NO_INTERLACE) - THROW_SALOME_CORBA_EXCEPTION("Not Yet Implemented", SALOME::BAD_PARAM); - if (!_compte) - calculeNbElts(); - - // Faut-il renvoyer un pointeur vide ??? - if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end()) - THROW_SALOME_CORBA_EXCEPTION("No Such Element in the mesh", - SALOME::BAD_PARAM); - - int index = _mapIndToSeqElts[geomElement]; - - return _seq_elemId[index]._retn(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + if (mode != SALOME_MED::MED_NODAL) + THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM); + /*if (typeSwitch == SALOME_MED::MED_NO_INTERLACE) + THROW_SALOME_CORBA_EXCEPTION("Not Yet Implemented", SALOME::BAD_PARAM);*/ + if (!_compte) + calculeNbElts(); + + // Faut-il renvoyer un pointeur vide ??? + if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end()) + THROW_SALOME_CORBA_EXCEPTION("No Such Element in the mesh", + SALOME::BAD_PARAM); + + int index = _mapIndToSeqElts[geomElement]; + + return _seq_elemId[index]._retn(); } //============================================================================= @@ -533,14 +540,14 @@ SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medModeSwitch typeSwitch, * CORBA: Accessor for connectivities */ //============================================================================= -SALOME_MED::long_array * +SALOME_TYPES::ListOfLong * SMESH_MEDMesh_i::getConnectivityIndex(SALOME_MED::medConnectivity mode, - SALOME_MED::medEntityMesh entity) + SALOME_MED::medEntityMesh entity) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -550,15 +557,15 @@ SMESH_MEDMesh_i::getConnectivityIndex(SALOME_MED::medConnectivity mode, //============================================================================= CORBA::Long SMESH_MEDMesh_i::getElementNumber(SALOME_MED::medConnectivity mode, - SALOME_MED::medEntityMesh entity, - SALOME_MED::medGeometryElement type, - const SALOME_MED::long_array & connectivity) + SALOME_MED::medEntityMesh entity, + SALOME_MED::medGeometryElement type, + const SALOME_TYPES::ListOfLong & connectivity) throw(SALOME::SALOME_Exception) { - const char *LOC = "getElementNumber "; - MESSAGE(LOC << "Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return -1; + const char *LOC = "getElementNumber "; + MESSAGE(LOC << "Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return -1; } //============================================================================= @@ -567,13 +574,13 @@ SMESH_MEDMesh_i::getElementNumber(SALOME_MED::medConnectivity mode, * not implemented for MED_ALL_ENTITIES and MED_MAILLE */ //============================================================================= -SALOME_MED::long_array * - SMESH_MEDMesh_i::getReverseConnectivity(SALOME_MED:: - medConnectivity mode) throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfLong * +SMESH_MEDMesh_i::getReverseConnectivity(SALOME_MED:: + medConnectivity mode) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -581,13 +588,13 @@ SALOME_MED::long_array * * CORBA: Accessor for connectivities */ //============================================================================= -SALOME_MED::long_array * - SMESH_MEDMesh_i::getReverseConnectivityIndex(SALOME_MED:: - medConnectivity mode) throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfLong * +SMESH_MEDMesh_i::getReverseConnectivityIndex(SALOME_MED:: + medConnectivity mode) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -596,14 +603,14 @@ SALOME_MED::long_array * */ //============================================================================= CORBA::Long SMESH_MEDMesh_i::getNumberOfFamilies(SALOME_MED:: - medEntityMesh entity) throw(SALOME::SALOME_Exception) + medEntityMesh entity) throw(SALOME::SALOME_Exception) { - if (_creeFamily == false) - createFamilies(); - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - return _families.size(); + if (_creeFamily == false) + createFamilies(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + return _families.size(); } //============================================================================= @@ -612,13 +619,13 @@ CORBA::Long SMESH_MEDMesh_i::getNumberOfFamilies(SALOME_MED:: */ //============================================================================= CORBA::Long SMESH_MEDMesh_i::getNumberOfGroups(SALOME_MED::medEntityMesh entity) -throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - MESSAGE(" Pas d implementation des groupes dans SMESH"); - return 0; + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + MESSAGE(" Pas d implementation des groupes dans SMESH"); + return 0; } //============================================================================= @@ -627,24 +634,24 @@ throw(SALOME::SALOME_Exception) */ //============================================================================= SALOME_MED::Family_array * - SMESH_MEDMesh_i::getFamilies(SALOME_MED:: - medEntityMesh entity) throw(SALOME::SALOME_Exception) +SMESH_MEDMesh_i::getFamilies(SALOME_MED:: + medEntityMesh entity) throw(SALOME::SALOME_Exception) { - if (_creeFamily == false) - createFamilies(); - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - SALOME_MED::Family_array_var myseq = new SALOME_MED::Family_array; - int nbfam = _families.size(); - myseq->length(nbfam); - int i = 0; - vector < SALOME_MED::FAMILY_ptr >::iterator it; - for (it = _families.begin(); it != _families.end(); it++) - { - myseq[i++] = *it; - }; - return myseq._retn(); + if (_creeFamily == false) + createFamilies(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + SALOME_MED::Family_array_var myseq = new SALOME_MED::Family_array; + int nbfam = _families.size(); + myseq->length(nbfam); + int i = 0; + vector < SALOME_MED::FAMILY_ptr >::iterator it; + for (it = _families.begin(); it != _families.end(); it++) + { + myseq[i++] = *it; + }; + return myseq._retn(); } //============================================================================= @@ -653,16 +660,16 @@ SALOME_MED::Family_array * */ //============================================================================= SALOME_MED::FAMILY_ptr SMESH_MEDMesh_i::getFamily(SALOME_MED:: - medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception) + medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception) { - if (_creeFamily == false) - createFamilies(); - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - - SCRUTE(_families[i]->getName()); - MESSAGE(" SMESH_MEDMesh_i::getFamily " << i) return _families[i]; + if (_creeFamily == false) + createFamilies(); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + + SCRUTE(_families[i]->getName()); + MESSAGE(" SMESH_MEDMesh_i::getFamily " << i) return _families[i]; } //============================================================================= @@ -671,14 +678,14 @@ SALOME_MED::FAMILY_ptr SMESH_MEDMesh_i::getFamily(SALOME_MED:: */ //============================================================================= SALOME_MED::Group_array * - SMESH_MEDMesh_i::getGroups(SALOME_MED::medEntityMesh entity) throw(SALOME:: - SALOME_Exception) +SMESH_MEDMesh_i::getGroups(SALOME_MED::medEntityMesh entity) throw(SALOME:: + SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - MESSAGE(" Pas d implementation des groupes dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + MESSAGE(" Pas d implementation des groupes dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM); } //============================================================================= @@ -687,20 +694,20 @@ SALOME_MED::Group_array * */ //============================================================================= SALOME_MED::GROUP_ptr SMESH_MEDMesh_i::getGroup(SALOME_MED:: - medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception) + medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception) { - if (_mesh_i == 0) - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - MESSAGE(" Pas d implementation des groupes dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM); + if (_mesh_i == 0) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + MESSAGE(" Pas d implementation des groupes dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM); } //============================================================================= /*! * CORBA: Returns references for the global numbering index */ //============================================================================= -SALOME_MED::long_array* +SALOME_TYPES::ListOfLong* SMESH_MEDMesh_i::getGlobalNumberingIndex(SALOME_MED::medEntityMesh entity) throw (SALOME::SALOME_Exception) { @@ -764,11 +771,11 @@ SMESH_MEDMesh_i::getSkin(SALOME_MED::SUPPORT_ptr mySupport3D) */ //============================================================================= SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getVolume(SALOME_MED:: - SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) + SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -777,11 +784,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getVolume(SALOME_MED:: */ //============================================================================= SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getArea(SALOME_MED:: - SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) + SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -790,11 +797,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getArea(SALOME_MED:: */ //============================================================================= SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getLength(SALOME_MED:: - SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) + SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -803,11 +810,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getLength(SALOME_MED:: */ //============================================================================= SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNormal(SALOME_MED:: - SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) + SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -816,11 +823,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNormal(SALOME_MED:: */ //============================================================================= SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getBarycenter(SALOME_MED:: - SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) + SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) { - MESSAGE("Pas Implemente dans SMESH"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Pas Implemente dans SMESH"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -829,11 +836,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getBarycenter(SALOME_MED:: */ //============================================================================= SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNeighbourhood(SALOME_MED:: - SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) + SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception) { - MESSAGE("Non Implemente"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Non Implemente"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -843,57 +850,57 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNeighbourhood(SALOME_MED:: */ //============================================================================= void SMESH_MEDMesh_i::addInStudy(SALOMEDS::Study_ptr myStudy, - SALOME_MED::MESH_ptr myIor) throw(SALOME::SALOME_Exception) + SALOME_MED::GMESH_ptr myIor) throw(SALOME::SALOME_Exception) { - BEGIN_OF("MED_Mesh_i::addInStudy"); - if (_meshId != "") - { - MESSAGE("Mesh already in Study"); - THROW_SALOME_CORBA_EXCEPTION("Mesh already in Study", - SALOME::BAD_PARAM); - }; - - /* - * SALOMEDS::StudyBuilder_var myBuilder = myStudy->NewBuilder(); - * - * // Create SComponent labelled 'MED' if it doesn't already exit - * SALOMEDS::SComponent_var medfather = myStudy->FindComponent("MED"); - * if ( CORBA::is_nil(medfather) ) - * { - * MESSAGE("Add Component MED"); - * medfather = myBuilder->NewComponent("MED"); - * //myBuilder->AddAttribute (medfather,SALOMEDS::Name,"MED"); - * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow( - * myBuilder->FindOrCreateAttribute(medfather, "AttributeName")); - * aName->SetValue("MED"); - * - * myBuilder->DefineComponentInstance(medfather,myIor); - * - * } ; - * - * MESSAGE("Add a mesh Object under MED"); - * myBuilder->NewCommand(); - * SALOMEDS::SObject_var newObj = myBuilder->NewObject(medfather); - * - * ORB_INIT &init = *SINGLETON_::Instance() ; - * ASSERT(SINGLETON_::IsAlreadyExisting()) ; - * CORBA::ORB_var &orb = init(0,0); - * CORBA::String_var iorStr = orb->object_to_string(myIor); - * //myBuilder->AddAttribute(newObj,SALOMEDS::IOR,iorStr.in()); - * SALOMEDS::AttributeIOR_var aIOR = SALOMEDS::AttributeIOR::_narrow( - * myBuilder->FindOrCreateAttribute(newObj, "AttributeIOR")); - * aIOR->SetValue(iorStr.c_str()); - * - * //myBuilder->AddAttribute(newObj,SALOMEDS::Name,_mesh_i->getName().c_str()); - * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow( - * myBuilder->FindOrCreateAttribute(newObj, "AttributeName")); - * aName->SetValue(_mesh_i->getName().c_str()); - * - * _meshId = newObj->GetID(); - * myBuilder->CommitCommand(); - * - */ - END_OF("Mesh_i::addInStudy(SALOMEDS::Study_ptr myStudy)"); + BEGIN_OF("MED_Mesh_i::addInStudy"); + if (_meshId != "") + { + MESSAGE("Mesh already in Study"); + THROW_SALOME_CORBA_EXCEPTION("Mesh already in Study", + SALOME::BAD_PARAM); + }; + + /* + * SALOMEDS::StudyBuilder_var myBuilder = myStudy->NewBuilder(); + * + * // Create SComponent labelled 'MED' if it doesn't already exit + * SALOMEDS::SComponent_var medfather = myStudy->FindComponent("MED"); + * if ( CORBA::is_nil(medfather) ) + * { + * MESSAGE("Add Component MED"); + * medfather = myBuilder->NewComponent("MED"); + * //myBuilder->AddAttribute (medfather,SALOMEDS::Name,"MED"); + * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow( + * myBuilder->FindOrCreateAttribute(medfather, "AttributeName")); + * aName->SetValue("MED"); + * + * myBuilder->DefineComponentInstance(medfather,myIor); + * + * } ; + * + * MESSAGE("Add a mesh Object under MED"); + * myBuilder->NewCommand(); + * SALOMEDS::SObject_var newObj = myBuilder->NewObject(medfather); + * + * ORB_INIT &init = *SINGLETON_::Instance() ; + * ASSERT(SINGLETON_::IsAlreadyExisting()) ; + * CORBA::ORB_var &orb = init(0,0); + * CORBA::String_var iorStr = orb->object_to_string(myIor); + * //myBuilder->AddAttribute(newObj,SALOMEDS::IOR,iorStr.in()); + * SALOMEDS::AttributeIOR_var aIOR = SALOMEDS::AttributeIOR::_narrow( + * myBuilder->FindOrCreateAttribute(newObj, "AttributeIOR")); + * aIOR->SetValue(iorStr.c_str()); + * + * //myBuilder->AddAttribute(newObj,SALOMEDS::Name,_mesh_i->getName().c_str()); + * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow( + * myBuilder->FindOrCreateAttribute(newObj, "AttributeName")); + * aName->SetValue(_mesh_i->getName().c_str()); + * + * _meshId = newObj->GetID(); + * myBuilder->CommitCommand(); + * + */ + END_OF("Mesh_i::addInStudy(SALOMEDS::Study_ptr myStudy)"); } //============================================================================= @@ -902,10 +909,10 @@ void SMESH_MEDMesh_i::addInStudy(SALOMEDS::Study_ptr myStudy, */ //============================================================================= void SMESH_MEDMesh_i::write(CORBA::Long i, const char *driverMeshName) -throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { - MESSAGE("Non Implemente"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + MESSAGE("Non Implemente"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); } //============================================================================= @@ -915,8 +922,8 @@ throw(SALOME::SALOME_Exception) //============================================================================= void SMESH_MEDMesh_i::read(CORBA::Long i) throw(SALOME::SALOME_Exception) { - MESSAGE("Non Implemente"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + MESSAGE("Non Implemente"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); } //============================================================================= @@ -926,8 +933,8 @@ void SMESH_MEDMesh_i::read(CORBA::Long i) throw(SALOME::SALOME_Exception) //============================================================================= void SMESH_MEDMesh_i::rmDriver(CORBA::Long i) throw(SALOME::SALOME_Exception) { - MESSAGE("Non Implemente"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + MESSAGE("Non Implemente"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); } //============================================================================= @@ -936,11 +943,11 @@ void SMESH_MEDMesh_i::rmDriver(CORBA::Long i) throw(SALOME::SALOME_Exception) */ //============================================================================= CORBA::Long SMESH_MEDMesh_i::addDriver(SALOME_MED::medDriverTypes driverType, - const char *fileName, const char *meshName) throw(SALOME::SALOME_Exception) + const char *fileName, const char *meshName) throw(SALOME::SALOME_Exception) { - MESSAGE("Non Implemente"); - THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); - return 0; + MESSAGE("Non Implemente"); + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + return 0; } //============================================================================= @@ -950,174 +957,174 @@ CORBA::Long SMESH_MEDMesh_i::addDriver(SALOME_MED::medDriverTypes driverType, //============================================================================= void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) { - if (!_compte) - { - _compte = true; - - _mapNbTypes[SALOME_MED::MED_NODE] = 1; - // On compte les aretes MED_SEG2 ou MED_SEG3 - // On range les elements dans les vecteurs correspondants - - _mapIndToSeqElts[SALOME_MED::MED_SEG2] = _indexElts++; - _mapIndToSeqElts[SALOME_MED::MED_SEG3] = _indexElts++; - _mapIndToVectTypes[SALOME_MED::MED_EDGE] = _indexEnts++; - - int trouveSeg2 = 0; - int trouveSeg3 = 0; - SALOME_MED::medGeometryElement medElement; - - SMDS_EdgeIteratorPtr itEdges=_meshDS->edgesIterator(); - while(itEdges->more()) - { - const SMDS_MeshEdge* elem = itEdges->next(); - int nb_of_nodes = elem->NbNodes(); - - switch (nb_of_nodes) - { - case 2: - { - medElement = SALOME_MED::MED_SEG2; - if (trouveSeg2 == 0) - { - trouveSeg2 = 1; - _TypesId[SALOME_MED::MED_EDGE]. - push_back(SALOME_MED::MED_SEG2); - } - break; - } - case 3: - { - medElement = SALOME_MED::MED_SEG3; - if (trouveSeg3 == 0) - { - trouveSeg3 = 1; - _TypesId[SALOME_MED::MED_EDGE]. - push_back(SALOME_MED::MED_SEG3); - } - break; - } - } - int index = _mapIndToSeqElts[medElement]; - SCRUTE(index); - // Traitement de l arete - - int longueur = _seq_elemId[index]->length(); - _seq_elemId[index]->length(longueur + nb_of_nodes); - - SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); - - for(int k=0; itn->more(); k++) - _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; - } - - _mapNbTypes[SALOME_MED::MED_EDGE] = trouveSeg2 + trouveSeg3; - - // On compte les faces MED_TRIA3, MED_HEXA8, MED_TRIA6 - // On range les elements dans les vecteurs correspondants - int trouveTria3 = 0; - int trouveTria6 = 0; - int trouveQuad4 = 0; - - _mapIndToSeqElts[SALOME_MED::MED_TRIA3] = _indexElts++; - _mapIndToSeqElts[SALOME_MED::MED_TRIA6] = _indexElts++; - _mapIndToSeqElts[SALOME_MED::MED_QUAD4] = _indexElts++; - _mapIndToVectTypes[SALOME_MED::MED_FACE] = _indexEnts++; - - SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator(); - while(itFaces->more()) - { - const SMDS_MeshFace * elem = itFaces->next(); - int nb_of_nodes = elem->NbNodes(); - - switch (nb_of_nodes) - { - case 3: - { - medElement = SALOME_MED::MED_TRIA3; - if (trouveTria3 == 0) - { - trouveTria3 = 1; - _TypesId[SALOME_MED::MED_FACE]. - push_back(SALOME_MED::MED_TRIA3); - } - break; - } - case 4: - { - medElement = SALOME_MED::MED_QUAD4; - if (trouveQuad4 == 0) - { - trouveQuad4 = 1; - _TypesId[SALOME_MED::MED_FACE]. - push_back(SALOME_MED::MED_QUAD4); - } - break; - } - case 6: - { - medElement = SALOME_MED::MED_TRIA6; - if (trouveTria6 == 0) - { - trouveTria6 = 1; - _TypesId[SALOME_MED::MED_FACE]. - push_back(SALOME_MED::MED_TRIA6); - } - break; - } - } - int index = _mapIndToSeqElts[medElement]; - SCRUTE(index); - - // Traitement de la face - // Attention La numérotation des noeuds Med commence a 1 - - int longueur = _seq_elemId[index]->length(); - _seq_elemId[index]->length(longueur + nb_of_nodes); - - SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); - - for(int k=0; itn->more(); k++) - _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; - } //itFaces - - _mapNbTypes[SALOME_MED::MED_FACE] = - trouveTria3 + trouveTria6 + trouveQuad4; - - _mapIndToSeqElts[SALOME_MED::MED_HEXA8] = _indexElts++; - _mapIndToVectTypes[SALOME_MED::MED_CELL] = _indexEnts++; - int index = _mapIndToSeqElts[medElement]; - - int trouveHexa8 = 0; - - SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator(); - while(itVolumes->more()) - { - const SMDS_MeshVolume * elem = itVolumes->next(); - - int nb_of_nodes = elem->NbNodes(); - medElement = SALOME_MED::MED_HEXA8; - ASSERT(nb_of_nodes == 8); - - if (trouveHexa8 == 0) - { - trouveHexa8 = 1; - _TypesId[SALOME_MED::MED_CELL].push_back(SALOME_MED::MED_HEXA8); - }; - // Traitement de la maille - int longueur = _seq_elemId[index]->length(); - _seq_elemId[index]->length(longueur + nb_of_nodes); - - SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); - for(int k=0; itn->more(); k++) - _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; - } - - _mapNbTypes[SALOME_MED::MED_CELL] = trouveHexa8; - _mapNbTypes[SALOME_MED::MED_ALL_ENTITIES] - = - trouveHexa8 + trouveTria3 + trouveTria6 + trouveQuad4 + trouveSeg2 + - trouveSeg3; - }// fin du _compte + if (!_compte) + { + _compte = true; + + _mapNbTypes[SALOME_MED::MED_NODE] = 1; + // On compte les aretes MED_SEG2 ou MED_SEG3 + // On range les elements dans les vecteurs correspondants + + _mapIndToSeqElts[SALOME_MED::MED_SEG2] = _indexElts++; + _mapIndToSeqElts[SALOME_MED::MED_SEG3] = _indexElts++; + _mapIndToVectTypes[SALOME_MED::MED_EDGE] = _indexEnts++; + + int trouveSeg2 = 0; + int trouveSeg3 = 0; + SALOME_MED::medGeometryElement medElement; + + SMDS_EdgeIteratorPtr itEdges=_meshDS->edgesIterator(); + while(itEdges->more()) + { + const SMDS_MeshEdge* elem = itEdges->next(); + int nb_of_nodes = elem->NbNodes(); + + switch (nb_of_nodes) + { + case 2: + { + medElement = SALOME_MED::MED_SEG2; + if (trouveSeg2 == 0) + { + trouveSeg2 = 1; + _TypesId[SALOME_MED::MED_EDGE]. + push_back(SALOME_MED::MED_SEG2); + } + break; + } + case 3: + { + medElement = SALOME_MED::MED_SEG3; + if (trouveSeg3 == 0) + { + trouveSeg3 = 1; + _TypesId[SALOME_MED::MED_EDGE]. + push_back(SALOME_MED::MED_SEG3); + } + break; + } + } + int index = _mapIndToSeqElts[medElement]; + SCRUTE(index); + // Traitement de l arete + + int longueur = _seq_elemId[index]->length(); + _seq_elemId[index]->length(longueur + nb_of_nodes); + + SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); + + for(int k=0; itn->more(); k++) + _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; + } + + _mapNbTypes[SALOME_MED::MED_EDGE] = trouveSeg2 + trouveSeg3; + + // On compte les faces MED_TRIA3, MED_HEXA8, MED_TRIA6 + // On range les elements dans les vecteurs correspondants + int trouveTria3 = 0; + int trouveTria6 = 0; + int trouveQuad4 = 0; + + _mapIndToSeqElts[SALOME_MED::MED_TRIA3] = _indexElts++; + _mapIndToSeqElts[SALOME_MED::MED_TRIA6] = _indexElts++; + _mapIndToSeqElts[SALOME_MED::MED_QUAD4] = _indexElts++; + _mapIndToVectTypes[SALOME_MED::MED_FACE] = _indexEnts++; + + SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator(); + while(itFaces->more()) + { + const SMDS_MeshFace * elem = itFaces->next(); + int nb_of_nodes = elem->NbNodes(); + + switch (nb_of_nodes) + { + case 3: + { + medElement = SALOME_MED::MED_TRIA3; + if (trouveTria3 == 0) + { + trouveTria3 = 1; + _TypesId[SALOME_MED::MED_FACE]. + push_back(SALOME_MED::MED_TRIA3); + } + break; + } + case 4: + { + medElement = SALOME_MED::MED_QUAD4; + if (trouveQuad4 == 0) + { + trouveQuad4 = 1; + _TypesId[SALOME_MED::MED_FACE]. + push_back(SALOME_MED::MED_QUAD4); + } + break; + } + case 6: + { + medElement = SALOME_MED::MED_TRIA6; + if (trouveTria6 == 0) + { + trouveTria6 = 1; + _TypesId[SALOME_MED::MED_FACE]. + push_back(SALOME_MED::MED_TRIA6); + } + break; + } + } + int index = _mapIndToSeqElts[medElement]; + SCRUTE(index); + + // Traitement de la face + // Attention La numérotation des noeuds Med commence a 1 + + int longueur = _seq_elemId[index]->length(); + _seq_elemId[index]->length(longueur + nb_of_nodes); + + SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); + + for(int k=0; itn->more(); k++) + _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; + } //itFaces + + _mapNbTypes[SALOME_MED::MED_FACE] = + trouveTria3 + trouveTria6 + trouveQuad4; + + _mapIndToSeqElts[SALOME_MED::MED_HEXA8] = _indexElts++; + _mapIndToVectTypes[SALOME_MED::MED_CELL] = _indexEnts++; + int index = _mapIndToSeqElts[medElement]; + + int trouveHexa8 = 0; + + SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator(); + while(itVolumes->more()) + { + const SMDS_MeshVolume * elem = itVolumes->next(); + + int nb_of_nodes = elem->NbNodes(); + medElement = SALOME_MED::MED_HEXA8; + ASSERT(nb_of_nodes == 8); + + if (trouveHexa8 == 0) + { + trouveHexa8 = 1; + _TypesId[SALOME_MED::MED_CELL].push_back(SALOME_MED::MED_HEXA8); + }; + // Traitement de la maille + int longueur = _seq_elemId[index]->length(); + _seq_elemId[index]->length(longueur + nb_of_nodes); + + SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator(); + for(int k=0; itn->more(); k++) + _seq_elemId[index][longueur + k] = itn->next()->GetID()+1; + } + + _mapNbTypes[SALOME_MED::MED_CELL] = trouveHexa8; + _mapNbTypes[SALOME_MED::MED_ALL_ENTITIES] + = + trouveHexa8 + trouveTria3 + trouveTria6 + trouveQuad4 + trouveSeg2 + + trouveSeg3; + }// fin du _compte }; //============================================================================= @@ -1128,49 +1135,49 @@ void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception) void SMESH_MEDMesh_i::createFamilies() throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - string famDes = ("Je ne sais pas"); - string famName0 = "Famille_"; - string famName; - char numero[10]; - - if (_creeFamily == false) - { - _creeFamily = true; - //SMESH_subMesh_i *subMeshServant; - - map < int, SMESH_subMesh_i * >::iterator it; - for (it = _mesh_i->_mapSubMesh_i.begin(); - it != _mesh_i->_mapSubMesh_i.end(); it++) - { - SMESH_subMesh_i *submesh_i = (*it).second; - int famIdent = (*it).first; - - ASSERT(famIdent < 999999999); - sprintf(numero, "%d\n", famIdent); - famName = famName0 + numero; - - SMESH_MEDFamily_i *famservant = - new SMESH_MEDFamily_i(famIdent, submesh_i, - famName, famDes, SALOME_MED::MED_NODE); + string famDes = ("Je ne sais pas"); + string famName0 = "Famille_"; + string famName; + char numero[10]; + + if (_creeFamily == false) + { + _creeFamily = true; + //SMESH_subMesh_i *subMeshServant; + + map < int, SMESH_subMesh_i * >::iterator it; + for (it = _mesh_i->_mapSubMesh_i.begin(); + it != _mesh_i->_mapSubMesh_i.end(); it++) + { + SMESH_subMesh_i *submesh_i = (*it).second; + int famIdent = (*it).first; + + ASSERT(famIdent < 999999999); + sprintf(numero, "%d\n", famIdent); + famName = famName0 + numero; + + SMESH_MEDFamily_i *famservant = + new SMESH_MEDFamily_i(famIdent, submesh_i, + famName, famDes, SALOME_MED::MED_NODE); #ifdef WNT SALOME_MED::FAMILY_ptr famille = SALOME_MED::FAMILY::_nil(); POA_SALOME_MED::FAMILY* servantbase = dynamic_cast(famservant); if ( servantbase ) famille = SALOME_MED::FAMILY::_narrow( servantbase->_this() ); #else - SALOME_MED::FAMILY_ptr famille = + SALOME_MED::FAMILY_ptr famille = SALOME_MED::FAMILY::_narrow( famservant->POA_SALOME_MED::FAMILY::_this() ); #endif - _families.push_back(famille); - } - } + _families.push_back(famille); + } + } }; //============================================================================= /*! * Gives informations of the considered mesh. */ //============================================================================= -SALOME_MED::MESH::meshInfos * SMESH_MEDMesh_i::getMeshGlobal() +SALOME_MED::GMESH::meshInfos * SMESH_MEDMesh_i::getMeshGlobal() throw (SALOME::SALOME_Exception) { MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!"); @@ -1179,12 +1186,28 @@ SALOME_MED::MESH::meshInfos * SMESH_MEDMesh_i::getMeshGlobal() return NULL; } + +//================================================================================ +/*! + * \brief Converts this GMESH into MESH + */ +//================================================================================ + +SALOME_MED::MESH_ptr SMESH_MEDMesh_i::convertInMESH() throw (SALOME::SALOME_Exception) +{ + MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!"); + + THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM); + + return NULL; +} + //============================================================================= /*! * Gives informations on coordinates of the considered mesh. */ //============================================================================= -SALOME_MED::MESH::coordinateInfos * SMESH_MEDMesh_i::getCoordGlobal() +SALOME_MED::GMESH::coordinateInfos * SMESH_MEDMesh_i::getCoordGlobal() throw (SALOME::SALOME_Exception) { MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!"); @@ -1216,7 +1239,7 @@ SMESH_MEDMesh_i::getConnectGlobal(SALOME_MED::medEntityMesh entity) //============================================================================= SALOME_MED::medGeometryElement SMESH_MEDMesh_i::getElementType(SALOME_MED::medEntityMesh entity, - CORBA::Long number) + CORBA::Long number) throw (SALOME::SALOME_Exception) { MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!"); diff --git a/src/SMESH_I/SMESH_MEDMesh_i.hxx b/src/SMESH_I/SMESH_MEDMesh_i.hxx index 8e56e0e79..6541939af 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.hxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MEDMesh_i.hxx // Module : SMESH @@ -62,7 +63,7 @@ protected: int _famIdent; std::map < SALOME_MED::medGeometryElement, int >_mapIndToSeqElts; - SALOME_MED::long_array_var _seq_elemId[MED_NBR_GEOMETRIE_MAILLE]; + SALOME_TYPES::ListOfLong_var _seq_elemId[MED_NBR_GEOMETRIE_MAILLE]; std::map < SALOME_MED::medEntityMesh, int >_mapNbTypes; std::map < SALOME_MED::medEntityMesh, int >_mapIndToVectTypes; @@ -81,13 +82,18 @@ public: void setProtocol(SALOME::TypeOfCommunication typ) {} void release() {} SALOME::SenderDouble_ptr getSenderForCoordinates(SALOME_MED::medModeSwitch) {return SALOME::SenderDouble::_nil();} - SALOME::SenderInt_ptr getSenderForConnectivity(SALOME_MED::medModeSwitch, - SALOME_MED::medConnectivity, - SALOME_MED::medEntityMesh, - SALOME_MED::medGeometryElement) + SALOME::SenderInt_ptr getSenderForConnectivity(SALOME_MED::medConnectivity, + SALOME_MED::medEntityMesh, + SALOME_MED::medGeometryElement) + { + return SALOME::SenderInt::_nil(); + } + SALOME::SenderInt_ptr getSenderForConnectivityIndex(SALOME_MED::medConnectivity, + SALOME_MED::medEntityMesh, + SALOME_MED::medGeometryElement) { return SALOME::SenderInt::_nil(); - } + } SALOME::SenderInt_ptr getSenderForPolygonsConnectivity(SALOME_MED::medConnectivity, SALOME_MED::medEntityMesh) {return SALOME::SenderInt::_nil();} SALOME::SenderInt_ptr getSenderForPolygonsConnectivityIndex(SALOME_MED::medConnectivity, SALOME_MED::medEntityMesh) {return SALOME::SenderInt::_nil();} SALOME::SenderInt_ptr getSenderForPolyhedronConnectivity(SALOME_MED::medConnectivity) {return SALOME::SenderInt::_nil();} @@ -103,7 +109,7 @@ public: CORBA::Boolean existConnectivity(SALOME_MED::medConnectivity connectivityType, - SALOME_MED::medEntityMesh entity) + SALOME_MED::medEntityMesh entity) throw (SALOME::SALOME_Exception); char *getCoordinatesSystem() throw(SALOME::SALOME_Exception); @@ -111,13 +117,13 @@ public: CORBA::Double getCoordinate(CORBA::Long Number, CORBA::Long Axis) throw (SALOME::SALOME_Exception); - SALOME_MED::double_array * getCoordinates(SALOME_MED::medModeSwitch typeSwitch) + SALOME_TYPES::ListOfDouble * getCoordinates(SALOME_MED::medModeSwitch typeSwitch) throw(SALOME::SALOME_Exception); - SALOME_MED::string_array * getCoordinatesNames() + SALOME_TYPES::ListOfString * getCoordinatesNames() throw(SALOME::SALOME_Exception); - SALOME_MED::string_array * getCoordinatesUnits() + SALOME_TYPES::ListOfString * getCoordinatesUnits() throw(SALOME::SALOME_Exception); CORBA::Long getNumberOfNodes() throw(SALOME::SALOME_Exception); @@ -127,44 +133,43 @@ public: SALOME_MED::medGeometryElement_array * getTypes(SALOME_MED::medEntityMesh entity) throw(SALOME:: - SALOME_Exception); + SALOME_Exception); SALOME_MED::medGeometryElement getElementType(SALOME_MED::medEntityMesh entity, - CORBA::Long number) + CORBA::Long number) throw (SALOME::SALOME_Exception); CORBA::Long getNumberOfElements(SALOME_MED::medEntityMesh entity, - SALOME_MED::medGeometryElement geomElement) + SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * - getConnectivity(SALOME_MED::medModeSwitch typeSwitch, - SALOME_MED::medConnectivity mode, - SALOME_MED::medEntityMesh entity, - SALOME_MED::medGeometryElement geomElement) + SALOME_TYPES::ListOfLong * + getConnectivity(SALOME_MED::medConnectivity mode, + SALOME_MED::medEntityMesh entity, + SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getConnectivityIndex(SALOME_MED::medConnectivity mode, - SALOME_MED::medEntityMesh entity) + SALOME_MED::medEntityMesh entity) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array* + SALOME_TYPES::ListOfLong* getGlobalNumberingIndex(SALOME_MED::medEntityMesh entity) throw (SALOME::SALOME_Exception); CORBA::Long getElementNumber(SALOME_MED::medConnectivity mode, - SALOME_MED::medEntityMesh entity, - SALOME_MED::medGeometryElement type, - const SALOME_MED::long_array & connectivity) + SALOME_MED::medEntityMesh entity, + SALOME_MED::medGeometryElement type, + const SALOME_TYPES::ListOfLong & connectivity) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getReverseConnectivity(SALOME_MED::medConnectivity mode) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getReverseConnectivityIndex(SALOME_MED::medConnectivity mode) throw(SALOME::SALOME_Exception); @@ -180,14 +185,14 @@ public: throw(SALOME::SALOME_Exception); SALOME_MED::FAMILY_ptr getFamily(SALOME_MED::medEntityMesh entity, - CORBA::Long i) + CORBA::Long i) throw(SALOME::SALOME_Exception); SALOME_MED::Group_array * getGroups(SALOME_MED::medEntityMesh entity) throw(SALOME::SALOME_Exception); SALOME_MED::GROUP_ptr getGroup(SALOME_MED::medEntityMesh entity, - CORBA::Long i) + CORBA::Long i) throw(SALOME::SALOME_Exception); SALOME_MED::SUPPORT_ptr @@ -221,10 +226,10 @@ public: // Others void addInStudy(SALOMEDS::Study_ptr myStudy, - SALOME_MED::MESH_ptr myIor) + SALOME_MED::GMESH_ptr myIor) throw(SALOME::SALOME_Exception); CORBA::Long addDriver(SALOME_MED::medDriverTypes driverType, - const char *fileName, const char *meshName) + const char *fileName, const char *meshName) throw(SALOME::SALOME_Exception); void rmDriver(CORBA::Long i) throw(SALOME::SALOME_Exception); void read(CORBA::Long i) throw(SALOME::SALOME_Exception); @@ -235,12 +240,14 @@ public: CORBA::Long getCorbaIndex() throw(SALOME::SALOME_Exception); - SALOME_MED::MESH::meshInfos * getMeshGlobal() + SALOME_MED::GMESH::meshInfos * getMeshGlobal() throw (SALOME::SALOME_Exception); - bool areEquals(SALOME_MED::MESH_ptr other) { return false;}; + bool areEquals(SALOME_MED::GMESH_ptr other) { return false;}; + + SALOME_MED::MESH_ptr convertInMESH() throw (SALOME::SALOME_Exception); - SALOME_MED::MESH::coordinateInfos * getCoordGlobal() + SALOME_MED::GMESH::coordinateInfos * getCoordGlobal() throw (SALOME::SALOME_Exception); SALOME_MED::MESH::connectivityInfos * diff --git a/src/SMESH_I/SMESH_MEDSupport_i.cxx b/src/SMESH_I/SMESH_MEDSupport_i.cxx index 56f3b73eb..23dd94144 100644 --- a/src/SMESH_I/SMESH_MEDSupport_i.cxx +++ b/src/SMESH_I/SMESH_MEDSupport_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MEDSupport_i.cxx // Module : SMESH @@ -28,12 +29,14 @@ #include "Utils_CorbaException.hxx" #include "Utils_ExceptHandlers.hxx" -#include #include "SMESHDS_Mesh.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_Mesh_i.hxx" #include "SMESH_subMesh_i.hxx" +#include "SMESH_Gen_i.hxx" + +#include using namespace std; @@ -45,8 +48,8 @@ using namespace std; //============================================================================= SMESH_MEDSupport_i::SMESH_MEDSupport_i() { - BEGIN_OF("Default Constructor SMESH_MEDSupport_i"); - END_OF("Default Constructor SMESH_MEDSupport_i"); + BEGIN_OF("Default Constructor SMESH_MEDSupport_i"); + END_OF("Default Constructor SMESH_MEDSupport_i"); } //============================================================================= @@ -55,40 +58,34 @@ SMESH_MEDSupport_i::SMESH_MEDSupport_i() */ //============================================================================= SMESH_MEDSupport_i::SMESH_MEDSupport_i(SMESH_subMesh_i * sm, string name, - string description, SALOME_MED::medEntityMesh entity) - :_subMesh_i(sm), _name(name), _description(description), _entity(entity), - _seqNumber(false), _seqLength(0) + string description, SALOME_MED::medEntityMesh entity) + :_subMesh_i(sm), _name(name), _description(description), _entity(entity), + _seqNumber(false), _seqLength(0) { - BEGIN_OF("Constructor SMESH_MEDSupport_i"); - - _meshDS = _subMesh_i->_mesh_i->GetImpl().GetMeshDS(); - - int subMeshId = _subMesh_i->GetId(); - - MESSAGE(" subMeshId " << subMeshId) - - if (_subMesh_i->_mesh_i->_mapSubMesh.find(subMeshId) != - _subMesh_i->_mesh_i->_mapSubMesh.end()) - { - ::SMESH_subMesh * subMesh = _subMesh_i->_mesh_i->_mapSubMesh[subMeshId]; - _subMeshDS = subMesh->GetSubMeshDS(); - } - - if (_entity == SALOME_MED::MED_NODE) - { - _numberOfGeometricType = 1; - _geometricType = new SALOME_MED::medGeometryElement[1]; - _geometricType[0] = SALOME_MED::MED_NONE; - } - else - { - MESSAGE("Pas implemente dans cette version"); - THROW_SALOME_CORBA_EXCEPTION - ("Seules les familles de noeuds sont implementees ", - SALOME::BAD_PARAM); - } - - END_OF("Constructor SMESH_MEDSupport_i"); + BEGIN_OF("Constructor SMESH_MEDSupport_i"); + + int subMeshId = sm->GetId(); + + MESSAGE(" subMeshId " << subMeshId); + + SMESH_Mesh_i* mesh_i = SMESH::DownCast( sm->GetMesh() ); + _subMesh = mesh_i->GetImpl().GetSubMeshContaining( subMeshId ); + + if (_entity == SALOME_MED::MED_NODE) + { + _numberOfGeometricType = 1; + _geometricType = new SALOME_MED::medGeometryElement[1]; + _geometricType[0] = SALOME_MED::MED_NONE; + } + else + { + MESSAGE("Pas implemente dans cette version"); + THROW_SALOME_CORBA_EXCEPTION + ("Seules les familles de noeuds sont implementees ", + SALOME::BAD_PARAM); + } + + END_OF("Constructor SMESH_MEDSupport_i"); } //============================================================================= @@ -97,23 +94,13 @@ SMESH_MEDSupport_i::SMESH_MEDSupport_i(SMESH_subMesh_i * sm, string name, */ //============================================================================= SMESH_MEDSupport_i:: -SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s):_subMesh_i(s._subMesh_i), +SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s):_subMesh(s._subMesh), _name(s._name), _description(s._description), _entity(s._entity), _seqNumber(false), _seqLength(0) { - BEGIN_OF("Constructor SMESH_MEDSupport_i"); - - _meshDS = _subMesh_i->_mesh_i->GetImpl().GetMeshDS(); - - int subMeshId = _subMesh_i->GetId(); - if (_subMesh_i->_mesh_i->_mapSubMesh.find(subMeshId) != - _subMesh_i->_mesh_i->_mapSubMesh.end()) - { - ::SMESH_subMesh * subMesh = _subMesh_i->_mesh_i->_mapSubMesh[subMeshId]; - _subMeshDS = subMesh->GetSubMeshDS(); - } + BEGIN_OF("Constructor SMESH_MEDSupport_i"); - END_OF("Constructor SMESH_MEDSupport_i"); + END_OF("Constructor SMESH_MEDSupport_i"); } //============================================================================= @@ -134,11 +121,11 @@ SMESH_MEDSupport_i::~SMESH_MEDSupport_i() CORBA::Long SMESH_MEDSupport_i::getCorbaIndex()throw(SALOME::SALOME_Exception) { - if (_subMeshDS == NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); - MESSAGE("Not implemented for SMESH_i"); - THROW_SALOME_CORBA_EXCEPTION("Not Implemented ", SALOME::BAD_PARAM); + if (_subMesh == NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); + MESSAGE("Not implemented for SMESH_i"); + THROW_SALOME_CORBA_EXCEPTION("Not Implemented ", SALOME::BAD_PARAM); } @@ -150,10 +137,10 @@ CORBA::Long SMESH_MEDSupport_i::getCorbaIndex()throw(SALOME::SALOME_Exception) char *SMESH_MEDSupport_i::getName() throw(SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); - return CORBA::string_dup(_name.c_str()); + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); + return CORBA::string_dup(_name.c_str()); } @@ -165,10 +152,10 @@ char *SMESH_MEDSupport_i::getName() throw(SALOME::SALOME_Exception) char *SMESH_MEDSupport_i::getDescription() throw(SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); - return CORBA::string_dup(_description.c_str()); + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); + return CORBA::string_dup(_description.c_str()); } //============================================================================= @@ -177,14 +164,14 @@ char *SMESH_MEDSupport_i::getDescription() throw(SALOME::SALOME_Exception) */ //============================================================================= -SALOME_MED::MESH_ptr SMESH_MEDSupport_i::getMesh()throw(SALOME:: - SALOME_Exception) +SALOME_MED::GMESH_ptr SMESH_MEDSupport_i::getMesh()throw(SALOME:: + SALOME_Exception) { - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); - return _subMesh_i->_mesh_i->GetMEDMesh(); + return _subMesh_i->GetMesh()->GetMEDMesh(); } //============================================================================= @@ -194,36 +181,36 @@ SALOME_MED::MESH_ptr SMESH_MEDSupport_i::getMesh()throw(SALOME:: //============================================================================= CORBA::Boolean SMESH_MEDSupport_i::isOnAllElements()throw(SALOME:: - SALOME_Exception) + SALOME_Exception) { - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); - if (_seqNumber == false) - { - if (_entity != SALOME_MED::MED_NONE) - { - _seqLength = _subMeshDS->NbNodes(); - _seqNumber = true; - } - else - { - MESSAGE("Only Node Families are implemented "); - THROW_SALOME_CORBA_EXCEPTION("Not implemented Yet ", - SALOME::BAD_PARAM); - } - } - try - { - _isOnAllElements = (_seqLength == _meshDS->NbNodes()); - } - catch(...) - { - MESSAGE("unable to acces related Mesh"); - THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", - SALOME::INTERNAL_ERROR); - }; - return _isOnAllElements; + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); + if (_seqNumber == false) + { + if (_entity != SALOME_MED::MED_NONE) + { + _seqLength = _subMesh_i->GetNumberOfNodes(/*all=*/false); + _seqNumber = true; + } + else + { + MESSAGE("Only Node Families are implemented "); + THROW_SALOME_CORBA_EXCEPTION("Not implemented Yet ", + SALOME::BAD_PARAM); + } + } + try + { + _isOnAllElements = (_seqLength == _subMesh->GetFather()->NbNodes()); + } + catch(...) + { + MESSAGE("unable to acces related Mesh"); + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", + SALOME::INTERNAL_ERROR); + }; + return _isOnAllElements; } //============================================================================= @@ -233,12 +220,12 @@ CORBA::Boolean SMESH_MEDSupport_i::isOnAllElements()throw(SALOME:: //============================================================================= SALOME_MED::medEntityMesh SMESH_MEDSupport_i::getEntity()throw(SALOME:: - SALOME_Exception) + SALOME_Exception) { - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); - return _entity; + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); + return _entity; } //============================================================================= @@ -248,29 +235,29 @@ SALOME_MED::medEntityMesh SMESH_MEDSupport_i::getEntity()throw(SALOME:: //============================================================================= SALOME_MED::medGeometryElement_array * - SMESH_MEDSupport_i::getTypes()throw(SALOME::SALOME_Exception) + SMESH_MEDSupport_i::getTypes()throw(SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); - SALOME_MED::medGeometryElement_array_var myseq = - new SALOME_MED::medGeometryElement_array; - try - { - int mySeqLength = _numberOfGeometricType; - myseq->length(mySeqLength); - for (int i = 0; i < mySeqLength; i++) - { - myseq[i] = _geometricType[i]; - } - } - catch(...) - { - MESSAGE("Exception lors de la recherche des differents types"); - THROW_SALOME_CORBA_EXCEPTION("Unable to acces Support Types", - SALOME::INTERNAL_ERROR); - } - return myseq._retn(); + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); + SALOME_MED::medGeometryElement_array_var myseq = + new SALOME_MED::medGeometryElement_array; + try + { + int mySeqLength = _numberOfGeometricType; + myseq->length(mySeqLength); + for (int i = 0; i < mySeqLength; i++) + { + myseq[i] = _geometricType[i]; + } + } + catch(...) + { + MESSAGE("Exception lors de la recherche des differents types"); + THROW_SALOME_CORBA_EXCEPTION("Unable to acces Support Types", + SALOME::INTERNAL_ERROR); + } + return myseq._retn(); } //============================================================================= @@ -280,12 +267,12 @@ SALOME_MED::medGeometryElement_array * */ //============================================================================= CORBA::Long SMESH_MEDSupport_i::getNumberOfElements(SALOME_MED:: - medGeometryElement geomElement) throw(SALOME::SALOME_Exception) + medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); - return _numberOfGeometricType; + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); + return _numberOfGeometricType; } @@ -295,33 +282,36 @@ CORBA::Long SMESH_MEDSupport_i::getNumberOfElements(SALOME_MED:: */ //============================================================================= -SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber( - SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfLong * SMESH_MEDSupport_i::getNumber( + SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - if (_subMeshDS==NULL) - THROW_SALOME_CORBA_EXCEPTION("No associated Support", - SALOME::INTERNAL_ERROR); + if (_subMesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Support", + SALOME::INTERNAL_ERROR); - // A changer s'il ne s agit plus seulement de famille de noeuds - if (geomElement != SALOME_MED::MED_NONE) - THROW_SALOME_CORBA_EXCEPTION("Not implemented", SALOME::BAD_PARAM); + // A changer s'il ne s agit plus seulement de famille de noeuds + if (geomElement != SALOME_MED::MED_NONE) + THROW_SALOME_CORBA_EXCEPTION("Not implemented", SALOME::BAD_PARAM); - SALOME_MED::long_array_var myseq = new SALOME_MED::long_array; + SALOME_TYPES::ListOfLong_var myseq = new SALOME_TYPES::ListOfLong; - int i = 0; - myseq->length(_subMeshDS->NbNodes()); + int i = 0; + myseq->length(_subMesh_i->GetNumberOfNodes(/*all=*/false)); - SMDS_NodeIteratorPtr it = _subMeshDS->GetNodes(); - while(it->more()) - { - myseq[i] = it->next()->GetID(); - i++; - }; + if ( _subMesh->GetSubMeshDS() ) + { + SMDS_NodeIteratorPtr it = _subMesh->GetSubMeshDS()->GetNodes(); + while(it->more()) + { + myseq[i] = it->next()->GetID(); + i++; + }; + } - SCRUTE(myseq->length()); - MESSAGE("End of SMESH_MEDSupport_i::getNumber"); - return myseq._retn(); + SCRUTE(myseq->length()); + MESSAGE("End of SMESH_MEDSupport_i::getNumber"); + return myseq._retn(); } @@ -331,8 +321,8 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber( */ //============================================================================= -SALOME_MED::long_array * SMESH_MEDSupport_i::getNumberFromFile( - SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfLong * SMESH_MEDSupport_i::getNumberFromFile( + SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { return getNumber(geomElement); } @@ -344,12 +334,12 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumberFromFile( */ //============================================================================= -SALOME_MED::long_array * - SMESH_MEDSupport_i::getNumberIndex()throw(SALOME::SALOME_Exception) +SALOME_TYPES::ListOfLong * + SMESH_MEDSupport_i::getNumberIndex()throw(SALOME::SALOME_Exception) { - MESSAGE("Not implemented for SMESH_i"); - THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM); - return NULL; + MESSAGE("Not implemented for SMESH_i"); + THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM); + return NULL; } //============================================================================= /*! @@ -358,10 +348,10 @@ SALOME_MED::long_array * //============================================================================= CORBA::Long SMESH_MEDSupport_i::getNumberOfGaussPoint(SALOME_MED:: - medGeometryElement geomElement) throw(SALOME::SALOME_Exception) + medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { - MESSAGE("Not implemented for SMESH_i"); - return 0; + MESSAGE("Not implemented for SMESH_i"); + return 0; } //============================================================================= /*! @@ -381,7 +371,7 @@ CORBA::Long SMESH_MEDSupport_i::getNumberOfTypes() * included in the support */ //============================================================================= -SALOME_MED::long_array* SMESH_MEDSupport_i::getNumbersOfGaussPoint() +SALOME_TYPES::ListOfLong* SMESH_MEDSupport_i::getNumbersOfGaussPoint() throw (SALOME::SALOME_Exception) { MESSAGE("!!! NOT YET IMPLEMENTED !!!!"); diff --git a/src/SMESH_I/SMESH_MEDSupport_i.hxx b/src/SMESH_I/SMESH_MEDSupport_i.hxx index 15cf3b8f4..67761e2e8 100644 --- a/src/SMESH_I/SMESH_MEDSupport_i.hxx +++ b/src/SMESH_I/SMESH_MEDSupport_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MEDSupport_i.hxx // Module : SMESH @@ -39,81 +40,81 @@ #include "SMESH_MEDSupport_i.hxx" #include "SALOME_GenericObj_i.hh" +class SMESH_subMesh; class SMESH_subMesh_i; class SMESH_I_EXPORT SMESH_MEDSupport_i: - public virtual POA_SALOME_MED::SUPPORT, public virtual SALOME::GenericObj_i + public virtual POA_SALOME_MED::SUPPORT, public virtual SALOME::GenericObj_i { public: // Constructors and associated internal methods - SMESH_MEDSupport_i(SMESH_subMesh_i * sm, - std::string name, std::string description, SALOME_MED::medEntityMesh entity); - SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s); + SMESH_MEDSupport_i(SMESH_subMesh_i * sm, + std::string name, std::string description, SALOME_MED::medEntityMesh entity); + SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s); // IDL Methods - char *getName() throw(SALOME::SALOME_Exception); - char *getDescription() throw(SALOME::SALOME_Exception); - SALOME_MED::MESH_ptr getMesh() throw(SALOME::SALOME_Exception); - CORBA::Boolean isOnAllElements() throw(SALOME::SALOME_Exception); - SALOME_MED::medEntityMesh getEntity() throw(SALOME::SALOME_Exception); + char *getName() throw(SALOME::SALOME_Exception); + char *getDescription() throw(SALOME::SALOME_Exception); + SALOME_MED::GMESH_ptr getMesh() throw(SALOME::SALOME_Exception); + CORBA::Boolean isOnAllElements() throw(SALOME::SALOME_Exception); + SALOME_MED::medEntityMesh getEntity() throw(SALOME::SALOME_Exception); CORBA::Long - getNumberOfElements(SALOME_MED::medGeometryElement geomElement) - throw(SALOME::SALOME_Exception); + getNumberOfElements(SALOME_MED::medGeometryElement geomElement) + throw(SALOME::SALOME_Exception); CORBA::Long getNumberOfTypes() throw (SALOME::SALOME_Exception); - SALOME_MED::long_array * - getNumber(SALOME_MED::medGeometryElement geomElement) - throw(SALOME::SALOME_Exception); + SALOME_TYPES::ListOfLong * + getNumber(SALOME_MED::medGeometryElement geomElement) + throw(SALOME::SALOME_Exception); /*! * Same function as getNumber. */ - SALOME_MED::long_array * - getNumberFromFile(SALOME_MED::medGeometryElement geomElement) - throw(SALOME::SALOME_Exception); + SALOME_TYPES::ListOfLong * + getNumberFromFile(SALOME_MED::medGeometryElement geomElement) + throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * getNumberIndex() - throw(SALOME::SALOME_Exception); + SALOME_TYPES::ListOfLong * getNumberIndex() + throw(SALOME::SALOME_Exception); CORBA::Long - getNumberOfGaussPoint(SALOME_MED::medGeometryElement geomElement) - throw(SALOME::SALOME_Exception); + getNumberOfGaussPoint(SALOME_MED::medGeometryElement geomElement) + throw(SALOME::SALOME_Exception); - SALOME_MED::long_array* getNumbersOfGaussPoint() - throw (SALOME::SALOME_Exception); + SALOME_TYPES::ListOfLong* getNumbersOfGaussPoint() + throw (SALOME::SALOME_Exception); - SALOME_MED::medGeometryElement_array *getTypes() - throw(SALOME::SALOME_Exception); + SALOME_MED::medGeometryElement_array *getTypes() + throw(SALOME::SALOME_Exception); void getBoundaryElements() throw (SALOME::SALOME_Exception); - CORBA::Long getCorbaIndex() throw(SALOME::SALOME_Exception); + CORBA::Long getCorbaIndex() throw(SALOME::SALOME_Exception); SALOME_MED::SUPPORT::supportInfos * getSupportGlobal() - throw (SALOME::SALOME_Exception); + throw (SALOME::SALOME_Exception); - void createSeq() throw(SALOME::SALOME_Exception); + void createSeq() throw(SALOME::SALOME_Exception); public: //public field - const SMESHDS_SubMesh * _subMeshDS; - ::SMESH_subMesh_i * _subMesh_i; + SMESH_subMesh_i * _subMesh_i; + ::SMESH_subMesh * _subMesh; - SMESHDS_Mesh * _meshDS; - std::string _name; + std::string _name; std::string _description; - bool _isOnAllElements; - bool _seqNumber; - int _seqLength; + bool _isOnAllElements; + bool _seqNumber; + int _seqLength; - SALOME_MED::medEntityMesh _entity; - SALOME_MED::medGeometryElement * _geometricType; - int _numberOfGeometricType; + SALOME_MED::medEntityMesh _entity; + SALOME_MED::medGeometryElement * _geometricType; + int _numberOfGeometricType; protected: - SMESH_MEDSupport_i(); - ~SMESH_MEDSupport_i(); + SMESH_MEDSupport_i(); + ~SMESH_MEDSupport_i(); }; #endif /* _MED_MEDSUPPORT_I_HXX_ */ diff --git a/src/SMESH_I/SMESH_Measurements_i.cxx b/src/SMESH_I/SMESH_Measurements_i.cxx new file mode 100644 index 000000000..48572a353 --- /dev/null +++ b/src/SMESH_I/SMESH_Measurements_i.cxx @@ -0,0 +1,259 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_Measurements_i.cxx +// Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com) + +#include "SMESH_Measurements_i.hxx" + +#include "SMESH_Gen_i.hxx" +#include "SMESH_PythonDump.hxx" + +#include "SMDS_Mesh.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_ElemIterator.hxx" + +#include "SMESHDS_Mesh.hxx" + + +using namespace SMESH; + +/** + * this local function to avoid uninitialized fields + */ +static void initMeasure( SMESH::Measure& theMeasure) +{ + + theMeasure.minX = theMeasure.minY = theMeasure.minZ = 0.; + theMeasure.maxX = theMeasure.maxY = theMeasure.maxZ = 0.; + theMeasure.node1 = theMeasure.node2 = -1; + theMeasure.elem1 = theMeasure.elem2 = -1; + theMeasure.value = 0.; +} + +//============================================================================= +/*! + * SMESH_Gen_i::CreateMeasurements + * + * Create measurement instance + */ +//============================================================================= + +SMESH::Measurements_ptr SMESH_Gen_i::CreateMeasurements() +{ + SMESH::Measurements_i* aMeasure = new SMESH::Measurements_i(); + SMESH::Measurements_var anObj = aMeasure->_this(); + return anObj._retn(); +} + + +/* + Class : Measurements + Description : make measure of mesh qunatities +*/ + +//======================================================================= +// name : Measurements_i +// Purpose : Constructor +//======================================================================= +Measurements_i::Measurements_i() +: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) +{ + //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method + //PortableServer::ObjectId_var anObjectId = + // SMESH_Gen_i::GetPOA()->activate_object( this ); +} + +//======================================================================= +// name : ~Measurements_i +// Purpose : Destructor +//======================================================================= +Measurements_i::~Measurements_i() +{ + //TPythonDump()<X(); if (theNode2) dd -= theNode2->X(); theMeasure.minX = dd; dd *= dd; dist += dd; + dd = theNode1->Y(); if (theNode2) dd -= theNode2->Y(); theMeasure.minY = dd; dd *= dd; dist += dd; + dd = theNode1->Z(); if (theNode2) dd -= theNode2->Z(); theMeasure.minZ = dd; dd *= dd; dist += dd; + + if (dist < 0) + return false; + + theMeasure.value = sqrt(dist); + theMeasure.node1 = theNode1->GetID(); + theMeasure.node2 = theNode2 ? theNode2->GetID() : 0; + + return true; +} + +static SMESHDS_Mesh* getMesh(SMESH::SMESH_IDSource_ptr theSource) +{ + if (!CORBA::is_nil( theSource )) + { + SMESH_Mesh_i* anImplPtr = DownCast(theSource->GetMesh()); + if (anImplPtr) + return anImplPtr->GetImpl().GetMeshDS(); + } + return 0; +} + +static bool isNodeType (SMESH::array_of_ElementType_var theTypes) +{ + return theTypes->length() > 0 && theTypes[0] == SMESH::NODE; +} + +//======================================================================= +// name : MinDistance +// Purpose : minimal distance between two given entities +//======================================================================= +SMESH::Measure Measurements_i::MinDistance + (SMESH::SMESH_IDSource_ptr theSource1, + SMESH::SMESH_IDSource_ptr theSource2) +{ + SMESH::Measure aMeasure; + initMeasure(aMeasure); + + if (CORBA::is_nil( theSource1 )) + return aMeasure; + + // if second source is null, min distance from theSource1 to the origin is calculated + bool isOrigin = CORBA::is_nil( theSource2 ); + + // calculate minimal distance between two mesh entities + SMESH::array_of_ElementType_var types1 = theSource1->GetTypes(); + SMESH::array_of_ElementType_var types2; + if ( !isOrigin ) types2 = theSource2->GetTypes(); + + // here we assume that type of all IDs defined by first type in array + bool isNode1 = isNodeType(types1); + bool isNode2 = isOrigin || isNodeType(types2); + + SMESH::long_array_var aElementsId1 = theSource1->GetIDs(); + SMESH::long_array_var aElementsId2; + if ( !isOrigin ) aElementsId2 = theSource2->GetIDs(); + + // compute distance between two entities + /* NOTE: currently only node-to-node case is implemented + * all other cases will be implemented later + * below IF should be replaced by complete switch + * on mesh entities types + */ + if (isNode1 && isNode2) + { + // node - node + const SMESHDS_Mesh* aMesh1 = getMesh( theSource1 ); + const SMESHDS_Mesh* aMesh2 = isOrigin ? 0 : getMesh( theSource2 ); + const SMDS_MeshNode* theNode1 = aMesh1 ? aMesh1->FindNode( aElementsId1[0] ) : 0; + const SMDS_MeshNode* theNode2 = aMesh2 ? aMesh2->FindNode( aElementsId2[0] ) : 0; + getNodeNodeDistance( aMeasure, theNode1, theNode2 ); + } + else + { + // NOT_IMPLEMENTED + } + + return aMeasure; +} + +//======================================================================= +// name : enlargeBoundingBox +// Purpose : +//======================================================================= +static void enlargeBoundingBox(const SMDS_MeshNode* theNode, + SMESH::Measure& theMeasure) +{ + if (!theNode) + return; + if ( theMeasure.node1 == -1 ) { + // we use this attribute as a flag that it is the first node added to the bnd box + theMeasure.minX = theMeasure.maxX = theNode->X(); + theMeasure.minY = theMeasure.maxY = theNode->Y(); + theMeasure.minZ = theMeasure.maxZ = theNode->Z(); + theMeasure.node1 = theNode->GetID(); + } + else { + theMeasure.minX = min( theMeasure.minX, theNode->X() ); + theMeasure.maxX = max( theMeasure.maxX, theNode->X() ); + theMeasure.minY = min( theMeasure.minY, theNode->Y() ); + theMeasure.maxY = max( theMeasure.maxY, theNode->Y() ); + theMeasure.minZ = min( theMeasure.minZ, theNode->Z() ); + theMeasure.maxZ = max( theMeasure.maxZ, theNode->Z() ); + } +} + +//======================================================================= +// name : enlargeBoundingBox +// Purpose : +//======================================================================= +static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject, + SMESH::Measure& theMeasure) +{ + if ( CORBA::is_nil( theObject ) ) + return; + const SMESHDS_Mesh* aMesh = getMesh( theObject ); + if ( !aMesh ) + return; + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + SMESH::long_array_var aElementsId = theObject->GetIDs(); + // here we assume that type of all IDs defined by first type in array + const bool isNode = isNodeType( types ); + for(int i = 0, n = aElementsId->length(); i < n; i++) + { + if (isNode) + enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure); + else + { + const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] ); + if (!elem) + continue; + SMDS_ElemIteratorPtr aNodeIter = elem->nodesIterator(); + while( aNodeIter->more() ) + enlargeBoundingBox( dynamic_cast( aNodeIter->next() ), theMeasure); + } + } +} + +//======================================================================= +// name : BoundingBox +// Purpose : compute common bounding box of entities +//======================================================================= +SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources) +{ + SMESH::Measure aMeasure; + initMeasure(aMeasure); + + // calculate bounding box on sources + for ( int i = 0, n = theSources.length(); i < n ; ++i ) + enlargeBoundingBox( theSources[i], aMeasure ); + + return aMeasure; +} diff --git a/src/SMESH_I/SMESH_Measurements_i.hxx b/src/SMESH_I/SMESH_Measurements_i.hxx new file mode 100644 index 000000000..df380ab3e --- /dev/null +++ b/src/SMESH_I/SMESH_Measurements_i.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_Measurements_i.hxx +// Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com) + +#ifndef _SMESH_MEASUREMENTS_I_HXX_ +#define _SMESH_MEASUREMENTS_I_HXX_ + +#include "SMESH.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_Measurements) + +#include "SALOME_GenericObj_i.hh" + +class SMESHDS_Mesh; + +namespace SMESH +{ + + /* + Measurements + */ + class SMESH_I_EXPORT Measurements_i: public virtual POA_SMESH::Measurements, + public virtual SALOME::GenericObj_i + { + public: + Measurements_i(); + ~Measurements_i(); + + /*! + * minimal distance between two given entities + */ + SMESH::Measure MinDistance(SMESH::SMESH_IDSource_ptr theSource1, + SMESH::SMESH_IDSource_ptr theSource2); + + /*! + * common bounding box of entities + */ + SMESH::Measure BoundingBox(const SMESH::ListOfIDSources& theSources); + }; +} + +#endif diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 8fb61b896..026eed079 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1,40 +1,48 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MeshEditor_i.cxx // Author : Nicolas REJNERI // Module : SMESH +#ifdef WNT +#define NOMINMAX +#endif + #include "SMESH_MeshEditor_i.hxx" -#include "SMDS_MeshEdge.hxx" +#include "SMDS_LinearEdge.hxx" +#include "SMDS_Mesh0DElement.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 "SMDS_SetIterator.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESH_ControlsDef.hxx" #include "SMESH_Filter_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Group_i.hxx" #include "SMESH_PythonDump.hxx" +#include "SMESH_subMeshEventListener.hxx" +#include "SMESH_subMesh_i.hxx" #include "utilities.h" #include "Utils_ExceptHandlers.hxx" @@ -61,11 +69,13 @@ #endif #include +#include #define cast2Node(elem) static_cast( elem ) using namespace std; using SMESH::TPythonDump; +using SMESH::TVar; namespace { @@ -80,12 +90,12 @@ namespace { SMDSAbs_ElementType myPreviewType; // type to show //!< Constructor TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) { - _isShapeToMesh = _id =_studyId =_idDoc = 0; + _isShapeToMesh = (_id =_studyId =_idDoc = 0); _myMeshDS = new SMESHDS_Mesh( _id, true ); myPreviewType = previewElements; } //!< Destructor - virtual ~TPreviewMesh() { delete _myMeshDS; } + virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; } //!< Copy a set of elements void Copy(const TIDSortedElemSet & theElements, TIDSortedElemSet& theCopyElements, @@ -102,8 +112,12 @@ namespace { if ( type == theAvoidType || ( theSelectType != SMDSAbs_All && type != theSelectType )) continue; - - if ( const SMDS_MeshElement* anElemCopy = Copy( anElem )) + const SMDS_MeshElement* anElemCopy; + if ( type == SMDSAbs_Node) + anElemCopy = Copy( cast2Node(anElem) ); + else + anElemCopy = Copy( anElem ); + if ( anElemCopy ) theCopyElements.insert( theCopyElements.end(), anElemCopy ); } } @@ -125,11 +139,11 @@ namespace { SMDS_MeshElement* anElemCopy = 0; if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume ) { - const SMDS_PolyhedralVolumeOfNodes* ph = - dynamic_cast (anElem); + const SMDS_VtkVolume* ph = + dynamic_cast (anElem); if ( ph ) anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID - (anElemNodesID, ph->GetQuanities(),anElem->GetID()); + (anElemNodesID, ph->GetQuantities(),anElem->GetID()); } else { anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID, @@ -141,29 +155,33 @@ namespace { //!< Copy a node SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode ) { - return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), + return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), anElemNode->GetID()); } };// struct TPreviewMesh - static SMESH_NodeSearcher * myNodeSearcher = 0; + static SMESH_NodeSearcher * theNodeSearcher = 0; + static SMESH_ElementSearcher * theElementSearcher = 0; //============================================================================= /*! - * \brief Deleter of myNodeSearcher at any compute event occured + * \brief Deleter of theNodeSearcher at any compute event occured */ //============================================================================= - struct TNodeSearcherDeleter : public SMESH_subMeshEventListener + struct TSearchersDeleter : public SMESH_subMeshEventListener { SMESH_Mesh* myMesh; + string myMeshPartIOR; //!< Constructor - TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh - myMesh(0) {} - //!< Delete myNodeSearcher + TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh + "SMESH_MeshEditor_i::TSearchersDeleter"), + myMesh(0) {} + //!< Delete theNodeSearcher static void Delete() { - if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 0; } + if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0; + if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0; } typedef map < int, SMESH_subMesh * > TDependsOnMap; //!< The meshod called by submesh: do my main job @@ -175,19 +193,23 @@ namespace { Unset( sm->GetFather() ); } } - //!< set self on all submeshes and delete myNodeSearcher if other mesh is set - void Set(SMESH_Mesh* mesh) + //!< set self on all submeshes and delete theNodeSearcher if other mesh is set + void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string()) { - 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 ); + if ( myMesh != mesh || myMeshPartIOR != meshPartIOR) + { + if ( myMesh ) { + Delete(); + Unset( myMesh ); + } + myMesh = mesh; + myMeshPartIOR = meshPartIOR; + 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 @@ -199,8 +221,10 @@ namespace { for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++) sm->second->DeleteEventListener( this ); } + myMesh = 0; } - }; + + } theSearchersDeleter; TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType ) { @@ -217,6 +241,162 @@ namespace { } return typeStr; } + //================================================================================ + /*! + * \brief function for conversion of long_array to TIDSortedElemSet + * \param IDs - array of IDs + * \param aMesh - mesh + * \param aMap - collection to fill + * \param aType - element type + */ + //================================================================================ + + void arrayToSet(const SMESH::long_array & IDs, + const SMESHDS_Mesh* aMesh, + TIDSortedElemSet& aMap, + const SMDSAbs_ElementType aType = SMDSAbs_All ) + { + for (int i=0; iFindNode(ind) : aMesh->FindElement(ind)); + if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType )) + aMap.insert( elem ); + } + } + //================================================================================ + /*! + * \brief Retrieve elements of given type from SMESH_IDSource + */ + //================================================================================ + + bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource, + const SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElemSet, + const SMDSAbs_ElementType theType, + const bool emptyIfIsMesh=false) + + { + if ( CORBA::is_nil( theIDSource ) ) + return false; + if ( emptyIfIsMesh && SMESH::DownCast( theIDSource )) + return true; + + SMESH::long_array_var anIDs = theIDSource->GetIDs(); + if ( anIDs->length() == 0 ) + return false; + SMESH::array_of_ElementType_var types = theIDSource->GetTypes(); + if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes + { + if ( theType == SMDSAbs_All || theType == SMDSAbs_Node ) + arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node ); + else + return false; + } + else + { + arrayToSet( anIDs, theMeshDS, theElemSet, theType); + return bool(anIDs->length()) == bool(theElemSet.size()); + } + return true; + } + //================================================================================ + /*! + * \brief Retrieve nodes from SMESH_IDSource + */ + //================================================================================ + + void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject, + const SMESHDS_Mesh* theMeshDS, + TIDSortedNodeSet& theNodeSet) + + { + if ( CORBA::is_nil( theObject ) ) + return; + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + SMESH::long_array_var aElementsId = theObject->GetIDs(); + if ( types->length() == 1 && types[0] == SMESH::NODE) + { + for(int i = 0; i < aElementsId->length(); i++) + if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] )) + theNodeSet.insert( theNodeSet.end(), n); + } + else if ( SMESH::DownCast( theObject )) + { + SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator(); + while ( nIt->more( )) + if( const SMDS_MeshElement * elem = nIt->next() ) + theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); + } + else + { + for(int i = 0; i < aElementsId->length(); i++) + if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) + theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); + } + } + + //================================================================================ + /*! + * \brief Returns elements connected to the given elements + */ + //================================================================================ + + void getElementsAround(const TIDSortedElemSet& theElements, + const SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElementsAround) + { + if ( theElements.empty() ) return; + + SMDSAbs_ElementType elemType = (*theElements.begin())->GetType(); + bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() ); + if ( sameElemType && + theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() ) + return; // all the elements are in theElements + + if ( !sameElemType ) + elemType = SMDSAbs_All; + + TIDSortedElemSet visitedNodes; + TIDSortedElemSet::const_iterator elemIt = theElements.begin(); + for ( ; elemIt != theElements.end(); ++elemIt ) + { + const SMDS_MeshElement* e = *elemIt; + int i = e->NbCornerNodes(); + while ( --i != -1 ) + { + const SMDS_MeshNode* n = e->GetNode( i ); + if ( visitedNodes.insert( n ).second ) + { + SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType); + while ( invIt->more() ) + { + const SMDS_MeshElement* elemAround = invIt->next(); + if ( !theElements.count( elemAround )) + theElementsAround.insert( elemAround ); + } + } + } + } + } + + //================================================================================ + /*! + * \brief Return a string used to detect change of mesh part on which theElementSearcher + * is going to be used + */ + //================================================================================ + + string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type) + { + string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart ); + if ( SMESH_Group_i* group_i = SMESH::DownCast( theMeshPart )) + // take into account passible group modification + partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() ); + partIOR += SMESH_Comment( type ); + return partIOR; + } + } //============================================================================= @@ -225,11 +405,12 @@ namespace { */ //============================================================================= -SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview) +SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview): + myMesh_i( theMesh ), + myMesh( &theMesh->GetImpl() ), + myEditor( myMesh ), + myPreviewMode ( isPreview ) { - myMesh_i = theMesh; - myMesh = & theMesh->GetImpl(); - myPreviewMode = isPreview; } //================================================================================ @@ -248,16 +429,173 @@ SMESH_MeshEditor_i::~SMESH_MeshEditor_i() */ //================================================================================ -void SMESH_MeshEditor_i::initData() +void SMESH_MeshEditor_i::initData(bool deleteSearchers) { if ( myPreviewMode ) { - myPreviewData = new SMESH::MeshPreviewStruct(); + //myPreviewData = new SMESH::MeshPreviewStruct(); } else { - myLastCreatedElems = new SMESH::long_array(); - myLastCreatedNodes = new SMESH::long_array(); - TNodeSearcherDeleter::Delete(); + if ( deleteSearchers ) + TSearchersDeleter::Delete(); + } +} + +//================================================================================ +/*! + * \brief Now does nothing + */ +//================================================================================ + +void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& ) +{ +} + +//================================================================================ +/*! + * Return data of mesh edition preview + */ +//================================================================================ + +SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() +{ + if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- + + list aNodesConnectivity; + typedef map TNodesMap; + TNodesMap nodesMap; + + TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( myEditor.GetMesh() ); + SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType; + + SMESHDS_Mesh* aMeshDS = myEditor.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 = new SMESH::MeshPreviewStruct(); + 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( 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 = aMeshElem->GetType(); + bool 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::iterator aConnIter = aNodesConnectivity.begin(); + myPreviewData->elementConnectivities.length(aNodesConnectivity.size()); + for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ ) + myPreviewData->elementConnectivities[i] = *aConnIter; + } + + return myPreviewData._retn(); +} + +//================================================================================ +/*! + * \brief Returns list of it's IDs of created nodes + * \retval SMESH::long_array* - list of node ID + */ +//================================================================================ + +SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes() +{ + SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array(); + const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedNodes(); + myLastCreatedNodes->length( aSeq.Length() ); + for (int i = 1; i <= aSeq.Length(); i++) + myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID(); + return myLastCreatedNodes._retn(); +} + +//================================================================================ +/*! + * \brief Returns list of it's IDs of created elements + * \retval SMESH::long_array* - list of elements' ID + */ +//================================================================================ + +SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems() +{ + SMESH::long_array_var myLastCreatedElems = new SMESH::long_array(); + const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedElems(); + myLastCreatedElems->length( aSeq.Length() ); + for ( int i = 1; i <= aSeq.Length(); i++ ) + myLastCreatedElems[i-1] = aSeq.Value(i)->GetID(); + return myLastCreatedElems._retn(); +} + +//======================================================================= +//function : MakeIDSource +//purpose : Wrap a sequence of ids in a SMESH_IDSource +//======================================================================= + +struct _IDSource : public POA_SMESH::SMESH_IDSource +{ + SMESH::long_array _ids; + SMESH::ElementType _type; + SMESH::SMESH_Mesh_ptr _mesh; + SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); } + SMESH::long_array* GetMeshInfo() { return 0; } + SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); } + bool IsMeshInfoCorrect() { return true; } + SMESH::array_of_ElementType* GetTypes() + { + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + if ( _ids.length() > 0 ) { + types->length( 1 ); + types[0] = _type; + } + return types._retn(); } +}; + +SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids, + SMESH::ElementType type) +{ + _IDSource* anIDSource = new _IDSource; + anIDSource->_ids = ids; + anIDSource->_type = type; + anIDSource->_mesh = myMesh_i->_this(); + SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this(); + + return anIDSourceVar._retn(); } //============================================================================= @@ -267,11 +605,10 @@ void SMESH_MeshEditor_i::initData() //============================================================================= CORBA::Boolean - SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements) +SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements) { initData(); - ::SMESH_MeshEditor anEditor( myMesh ); list< int > IdList; for (int i = 0; i < IDsOfElements.length(); i++) @@ -279,11 +616,13 @@ CORBA::Boolean // Update Python script TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'RemoveElements: ', isDone"; -#endif + // Remove Elements - return anEditor.Remove( IdList, false ); + bool ret = myEditor.Remove( IdList, false ); + myMesh->GetMeshDS()->Modified(); + if ( IDsOfElements.length() ) + myMesh->SetIsModified( true ); // issue 0020693 + return ret; } //============================================================================= @@ -296,18 +635,18 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo { initData(); - ::SMESH_MeshEditor anEditor( myMesh ); list< int > IdList; for (int i = 0; i < IDsOfNodes.length(); i++) IdList.push_back( IDsOfNodes[i] ); // Update Python script TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'RemoveNodes: ', isDone"; -#endif - return anEditor.Remove( IdList, true ); + bool ret = myEditor.Remove( IdList, true ); + myMesh->GetMeshDS()->Modified(); + if ( IDsOfNodes.length() ) + myMesh->SetIsModified( true ); // issue 0020693 + return ret; } //============================================================================= @@ -316,43 +655,37 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) +CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes() { initData(); - int NbNodes = IDsOfNodes.length(); - SMDS_MeshElement* elem = 0; - if (NbNodes == 2) - { - CORBA::Long index1 = IDsOfNodes[0]; - CORBA::Long index2 = IDsOfNodes[1]; - elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2)); - // Update Python script - TPythonDump() << "edge = " << this << ".AddEdge([ " - << index1 << ", " << index2 <<" ])"; - } - if (NbNodes == 3) { - CORBA::Long n1 = IDsOfNodes[0]; - CORBA::Long n2 = IDsOfNodes[1]; - CORBA::Long n12 = IDsOfNodes[2]; - elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1), - GetMeshDS()->FindNode(n2), - GetMeshDS()->FindNode(n12)); - // Update Python script - TPythonDump() << "edgeID = " << this << ".AddEdge([ " - <GetID(); + // Create filter to find all orphan nodes + SMESH::Controls::Filter::TIdSequence seq; + SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() ); + SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq ); - return 0; + // remove orphan nodes (if there are any) + list< int > IdList; + for ( int i = 0; i < seq.size(); i++ ) + IdList.push_back( seq[i] ); + + int nbNodesBefore = myMesh->NbNodes(); + myEditor.Remove( IdList, true ); + myMesh->GetMeshDS()->Modified(); + if ( IdList.size() ) + myMesh->SetIsModified( true ); + int nbNodesAfter = myMesh->NbNodes(); + + return nbNodesBefore - nbNodesAfter; } //============================================================================= /*! - * + * Add a new node. */ //============================================================================= @@ -365,37 +698,136 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x, // Update Python script TPythonDump() << "nodeID = " << this << ".AddNode( " - << x << ", " << y << ", " << z << " )"; + << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )"; + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); // issue 0020693 return N->GetID(); } //============================================================================= /*! - * AddFace + * Create 0D element on the given node. */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) +CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode) { initData(); - int NbNodes = IDsOfNodes.length(); - if (NbNodes < 3) - { - return 0; - } + const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode); + SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode); - std::vector nodes (NbNodes); - for (int i = 0; i < NbNodes; i++) - nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); + // Update Python script + TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )"; - SMDS_MeshElement* elem = 0; - if (NbNodes == 3) { - elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); - } - else if (NbNodes == 4) { - elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); // issue 0020693 + + if (elem) + return elem->GetID(); + + return 0; +} + +//============================================================================= +/*! + * Create a ball element on the given node. + */ +//============================================================================= + +CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter) + throw (SALOME::SALOME_Exception) +{ + initData(); + + if ( diameter < std::numeric_limits::min() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM); + + const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode); + SMDS_MeshElement* elem = GetMeshDS()->AddBall(aNode, diameter); + + // Update Python script + TPythonDump() << "ballElem = " + << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )"; + + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); // issue 0020693 + + if (elem) + return elem->GetID(); + + return 0; +} + +//============================================================================= +/*! + * Create an edge, either linear and quadratic (this is determed + * by number of given nodes, two or three) + */ +//============================================================================= + +CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes) +{ + initData(); + + int NbNodes = IDsOfNodes.length(); + SMDS_MeshElement* elem = 0; + if (NbNodes == 2) + { + CORBA::Long index1 = IDsOfNodes[0]; + CORBA::Long index2 = IDsOfNodes[1]; + elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2)); + + // Update Python script + TPythonDump() << "edge = " << this << ".AddEdge([ " + << index1 << ", " << index2 <<" ])"; + } + if (NbNodes == 3) { + CORBA::Long n1 = IDsOfNodes[0]; + CORBA::Long n2 = IDsOfNodes[1]; + CORBA::Long n12 = IDsOfNodes[2]; + elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1), + GetMeshDS()->FindNode(n2), + GetMeshDS()->FindNode(n12)); + // Update Python script + TPythonDump() << "edgeID = " << this << ".AddEdge([ " + <GetMeshDS()->Modified(); + if(elem) + return myMesh->SetIsModified( true ), elem->GetID(); + + return 0; +} + +//============================================================================= +/*! + * AddFace + */ +//============================================================================= + +CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) +{ + initData(); + + int NbNodes = IDsOfNodes.length(); + if (NbNodes < 3) + { + return 0; + } + + std::vector nodes (NbNodes); + for (int i = 0; i < NbNodes; i++) + nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); + + SMDS_MeshElement* elem = 0; + if (NbNodes == 3) { + elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); + } + else if (NbNodes == 4) { + elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); } else if (NbNodes == 6) { elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], @@ -405,12 +837,20 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], nodes[6], nodes[7]); } + else if (NbNodes == 9) { + elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] ); + } + else if (NbNodes > 2) { + elem = GetMeshDS()->AddPolygonalFace(nodes); + } // Update Python script TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )"; + myMesh->GetMeshDS()->Modified(); if(elem) - return elem->GetID(); + return myMesh->SetIsModified( true ), elem->GetID(); return 0; } @@ -420,8 +860,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) * AddPolygonalFace */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace - (const SMESH::long_array & IDsOfNodes) +CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes) { initData(); @@ -431,22 +870,18 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes); - + // Update Python script TPythonDump() <<"faceID = "<GetID(); - return 0; + myMesh->GetMeshDS()->Modified(); + return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } //============================================================================= /*! - * + * Create volume, either linear and quadratic (this is determed + * by number of given nodes) */ //============================================================================= @@ -469,6 +904,9 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5], n[6],n[7],n[8],n[9]); break; + case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5], + n[6],n[7],n[8],n[9],n[10],n[11]); + break; case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6], n[7],n[8],n[9],n[10],n[11],n[12]); break; @@ -479,16 +917,19 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) n[8],n[9],n[10],n[11],n[12],n[13],n[14], n[15],n[16],n[17],n[18],n[19]); break; + case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], + n[8],n[9],n[10],n[11],n[12],n[13],n[14], + n[15],n[16],n[17],n[18],n[19], + n[20],n[21],n[22],n[23],n[24],n[25],n[26]); + break; } // Update Python script TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'AddVolume: ', volID"; -#endif + myMesh->GetMeshDS()->Modified(); if(elem) - return elem->GetID(); + return myMesh->SetIsModified( true ), elem->GetID(); return 0; } @@ -498,16 +939,19 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) * AddPolyhedralVolume */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume - (const SMESH::long_array & IDsOfNodes, - const SMESH::long_array & Quantities) +CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes, + const SMESH::long_array & Quantities) { initData(); int NbNodes = IDsOfNodes.length(); std::vector n (NbNodes); for (int i = 0; i < NbNodes; i++) - n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); + { + const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]); + if (!aNode) return 0; + n[i] = aNode; + } int NbFaces = Quantities.length(); std::vector q (NbFaces); @@ -519,14 +963,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume // Update Python script TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( " << IDsOfNodes << ", " << Quantities << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'AddPolyhedralVolume: ', volID"; -#endif + myMesh->GetMeshDS()->Modified(); - if(elem) - return elem->GetID(); - - return 0; + return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } //============================================================================= @@ -534,8 +973,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume * AddPolyhedralVolumeByFaces */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces - (const SMESH::long_array & IdsOfFaces) +CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces) { initData(); @@ -558,14 +996,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces // Update Python script TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( " << IdsOfFaces << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'AddPolyhedralVolume: ', volID"; -#endif - - if(elem) - return elem->GetID(); + myMesh->GetMeshDS()->Modified(); - return 0; + return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0; } //============================================================================= @@ -595,6 +1028,8 @@ void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexI THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM); mesh->SetNodeOnVertex( node, VertexID ); + + myMesh->SetIsModified( true ); } //============================================================================= @@ -631,6 +1066,8 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID, THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM); mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge ); + + myMesh->SetIsModified( true ); } //============================================================================= @@ -671,15 +1108,16 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID, if ( isOut ) { #ifdef _DEBUG_ MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of " - << " u( " << surf.FirstUParameter() - << "," << surf.LastUParameter() - << ") v( " << surf.FirstVParameter() - << "," << surf.LastVParameter() << ")" ); -#endif + << " u( " << surf.FirstUParameter() + << "," << surf.LastUParameter() + << ") v( " << surf.FirstVParameter() + << "," << surf.LastVParameter() << ")" ); +#endif THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM); } mesh->SetNodeOnFace( node, FaceID, u, v ); + myMesh->SetIsModified( true ); } //============================================================================= @@ -710,6 +1148,8 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM); mesh->SetNodeInVolume( node, SolidID ); + + // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe } //============================================================================= @@ -743,33 +1183,8 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID, THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM); mesh->SetMeshElementOnShape( elem, ShapeID ); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, - CORBA::Double x, - CORBA::Double y, - CORBA::Double z) -{ - initData(); - - const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID ); - if ( !node ) - return false; - - GetMeshDS()->MoveNode(node, x, y, z); - - // Update Python script - TPythonDump() << "isDone = " << this << ".MoveNode( " - << NodeID << ", " << x << ", " << y << ", " << z << " )"; - - return true; + myMesh->SetIsModified( true ); } //============================================================================= @@ -792,8 +1207,11 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1, TPythonDump() << "isDone = " << this << ".InverseDiag( " << NodeID1 << ", " << NodeID2 << " )"; - ::SMESH_MeshEditor aMeshEditor( myMesh ); - return aMeshEditor.InverseDiag ( n1, n2 ); + + int ret = myEditor.InverseDiag ( n1, n2 ); + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + return ret; } //============================================================================= @@ -816,11 +1234,14 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1, TPythonDump() << "isDone = " << this << ".DeleteDiag( " << NodeID1 << ", " << NodeID2 << " )"; - ::SMESH_MeshEditor aMeshEditor( myMesh ); - bool stat = aMeshEditor.DeleteDiag ( n1, n2 ); + bool stat = myEditor.DeleteDiag ( n1, n2 ); - storeResult(aMeshEditor); + myMesh->GetMeshDS()->Modified(); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 + + storeResult(myEditor); return stat; } @@ -835,17 +1256,20 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme { initData(); - ::SMESH_MeshEditor anEditor( myMesh ); for (int i = 0; i < IDsOfElements.length(); i++) { CORBA::Long index = IDsOfElements[i]; const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index); if ( elem ) - anEditor.Reorient( elem ); + myEditor.Reorient( elem ); } // Update Python script TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )"; + myMesh->GetMeshDS()->Modified(); + if ( IDsOfElements.length() ) + myMesh->SetIsModified( true ); // issue 0020693 + return true; } @@ -860,43 +1284,102 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO { initData(); + TPythonDump aTPythonDump; // suppress dump in Reorient() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = Reorient(anElementsId); - // Clear python line, created by Reorient() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); - // Update Python script - TPythonDump() << "isDone = " << this << ".ReorientObject( " << theObject << " )"; + aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )"; return isDone; } -namespace +//======================================================================= +//function : Reorient2D +//purpose : Reorient faces contained in \a the2Dgroup. +// the2Dgroup - the mesh or its part to reorient +// theDirection - desired direction of normal of \a theFace +// theFace - ID of face whose orientation is checked. +// It can be < 1 then \a thePoint is used to find a face. +// thePoint - is used to find a face if \a theFace < 1. +// return number of reoriented elements. +//======================================================================= + +CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, + const SMESH::DirStruct& theDirection, + CORBA::Long theFace, + const SMESH::PointStruct& thePoint) + throw (SALOME::SALOME_Exception) { - //================================================================================ - /*! - * \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 - */ - //================================================================================ + Unexpect aCatch(SALOME_SalomeException); - void arrayToSet(const SMESH::long_array & IDs, - const SMESHDS_Mesh* aMesh, - TIDSortedElemSet& aMap, - const SMDSAbs_ElementType aType = SMDSAbs_All ) - { - for (int i=0; iFindElement(ind); - if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType )) - aMap.insert( elem ); + initData(/*deleteSearchers=*/false); + + TIDSortedElemSet elements; + if ( !idSourceToSet( the2Dgroup, GetMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1)) + THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM); + + + const SMDS_MeshElement* face = 0; + if ( theFace > 0 ) + { + face = GetMeshDS()->FindElement( theFace ); + if ( !face ) + THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM); + if ( face->GetType() != SMDSAbs_Face ) + THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM); + } + else + { + // create theElementSearcher if needed + theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE )); + if ( !theElementSearcher ) + { + if ( elements.empty() ) // search in the whole mesh + { + if ( myMesh->NbFaces() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM); + + theElementSearcher = myEditor.GetElementSearcher(); + } + else + { + typedef SMDS_SetIterator TIter; + SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() )); + + theElementSearcher = myEditor.GetElementSearcher(elemsIt); + } } + // find a face + gp_Pnt p( thePoint.x, thePoint.y, thePoint.z ); + face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face ); + + if ( !face ) + THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR ); + if ( !elements.empty() && !elements.count( face )) + THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM ); + } + + const SMESH::PointStruct * P = &theDirection.PS; + gp_Vec dirVec( P->x, P->y, P->z ); + if ( dirVec.Magnitude() < std::numeric_limits< double >::min() ) + THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM); + + int nbReori = myEditor.Reorient2D( elements, dirVec, face ); + storeResult(myEditor); + + if ( nbReori ) { + myMesh->SetIsModified( true ); + myMesh->GetMeshDS()->Modified(); } + TPythonDump() << this << ".Reorient2D( " + << the2Dgroup << ", " + << theDirection << ", " + << theFace << ", " + << thePoint << " )"; + + return nbReori; } //============================================================================= @@ -924,16 +1407,15 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE // Update Python script TPythonDump() << "isDone = " << this << ".TriToQuad( " - << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'TriToQuad: ', isDone"; -#endif + << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; - ::SMESH_MeshEditor anEditor( myMesh ); - bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle ); + bool stat = myEditor.TriToQuad( faces, aCrit, MaxAngle ); + myMesh->GetMeshDS()->Modified(); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 - storeResult(anEditor); + storeResult(myEditor); return stat; } @@ -950,25 +1432,16 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr { initData(); + TPythonDump aTPythonDump; // suppress dump in TriToQuad() SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle); - // Clear python line(s), created by TriToQuad() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#ifdef _DEBUG_ - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#endif - SMESH::NumericalFunctor_i* aNumericalFunctor = SMESH::DownCast( Criterion ); // Update Python script - TPythonDump() << "isDone = " << this << ".TriToQuadObject(" - << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'TriToQuadObject: ', isDone"; -#endif + aTPythonDump << "isDone = " << this << ".TriToQuadObject(" + << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; return isDone; } @@ -999,14 +1472,13 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfE // Update Python script TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'QuadToTri: ', isDone"; -#endif - ::SMESH_MeshEditor anEditor( myMesh ); - CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit ); + CORBA::Boolean stat = myEditor.QuadToTri( faces, aCrit ); + myMesh->GetMeshDS()->Modified(); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 - storeResult(anEditor); + storeResult(myEditor); return stat; } @@ -1022,24 +1494,16 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr { initData(); + TPythonDump aTPythonDump; // suppress dump in QuadToTri() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion); - // Clear python line(s), created by QuadToTri() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#ifdef _DEBUG_ - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#endif - SMESH::NumericalFunctor_i* aNumericalFunctor = SMESH::DownCast( Criterion ); // Update Python script - TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'QuadToTriObject: ', isDone"; -#endif + aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )"; return isDone; } @@ -1062,14 +1526,14 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle // Update Python script TPythonDump() << "isDone = " << this << ".SplitQuad( " << IDsOfElements << ", " << Diag13 << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'SplitQuad: ', isDone"; -#endif - ::SMESH_MeshEditor anEditor( myMesh ); - CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 ); + CORBA::Boolean stat = myEditor.QuadToTri( faces, Diag13 ); + myMesh->GetMeshDS()->Modified(); + if ( stat ) + myMesh->SetIsModified( true ); // issue 0020693 - storeResult(anEditor); + + storeResult(myEditor); return stat; } @@ -1085,22 +1549,14 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th { initData(); + TPythonDump aTPythonDump; // suppress dump in SplitQuad() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13); - // Clear python line(s), created by SplitQuad() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#ifdef _DEBUG_ - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#endif - // Update Python script - TPythonDump() << "isDone = " << this << ".SplitQuadObject( " - << theObject << ", " << Diag13 << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'SplitQuadObject: ', isDone"; -#endif + aTPythonDump << "isDone = " << this << ".SplitQuadObject( " + << theObject << ", " << Diag13 << " )"; return isDone; } @@ -1114,6 +1570,8 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, SMESH::NumericalFunctor_ptr Criterion) { + initData(); + const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad); if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4) { @@ -1125,12 +1583,40 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, else aCrit.reset(new SMESH::Controls::AspectRatio()); - ::SMESH_MeshEditor anEditor (myMesh); - return anEditor.BestSplit(quad, aCrit); + return myEditor.BestSplit(quad, aCrit); } return -1; } +//================================================================================ +/*! + * \brief Split volumic elements into tetrahedrons + */ +//================================================================================ + +void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, + CORBA::Short methodFlags) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + + initData(); + + SMESH::long_array_var anElementsId = elems->GetIDs(); + TIDSortedElemSet elemSet; + arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume ); + + myEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags )); + myMesh->GetMeshDS()->Modified(); + + storeResult(myEditor); + +// if ( myLastCreatedElems.length() ) - it does not influence Compute() +// myMesh->SetIsModified( true ); // issue 0020693 + + TPythonDump() << this << ".SplitVolumesIntoTetra( " + << elems << ", " << methodFlags << " )"; +} //======================================================================= //function : Smooth @@ -1138,14 +1624,14 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, //======================================================================= CORBA::Boolean - SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, - CORBA::Double MaxAspectRatio, - SMESH::SMESH_MeshEditor::Smooth_Method Method) +SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements, + const SMESH::long_array & IDsOfFixedNodes, + CORBA::Long MaxNbOfIterations, + CORBA::Double MaxAspectRatio, + SMESH::SMESH_MeshEditor::Smooth_Method Method) { return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, - MaxAspectRatio, Method, false ); + MaxAspectRatio, Method, false ); } @@ -1155,14 +1641,14 @@ CORBA::Boolean //======================================================================= CORBA::Boolean - SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, - CORBA::Double MaxAspectRatio, - SMESH::SMESH_MeshEditor::Smooth_Method Method) +SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements, + const SMESH::long_array & IDsOfFixedNodes, + CORBA::Long MaxNbOfIterations, + CORBA::Double MaxAspectRatio, + SMESH::SMESH_MeshEditor::Smooth_Method Method) { return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, - MaxAspectRatio, Method, true ); + MaxAspectRatio, Method, true ); } @@ -1172,11 +1658,11 @@ CORBA::Boolean //======================================================================= CORBA::Boolean - SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, - CORBA::Double MaxAspectRatio, - SMESH::SMESH_MeshEditor::Smooth_Method Method) +SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::long_array & IDsOfFixedNodes, + CORBA::Long MaxNbOfIterations, + CORBA::Double MaxAspectRatio, + SMESH::SMESH_MeshEditor::Smooth_Method Method) { return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, false); @@ -1189,11 +1675,11 @@ CORBA::Boolean //======================================================================= CORBA::Boolean - SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, - CORBA::Double MaxAspectRatio, - SMESH::SMESH_MeshEditor::Smooth_Method Method) +SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::long_array & IDsOfFixedNodes, + CORBA::Long MaxNbOfIterations, + CORBA::Double MaxAspectRatio, + SMESH::SMESH_MeshEditor::Smooth_Method Method) { return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, true); @@ -1207,12 +1693,12 @@ CORBA::Boolean //============================================================================= CORBA::Boolean - SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, - CORBA::Double MaxAspectRatio, - SMESH::SMESH_MeshEditor::Smooth_Method Method, - bool IsParametric) +SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, + const SMESH::long_array & IDsOfFixedNodes, + CORBA::Long MaxNbOfIterations, + CORBA::Double MaxAspectRatio, + SMESH::SMESH_MeshEditor::Smooth_Method Method, + bool IsParametric) { initData(); @@ -1232,23 +1718,22 @@ CORBA::Boolean if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH ) method = ::SMESH_MeshEditor::CENTROIDAL; - ::SMESH_MeshEditor anEditor( myMesh ); - anEditor.Smooth(elements, fixedNodes, method, + myEditor.Smooth(elements, fixedNodes, method, MaxNbOfIterations, MaxAspectRatio, IsParametric ); - storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); // issue 0020693 + + storeResult(myEditor); // Update Python script TPythonDump() << "isDone = " << this << "." << (IsParametric ? "SmoothParametric( " : "Smooth( ") << IDsOfElements << ", " << IDsOfFixedNodes << ", " - << MaxNbOfIterations << ", " << MaxAspectRatio << ", " + << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", " << "SMESH.SMESH_MeshEditor." << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ? "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )"); -#ifdef _DEBUG_ - TPythonDump() << "print 'Smooth: ', isDone"; -#endif return true; } @@ -1270,28 +1755,20 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObjec { initData(); + TPythonDump aTPythonDump; // suppress dump in smooth() + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, IsParametric); - // Clear python line(s), created by Smooth() - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#ifdef _DEBUG_ - aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID()); -#endif - // Update Python script - TPythonDump() << "isDone = " << this << "." - << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ") - << theObject << ", " << IDsOfFixedNodes << ", " - << MaxNbOfIterations << ", " << MaxAspectRatio << ", " - << "SMESH.SMESH_MeshEditor." - << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ? - "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )"); -#ifdef _DEBUG_ - TPythonDump() << "print 'SmoothObject: ', isDone"; -#endif + aTPythonDump << "isDone = " << this << "." + << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ") + << theObject << ", " << IDsOfFixedNodes << ", " + << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", " + << "SMESH.SMESH_MeshEditor." + << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ? + "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )"); return isDone; } @@ -1327,9 +1804,9 @@ void SMESH_MeshEditor_i::RenumberElements() } //======================================================================= - /*! - * \brief Return groups by their IDs - */ +/*! + * \brief Return groups by their IDs + */ //======================================================================= SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list* groupIDs) @@ -1342,7 +1819,7 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list* groupID //======================================================================= //function : rotationSweep -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1352,7 +1829,7 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements, CORBA::Long theNbOfSteps, CORBA::Double theTolerance, const bool theMakeGroups, - const SMDSAbs_ElementType theElementType) + const SMDSAbs_ElementType theElementType) { initData(); @@ -1379,11 +1856,13 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements, gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ), gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz )); - ::SMESH_MeshEditor anEditor( mesh ); ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians, - theNbOfSteps, theTolerance, theMakeGroups, makeWalls); - storeResult(anEditor); + myEditor.RotationSweep (*workElements, Ax1, theAngleInRadians, + theNbOfSteps, theTolerance, theMakeGroups, makeWalls); + storeResult(myEditor); + myMesh->GetMeshDS()->Modified(); + + // myMesh->SetIsModified( true ); -- it does not influence Compute() return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -1401,11 +1880,11 @@ void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElement { if ( !myPreviewMode ) { TPythonDump() << this << ".RotationSweep( " - << theIDsOfElements << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + << theIDsOfElements << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << TVar( theNbOfSteps ) << ", " + << TVar( theTolerance ) << " )"; } rotationSweep(theIDsOfElements, theAxis, @@ -1417,7 +1896,7 @@ void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElement //======================================================================= //function : RotationSweepMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1427,21 +1906,22 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle CORBA::Long theNbOfSteps, CORBA::Double theTolerance) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements, theAxis, theAngleInRadians, theNbOfSteps, theTolerance, true); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump<< this << ".RotationSweepMakeGroups( " - << theIDsOfElements << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".RotationSweepMakeGroups( " + << theIDsOfElements << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << TVar( theNbOfSteps ) << ", " + << TVar( theTolerance ) << " )"; } return aGroups; } @@ -1452,10 +1932,10 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle //======================================================================= void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) + const SMESH::AxisStruct & theAxis, + CORBA::Double theAngleInRadians, + CORBA::Long theNbOfSteps, + CORBA::Double theTolerance) { if ( !myPreviewMode ) { TPythonDump() << this << ".RotationSweepObject( " @@ -1480,18 +1960,18 @@ void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject //======================================================================= void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) + const SMESH::AxisStruct & theAxis, + CORBA::Double theAngleInRadians, + CORBA::Long theNbOfSteps, + CORBA::Double theTolerance) { if ( !myPreviewMode ) { TPythonDump() << this << ".RotationSweepObject1D( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + << theObject << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << TVar( theNbOfSteps ) << ", " + << TVar( theTolerance ) << " )"; } SMESH::long_array_var anElementsId = theObject->GetIDs(); rotationSweep(anElementsId, @@ -1500,7 +1980,7 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje theNbOfSteps, theTolerance, false, - SMDSAbs_Edge); + SMDSAbs_Edge); } //======================================================================= @@ -1509,18 +1989,18 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje //======================================================================= void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) + const SMESH::AxisStruct & theAxis, + CORBA::Double theAngleInRadians, + CORBA::Long theNbOfSteps, + CORBA::Double theTolerance) { if ( !myPreviewMode ) { TPythonDump() << this << ".RotationSweepObject2D( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + << theObject << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << TVar( theNbOfSteps ) << ", " + << TVar( theTolerance ) << " )"; } SMESH::long_array_var anElementsId = theObject->GetIDs(); rotationSweep(anElementsId, @@ -1529,12 +2009,12 @@ void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObje theNbOfSteps, theTolerance, false, - SMDSAbs_Face); + SMDSAbs_Face); } //======================================================================= //function : RotationSweepObjectMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1544,6 +2024,8 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO CORBA::Long theNbOfSteps, CORBA::Double theTolerance) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, theAxis, @@ -1551,31 +2033,32 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO theNbOfSteps, theTolerance, true); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump<< this << ".RotationSweepObjectMakeGroups( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".RotationSweepObjectMakeGroups( " + << theObject << ", " + << theAxis << ", " + << theAngleInRadians << ", " + << theNbOfSteps << ", " + << theTolerance << " )"; } return aGroups; } //======================================================================= //function : RotationSweepObject1DMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) + const SMESH::AxisStruct& theAxis, + CORBA::Double theAngleInRadians, + CORBA::Long theNbOfSteps, + CORBA::Double theTolerance) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, theAxis, @@ -1583,32 +2066,33 @@ SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr th theNbOfSteps, theTolerance, true, - SMDSAbs_Edge); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump<< this << ".RotationSweepObject1DMakeGroups( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + SMDSAbs_Edge); + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".RotationSweepObject1DMakeGroups( " + << theObject << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << TVar( theNbOfSteps ) << ", " + << TVar( theTolerance ) << " )"; } return aGroups; } //======================================================================= //function : RotationSweepObject2DMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) + const SMESH::AxisStruct& theAxis, + CORBA::Double theAngleInRadians, + CORBA::Long theNbOfSteps, + CORBA::Double theTolerance) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, theAxis, @@ -1616,16 +2100,15 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th theNbOfSteps, theTolerance, true, - SMDSAbs_Face); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump<< this << ".RotationSweepObject2DMakeGroups( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + SMDSAbs_Face); + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".RotationSweepObject2DMakeGroups( " + << theObject << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << TVar( theNbOfSteps ) << ", " + << TVar( theTolerance ) << " )"; } return aGroups; } @@ -1633,39 +2116,59 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th //======================================================================= //function : extrusionSweep -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements, const SMESH::DirStruct & theStepVector, CORBA::Long theNbOfSteps, - const bool theMakeGroups, + bool theMakeGroups, const SMDSAbs_ElementType theElementType) { initData(); - try { + try { #ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; #endif - TIDSortedElemSet elements; + TIDSortedElemSet elements, copyElements; arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType); const SMESH::PointStruct * P = &theStepVector.PS; gp_Vec stepVec( P->x, P->y, P->z ); + TIDSortedElemSet* workElements = & elements; + + SMDSAbs_ElementType aType = SMDSAbs_Face; + //::SMESH_MeshEditor::ExtrusionFlags aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_BOUNDARY; + if (theElementType == SMDSAbs_Node) + { + aType = SMDSAbs_Edge; + //aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_SEW; + } + TPreviewMesh tmpMesh( aType ); + SMESH_Mesh* mesh = myMesh; + + if ( myPreviewMode ) { + SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; + tmpMesh.Copy( elements, copyElements, select, avoid ); + mesh = &tmpMesh; + workElements = & copyElements; + theMakeGroups = false; + } + TElemOfElemListMap aHystory; - ::SMESH_MeshEditor anEditor( myMesh ); - ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups); + ::SMESH_MeshEditor::PGroupIDs groupIds = + myEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups); - storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); + storeResult(myEditor); return theMakeGroups ? getGroups(groupIds.get()) : 0; } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() ); } return 0; @@ -1681,12 +2184,27 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen CORBA::Long theNbOfSteps) { extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false ); - if ( !myPreviewMode ) { + if (!myPreviewMode) { TPythonDump() << this << ".ExtrusionSweep( " - << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )"; + << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )"; } } +//======================================================================= +//function : ExtrusionSweep0D +//purpose : +//======================================================================= + +void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements, + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps) +{ + extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node ); + if (!myPreviewMode) { + TPythonDump() << this << ".ExtrusionSweep0D( " + << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )"; + } +} //======================================================================= //function : ExtrusionSweepObject @@ -1694,17 +2212,34 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen //======================================================================= void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps) { SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false ); - if ( !myPreviewMode ) { + if (!myPreviewMode) { TPythonDump() << this << ".ExtrusionSweepObject( " << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; } } +//======================================================================= +//function : ExtrusionSweepObject0D +//purpose : +//======================================================================= + +void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps) +{ + SMESH::long_array_var anElementsId = theObject->GetIDs(); + extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node ); + if ( !myPreviewMode ) { + TPythonDump() << this << ".ExtrusionSweepObject0D( " + << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; + } +} + //======================================================================= //function : ExtrusionSweepObject1D //purpose : @@ -1718,7 +2253,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObj extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge ); if ( !myPreviewMode ) { TPythonDump() << this << ".ExtrusionSweepObject1D( " - << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; + << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; } } @@ -1735,13 +2270,13 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObj extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face ); if ( !myPreviewMode ) { TPythonDump() << this << ".ExtrusionSweepObject2D( " - << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; + << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; } } //======================================================================= //function : ExtrusionSweepMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1749,19 +2284,43 @@ SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfEl const SMESH::DirStruct& theStepVector, CORBA::Long theNbOfSteps) { - SMESH::ListOfGroups* aGroups = extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, true ); - - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump << this << ".ExtrusionSweepMakeGroups( " - << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )"; + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true); + + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements + << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )"; + } + return aGroups; +} + +//======================================================================= +//function : ExtrusionSweepMakeGroups0D +//purpose : +//======================================================================= + +SMESH::ListOfGroups* +SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements, + const SMESH::DirStruct& theStepVector, + CORBA::Long theNbOfSteps) +{ + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node); + + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements + << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )"; } return aGroups; } + //======================================================================= //function : ExtrusionSweepObjectMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1769,21 +2328,45 @@ SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr the const SMESH::DirStruct& theStepVector, CORBA::Long theNbOfSteps) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true ); - - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump<< this << ".ExtrusionSweepObjectMakeGroups( " - << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; + SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true); + + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject + << ", " << theStepVector << ", " << theNbOfSteps << " )"; + } + return aGroups; +} + +//======================================================================= +//function : ExtrusionSweepObject0DMakeGroups +//purpose : +//======================================================================= + +SMESH::ListOfGroups* +SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::DirStruct& theStepVector, + CORBA::Long theNbOfSteps) +{ + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::long_array_var anElementsId = theObject->GetIDs(); + SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, + theNbOfSteps, true, SMDSAbs_Node); + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject + << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; } return aGroups; } //======================================================================= //function : ExtrusionSweepObject1DMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1791,20 +2374,22 @@ SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr t const SMESH::DirStruct& theStepVector, CORBA::Long theNbOfSteps) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Edge ); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " - << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; + SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, + theNbOfSteps, true, SMDSAbs_Edge); + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject + << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; } return aGroups; } //======================================================================= //function : ExtrusionSweepObject2DMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1812,13 +2397,15 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t const SMESH::DirStruct& theStepVector, CORBA::Long theNbOfSteps) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Face ); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); - aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " - << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; + SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, + theNbOfSteps, true, SMDSAbs_Face); + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject + << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; } return aGroups; } @@ -1826,7 +2413,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t //======================================================================= //function : advancedExtrusion -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -1845,12 +2432,11 @@ SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements const SMESH::PointStruct * P = &theStepVector.PS; gp_Vec stepVec( P->x, P->y, P->z ); - ::SMESH_MeshEditor anEditor( myMesh ); TElemOfElemListMap aHystory; ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, + myEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups, theExtrFlags, theSewTolerance); - storeResult(anEditor); + storeResult(myEditor); return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -1861,10 +2447,10 @@ SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements //======================================================================= void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps, - CORBA::Long theExtrFlags, - CORBA::Double theSewTolerance) + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps, + CORBA::Long theExtrFlags, + CORBA::Double theSewTolerance) { if ( !myPreviewMode ) { TPythonDump() << "stepVector = " << theStepVector; @@ -1885,9 +2471,8 @@ void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfEle //======================================================================= //function : AdvancedExtrusionMakeGroups -//purpose : +//purpose : //======================================================================= - SMESH::ListOfGroups* SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements, const SMESH::DirStruct& theStepVector, @@ -1895,17 +2480,20 @@ SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsO CORBA::Long theExtrFlags, CORBA::Double theSewTolerance) { - SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements, - theStepVector, - theNbOfSteps, - theExtrFlags, - theSewTolerance, - true); - - if ( !myPreviewMode ) { + if (!myPreviewMode) { TPythonDump() << "stepVector = " << theStepVector; - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); + } + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements, + theStepVector, + theNbOfSteps, + theExtrFlags, + theSewTolerance, + true); + + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); aPythonDump << this << ".AdvancedExtrusionMakeGroups(" << theIDsOfElements << ", stepVector, " @@ -1928,13 +2516,13 @@ SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsO static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e ) { switch ( e ) { - RETCASE( EXTR_OK ); - RETCASE( EXTR_NO_ELEMENTS ); - RETCASE( EXTR_PATH_NOT_EDGE ); - RETCASE( EXTR_BAD_PATH_SHAPE ); - RETCASE( EXTR_BAD_STARTING_NODE ); - RETCASE( EXTR_BAD_ANGLES_NUMBER ); - RETCASE( EXTR_CANT_GET_TANGENT ); + RETCASE( EXTR_OK ); + RETCASE( EXTR_NO_ELEMENTS ); + RETCASE( EXTR_PATH_NOT_EDGE ); + RETCASE( EXTR_BAD_PATH_SHAPE ); + RETCASE( EXTR_BAD_STARTING_NODE ); + RETCASE( EXTR_BAD_ANGLES_NUMBER ); + RETCASE( EXTR_CANT_GET_TANGENT ); } return SMESH::SMESH_MeshEditor::EXTR_OK; } @@ -1942,9 +2530,8 @@ static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_Mesh //======================================================================= //function : extrusionAlongPath -//purpose : +//purpose : //======================================================================= - SMESH::ListOfGroups* SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements, SMESH::SMESH_Mesh_ptr thePathMesh, @@ -1956,8 +2543,9 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfEleme const SMESH::PointStruct & theRefPoint, const bool theMakeGroups, SMESH::SMESH_MeshEditor::Extrusion_Error & theError, - const SMDSAbs_ElementType theElementType) + const SMDSAbs_ElementType theElementType) { + MESSAGE("extrusionAlongPath"); initData(); if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) { @@ -1992,12 +2580,12 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfEleme int nbOldGroups = myMesh->NbGroup(); - ::SMESH_MeshEditor anEditor( myMesh ); ::SMESH_MeshEditor::Extrusion_Error error = - anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart, - theHasAngles, angles, + myEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart, + theHasAngles, angles, false, theHasRefPoint, refPnt, theMakeGroups ); - storeResult(anEditor); + myMesh->GetMeshDS()->Modified(); + storeResult(myEditor); theError = convExtrError( error ); if ( theMakeGroups ) { @@ -2010,21 +2598,131 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfEleme return 0; } + //======================================================================= -//function : ExtrusionAlongPath +//function : extrusionAlongPathX //purpose : //======================================================================= +SMESH::ListOfGroups* +SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements, + SMESH::SMESH_IDSource_ptr Path, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array& Angles, + CORBA::Boolean LinearVariation, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct& RefPoint, + bool MakeGroups, + const SMDSAbs_ElementType ElementType, + SMESH::SMESH_MeshEditor::Extrusion_Error & Error) +{ + SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups; + + initData(); + + list angles; + for (int i = 0; i < Angles.length(); i++) { + angles.push_back( Angles[i] ); + } + gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z ); + int nbOldGroups = myMesh->NbGroup(); + + if ( Path->_is_nil() ) { + Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; + return EmptyGr; + } + + TIDSortedElemSet elements, copyElements; + arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType); + + TIDSortedElemSet* workElements = &elements; + TPreviewMesh tmpMesh( SMDSAbs_Face ); + SMESH_Mesh* mesh = myMesh; + + if ( myPreviewMode ) + { + SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; + tmpMesh.Copy( elements, copyElements, select, avoid ); + mesh = &tmpMesh; + workElements = & copyElements; + MakeGroups = false; + } + + ::SMESH_MeshEditor::Extrusion_Error error; + + if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast( Path )) + { + // path as mesh + SMDS_MeshNode* aNodeStart = + (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart); + if ( !aNodeStart ) { + Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; + return EmptyGr; + } + error = myEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart, + HasAngles, angles, LinearVariation, + HasRefPoint, refPnt, MakeGroups ); + myMesh->GetMeshDS()->Modified(); + } + else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast( Path )) + { + // path as submesh + SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather(); + aMeshImp = SMESH::DownCast( aPathMesh ); + SMDS_MeshNode* aNodeStart = + (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart); + if ( !aNodeStart ) { + Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; + return EmptyGr; + } + SMESH_subMesh* aSubMesh = + aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId()); + error = myEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart, + HasAngles, angles, LinearVariation, + HasRefPoint, refPnt, MakeGroups ); + myMesh->GetMeshDS()->Modified(); + } + else if ( SMESH::DownCast( Path )) + { + // path as group of 1D elements + // ???????? + } + else + { + // invalid path + Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; + return EmptyGr; + } + + storeResult(myEditor); + Error = convExtrError( error ); + + if ( MakeGroups ) { + list groupIDs = myMesh->GetGroupIds(); + list::iterator newBegin = groupIDs.begin(); + std::advance( newBegin, nbOldGroups ); // skip old groups + groupIDs.erase( groupIDs.begin(), newBegin ); + return getGroups( & groupIDs ); + } + return EmptyGr; +} + +//======================================================================= +//function : ExtrusionAlongPath +//purpose : +//======================================================================= SMESH::SMESH_MeshEditor::Extrusion_Error - SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) +SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements, + SMESH::SMESH_Mesh_ptr thePathMesh, + GEOM::GEOM_Object_ptr thePathShape, + CORBA::Long theNodeStart, + CORBA::Boolean theHasAngles, + const SMESH::double_array & theAngles, + CORBA::Boolean theHasRefPoint, + const SMESH::PointStruct & theRefPoint) { + MESSAGE("ExtrusionAlongPath"); if ( !myPreviewMode ) { TPythonDump() << "error = " << this << ".ExtrusionAlongPath( " << theIDsOfElements << ", " @@ -2057,7 +2755,6 @@ SMESH::SMESH_MeshEditor::Extrusion_Error //function : ExtrusionAlongPathObject //purpose : //======================================================================= - SMESH::SMESH_MeshEditor::Extrusion_Error SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject, SMESH::SMESH_Mesh_ptr thePathMesh, @@ -2101,16 +2798,15 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObje //function : ExtrusionAlongPathObject1D //purpose : //======================================================================= - SMESH::SMESH_MeshEditor::Extrusion_Error SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) + SMESH::SMESH_Mesh_ptr thePathMesh, + GEOM::GEOM_Object_ptr thePathShape, + CORBA::Long theNodeStart, + CORBA::Boolean theHasAngles, + const SMESH::double_array & theAngles, + CORBA::Boolean theHasRefPoint, + const SMESH::PointStruct & theRefPoint) { if ( !myPreviewMode ) { TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( " @@ -2138,7 +2834,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theOb theRefPoint, false, anError, - SMDSAbs_Edge); + SMDSAbs_Edge); return anError; } @@ -2146,16 +2842,15 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theOb //function : ExtrusionAlongPathObject2D //purpose : //======================================================================= - SMESH::SMESH_MeshEditor::Extrusion_Error SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) + SMESH::SMESH_Mesh_ptr thePathMesh, + GEOM::GEOM_Object_ptr thePathShape, + CORBA::Long theNodeStart, + CORBA::Boolean theHasAngles, + const SMESH::double_array & theAngles, + CORBA::Boolean theHasRefPoint, + const SMESH::PointStruct & theRefPoint) { if ( !myPreviewMode ) { TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( " @@ -2183,16 +2878,15 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theOb theRefPoint, false, anError, - SMDSAbs_Face); + SMDSAbs_Face); return anError; } //======================================================================= //function : ExtrusionAlongPathMakeGroups -//purpose : +//purpose : //======================================================================= - SMESH::ListOfGroups* SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements, SMESH::SMESH_Mesh_ptr thePathMesh, @@ -2204,27 +2898,25 @@ SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theI const SMESH::PointStruct& theRefPoint, SMESH::SMESH_MeshEditor::Extrusion_Error& Error) { - SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error); - if ( !myPreviewMode ) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements, + thePathMesh, + thePathShape, + theNodeStart, + theHasAngles, + theAngles, + theHasRefPoint, + theRefPoint, + true, + Error); + if (!myPreviewMode) { bool isDumpGroups = aGroups && aGroups->length() > 0; - TPythonDump aPythonDump; - if(isDumpGroups) { - aPythonDump << "("<GetIDs(); SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, thePathMesh, @@ -2268,15 +2961,11 @@ ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, theRefPoint, true, Error); - - if ( !myPreviewMode ) { + + if (!myPreviewMode) { bool isDumpGroups = aGroups && aGroups->length() > 0; - TPythonDump aPythonDump; - if(isDumpGroups) { - aPythonDump << "("<GetIDs(); SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, thePathMesh, @@ -2323,18 +3013,14 @@ ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, theRefPoint, true, Error, - SMDSAbs_Edge); - - if ( !myPreviewMode ) { + SMDSAbs_Edge); + + if (!myPreviewMode) { bool isDumpGroups = aGroups && aGroups->length() > 0; - TPythonDump aPythonDump; - if(isDumpGroups) { - aPythonDump << "("<GetIDs(); SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, thePathMesh, @@ -2379,18 +3066,14 @@ ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, theRefPoint, true, Error, - SMDSAbs_Face); - - if ( !myPreviewMode ) { + SMDSAbs_Face); + + if (!myPreviewMode) { bool isDumpGroups = aGroups && aGroups->length() > 0; - TPythonDump aPythonDump; - if(isDumpGroups) { - aPythonDump << "("<GetIDs(); + SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId, + Path, + NodeStart, + HasAngles, + Angles, + LinearVariation, + HasRefPoint, + RefPoint, + MakeGroups, + (SMDSAbs_ElementType)ElemType, + Error); + + if (!myPreviewMode) { + bool isDumpGroups = aGroups && aGroups->length() > 0; + if (isDumpGroups) + aPythonDump << "(" << *aGroups << ", error)"; + else + aPythonDump << "error"; + + aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( " + << Object << ", " + << Path << ", " + << NodeStart << ", " + << HasAngles << ", " + << TVar( Angles ) << ", " + << LinearVariation << ", " + << HasRefPoint << ", " + << "SMESH.PointStruct( " + << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", " + << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", " + << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), " + << MakeGroups << ", " + << ElemType << " )"; + } + return aGroups; +} + + +//======================================================================= +//function : ExtrusionAlongPathX +//purpose : +//======================================================================= +SMESH::ListOfGroups* SMESH_MeshEditor_i:: +ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements, + SMESH::SMESH_IDSource_ptr Path, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array& Angles, + CORBA::Boolean LinearVariation, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct& RefPoint, + CORBA::Boolean MakeGroups, + SMESH::ElementType ElemType, + SMESH::SMESH_MeshEditor::Extrusion_Error& Error) +{ + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements, + Path, + NodeStart, + HasAngles, + Angles, + LinearVariation, + HasRefPoint, + RefPoint, + MakeGroups, + (SMDSAbs_ElementType)ElemType, + Error); + + if (!myPreviewMode) { + bool isDumpGroups = aGroups && aGroups->length() > 0; + if (isDumpGroups) + aPythonDump << "(" << *aGroups << ", error)"; + else + aPythonDump <<"error"; + + aPythonDump << " = " << this << ".ExtrusionAlongPathX( " + << IDsOfElements << ", " + << Path << ", " + << NodeStart << ", " + << HasAngles << ", " + << TVar( Angles ) << ", " + << LinearVariation << ", " + << HasRefPoint << ", " + << "SMESH.PointStruct( " + << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", " + << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", " + << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), " + << MakeGroups << ", " + << ElemType << " )"; } return aGroups; } + //================================================================================ /*! * \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 + * \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 */ //================================================================================ @@ -2455,7 +3254,7 @@ SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMes int iP = int( angPrevFloor ); double angPrevCeil = ceil(angPrev); angle = ( angPrevCeil - angPrev ) * theAngles[ iP ]; - + int iC = int( angCurFloor ); if ( iC < nbAngles ) angle += ( angCur - angCurFloor ) * theAngles[ iC ]; @@ -2482,25 +3281,25 @@ SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMes //======================================================================= //function : mirror -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::mirror(const SMESH::long_array & theIDsOfElements, +SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, const SMESH::AxisStruct & theAxis, SMESH::SMESH_MeshEditor::MirrorType theMirrorType, CORBA::Boolean theCopy, - const bool theMakeGroups, + bool theMakeGroups, ::SMESH_Mesh* theTargetMesh) { initData(); - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, GetMeshDS(), elements); - gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z ); gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz ); + if ( theTargetMesh ) + theCopy = false; + gp_Trsf aTrsf; switch ( theMirrorType ) { case SMESH::SMESH_MeshEditor::POINT: @@ -2513,20 +3312,50 @@ SMESH_MeshEditor_i::mirror(const SMESH::long_array & theIDsOfElements, aTrsf.SetMirror( gp_Ax2( P, V )); } - ::SMESH_MeshEditor anEditor( myMesh ); - ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + TIDSortedElemSet copyElements; + TPreviewMesh tmpMesh; + TIDSortedElemSet* workElements = & theElements; + SMESH_Mesh* mesh = myMesh; - if(theCopy) { - storeResult(anEditor); + if ( myPreviewMode ) + { + tmpMesh.Copy( theElements, copyElements); + if ( !theCopy && !theTargetMesh ) + { + TIDSortedElemSet elemsAround, elemsAroundCopy; + getElementsAround( theElements, GetMeshDS(), elemsAround ); + tmpMesh.Copy( elemsAround, elemsAroundCopy); + } + mesh = &tmpMesh; + workElements = & copyElements; + theMakeGroups = false; } - return theMakeGroups ? getGroups(groupIds.get()) : 0; -} -//======================================================================= -//function : Mirror -//purpose : -//======================================================================= + ::SMESH_MeshEditor::PGroupIDs groupIds = + myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + + if(theCopy || myPreviewMode) + storeResult(myEditor); // store preview data or new elements + + if ( !myPreviewMode ) + { + if ( theTargetMesh ) + { + theTargetMesh->GetMeshDS()->Modified(); + } + else + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } + } + return theMakeGroups ? getGroups(groupIds.get()) : 0; +} + +//======================================================================= +//function : Mirror +//purpose : +//======================================================================= void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements, const SMESH::AxisStruct & theAxis, @@ -2535,12 +3364,17 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElem { if ( !myPreviewMode ) { TPythonDump() << this << ".Mirror( " - << theIDsOfElements << ", " - << theAxis << ", " + << theIDsOfElements << ", " + << theAxis << ", " << mirrorTypeName(theMirrorType) << ", " - << theCopy << " )"; + << theCopy << " )"; + } + if ( theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + mirror(elements, theAxis, theMirrorType, theCopy, false); } - mirror(theIDsOfElements, theAxis, theMirrorType, theCopy, false); } @@ -2550,24 +3384,28 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElem //======================================================================= void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - SMESH::SMESH_MeshEditor::MirrorType theMirrorType, - CORBA::Boolean theCopy) + const SMESH::AxisStruct & theAxis, + SMESH::SMESH_MeshEditor::MirrorType theMirrorType, + CORBA::Boolean theCopy) { if ( !myPreviewMode ) { TPythonDump() << this << ".MirrorObject( " - << theObject << ", " - << theAxis << ", " + << theObject << ", " + << theAxis << ", " << mirrorTypeName(theMirrorType) << ", " - << theCopy << " )"; + << theCopy << " )"; } - SMESH::long_array_var anElementsId = theObject->GetIDs(); - mirror(anElementsId, theAxis, theMirrorType, theCopy, false); + TIDSortedElemSet elements; + + bool emptyIfIsMesh = myPreviewMode ? false : true; + + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) + mirror(elements, theAxis, theMirrorType, theCopy, false); } //======================================================================= //function : MirrorMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -2575,13 +3413,20 @@ SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsO const SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType theMirrorType) { - SMESH::ListOfGroups * aGroups = mirror(theIDsOfElements, theMirror, theMirrorType, true, true); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = 0; + if ( theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + aGroups = mirror(elements, theMirror, theMirrorType, true, true); + } + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); aPythonDump << this << ".MirrorMakeGroups( " - << theIDsOfElements << ", " - << theMirror << ", " + << theIDsOfElements << ", " + << theMirror << ", " << mirrorTypeName(theMirrorType) << " )"; } return aGroups; @@ -2589,7 +3434,7 @@ SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsO //======================================================================= //function : MirrorObjectMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -2597,14 +3442,19 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr t const SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType theMirrorType) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = mirror(anElementsId, theMirror, theMirrorType, true, true); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = 0; + TIDSortedElemSet elements; + if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + aGroups = mirror(elements, theMirror, theMirrorType, true, true); + + if (!myPreviewMode) + { DumpGroupsList(aPythonDump,aGroups); aPythonDump << this << ".MirrorObjectMakeGroups( " - << theObject << ", " - << theMirror << ", " + << theObject << ", " + << theMirror << ", " << mirrorTypeName(theMirrorType) << " )"; } return aGroups; @@ -2612,7 +3462,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr t //======================================================================= //function : MirrorMakeMesh -//purpose : +//purpose : //======================================================================= SMESH::SMESH_Mesh_ptr @@ -2626,37 +3476,40 @@ SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfE SMESH::SMESH_Mesh_var mesh; { // open new scope to dump "MakeMesh" command // and then "GetGroups" using SMESH_Mesh::GetGroups() - + TPythonDump pydump; // to prevent dump at mesh creation mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if (mesh_i) { - mirror(theIDsOfElements, theMirror, theMirrorType, + if (mesh_i && theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + mirror(elements, theMirror, theMirrorType, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } - - if ( !myPreviewMode ) { + + if (!myPreviewMode) { pydump << mesh << " = " << this << ".MirrorMakeMesh( " - << theIDsOfElements << ", " - << theMirror << ", " + << theIDsOfElements << ", " + << theMirror << ", " << mirrorTypeName(theMirrorType) << ", " - << theCopyGroups << ", '" - << theMeshName << "' )"; + << theCopyGroups << ", '" + << theMeshName << "' )"; } } //dump "GetGroups" - if(!myPreviewMode && mesh_i) + if (!myPreviewMode && mesh_i) mesh_i->GetGroups(); - + return mesh._retn(); } //======================================================================= //function : MirrorObjectMakeMesh -//purpose : +//purpose : //======================================================================= SMESH::SMESH_Mesh_ptr @@ -2670,62 +3523,94 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the SMESH::SMESH_Mesh_var mesh; { // open new scope to dump "MakeMesh" command // and then "GetGroups" using SMESH_Mesh::GetGroups() - + TPythonDump pydump; // to prevent dump at mesh creation mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if ( mesh_i ) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - mirror(anElementsId, theMirror, theMirrorType, + TIDSortedElemSet elements; + if ( mesh_i && + idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + { + mirror(elements, theMirror, theMirrorType, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } - - if ( !myPreviewMode ) { + if (!myPreviewMode) { pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( " - << theObject << ", " - << theMirror << ", " + << theObject << ", " + << theMirror << ", " << mirrorTypeName(theMirrorType) << ", " - << theCopyGroups << ", '" - << theMeshName << "' )"; + << theCopyGroups << ", '" + << theMeshName << "' )"; } - } + } //dump "GetGroups" - if(!myPreviewMode && mesh_i) + if (!myPreviewMode && mesh_i) mesh_i->GetGroups(); - + return mesh._retn(); } //======================================================================= //function : translate -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements, +SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, const SMESH::DirStruct & theVector, CORBA::Boolean theCopy, - const bool theMakeGroups, + bool theMakeGroups, ::SMESH_Mesh* theTargetMesh) { initData(); - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, GetMeshDS(), elements); + if ( theTargetMesh ) + theCopy = false; gp_Trsf aTrsf; const SMESH::PointStruct * P = &theVector.PS; aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z )); - ::SMESH_MeshEditor anEditor( myMesh ); + TIDSortedElemSet copyElements; + TIDSortedElemSet* workElements = &theElements; + TPreviewMesh tmpMesh; + SMESH_Mesh* mesh = myMesh; + + if ( myPreviewMode ) + { + tmpMesh.Copy( theElements, copyElements); + if ( !theCopy && !theTargetMesh ) + { + TIDSortedElemSet elemsAround, elemsAroundCopy; + getElementsAround( theElements, GetMeshDS(), elemsAround ); + tmpMesh.Copy( elemsAround, elemsAroundCopy); + } + mesh = &tmpMesh; + workElements = & copyElements; + theMakeGroups = false; + } + ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if(theCopy) - storeResult(anEditor); + if(theCopy || myPreviewMode) + storeResult(myEditor); + + if ( !myPreviewMode ) + { + if ( theTargetMesh ) + { + theTargetMesh->GetMeshDS()->Modified(); + } + else + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } + } return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -2739,16 +3624,17 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements, const SMESH::DirStruct & theVector, CORBA::Boolean theCopy) { - if ( !myPreviewMode ) { + if (!myPreviewMode) { TPythonDump() << this << ".Translate( " << theIDsOfElements << ", " - << theVector << ", " - << theCopy << " )"; + << theVector << ", " + << theCopy << " )"; + } + if (theIDsOfElements.length()) { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + translate(elements, theVector, theCopy, false); } - translate(theIDsOfElements, - theVector, - theCopy, - false); } //======================================================================= @@ -2757,58 +3643,67 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements, //======================================================================= void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theVector, - CORBA::Boolean theCopy) + const SMESH::DirStruct & theVector, + CORBA::Boolean theCopy) { - if ( !myPreviewMode ) { + if (!myPreviewMode) { TPythonDump() << this << ".TranslateObject( " << theObject << ", " << theVector << ", " - << theCopy << " )"; + << theCopy << " )"; } - SMESH::long_array_var anElementsId = theObject->GetIDs(); - translate(anElementsId, - theVector, - theCopy, - false); + TIDSortedElemSet elements; + + bool emptyIfIsMesh = myPreviewMode ? false : true; + + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) + translate(elements, theVector, theCopy, false); } //======================================================================= //function : TranslateMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements, const SMESH::DirStruct& theVector) { - SMESH::ListOfGroups * aGroups = translate(theIDsOfElements,theVector,true,true); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = 0; + if (theIDsOfElements.length()) { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + aGroups = translate(elements,theVector,true,true); + } + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); aPythonDump << this << ".TranslateMakeGroups( " << theIDsOfElements << ", " - << theVector << " )"; + << theVector << " )"; } return aGroups; } //======================================================================= //function : TranslateObjectMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::DirStruct& theVector) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = translate(anElementsId, theVector, true, true); - - if ( !myPreviewMode ) { + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); + SMESH::ListOfGroups * aGroups = 0; + TIDSortedElemSet elements; + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + aGroups = translate(elements, theVector, true, true); + + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); aPythonDump << this << ".TranslateObjectMakeGroups( " << theObject << ", " << theVector << " )"; @@ -2818,7 +3713,7 @@ SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObjec //======================================================================= //function : TranslateMakeMesh -//purpose : +//purpose : //======================================================================= SMESH::SMESH_Mesh_ptr @@ -2829,40 +3724,42 @@ SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements, { SMESH_Mesh_i* mesh_i; SMESH::SMESH_Mesh_var mesh; - + { // open new scope to dump "MakeMesh" command // and then "GetGroups" using SMESH_Mesh::GetGroups() TPythonDump pydump; // to prevent dump at mesh creation - + mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - - if ( mesh_i ) { - translate(theIDsOfElements, theVector, - false, theCopyGroups, & mesh_i->GetImpl()); + + if ( mesh_i && theIDsOfElements.length() ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } - + if ( !myPreviewMode ) { pydump << mesh << " = " << this << ".TranslateMakeMesh( " << theIDsOfElements << ", " - << theVector << ", " - << theCopyGroups << ", '" - << theMeshName << "' )"; + << theVector << ", " + << theCopyGroups << ", '" + << theMeshName << "' )"; } } - + //dump "GetGroups" - if(!myPreviewMode && mesh_i) + if (!myPreviewMode && mesh_i) mesh_i->GetGroups(); - + return mesh._retn(); } //======================================================================= //function : TranslateObjectMakeMesh -//purpose : +//purpose : //======================================================================= SMESH::SMESH_Mesh_ptr @@ -2875,50 +3772,51 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, SMESH::SMESH_Mesh_var mesh; { // open new scope to dump "MakeMesh" command // and then "GetGroups" using SMESH_Mesh::GetGroups() - + TPythonDump pydump; // to prevent dump at mesh creation mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - - if ( mesh_i ) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - translate(anElementsId, theVector, - false, theCopyGroups, & mesh_i->GetImpl()); + + TIDSortedElemSet elements; + if ( mesh_i && + idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + { + translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } if ( !myPreviewMode ) { pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( " - << theObject << ", " - << theVector << ", " + << theObject << ", " + << theVector << ", " << theCopyGroups << ", '" - << theMeshName << "' )"; + << theMeshName << "' )"; } } - - //dump "GetGroups" - if(!myPreviewMode && mesh_i) + + // dump "GetGroups" + if (!myPreviewMode && mesh_i) mesh_i->GetGroups(); - + return mesh._retn(); } //======================================================================= //function : rotate -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements, +SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, const SMESH::AxisStruct & theAxis, CORBA::Double theAngle, CORBA::Boolean theCopy, - const bool theMakeGroups, + bool theMakeGroups, ::SMESH_Mesh* theTargetMesh) { initData(); - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, GetMeshDS(), elements); + if ( theTargetMesh ) + theCopy = false; gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z ); gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz ); @@ -2926,13 +3824,43 @@ SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements, gp_Trsf aTrsf; aTrsf.SetRotation( gp_Ax1( P, V ), theAngle); - ::SMESH_MeshEditor anEditor( myMesh ); + TIDSortedElemSet copyElements; + TIDSortedElemSet* workElements = &theElements; + TPreviewMesh tmpMesh; + SMESH_Mesh* mesh = myMesh; + + if ( myPreviewMode ) { + tmpMesh.Copy( theElements, copyElements ); + if ( !theCopy && !theTargetMesh ) + { + TIDSortedElemSet elemsAround, elemsAroundCopy; + getElementsAround( theElements, GetMeshDS(), elemsAround ); + tmpMesh.Copy( elemsAround, elemsAroundCopy); + } + mesh = &tmpMesh; + workElements = ©Elements; + theMakeGroups = false; + } + ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + + if(theCopy || myPreviewMode) + storeResult(myEditor); - if(theCopy) { - storeResult(anEditor); + if ( !myPreviewMode ) + { + if ( theTargetMesh ) + { + theTargetMesh->GetMeshDS()->Modified(); + } + else + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } } + return theMakeGroups ? getGroups(groupIds.get()) : 0; } @@ -2946,18 +3874,19 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements, CORBA::Double theAngle, CORBA::Boolean theCopy) { - if ( !myPreviewMode ) { + if (!myPreviewMode) { TPythonDump() << this << ".Rotate( " << theIDsOfElements << ", " - << theAxis << ", " - << theAngle << ", " - << theCopy << " )"; + << theAxis << ", " + << TVar( theAngle ) << ", " + << theCopy << " )"; + } + if (theIDsOfElements.length() > 0) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + rotate(elements,theAxis,theAngle,theCopy,false); } - rotate(theIDsOfElements, - theAxis, - theAngle, - theCopy, - false); } //======================================================================= @@ -2966,28 +3895,26 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements, //======================================================================= void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngle, - CORBA::Boolean theCopy) + const SMESH::AxisStruct & theAxis, + CORBA::Double theAngle, + CORBA::Boolean theCopy) { if ( !myPreviewMode ) { TPythonDump() << this << ".RotateObject( " - << theObject << ", " - << theAxis << ", " - << theAngle << ", " - << theCopy << " )"; + << theObject << ", " + << theAxis << ", " + << TVar( theAngle ) << ", " + << theCopy << " )"; } - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotate(anElementsId, - theAxis, - theAngle, - theCopy, - false); + TIDSortedElemSet elements; + bool emptyIfIsMesh = myPreviewMode ? false : true; + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) + rotate(elements,theAxis,theAngle,theCopy,false); } //======================================================================= //function : RotateMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -2995,21 +3922,28 @@ SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements, const SMESH::AxisStruct& theAxis, CORBA::Double theAngle) { - SMESH::ListOfGroups * aGroups = rotate(theIDsOfElements,theAxis,theAngle,true,true); - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = 0; + if (theIDsOfElements.length() > 0) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + aGroups = rotate(elements,theAxis,theAngle,true,true); + } + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); aPythonDump << this << ".RotateMakeGroups( " << theIDsOfElements << ", " - << theAxis << ", " - << theAngle << " )"; + << theAxis << ", " + << TVar( theAngle ) << " )"; } return aGroups; } //======================================================================= //function : RotateObjectMakeGroups -//purpose : +//purpose : //======================================================================= SMESH::ListOfGroups* @@ -3017,26 +3951,29 @@ SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::AxisStruct& theAxis, CORBA::Double theAngle) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = rotate(anElementsId,theAxis,theAngle,true,true); - - if ( !myPreviewMode ) { - TPythonDump aPythonDump; - DumpGroupsList(aPythonDump,aGroups); + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = 0; + TIDSortedElemSet elements; + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + aGroups = rotate(elements, theAxis, theAngle, true, true); + + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); aPythonDump << this << ".RotateObjectMakeGroups( " - << theObject << ", " - << theAxis << ", " - << theAngle << " )"; + << theObject << ", " + << theAxis << ", " + << TVar( theAngle ) << " )"; } return aGroups; } //======================================================================= //function : RotateMakeMesh -//purpose : +//purpose : //======================================================================= -SMESH::SMESH_Mesh_ptr +SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements, const SMESH::AxisStruct& theAxis, CORBA::Double theAngleInRadians, @@ -3048,40 +3985,43 @@ SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements, { // open new scope to dump "MakeMesh" command // and then "GetGroups" using SMESH_Mesh::GetGroups() - + TPythonDump pydump; // to prevent dump at mesh creation mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - - if ( mesh_i ) { - rotate(theIDsOfElements, theAxis, theAngleInRadians, + + if ( mesh_i && theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + rotate(elements, theAxis, theAngleInRadians, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } if ( !myPreviewMode ) { pydump << mesh << " = " << this << ".RotateMakeMesh( " - << theIDsOfElements << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theCopyGroups << ", '" - << theMeshName << "' )"; + << theIDsOfElements << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << theCopyGroups << ", '" + << theMeshName << "' )"; } } - - //dump "GetGroups" - if(!myPreviewMode && mesh_i) + + // dump "GetGroups" + if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 ) mesh_i->GetGroups(); - + return mesh._retn(); } //======================================================================= //function : RotateObjectMakeMesh -//purpose : +//purpose : //======================================================================= -SMESH::SMESH_Mesh_ptr +SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, const SMESH::AxisStruct& theAxis, CORBA::Double theAngleInRadians, @@ -3090,108 +4030,220 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, { SMESH::SMESH_Mesh_var mesh; SMESH_Mesh_i* mesh_i; - + {// open new scope to dump "MakeMesh" command // and then "GetGroups" using SMESH_Mesh::GetGroups() - + TPythonDump pydump; // to prevent dump at mesh creation mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - - if (mesh_i ) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotate(anElementsId, theAxis, theAngleInRadians, + + TIDSortedElemSet elements; + if (mesh_i && + idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + { + rotate(elements, theAxis, theAngleInRadians, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } if ( !myPreviewMode ) { pydump << mesh << " = " << this << ".RotateObjectMakeMesh( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theCopyGroups << ", '" - << theMeshName << "' )"; + << theObject << ", " + << theAxis << ", " + << TVar( theAngleInRadians ) << ", " + << theCopyGroups << ", '" + << theMeshName << "' )"; } } - - //dump "GetGroups" - if(!myPreviewMode && mesh_i) + + // dump "GetGroups" + if (!myPreviewMode && mesh_i) mesh_i->GetGroups(); - + return mesh._retn(); } //======================================================================= -//function : FindCoincidentNodes +//function : scale //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance, - SMESH::array_of_long_array_out GroupsOfNodes) +SMESH::ListOfGroups* +SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact, + CORBA::Boolean theCopy, + bool theMakeGroups, + ::SMESH_Mesh* theTargetMesh) { initData(); + if ( theScaleFact.length() < 1 ) + THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM); + if ( theScaleFact.length() == 2 ) + THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM); - ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - ::SMESH_MeshEditor anEditor( myMesh ); - set nodes; // no input nodes - anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); + if ( theTargetMesh ) + theCopy = false; - 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(); + TIDSortedElemSet elements; + bool emptyIfIsMesh = myPreviewMode ? false : true; + if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) + return 0; + + double S[3] = { + theScaleFact[0], + (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1], + (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2], + }; + double tol = std::numeric_limits::max(); + gp_Trsf aTrsf; + aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), + 0, S[1], 0, thePoint.y * (1-S[1]), + 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol); + + TIDSortedElemSet copyElements; + TPreviewMesh tmpMesh; + TIDSortedElemSet* workElements = &elements; + SMESH_Mesh* mesh = myMesh; + + if ( myPreviewMode ) + { + tmpMesh.Copy( elements, copyElements); + if ( !theCopy && !theTargetMesh ) + { + TIDSortedElemSet elemsAround, elemsAroundCopy; + getElementsAround( elements, GetMeshDS(), elemsAround ); + tmpMesh.Copy( elemsAround, elemsAroundCopy); + } + mesh = &tmpMesh; + workElements = & copyElements; + theMakeGroups = false; } - TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( " - << Tolerance << " )"; + + ::SMESH_MeshEditor::PGroupIDs groupIds = + myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + + if(theCopy || myPreviewMode ) + storeResult(myEditor); + + if ( !myPreviewMode ) + { + if ( theTargetMesh ) + { + theTargetMesh->GetMeshDS()->Modified(); + } + else + { + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } + } + + return theMakeGroups ? getGroups(groupIds.get()) : 0; } //======================================================================= -//function : FindCoincidentNodesOnPart +//function : Scale //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject, - CORBA::Double Tolerance, - SMESH::array_of_long_array_out GroupsOfNodes) + +void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact, + CORBA::Boolean theCopy) { - initData(); - SMESH::long_array_var aElementsId = theObject->GetIDs(); + if ( !myPreviewMode ) { + TPythonDump() << this << ".Scale( " + << theObject << ", " + << thePoint << ", " + << TVar( theScaleFact ) << ", " + << theCopy << " )"; + } + scale(theObject, thePoint, theScaleFact, theCopy, false); +} - SMESHDS_Mesh* aMesh = GetMeshDS(); - set 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); - } +//======================================================================= +//function : ScaleMakeGroups +//purpose : +//======================================================================= + +SMESH::ListOfGroups* +SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact) +{ + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + + SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true); + if (!myPreviewMode) { + DumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".Scale(" + << theObject << "," + << thePoint << "," + << TVar( theScaleFact ) << ",True,True)"; } - else { - for(int i = 0; i < aElementsId->length(); i++) { - CORBA::Long ind = aElementsId[i]; - const SMDS_MeshElement * elem = aMesh->FindElement(ind); - if(elem) { - SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); - while ( nIt->more() ) - nodes.insert( nodes.end(),static_cast(nIt->next())); - } + return aGroups; +} + + +//======================================================================= +//function : ScaleMakeMesh +//purpose : +//======================================================================= + +SMESH::SMESH_Mesh_ptr +SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact, + CORBA::Boolean theCopyGroups, + const char* theMeshName) +{ + SMESH_Mesh_i* mesh_i; + SMESH::SMESH_Mesh_var mesh; + { // open new scope to dump "MakeMesh" command + // and then "GetGroups" using SMESH_Mesh::GetGroups() + + TPythonDump pydump; // to prevent dump at mesh creation + mesh = makeMesh( theMeshName ); + mesh_i = SMESH::DownCast( mesh ); + + if ( mesh_i ) + { + scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl()); + mesh_i->CreateGroupServants(); } + if ( !myPreviewMode ) + pydump << mesh << " = " << this << ".ScaleMakeMesh( " + << theObject << ", " + << thePoint << ", " + << TVar( theScaleFact ) << ", " + << theCopyGroups << ", '" + << theMeshName << "' )"; } - - + + // dump "GetGroups" + if (!myPreviewMode && mesh_i) + mesh_i->GetGroups(); + + return mesh._retn(); +} + + +//======================================================================= +//function : FindCoincidentNodes +//purpose : +//======================================================================= + +void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes) +{ + initData(); + ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - ::SMESH_MeshEditor anEditor( myMesh ); - if(!nodes.empty()) - anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); - + TIDSortedNodeSet nodes; // no input nodes + myEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); + GroupsOfNodes = new SMESH::array_of_long_array; GroupsOfNodes->length( aListOfListOfNodes.size() ); ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); @@ -3203,11 +4255,92 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) aGroup[ j ] = (*lIt)->GetID(); } + TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( " + << 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(); + + TIDSortedNodeSet nodes; + idSourceToNodeSet( theObject, GetMeshDS(), nodes ); + + ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; + if(!nodes.empty()) + myEditor.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(); + } TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( " <length( aListOfListOfNodes.size() ); + ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); + for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) + { + list< const SMDS_MeshNode* >& aListOfNodes = *llIt; + list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; + SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ]; + aGroup.length( aListOfNodes.size() ); + for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) + aGroup[ j ] = (*lIt)->GetID(); + } + TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( " + << theObject<<", " + << theTolerance << ", " + << theExceptSubMeshOrGroups << " )"; +} + //======================================================================= //function : MergeNodes //purpose : @@ -3240,10 +4373,11 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN if ( i > 0 ) aTPythonDump << ", "; aTPythonDump << aNodeGroup; } - ::SMESH_MeshEditor anEditor( myMesh ); - anEditor.MergeNodes( aListOfListOfNodes ); + myEditor.MergeNodes( aListOfListOfNodes ); aTPythonDump << "])"; + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); } //======================================================================= @@ -3251,11 +4385,13 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN //purpose : //======================================================================= void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject, - SMESH::array_of_long_array_out GroupsOfElementsID) + 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) ) { + + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject); + if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) ) + { typedef list TListOfIDs; set elems; SMESH::long_array_var aElementsId = theObject->GetIDs(); @@ -3265,13 +4401,12 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObj CORBA::Long anID = aElementsId[i]; const SMDS_MeshElement * elem = aMesh->FindElement(anID); if (elem) { - elems.insert(elem); + elems.insert(elem); } } ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; - ::SMESH_MeshEditor anEditor( myMesh ); - anEditor.FindEqualElements( elems, aListOfListOfElementsID ); + myEditor.FindEqualElements( elems, aListOfListOfElementsID ); GroupsOfElementsID = new SMESH::array_of_long_array; GroupsOfElementsID->length( aListOfListOfElementsID.size() ); @@ -3283,12 +4418,12 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObj aGroup.length( listOfIDs.size() ); TListOfIDs::iterator idIt = listOfIDs.begin(); for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) { - aGroup[ k ] = *idIt; + aGroup[ k ] = *idIt; } } - TPythonDump() << "equal_elements = " << this << ".FindEqualElements( " - <GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); aTPythonDump << "] )"; } @@ -3335,12 +4471,91 @@ void SMESH_MeshEditor_i::MergeEqualElements() { initData(); - ::SMESH_MeshEditor anEditor( myMesh ); - anEditor.MergeEqualElements(); + myEditor.MergeEqualElements(); + + myMesh->GetMeshDS()->Modified(); TPythonDump() << this << ".MergeEqualElements()"; } +//============================================================================= +/*! + * Move the node to a given point + */ +//============================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, + CORBA::Double x, + CORBA::Double y, + CORBA::Double z) +{ + initData(/*deleteSearchers=*/false); + + const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID ); + if ( !node ) + return false; + + if ( theNodeSearcher ) + theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other + + 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(); + SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node); + for ( ; nIt != linkedNodes.end(); ++nIt ) + { + SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt )); + tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2); + } + // move copied node + if ( nodeCpy1 ) + tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z); + // fill preview data + storeResult( myEditor ); + } + else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly + theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z )); + else + GetMeshDS()->MoveNode(node, x, y, z); + + if ( !myPreviewMode ) + { + // Update Python script + TPythonDump() << "isDone = " << this << ".MoveNode( " + << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )"; + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); + } + + return true; +} + +//================================================================================ +/*! + * \brief Return ID of node closest to a given point + */ +//================================================================================ + +CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x, + CORBA::Double y, + CORBA::Double z) +{ + theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other + + if ( !theNodeSearcher ) { + theNodeSearcher = myEditor.GetNodeSearcher(); + } + gp_Pnt p( x,y,z ); + if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p )) + return node->GetID(); + + return 0; +} + //================================================================================ /*! * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else @@ -3353,24 +4568,23 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, 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 + // We keep theNodeSearcher until any mesh modification: + // 1) initData() deletes theNodeSearcher at any edition, + // 2) TSearchersDeleter - at any mesh compute event and mesh change - initData(); + initData(/*deleteSearchers=*/false); + + theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other int nodeID = theNodeID; const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID ); - if ( !node ) + if ( !node ) // preview moving node { - static TNodeSearcherDeleter deleter; - deleter.Set( myMesh ); - if ( !myNodeSearcher ) { - ::SMESH_MeshEditor anEditor( myMesh ); - myNodeSearcher = anEditor.GetNodeSearcher(); + if ( !theNodeSearcher ) { + theNodeSearcher = myEditor.GetNodeSearcher(); } gp_Pnt p( x,y,z ); - node = myNodeSearcher->FindClosestTo( p ); + node = theNodeSearcher->FindClosestTo( p ); } if ( node ) { nodeID = node->GetID(); @@ -3383,7 +4597,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, TIDSortedElemSet::iterator nIt = linkedNodes.begin(); for ( ; nIt != linkedNodes.end(); ++nIt ) { - SMDS_MeshEdge edge( node, cast2Node( *nIt )); + SMDS_LinearEdge edge( node, cast2Node( *nIt )); tmpMesh.Copy( &edge ); } // move copied node @@ -3391,8 +4605,11 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, if ( node ) tmpMesh.GetMeshDS()->MoveNode(node, x, y, z); // fill preview data - ::SMESH_MeshEditor anEditor( & tmpMesh ); - storeResult( anEditor ); + storeResult( myEditor ); + } + else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly + { + theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z )); } else { @@ -3400,15 +4617,137 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, } } - if ( !myPreviewMode ) { + if ( !myPreviewMode ) + { TPythonDump() << "nodeID = " << this << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z << ", " << nodeID << " )"; + + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); } return nodeID; } +//======================================================================= +/*! + * Return elements of given type where the given point is IN or ON. + * + * 'ALL' type means elements of any type excluding nodes + */ +//======================================================================= + +SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, + CORBA::Double y, + CORBA::Double z, + SMESH::ElementType type) +{ + SMESH::long_array_var res = new SMESH::long_array; + vector< const SMDS_MeshElement* > foundElems; + + theSearchersDeleter.Set( myMesh ); + if ( !theElementSearcher ) { + theElementSearcher = myEditor.GetElementSearcher(); + } + theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ), + SMDSAbs_ElementType( type ), + foundElems); + res->length( foundElems.size() ); + for ( int i = 0; i < foundElems.size(); ++i ) + res[i] = foundElems[i]->GetID(); + + if ( !myPreviewMode ) // call from tui + TPythonDump() << "res = " << this << ".FindElementsByPoint( " + << x << ", " + << y << ", " + << z << ", " + << type << " )"; + + return res._retn(); +} + +//======================================================================= +//function : FindAmongElementsByPoint +//purpose : Searching among the given elements, return elements of given type +// where the given point is IN or ON. +// 'ALL' type means elements of any type excluding nodes +//======================================================================= + +SMESH::long_array* +SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs, + CORBA::Double x, + CORBA::Double y, + CORBA::Double z, + SMESH::ElementType type) +{ + SMESH::long_array_var res = new SMESH::long_array; + + SMESH::array_of_ElementType_var types = elementIDs->GetTypes(); + if ( types->length() == 1 && // a part contains only nodes or 0D elements + ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) && + type != types[0] ) // but search of elements of dim > 0 + return res._retn(); + + if ( SMESH::DownCast( elementIDs )) // elementIDs is the whole mesh + return FindElementsByPoint( x,y,z, type ); + + TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes + + theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type )); + if ( !theElementSearcher ) + { + // create a searcher from elementIDs + SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh(); + SMESHDS_Mesh* meshDS = SMESH::DownCast( mesh )->GetImpl().GetMeshDS(); + + if ( !idSourceToSet( elementIDs, meshDS, elements, + SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true)) + return res._retn(); + + typedef SMDS_SetIterator TIter; + SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() )); + + theElementSearcher = myEditor.GetElementSearcher(elemsIt); + } + + vector< const SMDS_MeshElement* > foundElems; + + theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ), + SMDSAbs_ElementType( type ), + foundElems); + res->length( foundElems.size() ); + for ( int i = 0; i < foundElems.size(); ++i ) + res[i] = foundElems[i]->GetID(); + + if ( !myPreviewMode ) // call from tui + TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( " + << elementIDs << ", " + << x << ", " + << y << ", " + << z << ", " + << type << " )"; + + return res._retn(); + +} +//======================================================================= +//function : GetPointState +//purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration. +// TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. +//======================================================================= + +CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x, + CORBA::Double y, + CORBA::Double z) +{ + theSearchersDeleter.Set( myMesh ); + if ( !theElementSearcher ) { + theElementSearcher = myEditor.GetElementSearcher(); + } + return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z ))); +} + //======================================================================= //function : convError //purpose : @@ -3419,16 +4758,16 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e ) { switch ( e ) { - RETCASE( SEW_OK ); - RETCASE( SEW_BORDER1_NOT_FOUND ); - RETCASE( SEW_BORDER2_NOT_FOUND ); - RETCASE( SEW_BOTH_BORDERS_NOT_FOUND ); - RETCASE( SEW_BAD_SIDE_NODES ); - RETCASE( SEW_VOLUMES_TO_SPLIT ); - RETCASE( SEW_DIFF_NB_OF_ELEMENTS ); - RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS ); - RETCASE( SEW_BAD_SIDE1_NODES ); - RETCASE( SEW_BAD_SIDE2_NODES ); + RETCASE( SEW_OK ); + RETCASE( SEW_BORDER1_NOT_FOUND ); + RETCASE( SEW_BORDER2_NOT_FOUND ); + RETCASE( SEW_BOTH_BORDERS_NOT_FOUND ); + RETCASE( SEW_BAD_SIDE_NODES ); + RETCASE( SEW_VOLUMES_TO_SPLIT ); + RETCASE( SEW_DIFF_NB_OF_ELEMENTS ); + RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS ); + RETCASE( SEW_BAD_SIDE1_NODES ); + RETCASE( SEW_BAD_SIDE2_NODES ); } return SMESH::SMESH_MeshEditor::SEW_OK; } @@ -3439,14 +4778,14 @@ static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Se //======================================================================= SMESH::SMESH_MeshEditor::Sew_Error - SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, - CORBA::Long SecondNodeID1, - CORBA::Long LastNodeID1, - CORBA::Long FirstNodeID2, - CORBA::Long SecondNodeID2, - CORBA::Long LastNodeID2, - CORBA::Boolean CreatePolygons, - CORBA::Boolean CreatePolyedrs) +SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, + CORBA::Long SecondNodeID1, + CORBA::Long LastNodeID1, + CORBA::Long FirstNodeID2, + CORBA::Long SecondNodeID2, + CORBA::Long LastNodeID2, + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs) { initData(); @@ -3478,9 +4817,8 @@ SMESH::SMESH_MeshEditor::Sew_Error << CreatePolygons<< ", " << CreatePolyedrs<< " )"; - ::SMESH_MeshEditor anEditor( myMesh ); SMESH::SMESH_MeshEditor::Sew_Error error = - convError( anEditor.SewFreeBorder (aBorderFirstNode, + convError( myEditor.SewFreeBorder (aBorderFirstNode, aBorderSecondNode, aBorderLastNode, aSide2FirstNode, @@ -3490,7 +4828,10 @@ SMESH::SMESH_MeshEditor::Sew_Error CreatePolygons, CreatePolyedrs) ); - storeResult(anEditor); + storeResult(myEditor); + + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); return error; } @@ -3534,9 +4875,8 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, << FirstNodeID2 << ", " << SecondNodeID2 << " )"; - ::SMESH_MeshEditor anEditor( myMesh ); SMESH::SMESH_MeshEditor::Sew_Error error = - convError( anEditor.SewFreeBorder (aBorderFirstNode, + convError( myEditor.SewFreeBorder (aBorderFirstNode, aBorderSecondNode, aBorderLastNode, aSide2FirstNode, @@ -3545,7 +4885,10 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, true, false, false) ); - storeResult(anEditor); + storeResult(myEditor); + + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); return error; } @@ -3593,9 +4936,8 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, << CreatePolygons << ", " << CreatePolyedrs << ") "; - ::SMESH_MeshEditor anEditor( myMesh ); SMESH::SMESH_MeshEditor::Sew_Error error = - convError( anEditor.SewFreeBorder (aBorderFirstNode, + convError( myEditor.SewFreeBorder (aBorderFirstNode, aBorderSecondNode, aBorderLastNode, aSide2FirstNode, @@ -3605,7 +4947,10 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, CreatePolygons, CreatePolyedrs) ); - storeResult(anEditor); + storeResult(myEditor); + + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); return error; } @@ -3652,15 +4997,17 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements, << NodeID2OfSide1ToMerge << ", " << NodeID2OfSide2ToMerge << ")"; - ::SMESH_MeshEditor anEditor( myMesh ); SMESH::SMESH_MeshEditor::Sew_Error error = - convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems, + convError( myEditor.SewSideElements (aSide1Elems, aSide2Elems, aFirstNode1ToMerge, aFirstNode2ToMerge, aSecondNode1ToMerge, aSecondNode2ToMerge)); - storeResult(anEditor); + storeResult(myEditor); + + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); return error; } @@ -3668,9 +5015,9 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements, //================================================================================ /*! * \brief Set new nodes for given element - * \param ide - element id - * \param newIDs - new node ids - * \retval CORBA::Boolean - true if result is OK + * \param ide - element id + * \param newIDs - new node ids + * \retval CORBA::Boolean - true if result is OK */ //================================================================================ @@ -3695,176 +5042,114 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide, } TPythonDump() << "isDone = " << this << ".ChangeElemNodes( " << ide << ", " << newIDs << " )"; -#ifdef _DEBUG_ - TPythonDump() << "print 'ChangeElemNodes: ', isDone"; -#endif - return GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 ); + MESSAGE("ChangeElementNodes"); + bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 ); + + myMesh->GetMeshDS()->Modified(); + if ( res ) + myMesh->SetIsModified( true ); + + return res; +} + +//======================================================================= +//function : ConvertToQuadratic +//purpose : +//======================================================================= + +void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d) +{ + myEditor.ConvertToQuadratic(theForce3d); + TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )"; + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); +} + +//======================================================================= +//function : ConvertFromQuadratic +//purpose : +//======================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic() +{ + CORBA::Boolean isDone = myEditor.ConvertFromQuadratic(); + TPythonDump() << this << ".ConvertFromQuadratic()"; + myMesh->GetMeshDS()->Modified(); + if ( isDone ) + myMesh->SetIsModified( true ); + return isDone; } - //================================================================================ /*! - * \brief Update myLastCreated* or myPreviewData - * \param anEditor - it contains last modification results + * \brief Makes a part of the mesh quadratic */ //================================================================================ -void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor) +void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d, + SMESH::SMESH_IDSource_ptr theObject) + throw (SALOME::SALOME_Exception) { - if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- + Unexpect aCatch(SALOME_SalomeException); + TPythonDump pyDump; + TIDSortedElemSet elems; + if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true )) + { + if ( elems.empty() ) + { + ConvertToQuadratic( theForce3d ); + } + else if ( (*elems.begin())->GetType() == SMDSAbs_Node ) + { + THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM); + } + else + { + myEditor.ConvertToQuadratic(theForce3d, elems); + } + } + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); - list aNodesConnectivity; - typedef map TNodesMap; - TNodesMap nodesMap; + pyDump << this << ".ConvertToQuadraticObject( "<( 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( 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++; +//================================================================================ +/*! + * \brief Makes a part of the mesh linear + */ +//================================================================================ +void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + TPythonDump pyDump; + TIDSortedElemSet elems; + if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true )) + { + if ( elems.empty() ) + { + ConvertFromQuadratic(); + } + else if ( (*elems.begin())->GetType() == SMDSAbs_Node ) + { + THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM); + } + else + { + myEditor.ConvertFromQuadratic(elems); } - myPreviewData->nodesXYZ.length( j ); - - // filling the elements connectivities - list::iterator aConnIter = aNodesConnectivity.begin(); - myPreviewData->elementConnectivities.length(aNodesConnectivity.size()); - for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ ) - myPreviewData->elementConnectivities[i] = *aConnIter; - - return; } + myMesh->GetMeshDS()->Modified(); + myMesh->SetIsModified( true ); - { - // add new nodes into myLastCreatedNodes - const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes(); - myLastCreatedNodes->length(aSeq.Length()); - for(int i=0; iGetID(); - } - { - // add new elements into myLastCreatedElems - const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems(); - myLastCreatedElems->length(aSeq.Length()); - for(int i=0; iGetID(); - } -} - -//================================================================================ -/*! - * Return data of mesh edition preview - */ -//================================================================================ - -SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() -{ - return myPreviewData._retn(); -} - -//================================================================================ -/*! - * \brief Returns list of it's IDs of created nodes - * \retval SMESH::long_array* - list of node ID - */ -//================================================================================ - -SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes() -{ - return myLastCreatedNodes._retn(); -} - -//================================================================================ -/*! - * \brief Returns list of it's IDs of created elements - * \retval SMESH::long_array* - list of elements' ID - */ -//================================================================================ - -SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems() -{ - return myLastCreatedElems._retn(); -} - -//======================================================================= -//function : ConvertToQuadratic -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d) -{ - ::SMESH_MeshEditor anEditor( myMesh ); - anEditor.ConvertToQuadratic(theForce3d); - TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )"; -} - -//======================================================================= -//function : ConvertFromQuadratic -//purpose : -//======================================================================= - -CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic() -{ - ::SMESH_MeshEditor anEditor( myMesh ); - CORBA::Boolean isDone = anEditor.ConvertFromQuadratic(); - TPythonDump() << this << ".ConvertFromQuadratic()"; - return isDone; + pyDump << this << ".ConvertFromQuadraticObject( "<GetCurrentStudy(); SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh ); gen->SetName( meshSO, theMeshName, "Mesh" ); - - SALOMEDS::StudyBuilder_var builder = study->NewBuilder(); - SALOMEDS::GenericAttribute_var anAttr - = builder->FindOrCreateAttribute( meshSO, "AttributePixMap" ); - SALOMEDS::AttributePixMap::_narrow( anAttr )->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); + gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED"); return mesh._retn(); } @@ -3887,7 +5168,7 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName) //function : DumpGroupsList //purpose : //======================================================================= -void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython, +void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython, const SMESH::ListOfGroups * theGroupList) { bool isDumpGroupList = theGroupList && theGroupList->length() > 0; @@ -3896,24 +5177,63 @@ void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPytho } } +//================================================================================ +/*! + \brief Generates the unique group name. + \param thePrefix name prefix + \return unique name +*/ +//================================================================================ +string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) +{ + SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); + set groupNames; + + // Get existing group names + for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = groups[i]; + if (CORBA::is_nil(aGroup)) + continue; + + groupNames.insert(aGroup->GetName()); + } + + // Find new name + string name = thePrefix; + int index = 0; + + while (!groupNames.insert(name).second) { + if (index == 0) { + name += "_1"; + } + else { + TCollection_AsciiString nbStr(index+1); + name.resize( name.rfind('_')+1 ); + name += nbStr.ToCString(); + } + ++index; + } + + return name; +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements \param theNodes - identifiers of nodes to be doubled - \param theModifiedElems - identifiers of elements to be updated by the new (doubled) - nodes. If list of element identifiers is empty then nodes are doubled but + \param theModifiedElems - identifiers of elements to be updated by the new (doubled) + nodes. If list of element identifiers is empty then nodes are doubled but they not assigned to elements \return TRUE if operation has been completed successfully, FALSE otherwise \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups() */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes, +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes, const SMESH::long_array& theModifiedElems ) { initData(); - ::SMESH_MeshEditor aMeshEditor( myMesh ); list< int > aListOfNodes; int i, n; for ( i = 0, n = theNodes.length(); i < n; i++ ) @@ -3923,9 +5243,15 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode for ( i = 0, n = theModifiedElems.length(); i < n; i++ ) aListOfElems.push_back( theModifiedElems[ i ] ); - bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems ); + bool aResult = myEditor.DoubleNodes( aListOfNodes, aListOfElems ); - storeResult( aMeshEditor) ; + myMesh->GetMeshDS()->Modified(); + storeResult( myEditor) ; + if ( aResult ) + myMesh->SetIsModified( true ); + + // Update Python script + TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )"; return aResult; } @@ -3941,13 +5267,20 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId, +CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId, const SMESH::long_array& theModifiedElems ) { SMESH::long_array_var aNodes = new SMESH::long_array; aNodes->length( 1 ); aNodes[ 0 ] = theNodeId; - return DoubleNodes( aNodes, theModifiedElems ); + + TPythonDump pyDump; // suppress dump by the next line + + CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems ); + + pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )"; + + return done; } //================================================================================ @@ -3961,9 +5294,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeI */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( - SMESH::SMESH_GroupBase_ptr theNodes, - SMESH::SMESH_GroupBase_ptr theModifiedElems ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ) { if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE ) return false; @@ -3972,13 +5304,68 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( SMESH::long_array_var aModifiedElems; if ( !CORBA::is_nil( theModifiedElems ) ) aModifiedElems = theModifiedElems->GetListOfID(); - else + else { aModifiedElems = new SMESH::long_array; aModifiedElems->length( 0 ); } - return DoubleNodes( aNodes, aModifiedElems ); + TPythonDump pyDump; // suppress dump by the next line + + bool done = DoubleNodes( aNodes, aModifiedElems ); + + pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )"; + + return done; +} + +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup(), but returns a new group with newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ +SMESH::SMESH_Group_ptr +SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ) +{ + SMESH::SMESH_Group_var aNewGroup; + + if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE ) + return aNewGroup._retn(); + + // Duplicate nodes + SMESH::long_array_var aNodes = theNodes->GetListOfID(); + SMESH::long_array_var aModifiedElems; + if ( !CORBA::is_nil( theModifiedElems ) ) + aModifiedElems = theModifiedElems->GetListOfID(); + else { + aModifiedElems = new SMESH::long_array; + aModifiedElems->length( 0 ); + } + + TPythonDump pyDump; // suppress dump by the next line + + bool aResult = DoubleNodes( aNodes, aModifiedElems ); + if ( aResult ) + { + // Create group with newly created nodes + SMESH::long_array_var anIds = GetLastCreatedNodes(); + if (anIds->length() > 0) { + string anUnindexedName (theNodes->GetName()); + string aNewName = generateGroupName(anUnindexedName + "_double"); + aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); + aNewGroup->Add(anIds); + pyDump << aNewGroup << " = "; + } + } + + pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", " + << theModifiedElems << " )"; + + return aNewGroup._retn(); } //================================================================================ @@ -3992,13 +5379,11 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( - const SMESH::ListOfGroups& theNodes, - const SMESH::ListOfGroups& theModifiedElems ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes, + const SMESH::ListOfGroups& theModifiedElems ) { initData(); - ::SMESH_MeshEditor aMeshEditor( myMesh ); std::list< int > aNodes; int i, n, j, m; @@ -4025,9 +5410,899 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( } } - bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems ); + bool aResult = myEditor.DoubleNodes( aNodes, anElems ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + if ( aResult ) + myMesh->SetIsModified( true ); + + + TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )"; + + return aResult; +} + +//================================================================================ +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroups(), but returns a new group with newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroups() + */ +//================================================================================ + +SMESH::SMESH_Group_ptr +SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes, + const SMESH::ListOfGroups& theModifiedElems ) +{ + SMESH::SMESH_Group_var aNewGroup; + + TPythonDump pyDump; // suppress dump by the next line + + bool aResult = DoubleNodeGroups( theNodes, theModifiedElems ); + + if ( aResult ) + { + // Create group with newly created nodes + SMESH::long_array_var anIds = GetLastCreatedNodes(); + if (anIds->length() > 0) { + string anUnindexedName (theNodes[0]->GetName()); + string aNewName = generateGroupName(anUnindexedName + "_double"); + aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); + aNewGroup->Add(anIds); + pyDump << aNewGroup << " = "; + } + } + + pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", " + << theModifiedElems << " )"; + + return aNewGroup._retn(); +} + + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - the list of elements (edges or faces) to be replicated + The nodes for duplication could be found from these elements + \param theNodesNot - list of nodes to NOT replicate + \param theAffectedElems - the list of elements (cells and edges) to which the + replicated nodes should be associated to. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodeGroup(), DoubleNodeGroups() +*/ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + const SMESH::long_array& theAffectedElems ) + +{ + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All); + arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node); + arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All); + + bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + if ( aResult ) + myMesh->SetIsModified( true ); + + // Update Python script + TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", " + << theNodesNot << ", " << theAffectedElems << " )"; + return aResult; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - the list of elements (edges or faces) to be replicated + The nodes for duplication could be found from these elements + \param theNodesNot - list of nodes to NOT replicate + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion() +*/ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + GEOM::GEOM_Object_ptr theShape ) + +{ + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes; + arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All); + arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node); + + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape ); + bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + if ( aResult ) + myMesh->SetIsModified( true ); + + // Update Python script + TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", " + << theNodesNot << ", " << theShape << " )"; + return aResult; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - group of of elements (edges or faces) to be replicated + \param theNodesNot - group of nodes not to replicated + \param theAffectedElems - group of elements to which the replicated nodes + should be associated to. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodes(), DoubleNodeGroups() +*/ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems) +{ + if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) + return false; + + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All ); + + bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + if ( aResult ) + myMesh->SetIsModified( true ); + + // Update Python script + TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", " + << theNodesNot << ", " << theAffectedElems << " )"; + return aResult; +} + +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ +SMESH::SMESH_Group_ptr +SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems) +{ + TPythonDump pyDump; + SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems, + theNodesNot, + theAffectedElems, + true, false ); + SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in(); + SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup ); + + pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( " + << theElems << ", " + << theNodesNot << ", " + << theAffectedElems << " )"; + + return elemGroup._retn(); +} + +SMESH::ListOfGroups* +SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems, + CORBA::Boolean theElemGroupNeeded, + CORBA::Boolean theNodeGroupNeeded) +{ + SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup; + SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups(); + aTwoGroups->length( 2 ); + + if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) + return aTwoGroups._retn(); + + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All ); + + + bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( myEditor) ; + myMesh->GetMeshDS()->Modified(); + + TPythonDump pyDump; + + if ( aResult ) + { + myMesh->SetIsModified( true ); + + // Create group with newly created elements + CORBA::String_var elemGroupName = theElems->GetName(); + string aNewName = generateGroupName( string(elemGroupName.in()) + "_double"); + if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded ) + { + SMESH::long_array_var anIds = GetLastCreatedElems(); + SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true); + aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str()); + aNewElemGroup->Add(anIds); + } + if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded ) + { + SMESH::long_array_var anIds = GetLastCreatedNodes(); + aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); + aNewNodeGroup->Add(anIds); + } + } + + // Update Python script + + pyDump << "[ "; + if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, "; + else pyDump << aNewElemGroup << ", "; + if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = "; + else pyDump << aNewNodeGroup << " ] = "; + + pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", " + << theNodesNot << ", " + << theAffectedElems << ", " + << theElemGroupNeeded << ", " + << theNodeGroupNeeded <<" )"; + + aTwoGroups[0] = aNewElemGroup._retn(); + aTwoGroups[1] = aNewNodeGroup._retn(); + return aTwoGroups._retn(); +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - group of of elements (edges or faces) to be replicated + \param theNodesNot - group of nodes not to replicated + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion() +*/ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + GEOM::GEOM_Object_ptr theShape ) + +{ + if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) + return false; + + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape ); + bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + if ( aResult ) + myMesh->SetIsModified( true ); + + // Update Python script + TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", " + << theNodesNot << ", " << theShape << " )"; + return aResult; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + This method provided for convenience works as DoubleNodes() described above. + \param theElems - list of groups of elements (edges or faces) to be replicated + \param theNodesNot - list of groups of nodes not to replicated + \param theAffectedElems - group of elements to which the replicated nodes + should be associated to. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew() +*/ +//================================================================================ + +static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList, + SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElemSet, + const bool theIsNodeGrp) +{ + for ( int i = 0, n = theGrpList.length(); i < n; i++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ]; + if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE + : aGrp->GetType() != SMESH::NODE ) ) + { + SMESH::long_array_var anIDs = aGrp->GetIDs(); + arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All ); + } + } +} + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems) +{ + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + listOfGroupToSet(theElems, aMeshDS, anElems, false ); + listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true ); + listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false ); + + bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + if ( aResult ) + myMesh->SetIsModified( true ); + + // Update Python script + TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", " + << &theNodesNot << ", " << &theAffectedElems << " )"; + return aResult; +} + +//================================================================================ +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements. + \param theElems - list of groups of elements (edges or faces) to be replicated + \param theNodesNot - list of groups of nodes not to replicated + \param theAffectedElems - group of elements to which the replicated nodes + should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroups() + */ +//================================================================================ + +SMESH::SMESH_Group_ptr +SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems) +{ + TPythonDump pyDump; + SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems, + theNodesNot, + theAffectedElems, + true, false ); + SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in(); + SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup ); + + pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( " + << theElems << ", " + << theNodesNot << ", " + << theAffectedElems << " )"; + + return elemGroup._retn(); +} + +SMESH::ListOfGroups* +SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems, + CORBA::Boolean theElemGroupNeeded, + CORBA::Boolean theNodeGroupNeeded) +{ + SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup; + SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups(); + aTwoGroups->length( 2 ); + + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + listOfGroupToSet(theElems, aMeshDS, anElems, false ); + listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true ); + listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false ); + + bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + TPythonDump pyDump; + if ( aResult ) + { + myMesh->SetIsModified( true ); + + // Create group with newly created elements + CORBA::String_var elemGroupName = theElems[0]->GetName(); + string aNewName = generateGroupName( string(elemGroupName.in()) + "_double"); + if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded ) + { + SMESH::long_array_var anIds = GetLastCreatedElems(); + SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true); + aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str()); + aNewElemGroup->Add(anIds); + } + if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded ) + { + SMESH::long_array_var anIds = GetLastCreatedNodes(); + aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); + aNewNodeGroup->Add(anIds); + } + } + + // Update Python script + + pyDump << "[ "; + if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, "; + else pyDump << aNewElemGroup << ", "; + if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = "; + else pyDump << aNewNodeGroup << " ] = "; + + pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", " + << &theNodesNot << ", " + << &theAffectedElems << ", " + << theElemGroupNeeded << ", " + << theNodeGroupNeeded << " )"; + + aTwoGroups[0] = aNewElemGroup._retn(); + aTwoGroups[1] = aNewNodeGroup._retn(); + return aTwoGroups._retn(); +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + This method provided for convenience works as DoubleNodes() described above. + \param theElems - list of groups of elements (edges or faces) to be replicated + \param theNodesNot - list of groups of nodes not to replicated + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion() +*/ +//================================================================================ + +CORBA::Boolean +SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + GEOM::GEOM_Object_ptr theShape ) +{ + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes; + listOfGroupToSet(theElems, aMeshDS, anElems,false ); + listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true ); + + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape ); + bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape ); + + storeResult( myEditor) ; + + myMesh->GetMeshDS()->Modified(); + if ( aResult ) + myMesh->SetIsModified( true ); + + // Update Python script + TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", " + << &theNodesNot << ", " << theShape << " )"; + return aResult; +} + +//================================================================================ +/*! + \brief Generated skin mesh (containing 2D cells) from 3D mesh + The created 2D mesh elements based on nodes of free faces of boundary volumes + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D() +{ + initData(); + + bool aResult = myEditor.Make2DMeshFrom3D(); + storeResult( myEditor) ; + myMesh->GetMeshDS()->Modified(); + TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()"; + return aResult; +} + +//================================================================================ +/*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * The flat elements are stored in groups of volumes. + * @param theDomains - list of groups of volumes + * @param createJointElems - if TRUE, create the elements + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains, + CORBA::Boolean createJointElems ) + throw (SALOME::SALOME_Exception) +{ + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + + vector domains; + domains.clear(); + + for ( int i = 0, n = theDomains.length(); i < n; i++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ]; + if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ ) + { +// if ( aGrp->GetType() != SMESH::VOLUME ) +// THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM); + TIDSortedElemSet domain; + domain.clear(); + domains.push_back(domain); + SMESH::long_array_var anIDs = aGrp->GetIDs(); + arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All ); + } + } + + bool aResult = myEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems ); + // TODO publish the groups of flat elements in study + + storeResult( myEditor) ; + myMesh->GetMeshDS()->Modified(); + + // Update Python script + TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains + << ", " << createJointElems << " )"; + return aResult; +} + +//================================================================================ +/*! + * \brief Double nodes on some external faces and create flat elements. + * Flat elements are mainly used by some types of mechanic calculations. + * + * Each group of the list must be constituted of faces. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * @param theGroupsOfFaces - list of groups of faces + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces ) +{ + initData(); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + + vector faceGroups; + faceGroups.clear(); + + for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ]; + if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) ) + { + TIDSortedElemSet faceGroup; + faceGroup.clear(); + faceGroups.push_back(faceGroup); + SMESH::long_array_var anIDs = aGrp->GetIDs(); + arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All ); + } + } + + bool aResult = myEditor.CreateFlatElementsOnFacesGroups( faceGroups ); + // TODO publish the groups of flat elements in study - storeResult( aMeshEditor) ; + storeResult( myEditor) ; + myMesh->GetMeshDS()->Modified(); + // Update Python script + TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )"; return aResult; } + +// issue 20749 =================================================================== +/*! + * \brief Creates missing boundary elements + * \param elements - elements whose boundary is to be checked + * \param dimension - defines type of boundary elements to create + * \param groupName - a name of group to store created boundary elements in, + * "" means not to create the group + * \param meshName - a name of new mesh to store created boundary elements in, + * "" means not to create the new mesh + * \param toCopyElements - if true, the checked elements will be copied into the new mesh + * \param toCopyExistingBondary - if true, not only new but also pre-existing + * boundary elements will be copied into the new mesh + * \param group - returns the create group, if any + * \retval SMESH::SMESH_Mesh - the mesh where elements were added to + */ +// ================================================================================ + +SMESH::SMESH_Mesh_ptr +SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, + SMESH::Bnd_Dimension dim, + const char* groupName, + const char* meshName, + CORBA::Boolean toCopyElements, + CORBA::Boolean toCopyExistingBondary, + SMESH::SMESH_Group_out group) +{ + initData(); + + if ( dim > SMESH::BND_1DFROM2D ) + THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM); + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + + SMESH::SMESH_Mesh_var mesh_var; + SMESH::SMESH_Group_var group_var; + + TPythonDump pyDump; + + TIDSortedElemSet elements; + SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume; + if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true )) + { + // mesh to fill in + mesh_var = + strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this()); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh_var ); + // other mesh + SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl(); + + // group of new boundary elements + SMESH_Group* smesh_group = 0; + if ( strlen(groupName) ) + { + group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName); + if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( group_var )) + smesh_group = group_i->GetSmeshGroup(); + } + + // do it + myEditor.MakeBoundaryMesh( elements, + ::SMESH_MeshEditor::Bnd_Dimension(dim), + smesh_group, + smesh_mesh, + toCopyElements, + toCopyExistingBondary); + storeResult( myEditor ); + + if ( smesh_mesh ) + smesh_mesh->GetMeshDS()->Modified(); + } + + const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" }; + + // result of MakeBoundaryMesh() is a tuple (mesh, group) + if ( mesh_var->_is_nil() ) + pyDump << myMesh_i->_this() << ", "; + else + pyDump << mesh_var << ", "; + if ( group_var->_is_nil() ) + pyDump << "_NoneGroup = "; // assignment to None is forbiden + else + pyDump << group_var << " = "; + pyDump << this << ".MakeBoundaryMesh( " + << idSource << ", " + << "SMESH." << dimName[int(dim)] << ", " + << "'" << groupName << "', " + << "'" << meshName<< "', " + << toCopyElements << ", " + << toCopyExistingBondary << ")"; + + group = group_var._retn(); + return mesh_var._retn(); +} + +//================================================================================ +/*! + * \brief Creates missing boundary elements + * \param dimension - defines type of boundary elements to create + * \param groupName - a name of group to store all boundary elements in, + * "" means not to create the group + * \param meshName - a name of a new mesh, which is a copy of the initial + * mesh + created boundary elements; "" means not to create the new mesh + * \param toCopyAll - if true, the whole initial mesh will be copied into + * the new mesh else only boundary elements will be copied into the new mesh + * \param groups - optional groups of elements to make boundary around + * \param mesh - returns the mesh where elements were added to + * \param group - returns the created group, if any + * \retval long - number of added boundary elements + */ +//================================================================================ + +CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, + const char* groupName, + const char* meshName, + CORBA::Boolean toCopyAll, + const SMESH::ListOfIDSources& groups, + SMESH::SMESH_Mesh_out mesh, + SMESH::SMESH_Group_out group) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + + initData(); + + if ( dim > SMESH::BND_1DFROM2D ) + THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM); + + // separate groups belonging to this and other mesh + SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources; + SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources; + groupsOfThisMesh->length( groups.length() ); + groupsOfOtherMesh->length( groups.length() ); + int nbGroups = 0, nbGroupsOfOtherMesh = 0; + for ( int i = 0; i < groups.length(); ++i ) + { + SMESH::SMESH_Mesh_var m = groups[i]->GetMesh(); + if ( myMesh_i != SMESH::DownCast( m )) + groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i]; + else + groupsOfThisMesh[ nbGroups++ ] = groups[i]; + if ( SMESH::DownCast( groups[i] )) + THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM); + } + groupsOfThisMesh->length( nbGroups ); + groupsOfOtherMesh->length( nbGroupsOfOtherMesh ); + + int nbAdded = 0; + TPythonDump pyDump; + + if ( nbGroupsOfOtherMesh > 0 ) + { + // process groups belonging to another mesh + SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh(); + SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor(); + nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll, + groupsOfOtherMesh, mesh, group ); + } + + SMESH::SMESH_Mesh_var mesh_var; + SMESH::SMESH_Group_var group_var; + + // get mesh to fill + mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() ); + const bool toCopyMesh = ( strlen( meshName ) > 0 ); + if ( toCopyMesh ) + { + if ( toCopyAll ) + mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var, + meshName, + /*toCopyGroups=*/false, + /*toKeepIDs=*/true); + else + mesh_var = makeMesh(meshName); + } + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh_var ); + SMESH_Mesh* tgtMesh = &mesh_i->GetImpl(); + + // source mesh + SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh; + SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); + + // group of boundary elements + SMESH_Group* smesh_group = 0; + SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face; + if ( strlen(groupName) ) + { + SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 ); + group_var = mesh_i->CreateGroup( groupType, groupName ); + if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( group_var )) + smesh_group = group_i->GetSmeshGroup(); + } + + TIDSortedElemSet elements; + + if ( groups.length() > 0 ) + { + for ( int i = 0; i < nbGroups; ++i ) + { + elements.clear(); + if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 )) + { + SMESH::Bnd_Dimension bdim = + ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D; + nbAdded += myEditor.MakeBoundaryMesh( elements, + ::SMESH_MeshEditor::Bnd_Dimension(bdim), + smesh_group, + tgtMesh, + /*toCopyElements=*/false, + /*toCopyExistingBondary=*/srcMesh != tgtMesh, + /*toAddExistingBondary=*/true, + /*aroundElements=*/true); + storeResult( myEditor ); + } + } + } + else + { + nbAdded += myEditor.MakeBoundaryMesh( elements, + ::SMESH_MeshEditor::Bnd_Dimension(dim), + smesh_group, + tgtMesh, + /*toCopyElements=*/false, + /*toCopyExistingBondary=*/srcMesh != tgtMesh, + /*toAddExistingBondary=*/true); + storeResult( myEditor ); + } + tgtMesh->GetMeshDS()->Modified(); + + const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" }; + + // result of MakeBoundaryElements() is a tuple (nb, mesh, group) + pyDump << "nbAdded, "; + if ( mesh_var->_is_nil() ) + pyDump << myMesh_i->_this() << ", "; + else + pyDump << mesh_var << ", "; + if ( group_var->_is_nil() ) + pyDump << "_NoneGroup = "; // assignment to None is forbiden + else + pyDump << group_var << " = "; + pyDump << this << ".MakeBoundaryElements( " + << "SMESH." << dimName[int(dim)] << ", " + << "'" << groupName << "', " + << "'" << meshName<< "', " + << toCopyAll << ", " + << groups << ")"; + + mesh = mesh_var._retn(); + group = group_var._retn(); + return nbAdded; +} diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index b127f2f89..15233798b 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_MeshEditor_i.hxx // Author : Nicolas REJNERI @@ -34,6 +35,7 @@ #include "SMESH_Mesh.hxx" #include "SMESH_PythonDump.hxx" +#include "SMESH_MeshEditor.hxx" #include class SMESH_MeshEditor; @@ -41,20 +43,30 @@ class SMESH_Mesh_i; class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor { - public: +public: SMESH_MeshEditor_i(SMESH_Mesh_i * theMesh, bool isPreview); virtual ~ SMESH_MeshEditor_i(); // --- CORBA + + /*! + * \brief Wrap a sequence of ids in a SMESH_IDSource + */ + SMESH::SMESH_IDSource_ptr MakeIDSource(const SMESH::long_array& IDsOfElements, + SMESH::ElementType type); CORBA::Boolean RemoveElements(const SMESH::long_array & IDsOfElements); CORBA::Boolean RemoveNodes(const SMESH::long_array & IDsOfNodes); + CORBA::Long RemoveOrphanNodes(); /*! * Methods for creation new elements. * Returns ID of created element or 0 if element not created */ CORBA::Long AddNode(CORBA::Double x, CORBA::Double y, CORBA::Double z); + CORBA::Long Add0DElement(CORBA::Long IDOfNode); + CORBA::Long AddBall(CORBA::Long IDOfNodem, CORBA::Double diameter) + throw (SALOME::SALOME_Exception); CORBA::Long AddEdge(const SMESH::long_array & IDsOfNodes); CORBA::Long AddFace(const SMESH::long_array & IDsOfNodes); CORBA::Long AddPolygonalFace(const SMESH::long_array & IDsOfNodes); @@ -112,6 +124,19 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean DeleteDiag(CORBA::Long NodeID1, CORBA::Long NodeID2); CORBA::Boolean Reorient(const SMESH::long_array & IDsOfElements); CORBA::Boolean ReorientObject(SMESH::SMESH_IDSource_ptr theObject); + /*! + * \brief Reorient faces contained in \a the2Dgroup. + * \param the2Dgroup - the mesh or its part to reorient + * \param theDirection - desired direction of normal of \a theFace + * \param theFace - ID of face whose orientation is checked. + * It can be < 1 then \a thePoint is used to find a face. + * \param thePoint - is used to find a face if \a theFace < 1. + * \return number of reoriented elements. + */ + CORBA::Long Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, + const SMESH::DirStruct& theDirection, + CORBA::Long theFace, + const SMESH::PointStruct& thePoint) throw (SALOME::SALOME_Exception); // Split/Join faces CORBA::Boolean TriToQuad (const SMESH::long_array & IDsOfElements, @@ -130,6 +155,8 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean Diag13); CORBA::Long BestSplit (CORBA::Long IDOfQuad, SMESH::NumericalFunctor_ptr Criterion); + void SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, + CORBA::Short methodFlags) throw (SALOME::SALOME_Exception); CORBA::Boolean Smooth(const SMESH::long_array & IDsOfElements, const SMESH::long_array & IDsOfFixedNodes, @@ -137,10 +164,10 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Double MaxAspectRatio, SMESH::SMESH_MeshEditor::Smooth_Method Method); CORBA::Boolean SmoothObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, - CORBA::Double MaxAspectRatio, - SMESH::SMESH_MeshEditor::Smooth_Method Method); + const SMESH::long_array & IDsOfFixedNodes, + CORBA::Long MaxNbOfIterations, + CORBA::Double MaxAspectRatio, + SMESH::SMESH_MeshEditor::Smooth_Method Method); CORBA::Boolean SmoothParametric(const SMESH::long_array & IDsOfElements, const SMESH::long_array & IDsOfFixedNodes, CORBA::Long MaxNbOfIterations, @@ -158,15 +185,20 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor SMESH::SMESH_MeshEditor::Smooth_Method Method, bool IsParametric); CORBA::Boolean smoothObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::long_array & IDsOfFixedNodes, - CORBA::Long MaxNbOfIterations, - CORBA::Double MaxAspectRatio, - SMESH::SMESH_MeshEditor::Smooth_Method Method, + const SMESH::long_array & IDsOfFixedNodes, + CORBA::Long MaxNbOfIterations, + CORBA::Double MaxAspectRatio, + SMESH::SMESH_MeshEditor::Smooth_Method Method, bool IsParametric); void ConvertToQuadratic(CORBA::Boolean Force3d); CORBA::Boolean ConvertFromQuadratic(); + void ConvertToQuadraticObject(CORBA::Boolean theForce3d, + SMESH::SMESH_IDSource_ptr theObject) + throw (SALOME::SALOME_Exception); + void ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject) + throw (SALOME::SALOME_Exception); void RenumberNodes(); void RenumberElements(); @@ -177,27 +209,35 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Long NbOfSteps, CORBA::Double Tolerance); void RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & Axis, - CORBA::Double AngleInRadians, - CORBA::Long NbOfSteps, - CORBA::Double Tolerance); + const SMESH::AxisStruct & Axis, + CORBA::Double AngleInRadians, + CORBA::Long NbOfSteps, + CORBA::Double Tolerance); void RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & Axis, - CORBA::Double AngleInRadians, - CORBA::Long NbOfSteps, - CORBA::Double Tolerance); + const SMESH::AxisStruct & Axis, + CORBA::Double AngleInRadians, + CORBA::Long NbOfSteps, + CORBA::Double Tolerance); void RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & Axis, - CORBA::Double AngleInRadians, - CORBA::Long NbOfSteps, - CORBA::Double Tolerance); + const SMESH::AxisStruct & Axis, + CORBA::Double AngleInRadians, + CORBA::Long NbOfSteps, + CORBA::Double Tolerance); void ExtrusionSweep(const SMESH::long_array & IDsOfElements, const SMESH::DirStruct & StepVector, CORBA::Long NbOfSteps); + void ExtrusionSweep0D(const SMESH::long_array & IDsOfElements, + const SMESH::DirStruct & StepVector, + CORBA::Long NbOfSteps); + void ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & StepVector, - CORBA::Long NbOfSteps); + const SMESH::DirStruct & StepVector, + CORBA::Long NbOfSteps); + + void ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::DirStruct & StepVector, + CORBA::Long NbOfSteps); void ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject, const SMESH::DirStruct & StepVector, CORBA::Long NbOfSteps); @@ -205,23 +245,32 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor const SMESH::DirStruct & StepVector, CORBA::Long NbOfSteps); void AdvancedExtrusion(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps, - CORBA::Long theExtrFlags, - CORBA::Double theSewTolerance); + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps, + CORBA::Long theExtrFlags, + CORBA::Double theSewTolerance); SMESH::SMESH_MeshEditor::Extrusion_Error - ExtrusionAlongPath(const SMESH::long_array & IDsOfElements, - SMESH::SMESH_Mesh_ptr PathMesh, - GEOM::GEOM_Object_ptr PathShape, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array & Angles, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct & RefPoint); + ExtrusionAlongPath(const SMESH::long_array & IDsOfElements, + SMESH::SMESH_Mesh_ptr PathMesh, + GEOM::GEOM_Object_ptr PathShape, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array & Angles, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct & RefPoint); SMESH::SMESH_MeshEditor::Extrusion_Error - ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject, + ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject, + SMESH::SMESH_Mesh_ptr PathMesh, + GEOM::GEOM_Object_ptr PathShape, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array & Angles, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct & RefPoint); + SMESH::SMESH_MeshEditor::Extrusion_Error + ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject, SMESH::SMESH_Mesh_ptr PathMesh, GEOM::GEOM_Object_ptr PathShape, CORBA::Long NodeStart, @@ -230,23 +279,14 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean HasRefPoint, const SMESH::PointStruct & RefPoint); SMESH::SMESH_MeshEditor::Extrusion_Error - ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr PathMesh, - GEOM::GEOM_Object_ptr PathShape, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array & Angles, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct & RefPoint); - SMESH::SMESH_MeshEditor::Extrusion_Error - ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr PathMesh, - GEOM::GEOM_Object_ptr PathShape, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array & Angles, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct & RefPoint); + ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject, + SMESH::SMESH_Mesh_ptr PathMesh, + GEOM::GEOM_Object_ptr PathShape, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array & Angles, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct & RefPoint); SMESH::double_array* LinearAnglesVariation(SMESH::SMESH_Mesh_ptr PathMesh, GEOM::GEOM_Object_ptr PathShape, @@ -257,23 +297,23 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor SMESH::SMESH_MeshEditor::MirrorType MirrorType, CORBA::Boolean Copy); void MirrorObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & Axis, - SMESH::SMESH_MeshEditor::MirrorType MirrorType, - CORBA::Boolean Copy); + const SMESH::AxisStruct & Axis, + SMESH::SMESH_MeshEditor::MirrorType MirrorType, + CORBA::Boolean Copy); void Translate(const SMESH::long_array & IDsOfElements, const SMESH::DirStruct & Vector, CORBA::Boolean Copy); void TranslateObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & Vector, - CORBA::Boolean Copy); + const SMESH::DirStruct & Vector, + CORBA::Boolean Copy); void Rotate(const SMESH::long_array & IDsOfElements, const SMESH::AxisStruct & Axis, CORBA::Double Angle, CORBA::Boolean Copy); void RotateObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & Axis, - CORBA::Double Angle, - CORBA::Boolean Copy); + const SMESH::AxisStruct & Axis, + CORBA::Double Angle, + CORBA::Boolean Copy); SMESH::ListOfGroups* RotationSweepMakeGroups(const SMESH::long_array& IDsOfElements, const SMESH::AxisStruct& Axix, @@ -286,18 +326,22 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Long NbOfSteps, CORBA::Double Tolerance); SMESH::ListOfGroups* RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr Object, - const SMESH::AxisStruct& Axix, - CORBA::Double AngleInRadians, - CORBA::Long NbOfSteps, - CORBA::Double Tolerance); + const SMESH::AxisStruct& Axix, + CORBA::Double AngleInRadians, + CORBA::Long NbOfSteps, + CORBA::Double Tolerance); SMESH::ListOfGroups* RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr Object, - const SMESH::AxisStruct& Axix, - CORBA::Double AngleInRadians, - CORBA::Long NbOfSteps, - CORBA::Double Tolerance); + const SMESH::AxisStruct& Axix, + CORBA::Double AngleInRadians, + CORBA::Long NbOfSteps, + CORBA::Double Tolerance); SMESH::ListOfGroups* ExtrusionSweepMakeGroups(const SMESH::long_array& IDsOfElements, const SMESH::DirStruct& StepVector, CORBA::Long NbOfSteps); + SMESH::ListOfGroups* ExtrusionSweepMakeGroups0D(const SMESH::long_array& IDsOfElements, + const SMESH::DirStruct& StepVector, + CORBA::Long NbOfSteps); + SMESH::ListOfGroups* AdvancedExtrusionMakeGroups(const SMESH::long_array& IDsOfElements, const SMESH::DirStruct& StepVector, CORBA::Long NbOfSteps, @@ -306,6 +350,9 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor SMESH::ListOfGroups* ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr Object, const SMESH::DirStruct& StepVector, CORBA::Long NbOfSteps); + SMESH::ListOfGroups* ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr Object, + const SMESH::DirStruct& StepVector, + CORBA::Long NbOfSteps); SMESH::ListOfGroups* ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr Object, const SMESH::DirStruct& StepVector, CORBA::Long NbOfSteps); @@ -331,23 +378,48 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor const SMESH::PointStruct& RefPoint, SMESH::SMESH_MeshEditor::Extrusion_Error& Error); SMESH::ListOfGroups* ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr Object, - SMESH::SMESH_Mesh_ptr PathMesh, - GEOM::GEOM_Object_ptr PathShape, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error); + SMESH::SMESH_Mesh_ptr PathMesh, + GEOM::GEOM_Object_ptr PathShape, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array& Angles, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct& RefPoint, + SMESH::SMESH_MeshEditor::Extrusion_Error& Error); SMESH::ListOfGroups* ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr Object, - SMESH::SMESH_Mesh_ptr PathMesh, - GEOM::GEOM_Object_ptr PathShape, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error); + SMESH::SMESH_Mesh_ptr PathMesh, + GEOM::GEOM_Object_ptr PathShape, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array& Angles, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct& RefPoint, + SMESH::SMESH_MeshEditor::Extrusion_Error& Error); + + // skl 04.06.2009 + SMESH::ListOfGroups* ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object, + SMESH::SMESH_IDSource_ptr Path, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array& Angles, + CORBA::Boolean LinearVariation, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct& RefPoint, + CORBA::Boolean MakeGroups, + SMESH::ElementType ElemType, + SMESH::SMESH_MeshEditor::Extrusion_Error& Error); + SMESH::ListOfGroups* ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements, + SMESH::SMESH_IDSource_ptr Path, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array& Angles, + CORBA::Boolean LinearVariation, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct& RefPoint, + CORBA::Boolean MakeGroups, + SMESH::ElementType ElemType, + SMESH::SMESH_MeshEditor::Extrusion_Error& Error); + SMESH::ListOfGroups* MirrorMakeGroups(const SMESH::long_array& IDsOfElements, const SMESH::AxisStruct& Mirror, SMESH::SMESH_MeshEditor::MirrorType MirrorType); @@ -394,11 +466,30 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean CopyGroups, const char* MeshName); + void Scale(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact, + CORBA::Boolean theCopy); + + SMESH::ListOfGroups* ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact); + + SMESH::SMESH_Mesh_ptr ScaleMakeMesh(SMESH::SMESH_IDSource_ptr Object, + const SMESH::PointStruct& Point, + const SMESH::double_array& theScaleFact, + CORBA::Boolean CopyGroups, + const char* MeshName); + void FindCoincidentNodes (CORBA::Double Tolerance, SMESH::array_of_long_array_out GroupsOfNodes); void FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr Object, CORBA::Double Tolerance, SMESH::array_of_long_array_out GroupsOfNodes); + void FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr Object, + CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + const SMESH::ListOfIDSources& ExceptSubMeshOrGroups); void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes); void FindEqualElements(SMESH::SMESH_IDSource_ptr Object, SMESH::array_of_long_array_out GroupsOfElementsID); @@ -408,8 +499,36 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Double y, CORBA::Double z, CORBA::Long nodeID); + /*! + * \brief Return ID of node closest to a given point + */ + CORBA::Long FindNodeClosestTo(CORBA::Double x, + CORBA::Double y, + CORBA::Double z); + /*! + * Return elements of given type where the given point is IN or ON. + * 'ALL' type means elements of any type excluding nodes + */ + SMESH::long_array* FindElementsByPoint(CORBA::Double x, + CORBA::Double y, + CORBA::Double z, + SMESH::ElementType type); + /*! + * Searching among the given elements, return elements of given type + * where the given point is IN or ON. + * 'ALL' type means elements of any type excluding nodes + */ + SMESH::long_array* FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elements, + CORBA::Double x, + CORBA::Double y, + CORBA::Double z, + SMESH::ElementType type); - + /*! + * Return point state in a closed 2D mesh in terms of TopAbs_State enumeration. + * TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. + */ + CORBA::Short GetPointState(CORBA::Double x, CORBA::Double y, CORBA::Double z); SMESH::SMESH_MeshEditor::Sew_Error SewFreeBorders(CORBA::Long FirstNodeID1, @@ -448,7 +567,7 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor * element - returns false */ CORBA::Boolean ChangeElemNodes(CORBA::Long ide, const SMESH::long_array& newIDs); - + /*! * Return data of mesh edition preview */ @@ -470,10 +589,10 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor /*! * \brief Return edited mesh ID - * \retval int - mesh ID + * \retval int - mesh ID */ int GetMeshId() const { return myMesh->GetId(); } - + CORBA::Boolean DoubleNodes( const SMESH::long_array& theNodes, const SMESH::long_array& theModifiedElems ); @@ -483,8 +602,194 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Boolean DoubleNodeGroup( SMESH::SMESH_GroupBase_ptr theNodes, SMESH::SMESH_GroupBase_ptr theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup(), but returns a new group with newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ + SMESH::SMESH_Group_ptr DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ); + CORBA::Boolean DoubleNodeGroups( const SMESH::ListOfGroups& theNodes, - const SMESH::ListOfGroups& theModifiedElems); + const SMESH::ListOfGroups& theModifiedElems ); + + SMESH::SMESH_Group_ptr DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes, + const SMESH::ListOfGroups& theModifiedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theAffectedElems - the list of elements (cells and edges) to which the + * replicated nodes should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodeGroups() + */ + CORBA::Boolean DoubleNodeElem( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + const SMESH::long_array& theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion() + */ + CORBA::Boolean DoubleNodeElemInRegion( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + GEOM::GEOM_Object_ptr theShape ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodes(), DoubleNodeGroups(), DoubleNodeElemGroupNew() + */ + CORBA::Boolean DoubleNodeElemGroup( SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ + SMESH::SMESH_Group_ptr DoubleNodeElemGroupNew( SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems ); + + SMESH::ListOfGroups* DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems, + CORBA::Boolean theElemGroupNeeded, + CORBA::Boolean theNodeGroupNeeded); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion() + */ + CORBA::Boolean DoubleNodeElemGroupInRegion( SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + GEOM::GEOM_Object_ptr theShape ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew() + */ + CORBA::Boolean DoubleNodeElemGroups( const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroups() + */ + SMESH::SMESH_Group_ptr DoubleNodeElemGroupsNew( const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems ); + + SMESH::ListOfGroups* DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems, + CORBA::Boolean theElemGroupNeeded, + CORBA::Boolean theNodeGroupNeeded); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion() + */ + CORBA::Boolean DoubleNodeElemGroupsInRegion( const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + GEOM::GEOM_Object_ptr theShape ); + /*! + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must describe a partition of the mesh volumes. + * The nodes of the internal faces at the boundaries of the groups are doubled. + * In option, the internal faces are replaced by flat elements. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * @param theDomains - list of groups of volumes + * @param createJointElems - if TRUE, create the elements + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ + CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains, + CORBA::Boolean createJointElems ) + throw (SALOME::SALOME_Exception); + /*! + * \brief Double nodes on some external faces and create flat elements. + * Flat elements are mainly used by some types of mechanic calculations. + * + * Each group of the list must be constituted of faces. + * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * @param theGroupsOfFaces - list of groups of faces + * @return TRUE if operation has been completed successfully, FALSE otherwise + */ + CORBA::Boolean CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces ); + + /*! + * \brief Generated skin mesh (containing 2D cells) from 3D mesh + * The created 2D mesh elements based on nodes of free faces of boundary volumes + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ + CORBA::Boolean Make2DMeshFrom3D(); + + SMESH::SMESH_Mesh_ptr MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr elements, + SMESH::Bnd_Dimension dimension, + const char* groupName, + const char* meshName, + CORBA::Boolean toCopyElements, + CORBA::Boolean toCopyMissingBondary, + SMESH::SMESH_Group_out group); + + CORBA::Long MakeBoundaryElements(SMESH::Bnd_Dimension dimension, + const char* groupName, + const char* meshName, + CORBA::Boolean toCopyAll, + const SMESH::ListOfIDSources& groups, + SMESH::SMESH_Mesh_out mesh, + SMESH::SMESH_Group_out group) + throw (SALOME::SALOME_Exception); private: //!< private methods @@ -492,13 +797,13 @@ private: //!< private methods /*! * \brief Update myLastCreated* or myPreviewData - * \param anEditor - it contains edition results + * \param anEditor - it contains edition results */ void storeResult(::SMESH_MeshEditor& anEditor); /*! * \brief Clear myLastCreated* or myPreviewData */ - void initData(); + void initData(bool deleteSearchers=true); /*! * \brief Return groups by their IDs @@ -511,11 +816,11 @@ private: //!< private methods CORBA::Long NbOfSteps, CORBA::Double Tolerance, const bool MakeGroups, - const SMDSAbs_ElementType ElementType=SMDSAbs_All); + const SMDSAbs_ElementType ElementType=SMDSAbs_All); SMESH::ListOfGroups* extrusionSweep(const SMESH::long_array & IDsOfElements, const SMESH::DirStruct & StepVector, CORBA::Long NbOfSteps, - const bool MakeGroups, + bool MakeGroups, const SMDSAbs_ElementType ElementType=SMDSAbs_All); SMESH::ListOfGroups* advancedExtrusion(const SMESH::long_array & theIDsOfElements, const SMESH::DirStruct & theStepVector, @@ -533,37 +838,55 @@ private: //!< private methods const SMESH::PointStruct & RefPoint, const bool MakeGroups, SMESH::SMESH_MeshEditor::Extrusion_Error & Error, - const SMDSAbs_ElementType ElementType=SMDSAbs_All); - SMESH::ListOfGroups* mirror(const SMESH::long_array & IDsOfElements, + const SMDSAbs_ElementType ElementType=SMDSAbs_All); + SMESH::ListOfGroups* extrusionAlongPathX(const SMESH::long_array & IDsOfElements, + SMESH::SMESH_IDSource_ptr Path, + CORBA::Long NodeStart, + CORBA::Boolean HasAngles, + const SMESH::double_array& Angles, + CORBA::Boolean LinearVariation, + CORBA::Boolean HasRefPoint, + const SMESH::PointStruct& RefPoint, + bool MakeGroups, + const SMDSAbs_ElementType ElementType, + SMESH::SMESH_MeshEditor::Extrusion_Error & theError); + SMESH::ListOfGroups* mirror(TIDSortedElemSet & IDsOfElements, const SMESH::AxisStruct & Axis, SMESH::SMESH_MeshEditor::MirrorType MirrorType, CORBA::Boolean Copy, - const bool MakeGroups, + bool MakeGroups, ::SMESH_Mesh* TargetMesh=0); - SMESH::ListOfGroups* translate(const SMESH::long_array & IDsOfElements, + SMESH::ListOfGroups* translate(TIDSortedElemSet & IDsOfElements, const SMESH::DirStruct & Vector, CORBA::Boolean Copy, - const bool MakeGroups, + bool MakeGroups, ::SMESH_Mesh* TargetMesh=0); - SMESH::ListOfGroups* rotate(const SMESH::long_array & IDsOfElements, + SMESH::ListOfGroups* rotate(TIDSortedElemSet & IDsOfElements, const SMESH::AxisStruct & Axis, CORBA::Double Angle, CORBA::Boolean Copy, - const bool MakeGroups, + bool MakeGroups, ::SMESH_Mesh* TargetMesh=0); + SMESH::ListOfGroups* scale(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact, + CORBA::Boolean theCopy, + bool theMakeGroups, + ::SMESH_Mesh* theTargetMesh=0); + SMESH::SMESH_Mesh_ptr makeMesh(const char* theMeshName); - + void DumpGroupsList(SMESH::TPythonDump & theDumpPython, const SMESH::ListOfGroups * theGroupList); -private: //!< fields + string generateGroupName(const string& thePrefix); - SMESH_Mesh_i* myMesh_i; - SMESH_Mesh * myMesh; +private: //!< fields - SMESH::long_array_var myLastCreatedElems; - SMESH::long_array_var myLastCreatedNodes; + SMESH_Mesh_i* myMesh_i; + SMESH_Mesh * myMesh; + ::SMESH_MeshEditor myEditor; SMESH::MeshPreviewStruct_var myPreviewData; bool myPreviewMode; diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 8371ccf2f..2e4d1772c 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,57 +1,60 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Mesh_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// -#include "SMESH_Mesh_i.hxx" -#include "SMESH_Filter_i.hxx" -#include "SMESH_Gen_i.hxx" -#include "SMESH_Group_i.hxx" -#include "SMESH_MEDMesh_i.hxx" -#include "SMESH_MeshEditor_i.hxx" -#include "SMESH_PythonDump.hxx" -#include "SMESH_subMesh_i.hxx" +#include "SMESH_Mesh_i.hxx" #include "DriverMED_R_SMESHDS_Mesh.h" #include "DriverMED_W_SMESHDS_Mesh.h" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_ElemIterator.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMDS_IteratorOnIterators.hxx" +#include "SMDS_SetIterator.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Command.hxx" #include "SMESHDS_CommandType.hxx" #include "SMESHDS_GroupOnGeom.hxx" +#include "SMESH_Filter_i.hxx" +#include "SMESH_Gen_i.hxx" #include "SMESH_Group.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_MEDMesh_i.hxx" #include "SMESH_MeshEditor.hxx" +#include "SMESH_MeshEditor_i.hxx" #include "SMESH_MesherHelper.hxx" -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" +#include "SMESH_PreMeshInfo.hxx" +#include "SMESH_PythonDump.hxx" +#include "SMESH_subMesh_i.hxx" -#include "OpUtil.hxx" -#include "SALOME_NamingService.hxx" -#include "Utils_CorbaException.hxx" -#include "Utils_ExceptHandlers.hxx" -#include "Utils_SINGLETON.hxx" -#include "utilities.h" +#include +#include +#include +#include +#include +#include +#include // OCCT Includes #include @@ -63,10 +66,14 @@ #include #include #include +#include #include #include +#include +#include // STL Includes +#include #include #include #include @@ -81,9 +88,11 @@ static int MYDEBUG = 0; using namespace std; using SMESH::TPythonDump; -int SMESH_Mesh_i::myIdGenerator = 0; - +int SMESH_Mesh_i::_idGenerator = 0; +//To disable automatic genericobj management, the following line should be commented. +//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx +#define WITHGENERICOBJ //============================================================================= /*! @@ -92,15 +101,16 @@ int SMESH_Mesh_i::myIdGenerator = 0; //============================================================================= SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, - SMESH_Gen_i* gen_i, - CORBA::Long studyId ) + SMESH_Gen_i* gen_i, + CORBA::Long studyId ) : SALOME::GenericObj_i( thePOA ) { MESSAGE("SMESH_Mesh_i"); _impl = NULL; _gen_i = gen_i; - _id = myIdGenerator++; + _id = _idGenerator++; _studyId = studyId; + _preMeshInfo = NULL; } //============================================================================= @@ -111,19 +121,52 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i::~SMESH_Mesh_i() { - INFOS("~SMESH_Mesh_i"); - map::iterator it; - for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) { - SMESH_GroupBase_i* aGroup = dynamic_cast( SMESH_Gen_i::GetServant( it->second ).in() ); - if ( aGroup ) { - // this method is colled from destructor of group (PAL6331) + MESSAGE("~SMESH_Mesh_i"); + +#ifdef WITHGENERICOBJ + // destroy groups + map::iterator itGr; + for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) { + if ( CORBA::is_nil( itGr->second )) + continue; + SMESH_GroupBase_i* aGroup = dynamic_cast(SMESH_Gen_i::GetServant(itGr->second).in()); + if (aGroup) { + // this method is called from destructor of group (PAL6331) //_impl->RemoveGroup( aGroup->GetLocalID() ); - - aGroup->Destroy(); + aGroup->myMeshServant = 0; + aGroup->UnRegister(); } } _mapGroups.clear(); - delete _impl; + + // destroy submeshes + map::iterator itSM; + for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) { + if ( CORBA::is_nil( itSM->second )) + continue; + SMESH_subMesh_i* aSubMesh = dynamic_cast(SMESH_Gen_i::GetServant(itSM->second).in()); + if (aSubMesh) { + aSubMesh->UnRegister(); + } + } + _mapSubMeshIor.clear(); + + // destroy hypotheses + map::iterator itH; + for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) { + if ( CORBA::is_nil( itH->second )) + continue; + SMESH_Hypothesis_i* aHypo = dynamic_cast(SMESH_Gen_i::GetServant(itH->second).in()); + if (aHypo) { + aHypo->UnRegister(); + } + } + _mapHypo.clear(); +#endif + + delete _impl; _impl = NULL; + + if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL; } //============================================================================= @@ -146,6 +189,8 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject ) catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } + // to track changes of GEOM groups + addGeomGroupData( theShapeObject, _this() ); } //================================================================================ @@ -189,6 +234,31 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() return aShapeObj._retn(); } +//================================================================================ +/*! + * \brief Return false if the mesh is not yet fully loaded from the study file + */ +//================================================================================ + +CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + return !_preMeshInfo; +} + +//================================================================================ +/*! + * \brief Load full mesh data from the study file + */ +//================================================================================ + +void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); +} + //================================================================================ /*! * \brief Remove all nodes and elements @@ -198,8 +268,12 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->ForgetAllData(); + try { _impl->Clear(); + CheckGeomGroupModif(); // issue 20145 } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); @@ -217,6 +291,9 @@ void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + try { _impl->ClearSubMesh( ShapeID ); } @@ -280,9 +357,9 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) int major, minor, release; if( !MED::getMEDVersion( theFileName, major, minor, release ) ) major = minor = release = -1; - myFileInfo = new SALOME_MED::MedFileInfo(); - myFileInfo->fileName = theFileName; - myFileInfo->fileSize = 0; + _medFileInfo = new SALOME_MED::MedFileInfo(); + _medFileInfo->fileName = theFileName; + _medFileInfo->fileSize = 0; #ifdef WIN32 struct _stati64 d; if ( ::_stati64( theFileName, &d ) != -1 ) @@ -290,10 +367,38 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) struct stat64 d; if ( ::stat64( theFileName, &d ) != -1 ) #endif - myFileInfo->fileSize = d.st_size; - myFileInfo->major = major; - myFileInfo->minor = minor; - myFileInfo->release = release; + _medFileInfo->fileSize = d.st_size; + _medFileInfo->major = major; + _medFileInfo->minor = minor; + _medFileInfo->release = release; + + return ConvertDriverMEDReadStatus(status); +} + +//================================================================================ +/*! + * \brief Imports mesh data from the CGNS file + */ +//================================================================================ + +SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName, + const int theMeshIndex, + std::string& theMeshName ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + int status; + try { + status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName ); + } + catch( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + catch ( ... ) { + THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM); + } + + CreateGroupServants(); return ConvertDriverMEDReadStatus(status); } @@ -306,7 +411,7 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits) { - std::string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version), + string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version), nbDigits); return CORBA::string_dup( ver.c_str() ); } @@ -346,23 +451,6 @@ int SMESH_Mesh_i::ImportSTLFile( const char* theFileName ) return 1; } -//============================================================================= -/*! - * importMEDFile - * - * Imports mesh data from MED file - */ -//============================================================================= - -// int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName ) -// { -// // Read mesh with name = and all its groups into SMESH_Mesh -// int status = _impl->MEDToMesh( theFileName, theMeshName ); -// CreateGroupServants(); - -// return status; -// } - //============================================================================= /*! * @@ -404,11 +492,14 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus */ //============================================================================= -SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, +SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, SMESH::SMESH_Hypothesis_ptr anHyp) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); + SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp ); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) @@ -442,7 +533,7 @@ SMESH_Hypothesis::Hypothesis_Status if(MYDEBUG) MESSAGE("addHypothesis"); if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); @@ -464,6 +555,9 @@ SMESH_Hypothesis::Hypothesis_Status status = _impl->AddHypothesis(myLocSubShape, hypId); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) { _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp ); +#ifdef WITHGENERICOBJ + _mapHypo[hypId]->Register(); +#endif // assure there is a corresponding submesh if ( !_impl->IsMainShape( myLocSubShape )) { int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); @@ -490,6 +584,9 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); + SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp ); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) @@ -516,41 +613,40 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS */ //============================================================================= -SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, - SMESH::SMESH_Hypothesis_ptr anHyp) +SMESH_Hypothesis::Hypothesis_Status +SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, + SMESH::SMESH_Hypothesis_ptr anHyp) { - if(MYDEBUG) MESSAGE("removeHypothesis()"); - // **** proposer liste de subShape (selection multiple) + if(MYDEBUG) MESSAGE("removeHypothesis()"); + // **** proposer liste de sub-shape (selection multiple) + + if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); - if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", - SALOME::BAD_PARAM); + SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); + if (CORBA::is_nil(myHyp)) + THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM); - SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); - if (CORBA::is_nil(myHyp)) - THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", - SALOME::BAD_PARAM); + SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; + try + { + TopoDS_Shape myLocSubShape; + //use PseudoShape in case if mesh has no shape + if(HasShapeToMesh()) + myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject); + else + myLocSubShape = _impl->GetShapeToMesh(); - SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; - try - { - TopoDS_Shape myLocSubShape; - //use PseudoShape in case if mesh has no shape - if(HasShapeToMesh()) - myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject); - else - myLocSubShape = _impl->GetShapeToMesh(); - - int hypId = myHyp->GetId(); - status = _impl->RemoveHypothesis(myLocSubShape, hypId); - if ( !SMESH_Hypothesis::IsStatusFatal(status) ) - _mapHypo.erase( hypId ); - } - catch(SALOME_Exception & S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); - } - return status; + int hypId = myHyp->GetId(); + status = _impl->RemoveHypothesis(myLocSubShape, hypId); +// if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes +// _mapHypo.erase( hypId ); + } + catch(SALOME_Exception & S_ex) + { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + return status; } //============================================================================= @@ -560,19 +656,20 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Ob //============================================================================= SMESH::ListOfHypothesis * - SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) + SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if (MYDEBUG) MESSAGE("GetHypothesisList"); - if (CORBA::is_nil(aSubShapeObject)) - THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", - SALOME::BAD_PARAM); + if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject)) + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis(); try { TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject); + if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() ) + myLocSubShape = _impl->GetShapeToMesh(); const list& aLocalList = _impl->GetHypothesisList( myLocSubShape ); int i = 0, n = aLocalList.size(); aList->length( n ); @@ -580,7 +677,7 @@ throw(SALOME::SALOME_Exception) for ( list::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) { SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt); if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() ) - aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] ); + aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] ); } aList->length( i ); @@ -592,20 +689,56 @@ throw(SALOME::SALOME_Exception) return aList._retn(); } +SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if (MYDEBUG) MESSAGE("GetSubMeshes"); + + SMESH::submesh_array_var aList = new SMESH::submesh_array(); + + // Python Dump + TPythonDump aPythonDump; + if ( !_mapSubMeshIor.empty() ) + aPythonDump << "[ "; + + try { + aList->length( _mapSubMeshIor.size() ); + int i = 0; + map::iterator it = _mapSubMeshIor.begin(); + for ( ; it != _mapSubMeshIor.end(); it++ ) { + if ( CORBA::is_nil( it->second )) continue; + aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second ); + // Python Dump + if (i > 1) aPythonDump << ", "; + aPythonDump << it->second; + } + aList->length( i ); + } + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + // Update Python script + if ( !_mapSubMeshIor.empty() ) + aPythonDump << " ] = " << _this() << ".GetSubMeshes()"; + + return aList._retn(); +} + //============================================================================= /*! * */ //============================================================================= SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, - const char* theName ) + const char* theName ) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_Mesh_i::GetSubMesh"); if (CORBA::is_nil(aSubShapeObject)) - THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", - SALOME::BAD_PARAM); + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", + SALOME::BAD_PARAM); SMESH::SMESH_subMesh_var subMesh; SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this()); @@ -615,12 +748,18 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap //Get or Create the SMESH_subMesh object implementation int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); + + if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape )) + { + TopoDS_Iterator it( myLocSubShape ); + if ( it.More() ) + THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM); + } subMesh = getSubMesh( subMeshId ); // create a new subMesh object servant if there is none for the shape if ( subMesh->_is_nil() ) subMesh = createSubMesh( aSubShapeObject ); - if ( _gen_i->CanPublishInStudy( subMesh )) { SALOMEDS::SObject_var aSO = _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh, @@ -660,7 +799,10 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) long aTag = SMESH_Gen_i::GetRefOnShapeTag(); SALOMEDS::SObject_var anObj, aRef; if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) ) - aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() ); + aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() ); + +// if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617) +// aSubShapeObject = theSubMesh->GetSubShape(); aStudy->NewBuilder()->RemoveObjectWithChildren( anSO ); @@ -669,26 +811,9 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) } } - removeSubMesh( theSubMesh, aSubShapeObject.in() ); -} - -//============================================================================= -/*! - * ElementTypeString - */ -//============================================================================= -#define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum; -inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType) -{ - switch (theElemType) { - CASE2STRING( ALL ); - CASE2STRING( NODE ); - CASE2STRING( EDGE ); - CASE2STRING( FACE ); - CASE2STRING( VOLUME ); - default:; - } - return ""; + if ( removeSubMesh( theSubMesh, aSubShapeObject.in() )) + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); } //============================================================================= @@ -698,10 +823,13 @@ inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType //============================================================================= SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType, - const char* theName ) + const char* theName ) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::SMESH_Group_var aNewGroup = SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName )); @@ -712,7 +840,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType if ( !aSO->_is_nil()) { // Update Python script TPythonDump() << aSO << " = " << _this() << ".CreateGroup( " - << ElementTypeString(theElemType) << ", '" << theName << "' )"; + << theElemType << ", '" << theName << "' )"; } } return aNewGroup._retn(); @@ -724,18 +852,24 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType * */ //============================================================================= -SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, - const char* theName, - GEOM::GEOM_Object_ptr theGeomObj) +SMESH::SMESH_GroupOnGeom_ptr +SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, + const char* theName, + GEOM::GEOM_Object_ptr theGeomObj) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::SMESH_GroupOnGeom_var aNewGroup; TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj ); - if ( !aShape.IsNull() ) { + if ( !aShape.IsNull() ) + { aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow ( createGroup( theElemType, theName, aShape )); + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { SALOMEDS::SObject_var aSO = _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), @@ -743,8 +877,7 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementTy if ( !aSO->_is_nil()) { // Update Python script TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM(" - << ElementTypeString(theElemType) << ", '" << theName << "', " - << theGeomObj << " )"; + << theElemType << ", '" << theName << "', " << theGeomObj << " )"; } } } @@ -752,6 +885,55 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementTy return aNewGroup._retn(); } +//================================================================================ +/*! + * \brief Creates a group whose contents is defined by filter + * \param theElemType - group type + * \param theName - group name + * \param theFilter - the filter + * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter + */ +//================================================================================ + +SMESH::SMESH_GroupOnFilter_ptr +SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, + const char* theName, + SMESH::Filter_ptr theFilter ) + throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + if ( CORBA::is_nil( theFilter )) + THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM); + + SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter ); + if ( !predicate ) + THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM); + + SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow + ( createGroup( theElemType, theName, TopoDS_Shape(), predicate )); + + TPythonDump pd; + if ( !aNewGroup->_is_nil() ) + aNewGroup->SetFilter( theFilter ); + + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SALOMEDS::SObject_var aSO = + _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup, + GEOM::GEOM_Object::_nil(), theName); + if ( !aSO->_is_nil()) { + // Update Python script + pd << aSO << " = " << _this() << ".CreateGroupFromFilter(" + << theElemType << ", '" << theName << "', " << theFilter << " )"; + } + } + + return aNewGroup._retn(); +} + //============================================================================= /*! * @@ -787,13 +969,17 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) } //============================================================================= -/*! RemoveGroupWithContents +/*! * Remove group with its contents */ //============================================================================= + void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + if ( theGroup->_is_nil() ) return; @@ -805,8 +991,7 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup SMESH::long_array_var anIds = aGroup->GetListOfID(); SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); - // Update Python script - TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; + TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup() // Remove contents if ( aGroup->GetType() == SMESH::NODE ) @@ -817,12 +1002,10 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup // Remove group RemoveGroup( theGroup ); - // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup() - _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId()); - _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId()); + // Update Python script + pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; } - //================================================================================ /*! * \brief Get the list of groups existing in the mesh @@ -865,6 +1048,7 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception) return aList._retn(); } + //============================================================================= /*! * Get number of groups existing in the mesh @@ -888,6 +1072,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the const char* theName ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + try { if ( theGroup1->_is_nil() || theGroup2->_is_nil() || @@ -951,12 +1138,15 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups const char* theName ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + if ( !theName ) return SMESH::SMESH_Group::_nil(); try { - NCollection_Map< int > anIds; + vector< int > anIds; SMESH::ElementType aType = SMESH::ALL; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { @@ -979,7 +1169,7 @@ throw (SALOME::SALOME_Exception) for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - anIds.Add( aCurrId ); + anIds.push_back( aCurrId ); } } @@ -990,12 +1180,12 @@ throw (SALOME::SALOME_Exception) // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; anIter.More(); anIter.Next(), i++ ) + //NCollection_Map< int >::Iterator anIter( anIds ); + for ( int i = 0; iAdd( aResIds ); @@ -1028,6 +1218,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr const char* theName ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + if ( theGroup1->_is_nil() || theGroup2->_is_nil() || theGroup1->GetType() != theGroup2->GetType() ) return SMESH::SMESH_Group::_nil(); @@ -1080,10 +1273,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr \return pointer on the group */ //============================================================================= -SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups( - const SMESH::ListOfGroups& theGroups, const char* theName ) -throw (SALOME::SALOME_Exception) +SMESH::SMESH_Group_ptr +SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, + const char* theName ) + throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + if ( !theName ) return SMESH::SMESH_Group::_nil(); @@ -1121,14 +1318,14 @@ throw (SALOME::SALOME_Exception) // create map of ids int nbGrp = theGroups.length(); - NCollection_Map< int > anIds; + vector< int > anIds; NCollection_DataMap< int, int >::Iterator anIter( anIdToCount ); for ( ; anIter.More(); anIter.Next() ) { int aCurrId = anIter.Key(); int aCurrNb = anIter.Value(); if ( aCurrNb == nbGrp ) - anIds.Add( aCurrId ); + anIds.push_back( aCurrId ); } // Create group @@ -1138,12 +1335,12 @@ throw (SALOME::SALOME_Exception) // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator aListIter( anIds ); - for ( int i = 0; aListIter.More(); aListIter.Next(), i++ ) + //NCollection_Map< int >::Iterator aListIter( anIds ); + for ( int i = 0; iAdd( aResIds ); @@ -1173,9 +1370,12 @@ throw (SALOME::SALOME_Exception) //============================================================================= SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, - const char* theName ) + const char* theName ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + if ( theGroup1->_is_nil() || theGroup2->_is_nil() || theGroup1->GetType() != theGroup2->GetType() ) return SMESH::SMESH_Group::_nil(); @@ -1229,18 +1429,21 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr \return pointer on the group */ //============================================================================= -SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( - const SMESH::ListOfGroups& theMainGroups, - const SMESH::ListOfGroups& theToolGroups, - const char* theName ) +SMESH::SMESH_Group_ptr +SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, + const SMESH::ListOfGroups& theToolGroups, + const char* theName ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + if ( !theName ) return SMESH::SMESH_Group::_nil(); try { - NCollection_Map< int > aToolIds; + set< int > aToolIds; SMESH::ElementType aType = SMESH::ALL; int g, n; // iterate through tool groups @@ -1265,11 +1468,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - aToolIds.Add( aCurrId ); + aToolIds.insert( aCurrId ); } } - NCollection_Map< int > anIds; // result + vector< int > anIds; // result // Iterate through main group for ( g = 0, n = theMainGroups.length(); g < n; g++ ) @@ -1293,8 +1496,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) { int aCurrId = aCurrIds[ i ]; - if ( !aToolIds.Contains( aCurrId ) ) - anIds.Add( aCurrId ); + if ( !aToolIds.count( aCurrId ) ) + anIds.push_back( aCurrId ); } } @@ -1305,12 +1508,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.Extent() ); + aResIds->length( anIds.size() ); - NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; anIter.More(); anIter.Next(), i++ ) + for (int i=0; iAdd( aResIds ); @@ -1345,12 +1547,15 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( \return pointer on new group */ //============================================================================= -SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( - const SMESH::ListOfGroups& theGroups, - SMESH::ElementType theElemType, - const char* theName ) +SMESH::SMESH_Group_ptr +SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, + SMESH::ElementType theElemType, + const char* theName ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); if ( !theName || !aMeshDS ) @@ -1362,7 +1567,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( { // Create map of nodes from all groups - NCollection_Map< int > aNodeMap; + set< int > aNodeMap; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { @@ -1381,7 +1586,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( int aCurrId = aCurrIds[ i ]; const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId ); if ( aNode ) - aNodeMap.Add( aNode->GetID() ); + aNodeMap.insert( aNode->GetID() ); } } else @@ -1399,7 +1604,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( const SMDS_MeshNode* aNode = dynamic_cast( aNodeIter->next() ); if ( aNode ) - aNodeMap.Add( aNode->GetID() ); + aNodeMap.insert( aNode->GetID() ); } } } @@ -1407,22 +1612,25 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( // Get result identifiers - NCollection_Map< int > aResultIds; + vector< int > aResultIds; if ( theElemType == SMESH::NODE ) { - NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - for ( ; aNodeIter.More(); aNodeIter.Next() ) - aResultIds.Add( aNodeIter.Value() ); + //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); + set::iterator iter = aNodeMap.begin(); + for ( ; iter != aNodeMap.end(); iter++ ) + aResultIds.push_back( *iter); } else { // Create list of elements of given dimension constructed on the nodes - NCollection_Map< int > anElemList; - NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - for ( ; aNodeIter.More(); aNodeIter.Next() ) + vector< int > anElemList; + //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); + //for ( ; aNodeIter.More(); aNodeIter.Next() ) + set::iterator iter = aNodeMap.begin(); + for ( ; iter != aNodeMap.end(); iter++ ) { const SMDS_MeshElement* aNode = - dynamic_cast( aMeshDS->FindNode( aNodeIter.Value() ) ); + dynamic_cast( aMeshDS->FindNode( *iter ) ); if ( !aNode ) continue; @@ -1432,15 +1640,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( const SMDS_MeshElement* anElem = dynamic_cast( anElemIter->next() ); if ( anElem && anElem->GetType() == anElemType ) - anElemList.Add( anElem->GetID() ); + anElemList.push_back( anElem->GetID() ); } } // check whether all nodes of elements are present in nodes map - NCollection_Map< int >::Iterator anIter( anElemList ); - for ( ; anIter.More(); anIter.Next() ) + for (int i=0; i< anElemList.size(); i++) { - const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() ); + const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] ); if ( !anElem ) continue; @@ -1450,14 +1657,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( { const SMDS_MeshNode* aNode = dynamic_cast( aNodeIter->next() ); - if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) ) + if ( !aNode || !aNodeMap.count( aNode->GetID() ) ) { isOk = false; break; } } if ( isOk ) - aResultIds.Add( anElem->GetID() ); + aResultIds.push_back( anElem->GetID() ); } } @@ -1469,11 +1676,10 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( // Create array of identifiers SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aResultIds.Extent() ); + aResIds->length( aResultIds.size() ); - NCollection_Map< int >::Iterator aResIter( aResultIds ); - for ( int i = 0; aResIter.More(); aResIter.Next(), i++ ) - aResIds[ i ] = aResIter.Value(); + for (int i=0; i< aResultIds.size(); i++) + aResIds[ i ] = aResultIds[i]; aResGrp->Add( aResIds ); // Remove strings corresponding to group creation @@ -1496,61 +1702,128 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( //================================================================================ /*! - * \brief Return group items of a group present in a study + * \brief Remember GEOM group data */ //================================================================================ -static GEOM::GEOM_Object_ptr getGroupItemsFromStudy(CORBA::Object_ptr theMesh, - SMESH_Gen_i* theGen, - list & theItems) +void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, + CORBA::Object_ptr theSmeshObj) { - GEOM::GEOM_Object_var groupObj; - SALOMEDS::Study_var study = theGen->GetCurrentStudy(); - GEOM::GEOM_Gen_var geomGen = theGen->GetGeomEngine(); - if ( study->_is_nil() || geomGen->_is_nil() ) - return groupObj._retn(); - + if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP ) + return; + // group SO + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); + if ( groupSO->_is_nil() ) + return; + // group indices + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); GEOM::GEOM_IGroupOperations_var groupOp = - geomGen->GetIGroupOperations( theGen->GetCurrentStudyID() ); - GEOM::GEOM_IShapesOperations_var shapeOp = - geomGen->GetIShapesOperations( theGen->GetCurrentStudyID() ); - - SALOMEDS::SObject_var meshOS = theGen->ObjectToSObject(study, theMesh); - if ( meshOS->_is_nil() || groupOp->_is_nil() || shapeOp->_is_nil() ) - return groupObj._retn(); - SALOMEDS::SObject_var fatherSO = meshOS->GetFather(); - if ( fatherSO->_is_nil() || fatherSO->Tag() != theGen->GetSubMeshOnCompoundTag() ) - return groupObj._retn(); // keep only submeshes on groups - - SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(meshOS); - if ( anIter->_is_nil() ) return groupObj._retn(); - for ( ; anIter->More(); anIter->Next()) - { - SALOMEDS::SObject_var aSObject = anIter->Value(); - SALOMEDS::SObject_var aRefSO; - if ( !aSObject->_is_nil() && aSObject->ReferencedObject(aRefSO) ) - { - groupObj = GEOM::GEOM_Object::_narrow(aRefSO->GetObject()); - if ( groupObj->_is_nil() ) break; - GEOM::ListOfLong_var ids = groupOp->GetObjects( groupObj ); - GEOM::GEOM_Object_var mainShape = groupObj->GetMainShape(); - for ( int i = 0; i < ids->length(); ++i ) { - GEOM::GEOM_Object_var subShape = shapeOp->GetSubShape( mainShape, ids[i] ); - TopoDS_Shape S = theGen->GeomObjectToShape( subShape ); - if ( !S.IsNull() ) - theItems.push_back( S ); - } - break; + geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); + GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); + + // store data + _geomGroupData.push_back( TGeomGroupData() ); + TGeomGroupData & groupData = _geomGroupData.back(); + // entry + CORBA::String_var entry = groupSO->GetID(); + groupData._groupEntry = entry.in(); + // indices + for ( int i = 0; i < ids->length(); ++i ) + groupData._indices.insert( ids[i] ); + // SMESH object + groupData._smeshObject = theSmeshObj; +} + +//================================================================================ +/*! + * Remove GEOM group data relating to removed smesh object + */ +//================================================================================ + +void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj) +{ + list::iterator + data = _geomGroupData.begin(), dataEnd = _geomGroupData.end(); + for ( ; data != dataEnd; ++data ) { + if ( theSmeshObj->_is_equivalent( data->_smeshObject )) { + _geomGroupData.erase( data ); + return; } } - return groupObj._retn(); } +//================================================================================ +/*! + * \brief Return new group contents if it has been changed and update group data + */ +//================================================================================ + +TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) +{ + TopoDS_Shape newShape; + + // get geom group + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) return newShape; // means "not changed" + SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() ); + if ( !groupSO->_is_nil() ) + { + CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO ); + if ( CORBA::is_nil( groupObj )) return newShape; + GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj ); + + // get indices of group items + set curIndices; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); + GEOM::GEOM_IGroupOperations_var groupOp = + geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); + GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); + for ( int i = 0; i < ids->length(); ++i ) + curIndices.insert( ids[i] ); + + if ( groupData._indices == curIndices ) + return newShape; // group not changed + + // update data + groupData._indices = curIndices; + + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) return newShape; + TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup ); + geomClient->RemoveShapeFromBuffer( groupIOR ); + newShape = _gen_i->GeomObjectToShape( geomGroup ); + } + + if ( newShape.IsNull() ) { + // geom group becomes empty - return empty compound + TopoDS_Compound compound; + BRep_Builder().MakeCompound(compound); + newShape = compound; + } + return newShape; +} + +namespace +{ + //============================================================================= + /*! + * \brief Storage of shape and index used in CheckGeomGroupModif() + */ + //============================================================================= + struct TIndexedShape + { + int _index; + TopoDS_Shape _shape; + TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {} + }; +} //============================================================================= /*! - * \brief Update hypotheses assigned to geom groups if the latter change + * \brief Update objects depending on changed geom groups * - * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation + * issue 0020210: Update of a smesh group after modification of the associated geom group */ //============================================================================= @@ -1561,83 +1834,240 @@ void SMESH_Mesh_i::CheckGeomGroupModif() SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); if ( study->_is_nil() ) return; - // check if items of groups changed - map::iterator i_sm = _mapSubMesh.begin(); - for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) - { - const TopoDS_Shape & oldGroupShape = i_sm->second->GetSubShape(); - SMESHDS_SubMesh * oldDS = i_sm->second->GetSubMeshDS(); - if ( !oldDS /*|| !oldDS->IsComplexSubmesh()*/ ) - continue; - int oldID = i_sm->first; - map::iterator i_smIor = _mapSubMeshIor.find( oldID ); - if ( i_smIor == _mapSubMeshIor.end() ) - continue; - list< TopoDS_Shape> newItems; - GEOM::GEOM_Object_var groupObj = getGroupItemsFromStudy ( i_smIor->second, _gen_i, newItems ); - if ( groupObj->_is_nil() ) - continue; + CORBA::Long nbEntities = NbNodes() + NbElements(); - int nbOldItems = oldDS->IsComplexSubmesh() ? oldDS->NbSubMeshes() : 1; - int nbNewItems = newItems.size(); - bool groupChanged = ( nbOldItems != nbNewItems); - if ( !groupChanged ) { - if ( !oldDS->IsComplexSubmesh() ) { // old group has one item - groupChanged = ( oldGroupShape != newItems.front() ); - } - else { - list::iterator item = newItems.begin(); - for ( ; item != newItems.end() && !groupChanged; ++item ) - { - SMESHDS_SubMesh * itemDS = _impl->GetMeshDS()->MeshElements( *item ); - groupChanged = ( !itemDS || !oldDS->ContainsSubMesh( itemDS )); - } - } + // Check if group contents changed + + typedef map< string, TopoDS_Shape > TEntry2Geom; + TEntry2Geom newGroupContents; + + list::iterator + data = _geomGroupData.begin(), dataEnd = _geomGroupData.end(); + for ( ; data != dataEnd; ++data ) + { + pair< TEntry2Geom::iterator, bool > it_new = + newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() )); + bool processedGroup = !it_new.second; + TopoDS_Shape& newShape = it_new.first->second; + if ( !processedGroup ) + newShape = newGroupShape( *data ); + if ( newShape.IsNull() ) + continue; // no changes + + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); + + if ( processedGroup ) { // update group indices + list::iterator data2 = data; + for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {} + data->_indices = data2->_indices; } - // update hypotheses and submeshes if necessary - if ( groupChanged ) + + // Update SMESH objects according to new GEOM group contents + + SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject ); + if ( !submesh->_is_nil() ) // -------------- Sub mesh --------------------- { - // get a new group shape - GEOM_Client* geomClient = _gen_i->GetShapeReader(); - if ( !geomClient ) continue; - TCollection_AsciiString groupIOR = _gen_i->GetGeomEngine()->GetStringFromIOR( groupObj ); - geomClient->RemoveShapeFromBuffer( groupIOR ); - TopoDS_Shape newGroupShape = _gen_i->GeomObjectToShape( groupObj ); + int oldID = submesh->GetId(); + if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() ) + continue; + TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape(); + // update hypotheses - list hyps = _impl->GetHypothesisList(oldGroupShape); + list hyps = _impl->GetHypothesisList(oldShape); list ::iterator hypIt; for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) { - _impl->RemoveHypothesis( oldGroupShape, (*hypIt)->GetID()); - _impl->AddHypothesis ( newGroupShape, (*hypIt)->GetID()); + _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID()); + _impl->AddHypothesis ( newShape, (*hypIt)->GetID()); } // care of submeshes - SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newGroupShape ); + SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape ); int newID = newSubmesh->GetId(); if ( newID != oldID ) { _mapSubMesh [ newID ] = newSubmesh; _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; - _mapSubMesh.erase (oldID); - _mapSubMesh_i.erase (oldID); + _mapSubMesh. erase(oldID); + _mapSubMesh_i. erase(oldID); _mapSubMeshIor.erase(oldID); _mapSubMesh_i [ newID ]->changeLocalId( newID ); } + continue; } - } -} -//============================================================================= -/*! - * \brief Create standalone group instead if group on geometry - * - */ -//============================================================================= + SMESH::SMESH_GroupOnGeom_var smeshGroup = + SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject ); + if ( !smeshGroup->_is_nil() ) // ------------ GROUP ----------------------- + { + SMESH_GroupOnGeom_i* group_i = SMESH::DownCast( smeshGroup ); + if ( group_i ) { + ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() ); + SMESHDS_GroupOnGeom* ds = static_cast( group->GetGroupDS() ); + ds->SetShape( newShape ); + } + continue; + } -SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup ) -{ - SMESH::SMESH_Group_var aGroup; - if ( theGroup->_is_nil() ) + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject ); + if ( !mesh->_is_nil() ) // -------------- MESH ---------------------------- + { + // Remove groups and submeshes basing on removed sub-shapes + + TopTools_MapOfShape newShapeMap; + TopoDS_Iterator shapeIt( newShape ); + for ( ; shapeIt.More(); shapeIt.Next() ) + newShapeMap.Add( shapeIt.Value() ); + + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); + for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() ) + { + if ( newShapeMap.Contains( shapeIt.Value() )) + continue; + TopTools_IndexedMapOfShape oldShapeMap; + TopExp::MapShapes( shapeIt.Value(), oldShapeMap ); + for ( int i = 1; i <= oldShapeMap.Extent(); ++i ) + { + const TopoDS_Shape& oldShape = oldShapeMap(i); + int oldInd = meshDS->ShapeToIndex( oldShape ); + // -- submeshes -- + map::iterator i_smIor = _mapSubMeshIor.find( oldInd ); + if ( i_smIor != _mapSubMeshIor.end() ) { + RemoveSubMesh( i_smIor->second ); // one submesh per shape index + } + // --- groups --- + map::iterator i_grp = _mapGroups.begin(); + for ( ; i_grp != _mapGroups.end(); ++i_grp ) + { + // check if a group bases on oldInd shape + SMESHDS_GroupOnGeom* grpOnGeom = 0; + if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first )) + grpOnGeom = dynamic_cast( g->GetGroupDS() ); + if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() )) + { // remove + RemoveGroup( i_grp->second ); // several groups can base on same shape + i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration + } + } + } + } + // Reassign hypotheses and update groups after setting the new shape to mesh + + // collect anassigned hypotheses + typedef list< pair< TIndexedShape, list > > TShapeHypList; + list ::const_iterator hypIt; + TShapeHypList assignedHyps; + for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i ) + { + const TopoDS_Shape& oldShape = meshDS->IndexToShape(i); + list hyps = meshDS->GetHypothesis( oldShape );// copy + if ( !hyps.empty() ) { + assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps )); + for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) + _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID()); + } + } + // collect shapes supporting groups + typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList; + TShapeTypeList groupData; + const set& groups = meshDS->GetGroups(); + set::const_iterator grIt = groups.begin(); + for ( ; grIt != groups.end(); ++grIt ) + { + if ( SMESHDS_GroupOnGeom* gog = dynamic_cast( *grIt )) + groupData.push_back + ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType())); + } + // set new shape to mesh -> DS of submeshes and geom groups is deleted + _impl->ShapeToMesh( newShape ); + + // reassign hypotheses + TShapeHypList::iterator indS_hyps = assignedHyps.begin(); + for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps ) + { + TIndexedShape& geom = indS_hyps->first; + list& hyps = indS_hyps->second; + int oldID = geom._index; + int newID = meshDS->ShapeToIndex( geom._shape ); + if ( !newID ) + continue; + if ( oldID == 1 ) { // main shape + newID = 1; + geom._shape = newShape; + } + for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) + _impl->AddHypothesis( geom._shape, (*hypIt)->GetID()); + // care of submeshes + SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape ); + if ( newID != oldID ) { + _mapSubMesh [ newID ] = newSubmesh; + _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; + _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; + _mapSubMesh. erase(oldID); + _mapSubMesh_i. erase(oldID); + _mapSubMeshIor.erase(oldID); + _mapSubMesh_i [ newID ]->changeLocalId( newID ); + } + } + // recreate groups + TShapeTypeList::iterator geomType = groupData.begin(); + for ( ; geomType != groupData.end(); ++geomType ) + { + const TIndexedShape& geom = geomType->first; + int oldID = geom._index; + if ( _mapGroups.find( oldID ) == _mapGroups.end() ) + continue; + // get group name + SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] ); + CORBA::String_var name = groupSO->GetName(); + // update + SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID] ); + int newID; + if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape )) + group_i->changeLocalId( newID ); + } + + break; // everything has been updated + + } // update mesh + } // loop on group data + + // Update icons + + CORBA::Long newNbEntities = NbNodes() + NbElements(); + list< SALOMEDS::SObject_var > soToUpdateIcons; + if ( newNbEntities != nbEntities ) + { + // Add all SObjects with icons to soToUpdateIcons + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh + + for (map::iterator i_sm = _mapSubMeshIor.begin(); + i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second )); + + for ( map::iterator i_gr = _mapGroups.begin(); + i_gr != _mapGroups.end(); ++i_gr ) // groups + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second )); + } + + list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin(); + for ( ; so != soToUpdateIcons.end(); ++so ) + _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" ); +} + +//============================================================================= +/*! + * \brief Create standalone group from a group on geometry or filter + */ +//============================================================================= + +SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup ) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::SMESH_Group_var aGroup; + if ( theGroup->_is_nil() ) return aGroup._retn(); Unexpect aCatch(SALOME_SalomeException); @@ -1647,13 +2077,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe if ( !aGroupToRem ) return aGroup._retn(); + const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )); + int anId = aGroupToRem->GetLocalID(); if ( !_impl->ConvertToStandalone( anId ) ) return aGroup._retn(); + removeGeomGroupData( theGroup ); - SMESH_GroupBase_i* aGroupImpl; - aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); - + SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); // remove old instance of group from own map _mapGroups.erase( anId ); @@ -1666,15 +2097,29 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); if ( !aGroupSO->_is_nil() ) { - // remove reference to geometry - SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO); - for ( ; chItr->More(); chItr->Next() ) - // Remove group's child SObject - builder->RemoveObject( chItr->Value() ); + // remove reference to geometry + SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO); + for ( ; chItr->More(); chItr->Next() ) + // Remove group's child SObject + builder->RemoveObject( chItr->Value() ); // Update Python script TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( " << aGroupSO << " )"; + + // change icon of Group on Filter + if ( isOnFilter ) + { + SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes(); + const int isEmpty = ( elemTypes->length() == 0 ); + if ( !isEmpty ) + { + SALOMEDS::GenericAttribute_var anAttr = + builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" ); + SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr ); + pm->SetPixMap( "ICON_SMESH_TREE_GROUP" ); + } + } } } @@ -1688,8 +2133,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup ); // register CORBA object for persistence - //int nextId = _gen_i->RegisterObject( aGroup ); - //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); + /*int nextId =*/ _gen_i->RegisterObject( aGroup ); + builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) ); return aGroup._retn(); @@ -1720,6 +2165,9 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theS int nextId = _gen_i->RegisterObject( subMesh ); if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId); + // to track changes of GEOM groups + addGeomGroupData( theSubShapeObject, subMesh ); + return subMesh._retn(); } @@ -1744,29 +2192,50 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID) */ //============================================================================= -void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, +bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Object_ptr theSubShapeObject ) { - MESSAGE("SMESH_Mesh_i::removeSubMesh()"); - if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() ) - return; + bool isHypChanged = false; + if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ ) + return isHypChanged; - try { - SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject ); - for ( int i = 0, n = aHypList->length(); i < n; i++ ) { - removeHypothesis( theSubShapeObject, aHypList[i] ); + if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617) + { + CORBA::Long shapeId = theSubMesh->GetId(); + if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end()) + { + TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape(); + if ( !S.IsNull() ) + { + list hyps = _impl->GetHypothesisList( S ); + isHypChanged = !hyps.empty(); + list::const_iterator hyp = hyps.begin(); + for ( ; hyp != hyps.end(); ++hyp ) + _impl->RemoveHypothesis(S, (*hyp)->GetID()); + } } } - catch( const SALOME::SALOME_Exception& ) { - INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!"); + else + { + try { + SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject ); + isHypChanged = ( aHypList->length() > 0 ); + for ( int i = 0, n = aHypList->length(); i < n; i++ ) { + removeHypothesis( theSubShapeObject, aHypList[i] ); + } + } + catch( const SALOME::SALOME_Exception& ) { + INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!"); + } + removeGeomGroupData( theSubShapeObject ); } - int subMeshId = theSubMesh->GetId(); _mapSubMesh.erase(subMeshId); _mapSubMesh_i.erase(subMeshId); _mapSubMeshIor.erase(subMeshId); - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed"); + + return isHypChanged; } //============================================================================= @@ -1775,16 +2244,32 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, */ //============================================================================= -SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType, - const char* theName, - const TopoDS_Shape& theShape ) +SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType, + const char* theName, + const TopoDS_Shape& theShape, + const SMESH_PredicatePtr& thePredicate ) { + std::string newName; + if ( !theName || strlen( theName ) == 0 ) + { + std::set< std::string > presentNames; + std::map::const_iterator i_gr = _mapGroups.begin(); + for ( ; i_gr != _mapGroups.end(); ++i_gr ) + presentNames.insert( i_gr->second->GetName() ); + do { + newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 ); + } while ( !presentNames.insert( newName ).second ); + theName = newName.c_str(); + } int anId; SMESH::SMESH_GroupBase_var aGroup; - if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) { + if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate )) + { SMESH_GroupBase_i* aGroupImpl; if ( !theShape.IsNull() ) aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId ); + else if ( thePredicate ) + aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId ); else aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); @@ -1799,6 +2284,12 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElem // register CORBA object for persistence int nextId = _gen_i->RegisterObject( aGroup ); if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); + + // to track changes of GEOM groups + if ( !theShape.IsNull() ) { + GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape ); + addGeomGroupData( geom, aGroup ); + } } return aGroup._retn(); } @@ -1815,12 +2306,17 @@ void SMESH_Mesh_i::removeGroup( const int theId ) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" ); if ( _mapGroups.find( theId ) != _mapGroups.end() ) { + SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId]; _mapGroups.erase( theId ); - _impl->RemoveGroup( theId ); + removeGeomGroupData( group ); + if (! _impl->RemoveGroup( theId )) + { + // it seems to be a call up from _impl caused by hyp modification (issue 0020918) + RemoveGroup( group ); + } } } - //============================================================================= /*! * @@ -1830,7 +2326,8 @@ void SMESH_Mesh_i::removeGroup( const int theId ) SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) throw(SALOME::SALOME_Exception) { - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog"); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); SMESH::log_array_var aLog; try{ @@ -1860,14 +2357,14 @@ throw(SALOME::SALOME_Exception) aLog[indexLog].coords.length(rnum); aLog[indexLog].indexes.length(inum); for(int i = 0; i < rnum; i++){ - aLog[indexLog].coords[i] = *ir; - //MESSAGE(" "<ClearLog(); } //============================================================================= @@ -1917,6 +2414,34 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception) return _studyId; } +//============================================================================= +namespace +{ + //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh + // issue 0020918: groups removal is caused by hyp modification + // issue 0021208: to forget not loaded mesh data at hyp modification + struct TCallUp_i : public SMESH_Mesh::TCallUp + { + SMESH_Mesh_i* _mesh; + TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {} + virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); } + virtual void HypothesisModified () { _mesh->onHypothesisModified(); } + virtual void Load () { _mesh->Load(); } + }; +} + +//================================================================================ +/*! + * \brief callback from _impl to forget not loaded mesh data (issue 0021208) + */ +//================================================================================ + +void SMESH_Mesh_i::onHypothesisModified() +{ + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); +} + //============================================================================= /*! * @@ -1927,6 +2452,8 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl"); _impl = impl; + if ( _impl ) + _impl->SetCallUp( new TCallUp_i(this)); } //============================================================================= @@ -1949,6 +2476,9 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl) SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + // Create MeshEditor SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false ); SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this(); @@ -1967,37 +2497,102 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer() { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true ); SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this(); return aMesh._retn(); } +//================================================================================ +/*! + * \brief Return true if the mesh has been edited since a last total re-compute + * and those modifications may prevent successful partial re-compute + */ +//================================================================================ + +CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + return _impl->HasModificationsToDiscard(); +} + +//================================================================================ +/*! + * \brief Returns a random unique color + */ +//================================================================================ + +static SALOMEDS::Color getUniqueColor( const std::list& theReservedColors ) +{ + const int MAX_ATTEMPTS = 100; + int cnt = 0; + double tolerance = 0.5; + SALOMEDS::Color col; + + bool ok = false; + while ( !ok ) { + // generate random color + double red = (double)rand() / RAND_MAX; + double green = (double)rand() / RAND_MAX; + double blue = (double)rand() / RAND_MAX; + // check existence in the list of the existing colors + bool matched = false; + std::list::const_iterator it; + for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) { + SALOMEDS::Color color = *it; + double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue ); + matched = tol < tolerance; + } + if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2; + ok = ( ++cnt == MAX_ATTEMPTS ) || !matched; + col.R = red; + col.G = green; + col.B = blue; + } + return col; +} + //============================================================================= /*! - * + * Sets auto-color mode. If it is on, groups get unique random colors */ //============================================================================= + void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); _impl->SetAutoColor(theAutoColor); + + TPythonDump pyDump; // not to dump group->SetColor() from below code + pyDump<<_this()<<".SetAutoColor( "< aReservedColors; + map::iterator it = _mapGroups.begin(); + for ( ; it != _mapGroups.end(); it++ ) { + if ( CORBA::is_nil( it->second )) continue; + SALOMEDS::Color aColor = getUniqueColor( aReservedColors ); + it->second->SetColor( aColor ); + aReservedColors.push_back( aColor ); + } } //============================================================================= /*! - * + * Returns true if auto-color mode is on */ //============================================================================= + CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); return _impl->GetAutoColor(); } - //============================================================================= /*! - * Export in different formats + * Checks if there are groups with equal names */ //============================================================================= @@ -2006,7 +2601,13 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED() return _impl->HasDuplicatedGroupNamesMED(); } -void SMESH_Mesh_i::PrepareForWriting (const char* file) +//================================================================================ +/*! + * \brief Care of a file before exporting mesh into it + */ +//================================================================================ + +void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) { TCollection_AsciiString aFullName ((char*)file); OSD_Path aPath (aFullName); @@ -2015,8 +2616,10 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file) // existing filesystem node if (aFile.KindOfFile() == OSD_FILE) { if (aFile.IsWriteable()) { - aFile.Reset(); - aFile.Remove(); + if (overwrite) { + aFile.Reset(); + aFile.Remove(); + } if (aFile.Failed()) { TCollection_AsciiString msg ("File "); msg += aFullName + " cannot be replaced."; @@ -2047,98 +2650,188 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file) } } -void SMESH_Mesh_i::ExportToMED (const char* file, - CORBA::Boolean auto_groups, - SMESH::MED_VERSION theVersion) - throw(SALOME::SALOME_Exception) -{ - Unexpect aCatch(SALOME_SalomeException); +//================================================================================ +/*! + * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS + * \param file - file name + * \param overwrite - to erase the file or not + * \retval string - mesh name + */ +//================================================================================ +string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, + CORBA::Boolean overwrite) +{ // Perform Export - PrepareForWriting(file); - const char* aMeshName = "Mesh"; + PrepareForWriting(file, overwrite); + string aMeshName = "Mesh"; SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() ); if ( !aMeshSO->_is_nil() ) { - aMeshName = aMeshSO->GetName(); + CORBA::String_var name = aMeshSO->GetName(); + aMeshName = name; // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes if ( !aStudy->GetProperties()->IsLocked() ) - { - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); - SALOMEDS::AttributeExternalFileDef_var aFileName; - anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef"); - aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr); - ASSERT(!aFileName->_is_nil()); + { + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::AttributeExternalFileDef_var aFileName; + anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef"); + aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr); + ASSERT(!aFileName->_is_nil()); aFileName->SetValue(file); SALOMEDS::AttributeFileType_var aFileType; anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType"); aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr); ASSERT(!aFileType->_is_nil()); aFileType->SetValue("FICHIERMED"); - } + } } } // Update Python script // set name of mesh before export - TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')"; - + TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')"; + // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportToMED( '" - << file << "', " << auto_groups << ", " << theVersion << " )"; + return aMeshName; +} + +//================================================================================ +/*! + * \brief Export to med file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportToMEDX (const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION theVersion, + CORBA::Boolean overwrite) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + string aMeshName = prepareMeshNameAndGroups(file, overwrite); + TPythonDump() << _this() << ".ExportToMEDX( r'" + << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )"; + + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion ); +} + +//================================================================================ +/*! + * \brief Export a mesh to a med file + */ +//================================================================================ - _impl->ExportMED( file, aMeshName, auto_groups, theVersion ); +void SMESH_Mesh_i::ExportToMED (const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION theVersion) + throw(SALOME::SALOME_Exception) +{ + ExportToMEDX(file,auto_groups,theVersion,true); } +//================================================================================ +/*! + * \brief Export a mesh to a med file + */ +//================================================================================ + void SMESH_Mesh_i::ExportMED (const char* file, - CORBA::Boolean auto_groups) + CORBA::Boolean auto_groups) + throw(SALOME::SALOME_Exception) +{ + ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true); +} + +//================================================================================ +/*! + * \brief Export a mesh to a SAUV file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportSAUV (const char* file, + CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception) { - ExportToMED(file,auto_groups,SMESH::MED_V2_1); + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + string aMeshName = prepareMeshNameAndGroups(file, true); + TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )"; + _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups); } + +//================================================================================ +/*! + * \brief Export a mesh to a DAT file + */ +//================================================================================ + void SMESH_Mesh_i::ExportDAT (const char *file) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportDAT( '" << file << "' )"; + TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )"; // Perform Export PrepareForWriting(file); _impl->ExportDAT(file); } +//================================================================================ +/*! + * \brief Export a mesh to an UNV file + */ +//================================================================================ + void SMESH_Mesh_i::ExportUNV (const char *file) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportUNV( '" << file << "' )"; + TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )"; // Perform Export PrepareForWriting(file); _impl->ExportUNV(file); } +//================================================================================ +/*! + * \brief Export a mesh to an STL file + */ +//================================================================================ + void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )"; + TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )"; // Perform Export PrepareForWriting(file); @@ -2147,84 +2840,282 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) //============================================================================= /*! - * + * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource. + * It is used to export a part of mesh as a whole mesh. */ -//============================================================================= - -SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception) +class SMESH_MeshPartDS : public SMESHDS_Mesh { - Unexpect aCatch(SALOME_SalomeException); - SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this); - SALOME_MED::MESH_var aMesh = aMedMesh->_this(); - return aMesh._retn(); -} +public: + SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart); + + virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; + virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const; + virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const; + virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const; + + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; + virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const; + virtual SMDS_ElemIteratorPtr elementEntityIterator(SMDSAbs_EntityType type) const; + +private: + TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ]; + SMESHDS_Mesh* _meshDS; + /*! + * \brief Class used to access to protected data of SMDS_MeshInfo + */ + struct TMeshInfo : public SMDS_MeshInfo + { + void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); } + }; +}; -//============================================================================= +//================================================================================ /*! - * + * \brief Export a part of mesh to a med file */ -//============================================================================= -CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) +//================================================================================ + +void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + ::SMESH::MED_VERSION version, + ::CORBA::Boolean overwrite) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - return _impl->NbNodes(); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + PrepareForWriting(file, overwrite); + + string aMeshName = "Mesh"; + SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart ); + if ( !SO->_is_nil() ) { + CORBA::String_var name = SO->GetName(); + aMeshName = name; + } + } + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS ); + + TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', " + << auto_groups << ", " << version << ", " << overwrite << " )"; } -//============================================================================= +//================================================================================ /*! - * + * \brief Export a part of mesh to a DAT file */ -//============================================================================= -CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception) +//================================================================================ + +void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - return NbEdges() + NbFaces() + NbVolumes(); -} + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); -//============================================================================= + PrepareForWriting(file); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportDAT(file,&partDS); + + TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )"; +} +//================================================================================ /*! - * + * \brief Export a part of mesh to an UNV file */ -//============================================================================= -CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception) +//================================================================================ + +void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - return _impl->NbEdges(); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + PrepareForWriting(file); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportUNV(file, &partDS); + + TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )"; } +//================================================================================ +/*! + * \brief Export a part of mesh to an STL file + */ +//================================================================================ -CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order) - throw(SALOME::SALOME_Exception) +void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + ::CORBA::Boolean isascii) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - return _impl->NbEdges( (SMDSAbs_ElementOrder) order); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + PrepareForWriting(file); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportSTL(file, isascii, &partDS); + + TPythonDump() << _this() << ".ExportPartToSTL( " + << meshPart<< ", r'" << file << "', " << isascii << ")"; } -//============================================================================= +//================================================================================ /*! - * + * \brief Export a part of mesh to an STL file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean overwrite) + throw (SALOME::SALOME_Exception) +{ +#ifdef WITH_CGNS + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + PrepareForWriting(file,overwrite); + + SMESH_MeshPartDS partDS( meshPart ); + _impl->ExportCGNS(file, &partDS); + + TPythonDump() << _this() << ".ExportCGNS( " + << meshPart<< ", r'" << file << "', " << overwrite << ")"; +#else + THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); +#endif +} + +//============================================================================= +/*! + * Return implementation of SALOME_MED::MESH interfaces */ //============================================================================= + +SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this); + SALOME_MED::MESH_var aMesh = aMedMesh->_this(); + return aMesh._retn(); +} + +//============================================================================= + +CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbNodes(); + + return _impl->NbNodes(); +} + +CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbElements(); + + return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls(); +} + +CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->Nb0DElements(); + + return _impl->Nb0DElements(); +} + +CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbBalls(); + + return _impl->NbBalls(); +} + +CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbEdges(); + + return _impl->NbEdges(); +} + +CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order ); + + return _impl->NbEdges( (SMDSAbs_ElementOrder) order); +} + +//============================================================================= + CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbFaces(); + return _impl->NbFaces(); } CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbTriangles(); + return _impl->NbTriangles(); } CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbQuadrangles(); + return _impl->NbQuadrangles(); } +CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbBiQuadQuadrangles(); + + return _impl->NbBiQuadQuadrangles(); +} + CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPolygons(); + return _impl->NbPolygons(); } @@ -2232,6 +3123,9 @@ CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order ); + return _impl->NbFaces( (SMDSAbs_ElementOrder) order); } @@ -2239,6 +3133,9 @@ CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order ); + return _impl->NbTriangles( (SMDSAbs_ElementOrder) order); } @@ -2246,47 +3143,83 @@ CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order ); + return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order); } //============================================================================= -/*! - * - */ -//============================================================================= + CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbVolumes(); + return _impl->NbVolumes(); } CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbTetras(); + return _impl->NbTetras(); } CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbHexas(); + return _impl->NbHexas(); } +CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbTriQuadHexas(); + + return _impl->NbTriQuadraticHexas(); +} + CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPyramids(); + return _impl->NbPyramids(); } CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPrisms(); + return _impl->NbPrisms(); } +CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbHexPrisms(); + + return _impl->NbHexagonalPrisms(); +} + CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPolyhedrons(); + return _impl->NbPolyhedrons(); } @@ -2294,6 +3227,9 @@ CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order ); + return _impl->NbVolumes( (SMDSAbs_ElementOrder) order); } @@ -2301,6 +3237,9 @@ CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order); + return _impl->NbTetras( (SMDSAbs_ElementOrder) order); } @@ -2308,6 +3247,9 @@ CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order); + return _impl->NbHexas( (SMDSAbs_ElementOrder) order); } @@ -2315,6 +3257,9 @@ CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order); + return _impl->NbPyramids( (SMDSAbs_ElementOrder) order); } @@ -2322,14 +3267,18 @@ CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order); + return _impl->NbPrisms( (SMDSAbs_ElementOrder) order); } //============================================================================= /*! - * + * Returns nb of published sub-meshes */ //============================================================================= + CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -2338,41 +3287,31 @@ CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception) //============================================================================= /*! - * + * Dumps mesh into a string */ //============================================================================= + char* SMESH_Mesh_i::Dump() { - std::ostringstream os; + ostringstream os; _impl->Dump( os ); return CORBA::string_dup( os.str().c_str() ); } //============================================================================= /*! - * + * Method of SMESH_IDSource interface */ //============================================================================= + SMESH::long_array* SMESH_Mesh_i::GetIDs() { -// SMESH::long_array_var aResult = new SMESH::long_array(); -// SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); -// int aMinId = aSMESHDS_Mesh->MinElementID(); -// int aMaxId = aSMESHDS_Mesh->MaxElementID(); - -// aResult->length(aMaxId - aMinId + 1); - -// for (int i = 0, id = aMinId; id <= aMaxId; id++ ) -// aResult[i++] = id; - -// return aResult._retn(); - // PAL12398 return GetElementsId(); } //============================================================================= /*! - * + * Returns ids of all elements */ //============================================================================= @@ -2380,7 +3319,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsId() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_Mesh_i::GetElementsId"); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aResult = new SMESH::long_array(); SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); @@ -2399,7 +3340,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsId() //============================================================================= /*! - * + * Returns ids of all elements of given type */ //============================================================================= @@ -2407,7 +3348,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetElementsByType"); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aResult = new SMESH::long_array(); SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); @@ -2419,7 +3362,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy // No sense in returning ids of elements along with ids of nodes: // when theElemType == SMESH::ALL, return node ids only if // there are no elements - if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 ) + if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) ) return GetNodesId(); aResult->length( nbElements ); @@ -2440,7 +3383,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy //============================================================================= /*! - * + * Returns ids of all nodes */ //============================================================================= @@ -2448,7 +3391,9 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetNodesId"); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aResult = new SMESH::long_array(); SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); @@ -2457,7 +3402,7 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() long nbNodes = NbNodes(); aResult->length( nbNodes ); - SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(); + SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true); for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); @@ -2473,9 +3418,30 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + return ( SMESH::ElementType )_impl->GetElementType( id, iselem ); } +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id ) + throw (SALOME::SALOME_Exception) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id); + if ( !e ) + THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM ); + + return ( SMESH::EntityType ) e->GetEntityType(); +} //============================================================================= /*! @@ -2485,6 +3451,9 @@ SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const boo SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aResult = new SMESH::long_array(); SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID); @@ -2512,9 +3481,13 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) * returns only nodes on shapes. */ //============================================================================= -SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all) - throw (SALOME::SALOME_Exception) +SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, + CORBA::Boolean all) + throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aResult = new SMESH::long_array(); SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID); @@ -2552,15 +3525,18 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CO return aResult._retn(); } - //============================================================================= /*! * Returns type of elements for given submesh */ //============================================================================= + SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID); if(!SM) return SMESH::ALL; @@ -2578,12 +3554,15 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID //============================================================================= /*! - * + * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client */ //============================================================================= CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + CORBA::LongLong pointeur = CORBA::LongLong(_impl); if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<FullLoadFromFile(); + SMESH::double_array_var aResult = new SMESH::double_array(); SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) @@ -2628,6 +3610,9 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id) SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aResult = new SMESH::long_array(); SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) @@ -2663,6 +3648,9 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::NodePosition* aNodePosition = new SMESH::NodePosition(); aNodePosition->shapeID = 0; aNodePosition->shapeType = GEOM::SHAPE; @@ -2674,21 +3662,21 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) { if ( SMDS_PositionPtr pos = aNode->GetPosition() ) { - aNodePosition->shapeID = pos->GetShapeId(); + aNodePosition->shapeID = aNode->getshapeId(); switch ( pos->GetTypeOfPosition() ) { case SMDS_TOP_EDGE: aNodePosition->shapeType = GEOM::EDGE; aNodePosition->params.length(1); aNodePosition->params[0] = - static_cast( pos.get() )->GetUParameter(); + static_cast( pos )->GetUParameter(); break; case SMDS_TOP_FACE: aNodePosition->shapeType = GEOM::FACE; aNodePosition->params.length(2); aNodePosition->params[0] = - static_cast( pos.get() )->GetUParameter(); + static_cast( pos )->GetUParameter(); aNodePosition->params[1] = - static_cast( pos.get() )->GetVParameter(); + static_cast( pos )->GetVParameter(); break; case SMDS_TOP_VERTEX: aNodePosition->shapeType = GEOM::VERTEX; @@ -2715,6 +3703,9 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return -1; @@ -2722,11 +3713,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) // try to find node const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); if(aNode) { - SMDS_PositionPtr pos = aNode->GetPosition(); - if(!pos) - return -1; - else - return pos->GetShapeId(); + return aNode->getshapeId(); } return -1; @@ -2743,6 +3730,9 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return -1; @@ -2771,6 +3761,9 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id) CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return -1; // try to find element @@ -2790,6 +3783,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id) CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return -1; const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); @@ -2806,6 +3802,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long in SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::long_array_var aResult = new SMESH::long_array(); if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() ) { @@ -2828,6 +3827,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return false; // try to find node @@ -2851,6 +3853,9 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Lo CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn, SMESH::ElementType theElemType) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return false; @@ -2878,6 +3883,9 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn, CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return -1; const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); @@ -2894,6 +3902,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id) CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return -1; const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); @@ -2901,6 +3912,63 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id) return elem->NbFaces(); } +//======================================================================= +//function : GetElemFaceNodes +//purpose : Returns nodes of given face (counted from zero) for given element. +//======================================================================= + +SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, + CORBA::Short faceIndex) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::long_array_var aResult = new SMESH::long_array(); + if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() ) + { + if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) ) + { + SMDS_VolumeTool vtool( elem ); + if ( faceIndex < vtool.NbFaces() ) + { + aResult->length( vtool.NbFaceNodes( faceIndex )); + const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex ); + for ( int i = 0; i < aResult->length(); ++i ) + aResult[ i ] = nn[ i ]->GetID(); + } + } + } + return aResult._retn(); +} + +//======================================================================= +//function : FindElementByNodes +//purpose : Returns an element based on all given nodes. +//======================================================================= + +CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + CORBA::Long elemID(0); + if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) + { + vector< const SMDS_MeshNode * > nn( nodes.length() ); + for ( int i = 0; i < nodes.length(); ++i ) + if ( !( nn[i] = mesh->FindNode( nodes[i] ))) + return elemID; + + const SMDS_MeshElement* elem = mesh->FindElement( nn ); + if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) || + _impl->NbFaces ( ORDER_QUADRATIC ) || + _impl->NbVolumes( ORDER_QUADRATIC ))) + elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true ); + + if ( elem ) elemID = CORBA::Long( elem->GetID() ); + } + return elemID; +} //============================================================================= /*! @@ -2910,6 +3978,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id) CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return false; const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); @@ -2926,6 +3997,9 @@ CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id) CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) return false; const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); @@ -2933,6 +4007,23 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id) return elem->IsQuadratic(); } +//============================================================================= +/*! + * Returns diameter of ball discrete element or zero in case of an invalid \a id + */ +//============================================================================= + +CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + if ( const SMDS_BallElement* ball = + dynamic_cast( _impl->GetMeshDS()->FindElement( id ))) + return ball->GetDiameter(); + + return 0; +} //============================================================================= /*! @@ -2942,6 +4033,9 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id) SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + SMESH::double_array_var aResult = new SMESH::double_array(); SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); if ( aSMESHDS_Mesh == NULL ) @@ -2993,6 +4087,7 @@ void SMESH_Mesh_i::CreateGroupServants() { SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + set addedIDs; ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups(); while ( groupIt->more() ) { @@ -3002,6 +4097,7 @@ void SMESH_Mesh_i::CreateGroupServants() map::iterator it = _mapGroups.find(anId); if ( it != _mapGroups.end() && !CORBA::is_nil( it->second )) continue; + addedIDs.insert( anId ); SMESH_GroupBase_i* aGroupImpl; TopoDS_Shape shape; @@ -3027,12 +4123,23 @@ void SMESH_Mesh_i::CreateGroupServants() int nextId = _gen_i->RegisterObject( groupVar ); if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); - // publishing of the groups in the study + // publishing the groups in the study if ( !aStudy->_is_nil() ) { GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape ); _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName()); } } + if ( !addedIDs.empty() ) + { + // python dump + set::iterator id = addedIDs.begin(); + for ( ; id != addedIDs.end(); ++id ) + { + map::iterator it = _mapGroups.find(*id); + int i = std::distance( _mapGroups.begin(), it ); + TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]"; + } + } } //============================================================================= @@ -3066,7 +4173,7 @@ SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list& groupIDs) const SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo() { - SALOME_MED::MedFileInfo_var res( myFileInfo ); + SALOME_MED::MedFileInfo_var res( _medFileInfo ); if ( !res.operator->() ) { res = new SALOME_MED::MedFileInfo; res->fileName = ""; @@ -3077,7 +4184,7 @@ SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo() //============================================================================= /*! - * \brief Check and correct names of mesh groups + * \brief Pass names of mesh groups from study to mesh DS */ //============================================================================= @@ -3120,8 +4227,9 @@ void SMESH_Mesh_i::checkGroupNames() //============================================================================= void SMESH_Mesh_i::SetParameters(const char* theParameters) { - SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()), - CORBA::string_dup(theParameters)); + // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()), + // CORBA::string_dup(theParameters)); + SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters); } //============================================================================= @@ -3159,3 +4267,653 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() } return aResult._retn(); } + +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes() +{ + if ( _preMeshInfo ) + return _preMeshInfo->GetTypes(); + + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + types->length( 5 ); + int nbTypes = 0; + if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE; + if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE; + if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME; + if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D; + if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL; + types->length( nbTypes ); + + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : Returns self +//======================================================================= + +SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() +{ + return SMESH::SMESH_Mesh::_duplicate( _this() ); +} + +//======================================================================= +//function : IsMeshInfoCorrect +//purpose : * Returns false if GetMeshInfo() returns incorrect information that may +// * happen if mesh data is not yet fully loaded from the file of study. +//======================================================================= + +bool SMESH_Mesh_i::IsMeshInfoCorrect() +{ + return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true; +} + +//============================================================================= +/*! + * \brief Returns statistic of mesh elements + */ +//============================================================================= + +SMESH::long_array* SMESH_Mesh_i::GetMeshInfo() +{ + if ( _preMeshInfo ) + return _preMeshInfo->GetMeshInfo(); + + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if (!aMeshDS) + return aRes._retn(); + const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo(); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i); + return aRes._retn(); +} + +//============================================================================= +/*! + * \brief Collect statistic of mesh elements given by iterator + */ +//============================================================================= + +void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, + SMESH::long_array& theInfo) +{ + if (!theItr) return; + while (theItr->more()) + theInfo[ theItr->next()->GetEntityType() ]++; +} + +//============================================================================= +/*! + * \brief mapping of mesh dimension into shape type + */ +//============================================================================= + +static TopAbs_ShapeEnum shapeTypeByDim(const int theDim) +{ + TopAbs_ShapeEnum aType = TopAbs_SOLID; + switch ( theDim ) { + case 0: aType = TopAbs_VERTEX; break; + case 1: aType = TopAbs_EDGE; break; + case 2: aType = TopAbs_FACE; break; + case 3: + default:aType = TopAbs_SOLID; break; + } + return aType; +} + +//============================================================================= +/*! + * \brief Internal structure used to find concurent submeshes + * + * It represents a pair < submesh, concurent dimension >, where + * 'concurrent dimension' is dimension of shape where the submesh can concurent + * with another submesh. In other words, it is dimension of a hypothesis assigned + * to submesh. + */ +//============================================================================= + +class SMESH_DimHyp +{ + public: + //! fileds + int _dim; //!< a dimension the algo can build (concurrent dimension) + int _ownDim; //!< dimension of shape of _subMesh (>=_dim) + TopTools_MapOfShape _shapeMap; + SMESH_subMesh* _subMesh; + list _hypothesises; //!< algo is first, then its parameters + + //! Constructors + SMESH_DimHyp(const SMESH_subMesh* theSubMesh, + const int theDim, + const TopoDS_Shape& theShape) + { + _subMesh = (SMESH_subMesh*)theSubMesh; + SetShape( theDim, theShape ); + } + + //! set shape + void SetShape(const int theDim, + const TopoDS_Shape& theShape) + { + _dim = theDim; + _ownDim = (int)SMESH_Gen::GetShapeDim(theShape); + if (_dim >= _ownDim) + _shapeMap.Add( theShape ); + else { + TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) ); + for( ; anExp.More(); anExp.Next() ) + _shapeMap.Add( anExp.Current() ); + } + } + + //! Check sharing of sub-shapes + static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck, + const TopTools_MapOfShape& theToFind, + const TopAbs_ShapeEnum theType) + { + bool isShared = false; + TopTools_MapIteratorOfMapOfShape anItr( theToCheck ); + for (; !isShared && anItr.More(); anItr.Next() ) + { + const TopoDS_Shape aSubSh = anItr.Key(); + // check for case when concurrent dimensions are same + isShared = theToFind.Contains( aSubSh ); + // check for sub-shape with concurrent dimension + TopExp_Explorer anExp( aSubSh, theType ); + for ( ; !isShared && anExp.More(); anExp.Next() ) + isShared = theToFind.Contains( anExp.Current() ); + } + return isShared; + } + + //! check algorithms + static bool checkAlgo(const SMESHDS_Hypothesis* theA1, + const SMESHDS_Hypothesis* theA2) + { + if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO || + theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ) + return false; // one of the hypothesis is not algorithm + // check algorithm names (should be equal) + return strcmp( theA1->GetName(), theA2->GetName() ) == 0; + } + + + //! Check if sub-shape hypotheses are concurrent + bool IsConcurrent(const SMESH_DimHyp* theOther) const + { + if ( _subMesh == theOther->_subMesh ) + return false; // same sub-shape - should not be + + // if ( == && + // any of the two submeshes is not on COMPOUND shape ) + // -> no concurrency + bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh()); + bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh()); + if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound)) + return false; + +// bool checkSubShape = ( _dim >= theOther->_dim ) +// ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) ) +// : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ; + bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim)); + if ( !checkSubShape ) + return false; + + // check algorithms to be same + if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() )) + return true; // different algorithms + + // check hypothesises for concurrence (skip first as algorithm) + int nbSame = 0; + // pointers should be same, becase it is referenes from mesh hypothesis partition + list ::const_iterator hypIt = _hypothesises.begin(); + list ::const_iterator otheEndIt = theOther->_hypothesises.end(); + for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ ) + if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt ) + nbSame++; + // the submeshes are concurrent if their algorithms has different parameters + return nbSame != theOther->_hypothesises.size() - 1; + } + +}; // end of SMESH_DimHyp + +typedef list TDimHypList; + +static void addDimHypInstance(const int theDim, + const TopoDS_Shape& theShape, + const SMESH_Algo* theAlgo, + const SMESH_subMesh* theSubMesh, + const list & theHypList, + TDimHypList* theDimHypListArr ) +{ + TDimHypList& listOfdimHyp = theDimHypListArr[theDim]; + if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) { + SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape ); + listOfdimHyp.push_back( dimHyp ); + } + + SMESH_DimHyp* dimHyp = listOfdimHyp.back(); + dimHyp->_hypothesises.push_front(theAlgo); + list ::const_iterator hypIt = theHypList.begin(); + for( ; hypIt != theHypList.end(); hypIt++ ) + dimHyp->_hypothesises.push_back( *hypIt ); +} + +static void findConcurrents(const SMESH_DimHyp* theDimHyp, + const TDimHypList& theListOfDimHyp, + TListOfInt& theListOfConcurr ) +{ + TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin(); + for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) { + const SMESH_DimHyp* curDimHyp = *rIt; + if ( curDimHyp == theDimHyp ) + break; // meet own dimHyp pointer in same dimension + else if ( theDimHyp->IsConcurrent( curDimHyp ) ) + if ( find( theListOfConcurr.begin(), + theListOfConcurr.end(), + curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() ) + theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() ); + } +} + +static void unionLists(TListOfInt& theListOfId, + TListOfListOfInt& theListOfListOfId, + const int theIndx ) +{ + TListOfListOfInt::iterator it = theListOfListOfId.begin(); + for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) { + if ( i < theIndx ) + continue; //skip already treated lists + // check if other list has any same submesh object + TListOfInt& otherListOfId = *it; + if ( find_first_of( theListOfId.begin(), theListOfId.end(), + otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() ) + continue; + + // union two lists (from source into target) + TListOfInt::iterator it2 = otherListOfId.begin(); + for ( ; it2 != otherListOfId.end(); it2++ ) { + if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() ) + theListOfId.push_back(*it2); + } + // clear source list + otherListOfId.clear(); + } +} + +//! free memory allocated for dimension-hypothesis objects +static void removeDimHyps( TDimHypList* theArrOfList ) +{ + for (int i = 0; i < 4; i++ ) { + TDimHypList& listOfdimHyp = theArrOfList[i]; + TDimHypList::const_iterator it = listOfdimHyp.begin(); + for ( ; it != listOfdimHyp.end(); it++ ) + delete (*it); + } +} + +//============================================================================= +/*! + * \brief Return submesh objects list in meshing order + */ +//============================================================================= + +SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() +{ + SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array(); + + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( !aMeshDS ) + return aResult._retn(); + + ::SMESH_Mesh& mesh = GetImpl(); + TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order? + if ( !anOrder.size() ) { + + // collect submeshes detecting concurrent algorithms and hypothesises + TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension + + map::iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) { + ::SMESH_subMesh* sm = (*i_sm).second; + // shape of submesh + const TopoDS_Shape& aSubMeshShape = sm->GetSubShape(); + + // list of assigned hypothesises + const list & hypList = mesh.GetHypothesisList(aSubMeshShape); + // Find out dimensions where the submesh can be concurrent. + // We define the dimensions by algo of each of hypotheses in hypList + list ::const_iterator hypIt = hypList.begin(); + for( ; hypIt != hypList.end(); hypIt++ ) { + SMESH_Algo* anAlgo = 0; + const SMESH_Hypothesis* hyp = dynamic_cast(*hypIt); + if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO ) + // hyp it-self is algo + anAlgo = (SMESH_Algo*)dynamic_cast(hyp); + else { + // try to find algorithm with help of sub-shapes + TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) ); + for ( ; !anAlgo && anExp.More(); anExp.Next() ) + anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() ); + } + if (!anAlgo) + continue; // no assigned algorithm to current submesh + + int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp) + // the submesh can concurrent at (or lower dims if !anAlgo->NeedDiscreteBoundary()) + + // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm + for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ ) + addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr ); + } + } // end iterations on submesh + + // iterate on created dimension-hypotheses and check for concurrents + for ( int i = 0; i < 4; i++ ) { + const list& listOfDimHyp = dimHypListArr[i]; + // check for concurrents in own and other dimensions (step-by-step) + TDimHypList::const_iterator dhIt = listOfDimHyp.begin(); + for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) { + const SMESH_DimHyp* dimHyp = *dhIt; + TListOfInt listOfConcurr; + // looking for concurrents and collect into own list + for ( int j = i; j < 4; j++ ) + findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr ); + // check if any concurrents found + if ( listOfConcurr.size() > 0 ) { + // add own submesh to list of concurrent + listOfConcurr.push_front( dimHyp->_subMesh->GetId() ); + anOrder.push_back( listOfConcurr ); + } + } + } + + removeDimHyps(dimHypListArr); + + // now, minimise the number of concurrent groups + // Here we assume that lists of submeshes can have same submesh + // in case of multi-dimension algorithms, as result + // list with common submesh has to be united into one list + int listIndx = 0; + TListOfListOfInt::iterator listIt = anOrder.begin(); + for(; listIt != anOrder.end(); listIt++, listIndx++ ) + unionLists( *listIt, anOrder, listIndx + 1 ); + } + // convert submesh ids into interface instances + // and dump command into python + convertMeshOrder( anOrder, aResult, false ); + + return aResult._retn(); +} + +//============================================================================= +/*! + * \brief find common submeshes with given submesh + * \param theSubMeshList list of already collected submesh to check + * \param theSubMesh given submesh to intersect with other + * \param theCommonSubMeshes collected common submeshes + */ +//============================================================================= + +static void findCommonSubMesh (list& theSubMeshList, + const SMESH_subMesh* theSubMesh, + set& theCommon ) +{ + if ( !theSubMesh ) + return; + list::const_iterator it = theSubMeshList.begin(); + for ( ; it != theSubMeshList.end(); it++ ) + theSubMesh->FindIntersection( *it, theCommon ); + theSubMeshList.push_back( theSubMesh ); + //theCommon.insert( theSubMesh ); +} + +//============================================================================= +/*! + * \brief Set submesh object order + * \param theSubMeshArray submesh array order + */ +//============================================================================= + +::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray) +{ + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); + + bool res = false; + ::SMESH_Mesh& mesh = GetImpl(); + + TPythonDump aPythonDump; // prevent dump of called methods + aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ "; + + TListOfListOfInt subMeshOrder; + for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ ) + { + const SMESH::submesh_array& aSMArray = theSubMeshArray[i]; + TListOfInt subMeshIds; + aPythonDump << "[ "; + // Collect subMeshes which should be clear + // do it list-by-list, because modification of submesh order + // take effect between concurrent submeshes only + set subMeshToClear; + list subMeshList; + for ( int j = 0, jn = aSMArray.length(); j < jn; j++ ) + { + const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]); + if ( j > 0 ) + aPythonDump << ", "; + aPythonDump << subMesh; + subMeshIds.push_back( subMesh->GetId() ); + // detect common parts of submeshes + if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() ) + findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear ); + } + aPythonDump << " ]"; + subMeshOrder.push_back( subMeshIds ); + + // clear collected submeshes + set::iterator clrIt = subMeshToClear.begin(); + for ( ; clrIt != subMeshToClear.end(); clrIt++ ) + if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt ) + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + } + aPythonDump << " ])"; + + mesh.SetMeshOrder( subMeshOrder ); + res = true; + + return res; +} + +//============================================================================= +/*! + * \brief Convert submesh ids into submesh interfaces + */ +//============================================================================= + +void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, + SMESH::submesh_array_array& theResOrder, + const bool theIsDump) +{ + int nbSet = theIdsOrder.size(); + TPythonDump aPythonDump; // prevent dump of called methods + if ( theIsDump ) + aPythonDump << "[ "; + theResOrder.length(nbSet); + TListOfListOfInt::const_iterator it = theIdsOrder.begin(); + int listIndx = 0; + for( ; it != theIdsOrder.end(); it++ ) { + // translate submesh identificators into submesh objects + // takeing into account real number of concurrent lists + const TListOfInt& aSubOrder = (*it); + if (!aSubOrder.size()) + continue; + if ( theIsDump ) + aPythonDump << "[ "; + // convert shape indeces into interfaces + SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array(); + aResSubSet->length(aSubOrder.size()); + TListOfInt::const_iterator subIt = aSubOrder.begin(); + for( int j = 0; subIt != aSubOrder.end(); subIt++ ) { + if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() ) + continue; + SMESH::SMESH_subMesh_var subMesh = + SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] ); + if ( theIsDump ) { + if ( j > 0 ) + aPythonDump << ", "; + aPythonDump << subMesh; + } + aResSubSet[ j++ ] = subMesh; + } + if ( theIsDump ) + aPythonDump << " ]"; + theResOrder[ listIndx++ ] = aResSubSet; + } + // correct number of lists + theResOrder.length( listIndx ); + + if ( theIsDump ) { + // finilise python dump + aPythonDump << " ]"; + aPythonDump << " = " << _this() << ".GetMeshOrder()"; + } +} + +//================================================================================ +// +// Implementation of SMESH_MeshPartDS +// +SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): + SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true) +{ + SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + + _meshDS = mesh_i->GetImpl().GetMeshDS(); + + SetPersistentId( _meshDS->GetPersistentId() ); + + if ( mesh_i == SMESH::DownCast( meshPart )) + { + // is the whole mesh + myInfo = _meshDS->GetMeshInfo(); // copy mesh info; + // copy groups + set& myGroupSet = const_cast&>( GetGroups() ); + myGroupSet = _meshDS->GetGroups(); + } + else + { + TMeshInfo tmpInfo; + SMESH::long_array_var anIDs = meshPart->GetIDs(); + SMESH::array_of_ElementType_var types = meshPart->GetTypes(); + if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes + { + for (int i=0; i < anIDs->length(); i++) + if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i])) + if ( _elements[ SMDSAbs_Node ].insert( n ).second ) + tmpInfo.Add( n ); + } + else + { + for (int i=0; i < anIDs->length(); i++) + if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i])) + if ( _elements[ e->GetType() ].insert( e ).second ) + { + tmpInfo.Add( e ); + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + while ( nIt->more() ) + { + const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next(); + if ( _elements[ SMDSAbs_Node ].insert( n ).second ) + tmpInfo.Add( n ); + } + } + } + myInfo = tmpInfo; + + _meshDS = 0; // to enforce iteration on _elements and _nodes + } +} +// ------------------------------------------------------------------------------------- +SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const +{ + if ( _meshDS ) return _meshDS->elementGeomIterator( geomType ); + + typedef SMDS_SetIterator + , + SMDS_MeshElement::GeomFilter + > TIter; + + SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType ); + + return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(), + _elements[type].end(), + SMDS_MeshElement::GeomFilter( geomType ))); +} +// ------------------------------------------------------------------------------------- +SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const +{ + if ( _meshDS ) return _meshDS->elementEntityIterator( entity ); + + typedef SMDS_SetIterator + , + SMDS_MeshElement::EntityFilter + > TIter; + + SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity ); + + return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(), + _elements[type].end(), + SMDS_MeshElement::EntityFilter( entity ))); +} +// ------------------------------------------------------------------------------------- +SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const +{ + typedef SMDS_SetIterator TIter; + if ( type == SMDSAbs_All && !_meshDS ) + { + typedef vector< SMDS_ElemIteratorPtr > TIterVec; + TIterVec iterVec; + for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i ) + if ( !_elements[i].empty() && i != SMDSAbs_Node ) + iterVec.push_back + ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() ))); + + typedef SMDS_IteratorOnIterators TIterOnIters; + return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec )); + } + return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr + ( new TIter( _elements[type].begin(), _elements[type].end() )); +} +// ------------------------------------------------------------------------------------- +#define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \ + iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \ + { \ + typedef SMDS_SetIterator TIter; \ + return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \ + ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \ + } +// ------------------------------------------------------------------------------------- +_GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node ) +_GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge ) +_GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face ) +_GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume) +#undef _GET_ITER_DEFINE +// +// END Implementation of SMESH_MeshPartDS +// +//================================================================================ diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 32fe2153d..3c13916a4 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Mesh_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #ifndef _SMESH_MESH_I_HXX_ #define _SMESH_MESH_I_HXX_ @@ -46,6 +45,7 @@ class SMESH_Gen_i; class SMESH_GroupBase_i; class SMESH_subMesh_i; +class SMESH_PreMeshInfo; #include @@ -58,7 +58,7 @@ class SMESH_I_EXPORT SMESH_Mesh_i: public: SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Gen_i* myGen_i, - CORBA::Long studyId ); + CORBA::Long studyId ); virtual ~SMESH_Mesh_i(); @@ -72,6 +72,12 @@ public: GEOM::GEOM_Object_ptr GetShapeToMesh() throw (SALOME::SALOME_Exception); + CORBA::Boolean IsLoaded() + throw (SALOME::SALOME_Exception); + + void Load() + throw (SALOME::SALOME_Exception); + void Clear() throw (SALOME::SALOME_Exception); @@ -89,6 +95,9 @@ public: SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) throw (SALOME::SALOME_Exception); + SMESH::submesh_array* GetSubMeshes() + throw (SALOME::SALOME_Exception); + SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, const char* theName) throw (SALOME::SALOME_Exception); @@ -97,59 +106,64 @@ public: SMESH::SMESH_Group_ptr CreateGroup( SMESH::ElementType theElemType, const char* theName ) throw (SALOME::SALOME_Exception); - + SMESH::SMESH_GroupOnGeom_ptr CreateGroupFromGEOM(SMESH::ElementType theElemType, const char* theName, GEOM::GEOM_Object_ptr theGeomObj ) throw (SALOME::SALOME_Exception); + SMESH::SMESH_GroupOnFilter_ptr CreateGroupFromFilter(SMESH::ElementType theElemType, + const char* theName, + SMESH::Filter_ptr theFilter ) + throw (SALOME::SALOME_Exception); + void RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception); - + void RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception); - + SMESH::ListOfGroups* GetGroups() throw (SALOME::SALOME_Exception); CORBA::Long NbGroups() throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, - SMESH::SMESH_GroupBase_ptr theGroup2, + SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr UnionListOfGroups( const SMESH::ListOfGroups& theGroups, + SMESH::SMESH_Group_ptr UnionListOfGroups( const SMESH::ListOfGroups& theGroups, const char* theName) throw (SALOME::SALOME_Exception); - - SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, - SMESH::SMESH_GroupBase_ptr theGroup2, + + SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr IntersectListOfGroups( const SMESH::ListOfGroups& theGroups, + SMESH::SMESH_Group_ptr IntersectListOfGroups( const SMESH::ListOfGroups& theGroups, const char* theName ) throw (SALOME::SALOME_Exception); - - SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, - SMESH::SMESH_GroupBase_ptr theGroup2, + + SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr CutListOfGroups( const SMESH::ListOfGroups& theMainGroups, - const SMESH::ListOfGroups& theToolGroups, + SMESH::SMESH_Group_ptr CutListOfGroups( const SMESH::ListOfGroups& theMainGroups, + const SMESH::ListOfGroups& theToolGroups, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups, - SMESH::ElementType theElemType, + SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups, + SMESH::ElementType theElemType, const char* theName ) throw (SALOME::SALOME_Exception); - - SMESH::SMESH_Group_ptr ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGeomGroup ); + + SMESH::SMESH_Group_ptr ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroupOn ); // SMESH::string_array* GetLog(CORBA::Boolean clearAfterGet) // throw (SALOME::SALOME_Exception); @@ -161,6 +175,8 @@ public: SMESH::SMESH_MeshEditor_ptr GetMeshEditPreviewer(); + CORBA::Boolean HasModificationsToDiscard() throw (SALOME::SALOME_Exception); + void ClearLog() throw (SALOME::SALOME_Exception); @@ -188,6 +204,11 @@ public: SMESH::DriverMED_ReadStatus ImportMEDFile( const char* theFileName, const char* theMeshName ) throw (SALOME::SALOME_Exception); + SMESH::DriverMED_ReadStatus ImportCGNSFile( const char* theFileName, + const int theMeshIndex, + std::string& theMeshName) + throw (SALOME::SALOME_Exception); + /*! * Auto color */ @@ -206,17 +227,37 @@ public: */ char* GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits); - void ExportToMED( const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion ) - throw (SALOME::SALOME_Exception); - void ExportMED( const char* file, CORBA::Boolean auto_groups ) - throw (SALOME::SALOME_Exception); - - void ExportDAT( const char* file ) - throw (SALOME::SALOME_Exception); - void ExportUNV( const char* file ) - throw (SALOME::SALOME_Exception); - void ExportSTL( const char* file, bool isascii ) - throw (SALOME::SALOME_Exception); + void ExportToMEDX( const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION version, + CORBA::Boolean overwrite ) throw (SALOME::SALOME_Exception); + void ExportToMED ( const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION version ) throw (SALOME::SALOME_Exception); + void ExportMED ( const char* file, + CORBA::Boolean auto_groups ) throw (SALOME::SALOME_Exception); + + void ExportSAUV( const char* file, CORBA::Boolean auto_groups ) throw (SALOME::SALOME_Exception); + + void ExportDAT( const char* file ) throw (SALOME::SALOME_Exception); + void ExportUNV( const char* file ) throw (SALOME::SALOME_Exception); + void ExportSTL( const char* file, bool isascii ) throw (SALOME::SALOME_Exception); + void ExportCGNS(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean overwrite) throw (SALOME::SALOME_Exception); + + void ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION version, + CORBA::Boolean overwrite) throw (SALOME::SALOME_Exception); + void ExportPartToDAT(SMESH::SMESH_IDSource_ptr meshPart, + const char* file) throw (SALOME::SALOME_Exception); + void ExportPartToUNV(SMESH::SMESH_IDSource_ptr meshPart, + const char* file) throw (SALOME::SALOME_Exception); + void ExportPartToSTL(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean isascii) throw (SALOME::SALOME_Exception); SALOME_MED::MESH_ptr GetMEDMesh() throw (SALOME::SALOME_Exception); @@ -227,6 +268,12 @@ public: CORBA::Long NbElements() throw (SALOME::SALOME_Exception); + CORBA::Long Nb0DElements() + throw (SALOME::SALOME_Exception); + + CORBA::Long NbBalls() + throw (SALOME::SALOME_Exception); + CORBA::Long NbEdges() throw (SALOME::SALOME_Exception); @@ -251,6 +298,9 @@ public: CORBA::Long NbQuadranglesOfOrder(SMESH::ElementOrder order) throw (SALOME::SALOME_Exception); + CORBA::Long NbBiQuadQuadrangles() + throw (SALOME::SALOME_Exception); + CORBA::Long NbPolygons() throw (SALOME::SALOME_Exception); @@ -272,6 +322,9 @@ public: CORBA::Long NbHexasOfOrder(SMESH::ElementOrder order) throw (SALOME::SALOME_Exception); + CORBA::Long NbTriQuadraticHexas() + throw (SALOME::SALOME_Exception); + CORBA::Long NbPyramids() throw (SALOME::SALOME_Exception); @@ -284,6 +337,9 @@ public: CORBA::Long NbPrismsOfOrder(SMESH::ElementOrder order) throw (SALOME::SALOME_Exception); + CORBA::Long NbHexagonalPrisms() + throw (SALOME::SALOME_Exception); + CORBA::Long NbPolyhedrons() throw (SALOME::SALOME_Exception); @@ -295,13 +351,16 @@ public: SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType ) throw (SALOME::SALOME_Exception); - + SMESH::long_array* GetNodesId() throw (SALOME::SALOME_Exception); - + SMESH::ElementType GetElementType( CORBA::Long id, bool iselem ) throw (SALOME::SALOME_Exception); - + + SMESH::EntityType GetElementGeomType( CORBA::Long id ) + throw (SALOME::SALOME_Exception); + /*! * Returns ID of elements for given submesh */ @@ -315,15 +374,15 @@ public: */ SMESH::long_array* GetSubMeshNodesId(CORBA::Long ShapeID, CORBA::Boolean all) throw (SALOME::SALOME_Exception); - + /*! * Returns type of elements for given submesh */ SMESH::ElementType GetSubMeshElementType(CORBA::Long ShapeID) throw (SALOME::SALOME_Exception); - + char* Dump(); - + // Internal methods not available through CORBA // They are called by corresponding interface methods SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, @@ -331,22 +390,23 @@ public: SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, SMESH::SMESH_Hypothesis_ptr anHyp); - + static SMESH::Hypothesis_Status ConvertHypothesisStatus (SMESH_Hypothesis::Hypothesis_Status theStatus); - static void PrepareForWriting (const char* file); + static void PrepareForWriting (const char* file, bool overwrite = true); //int importMEDFile( const char* theFileName, const char* theMeshName ); SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject ); - void removeSubMesh(SMESH::SMESH_subMesh_ptr theSubMesh, + bool removeSubMesh(SMESH::SMESH_subMesh_ptr theSubMesh, GEOM::GEOM_Object_ptr theSubShapeObject ); - SMESH::SMESH_GroupBase_ptr createGroup(SMESH::ElementType theElemType, - const char* theName, - const TopoDS_Shape& theShape = TopoDS_Shape()); + SMESH::SMESH_GroupBase_ptr createGroup(SMESH::ElementType theElemType, + const char* theName, + const TopoDS_Shape& theShape = TopoDS_Shape(), + const SMESH_PredicatePtr& thePred = SMESH_PredicatePtr()); void removeGroup( const int theId ); @@ -356,15 +416,18 @@ public: const std::map& getGroups() { return _mapGroups; } // return an existing group object. + void onHypothesisModified(); + // callback from _impl to forget not loaded mesh data (issue 0021208) + + void checkMeshLoaded(); + /*! * \brief Update hypotheses assigned to geom groups if the latter change - * + * * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" */ void CheckGeomGroupModif(); - virtual SMESH::long_array* GetIDs(); - CORBA::LongLong GetMeshPtr(); /*! @@ -382,7 +445,7 @@ public: * If there is not node for given ID - returns empty list */ SMESH::double_array* GetNodeXYZ(CORBA::Long id); - + /*! * For given node returns list of IDs of inverse elements * If there is not node for given ID - returns empty list @@ -401,7 +464,7 @@ public: CORBA::Long GetShapeID(CORBA::Long id); /*! - * For given element returns ID of result shape after + * For given element returns ID of result shape after * ::FindShape() from SMESH_MeshEditor * If there is not element for given ID - returns -1 */ @@ -424,40 +487,54 @@ public: * If there is not node for given index - returns -2 */ CORBA::Long GetElemNode(CORBA::Long id, CORBA::Long index); - + /*! * Returns true if given node is medium node * in given quadratic element */ CORBA::Boolean IsMediumNode(CORBA::Long ide, CORBA::Long idn); - + /*! * Returns true if given node is medium node * in one of quadratic elements */ CORBA::Boolean IsMediumNodeOfAnyElem(CORBA::Long idn, SMESH::ElementType theElemType); - + /*! * Returns number of edges for given element */ CORBA::Long ElemNbEdges(CORBA::Long id); - + /*! * Returns number of faces for given element */ CORBA::Long ElemNbFaces(CORBA::Long id); - + /*! + * Returns nodes of given face (counted from zero) for given element. + */ + SMESH::long_array* GetElemFaceNodes(CORBA::Long elemId, CORBA::Short faceIndex); + + /*! + * Returns an element based on all given nodes. + */ + CORBA::Long FindElementByNodes(const SMESH::long_array& nodes); + /*! * Returns true if given element is polygon */ CORBA::Boolean IsPoly(CORBA::Long id); - + /*! * Returns true if given element is quadratic */ CORBA::Boolean IsQuadratic(CORBA::Long id); - + + /*! + * Returns diameter of ball discrete element or zero in case of an invalid \a id + */ + CORBA::Double GetBallDiameter(CORBA::Long id); + /*! * Returns bary center for given element */ @@ -472,7 +549,7 @@ public: * Sets list of notebook variables used for Mesh operations separated by ":" symbol */ void SetParameters (const char* theParameters); - + /*! * Returns list of notebook variables used for Mesh operations separated by ":" symbol */ @@ -482,28 +559,108 @@ public: * Returns list of notebook variables used for last Mesh operation */ SMESH::string_array* GetLastParameters(); - + + /*! + * Collect statistic of mesh elements given by iterator + */ + static void CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, + SMESH::long_array& theInfo); + + /*! + * \brief Return submesh objects list in meshing order + */ + virtual SMESH::submesh_array_array* GetMeshOrder(); + /*! + * \brief Set submesh object order + */ + virtual ::CORBA::Boolean SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray); + + + // ========================= + // SMESH_IDSource interface + // ========================= + + virtual SMESH::long_array* GetIDs(); + /*! + * Returns statistic of mesh elements + * Result array of number enityties + * Inherited from SMESH_IDSource + */ + virtual SMESH::long_array* GetMeshInfo(); + /*! + * Returns types of elements it contains + */ + virtual SMESH::array_of_ElementType* GetTypes(); + /*! + * Returns self + */ + virtual SMESH::SMESH_Mesh_ptr GetMesh(); + /*! + * Returns false if GetMeshInfo() returns incorrect information that may + * happen if mesh data is not yet fully loaded from the file of study. + */ + bool IsMeshInfoCorrect(); + std::map _mapSubMesh_i; //NRI std::map _mapSubMesh; //NRI private: + std::string prepareMeshNameAndGroups( const char* file, CORBA::Boolean overwrite ); + /*! * Check and correct names of mesh groups */ void checkGroupNames(); + /*! + * Convert submesh ids into submesh interfaces + */ + void convertMeshOrder(const TListOfListOfInt& theIdsOrder, + SMESH::submesh_array_array& theSubMeshOrder, + const bool theIsDump); + private: - static int myIdGenerator; - ::SMESH_Mesh* _impl; // :: force no namespace here - SMESH_Gen_i* _gen_i; - int _id; // id given by creator (unique within the creator instance) - int _studyId; + static int _idGenerator; + ::SMESH_Mesh* _impl; // :: force no namespace here + SMESH_Gen_i* _gen_i; + int _id; // id given by creator (unique within the creator instance) + int _studyId; std::map _mapSubMeshIor; std::map _mapGroups; std::map _mapHypo; - SALOME_MED::MedFileInfo_var myFileInfo; + SALOME_MED::MedFileInfo_var _medFileInfo; + SMESH_PreMeshInfo* _preMeshInfo; // mesh info before full loading from study file + + SMESH_PreMeshInfo* & changePreMeshInfo() { return _preMeshInfo; } + friend class SMESH_PreMeshInfo; + +private: + + // Data used to track changes of GEOM groups + struct TGeomGroupData { + // keep study entry but not ior because GEOM_Object actually changes if + // number of items in a group varies (1) <-> (>1) + std::string _groupEntry; + std::set _indices; // indices of group items within group's main shape + CORBA::Object_ptr _smeshObject; // SMESH object depending on GEOM group + }; + std::list _geomGroupData; + + /*! + * Remember GEOM group data + */ + void addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, + CORBA::Object_ptr theSmeshObj); + /*! + * Remove GEOM group data relating to removed smesh object + */ + void removeGeomGroupData(CORBA::Object_ptr theSmeshObj); + /*! + * \brief Return new group contents if it has been changed and update group data + */ + TopoDS_Shape newGroupShape( TGeomGroupData & groupData); + }; #endif - diff --git a/src/SMESH_I/SMESH_NoteBook.cxx b/src/SMESH_I/SMESH_NoteBook.cxx index bd7268049..7ecbe0823 100644 --- a/src/SMESH_I/SMESH_NoteBook.cxx +++ b/src/SMESH_I/SMESH_NoteBook.cxx @@ -1,12 +1,11 @@ -// Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // -// This library is distributed in the hope that it will be useful +// 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. @@ -17,13 +16,15 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_NoteBook.cxx // Author : Roman NIKOLAEV - +// #include "SMESH_2smeshpy.hxx" #include "SMESH_NoteBook.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_PythonDump.hxx" +#include "SMESH_Hypothesis_i.hxx" #include #include @@ -41,14 +42,28 @@ static int MYDEBUG = 0; using namespace std; -void SetVariable(Handle(_pyCommand) theCommand,const ObjectStates* theStates, int position, int theArgNb); +namespace +{ + /*! + * Set variable of the SMESH_ObjectStates from position to the _pyCommand + * method as nbArg argument + */ + void SetVariable(Handle(_pyCommand) theCommand, + const SMESH_ObjectStates* theStates, + int position, int theArgNb) + { + if(theStates->GetCurrectState().size() > position) + if(!theStates->GetCurrectState().at(position).IsEmpty()) + theCommand->SetArg(theArgNb,theStates->GetCurrectState().at(position)); + } +} //================================================================================ /*! * \brief Constructor */ //================================================================================ -ObjectStates::ObjectStates(TCollection_AsciiString theType) +SMESH_ObjectStates::SMESH_ObjectStates(TCollection_AsciiString theType) { _type = theType; _dumpstate = 0; @@ -59,7 +74,7 @@ ObjectStates::ObjectStates(TCollection_AsciiString theType) * \brief Destructor */ //================================================================================ -ObjectStates::~ObjectStates() +SMESH_ObjectStates::~SMESH_ObjectStates() { } @@ -69,7 +84,7 @@ ObjectStates::~ObjectStates() * \param theState - Object state (vector of notebook variable) */ //================================================================================ -void ObjectStates::AddState(const TState &theState) +void SMESH_ObjectStates::AddState(const TState &theState) { _states.push_back(theState); } @@ -80,7 +95,7 @@ void ObjectStates::AddState(const TState &theState) * \\retval state - Object state (vector of notebook variable) */ //================================================================================ -TState ObjectStates::GetCurrectState() const +TState SMESH_ObjectStates::GetCurrectState() const { if(_states.size() > _dumpstate) return _states[_dumpstate]; @@ -94,7 +109,7 @@ TState ObjectStates::GetCurrectState() const * */ //================================================================================ -TAllStates ObjectStates::GetAllStates() const +TAllStates SMESH_ObjectStates::GetAllStates() const { return _states; } @@ -104,7 +119,7 @@ TAllStates ObjectStates::GetAllStates() const * */ //================================================================================ -void ObjectStates::IncrementState() +void SMESH_ObjectStates::IncrementState() { _dumpstate++; } @@ -114,7 +129,7 @@ void ObjectStates::IncrementState() * */ //================================================================================ -TCollection_AsciiString ObjectStates::GetObjectType() const{ +TCollection_AsciiString SMESH_ObjectStates::GetObjectType() const{ return _type; } @@ -125,7 +140,7 @@ TCollection_AsciiString ObjectStates::GetObjectType() const{ */ //================================================================================ LayerDistributionStates::LayerDistributionStates(): - ObjectStates("LayerDistribution") + SMESH_ObjectStates("LayerDistribution") { } //================================================================================ @@ -229,7 +244,7 @@ void SMESH_NoteBook::ReplaceVariables() cout<<"Object : "<< aObject<GetArg(1)); + aMethod.IsEqual("ApplyToHexahedrons")) + it = _objectMap.find(aCmd->GetArg(1)); } - + if(it != _objectMap.end()) { if(MYDEBUG) - cout << "Found object : " << (*it).first << endl; - ObjectStates *aStates = (*it).second; + cout << "Found object : " << (*it).first << endl; + SMESH_ObjectStates *aStates = (*it).second; // Case for LocalLength hypothesis - if(aStates->GetObjectType().IsEqual("LocalLength") && aStates->GetCurrectState().size() >= 2) { + if(aStates->GetObjectType().IsEqual("LocalLength") && aStates->GetCurrectState().size() >= 2) + { if(aMethod.IsEqual("SetLength")) { if(!aStates->GetCurrectState().at(0).IsEmpty() ) aCmd->SetArg(1,aStates->GetCurrectState().at(0)); @@ -326,57 +342,6 @@ void SMESH_NoteBook::ReplaceVariables() aStates->IncrementState(); } } - - // Case for NETGEN_Parameters_2D or NETGEN_Parameters_2D hypothesis - else if(aStates->GetObjectType().IsEqual("NETGEN_Parameters_2D") || - aStates->GetObjectType().IsEqual("NETGEN_Parameters")){ - if(aMethod == "SetMaxSize" && aStates->GetCurrectState().size() >= 1) { - if(!aStates->GetCurrectState().at(0).IsEmpty() ) - aCmd->SetArg(1,aStates->GetCurrectState().at(0)); - aStates->IncrementState(); - } - else if(aMethod == "SetGrowthRate" && aStates->GetCurrectState().size() >= 2) { - if(!aStates->GetCurrectState().at(1).IsEmpty() ) - aCmd->SetArg(1,aStates->GetCurrectState().at(1)); - aStates->IncrementState(); - } - else if(aMethod == "SetNbSegPerEdge" && aStates->GetCurrectState().size() >= 3) { - if(!aStates->GetCurrectState().at(2).IsEmpty() ) - aCmd->SetArg(1,aStates->GetCurrectState().at(2)); - aStates->IncrementState(); - } - else if(aMethod == "SetNbSegPerRadius" && aStates->GetCurrectState().size() >= 4) { - if(!aStates->GetCurrectState().at(3).IsEmpty() ) - aCmd->SetArg(1,aStates->GetCurrectState().at(3)); - aStates->IncrementState(); - } - } - - // Case for NETGEN_SimpleParameters_3D or NETGEN_SimpleParameters_2D hypothesis - else if(aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_3D") || - aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_2D")){ - - if((aMethod == "SetNumberOfSegments" || aMethod == "SetLocalLength") && - aStates->GetCurrectState().size() >= 1) { - if(!aStates->GetCurrectState().at(0).IsEmpty() ) - aCmd->SetArg(1,aStates->GetCurrectState().at(0)); - aStates->IncrementState(); - } - else if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 2) { - if(!aStates->GetCurrectState().at(1).IsEmpty() ) - aCmd->SetArg(1,aStates->GetCurrectState().at(1)); - aStates->IncrementState(); - } - else if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 3) { - if(!aStates->GetCurrectState().at(2).IsEmpty() ) - aCmd->SetArg(1,aStates->GetCurrectState().at(2)); - aStates->IncrementState(); - } - else if(aMethod == "LengthFromEdges" || aMethod == "LengthFromFaces"){ - aStates->IncrementState(); - } - } - // Case for NumberOfLayers hypothesis else if(aStates->GetObjectType().IsEqual("NumberOfLayers")){ if(aMethod == "SetNumberOfLayers" && aStates->GetCurrectState().size() >= 1) { @@ -402,9 +367,9 @@ void SMESH_NoteBook::ReplaceVariables() } else if(aStates->GetObjectType().IsEqual("Mesh")) { - TState aCurrentState = aStates->GetCurrectState(); + TState aCurrentState = aStates->GetCurrectState(); int aCurrentStateSize = aCurrentState.size(); - if(aMethod.IsEqual("Translate") || + if(aMethod.IsEqual("Translate") || aMethod.IsEqual("TranslateMakeGroups") || aMethod.IsEqual("TranslateMakeMesh") || aMethod.IsEqual("TranslateObject") || @@ -419,211 +384,284 @@ void SMESH_NoteBook::ReplaceVariables() } } if(anArgIndex > 0) { - if(aCurrentStateSize == 3) { // translation by dx, dy, dz - for(int j = 0; j < aCurrentStateSize; j++) { - if(!aCurrentState.at(j).IsEmpty()) { - isVariableFound = true; - aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); - } - } - } - else if(aCurrentStateSize == 6) { // translation by x1, x2, y1, y2, z1, z2 - // TODO: limitation until operations on the variables will be introduced - /* - isVariableFound = true; - for(int j = 0; j < 3; j++) { - TCollection_AsciiString anArg = aCmd->GetArg(anArgIndex+j); - TCollection_AsciiString aValue1 = aCurrentState.at(2*j), aValue2 = aCurrentState.at(2*j+1); - bool aV1 = !aValue1.IsEmpty(); - bool aV2 = !aValue2.IsEmpty(); - double aValue, aCurrentValue = anArg.IsRealValue() ? anArg.RealValue() : 0; - if(aV1 && !aV2) { - if(!GetReal(aValue1, aValue)) - aValue = 0; - aValue2 = TCollection_AsciiString( aValue + aCurrentValue ); - } - else if(!aV1 && aV2) { - if(!GetReal(aValue2, aValue)) - aValue = 0; - aValue1 = TCollection_AsciiString( aValue - aCurrentValue ); - } - else if(!aV1 && !aV2) { - aValue1 = TCollection_AsciiString( 0 ); - aValue2 = TCollection_AsciiString( aCurrentValue ); - } - aCmd->SetArg(anArgIndex+j, aValue1 + ", " + aValue2 ); - } - */ - } + if(aCurrentStateSize == 3) { // translation by dx, dy, dz + for(int j = 0; j < aCurrentStateSize; j++) { + if(!aCurrentState.at(j).IsEmpty()) { + isVariableFound = true; + aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); + } + } + } + else if(aCurrentStateSize == 6) { // translation by x1, x2, y1, y2, z1, z2 + // TODO: limitation until operations on the variables will be introduced + /* + isVariableFound = true; + for(int j = 0; j < 3; j++) { + TCollection_AsciiString anArg = aCmd->GetArg(anArgIndex+j); + TCollection_AsciiString aValue1 = aCurrentState.at(2*j), aValue2 = aCurrentState.at(2*j+1); + bool aV1 = !aValue1.IsEmpty(); + bool aV2 = !aValue2.IsEmpty(); + double aValue, aCurrentValue = anArg.IsRealValue() ? anArg.RealValue() : 0; + if(aV1 && !aV2) { + if(!GetReal(aValue1, aValue)) + aValue = 0; + aValue2 = TCollection_AsciiString( aValue + aCurrentValue ); + } + else if(!aV1 && aV2) { + if(!GetReal(aValue2, aValue)) + aValue = 0; + aValue1 = TCollection_AsciiString( aValue - aCurrentValue ); + } + else if(!aV1 && !aV2) { + aValue1 = TCollection_AsciiString( 0 ); + aValue2 = TCollection_AsciiString( aCurrentValue ); + } + aCmd->SetArg(anArgIndex+j, aValue1 + ", " + aValue2 ); + } + */ + } } if(isVariableFound) { TCollection_AsciiString aDim; - if(aCurrentStateSize == 6) - aDim = "6"; + if(aCurrentStateSize == 6) + aDim = "6"; aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr"+aDim); aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr"); } aStates->IncrementState(); } - else if(aMethod.IsEqual("Rotate") || - aMethod.IsEqual("RotateMakeGroups") || - aMethod.IsEqual("RotateMakeMesh") || + else if(aMethod.IsEqual("Rotate") || + aMethod.IsEqual("RotateMakeGroups") || + aMethod.IsEqual("RotateMakeMesh") || aMethod.IsEqual("RotateObject") || aMethod.IsEqual("RotateObjectMakeGroups") || aMethod.IsEqual("RotateObjectMakeMesh") || - aMethod.IsEqual("RotationSweep") || - aMethod.IsEqual("RotationSweepObject") || - aMethod.IsEqual("RotationSweepObject1D") || - aMethod.IsEqual("RotationSweepObject2D") || - aMethod.IsEqual("RotationSweepMakeGroups") || - aMethod.IsEqual("RotationSweepObjectMakeGroups") || - aMethod.IsEqual("RotationSweepObject1DMakeGroups") || - aMethod.IsEqual("RotationSweepObject2DMakeGroups") || - aMethod.IsEqual("Mirror") || - aMethod.IsEqual("MirrorMakeMesh") || + aMethod.IsEqual("RotationSweep") || + aMethod.IsEqual("RotationSweepObject") || + aMethod.IsEqual("RotationSweepObject1D") || + aMethod.IsEqual("RotationSweepObject2D") || + aMethod.IsEqual("RotationSweepMakeGroups") || + aMethod.IsEqual("RotationSweepObjectMakeGroups") || + aMethod.IsEqual("RotationSweepObject1DMakeGroups") || + aMethod.IsEqual("RotationSweepObject2DMakeGroups") || + aMethod.IsEqual("Mirror") || + aMethod.IsEqual("MirrorMakeMesh") || aMethod.IsEqual("MirrorMakeGroups") || aMethod.IsEqual("MirrorObject") || aMethod.IsEqual("MirrorObjectMakeMesh") || aMethod.IsEqual("MirrorObjectMakeGroups")) { - bool isSubstitute = false; - int anArgIndex = 0; - for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) { - if(aCmd->GetArg(i).IsEqual("SMESH.AxisStruct")) { - anArgIndex = i+1; - break; - } - } - if(anArgIndex > 0) { - for(int j = 0; j < aCurrentStateSize; j++) { - if(!aCurrentState.at(j).IsEmpty()) { - if(j < 6) // 0-5 - axis struct, 6 - angle (rotation & sweep), 7-8 - nbSteps and tolerance (sweep) - isSubstitute = true; - aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); - } - } - } - if(isSubstitute) - aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".AxisStructStr"); - aStates->IncrementState(); - } - else if(aMethod.IsEqual("AddNode") || - aMethod.IsEqual("MoveClosestNodeToPoint")) { - for(int j = 0; j < aCurrentStateSize; j++) { - if(!aCurrentState.at(j).IsEmpty()) - aCmd->SetArg(j+1, aCurrentState.at(j)); - } - aStates->IncrementState(); - } - else if(aMethod.IsEqual("MoveNode")) { - for(int j = 0; j < aCurrentStateSize; j++) { - if(!aCurrentState.at(j).IsEmpty()) - aCmd->SetArg(j+2, aCurrentState.at(j)); - } - aStates->IncrementState(); - } - else if(aMethod.IsEqual("ExtrusionSweep") || - aMethod.IsEqual("ExtrusionSweepObject") || - aMethod.IsEqual("ExtrusionSweepObject1D") || - aMethod.IsEqual("ExtrusionSweepObject2D") || - aMethod.IsEqual("ExtrusionSweepMakeGroups") || - aMethod.IsEqual("ExtrusionSweepObjectMakeGroups") || - aMethod.IsEqual("ExtrusionSweepObject1DMakeGroups") || - aMethod.IsEqual("ExtrusionSweepObject2DMakeGroups")) { - bool isSubstitute = false; - int anArgIndex = 0; - for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) { - if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) { - anArgIndex = i+1; - break; - } - } - if(anArgIndex > 0) { - for(int j = 0; j < aCurrentStateSize; j++) { - if(!aCurrentState.at(j).IsEmpty()) { - if(j < 3) // 0-2 - dir struct, 3 - number of steps - isSubstitute = true; - aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); - } - } - } - if(isSubstitute) { + bool isSubstitute = false; + int anArgIndex = 0; + for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) { + if(aCmd->GetArg(i).IsEqual("SMESH.AxisStruct")) { + anArgIndex = i+1; + break; + } + } + if(anArgIndex > 0) { + for(int j = 0; j < aCurrentStateSize; j++) { + if(!aCurrentState.at(j).IsEmpty()) { + if(j < 6) // 0-5 - axis struct, 6 - angle (rotation & sweep), 7-8 - nbSteps and tolerance (sweep) + isSubstitute = true; + aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); + } + } + } + if(isSubstitute) + aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".AxisStructStr"); + aStates->IncrementState(); + } + else if(aMethod.IsEqual("AddNode") || + aMethod.IsEqual("MoveClosestNodeToPoint")) { + for(int j = 0; j < aCurrentStateSize; j++) { + if(!aCurrentState.at(j).IsEmpty()) + aCmd->SetArg(j+1, aCurrentState.at(j)); + } + aStates->IncrementState(); + } + else if(aMethod.IsEqual("MoveNode")) { + for(int j = 0; j < aCurrentStateSize; j++) { + if(!aCurrentState.at(j).IsEmpty()) + aCmd->SetArg(j+2, aCurrentState.at(j)); + } + aStates->IncrementState(); + } + else if(aMethod.IsEqual("ExtrusionSweep") || + aMethod.IsEqual("ExtrusionSweepObject") || + aMethod.IsEqual("ExtrusionSweepObject1D") || + aMethod.IsEqual("ExtrusionSweepObject2D") || + aMethod.IsEqual("ExtrusionSweepMakeGroups") || + aMethod.IsEqual("ExtrusionSweepObjectMakeGroups") || + aMethod.IsEqual("ExtrusionSweepObject1DMakeGroups") || + aMethod.IsEqual("ExtrusionSweepObject2DMakeGroups")) { + bool isSubstitute = false; + int anArgIndex = 0; + for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) { + if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) { + anArgIndex = i+1; + break; + } + } + if(anArgIndex > 0) { + for(int j = 0; j < aCurrentStateSize; j++) { + if(!aCurrentState.at(j).IsEmpty()) { + if(j < 3) // 0-2 - dir struct, 3 - number of steps + isSubstitute = true; + aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); + } + } + } + if(isSubstitute) { aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr"); aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr"); - } - aStates->IncrementState(); - } - else if(aMethod.IsEqual("ExtrusionAlongPath") || - aMethod.IsEqual("ExtrusionAlongPathObject") || - aMethod.IsEqual("ExtrusionAlongPathObject1D") || - aMethod.IsEqual("ExtrusionAlongPathObject2D") || - aMethod.IsEqual("ExtrusionAlongPathMakeGroups") || - aMethod.IsEqual("ExtrusionAlongPathObjectMakeGroups") || - aMethod.IsEqual("ExtrusionAlongPathObject1DMakeGroups") || - aMethod.IsEqual("ExtrusionAlongPathObject2DMakeGroups") || - /* workaround for a bug in the command parsing algorithm */ - aCmd->GetString().Search("ExtrusionAlongPathMakeGroups") != -1 || - aCmd->GetString().Search("ExtrusionAlongPathObjectMakeGroups") != -1 || - aCmd->GetString().Search("ExtrusionAlongPathObject1DMakeGroups") != -1 || - aCmd->GetString().Search("ExtrusionAlongPathObject2DMakeGroups") != -1 ) { - int aNbAngles = aCurrentStateSize-3; // State looks like "Angle1:...:AngleN:X:Y:Z" - bool isSubstitute = false; - int anArgIndex = 0; - for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) { - if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) { - anArgIndex = i-1-aNbAngles; - break; - } - } - if(anArgIndex > 0) { - int j = 0; - for(; j < aNbAngles; j++) { - if(!aCurrentState.at(j).IsEmpty()) { - aCmd->SetArg(anArgIndex+j-1, aCurrentState.at(j)); - } - } - for(; j < aNbAngles+3; j++) { - if(!aCurrentState.at(j).IsEmpty()) { - isSubstitute = true; - aCmd->SetArg(anArgIndex+j+2, aCurrentState.at(j)); - } - } - } - if(isSubstitute) - aCmd->SetArg(anArgIndex + aNbAngles + 1, - TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr"); - aStates->IncrementState(); - } - else if(aMethod.IsEqual("TriToQuad") || - aMethod.IsEqual("Concatenate") || - aMethod.IsEqual("ConcatenateWithGroups")) { - if(aCurrentStateSize && !aCurrentState.at(0).IsEmpty()) - aCmd->SetArg(aCmd->GetNbArgs(), aCurrentState.at(0)); - aStates->IncrementState(); - } - else if(aMethod.IsEqual("Smooth") || - aMethod.IsEqual("SmoothObject") || - aMethod.IsEqual("SmoothParametric") || - aMethod.IsEqual("SmoothParametricObject")) { - int anArgIndex = aCmd->GetNbArgs() - 2; - for(int j = 0; j < aCurrentStateSize; j++) { - if(!aCurrentState.at(j).IsEmpty()) - aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); - } - aStates->IncrementState(); - } - else if(aMethod.IsEqual("ApplyToMeshFaces") || - aMethod.IsEqual("ApplyToHexahedrons")) { - int anArgIndex = aCmd->GetNbArgs()-1; - for(int j = 0; j < aCurrentStateSize; j++) - if(!aCurrentState.at(j).IsEmpty()) - aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); - aStates->IncrementState(); - } + } + aStates->IncrementState(); + } + else if(aMethod.IsEqual("ExtrusionAlongPath") || + aMethod.IsEqual("ExtrusionAlongPathObject") || + aMethod.IsEqual("ExtrusionAlongPathObject1D") || + aMethod.IsEqual("ExtrusionAlongPathObject2D") || + aMethod.IsEqual("ExtrusionAlongPathMakeGroups") || + aMethod.IsEqual("ExtrusionAlongPathObjectMakeGroups") || + aMethod.IsEqual("ExtrusionAlongPathObject1DMakeGroups") || + aMethod.IsEqual("ExtrusionAlongPathObject2DMakeGroups") || + /* workaround for a bug in the command parsing algorithm */ + aCmd->GetString().Search("ExtrusionAlongPathMakeGroups") != -1 || + aCmd->GetString().Search("ExtrusionAlongPathObjectMakeGroups") != -1 || + aCmd->GetString().Search("ExtrusionAlongPathObject1DMakeGroups") != -1 || + aCmd->GetString().Search("ExtrusionAlongPathObject2DMakeGroups") != -1 ) { + int aNbAngles = aCurrentStateSize-3; // State looks like "Angle1:...:AngleN:X:Y:Z" + bool isSubstitute = false; + int anArgIndex = 0; + for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) { + if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) { + anArgIndex = i-1-aNbAngles; + break; + } + } + if(anArgIndex > 0) { + int j = 0; + for(; j < aNbAngles; j++) { + if(!aCurrentState.at(j).IsEmpty()) { + aCmd->SetArg(anArgIndex+j-1, aCurrentState.at(j)); + } + } + for(; j < aNbAngles+3; j++) { + if(!aCurrentState.at(j).IsEmpty()) { + isSubstitute = true; + aCmd->SetArg(anArgIndex+j+2, aCurrentState.at(j)); + } + } + } + if(isSubstitute) + aCmd->SetArg(anArgIndex + aNbAngles + 1, + TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr"); + aStates->IncrementState(); + } + else if(aMethod.IsEqual("TriToQuad") || + aMethod.IsEqual("Concatenate") || + aMethod.IsEqual("ConcatenateWithGroups")) { + if(aCurrentStateSize && !aCurrentState.at(0).IsEmpty()) + aCmd->SetArg(aCmd->GetNbArgs(), aCurrentState.at(0)); + aStates->IncrementState(); + } + else if(aMethod.IsEqual("Smooth") || + aMethod.IsEqual("SmoothObject") || + aMethod.IsEqual("SmoothParametric") || + aMethod.IsEqual("SmoothParametricObject")) { + int anArgIndex = aCmd->GetNbArgs() - 2; + for(int j = 0; j < aCurrentStateSize; j++) { + if(!aCurrentState.at(j).IsEmpty()) + aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); + } + aStates->IncrementState(); + } + else if(aMethod.IsEqual("ApplyToMeshFaces") || + aMethod.IsEqual("ApplyToHexahedrons")) { + int anArgIndex = aCmd->GetNbArgs()-1; + for(int j = 0; j < aCurrentStateSize; j++) + if(!aCurrentState.at(j).IsEmpty()) + aCmd->SetArg(anArgIndex+j, aCurrentState.at(j)); + aStates->IncrementState(); + } + } // if ( aStates->GetObjectType().IsEqual("Mesh")) + + // Case for NETGEN_Parameters_2D or NETGEN_Parameters_2D hypothesis + // else if(aStates->GetObjectType().IsEqual("NETGEN_Parameters_2D") || + // aStates->GetObjectType().IsEqual("NETGEN_Parameters")){ + // if(aMethod == "SetMaxSize" && aStates->GetCurrectState().size() >= 1) { + // if(!aStates->GetCurrectState().at(0).IsEmpty() ) + // aCmd->SetArg(1,aStates->GetCurrectState().at(0)); + // aStates->IncrementState(); + // } + // else if(aMethod == "SetGrowthRate" && aStates->GetCurrectState().size() >= 2) { + // if(!aStates->GetCurrectState().at(1).IsEmpty() ) + // aCmd->SetArg(1,aStates->GetCurrectState().at(1)); + // aStates->IncrementState(); + // } + // else if(aMethod == "SetNbSegPerEdge" && aStates->GetCurrectState().size() >= 3) { + // if(!aStates->GetCurrectState().at(2).IsEmpty() ) + // aCmd->SetArg(1,aStates->GetCurrectState().at(2)); + // aStates->IncrementState(); + // } + // else if(aMethod == "SetNbSegPerRadius" && aStates->GetCurrectState().size() >= 4) { + // if(!aStates->GetCurrectState().at(3).IsEmpty() ) + // aCmd->SetArg(1,aStates->GetCurrectState().at(3)); + // aStates->IncrementState(); + // } + // } + + // // Case for NETGEN_SimpleParameters_3D or NETGEN_SimpleParameters_2D hypothesis + // else if(aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_3D") || + // aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_2D")) { + + // if((aMethod == "SetNumberOfSegments" || aMethod == "SetLocalLength") && + // aStates->GetCurrectState().size() >= 1) { + // if(!aStates->GetCurrectState().at(0).IsEmpty() ) + // aCmd->SetArg(1,aStates->GetCurrectState().at(0)); + // aStates->IncrementState(); + // } + // else if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 2) { + // if(!aStates->GetCurrectState().at(1).IsEmpty() ) + // aCmd->SetArg(1,aStates->GetCurrectState().at(1)); + // aStates->IncrementState(); + // } + // else if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 3) { + // if(!aStates->GetCurrectState().at(2).IsEmpty() ) + // aCmd->SetArg(1,aStates->GetCurrectState().at(2)); + // aStates->IncrementState(); + // } + // else if(aMethod == "LengthFromEdges" || aMethod == "LengthFromFaces"){ + // aStates->IncrementState(); + // } + // } + + else + { + // treat Netgen hypotheses; + // this (and above) code can work wrong since nb of states can differ from nb of + // dumped calls due to the fix of + // issue 0021364:: Dump of netgen parameters has duplicate lines + SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_ptr aStudy = aGen->GetCurrentStudy(); + SALOMEDS::SObject_var sobj = aStudy->FindObjectID( (*it).first.ToCString() ); + CORBA::Object_var obj = aGen->SObjectToObject( sobj ); + if ( SMESH_Hypothesis_i* h = SMESH::DownCast< SMESH_Hypothesis_i*>( obj )) + { + TState aCurrentState = aStates->GetCurrectState(); + int argIndex = h->getParamIndex( aMethod, aCurrentState.size() ); + if ( 0 <= argIndex && argIndex < aCurrentState.size() && + !aCurrentState[argIndex].IsEmpty() ) + aCmd->SetArg( 1, aCurrentState[argIndex] ); + + if ( argIndex >= 0 ) + aStates->IncrementState(); + } } } else { if(MYDEBUG) - cout << "Object not found" << endl; + cout << "Object not found" << endl; } if(MYDEBUG) { cout<<"Command after: "<< aCmd->GetString()<_is_nil()) { - anObjType = TCollection_AsciiString(aHyp->GetName()); + CORBA::String_var hypName = aHyp->GetName(); + anObjType = hypName.in(); } - else if(SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObject)) { - anObjType = TCollection_AsciiString("Mesh"); + else if (!aMesh->_is_nil() ) { + anObjType = "Mesh"; } if(MYDEBUG) cout<<"The object Type : "<length(); i++) { TState aVars; SALOMEDS::ListOfStrings aListOfVars = aSections[i]; for(int j = 0;jIsVariable(aVar.ToCString())) { - aVar.InsertBefore(1,"\""); - aVar.InsertAfter(aVar.Length(),"\""); + aVar.InsertBefore(1, SMESH::TVar::Quote() ); + aVar.InsertAfter(aVar.Length(), SMESH::TVar::Quote() ); } aVars.push_back(aVar); if(MYDEBUG) { @@ -697,7 +736,15 @@ void SMESH_NoteBook::InitObjectMap() } aState->AddState(aVars); } - _objectMap.insert(pair(TCollection_AsciiString(aSObject->GetID()),aState)); + if ( aState->GetAllStates().empty() ) + { + delete aState; + } + else + { + CORBA::String_var objID = aSObject->GetID(); + _objectMap.insert( make_pair(TCollection_AsciiString( objID.in() ), aState )); + } } } } @@ -716,7 +763,7 @@ void SMESH_NoteBook::AddCommand(const TCollection_AsciiString& theString) if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation myMeshEditors.insert( make_pair( aCommand->GetResultValue(), - aCommand->GetObject() ) ); + aCommand->GetObject() ) ); } } @@ -848,14 +895,3 @@ bool SMESH_NoteBook::GetReal(const TCollection_AsciiString& theVarName, double& return ok; } - -/*! - * Set variable of the ObjectStates from position to the _pyCommand - * method as nbArg argument - */ -void SetVariable(Handle(_pyCommand) theCommand, const ObjectStates* theStates, int position, int theArgNb) -{ - if(theStates->GetCurrectState().size() > position) - if(!theStates->GetCurrectState().at(position).IsEmpty()) - theCommand->SetArg(theArgNb,theStates->GetCurrectState().at(position)); -} diff --git a/src/SMESH_I/SMESH_NoteBook.hxx b/src/SMESH_I/SMESH_NoteBook.hxx index dfeb3b50a..661f42f49 100644 --- a/src/SMESH_I/SMESH_NoteBook.hxx +++ b/src/SMESH_I/SMESH_NoteBook.hxx @@ -1,12 +1,11 @@ -// Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // -// This library is distributed in the hope that it will be useful +// 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. @@ -17,13 +16,17 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_NoteBook.hxx // Author : Roman NIKOLAEV () - - +// #ifndef SMESH_NoteBook_HeaderFile #define SMESH_NoteBook_HeaderFile +// All this stuff is obsolete since issue 0021308: +// "Remove hard-coded dependency of the external mesh plugins from the SMESH module" +// is implemented (Mar 2012). It is kept for backward compatibility only. + #include #include @@ -34,14 +37,14 @@ class _pyCommand; typedef std::vector TState; typedef std::vector TAllStates; -typedef TCollection_AsciiString _pyID; +typedef TCollection_AsciiString _pyID; -class ObjectStates{ +class SMESH_ObjectStates{ public: - ObjectStates(TCollection_AsciiString theType); - virtual ~ObjectStates(); + SMESH_ObjectStates(TCollection_AsciiString theType); + virtual ~SMESH_ObjectStates(); void AddState(const TState &theState); @@ -58,7 +61,7 @@ private: int _dumpstate; }; -class LayerDistributionStates : public ObjectStates +class LayerDistributionStates : public SMESH_ObjectStates { public: typedef std::map TDistributionMap; @@ -81,7 +84,7 @@ private: class SMESH_NoteBook { public: - typedef std::map TVariablesMap; + typedef std::map TVariablesMap; typedef std::map TMeshEditorMap; SMESH_NoteBook(); ~SMESH_NoteBook(); diff --git a/src/SMESH_I/SMESH_Pattern_i.cxx b/src/SMESH_I/SMESH_Pattern_i.cxx index b96a8d954..b1a3d0c35 100644 --- a/src/SMESH_I/SMESH_Pattern_i.cxx +++ b/src/SMESH_I/SMESH_Pattern_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Pattern_i.cxx // Created : Fri Aug 20 16:15:49 2004 // Author : Edward AGAPOV (eap) -// $Header: // #include "SMESH_Pattern_i.hxx" @@ -46,6 +46,7 @@ #include using SMESH::TPythonDump; +using SMESH::TVar; //======================================================================= //function : dumpErrorCode @@ -149,7 +150,7 @@ CORBA::Boolean SMESH_Pattern_i::LoadFromFace(SMESH::SMESH_Mesh_ptr theMesh, return false; // Update Python script - TPythonDump() << "isDone = pattern.LoadFromFace( " << theMesh << ", " + TPythonDump() << "isDone = pattern.LoadFromFace( " << theMesh << ".GetMesh(), " << theFace << ", " << theProject << " )"; addErrorCode( "LoadFromFace" ); @@ -180,7 +181,7 @@ CORBA::Boolean SMESH_Pattern_i::LoadFrom3DBlock(SMESH::SMESH_Mesh_ptr theMesh, return false; // Update Python script - TPythonDump() << "isDone = pattern.LoadFrom3DBlock( " << theMesh << ", " << theBlock << " )"; + TPythonDump() << "isDone = pattern.LoadFrom3DBlock( " << theMesh << ".GetMesh(), " << theBlock << " )"; addErrorCode( "LoadFrom3DBlock" ); return myPattern.Load( aMesh, TopoDS::Shell( exp.Current() )); @@ -214,7 +215,6 @@ SMESH::point_array* SMESH_Pattern_i::ApplyToFace(GEOM::GEOM_Object_ptr theFace, (*xyzIt)->Coord( p.x, p.y, p.z ); } } - // Update Python script TPythonDump() << "pattern.ApplyToFace( " << theFace << ", " << theVertexOnKeyPoint1 << ", " << theReverse << " )"; @@ -316,9 +316,9 @@ SMESH::point_array* } // Update Python script - TPythonDump() << "pattern.ApplyToMeshFaces( " << theMesh << ", " + TPythonDump() << "pattern.ApplyToMeshFaces( " << theMesh << ".GetMesh(), " << theFacesIDs << ", " - << theNodeIndexOnKeyPoint1 << ", " << theReverse << " )"; + << TVar( theNodeIndexOnKeyPoint1 ) << ", " << theReverse << " )"; return points._retn(); } @@ -361,9 +361,9 @@ SMESH::point_array* } // Update Python script - TPythonDump() << "pattern.ApplyToHexahedrons( " << theMesh << ", " + TPythonDump() << "pattern.ApplyToHexahedrons( " << theMesh << ".GetMesh(), " << theVolumesIDs << ", " - << theNode000Index << ", " << theNode001Index << " )"; + << TVar(theNode000Index) << ", " << TVar(theNode001Index) << " )"; return points._retn(); } @@ -382,11 +382,20 @@ CORBA::Boolean SMESH_Pattern_i::MakeMesh (SMESH::SMESH_Mesh_ptr theMesh, return false; // Update Python script - TPythonDump() << "isDone = pattern.MakeMesh( " << theMesh << ", " + TPythonDump() << "isDone = pattern.MakeMesh( " << theMesh << ".GetMesh(), " << CreatePolygons << ", " << CreatePolyedrs << " )"; addErrorCode( "MakeMesh" ); - return myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs ); + int nb = aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes(); + + bool res = myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs ); + + if ( nb > 0 && nb != aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes()) + { + aMesh->SetIsModified(true); + aMesh->GetMeshDS()->Modified(); + } + return res; } //======================================================================= diff --git a/src/SMESH_I/SMESH_Pattern_i.hxx b/src/SMESH_I/SMESH_Pattern_i.hxx index 8526ef9ad..b363ac10d 100644 --- a/src/SMESH_I/SMESH_Pattern_i.hxx +++ b/src/SMESH_I/SMESH_Pattern_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Pattern_i.hxx // Created : Fri Aug 20 16:03:15 2004 diff --git a/src/SMESH_I/SMESH_PreMeshInfo.cxx b/src/SMESH_I/SMESH_PreMeshInfo.cxx new file mode 100644 index 000000000..e56adfadf --- /dev/null +++ b/src/SMESH_I/SMESH_PreMeshInfo.cxx @@ -0,0 +1,1278 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_PreMeshInfo.cxx +// Created : Fri Feb 10 17:36:39 2012 +// Author : Edward AGAPOV (eap) +// + +#include "SMESH_PreMeshInfo.hxx" + +#include "DriverMED_R_SMESHDS_Mesh.h" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMDS_SpacePosition.hxx" +#include "SMDS_VertexPosition.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESHDS_GroupOnFilter.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_Mesh_i.hxx" +#include "SMESH_subMesh_i.hxx" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include CORBA_SERVER_HEADER(SALOME_Session) + +#define MYDEBUGOUT(msg) //std::cout << msg << std::endl; + +//================================================================================ +#define PreMeshInfo_TRY \ + try { OCC_CATCH_SIGNALS +//================================================================================ +#define PreMeshInfo_CATCH } \ + catch (Standard_Failure& ex) { \ + onExceptionCaught(SMESH_Comment("OCC Exception caught: \t")< theStudyIDToMeshCounter; + + //================================================================================ + /*! + * \brief Counts not fully loaded meshes + */ + //================================================================================ + + void meshInfoLoaded( SMESH_Mesh_i* mesh ) + { + map< int, int >::iterator id2counter = + theStudyIDToMeshCounter.insert( make_pair( (int) mesh->GetStudyId(), 0 )).first; + id2counter->second++; + } + //================================================================================ + /*! + * \brief Removes temporary files if none of meshes needs them + */ + //================================================================================ + + void filesNoMoreNeeded(SMESH_Mesh_i* mesh, + std::string medFile, + std::string hdfFile) + { + if ( --theStudyIDToMeshCounter[ (int) mesh->GetStudyId() ] == 0 ) + { + string tmpDir = SALOMEDS_Tool::GetDirFromPath( hdfFile ); + + SALOMEDS::ListOfFileNames_var aFiles = new SALOMEDS::ListOfFileNames; + aFiles->length(2); + medFile = SALOMEDS_Tool::GetNameFromPath( medFile ) + ".med"; + hdfFile = SALOMEDS_Tool::GetNameFromPath( hdfFile ) + ".hdf"; + aFiles[0] = medFile.c_str(); + aFiles[1] = hdfFile.c_str(); + + SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.c_str(), aFiles.in(), true ); + } + } + + //================================================================================ + /*! + * \brief Method useful only to set a breakpoint to debug in case of exception + */ + //================================================================================ + + void onExceptionCaught(const string& msg) + { + INFOS( msg ); + MYDEBUGOUT( msg ); + } + + //============================================================================= + /*! + * \brief Class sending signals on start and finish of loading + */ + //============================================================================= + + class SignalToGUI + { + string _messagePrefix; + SALOME::Session_var _session; + public: + SignalToGUI( SMESH_Mesh_i* mesh ) + { + SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_var study = gen->GetCurrentStudy(); + if ( !study->_is_nil() && study->StudyId() == mesh->GetStudyId() ) + { + SALOMEDS::SObject_var meshSO = gen->ObjectToSObject(study, mesh->_this() ); + CORBA::Object_var obj = gen->GetNS()->Resolve( "/Kernel/Session" ); + _session = SALOME::Session::_narrow( obj ); + if ( !meshSO->_is_nil() && !_session->_is_nil() ) + { + CORBA::String_var meshEntry = meshSO->GetID(); + _messagePrefix = "SMESH/mesh_loading/"; + _messagePrefix += meshEntry.in(); + + string msgToGUI = _messagePrefix + "/"; + msgToGUI += SMESH_Comment( mesh->NbNodes() ); + msgToGUI += "/"; + msgToGUI += SMESH_Comment( mesh->NbElements() ); + + _session->emitMessageOneWay( msgToGUI.c_str()); + } + } + } + void sendStop() + { + if ( !_messagePrefix.empty() ) + { + string msgToGUI = _messagePrefix + "/stop"; + _session->emitMessageOneWay( msgToGUI.c_str()); + _messagePrefix.clear(); + } + } + ~SignalToGUI() { sendStop(); } + }; + + //============================================================================= + /*! + * \brief Creates SMDS_Position according to shape type + */ + //============================================================================= + + class PositionCreator { + public: + SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) { + return (this->*myFuncTable[ type ])(); + } + PositionCreator() { + myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition ); + myFuncTable[ TopAbs_SOLID ] = & PositionCreator::volumePosition; + myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition; + myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition; + myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition; + } + private: + SMDS_PositionPtr edgePosition() const { return SMDS_PositionPtr( new SMDS_EdgePosition ); } + SMDS_PositionPtr facePosition() const { return SMDS_PositionPtr( new SMDS_FacePosition ); } + SMDS_PositionPtr volumePosition() const { return SMDS_PositionPtr( new SMDS_SpacePosition ); } + SMDS_PositionPtr vertexPosition() const { return SMDS_PositionPtr( new SMDS_VertexPosition); } + SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition(); } + typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const; + vector myFuncTable; + }; + + //================================================================================ + /*! + * \brief Returns ids of simple shapes composing a complex one + */ + //================================================================================ + + vector getSimpleSubMeshIds( SMESHDS_Mesh* meshDS, int shapeId ) + { + vector ids; + + list shapeQueue( 1, meshDS->IndexToShape( shapeId )); + list::iterator shape = shapeQueue.begin(); + for ( ; shape != shapeQueue.end(); ++shape ) + { + if ( shape->IsNull() ) continue; + if ( shape->ShapeType() == TopAbs_COMPOUND || + shape->ShapeType() == TopAbs_COMPSOLID ) + { + for ( TopoDS_Iterator it( *shape ); it.More(); it.Next() ) + shapeQueue.push_back( it.Value() ); + } + else + { + ids.push_back( meshDS->ShapeToIndex( *shape )); + } + } + return ids; + } + + //================================================================================ + /*! + * \brief Return EEntiteMaillage by EGeometrieElement + */ + //================================================================================ + + MED::EEntiteMaillage entityByGeom(const MED::EGeometrieElement geom ) + { + return geom == MED::eBALL ? MED::eSTRUCT_ELEMENT : MED::eMAILLE; + } + + //================================================================================ + /*! + * \brief Return a map< EGeometrieElement, SMDSAbs_EntityType > + */ + //================================================================================ + + typedef map< MED::EGeometrieElement, SMDSAbs_EntityType > Tmed2smeshElemTypeMap; + const Tmed2smeshElemTypeMap& med2smeshElemTypeMap() + { + static map< MED::EGeometrieElement, SMDSAbs_EntityType> med2smeshTypes; + if ( med2smeshTypes.empty() ) + { + med2smeshTypes[ MED::ePOINT1 ] = SMDSEntity_0D ; + med2smeshTypes[ MED::eSEG2 ] = SMDSEntity_Edge ; + med2smeshTypes[ MED::eSEG3 ] = SMDSEntity_Quad_Edge ; + med2smeshTypes[ MED::eTRIA3 ] = SMDSEntity_Triangle ; + med2smeshTypes[ MED::eTRIA6 ] = SMDSEntity_Quad_Triangle ; + med2smeshTypes[ MED::eQUAD4 ] = SMDSEntity_Quadrangle ; + med2smeshTypes[ MED::eQUAD8 ] = SMDSEntity_Quad_Quadrangle ; + med2smeshTypes[ MED::eQUAD9 ] = SMDSEntity_BiQuad_Quadrangle ; + med2smeshTypes[ MED::eTETRA4 ] = SMDSEntity_Tetra ; + med2smeshTypes[ MED::ePYRA5 ] = SMDSEntity_Pyramid ; + med2smeshTypes[ MED::ePENTA6 ] = SMDSEntity_Penta ; + med2smeshTypes[ MED::eHEXA8 ] = SMDSEntity_Hexa ; + med2smeshTypes[ MED::eOCTA12 ] = SMDSEntity_Hexagonal_Prism ; + med2smeshTypes[ MED::eTETRA10 ] = SMDSEntity_Quad_Tetra ; + med2smeshTypes[ MED::ePYRA13 ] = SMDSEntity_Quad_Pyramid ; + med2smeshTypes[ MED::ePENTA15 ] = SMDSEntity_Quad_Penta ; + med2smeshTypes[ MED::eHEXA20 ] = SMDSEntity_Quad_Hexa ; + med2smeshTypes[ MED::eHEXA27 ] = SMDSEntity_TriQuad_Hexa ; + med2smeshTypes[ MED::ePOLYGONE ] = SMDSEntity_Polygon ; + med2smeshTypes[ MED::ePOLYEDRE ] = SMDSEntity_Polyhedra ; + med2smeshTypes[ MED::eNONE ] = SMDSEntity_Node ; + med2smeshTypes[ MED::eBALL ] = SMDSEntity_Ball ; + } + return med2smeshTypes; + } + + //================================================================================ + /*! + * \brief Return a vector intended to retrieve + * MED::EGeometrieElement by SMDSAbs_EntityType + */ + //================================================================================ + + const vector& mesh2medElemType() + { + static vector mesh2medElemTypes; + if ( mesh2medElemTypes.empty() ) + { + mesh2medElemTypes.resize( SMDSEntity_Last + 1 ); + Tmed2smeshElemTypeMap::const_iterator me2sme = med2smeshElemTypeMap().begin(); + Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end(); + for ( ; me2sme != me2smeEnd; ++me2sme ) + mesh2medElemTypes[ me2sme->second ] = me2sme->first; + } + return mesh2medElemTypes; + } + + //================================================================================ + /*! + * \brief Writes meshInfo into a HDF file + */ + //================================================================================ + + void meshInfo2hdf( SMESH::long_array_var meshInfo, + const std::string& name, + HDFgroup* hdfGroup) + { + // we use med identification of element (MED::EGeometrieElement>) types + // but not enum SMDSAbs_EntityType because values of SMDSAbs_EntityType may + // change at insertion of new items in the middle. + const vector& medTypes = mesh2medElemType(); + + vector data; + + for ( size_t i = 0; i < meshInfo->length(); ++i ) + if ( meshInfo[i] > 0 ) + { + data.push_back( medTypes[ i ] ); + data.push_back( meshInfo[ i ] ); + } + + if ( !data.empty() ) + { + hdf_size datasetSize[] = { data.size() }; + HDFarray* anArray = new HDFarray(0, HDF_INT32, 1, datasetSize); + anArray->CreateOnDisk(); + datasetSize[0] = 1; + HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup, HDF_ARRAY, datasetSize, 1 ); + dataset->SetArrayId(anArray->GetId()); + dataset->CreateOnDisk(); + dataset->WriteOnDisk( & data[0] ); + dataset->CloseOnDisk(); + anArray->CloseOnDisk(); + } + } +} + +//================================================================================ +/*! + * \brief Reads meshInfo from a HDF file + */ +//================================================================================ + +void SMESH_PreMeshInfo::hdf2meshInfo( const std::string& name, + HDFgroup* hdfGroup) +{ + if ( hdfGroup->ExistInternalObject( name.c_str()) ) + { + HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup ); + dataset->OpenOnDisk(); + + // // hdf_size datasetSize[ 1 ]; + // // HDFarray *array = new HDFarray(dataset); + // // array->GetDim( datasetSize ); + // int size = dataset->GetSize(); + + vector info( SMDSEntity_Last * 2, 0 ); + dataset->ReadFromDisk( &info[0] ); + dataset->CloseOnDisk(); + + const Tmed2smeshElemTypeMap& med2smesh = med2smeshElemTypeMap(); + Tmed2smeshElemTypeMap::const_iterator me2sme, me2smeEnd = med2smesh.end(); + for ( size_t i = 0; i < info.size(); ) + { + int medType = info[i++]; + int nbElems = info[i++]; + if ( !nbElems ) break; + me2sme = med2smesh.find( (MED::EGeometrieElement) medType ); + if ( me2sme != me2smeEnd ) + setNb( me2sme->second, nbElems ); + } + } + _isInfoOk = true; + + if ( NbNodes() == GroupOnFilter_OutOfDate ) // case of !SMESHDS_GroupOnFilter::IsUpToDate() + { + _isInfoOk = false; + setNb( SMDSEntity_Node, 0 ); + } +} + +//================================================================================ +/*! + * \brief Constructor callable by SMESH_PreMeshInfo only + */ +//================================================================================ + +SMESH_PreMeshInfo::SMESH_PreMeshInfo(SMESH_Mesh_i* mesh, + const int meshID, + const std::string& medFile, + const std::string& hdfFile) + : _medFileName( medFile ), + _hdfFileName( hdfFile ), + _toRemoveFiles( false ), + _meshID( meshID ), + _mesh( mesh ), + _isInfoOk( false ), + _elemCounter( 0 ) +{ +} + +//================================================================================ +/*! + * \brief Release temporary files + */ +//================================================================================ + +SMESH_PreMeshInfo::~SMESH_PreMeshInfo() +{ + if ( _toRemoveFiles ) // it can be true only for SMESH_PreMeshInfo of the mesh + filesNoMoreNeeded( _mesh, _medFileName, _hdfFileName ); + + _toRemoveFiles = false; +} + +//================================================================================ +/*! + * \brief fills SMESH_PreMeshInfo field of all objects of mesh + */ +//================================================================================ + +void SMESH_PreMeshInfo::LoadFromFile( SMESH_Mesh_i* mesh, + const int meshID, + const std::string& medFile, + const std::string& hdfFile, + const bool toRemoveFiles) +{ + PreMeshInfo_TRY; + + SMESH_PreMeshInfo* meshPreInfo = new SMESH_PreMeshInfo( mesh,meshID,medFile,hdfFile ); + mesh->changePreMeshInfo() = meshPreInfo; + + meshPreInfo->_toRemoveFiles = toRemoveFiles; + if ( toRemoveFiles ) + meshInfoLoaded( mesh ); + + if ( meshPreInfo->readPreInfoFromHDF() ) + // all SMESH_PreMeshInfo's are stored in HDF file (written after + // implementing SMESH_PreMeshInfo) + return; + + // try to read SMESH_PreMeshInfo from med file (as study is older than SMESH_PreMeshInfo) + if ( meshPreInfo->readMeshInfo() ) + { + meshPreInfo->readGroupInfo(); + meshPreInfo->readSubMeshInfo(); + } + else + { + meshPreInfo->FullLoadFromFile(); + } + PreMeshInfo_CATCH; +} + +//================================================================================ +/*! + * \brief Tries to read all SMESH_PreMeshInfo from a HDF file + * \retval bool - true if succeeded + * + * This method is symmetrical to SaveToFile() + */ +//================================================================================ + +bool SMESH_PreMeshInfo::readPreInfoFromHDF() +{ + HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() ); + aFile->OpenOnDisk( HDF_RDONLY ); + + SMESH_Comment hdfGroupName("SMESH_PreMeshInfo"); hdfGroupName << _meshID; + const bool infoAvailable = aFile->ExistInternalObject( hdfGroupName ); + if ( infoAvailable ) + { + HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, aFile ); + infoHdfGroup->OpenOnDisk(); + + _mesh->changePreMeshInfo()->hdf2meshInfo( "Mesh", infoHdfGroup ); + + // read SMESH_PreMeshInfo of groups + map::const_iterator i2group = _mesh->_mapGroups.begin(); + for ( ; i2group != _mesh->_mapGroups.end(); ++i2group ) + { + if ( SMESH_GroupBase_i* group_i = + SMESH::DownCast( i2group->second )) + { + group_i->changePreMeshInfo() = newInstance(); + if ( SMESHDS_GroupBase* group = group_i->GetGroupDS() ) + { + const string name = group->GetStoreName(); + group_i->changePreMeshInfo()->hdf2meshInfo( name, infoHdfGroup ); + } + } + } + + // read SMESH_PreMeshInfo of sub-meshes + map::iterator id2sm = _mesh->_mapSubMeshIor.begin(); + for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm ) + { + if ( SMESH_subMesh_i* sm = SMESH::DownCast( id2sm->second )) + { + sm->changePreMeshInfo() = newInstance(); + sm->changePreMeshInfo()->hdf2meshInfo( SMESH_Comment( sm->GetId()), infoHdfGroup ); + } + } + } + + aFile->CloseOnDisk(); + delete aFile; + + return infoAvailable; +} + +//================================================================================ +/*! + * \brief Reads mesh info of mesh from the med file + */ +//================================================================================ + +bool SMESH_PreMeshInfo::readMeshInfo() +{ + _isInfoOk = true; + + MED::PWrapper aMed = MED::CrWrapper(_medFileName,true); + // if ( aMed->GetVersion() != MED::eV2_2 ) + // return false; + + MED::PMeshInfo medMeshInfo = aMed->CrMeshInfo(3,3,SMESH_Comment( _meshID )); + + // read nb nodes + int nbNodes = std::max( 0, aMed->GetNbNodes( medMeshInfo )); + if ( nbNodes > 0 ) + { + setNb( SMDSEntity_Node, nbNodes); + + // read nb of elements + Tmed2smeshElemTypeMap::const_iterator me2sme = med2smeshElemTypeMap().begin(); + Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end(); + for ( ; me2sme != me2smeEnd; ++me2sme ) + { + int nbElems = aMed->GetNbCells( medMeshInfo, entityByGeom(me2sme->first), me2sme->first ); + if ( nbElems > 0 ) + setNb( me2sme->second, nbElems ); + } + } + return true; +} + +//================================================================================ +/*! + * \brief Reads info of groups from the med file + */ +//================================================================================ + +void SMESH_PreMeshInfo::readGroupInfo() +{ + if ( _mesh->_mapGroups.empty() ) return; + + // make SMESH_PreMeshInfo of groups + map< string, SMESH_PreMeshInfo* > name2GroupInfo; + map::const_iterator i2group = _mesh->_mapGroups.begin(); + for ( ; i2group != _mesh->_mapGroups.end(); ++i2group ) + { + if ( SMESH_GroupBase_i* group_i = + SMESH::DownCast( i2group->second )) + { + SMESH_PreMeshInfo* info = newInstance(); + group_i->changePreMeshInfo() = info; + if ( SMESHDS_Group* group = dynamic_cast< SMESHDS_Group* >( group_i->GetGroupDS() )) + { + string name = group->GetStoreName(); + name2GroupInfo.insert( make_pair( name, info )); + info->_isInfoOk = true; + } + } + } + + map< int, vector< SMESH_PreMeshInfo* > > famId2grInfo; + + MED::PWrapper aMed = MED::CrWrapper(_medFileName,false); + MED::PMeshInfo medMeshInfo = aMed->CrMeshInfo(3,3,SMESH_Comment( _meshID )); + + // read families to fill in famId2grInfo + int nbFams = aMed->GetNbFamilies( medMeshInfo ); + if ( nbFams <= 1 ) return; // zero family is always present + for ( int iF = 0; iF <= nbFams; ++iF ) + { + int nbGroups = aMed->GetNbFamGroup( iF, medMeshInfo ); + if ( nbGroups < 1 ) continue; + MED::PFamilyInfo medFamInfo = aMed->CrFamilyInfo( medMeshInfo, nbGroups, nbGroups ); + aMed->GetFamilyInfo( iF, medFamInfo ); // read groups of a family + vector< SMESH_PreMeshInfo* >& grInfoVec = famId2grInfo[ medFamInfo->GetId() ]; + for ( int iG = 0; iG < nbGroups; ++iG ) + { + const string grName = medFamInfo->GetGroupName( iG ); + map< string, SMESH_PreMeshInfo* >::iterator n2i = name2GroupInfo.find( grName ); + if ( n2i != name2GroupInfo.end() ) + grInfoVec.push_back( n2i->second ); + } + } + + // read family numbers of elements + Tmed2smeshElemTypeMap::const_iterator me2sme = med2smeshElemTypeMap().begin(); + Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end(); + MED::PElemInfo medElemInfo = aMed->CrElemInfo( medMeshInfo, 0 ); + MED::TIntVector& famNums = medElemInfo->myFamNum; + for ( ; me2sme != me2smeEnd; ++me2sme ) // loop on elem types + { + famNums.resize( NbEntities( me2sme->second )); + if ( famNums.empty() ) continue; + aMed->GetFamilies( medElemInfo, famNums.size(), entityByGeom(me2sme->first), me2sme->first ); + // distribute elements of a type among groups + map< int, vector< SMESH_PreMeshInfo* > >::iterator f2infos = famId2grInfo.begin(); + for ( size_t i = 0; i < famNums.size(); ++i ) + { + if ( famNums[i] != f2infos->first ) + { + f2infos = famId2grInfo.find( famNums[i] ); + if ( f2infos == famId2grInfo.end() ) + f2infos = famId2grInfo.insert + ( make_pair( famNums[i], vector< SMESH_PreMeshInfo*>())).first; + } + vector< SMESH_PreMeshInfo* >& infoVec = f2infos->second ; + for ( size_t j = 0; j < infoVec.size(); ++j ) + infoVec[j]->_elemCounter++; + } + // pass _elemCounter to a real elem type + map< string, SMESH_PreMeshInfo* >::iterator n2i = name2GroupInfo.begin(); + for ( ; n2i != name2GroupInfo.end(); ++n2i ) + { + SMESH_PreMeshInfo* info = n2i->second; + info->setNb( me2sme->second, info->_elemCounter ); + info->_elemCounter = 0; + } + } +} + +//================================================================================ +/*! + * \brief Reads info of sub-meshes from hdf file of old study + */ +//================================================================================ + +void SMESH_PreMeshInfo::readSubMeshInfo() +{ + if ( _mesh->_mapSubMeshIor.empty() ) return; + + // create SMESH_PreMeshInfo of sub-meshes + map::iterator id2sm = _mesh->_mapSubMeshIor.begin(); + for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm ) + { + if ( SMESH_subMesh_i* sm = SMESH::DownCast( id2sm->second )) + { + sm->changePreMeshInfo() = newInstance(); + sm->changePreMeshInfo()->_isInfoOk = true; + } + } + + // try to read + HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() ); + aFile->OpenOnDisk( HDF_RDONLY ); + + char meshGrpName[ 30 ]; + sprintf( meshGrpName, "Mesh %d", _meshID ); + if ( aFile->ExistInternalObject( meshGrpName ) ) + { + HDFgroup* aTopGroup = new HDFgroup( meshGrpName, aFile ); + aTopGroup->OpenOnDisk(); + if ( aTopGroup->ExistInternalObject( "Submeshes" )) + { + HDFgroup* aGroup = new HDFgroup( "Submeshes", aTopGroup ); + aGroup->OpenOnDisk(); + + SMESHDS_Mesh* meshDS = _mesh->GetImpl().GetMeshDS(); + int maxSmId = Max( meshDS->MaxSubMeshIndex(), meshDS->MaxShapeIndex() ); + + for ( int isNode = 0; isNode < 2; ++isNode ) + { + string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); + if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() )) + { + // read sub-mesh id of all nodes or elems + HDFdataset* aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup ); + aDataset->OpenOnDisk(); + int nbElems = aDataset->GetSize(); + int* smIDs = new int [ nbElems ]; + aDataset->ReadFromDisk( smIDs ); + aDataset->CloseOnDisk(); + // count nb elems in each sub-mesh + vector nbBySubmeshId( maxSmId + 1, 0 ); + for ( int i = 0; i < nbElems; ++i ) + { + const int smID = smIDs[ i ]; + if ( smID < (int) nbBySubmeshId.size() ) + nbBySubmeshId[ smID ]++; + } + delete [] smIDs; + + // store nb elems in SMESH_PreMeshInfo of sub-meshes + map::iterator id2sm = _mesh->_mapSubMeshIor.begin(); + for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm ) + { + if ( SMESH_subMesh_i* sm = SMESH::DownCast( id2sm->second )) + { + SMESH_PreMeshInfo* & info = sm->changePreMeshInfo(); + + vector smIds = getSimpleSubMeshIds( meshDS, id2sm->first ); + for ( size_t i = 0; i < smIds.size(); ++i ) + info->_elemCounter += nbBySubmeshId[ smIds[i] ]; + + SMDSAbs_EntityType elemType; + if ( isNode ) + { + elemType = SMDSEntity_Node; + } + else + { + bool koElemType = false; + const TopoDS_Shape& shape = meshDS->IndexToShape( smIds[0] ); + elemType = getElemType( shape.ShapeType(), info->_elemCounter, koElemType ); + info->_isInfoOk = !koElemType; + } + info->setNb( elemType, info->_elemCounter ); + } + } + } // if ( aGroup->ExistInternalObject( aDSName )) + } // for ( int isNode = 0; isNode < 2; ++isNode ) + + aGroup->CloseOnDisk(); + } // if ( aTopGroup->ExistInternalObject( "Submeshes" )) + + aTopGroup->CloseOnDisk(); + } // if ( aFile->ExistInternalObject( meshGrpName ) ) + + aFile->CloseOnDisk(); + delete aFile; +} + +//================================================================================ +/*! + * \brief Return type of element for sub-mesh on a shape of given type + */ +//================================================================================ + +SMDSAbs_EntityType SMESH_PreMeshInfo::getElemType( const TopAbs_ShapeEnum shapeType, + const int nbElemsInSubMesh, + bool& isKoType) const +{ + isKoType = false; + int type, typeEnd; + SMESH_PreMeshInfo* meshInfo = _mesh->changePreMeshInfo(); + + switch ( shapeType ) + { + case TopAbs_SOLID: + type = SMDSEntity_Tetra; + typeEnd = SMDSEntity_Last; + isKoType = ( meshInfo->NbVolumes() != nbElemsInSubMesh ); + break; + case TopAbs_FACE: + case TopAbs_SHELL: + type = SMDSEntity_Triangle; + typeEnd = SMDSEntity_Tetra; + isKoType = ( meshInfo->NbFaces() != nbElemsInSubMesh ); + break; + case TopAbs_WIRE: + case TopAbs_EDGE: return SMDSEntity_Edge; + case TopAbs_VERTEX: return SMDSEntity_0D; + default: return SMDSEntity_Last; + } + + if ( !isKoType ) + { + for ( int t = type; t < typeEnd; ++t ) + if ( nbElemsInSubMesh == meshInfo->NbEntities( SMDSAbs_EntityType( t ))) + return SMDSAbs_EntityType( t ); + } + isKoType = true; + return SMDSAbs_EntityType( type ); +} + +//================================================================================ +/*! + * \brief Saves SMESH_PreMeshInfo to the study file + */ +//================================================================================ + +void SMESH_PreMeshInfo::SaveToFile( SMESH_Mesh_i* mesh, + const int meshID, + HDFfile* hdfFile) +{ + // create a HDF group for SMESH_PreMeshInfo of this mesh + SMESH_Comment hdfGroupName("SMESH_PreMeshInfo"); hdfGroupName << meshID; + HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, hdfFile ); + infoHdfGroup->CreateOnDisk(); + + PreMeshInfo_TRY; + + // info of mesh + meshInfo2hdf( mesh->GetMeshInfo(), "Mesh", infoHdfGroup ); + + // info of groups + SMESH_PreMeshInfo incompleteInfo( 0,0,"",""); + incompleteInfo.setNb( SMDSEntity_Node, GroupOnFilter_OutOfDate ); + SMESHDS_Mesh* meshDS = mesh->GetImpl().GetMeshDS(); + + map::const_iterator i2group = mesh->_mapGroups.begin(); + for ( ; i2group != mesh->_mapGroups.end(); ++i2group ) + { + if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( i2group->second )) + { + SMESHDS_GroupBase * group = group_i->GetGroupDS(); + if ( SMESHDS_GroupOnFilter* gof = dynamic_cast(group)) + { + // prevent too long storage time due to applying filter to many elements + if ( !gof->IsUpToDate() && meshDS->GetMeshInfo().NbElements( gof->GetType() ) > 1e5 ) + { + meshInfo2hdf( incompleteInfo.GetMeshInfo(), + group->GetStoreName(), + infoHdfGroup); + continue; + } + } + meshInfo2hdf( group_i->GetMeshInfo(), group->GetStoreName(), infoHdfGroup); + } + } + + // info of sub-meshes + map::iterator id2sm = mesh->_mapSubMeshIor.begin(); + for ( ; id2sm != mesh->_mapSubMeshIor.end(); ++id2sm ) + { + if ( SMESH_subMesh_i* sm = SMESH::DownCast( id2sm->second )) + { + meshInfo2hdf( sm->GetMeshInfo(), + SMESH_Comment( sm->GetId() ), + infoHdfGroup); + } + } + + PreMeshInfo_CATCH; + + infoHdfGroup->CloseOnDisk(); +} + +//================================================================================ +/*! + * \brief Reads all data and remove all SMESH_PreMeshInfo fields from objects + */ +//================================================================================ + +void SMESH_PreMeshInfo::FullLoadFromFile() const +{ + SignalToGUI signalOnLoading( _mesh ); + + SMESH_PreMeshInfo* meshInfo = _mesh->changePreMeshInfo(); + _mesh->changePreMeshInfo() = NULL; // to allow GUI accessing to real info + + ::SMESH_Mesh& mesh = _mesh->GetImpl(); + SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); + + PreMeshInfo_TRY; + + MYDEBUGOUT( "BEG FullLoadFromFile() " << _meshID ); + + // load mesh + DriverMED_R_SMESHDS_Mesh myReader; + myReader.SetFile( _medFileName.c_str() ); + myReader.SetMesh( meshDS ); + myReader.SetMeshId( _meshID ); + myReader.Perform(); + + // load groups + const set& groups = meshDS->GetGroups(); + set::const_iterator groupIt = groups.begin(); + for ( ; groupIt != groups.end(); ++groupIt ) + if ( SMESHDS_Group* aGrp = dynamic_cast( *groupIt )) + myReader.GetGroup( aGrp ); + + // load sub-meshes + readSubMeshes( &myReader ); + + PreMeshInfo_CATCH; + + _mesh->changePreMeshInfo() = meshInfo; + + ForgetAllData(); + + signalOnLoading.sendStop(); + + meshDS->Modified(); + + // load dependent meshes referring/referred via hypotheses + mesh.GetSubMesh( mesh.GetShapeToMesh() )-> + ComputeStateEngine (SMESH_subMesh::SUBMESH_LOADED); + + MYDEBUGOUT( "END FullLoadFromFile()" ); +} + +//================================================================================ +/*! + * \brief Reads full data of sub-meshes + */ +//================================================================================ + +void SMESH_PreMeshInfo::readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const +{ + HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() ); + aFile->OpenOnDisk( HDF_RDONLY ); + + char meshGrpName[ 30 ]; + sprintf( meshGrpName, "Mesh %d", _meshID ); + if ( aFile->ExistInternalObject( meshGrpName ) ) + { + HDFgroup* aTopGroup = new HDFgroup( meshGrpName, aFile ); + aTopGroup->OpenOnDisk(); + + SMESHDS_Mesh* meshDS = _mesh->GetImpl().GetMeshDS(); + + bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" )); + if ( submeshesInFamilies ) // from MED + { + // old way working before fix of PAL 12992 + reader->CreateAllSubMeshes(); + } + else + { + // open a group + HDFgroup* aGroup = new HDFgroup( "Submeshes", aTopGroup ); + aGroup->OpenOnDisk(); + + int maxID = Max( meshDS->MaxSubMeshIndex(), meshDS->MaxShapeIndex() ); + vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 ); + vector< TopAbs_ShapeEnum > smType ( maxID + 1, TopAbs_SHAPE ); + + PositionCreator aPositionCreator; + + SMDS_NodeIteratorPtr nIt = meshDS->nodesIterator(); + SMDS_ElemIteratorPtr eIt = meshDS->elementsIterator(); + for ( int isNode = 0; isNode < 2; ++isNode ) + { + string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); + if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() )) + { + HDFdataset* aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup ); + aDataset->OpenOnDisk(); + // read submesh IDs for all elements sorted by ID + int nbElems = aDataset->GetSize(); + int* smIDs = new int [ nbElems ]; + aDataset->ReadFromDisk( smIDs ); + aDataset->CloseOnDisk(); + + // get elements sorted by ID + TIDSortedElemSet elemSet; + if ( isNode ) + while ( nIt->more() ) elemSet.insert( elemSet.end(), nIt->next() ); + else + while ( eIt->more() ) elemSet.insert( elemSet.end(), eIt->next() ); + //ASSERT( elemSet.size() == nbElems ); -- issue 20182 + // -- Most probably a bad study was saved when there were + // not fixed bugs in SMDS_MeshInfo + if ( elemSet.size() < nbElems ) { +#ifdef _DEBUG_ + cout << "SMESH_Gen_i::Load(), warning: Node position data is invalid" << endl; +#endif + nbElems = elemSet.size(); + } + // add elements to submeshes + TIDSortedElemSet::iterator iE = elemSet.begin(); + for ( int i = 0; i < nbElems; ++i, ++iE ) + { + int smID = smIDs[ i ]; + if ( smID == 0 ) continue; + const SMDS_MeshElement* elem = *iE; + if ( smID > maxID ) { + // corresponding subshape no longer exists: maybe geom group has been edited + if ( _mesh->GetImpl().HasShapeToMesh() ) + meshDS->RemoveElement( elem ); + continue; + } + // get or create submesh + SMESHDS_SubMesh* & sm = subMeshes[ smID ]; + if ( ! sm ) { + sm = meshDS->NewSubMesh( smID ); + smType[ smID ] = meshDS->IndexToShape( smID ).ShapeType(); + } + // add + if ( isNode ) { + SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]); + SMDS_MeshNode* node = const_cast( static_cast( elem )); + node->SetPosition( pos ); + sm->AddNode( node ); + } else { + sm->AddElement( elem ); + } + } + delete [] smIDs; + } + } + } // end reading submeshes + + // Read node positions on sub-shapes (SMDS_Position) + + if ( aTopGroup->ExistInternalObject( "Node Positions" )) + { + // There are 5 datasets to read: + // "Nodes on Edges" - ID of node on edge + // "Edge positions" - U parameter on node on edge + // "Nodes on Faces" - ID of node on face + // "Face U positions" - U parameter of node on face + // "Face V positions" - V parameter of node on face + const char* aEid_DSName = "Nodes on Edges"; + const char* aEu_DSName = "Edge positions"; + const char* aFu_DSName = "Face U positions"; + //char* aFid_DSName = "Nodes on Faces"; + //char* aFv_DSName = "Face V positions"; + + // data to retrieve + int nbEids = 0, nbFids = 0; + int *aEids = 0, *aFids = 0; + double *aEpos = 0, *aFupos = 0, *aFvpos = 0; + + // open a group + HDFgroup* aGroup = new HDFgroup( "Node Positions", aTopGroup ); + aGroup->OpenOnDisk(); + + // loop on 5 data sets + int aNbObjects = aGroup->nInternalObjects(); + for ( int i = 0; i < aNbObjects; i++ ) + { + // identify dataset + char aDSName[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( i, aDSName ); + // read data + HDFdataset* aDataset = new HDFdataset( aDSName, aGroup ); + aDataset->OpenOnDisk(); + if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions + { + double* pos = new double [ aDataset->GetSize() ]; + aDataset->ReadFromDisk( pos ); + // which one? + if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 ) + aEpos = pos; + else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 ) + aFupos = pos; + else + aFvpos = pos; + } + else // NODE IDS + { + int aSize = aDataset->GetSize(); + + // for reading files, created from 18.07.2005 till 10.10.2005 + if (aDataset->GetType() == HDF_STRING) + aSize /= sizeof(int); + + int* ids = new int [aSize]; + aDataset->ReadFromDisk( ids ); + // on face or nodes? + if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) { + aEids = ids; + nbEids = aSize; + } + else { + aFids = ids; + nbFids = aSize; + } + } + aDataset->CloseOnDisk(); + } // loop on 5 datasets + + // Set node positions on edges or faces + for ( int onFace = 0; onFace < 2; onFace++ ) + { + int nbNodes = ( onFace ? nbFids : nbEids ); + if ( nbNodes == 0 ) continue; + int* aNodeIDs = ( onFace ? aFids : aEids ); + double* aUPos = ( onFace ? aFupos : aEpos ); + double* aVPos = ( onFace ? aFvpos : 0 ); + // loop on node IDs + for ( int iNode = 0; iNode < nbNodes; iNode++ ) + { + const SMDS_MeshNode* node = meshDS->FindNode( aNodeIDs[ iNode ]); + if ( !node ) continue; // maybe removed while Loading() if geometry changed + SMDS_PositionPtr aPos = node->GetPosition(); + ASSERT( aPos ); + if ( onFace ) { + // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );-- issue 20182 + // -- Most probably a bad study was saved when there were + // not fixed bugs in SMDS_MeshInfo + if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) { + SMDS_FacePosition* fPos = const_cast + ( static_cast( aPos )); + fPos->SetUParameter( aUPos[ iNode ]); + fPos->SetVParameter( aVPos[ iNode ]); + } + } + else { + // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182 + if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) { + SMDS_EdgePosition* fPos = const_cast + ( static_cast( aPos )); + fPos->SetUParameter( aUPos[ iNode ]); + } + } + } + } + if ( aEids ) delete [] aEids; + if ( aFids ) delete [] aFids; + if ( aEpos ) delete [] aEpos; + if ( aFupos ) delete [] aFupos; + if ( aFvpos ) delete [] aFvpos; + + aGroup->CloseOnDisk(); + + } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) ) + + aTopGroup->CloseOnDisk(); + } // if ( aFile->ExistInternalObject( meshGrpName ) ) + + aFile->CloseOnDisk(); + delete aFile; +} + +//================================================================================ +/*! + * \brief Remove all SMESH_PreMeshInfo fields from objects w/o data loading + */ +//================================================================================ + +void SMESH_PreMeshInfo::ForgetAllData() const +{ + PreMeshInfo_TRY; + + if ( _mesh->changePreMeshInfo() != this ) + return _mesh->changePreMeshInfo()->ForgetAllData(); + + // remove SMESH_PreMeshInfo from groups + map::const_iterator i2group = _mesh->_mapGroups.begin(); + for ( ; i2group != _mesh->_mapGroups.end(); ++i2group ) + { + if ( SMESH_GroupBase_i* group_i = + SMESH::DownCast( i2group->second )) + { + SMESH_PreMeshInfo* & info = group_i->changePreMeshInfo(); + delete info; + info = NULL; + } + } + // remove SMESH_PreMeshInfo from sub-meshes + map::iterator id2sm = _mesh->_mapSubMeshIor.begin(); + for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm ) + { + if ( SMESH_subMesh_i* sm = SMESH::DownCast( id2sm->second )) + { + SMESH_PreMeshInfo* & info = sm->changePreMeshInfo(); + delete info; + info = NULL; + } + } + // remove SMESH_PreMeshInfo from the mesh + _mesh->changePreMeshInfo() = NULL; + delete this; + + PreMeshInfo_CATCH; + + + // Finalize loading + + // PreMeshInfo_TRY; + + // ::SMESH_Mesh& mesh = _mesh->GetImpl(); + + // // update hyps needing full mesh data restored (issue 20918) + // // map::iterator id2hyp= _mesh->_mapHypo.begin(); + // // for ( ; id2hyp != _mesh->_mapHypo.end(); ++id2hyp ) + // // if ( SMESH_Hypothesis_i* hyp = SMESH::DownCast( id2hyp->second )) + // // hyp->UpdateAsMeshesRestored(); + + + // PreMeshInfo_CATCH; +} + +//================================================================================ +/*! + * \brief Calls either FullLoadFromFile() or ForgetAllData() depending on preferences + */ +//================================================================================ + +void SMESH_PreMeshInfo::ForgetOrLoad() const +{ + if ( SMESH_Gen_i::GetSMESHGen()->ToForgetMeshDataOnHypModif() && + _mesh->HasShapeToMesh()) + ForgetAllData(); + else + FullLoadFromFile(); +} + +//================================================================================ +/*! + * \brief Method of SMESH_IDSource interface + */ +//================================================================================ + +SMESH::array_of_ElementType* SMESH_PreMeshInfo::GetTypes() const +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + types->length( 4 ); + int nbTypes = 0; + if (NbEdges()) types[nbTypes++] = SMESH::EDGE; + if (NbFaces()) types[nbTypes++] = SMESH::FACE; + if (NbVolumes()) types[nbTypes++] = SMESH::VOLUME; + if (Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D; + if (NbBalls()) types[nbTypes++] = SMESH::BALL; + types->length( nbTypes ); + + return types._retn(); +} + +//================================================================================ +/*! + * \brief Method of SMESH_IDSource interface returning nb elements by element type + */ +//================================================================================ + +SMESH::long_array* SMESH_PreMeshInfo::GetMeshInfo() const +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = NbEntities((SMDSAbs_EntityType)i); + return aRes._retn(); +} + +//================================================================================ +/*! + * Returns false if GetMeshInfo() returns incorrect information that may + * happen if mesh data is not yet fully loaded from the file of study. + */ +//================================================================================ + +bool SMESH_PreMeshInfo::IsMeshInfoCorrect() const +{ + return _isInfoOk; +} + +//================================================================================ +/*! + * \brief TEMPORARY method to remove study files on closing study; + * RIGHT WAY: study files are remove automatically when meshes are destroyed + */ +//================================================================================ + +void SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD(SALOMEDS::SComponent_ptr smeshComp) +{ + SALOMEDS::Study_var study = smeshComp->GetStudy(); + if ( theStudyIDToMeshCounter[ (int) study->StudyId() ] > 0 ) + { + SALOMEDS::ChildIterator_var itBig = study->NewChildIterator( smeshComp ); + for ( ; itBig->More(); itBig->Next() ) { + SALOMEDS::SObject_var gotBranch = itBig->Value(); + CORBA::Object_var anObject = SMESH_Gen_i::SObjectToObject( gotBranch ); + if ( SMESH_Mesh_i* mesh = SMESH::DownCast( anObject )) + { + if ( mesh->changePreMeshInfo() ) + { + mesh->changePreMeshInfo()->ForgetAllData(); + } + } + } + } +} diff --git a/src/SMESH_I/SMESH_PreMeshInfo.hxx b/src/SMESH_I/SMESH_PreMeshInfo.hxx new file mode 100644 index 000000000..38b15a242 --- /dev/null +++ b/src/SMESH_I/SMESH_PreMeshInfo.hxx @@ -0,0 +1,125 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : SMESH_PreMeshInfo.hxx +// Created : Fri Feb 10 13:25:02 2012 +// Author : Edward AGAPOV (eap) + + +#ifndef __SMESH_PreMeshInfo_HXX__ +#define __SMESH_PreMeshInfo_HXX__ + +#include "SMDS_MeshInfo.hxx" +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SALOMEDS) + +#include + +class DriverMED_R_SMESHDS_Mesh; +class HDFfile; +class HDFgroup; +class SMESH_Mesh_i; + +/*! + * \brief Class loading and holding information of a mesh object (mesh, group, submesh) + * not yet loaded from HDF file of study. + * + * Usage scenario: + * - SMESH_PreMeshInfo::LoadFromFile() // reads info of all objects + * - if ( myPreInfo ) myPreInfo->NbElements() // access to info by objects + * - myPreInfo->FullLoadFromFile() // reads all mesh data and resets myPreInfo=NULL + */ + +class SMESH_PreMeshInfo : public SMDS_MeshInfo +{ +public: + // fills SMESH_PreMeshInfo field of all objects of mesh + static void LoadFromFile( SMESH_Mesh_i* mesh, + const int meshID, + const std::string& medFile, + const std::string& hdfFile, + const bool toRemoveFiles); + + // saves SMESH_PreMeshInfo to the study file + static void SaveToFile( SMESH_Mesh_i* mesh, + const int meshID, + HDFfile* hdfFile); + + // reads all data and remove all SMESH_PreMeshInfo fields from objects + void FullLoadFromFile() const; + + // remove all SMESH_PreMeshInfo fields from objects w/o data loading + void ForgetAllData() const; + + // calls either FullLoadFromFile() or ForgetAllData() depending on preferences; + // is called on hypothesis modification + void ForgetOrLoad() const; + + // meshods of SMESH_IDSource interface + SMESH::array_of_ElementType* GetTypes() const; + SMESH::long_array* GetMeshInfo() const; + bool IsMeshInfoCorrect() const; + + ~SMESH_PreMeshInfo(); + + // TEMPORARY method to remove study files on closing study; + // RIGHT WAY: study files are remove automatically when meshes are destroyed + static void RemoveStudyFiles_TMP_METHOD(SALOMEDS::SComponent_ptr smeshComp); + +private: + + // creation by LoadFromFile() only + SMESH_PreMeshInfo(SMESH_Mesh_i* mesh, + const int meshID, + const std::string& medFile, + const std::string& hdfFile); + + SMESH_PreMeshInfo* newInstance() + { return new SMESH_PreMeshInfo( _mesh,_meshID,_medFileName,_hdfFileName ); } + + // reading from the new study, for which SaveToFile() was called + bool readPreInfoFromHDF(); + void hdf2meshInfo( const std::string& dataSetName, HDFgroup* infoHdfGroup ); + + // reading from the old study, for which SaveToFile() was not called + bool readMeshInfo(); + void readGroupInfo(); + void readSubMeshInfo(); + SMDSAbs_EntityType getElemType( const TopAbs_ShapeEnum shapeType, + const int nbElemsInSubMesh, + bool& isKoType) const; + + void readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const; + + // general data + std::string _medFileName, _hdfFileName; + bool _toRemoveFiles; + int _meshID; + SMESH_Mesh_i* _mesh; + bool _isInfoOk; + + int _elemCounter; /* used as a counter while mesh info reading and + as a signal that mesh info is incorrect after reading + */ +}; + +#endif diff --git a/src/SMESH_I/SMESH_PythonDump.hxx b/src/SMESH_I/SMESH_PythonDump.hxx index 1ea9f59ff..29c544313 100644 --- a/src/SMESH_I/SMESH_PythonDump.hxx +++ b/src/SMESH_I/SMESH_PythonDump.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + #ifndef _SMESH_PYTHONDUMP_HXX_ #define _SMESH_PYTHONDUMP_HXX_ @@ -29,6 +30,7 @@ #include CORBA_SERVER_HEADER(SALOMEDS) #include +#include class SMESH_Gen_i; class SMESH_MeshEditor_i; @@ -37,7 +39,7 @@ class Resource_DataMapOfAsciiStringAsciiString; // =========================================================================================== /*! - * \brief Tool converting SMESH engine calls into commands defined in smesh.py + * \brief Tool converting SMESH engine calls into commands defined in smeshDC.py * * Implementation is in SMESH_2smeshpy.cxx */ @@ -51,19 +53,23 @@ public: * \param theScript - Input script * \param theEntry2AccessorMethod - The returning method names to access to * objects wrapped with python class + * \param theHistoricalDump - true means to keep all commands, false means + * to exclude commands relating to objects removed from study * \retval TCollection_AsciiString - Convertion result */ static TCollection_AsciiString - ConvertScript(const TCollection_AsciiString& theScript, + ConvertScript(const TCollection_AsciiString& theScript, Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, - Resource_DataMapOfAsciiStringAsciiString& theObjectNames); + Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + SALOMEDS::Study_ptr& theStudy, + const bool theHistoricalDump); /*! * \brief Return the name of the python file wrapping IDL API - * \retval TCollection_AsciiString - The file name + * \retval const char* - the file name */ static const char* SmeshpyName() { return "smesh"; } - static const char* GenName() { return "smesh.smesh"; } + static const char* GenName() { return "smesh"; } }; namespace SMESH @@ -72,73 +78,113 @@ namespace SMESH class FilterManager_i; class Filter_i; class Functor_i; + class Measurements_i; -// =========================================================================================== -/*! - * \brief Utility helping in storing SMESH engine calls as python commands - */ -// =========================================================================================== + // =========================================================================================== + /*! + * \brief Object used to make TPythonDump know that its held value can be a varible + * + * TPythonDump substitute TVar with names of notebook variables if any. + */ + // =========================================================================================== + + struct SMESH_I_EXPORT TVar + { + std::vector< std::string > myVals; + TVar(CORBA::Double value); + TVar(CORBA::Long value); + TVar(CORBA::Short value); + TVar(const SMESH::double_array& value); + // string used to temporary quote variable names in order + // not to confuse variables with string arguments + static char Quote() { return '$'; } + }; + + // =========================================================================================== + /*! + * \brief Utility helping in storing SMESH engine calls as python commands + */ + // =========================================================================================== class SMESH_I_EXPORT TPythonDump { std::ostringstream myStream; - static size_t myCounter; + static size_t myCounter; + int myVarsCounter; // counts stored TVar's public: TPythonDump(); virtual ~TPythonDump(); - - TPythonDump& + + TPythonDump& + operator<<(const TVar& theVariableValue); + + TPythonDump& operator<<(long int theArg); - TPythonDump& + TPythonDump& operator<<(int theArg); - TPythonDump& + TPythonDump& operator<<(double theArg); - TPythonDump& + TPythonDump& operator<<(float theArg); - TPythonDump& + TPythonDump& operator<<(const void* theArg); - TPythonDump& + TPythonDump& operator<<(const char* theArg); - TPythonDump& + TPythonDump& operator<<(const SMESH::ElementType& theArg); - TPythonDump& + TPythonDump& + operator<<(const SMESH::GeometryType& theArg); + + TPythonDump& operator<<(const SMESH::long_array& theArg); - TPythonDump& + TPythonDump& operator<<(const SMESH::double_array& theArg); - TPythonDump& + TPythonDump& + operator<<(const SMESH::string_array& theArg); + + TPythonDump& + operator<<(SMESH::SMESH_Hypothesis_ptr theArg); + + TPythonDump& + operator<<(SMESH::SMESH_IDSource_ptr theArg); + + TPythonDump& operator<<(SALOMEDS::SObject_ptr theArg); - TPythonDump& + TPythonDump& operator<<(CORBA::Object_ptr theArg); - TPythonDump& + TPythonDump& operator<<(SMESH::FilterLibrary_i* theArg); - TPythonDump& + TPythonDump& operator<<(SMESH::FilterManager_i* theArg); - TPythonDump& + TPythonDump& operator<<(SMESH::Filter_i* theArg); - TPythonDump& + TPythonDump& operator<<(SMESH::Functor_i* theArg); - TPythonDump& + TPythonDump& + operator<<(SMESH::Measurements_i* theArg); + + TPythonDump& operator<<(SMESH_Gen_i* theArg); - TPythonDump& + TPythonDump& operator<<(SMESH_MeshEditor_i* theArg); - TPythonDump& + TPythonDump& operator<<(SMESH::MED_VERSION theArg); TPythonDump& @@ -147,18 +193,27 @@ namespace SMESH TPythonDump& operator<<(const SMESH::DirStruct & theDir); + TPythonDump& + operator<<(const SMESH::PointStruct & P); + TPythonDump& operator<<(const TCollection_AsciiString & theArg); + TPythonDump& + operator<<(const SMESH::ListOfGroups& theList); + TPythonDump& operator<<(const SMESH::ListOfGroups * theList); + TPythonDump& + operator<<(const SMESH::ListOfIDSources& theList); + static const char* SMESHGenName() { return "smeshgen"; } static const char* MeshEditorName() { return "mesh_editor"; } /*! * \brief Return marker of long string literal beginning - * \param type - a name of functionality producing the string literal + * \param type - a name of functionality producing the string literal * \retval TCollection_AsciiString - the marker string to be written into * a raw python script */ @@ -176,7 +231,7 @@ namespace SMESH * \param theLongString - the retrieved literal * \param theStringType - a name of functionality produced the literal * \retval bool - true if a string literal found - * + * * The literal is removed from theText; theFrom points position right after * the removed literal */ diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index f90cb300a..fd7fc3d80 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -1,33 +1,34 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_subMesh_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "SMESH_subMesh_i.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Mesh_i.hxx" +#include "SMESH_PreMeshInfo.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" @@ -49,7 +50,7 @@ SMESH_subMesh_i::SMESH_subMesh_i() : SALOME::GenericObj_i( PortableServer::POA::_nil() ) { MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use"); - ASSERT(0); + ASSERT(0); } //============================================================================= @@ -59,16 +60,15 @@ SMESH_subMesh_i::SMESH_subMesh_i() //============================================================================= SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA, - SMESH_Gen_i* gen_i, - SMESH_Mesh_i* mesh_i, - int localId ) + SMESH_Gen_i* gen_i, + SMESH_Mesh_i* mesh_i, + int localId ) : SALOME::GenericObj_i( thePOA ) { - MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i"); _gen_i = gen_i; _mesh_i = mesh_i; _localId = localId; - // **** + _preMeshInfo = NULL; } //============================================================================= /*! @@ -79,7 +79,8 @@ SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA, SMESH_subMesh_i::~SMESH_subMesh_i() { MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i"); - // **** + if ( _preMeshInfo ) delete _preMeshInfo; + _preMeshInfo = NULL; } //======================================================================= @@ -161,7 +162,10 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetNumberOfElements"); + + if ( _preMeshInfo ) + return _preMeshInfo->NbElements(); + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return 0; @@ -191,10 +195,15 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetNumberOfNodes"); + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return 0; + if ( _preMeshInfo ) + { + if ( all ) return _preMeshInfo->NbNodes(); + else _preMeshInfo->FullLoadFromFile(); + } ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); @@ -257,12 +266,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetElementsId"); + SMESH::long_array_var aResult = new SMESH::long_array(); if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return aResult._retn(); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); @@ -304,12 +316,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetElementsByType"); + SMESH::long_array_var aResult = new SMESH::long_array(); if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return aResult._retn(); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); @@ -412,7 +427,7 @@ SMESH::long_array* SMESH_subMesh_i::GetNodesId() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetNodesId"); + SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE ); return aResult._retn(); } @@ -427,7 +442,6 @@ SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetFather"); return _mesh_i->_this(); } @@ -439,7 +453,6 @@ SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather() CORBA::Long SMESH_subMesh_i::GetId() { - MESSAGE("SMESH_subMesh_i::GetId"); return _localId; } @@ -458,11 +471,11 @@ GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape() TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape(); if ( !S.IsNull() ) { aShapeObj = _gen_i->ShapeToGeomObject( S ); - //mzn: N7PAL16232, N7PAL16233 - //In some cases it's possible that GEOM_Client contains the shape same to S, but - //with another orientation. - if (aShapeObj->_is_nil()) - aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() ); + //mzn: N7PAL16232, N7PAL16233 + //In some cases it's possible that GEOM_Client contains the shape same to S, but + //with another orientation. + if (aShapeObj->_is_nil()) + aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() ); } } } @@ -481,6 +494,8 @@ SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh(); SALOME_MED::Family_array_var families = @@ -501,8 +516,7 @@ SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily() //============================================================================= SMESH::long_array* SMESH_subMesh_i::GetIDs() { - SMESH::long_array_var aResult = GetElementsId(); - return aResult._retn(); + return GetElementsId(); } //============================================================================= @@ -513,5 +527,100 @@ SMESH::long_array* SMESH_subMesh_i::GetIDs() SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem ) throw (SALOME::SALOME_Exception) { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); return GetFather()->GetElementType( id, iselem ); } + + +//============================================================================= +/*! + * Returns statistic of mesh elements + * Result array of number enityties + * Inherited from SMESH_IDSource + */ +//============================================================================= +SMESH::long_array* SMESH_subMesh_i::GetMeshInfo() +{ + if ( _preMeshInfo ) + return _preMeshInfo->GetMeshInfo(); + + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + + // get number of nodes + aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true); + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + + // get statistic from child sub-meshes + TListOfSubMeshes smList; + if ( getSubMeshes( aSubMesh, smList ) ) + for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm ) + SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes ); + + return aRes._retn(); +} + + +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes() +{ + if ( _preMeshInfo ) + return _preMeshInfo->GetTypes(); + + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() ) + { + SMDS_ElemIteratorPtr eIt = smDS->GetElements(); + if ( eIt->more() ) + { + types->length( 1 ); + types[0] = SMESH::ElementType( eIt->next()->GetType()); + } + else if ( smDS->GetNodes()->more() ) + { + TopoDS_Shape shape = aSubMesh->GetSubShape(); + while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND ) + { + TopoDS_Iterator it( shape ); + shape = it.More() ? it.Value() : TopoDS_Shape(); + } + if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX ) + { + types->length( 1 ); + types[0] = SMESH::NODE; + } + } + } + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : interface SMESH_IDSource +//======================================================================= + +SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh() +{ + return GetFather(); +} + +//======================================================================= +//function : IsMeshInfoCorrect +//purpose : * Returns false if GetMeshInfo() returns incorrect information that may +// * happen if mesh data is not yet fully loaded from the file of study. +//======================================================================= + +bool SMESH_subMesh_i::IsMeshInfoCorrect() +{ + return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true; +} diff --git a/src/SMESH_I/SMESH_subMesh_i.hxx b/src/SMESH_I/SMESH_subMesh_i.hxx index fcfc5673b..d9cf053a6 100644 --- a/src/SMESH_I/SMESH_subMesh_i.hxx +++ b/src/SMESH_I/SMESH_subMesh_i.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_subMesh_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_SUBMESH_I_HXX_ #define _SMESH_SUBMESH_I_HXX_ @@ -40,7 +40,7 @@ #include "SMESH_Mesh_i.hxx" class SMESH_Gen_i; -class SMESH_Mesh_i; +class SMESH_PreMeshInfo; class SMESH_I_EXPORT SMESH_subMesh_i: public virtual POA_SMESH::SMESH_subMesh, @@ -50,8 +50,8 @@ public: SMESH_subMesh_i(); SMESH_subMesh_i( PortableServer::POA_ptr thePOA, SMESH_Gen_i* gen_i, - SMESH_Mesh_i* mesh_i, - int localId ); + SMESH_Mesh_i* mesh_i, + int localId ); ~SMESH_subMesh_i(); CORBA::Long GetNumberOfElements() @@ -66,9 +66,6 @@ public: SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType ) throw (SALOME::SALOME_Exception); - //for omniORB conflict compilation - /*SMESH::ElementType GetElementType( const CORBA::Long id, const bool iselem ) - throw (SALOME::SALOME_Exception);*/ SMESH::ElementType GetElementType( CORBA::Long id, bool iselem ) throw (SALOME::SALOME_Exception); @@ -81,21 +78,53 @@ public: GEOM::GEOM_Object_ptr GetSubShape() throw (SALOME::SALOME_Exception); - CORBA::Long GetId(); + CORBA::Long GetId(); SALOME_MED::FAMILY_ptr GetFamily() throw (SALOME::SALOME_Exception); + + // ========================= + // interface SMESH_IDSource + // ========================= + /*! + * Returns a sequence of all element IDs + */ virtual SMESH::long_array* GetIDs(); + /*! + * Returns statistic of mesh elements + * Result array of number enityties + * Inherited from SMESH_IDSource + */ + virtual SMESH::long_array* GetMeshInfo(); + /*! + * Returns types of elements it contains + */ + virtual SMESH::array_of_ElementType* GetTypes(); + /*! + * Returns the mesh + */ + virtual SMESH::SMESH_Mesh_ptr GetMesh(); + /*! + * Returns false if GetMeshInfo() returns incorrect information that may + * happen if mesh data is not yet fully loaded from the file of study. + */ + virtual bool IsMeshInfoCorrect(); - SMESH_Mesh_i* _mesh_i; //NRI protected: - void changeLocalId(int localId) { _localId = localId; } - SMESH_Gen_i* _gen_i; - int _localId; + SMESH_Gen_i* _gen_i; + int _localId; + SMESH_Mesh_i* _mesh_i; //NRI + + void changeLocalId(int localId) { _localId = localId; } friend void SMESH_Mesh_i::CheckGeomGroupModif(); + + SMESH_PreMeshInfo* _preMeshInfo; // mesh info before full loading from study file + + SMESH_PreMeshInfo* & changePreMeshInfo() { return _preMeshInfo; } + friend class SMESH_PreMeshInfo; }; #endif diff --git a/src/SMESH_I/smeshpy.py b/src/SMESH_I/smeshpy.py index 869ea8108..fa01ce28f 100644 --- a/src/SMESH_I/smeshpy.py +++ b/src/SMESH_I/smeshpy.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses # File : smeshpy.py # Module : SMESH diff --git a/src/SMESH_PY/Makefile.am b/src/SMESH_PY/Makefile.am new file mode 100644 index 000000000..3219c8567 --- /dev/null +++ b/src/SMESH_PY/Makefile.am @@ -0,0 +1,25 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +salomepypkgdir = $(smeshpypkgdir) +salomepypkg_PYTHON = \ + __init__.py \ + smeshstudytools.py diff --git a/src/SMESH_PY/__init__.py b/src/SMESH_PY/__init__.py new file mode 100644 index 000000000..f333c9216 --- /dev/null +++ b/src/SMESH_PY/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2010-2011 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# diff --git a/src/SMESH_PY/smeshstudytools.py b/src/SMESH_PY/smeshstudytools.py new file mode 100644 index 000000000..7281fe519 --- /dev/null +++ b/src/SMESH_PY/smeshstudytools.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +""" +This module provides a new class :class:`SMeshStudyTools` to facilitate the +use of mesh objects in Salome study. +""" + +import salome +SMESH = None # SMESH module is loaded only when needed + +from salome.kernel.studyedit import getStudyEditor +try: + from salome.gui import helper +except ImportError: + pass + +class SMeshStudyTools: + """ + This class provides several methods to manipulate mesh objects in Salome + study. The parameter `studyEditor` defines a + :class:`~salome.kernel.studyedit.StudyEditor` object used to access the study. If + :const:`None`, the method returns a :class:`~salome.kernel.studyedit.StudyEditor` + object on the current study. + + .. attribute:: editor + + This instance attribute contains the underlying + :class:`~salome.kernel.studyedit.StudyEditor` object. It can be used to access + the study but the attribute itself should not be modified. + + """ + + def __init__(self, studyEditor = None): + global SMESH + if SMESH is None: + SMESH = __import__("SMESH") + if studyEditor is None: + studyEditor = getStudyEditor() + self.editor = studyEditor + self.smeshGui = None + + def updateStudy(self, studyId=None): + """ + This function updates the tools so that it works on the + specified study. + """ + self.editor = getStudyEditor(studyId) + + def getMeshFromGroup(self, meshGroupItem): + """ + Get the mesh item owning the mesh group `meshGroupItem`. + + :type meshGroupItem: SObject + :param meshGroupItem: Mesh group belonging to the searched mesh. + + :return: The SObject corresponding to the mesh, or None if it was not + found. + """ + meshItem = None + obj = self.editor.getOrLoadObject(meshGroupItem) + group = obj._narrow(SMESH.SMESH_GroupBase) + if group is not None: # The type of the object is ok + meshObj = group.GetMesh() + meshItem = salome.ObjectToSObject(meshObj) + return meshItem + + + def getMeshObjectSelected(self): + ''' + Returns the MESH object currently selected in the active study. + ''' + sobject, entry = helper.getSObjectSelected() + meshObject = self.getMeshObjectFromEntry(entry) + return meshObject + + def getMeshObjectFromEntry(self, entry): + ''' + Returns the MESH object associated to the specified entry, + (the entry is the identifier of an item in the objects browser). + ''' + if entry is None: + return None + import smesh + smesh.SetCurrentStudy(self.editor.study) + meshObject=smesh.IDToObject(entry) + return meshObject + + def getMeshObjectFromSObject(self, sobject): + ''' + Returns the SMESH object associated to the specified SObject, + (the SObject is an item in the objects browser). + ''' + if sobject is None: + return None + + obj = self.editor.getOrLoadObject(sobject) + meshObject = obj._narrow(SMESH.SMESH_Mesh) + return meshObject + + def displayMeshObjectFromEntry(self,entry): + ''' + Display the SMESH object associated to the specified entry + (the entry is the identifier of an item in the objects browser). + ''' + if self.smeshGui is None: + self.smeshGui = salome.ImportComponentGUI("SMESH") + + if not helper.SalomeGUI.hasDesktop(): + print "displayMeshObject: no desktop available" + return + self.smeshGui.CreateAndDisplayActor(entry) + +# +# ================================================================== +# Use cases and demo functions +# ================================================================== +# + +# CAUTION: Before running this test functions, you first have to +# create (or import) an smesh object and select this object in the +# objects browser. You can run the box mesh creation procedure below +# instead. + +# How to test? +# 1. Run a SALOME application including GEOM and SMESH, and create a new study +# 2. In the console, enter: +# >>> from salome.smesh import smeshstudytools +# >>> smeshstudytools.TEST_createBoxMesh() +# 3. Select the object named "boxmesh" in the browser +# 4. In the console, enter: +# >>> smeshstudytools.TEST_selectAndExport_01() +# >>> smeshstudytools.TEST_selectAndExport_02() +# >>> smeshstudytools.TEST_display() + + +def TEST_createBoxMesh(): + theStudy = helper.getActiveStudy() + + import geompy + geompy.init_geom(theStudy) + box = geompy.MakeBoxDXDYDZ(200, 200, 200) + + import smesh, SMESH, SALOMEDS + smesh.SetCurrentStudy(theStudy) + import StdMeshers + boxmesh = smesh.Mesh(box) + Regular_1D = boxmesh.Segment() + Nb_Segments_1 = Regular_1D.NumberOfSegments(15) + Nb_Segments_1.SetDistrType( 0 ) + Quadrangle_2D = boxmesh.Quadrangle() + Hexa_3D = smesh.CreateHypothesis('Hexa_3D') + status = boxmesh.AddHypothesis(Hexa_3D) + isDone = boxmesh.Compute() + + smesh.SetName(boxmesh.GetMesh(), 'boxmesh') + if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(1) + +# +# Definitions: +# - the SObject is an item in the study (Study Object). +# - the entry is the identifier of an item. +# - the object (geom object or smesh object) is a CORBA servant +# embedded in the SALOME component container and with a reference in +# the SALOME study, so that it can be retrieved. +# + +def TEST_selectAndExport_01(): + tool = SMeshStudyTools() + myMesh = tool.getMeshObjectSelected() + myMesh.ExportUNV("/tmp/myMesh.unv") + +def TEST_selectAndExport_02(): + # In this case, we want to retrieve the name of the mesh in the + # object browser. Note that in SALOME, a mesh object has no + # name. Only the SObject in the object browser has a name + # attribute. + tool = SMeshStudyTools() + + mySObject, myEntry = helper.getSObjectSelected() + myName = mySObject.GetName() + + myMesh = tool.getMeshObjectFromEntry(myEntry) + exportFileName = "/tmp/"+myName+".unv" + myMesh.ExportUNV(exportFileName) + +def TEST_display(): + mySObject, myEntry = helper.getSObjectSelected() + + tool = SMeshStudyTools() + tool.displayMeshObjectFromEntry(myEntry) + +if __name__ == "__main__": + TEST_selectAndExport_01() + TEST_selectAndExport_02() + TEST_display() diff --git a/src/SMESH_SWIG/Makefile.am b/src/SMESH_SWIG/Makefile.am index 7b6ef9fe4..ab94f663c 100644 --- a/src/SMESH_SWIG/Makefile.am +++ b/src/SMESH_SWIG/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : Makefile.in # Author : Nicolas REJNERI, Paul RASCLE # Modified by : Alexander BORODIN (OCN) - autotools usage @@ -31,6 +29,7 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am dist_salomescript_DATA= \ smesh.py \ smeshDC.py \ + StdMeshersDC.py \ batchmode_smesh.py \ batchmode_mefisto.py \ ex00_all.py \ diff --git a/src/SMESH_SWIG/PAL_MESH_041_mesh.py b/src/SMESH_SWIG/PAL_MESH_041_mesh.py index c1138f9be..bbfdd1abf 100755 --- a/src/SMESH_SWIG/PAL_MESH_041_mesh.py +++ b/src/SMESH_SWIG/PAL_MESH_041_mesh.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + import salome import geompy import smesh @@ -53,7 +55,7 @@ Id_face1 = geompy.addToStudy(face1,"Face1") #-----------------------------SMESH------------------------------------------- - +smesh.SetCurrentStudy(salome.myStudy) # -- Init mesh -- plane_mesh = salome.IDToObject( Id_face1) diff --git a/src/SMESH_SWIG/PAL_MESH_043_2D.py b/src/SMESH_SWIG/PAL_MESH_043_2D.py index 678f6db30..8db9bf12f 100755 --- a/src/SMESH_SWIG/PAL_MESH_043_2D.py +++ b/src/SMESH_SWIG/PAL_MESH_043_2D.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_testExtrusion2D.py # Module : SMESH # Description : Create meshes to test extrusion of mesh elements along path @@ -51,6 +53,7 @@ id_ellipse2 = geompy.addToStudy(ellipse2, "Ellips 2") #---------------------------------SMESH +smesh.SetCurrentStudy(salome.myStudy) # create the path mesh mesh1 = smesh.Mesh(ellipse1, "Path Mesh") diff --git a/src/SMESH_SWIG/PAL_MESH_043_3D.py b/src/SMESH_SWIG/PAL_MESH_043_3D.py index e40854bbe..9607f9bb7 100755 --- a/src/SMESH_SWIG/PAL_MESH_043_3D.py +++ b/src/SMESH_SWIG/PAL_MESH_043_3D.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_testExtrusion3D.py # Module : SMESH # Description : Create meshes to test extrusion of mesh elements along path @@ -49,6 +51,7 @@ idcircle = geompy.addToStudy(circle, "Circle") idface = geompy.addToStudy(face, "Circular face") +smesh.SetCurrentStudy(salome.myStudy) # init a Mesh with the circular face mesh1 = smesh.Mesh(face, "Mesh on circular face") diff --git a/src/SMESH_SWIG/SMESH_AdvancedEditor.py b/src/SMESH_SWIG/SMESH_AdvancedEditor.py index 86e8ce1f0..958dba283 100644 --- a/src/SMESH_SWIG/SMESH_AdvancedEditor.py +++ b/src/SMESH_SWIG/SMESH_AdvancedEditor.py @@ -1,27 +1,32 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + +import salome import smesh import math +salome.salome_init() + def GetNewNodes(mesh,Elems,OldNodes): """ Auxilary function, which return list of nodes from @@ -50,7 +55,8 @@ def GetNewNodes(mesh,Elems,OldNodes): pass return newnodes - +smesh.SetCurrentStudy(salome.myStudy) + # create empty mesh mesh = smesh.Mesh() diff --git a/src/SMESH_SWIG/SMESH_BelongToGeom.py b/src/SMESH_SWIG/SMESH_BelongToGeom.py index b66986067..d1ef60872 100644 --- a/src/SMESH_SWIG/SMESH_BelongToGeom.py +++ b/src/SMESH_SWIG/SMESH_BelongToGeom.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + from SMESH_test1 import * ## Old style @@ -38,6 +40,7 @@ def CheckBelongToGeomFilterOld(theMeshGen, theMesh, theShape, theSubShape, theEl aBelongToGeom.SetElementType(theElemType) aFilter.SetPredicate(aBelongToGeom) + aFilterMgr.UnRegister() return aFilter.GetElementsId(theMesh) ## Current style diff --git a/src/SMESH_SWIG/SMESH_BuildCompound.py b/src/SMESH_SWIG/SMESH_BuildCompound.py index 87c7e47ca..0c1a9126d 100644 --- a/src/SMESH_SWIG/SMESH_BuildCompound.py +++ b/src/SMESH_SWIG/SMESH_BuildCompound.py @@ -1,24 +1,23 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_BuildCompound.py # Author : Alexander KOVALEV # Module : SMESH @@ -28,6 +27,7 @@ # ! as some sequences of symbols from this example are used during # ! documentation generation to identify certain places of this file # +import salome import geompy import smesh @@ -60,6 +60,8 @@ geompy.addToStudy(Box_sup, "Box_sup") geompy.addToStudyInFather(Box_sup, Fsup2, "Fsup") geompy.addToStudyInFather(Box_sup, Finf2, "Finf") +smesh.SetCurrentStudy(salome.myStudy) + ## create a bottom mesh Mesh_inf = smesh.Mesh(Box_inf, "Mesh_inf") algo1D_1=Mesh_inf.Segment() @@ -93,6 +95,6 @@ Compound1 = smesh.smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 0, smesh.SetName(Compound1, 'Compound_with_RenamedGrps_and_MergeElems') # create a compound of two meshes with uniting groups with the same names and # creating groups of all elements -Compound2 = smesh.smesh.ConcatenateWithGroups([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e-05) +Compound2 = smesh.smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e-05, True) smesh.SetName(Compound2, 'Compound_with_UniteGrps_and_GrpsOfAllElems') #end diff --git a/src/SMESH_SWIG/SMESH_GroupFromGeom.py b/src/SMESH_SWIG/SMESH_GroupFromGeom.py index 1bc88014b..8c746d15e 100644 --- a/src/SMESH_SWIG/SMESH_GroupFromGeom.py +++ b/src/SMESH_SWIG/SMESH_GroupFromGeom.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_GroupFromGeom.py # Module : SMESH # diff --git a/src/SMESH_SWIG/SMESH_GroupFromGeom2.py b/src/SMESH_SWIG/SMESH_GroupFromGeom2.py index 0b15ecbac..02ec044fe 100755 --- a/src/SMESH_SWIG/SMESH_GroupFromGeom2.py +++ b/src/SMESH_SWIG/SMESH_GroupFromGeom2.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + #============================================================================== # Info. # Bug (from script, bug) : SMESH_GroupFromGeom.py, PAL6945 diff --git a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py index 67d498fad..03978e0d5 100644 --- a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py +++ b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py @@ -1,26 +1,31 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + +import salome import smesh +smesh.SetCurrentStudy(salome.myStudy) + def BuildGroupLyingOn(theMesh, theElemType, theName, theShape): aFilterMgr = smesh.smesh.CreateFilterManager() aFilter = aFilterMgr.CreateFilter() @@ -31,6 +36,7 @@ def BuildGroupLyingOn(theMesh, theElemType, theName, theShape): aFilter.SetPredicate(aLyingOnGeom) anIds = aFilter.GetElementsId(theMesh) + aFilterMgr.UnRegister() aGroup = theMesh.CreateGroup(theElemType, theName) aGroup.Add(anIds) diff --git a/src/SMESH_SWIG/SMESH_Nut.py b/src/SMESH_SWIG/SMESH_Nut.py index 6d2ac9e86..e292cbc2a 100755 --- a/src/SMESH_SWIG/SMESH_Nut.py +++ b/src/SMESH_SWIG/SMESH_Nut.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + ##################################################################### #Created :17/02/2005 #Auhtor :MASLOV Eugeny, KOVALTCHUK Alexey @@ -72,7 +74,7 @@ for i in range(0, len(CommonExplodedListEdges)): #Fillet applying print "Fillet creation..." -Fillet_1 = geompy.MakeFillet(Common_1, 10, geompy.ShapeType["EDGE"], [6]) +Fillet_1 = geompy.MakeFillet(Common_1, 10, geompy.ShapeType["EDGE"], [5]) geompy.addToStudy(Fillet_1, "Fillet_1") #Chamfer applying @@ -85,7 +87,7 @@ geompy.addToStudy(Chamfer_2, "Chamfer_2") #Import of the shape from "slots.brep" print "Import multi-rotation from the DATA_DIR/Shapes/Brep/slots.brep" thePath = os.getenv("DATA_DIR") -theFileName = thePath + "/Shapes/Brep/slots.brep" +theFileName = os.path.join( thePath,"Shapes","Brep","slots.brep") theShapeForCut = geompy.ImportBREP(theFileName) geompy.addToStudy(theShapeForCut, "slot.brep_1") @@ -96,6 +98,8 @@ Cut_1_ID = geompy.addToStudy(Cut_1, "Cut_1") #Mesh creation +smesh.SetCurrentStudy(salome.myStudy) + # -- Init -- shape_mesh = salome.IDToObject( Cut_1_ID ) diff --git a/src/SMESH_SWIG/SMESH_Partition1_tetra.py b/src/SMESH_SWIG/SMESH_Partition1_tetra.py index 11a68dfa4..ddd5bb16e 100644 --- a/src/SMESH_SWIG/SMESH_Partition1_tetra.py +++ b/src/SMESH_SWIG/SMESH_Partition1_tetra.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tetrahedrization of the geometry generated by the Python script GEOM_Partition1.py # Hypothesis and algorithms for the mesh generation are global # -- Rayon de la bariere @@ -86,7 +88,7 @@ print "number of Edges in alveole : ", len(subEdgeList) subshapes = geompy.SubShapeAll(alveole, geompy.ShapeType["SHAPE"]) -## there are 9 subshapes +## there are 9 sub-shapes comp1 = geompy.MakeCompound( [ subshapes[0], subshapes[1] ] ) comp2 = geompy.MakeCompound( [ subshapes[2], subshapes[3] ] ) @@ -118,6 +120,7 @@ status = geompy.CheckShape(alveole) print " check status ", status # ---- launch SMESH +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the alveole shape_mesh = salome.IDToObject( idalveole ) diff --git a/src/SMESH_SWIG/SMESH_Sphere.py b/src/SMESH_SWIG/SMESH_Sphere.py index b39917819..64a390752 100644 --- a/src/SMESH_SWIG/SMESH_Sphere.py +++ b/src/SMESH_SWIG/SMESH_Sphere.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # GEOM GEOM_SWIG : binding of C++ omplementaion with Python # File : GEOM_Sphere.py # Author : Damien COQUERET, Open CASCADE @@ -77,8 +79,8 @@ Cube = MakeHexa2Faces(Face1, Face3) Common1 = MakeBoolean(Sphere, Block, 1) Common2 = MakeRotation(Common1, VZ, Angle90) -MultiBlock1 = MakeMultiTransformation1D(Common1, 21, -1, 3) -MultiBlock2 = MakeMultiTransformation1D(Common2, 31, -1, 3) +MultiBlock1 = MakeMultiTransformation1D(Common1, 20, -1, 3) +MultiBlock2 = MakeMultiTransformation1D(Common2, 30, -1, 3) #Reconstruct sphere from several blocks ShapesList.append(Cube) @@ -102,6 +104,7 @@ Id_Result = addToStudy(Result, "Result") #----------------------------------------------------------------------- #Meshing +smesh.SetCurrentStudy(salome.myStudy) my_hexa = smesh.Mesh(Result, "Sphere_Mesh") algo = my_hexa.Segment() algo.NumberOfSegments(NbSeg) diff --git a/src/SMESH_SWIG/SMESH_blocks.py b/src/SMESH_SWIG/SMESH_blocks.py index e61ce50f2..2de2a408f 100644 --- a/src/SMESH_SWIG/SMESH_blocks.py +++ b/src/SMESH_SWIG/SMESH_blocks.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESH_SWIG : binding of C++ implementaion with Python # File : SMESH_blocks.py # Author : Julia DOROVSKIKH @@ -35,6 +37,7 @@ import GEOM_Spanner isBlocksTest = 0 # False isMeshTest = 1 # True +smesh.SetCurrentStudy(salome.myStudy) GEOM_Spanner.MakeSpanner(geompy, math, isBlocksTest, isMeshTest, smesh) diff --git a/src/SMESH_SWIG/SMESH_box.py b/src/SMESH_SWIG/SMESH_box.py index b57138a1c..8680208cb 100755 --- a/src/SMESH_SWIG/SMESH_box.py +++ b/src/SMESH_SWIG/SMESH_box.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + #============================================================================== # Info. # Bug (from script, bug) : box.py, PAL5223 @@ -46,6 +48,7 @@ box = geompy.MakeBox(0.,0.,0.,1.,1.,1.) boxId = geompy.addToStudy(box,"box") # ---- SMESH +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh diff --git a/src/SMESH_SWIG/SMESH_box2_tetra.py b/src/SMESH_SWIG/SMESH_box2_tetra.py index c77f1f001..0aaa8cbab 100644 --- a/src/SMESH_SWIG/SMESH_box2_tetra.py +++ b/src/SMESH_SWIG/SMESH_box2_tetra.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tetrahedrization of the geometry union of 2 boxes having a face in common # Hypothesis and algorithms for the mesh generation are global # @@ -72,6 +74,7 @@ print "number of Edges in shell : ", len(subEdgeList) ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the shell diff --git a/src/SMESH_SWIG/SMESH_box3_tetra.py b/src/SMESH_SWIG/SMESH_box3_tetra.py index e13fd8659..503ff4f87 100644 --- a/src/SMESH_SWIG/SMESH_box3_tetra.py +++ b/src/SMESH_SWIG/SMESH_box3_tetra.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tetrahedrization of the geometry union of 3 boxes aligned where the middle # one has a race in common with the two others. # Hypothesis and algorithms for the mesh generation are global @@ -83,7 +85,7 @@ print "number of Edges in shell : ", len(subEdgeList) ### ---------------------------- SMESH -------------------------------------- - +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the shell diff --git a/src/SMESH_SWIG/SMESH_box_tetra.py b/src/SMESH_SWIG/SMESH_box_tetra.py index 39dd1db2d..4aff58411 100644 --- a/src/SMESH_SWIG/SMESH_box_tetra.py +++ b/src/SMESH_SWIG/SMESH_box_tetra.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tetrahedrization of a simple box. Hypothesis and algorithms for # the mesh generation are global # @@ -44,6 +46,7 @@ print "number of Edges in box : ", len(subEdgeList) ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the boxe diff --git a/src/SMESH_SWIG/SMESH_controls.py b/src/SMESH_SWIG/SMESH_controls.py index 18cdb4a4c..d7f533cab 100644 --- a/src/SMESH_SWIG/SMESH_controls.py +++ b/src/SMESH_SWIG/SMESH_controls.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_control.py # Author : Sergey LITONIN # Module : SMESH @@ -126,4 +128,16 @@ print "Criterion: Borders at multi-connections = 2 Nb = ", len( anIds ) #print anIds[ i ] +# Criterion : Element Diameter 2D > 10 + +# create group +aGroup = mesh.MakeGroup("Element Diameter 2D > 10", smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10 ) + +# print result +anIds = aGroup.GetIDs() +print "Criterion: Element Diameter 2D > 10 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + + salome.sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py b/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py index 245fccec4..555ad5b08 100755 --- a/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py +++ b/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + #============================================================================== # Info. # Bug (from script, bug) : SMESH_demo_hexa2_upd.py, PAL6781 @@ -123,6 +125,7 @@ for i in range(8): idEdgeZ.append(geompy.addToStudyInFather(vol,edgeZ[i],"EdgeZ"+str(i+1))) ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the volume diff --git a/src/SMESH_SWIG/SMESH_fixation.py b/src/SMESH_SWIG/SMESH_fixation.py index 597b1d0ea..e5a68fdec 100644 --- a/src/SMESH_SWIG/SMESH_fixation.py +++ b/src/SMESH_SWIG/SMESH_fixation.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_fix_volute.py # Author : Paul RASCLE, EDF # Module : SMESH diff --git a/src/SMESH_SWIG/SMESH_fixation_hexa.py b/src/SMESH_SWIG/SMESH_fixation_hexa.py index 5195cc9ae..3110f003a 100644 --- a/src/SMESH_SWIG/SMESH_fixation_hexa.py +++ b/src/SMESH_SWIG/SMESH_fixation_hexa.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Hexahedrization of the geometry generated by the Python script # SMESH_fixation.py # Hypothesis and algorithms for the mesh generation are global @@ -44,6 +46,7 @@ status = geompy.CheckShape(compshell) print " check status ", status ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the compshell shape_mesh = salome.IDToObject( idcomp ) diff --git a/src/SMESH_SWIG/SMESH_fixation_netgen.py b/src/SMESH_SWIG/SMESH_fixation_netgen.py index ae0039735..f3374b7bf 100644 --- a/src/SMESH_SWIG/SMESH_fixation_netgen.py +++ b/src/SMESH_SWIG/SMESH_fixation_netgen.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tetrahedrization of the geometry generated by the Python script # SMESH_fixation.py # The new Netgen algorithm is used that discretizes baoundaries itself @@ -44,6 +46,7 @@ status = geompy.CheckShape(compshell) print " check status ", status ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) print "-------------------------- create Mesh, algorithm, hypothesis" diff --git a/src/SMESH_SWIG/SMESH_fixation_tetra.py b/src/SMESH_SWIG/SMESH_fixation_tetra.py index bb190b30f..b94c354a3 100644 --- a/src/SMESH_SWIG/SMESH_fixation_tetra.py +++ b/src/SMESH_SWIG/SMESH_fixation_tetra.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tetrahedrization of the geometry generated by the Python script # SMESH_fixation.py # Hypothesis and algorithms for the mesh generation are global @@ -44,6 +46,7 @@ status = geompy.CheckShape(compshell) print " check status ", status ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the compshell diff --git a/src/SMESH_SWIG/SMESH_flight_skin.py b/src/SMESH_SWIG/SMESH_flight_skin.py index 6aa8d3716..2d5206194 100644 --- a/src/SMESH_SWIG/SMESH_flight_skin.py +++ b/src/SMESH_SWIG/SMESH_flight_skin.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Triangulation of the skin of the geometry from a Brep representing a plane # Hypothesis and algorithms for the mesh generation are global # @@ -54,6 +56,7 @@ print "number of Edges in flight : ", len(subEdgeList) ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the shell shape_mesh = salome.IDToObject( idShape ) diff --git a/src/SMESH_SWIG/SMESH_freebord.py b/src/SMESH_SWIG/SMESH_freebord.py index b1c1e8b9b..56b3fe13f 100644 --- a/src/SMESH_SWIG/SMESH_freebord.py +++ b/src/SMESH_SWIG/SMESH_freebord.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + import salome import geompy import smesh @@ -40,6 +42,7 @@ idbox = geompy.addToStudy( aBox, "box" ) aBox = salome.IDToObject( idbox ) # Create mesh +smesh.SetCurrentStudy(salome.myStudy) mesh = smesh.Mesh(aBox, "Mesh_freebord") diff --git a/src/SMESH_SWIG/SMESH_hexaedre.py b/src/SMESH_SWIG/SMESH_hexaedre.py index d32e9b0bd..4159ded64 100755 --- a/src/SMESH_SWIG/SMESH_hexaedre.py +++ b/src/SMESH_SWIG/SMESH_hexaedre.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + #============================================================================== # Info. # Bug (from script, bug) : hexaedre_modified.py, PAL6194, PAL7153 @@ -94,6 +96,7 @@ salome.sg.updateObjBrowser(1) # ----------------------------------------------------------------------------- print "-------------------------- mesh" +smesh.SetCurrentStudy(salome.myStudy) # ---- init a Mesh with the geom shape shape_mesh = blob diff --git a/src/SMESH_SWIG/SMESH_mechanic.py b/src/SMESH_SWIG/SMESH_mechanic.py index f1b02854d..5411c8dfd 100644 --- a/src/SMESH_SWIG/SMESH_mechanic.py +++ b/src/SMESH_SWIG/SMESH_mechanic.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_withHole.py # Author : Lucien PIGNOLONI # Module : SMESH @@ -94,31 +96,32 @@ Id_mechanic = geompy.addToStudy( mechanic, "mechanic" ) # ---- explode on faces SubFaceL = geompy.SubShapeAllSorted(mechanic, geompy.ShapeType["FACE"]) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face1 = SubFaceL[0] name = geompy.SubShapeName( sub_face1, mechanic ) Id_SubFace1 = geompy.addToStudyInFather( mechanic, sub_face1, name ) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face2 = SubFaceL[4] name = geompy.SubShapeName( sub_face2, mechanic ) Id_SubFace2 = geompy.addToStudyInFather( mechanic, sub_face2, name ) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face3 = SubFaceL[5] name = geompy.SubShapeName( sub_face3, mechanic ) Id_SubFace3 = geompy.addToStudyInFather( mechanic, sub_face3, name ) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face4 = SubFaceL[10] name = geompy.SubShapeName( sub_face4, mechanic ) Id_SubFace4 = geompy.addToStudyInFather( mechanic, sub_face4, name ) # ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # -- Init -- shape_mesh = salome.IDToObject( Id_mechanic ) diff --git a/src/SMESH_SWIG/SMESH_mechanic_editor.py b/src/SMESH_SWIG/SMESH_mechanic_editor.py index 80780ca63..f754354a9 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_editor.py +++ b/src/SMESH_SWIG/SMESH_mechanic_editor.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_withHole.py # Author : Lucien PIGNOLONI # Module : SMESH @@ -29,6 +31,7 @@ import salome import geompy import smesh +salome.salome_init() # ---------------------------- GEOM -------------------------------------- # ---- define contigous arcs and segment to define a closed wire @@ -92,31 +95,32 @@ Id_mechanic = geompy.addToStudy( mechanic, "mechanic" ) # ---- explode on faces SubFaceL = geompy.SubShapeAllSorted(mechanic, geompy.ShapeType["FACE"]) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face1 = SubFaceL[0] name = geompy.SubShapeName( sub_face1, mechanic ) Id_SubFace1 = geompy.addToStudyInFather( mechanic, sub_face1, name ) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face2 = SubFaceL[4] name = geompy.SubShapeName( sub_face2, mechanic ) Id_SubFace2 = geompy.addToStudyInFather( mechanic, sub_face2, name ) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face3 = SubFaceL[5] name = geompy.SubShapeName( sub_face3, mechanic ) Id_SubFace3 = geompy.addToStudyInFather( mechanic, sub_face3, name ) -# ---- add a face sub shape in study to be meshed different +# ---- add a face sub-shape in study to be meshed different sub_face4 = SubFaceL[10] name = geompy.SubShapeName( sub_face4, mechanic ) Id_SubFace4 = geompy.addToStudyInFather( mechanic, sub_face4, name ) # ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) # -- Init -- shape_mesh = salome.IDToObject( Id_mechanic ) @@ -189,9 +193,9 @@ print "Number of tetrahedrons: ", mesh.NbTetras() mesh.SplitQuadObject(submesh2, 1) #2 cutting of triangles of the group -FacesTriToQuad = [2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422] +FacesTriToQuad = [ 2391, 2824, 2825, 2826, 2827, 2828, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2841, 2844, 2845, 2847, 2854, 2861, 2863, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2940, 2941, 2946, 2951, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985 ] GroupTriToQuad = mesh.MakeGroupByIds("Group of faces (quad)", smesh.FACE, FacesTriToQuad) -mesh.TriToQuadObject(GroupTriToQuad, None , 1.57) +mesh.TriToQuadObject(GroupTriToQuad, smesh.FT_AspectRatio , 1.57) #3 extrusion of the group point = smesh.PointStruct(0, 0, 5) diff --git a/src/SMESH_SWIG/SMESH_mechanic_netgen.py b/src/SMESH_SWIG/SMESH_mechanic_netgen.py index e296eaed1..f5088378b 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_netgen.py +++ b/src/SMESH_SWIG/SMESH_mechanic_netgen.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Quadrangulation of the geometry generated by the Python script # SMESH_mechanic.py # The new Netgen algorithm is used that discretizes baoundaries itself @@ -103,6 +105,7 @@ print "number of Faces in mechanic : ",len(subFaceList) print "number of Edges in mechanic : ",len(subEdgeList) ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) print "-------------------------- create Mesh, algorithm, hypothesis" diff --git a/src/SMESH_SWIG/SMESH_mechanic_tetra.py b/src/SMESH_SWIG/SMESH_mechanic_tetra.py index ff2f421f7..135d5d152 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_tetra.py +++ b/src/SMESH_SWIG/SMESH_mechanic_tetra.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_withHole.py # Author : Lucien PIGNOLONI # Module : SMESH @@ -103,6 +105,7 @@ print "number of Faces in mechanic : ",len(subFaceList) print "number of Edges in mechanic : ",len(subEdgeList) ### ---------------------------- SMESH -------------------------------------- +smesh.SetCurrentStudy(salome.myStudy) shape_mesh = salome.IDToObject( Id_mechanic ) diff --git a/src/SMESH_SWIG/SMESH_reg.py b/src/SMESH_SWIG/SMESH_reg.py index 8a0ec7cfc..afd2a0a7c 100644 --- a/src/SMESH_SWIG/SMESH_reg.py +++ b/src/SMESH_SWIG/SMESH_reg.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_reg.py # Module : SMESH # @@ -57,7 +59,7 @@ salome.sg.updateObjBrowser(1); # ---- launch SMESH smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(salome.myStudyId) - +smesh.SetCurrentStudy(salome.myStudy) # ---- Creating meshes diff --git a/src/SMESH_SWIG/SMESH_shared_modules.py b/src/SMESH_SWIG/SMESH_shared_modules.py index 01286ea65..e0021db89 100644 --- a/src/SMESH_SWIG/SMESH_shared_modules.py +++ b/src/SMESH_SWIG/SMESH_shared_modules.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + """ """ diff --git a/src/SMESH_SWIG/SMESH_test.py b/src/SMESH_SWIG/SMESH_test.py index bc98e1c5c..7b2bbbcac 100644 --- a/src/SMESH_SWIG/SMESH_test.py +++ b/src/SMESH_SWIG/SMESH_test.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses # File : SMESH_test.py # Module : SMESH @@ -55,6 +57,7 @@ ide = geompy.addToStudyInFather(face, edge, name) # ---- SMESH +smesh.SetCurrentStudy(salome.myStudy) box = salome.IDToObject(idb) mesh = smesh.Mesh(box, "Meshbox") @@ -123,11 +126,17 @@ for a in log: elif comType == 2: for i in range(a.number): ind = a.indexes[ii] + print ind ii = ii+1 + print ii i1 = a.indexes[ii] ii = ii+1 i2 = a.indexes[ii] + print i2 ii = ii+1 + print "ii", ii i3 = a.indexes[ii] + print i3 + #ii = ii+1 ii = ii+1 print "AddTriangle %i - %i %i %i" % (ind, i1, i2, i3) diff --git a/src/SMESH_SWIG/SMESH_test0.py b/src/SMESH_SWIG/SMESH_test0.py index 421acc1ed..10fd4ab4b 100644 --- a/src/SMESH_SWIG/SMESH_test0.py +++ b/src/SMESH_SWIG/SMESH_test0.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_test0.py # Module : SMESH # diff --git a/src/SMESH_SWIG/SMESH_test1.py b/src/SMESH_SWIG/SMESH_test1.py index 25ce49704..a739dc9b9 100644 --- a/src/SMESH_SWIG/SMESH_test1.py +++ b/src/SMESH_SWIG/SMESH_test1.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_test1.py # Module : SMESH # @@ -26,7 +28,6 @@ import salome import geompy import smesh - # ---- define a box box = geompy.MakeBox(0., 0., 0., 100., 200., 300.) @@ -59,6 +60,8 @@ idedge = geompy.addToStudyInFather(face, edge, name) # ---- SMESH +smesh.SetCurrentStudy(salome.myStudy) + # ---- Init a Mesh with the box mesh = smesh.Mesh(box, "Meshbox") diff --git a/src/SMESH_SWIG/SMESH_test1_AndDisplay.py b/src/SMESH_SWIG/SMESH_test1_AndDisplay.py index e529d2c13..9c1578404 100644 --- a/src/SMESH_SWIG/SMESH_test1_AndDisplay.py +++ b/src/SMESH_SWIG/SMESH_test1_AndDisplay.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_test1.py # Module : SMESH # @@ -59,6 +61,8 @@ idedge = geompy.addToStudyInFather(face, edge, name) # ---- SMESH +smesh.SetCurrentStudy(salome.myStudy) + # ---- Init a Mesh with the box mesh = smesh.Mesh(box, "Meshbox") diff --git a/src/SMESH_SWIG/SMESH_test2.py b/src/SMESH_SWIG/SMESH_test2.py index fe38b2da4..89e4e8f11 100644 --- a/src/SMESH_SWIG/SMESH_test2.py +++ b/src/SMESH_SWIG/SMESH_test2.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_test2.py # Module : SMESH # diff --git a/src/SMESH_SWIG/SMESH_test3.py b/src/SMESH_SWIG/SMESH_test3.py index 59c853a46..04455050b 100644 --- a/src/SMESH_SWIG/SMESH_test3.py +++ b/src/SMESH_SWIG/SMESH_test3.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_test3.py # Module : SMESH #import salome diff --git a/src/SMESH_SWIG/SMESH_test4.py b/src/SMESH_SWIG/SMESH_test4.py index dd86094d5..230b1f3fb 100755 --- a/src/SMESH_SWIG/SMESH_test4.py +++ b/src/SMESH_SWIG/SMESH_test4.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + import salome import geompy import smesh @@ -39,6 +41,7 @@ face = salome.IDToObject(idface) # ---- SMESH +smesh.SetCurrentStudy(salome.myStudy) mesh = smesh.Mesh(box, "Meshbox") # Set 1D algorithm/hypotheses to mesh diff --git a/src/SMESH_SWIG/SMESH_test5.py b/src/SMESH_SWIG/SMESH_test5.py index 03a380ca6..749c9d9d9 100644 --- a/src/SMESH_SWIG/SMESH_test5.py +++ b/src/SMESH_SWIG/SMESH_test5.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : SMESH_test5.py # Module : SMESH # @@ -29,6 +31,8 @@ import CORBA import os import os.path +smesh.SetCurrentStudy(salome.myStudy) + def SetSObjName(theSObj,theName) : ok, anAttr = theSObj.FindAttribute("AttributeName") if ok: diff --git a/src/SMESH_SWIG/StdMeshersDC.py b/src/SMESH_SWIG/StdMeshersDC.py new file mode 100644 index 000000000..af20cb4e2 --- /dev/null +++ b/src/SMESH_SWIG/StdMeshersDC.py @@ -0,0 +1,1126 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from smesh import Mesh_Algorithm, AssureGeomPublished, IsEqual, ParseParameters +from smesh import GetName, TreatHypoStatus +from smeshDC import Mesh + +import StdMeshers + +# Types of algorithms +REGULAR = "Regular_1D" +PYTHON = "Python_1D" +COMPOSITE = "CompositeSegment_1D" +MEFISTO = "MEFISTO_2D" +Hexa = "Hexa_3D" +QUADRANGLE = "Quadrangle_2D" +RADIAL_QUAD = "RadialQuadrangle_1D2D" + + +# import items of enum QuadType +for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e)) + + +# Public class: Mesh_Segment +# -------------------------- + +## Class to define a REGULAR 1D algorithm for discretization. It is created by +# calling Mesh.Segment(geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_Segment(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Segment" + ## Name of algorithm type + algoType = REGULAR + isDefault = True + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + + ## Defines "LocalLength" hypothesis to cut an edge in several segments with the same length + # @param l for the length of segments that cut an edge + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @param p precision, used for calculation of the number of segments. + # The precision should be a positive, meaningful value within the range [0,1]. + # In general, the number of segments is calculated with the formula: + # nb = ceil((edge_length / l) - p) + # Function ceil rounds its argument to the higher integer. + # So, p=0 means rounding of (edge_length / l) to the higher integer, + # p=0.5 means rounding of (edge_length / l) to the nearest integer, + # p=1 means rounding of (edge_length / l) to the lower integer. + # Default value is 1e-07. + # @return an instance of StdMeshers_LocalLength hypothesis + # @ingroup l3_hypos_1dhyps + def LocalLength(self, l, UseExisting=0, p=1e-07): + comFun=lambda hyp, args: IsEqual(hyp.GetLength(), args[0]) and IsEqual(hyp.GetPrecision(), args[1]) + hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting, CompareMethod=comFun) + hyp.SetLength(l) + hyp.SetPrecision(p) + return hyp + + ## Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value + # @param length is optional maximal allowed length of segment, if it is omitted + # the preestimated length is used that depends on geometry size + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @return an instance of StdMeshers_MaxLength hypothesis + # @ingroup l3_hypos_1dhyps + def MaxSize(self, length=0.0, UseExisting=0): + hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting) + if length > 0.0: + # set given length + hyp.SetLength(length) + if not UseExisting: + # set preestimated length + gen = self.mesh.smeshpyD + initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so", + self.mesh.GetMesh(), self.mesh.GetShape(), + False) # <- byMesh + preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength) + if preHyp: + hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() ) + pass + pass + hyp.SetUsePreestimatedLength( length == 0.0 ) + return hyp + + ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments + # @param n for the number of segments that cut an edge + # @param s for the scale factor (optional) + # @param reversedEdges is a list of edges to mesh using reversed orientation. + # A list item can also be a tuple (edge, 1st_vertex_of_edge) + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - create a new one + # @return an instance of StdMeshers_NumberOfSegments hypothesis + # @ingroup l3_hypos_1dhyps + def NumberOfSegments(self, n, s=[], reversedEdges=[], UseExisting=0): + if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges + reversedEdges, UseExisting = [], reversedEdges + entry = self.MainShapeEntry() + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) + if s == []: + hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdgeInd, entry], + UseExisting=UseExisting, + CompareMethod=self._compareNumberOfSegments) + else: + hyp = self.Hypothesis("NumberOfSegments", [n,s, reversedEdgeInd, entry], + UseExisting=UseExisting, + CompareMethod=self._compareNumberOfSegments) + hyp.SetDistrType( 1 ) + hyp.SetScaleFactor(s) + hyp.SetNumberOfSegments(n) + hyp.SetReversedEdges( reversedEdgeInd ) + hyp.SetObjectEntry( entry ) + return hyp + + ## Private method + ## Checks if the given "NumberOfSegments" hypothesis has the same parameters as the given arguments + def _compareNumberOfSegments(self, hyp, args): + if hyp.GetNumberOfSegments() == args[0]: + if len(args) == 3: + if hyp.GetReversedEdges() == args[1]: + if not args[1] or hyp.GetObjectEntry() == args[2]: + return True + else: + if hyp.GetReversedEdges() == args[2]: + if not args[2] or hyp.GetObjectEntry() == args[3]: + if hyp.GetDistrType() == 1: + if IsEqual(hyp.GetScaleFactor(), args[1]): + return True + return False + + ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length + # @param start defines the length of the first segment + # @param end defines the length of the last segment + # @param reversedEdges is a list of edges to mesh using reversed orientation. + # A list item can also be a tuple (edge, 1st_vertex_of_edge) + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @return an instance of StdMeshers_Arithmetic1D hypothesis + # @ingroup l3_hypos_1dhyps + def Arithmetic1D(self, start, end, reversedEdges=[], UseExisting=0): + if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges + reversedEdges, UseExisting = [], reversedEdges + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) + entry = self.MainShapeEntry() + compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \ + IsEqual(hyp.GetLength(0), args[1]) and \ + hyp.GetReversedEdges() == args[2] and \ + (not args[2] or hyp.GetObjectEntry() == args[3])) + hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdgeInd, entry], + UseExisting=UseExisting, CompareMethod=compFun) + hyp.SetStartLength(start) + hyp.SetEndLength(end) + hyp.SetReversedEdges( reversedEdgeInd ) + hyp.SetObjectEntry( entry ) + return hyp + + ## Defines "FixedPoints1D" hypothesis to cut an edge using parameter + # on curve from 0 to 1 (additionally it is neecessary to check + # orientation of edges and create list of reversed edges if it is + # needed) and sets numbers of segments between given points (default + # values are equals 1 + # @param points defines the list of parameters on curve + # @param nbSegs defines the list of numbers of segments + # @param reversedEdges is a list of edges to mesh using reversed orientation. + # A list item can also be a tuple (edge, 1st_vertex_of_edge) + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @return an instance of StdMeshers_Arithmetic1D hypothesis + # @ingroup l3_hypos_1dhyps + def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0): + if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges + reversedEdges, UseExisting = [], reversedEdges + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) + entry = self.MainShapeEntry() + compFun = lambda hyp, args: ( hyp.GetPoints() == args[0] and \ + hyp.GetNbSegments() == args[1] and \ + hyp.GetReversedEdges() == args[2] and \ + (not args[2] or hyp.GetObjectEntry() == args[3])) + hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdgeInd, entry], + UseExisting=UseExisting, CompareMethod=compFun) + hyp.SetPoints(points) + hyp.SetNbSegments(nbSegs) + hyp.SetReversedEdges(reversedEdgeInd) + hyp.SetObjectEntry(entry) + return hyp + + ## Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length + # @param start defines the length of the first segment + # @param end defines the length of the last segment + # @param reversedEdges is a list of edges to mesh using reversed orientation. + # A list item can also be a tuple (edge, 1st_vertex_of_edge) + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @return an instance of StdMeshers_StartEndLength hypothesis + # @ingroup l3_hypos_1dhyps + def StartEndLength(self, start, end, reversedEdges=[], UseExisting=0): + if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges + reversedEdges, UseExisting = [], reversedEdges + reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges) + entry = self.MainShapeEntry() + compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \ + IsEqual(hyp.GetLength(0), args[1]) and \ + hyp.GetReversedEdges() == args[2] and \ + (not args[2] or hyp.GetObjectEntry() == args[3])) + hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdgeInd, entry], + UseExisting=UseExisting, CompareMethod=compFun) + hyp.SetStartLength(start) + hyp.SetEndLength(end) + hyp.SetReversedEdges( reversedEdgeInd ) + hyp.SetObjectEntry( entry ) + return hyp + + ## Defines "Deflection1D" hypothesis + # @param d for the deflection + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - create a new one + # @ingroup l3_hypos_1dhyps + def Deflection1D(self, d, UseExisting=0): + compFun = lambda hyp, args: IsEqual(hyp.GetDeflection(), args[0]) + hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting, CompareMethod=compFun) + hyp.SetDeflection(d) + return hyp + + ## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at + # the opposite side in case of quadrangular faces + # @ingroup l3_hypos_additi + def Propagation(self): + return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp) + + ## Defines "AutomaticLength" hypothesis + # @param fineness for the fineness [0-1] + # @param UseExisting if ==true - searches for an existing hypothesis created with the + # same parameters, else (default) - create a new one + # @ingroup l3_hypos_1dhyps + def AutomaticLength(self, fineness=0, UseExisting=0): + compFun = lambda hyp, args: IsEqual(hyp.GetFineness(), args[0]) + hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting, + CompareMethod=compFun) + hyp.SetFineness( fineness ) + return hyp + + ## Defines "SegmentLengthAroundVertex" hypothesis + # @param length for the segment length + # @param vertex for the length localization: the vertex index [0,1] | vertex object. + # Any other integer value means that the hypothesis will be set on the + # whole 1D shape, where Mesh_Segment algorithm is assigned. + # @param UseExisting if ==true - searches for an existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_algos_segmarv + def LengthNearVertex(self, length, vertex=0, UseExisting=0): + import types + store_geom = self.geom + if type(vertex) is types.IntType: + if vertex == 0 or vertex == 1: + import geompyDC + vertex = self.mesh.geompyD.ExtractShapes(self.geom, geompyDC.ShapeType["VERTEX"],True)[vertex] + self.geom = vertex + pass + pass + else: + self.geom = vertex + pass + ### 0D algorithm + if self.geom is None: + raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape" + AssureGeomPublished( self.mesh, self.geom ) + name = GetName(self.geom) + + algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD) + if algo is None: + algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so") + pass + status = self.mesh.mesh.AddHypothesis(self.geom, algo) + TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True) + ### + comFun = lambda hyp, args: IsEqual(hyp.GetLength(), args[0]) + hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting, + CompareMethod=comFun) + self.geom = store_geom + hyp.SetLength( length ) + return hyp + + ## Defines "QuadraticMesh" hypothesis, forcing construction of quadratic edges. + # If the 2D mesher sees that all boundary edges are quadratic, + # it generates quadratic faces, else it generates linear faces using + # medium nodes as if they are vertices. + # The 3D mesher generates quadratic volumes only if all boundary faces + # are quadratic, else it fails. + # + # @ingroup l3_hypos_additi + def QuadraticMesh(self): + hyp = self.Hypothesis("QuadraticMesh", UseExisting=1, CompareMethod=self.CompareEqualHyp) + return hyp + +# Public class: Mesh_CompositeSegment +# -------------------------- + +## A regular 1D algorithm for discretization of a set of adjacent edges as one. +# It is created by calling Mesh.Segment(COMPOSITE,geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_CompositeSegment(StdMeshersDC_Segment): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Segment" + ## Name of algorithm type + algoType = COMPOSITE + isDefault = False + + ## Private constructor. + def __init__(self, mesh, geom=0): + self.Create(mesh, geom, self.algoType) + + +# Public class: Mesh_Segment_Python +# --------------------------------- + +## Defines a segment 1D algorithm for discretization with python function +# It is created by calling Mesh.Segment(PYTHON,geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_Segment_Python(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Segment" + ## Name of algorithm type + algoType = PYTHON + + ## Private constructor. + def __init__(self, mesh, geom=0): + import Python1dPlugin + self.Create(mesh, geom, self.algoType, "libPython1dEngine.so") + + ## Defines "PythonSplit1D" hypothesis + # @param n for the number of segments that cut an edge + # @param func for the python function that calculates the length of all segments + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_1dhyps + def PythonSplit1D(self, n, func, UseExisting=0): + compFun = lambda hyp, args: False + hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so", + UseExisting=UseExisting, CompareMethod=compFun) + hyp.SetNumberOfSegments(n) + hyp.SetPythonLog10RatioFunction(func) + return hyp + +# Public class: Mesh_Triangle_MEFISTO +# ----------------------------------- + +## Triangle MEFISTO 2D algorithm +# It is created by calling Mesh.Triangle(MEFISTO,geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_Triangle_MEFISTO(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Triangle" + ## Name of algorithm type + algoType = MEFISTO + isDefault = True + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + + ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle + # @param area for the maximum area of each triangle + # @param UseExisting if ==true - searches for an existing hypothesis created with the + # same parameters, else (default) - creates a new one + # + # @ingroup l3_hypos_2dhyps + def MaxElementArea(self, area, UseExisting=0): + comparator = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0]) + hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting, + CompareMethod=comparator) + hyp.SetMaxElementArea(area) + return hyp + + ## Defines "LengthFromEdges" hypothesis to build triangles + # based on the length of the edges taken from the wire + # + # @ingroup l3_hypos_2dhyps + def LengthFromEdges(self): + hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp) + return hyp + +# Public class: Mesh_Quadrangle +# ----------------------------- + +## Defines a quadrangle 2D algorithm +# It is created by calling Mesh.Quadrangle(geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_Quadrangle(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Quadrangle" + ## Name of algorithm type + algoType = QUADRANGLE + isDefault = True + + params=0 + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + return + + ## Defines "QuadrangleParameters" hypothesis + # @param quadType defines the algorithm of transition between differently descretized + # sides of a geometrical face: + # - QUAD_STANDARD - both triangles and quadrangles are possible in the transition + # area along the finer meshed sides. + # - QUAD_TRIANGLE_PREF - only triangles are built in the transition area along the + # finer meshed sides. + # - QUAD_QUADRANGLE_PREF - only quadrangles are built in the transition area along + # the finer meshed sides, iff the total quantity of segments on + # all four sides of the face is even (divisible by 2). + # - QUAD_QUADRANGLE_PREF_REVERSED - same as QUAD_QUADRANGLE_PREF but the transition + # area is located along the coarser meshed sides. + # - QUAD_REDUCED - only quadrangles are built and the transition between the sides + # is made gradually, layer by layer. This type has a limitation on + # the number of segments: one pair of opposite sides must have the + # same number of segments, the other pair must have an even difference + # between the numbers of segments on the sides. + # @param triangleVertex: vertex of a trilateral geometrical face, around which triangles + # will be created while other elements will be quadrangles. + # Vertex can be either a GEOM_Object or a vertex ID within the + # shape to mesh + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0, UseExisting=0): + import GEOM + vertexID = triangleVertex + if isinstance( triangleVertex, GEOM._objref_GEOM_Object ): + vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex ) + if not self.params: + compFun = lambda hyp,args: \ + hyp.GetQuadType() == args[0] and \ + ( hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1)) + self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID], + UseExisting = UseExisting, CompareMethod=compFun) + pass + if self.params.GetQuadType() != quadType: + self.params.SetQuadType(quadType) + if vertexID > 0: + self.params.SetTriaVertex( vertexID ) + return self.params + + ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only + # quadrangles are built in the transition area along the finer meshed sides, + # iff the total quantity of segments on all four sides of the face is even. + # @param reversed if True, transition area is located along the coarser meshed sides. + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def QuadranglePreference(self, reversed=False, UseExisting=0): + if reversed: + return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF_REVERSED,UseExisting=UseExisting) + return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF,UseExisting=UseExisting) + + ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only + # triangles are built in the transition area along the finer meshed sides. + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def TrianglePreference(self, UseExisting=0): + return self.QuadrangleParameters(QUAD_TRIANGLE_PREF,UseExisting=UseExisting) + + ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only + # quadrangles are built and the transition between the sides is made gradually, + # layer by layer. This type has a limitation on the number of segments: one pair + # of opposite sides must have the same number of segments, the other pair must + # have an even difference between the numbers of segments on the sides. + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def Reduced(self, UseExisting=0): + return self.QuadrangleParameters(QUAD_REDUCED,UseExisting=UseExisting) + + ## Defines "QuadrangleParams" hypothesis with QUAD_STANDARD type of quadrangulation + # @param vertex: vertex of a trilateral geometrical face, around which triangles + # will be created while other elements will be quadrangles. + # Vertex can be either a GEOM_Object or a vertex ID within the + # shape to mesh + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def TriangleVertex(self, vertex, UseExisting=0): + return self.QuadrangleParameters(QUAD_STANDARD,vertex,UseExisting) + + +# Public class: Mesh_Hexahedron +# ------------------------------ + +## Defines a hexahedron 3D algorithm +# It is created by calling Mesh.Hexahedron(geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_Hexahedron(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Hexahedron" + ## Name of algorithm type + algoType = Hexa + isDefault = True + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, Hexa) + pass + +# Public class: Mesh_Projection1D +# ------------------------------- + +## Defines a projection 1D algorithm +# It is created by calling Mesh.Projection1D(geom=0) +# @ingroup l3_algos_proj +# +class StdMeshersDC_Projection1D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Projection1D" + ## Name of algorithm type + algoType = "Projection_1D" + isDefault = True + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + + ## Defines "Source Edge" hypothesis, specifying a meshed edge, from where + # a mesh pattern is taken, and, optionally, the association of vertices + # between the source edge and a target edge (to which a hypothesis is assigned) + # @param edge from which nodes distribution is taken + # @param mesh from which nodes distribution is taken (optional) + # @param srcV a vertex of \a edge to associate with \a tgtV (optional) + # @param tgtV a vertex of \a the edge to which the algorithm is assigned, + # to associate with \a srcV (optional) + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0): + AssureGeomPublished( self.mesh, edge ) + AssureGeomPublished( self.mesh, srcV ) + AssureGeomPublished( self.mesh, tgtV ) + hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV], + UseExisting=0) + # it does not seem to be useful to reuse the existing "SourceEdge" hypothesis + #UseExisting=UseExisting, CompareMethod=self.CompareSourceEdge) + hyp.SetSourceEdge( edge ) + if not mesh is None and isinstance(mesh, Mesh): + mesh = mesh.GetMesh() + hyp.SetSourceMesh( mesh ) + hyp.SetVertexAssociation( srcV, tgtV ) + return hyp + + +# Public class: Mesh_Projection2D +# ------------------------------ + +## Defines a projection 2D algorithm +# It is created by calling Mesh.Projection2D(geom=0) +# @ingroup l3_algos_proj +# +class StdMeshersDC_Projection2D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Projection2D" + ## Name of algorithm type + algoType = "Projection_2D" + isDefault = True + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + + ## Defines "Source Face" hypothesis, specifying a meshed face, from where + # a mesh pattern is taken, and, optionally, the association of vertices + # between the source face and the target face (to which a hypothesis is assigned) + # @param face from which the mesh pattern is taken + # @param mesh from which the mesh pattern is taken (optional) + # @param srcV1 a vertex of \a face to associate with \a tgtV1 (optional) + # @param tgtV1 a vertex of \a the face to which the algorithm is assigned, + # to associate with \a srcV1 (optional) + # @param srcV2 a vertex of \a face to associate with \a tgtV1 (optional) + # @param tgtV2 a vertex of \a the face to which the algorithm is assigned, + # to associate with \a srcV2 (optional) + # @param UseExisting if ==true - forces the search for the existing hypothesis created with + # the same parameters, else (default) - forces the creation a new one + # + # Note: all association vertices must belong to one edge of a face + def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None, + srcV2=None, tgtV2=None, UseExisting=0): + from smeshDC import Mesh + if isinstance(mesh, Mesh): + mesh = mesh.GetMesh() + for geom in [ face, srcV1, tgtV1, srcV2, tgtV2 ]: + AssureGeomPublished( self.mesh, geom ) + hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2], + UseExisting=0) + # it does not seem to be useful to reuse the existing "SourceFace" hypothesis + #UseExisting=UseExisting, CompareMethod=self.CompareSourceFace) + hyp.SetSourceFace( face ) + hyp.SetSourceMesh( mesh ) + hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 ) + return hyp + +# Public class: Mesh_Projection1D2D +# --------------------------------- + +## Defines a projection 1D-2D algorithm +# It is created by calling Mesh.Projection1D2D(geom=0) +# +# @ingroup l3_algos_proj + +class StdMeshersDC_Projection1D2D(StdMeshersDC_Projection2D): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Projection1D2D" + ## Name of algorithm type + algoType = "Projection_1D2D" + + ## Private constructor. + def __init__(self, mesh, geom=0): + StdMeshersDC_Projection2D.__init__(self, mesh, geom) + +# Public class: Mesh_Projection3D +# ------------------------------ + +## Defines a projection 3D algorithm +# It is created by calling Mesh.Projection3D(COMPOSITE) +# +# @ingroup l3_algos_proj +# +class StdMeshersDC_Projection3D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Projection3D" + ## Name of algorithm type + algoType = "Projection_3D" + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + + ## Defines the "Source Shape 3D" hypothesis, specifying a meshed solid, from where + # the mesh pattern is taken, and, optionally, the association of vertices + # between the source and the target solid (to which a hipothesis is assigned) + # @param solid from where the mesh pattern is taken + # @param mesh from where the mesh pattern is taken (optional) + # @param srcV1 a vertex of \a solid to associate with \a tgtV1 (optional) + # @param tgtV1 a vertex of \a the solid where the algorithm is assigned, + # to associate with \a srcV1 (optional) + # @param srcV2 a vertex of \a solid to associate with \a tgtV1 (optional) + # @param tgtV2 a vertex of \a the solid to which the algorithm is assigned, + # to associate with \a srcV2 (optional) + # @param UseExisting - if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # + # Note: association vertices must belong to one edge of a solid + def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0, + srcV2=0, tgtV2=0, UseExisting=0): + for geom in [ solid, srcV1, tgtV1, srcV2, tgtV2 ]: + AssureGeomPublished( self.mesh, geom ) + hyp = self.Hypothesis("ProjectionSource3D", + [solid,mesh,srcV1,tgtV1,srcV2,tgtV2], + UseExisting=0) + # seems to be not really useful to reuse existing "SourceShape3D" hypothesis + #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D) + hyp.SetSource3DShape( solid ) + if isinstance(mesh, Mesh): + mesh = mesh.GetMesh() + if mesh: + hyp.SetSourceMesh( mesh ) + if srcV1 and srcV2 and tgtV1 and tgtV2: + hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 ) + #elif srcV1 or srcV2 or tgtV1 or tgtV2: + return hyp + +# Public class: Mesh_Prism +# ------------------------ + +## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism" +# depending on geometry +# It is created by calling Mesh.Prism(geom=0) +# +# @ingroup l3_algos_3dextr +# +class StdMeshersDC_Prism3D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Prism" + ## Name of algorithm type + algoType = "Prism_3D" + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + + shape = geom + if not shape: + shape = mesh.geom + from geompy import SubShapeAll, ShapeType + nbSolids = len( SubShapeAll( shape, ShapeType["SOLID"] )) + nbShells = len( SubShapeAll( shape, ShapeType["SHELL"] )) + if nbSolids == 0 or nbSolids == nbShells: + self.Create(mesh, geom, "Prism_3D") + else: + self.algoType = "RadialPrism_3D" + self.Create(mesh, geom, "RadialPrism_3D") + self.distribHyp = self.Hypothesis("LayerDistribution", UseExisting=0) + self.nbLayers = None + + ## Return 3D hypothesis holding the 1D one + def Get3DHypothesis(self): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + return self.distribHyp + + ## Private method creating a 1D hypothesis and storing it in the LayerDistribution + # hypothesis. Returns the created hypothesis + def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + if not self.nbLayers is None: + self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers ) + self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp ) + study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis + self.mesh.smeshpyD.SetCurrentStudy( None ) + hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so) + self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing + self.distribHyp.SetLayerDistribution( hyp ) + return hyp + + ## Defines "NumberOfLayers" hypothesis, specifying the number of layers of + # prisms to build between the inner and outer shells + # @param n number of layers + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def NumberOfLayers(self, n, UseExisting=0): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + self.mesh.RemoveHypothesis( self.distribHyp, self.geom ) + compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0]) + self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting, + CompareMethod=compFun) + self.nbLayers.SetNumberOfLayers( n ) + return self.nbLayers + + ## Defines "LocalLength" hypothesis, specifying the segment length + # to build between the inner and the outer shells + # @param l the length of segments + # @param p the precision of rounding + def LocalLength(self, l, p=1e-07): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + hyp = self.OwnHypothesis("LocalLength", [l,p]) + hyp.SetLength(l) + hyp.SetPrecision(p) + return hyp + + ## Defines "NumberOfSegments" hypothesis, specifying the number of layers of + # prisms to build between the inner and the outer shells. + # @param n the number of layers + # @param s the scale factor (optional) + def NumberOfSegments(self, n, s=[]): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + if s == []: + hyp = self.OwnHypothesis("NumberOfSegments", [n]) + else: + hyp = self.OwnHypothesis("NumberOfSegments", [n,s]) + hyp.SetDistrType( 1 ) + hyp.SetScaleFactor(s) + hyp.SetNumberOfSegments(n) + return hyp + + ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments + # to build between the inner and the outer shells with a length that changes in arithmetic progression + # @param start the length of the first segment + # @param end the length of the last segment + def Arithmetic1D(self, start, end ): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + hyp = self.OwnHypothesis("Arithmetic1D", [start, end]) + hyp.SetLength(start, 1) + hyp.SetLength(end , 0) + return hyp + + ## Defines "StartEndLength" hypothesis, specifying distribution of segments + # to build between the inner and the outer shells as geometric length increasing + # @param start for the length of the first segment + # @param end for the length of the last segment + def StartEndLength(self, start, end): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + hyp = self.OwnHypothesis("StartEndLength", [start, end]) + hyp.SetLength(start, 1) + hyp.SetLength(end , 0) + return hyp + + ## Defines "AutomaticLength" hypothesis, specifying the number of segments + # to build between the inner and outer shells + # @param fineness defines the quality of the mesh within the range [0-1] + def AutomaticLength(self, fineness=0): + if self.algoType != "RadialPrism_3D": + print "Prism_3D algorith doesn't support any hyposesis" + return None + hyp = self.OwnHypothesis("AutomaticLength") + hyp.SetFineness( fineness ) + return hyp + + +# Public class: Mesh_RadialQuadrangle1D2D +# ------------------------------- + +## Defines a Radial Quadrangle 1D2D algorithm +# It is created by calling Mesh.Quadrangle(RADIAL_QUAD,geom=0) +# +# @ingroup l2_algos_radialq +class StdMeshersDC_RadialQuadrangle1D2D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "Quadrangle" + ## Name of algorithm type + algoType = RADIAL_QUAD + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + + self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0) + self.nbLayers = None + + ## Return 2D hypothesis holding the 1D one + def Get2DHypothesis(self): + if not self.distribHyp: + self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0) + return self.distribHyp + + ## Private method creating a 1D hypothesis and storing it in the LayerDistribution + # hypothesis. Returns the created hypothesis + def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"): + if self.nbLayers: + self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers ) + if self.distribHyp is None: + self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0) + else: + self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp ) + study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis + self.mesh.smeshpyD.SetCurrentStudy( None ) + hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so) + self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing + self.distribHyp.SetLayerDistribution( hyp ) + return hyp + + ## Defines "NumberOfLayers" hypothesis, specifying the number of layers + # @param n number of layers + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def NumberOfLayers(self, n, UseExisting=0): + if self.distribHyp: + self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp ) + compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0]) + self.nbLayers = self.Hypothesis("NumberOfLayers2D", [n], UseExisting=UseExisting, + CompareMethod=compFun) + self.nbLayers.SetNumberOfLayers( n ) + return self.nbLayers + + ## Defines "LocalLength" hypothesis, specifying the segment length + # @param l the length of segments + # @param p the precision of rounding + def LocalLength(self, l, p=1e-07): + hyp = self.OwnHypothesis("LocalLength", [l,p]) + hyp.SetLength(l) + hyp.SetPrecision(p) + return hyp + + ## Defines "NumberOfSegments" hypothesis, specifying the number of layers + # @param n the number of layers + # @param s the scale factor (optional) + def NumberOfSegments(self, n, s=[]): + if s == []: + hyp = self.OwnHypothesis("NumberOfSegments", [n]) + else: + hyp = self.OwnHypothesis("NumberOfSegments", [n,s]) + hyp.SetDistrType( 1 ) + hyp.SetScaleFactor(s) + hyp.SetNumberOfSegments(n) + return hyp + + ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments + # with a length that changes in arithmetic progression + # @param start the length of the first segment + # @param end the length of the last segment + def Arithmetic1D(self, start, end ): + hyp = self.OwnHypothesis("Arithmetic1D", [start, end]) + hyp.SetLength(start, 1) + hyp.SetLength(end , 0) + return hyp + + ## Defines "StartEndLength" hypothesis, specifying distribution of segments + # as geometric length increasing + # @param start for the length of the first segment + # @param end for the length of the last segment + def StartEndLength(self, start, end): + hyp = self.OwnHypothesis("StartEndLength", [start, end]) + hyp.SetLength(start, 1) + hyp.SetLength(end , 0) + return hyp + + ## Defines "AutomaticLength" hypothesis, specifying the number of segments + # @param fineness defines the quality of the mesh within the range [0-1] + def AutomaticLength(self, fineness=0): + hyp = self.OwnHypothesis("AutomaticLength") + hyp.SetFineness( fineness ) + return hyp + + +# Public class: Mesh_UseExistingElements +# -------------------------------------- +## Defines a Radial Quadrangle 1D2D algorithm +# It is created by calling Mesh.UseExisting1DElements(geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_UseExistingElements_1D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "UseExisting1DElements" + ## Name of algorithm type + algoType = "Import_1D" + isDefault = True + + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + return + + ## Defines "Source edges" hypothesis, specifying groups of edges to import + # @param groups list of groups of edges + # @param toCopyMesh if True, the whole mesh \a groups belong to is imported + # @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False): + for group in groups: + AssureGeomPublished( self.mesh, group ) + compFun = lambda hyp, args: ( hyp.GetSourceEdges() == args[0] and \ + hyp.GetCopySourceMesh() == args[1], args[2] ) + hyp = self.Hypothesis("ImportSource1D", [groups, toCopyMesh, toCopyGroups], + UseExisting=UseExisting, CompareMethod=compFun) + hyp.SetSourceEdges(groups) + hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups) + return hyp + +# Public class: Mesh_UseExistingElements +# -------------------------------------- +## Defines a Radial Quadrangle 1D2D algorithm +# It is created by calling Mesh.UseExisting2DElements(geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_UseExistingElements_1D2D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "UseExisting2DElements" + ## Name of algorithm type + algoType = "Import_1D2D" + isDefault = True + + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + self.Create(mesh, geom, self.algoType) + return + + ## Defines "Source faces" hypothesis, specifying groups of faces to import + # @param groups list of groups of faces + # @param toCopyMesh if True, the whole mesh \a groups belong to is imported + # @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False): + for group in groups: + AssureGeomPublished( self.mesh, group ) + compFun = lambda hyp, args: ( hyp.GetSourceFaces() == args[0] and \ + hyp.GetCopySourceMesh() == args[1], args[2] ) + hyp = self.Hypothesis("ImportSource2D", [groups, toCopyMesh, toCopyGroups], + UseExisting=UseExisting, CompareMethod=compFun) + hyp.SetSourceFaces(groups) + hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups) + return hyp + + +# Public class: Mesh_Cartesian_3D +# -------------------------------------- +## Defines a Body Fitting 3D algorithm +# It is created by calling Mesh.BodyFitted(geom=0) +# +# @ingroup l3_algos_basic +class StdMeshersDC_Cartesian_3D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "BodyFitted" + ## Name of algorithm type + algoType = "Cartesian_3D" + isDefault = True + + def __init__(self, mesh, geom=0): + self.Create(mesh, geom, self.algoType) + self.hyp = None + return + + ## Defines "Body Fitting parameters" hypothesis + # @param xGridDef is definition of the grid along the X asix. + # It can be in either of two following forms: + # - Explicit coordinates of nodes, e.g. [-1.5, 0.0, 3.1] or range( -100,200,10) + # - Functions f(t) defining grid spacing at each point on grid axis. If there are + # several functions, they must be accompanied by relative coordinates of + # points dividing the whole shape into ranges where the functions apply; points + # coodrinates should vary within (0.0, 1.0) range. Parameter \a t of the spacing + # function f(t) varies from 0.0 to 1.0 witin a shape range. + # Examples: + # - "10.5" - defines a grid with a constant spacing + # - [["1", "1+10*t", "11"] [0.1, 0.6]] - defines different spacing in 3 ranges. + # @param yGridDef defines the grid along the Y asix the same way as \a xGridDef does + # @param zGridDef defines the grid along the Z asix the same way as \a xGridDef does + # @param sizeThreshold (> 1.0) defines a minimal size of a polyhedron so that + # a polyhedron of size less than hexSize/sizeThreshold is not created + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def SetGrid(self, xGridDef, yGridDef, zGridDef, sizeThreshold=4.0, UseExisting=False): + if not self.hyp: + compFun = lambda hyp, args: False + self.hyp = self.Hypothesis("CartesianParameters3D", + [xGridDef, yGridDef, zGridDef, sizeThreshold], + UseExisting=UseExisting, CompareMethod=compFun) + if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ): + self.mesh.AddHypothesis( self.hyp, self.geom ) + + for axis, gridDef in enumerate( [xGridDef, yGridDef, zGridDef]): + if not gridDef: raise ValueError, "Empty grid definition" + if isinstance( gridDef, str ): + self.hyp.SetGridSpacing( [gridDef], [], axis ) + elif isinstance( gridDef[0], str ): + self.hyp.SetGridSpacing( gridDef, [], axis ) + elif isinstance( gridDef[0], int ) or \ + isinstance( gridDef[0], float ): + self.hyp.SetGrid(gridDef, axis ) + else: + self.hyp.SetGridSpacing( gridDef[0], gridDef[1], axis ) + self.hyp.SetSizeThreshold( sizeThreshold ) + return self.hyp + +# Public class: Mesh_UseExisting_1D +# --------------------------------- +## Defines a stub 1D algorithm, which enables "manual" creation of nodes and +# segments usable by 2D algoritms +# It is created by calling Mesh.UseExistingSegments(geom=0) +# +# @ingroup l3_algos_basic + +class StdMeshersDC_UseExisting_1D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "UseExistingSegments" + ## Name of algorithm type + algoType = "UseExisting_1D" + + def __init__(self, mesh, geom=0): + self.Create(mesh, geom, self.algoType) + + +# Public class: Mesh_UseExisting +# ------------------------------- +## Defines a stub 2D algorithm, which enables "manual" creation of nodes and +# faces usable by 3D algoritms +# It is created by calling Mesh.UseExistingFaces(geom=0) +# +# @ingroup l3_algos_basic + +class StdMeshersDC_UseExisting_2D(Mesh_Algorithm): + + ## Name of method of class Mesh creating an instance of this class + meshMethod = "UseExistingFaces" + ## Name of algorithm type + algoType = "UseExisting_2D" + + def __init__(self, mesh, geom=0): + self.Create(mesh, geom, self.algoType) diff --git a/src/SMESH_SWIG/batchmode_mefisto.py b/src/SMESH_SWIG/batchmode_mefisto.py index 775023370..fb888795a 100644 --- a/src/SMESH_SWIG/batchmode_mefisto.py +++ b/src/SMESH_SWIG/batchmode_mefisto.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + import os import re diff --git a/src/SMESH_SWIG/batchmode_smesh.py b/src/SMESH_SWIG/batchmode_smesh.py index d6688362d..6daa0e946 100644 --- a/src/SMESH_SWIG/batchmode_smesh.py +++ b/src/SMESH_SWIG/batchmode_smesh.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : batchmode_smesh.py # Author : Oksana TCHEBANOVA # Module : SMESH @@ -32,6 +34,7 @@ import SMESH modulecatalog = naming_service.Resolve("/Kernel/ModulCatalog") smesh = lcc.FindOrLoadComponent("FactoryServer", "SMESH") +smesh.SetCurrentStudy(myStudy) myStudyBuilder = myStudy.NewBuilder() if myStudyBuilder is None: diff --git a/src/SMESH_SWIG/ex00_all.py b/src/SMESH_SWIG/ex00_all.py index e4159ebdb..381b9ae3c 100644 --- a/src/SMESH_SWIG/ex00_all.py +++ b/src/SMESH_SWIG/ex00_all.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ================================== # Load all examples # ----------------- diff --git a/src/SMESH_SWIG/ex01_cube2build.py b/src/SMESH_SWIG/ex01_cube2build.py index fbc8c5f23..10ba3f33a 100644 --- a/src/SMESH_SWIG/ex01_cube2build.py +++ b/src/SMESH_SWIG/ex01_cube2build.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -286,6 +288,8 @@ piece_id = addToStudy(piece, "ex01_cube2build") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create hexahedrical mesh on piece # --------------------------------- diff --git a/src/SMESH_SWIG/ex02_cube2primitive.py b/src/SMESH_SWIG/ex02_cube2primitive.py index 732b579b7..9350199eb 100644 --- a/src/SMESH_SWIG/ex02_cube2primitive.py +++ b/src/SMESH_SWIG/ex02_cube2primitive.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -97,6 +99,8 @@ piece_id = addToStudy(piece, "ex02_cube2primitive") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create hexahedrical mesh on piece # --------------------------------- diff --git a/src/SMESH_SWIG/ex03_cube2partition.py b/src/SMESH_SWIG/ex03_cube2partition.py index e3447c37d..1849895fe 100644 --- a/src/SMESH_SWIG/ex03_cube2partition.py +++ b/src/SMESH_SWIG/ex03_cube2partition.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -84,6 +86,8 @@ piece_id = addToStudy(piece, "ex03_cube2partition") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create hexahedrical mesh on piece # --------------------------------- diff --git a/src/SMESH_SWIG/ex04_cube5tetraHexa.py b/src/SMESH_SWIG/ex04_cube5tetraHexa.py index 18d4900ff..773aca145 100644 --- a/src/SMESH_SWIG/ex04_cube5tetraHexa.py +++ b/src/SMESH_SWIG/ex04_cube5tetraHexa.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -65,6 +67,8 @@ piece_id = addToStudy(piece, "ex04_cube5tetraHexa") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex05_hole1build.py b/src/SMESH_SWIG/ex05_hole1build.py index 050509e29..231c3f1d4 100644 --- a/src/SMESH_SWIG/ex05_hole1build.py +++ b/src/SMESH_SWIG/ex05_hole1build.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -123,6 +125,8 @@ piece_id = addToStudy(piece, "ex05_hole1build") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex06_hole1boolean.py b/src/SMESH_SWIG/ex06_hole1boolean.py index 3f2c6893d..0335c3357 100644 --- a/src/SMESH_SWIG/ex06_hole1boolean.py +++ b/src/SMESH_SWIG/ex06_hole1boolean.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -107,7 +109,7 @@ c_l.append(baseHexa4) c_cpd = MakeCompound(c_l) c_glu = MakeGlueFaces(c_cpd, 1.e-5) -piece = RemoveExtraEdges(c_glu) +piece = RemoveExtraEdges(c_glu, doUnionFaces=True) # Add in study # ------------ @@ -117,6 +119,8 @@ piece_id = addToStudy(piece, "ex06_hole1boolean") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex07_hole1partition.py b/src/SMESH_SWIG/ex07_hole1partition.py index c46864c2d..84a4326d6 100644 --- a/src/SMESH_SWIG/ex07_hole1partition.py +++ b/src/SMESH_SWIG/ex07_hole1partition.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -70,7 +72,7 @@ p_tools.append(MakePlane(p_centre, MakeVectorDXDYDZ(-g_largeur, 0, g_longueur), p_part = MakePartition([c_piece], p_tools, [], [], ShapeType["SOLID"]) -p_blocs = RemoveExtraEdges(p_part) +p_blocs = RemoveExtraEdges(p_part, doUnionFaces=True) piece = MakeGlueFaces(p_blocs, 1.e-5) # Add in study @@ -81,6 +83,8 @@ piece_id = addToStudy(piece, "ex07_hole1partition") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex08_hole2build.py b/src/SMESH_SWIG/ex08_hole2build.py index 6ccb77d41..0bc58f133 100644 --- a/src/SMESH_SWIG/ex08_hole2build.py +++ b/src/SMESH_SWIG/ex08_hole2build.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -114,6 +116,8 @@ piece_id = addToStudy(piece, "ex08_hole2build") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex09_grid4build.py b/src/SMESH_SWIG/ex09_grid4build.py index d0e0fb72a..cbbec434c 100644 --- a/src/SMESH_SWIG/ex09_grid4build.py +++ b/src/SMESH_SWIG/ex09_grid4build.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -117,6 +119,8 @@ piece_id = addToStudy(piece, "ex09_grid4build") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex10_grid4geometry.py b/src/SMESH_SWIG/ex10_grid4geometry.py index 8f63e031d..1679e4b5f 100644 --- a/src/SMESH_SWIG/ex10_grid4geometry.py +++ b/src/SMESH_SWIG/ex10_grid4geometry.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -79,6 +81,8 @@ piece_id = addToStudy(piece, "ex10_grid4geometry") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex11_grid3partition.py b/src/SMESH_SWIG/ex11_grid3partition.py index 3369074d2..252aa5563 100644 --- a/src/SMESH_SWIG/ex11_grid3partition.py +++ b/src/SMESH_SWIG/ex11_grid3partition.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -83,7 +85,7 @@ p_tools.append(MakePlane(e_centre, MakeVectorDXDYDZ(-1, 0, 1), g_trim)) p_part = MakePartition([e_blo1, e_blo2, e_blo3], p_tools, [], [], ShapeType["SOLID"]) -p_element = RemoveExtraEdges(p_part) +p_element = RemoveExtraEdges(p_part, doUnionFaces=True) # Grid and glue # ------------- @@ -100,6 +102,8 @@ piece_id = addToStudy(piece, "ex11_grid3partition") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex12_grid17partition.py b/src/SMESH_SWIG/ex12_grid17partition.py index 2f41e3bee..bf6593b99 100644 --- a/src/SMESH_SWIG/ex12_grid17partition.py +++ b/src/SMESH_SWIG/ex12_grid17partition.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -115,6 +117,8 @@ piece_id = addToStudy(piece, "ex12_grid17partition") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex13_hole1partial.py b/src/SMESH_SWIG/ex13_hole1partial.py index 0b3ff6baf..a54fd6266 100644 --- a/src/SMESH_SWIG/ex13_hole1partial.py +++ b/src/SMESH_SWIG/ex13_hole1partial.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ================================== # from geompy import * @@ -204,7 +206,7 @@ blocks.append(full_parts) piece_cpd = MakeCompound(blocks) -piece_ok = RemoveExtraEdges(piece_cpd) +piece_ok = RemoveExtraEdges(piece_cpd, doUnionFaces=True) piece = MakeGlueFaces(piece_ok, 1.e-3) @@ -213,6 +215,8 @@ piece_id = addToStudy(piece, "ex13_hole1partial") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a mesh # ------------- diff --git a/src/SMESH_SWIG/ex14_cyl1holed.py b/src/SMESH_SWIG/ex14_cyl1holed.py index 42d460b93..0f058c098 100644 --- a/src/SMESH_SWIG/ex14_cyl1holed.py +++ b/src/SMESH_SWIG/ex14_cyl1holed.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -98,6 +100,8 @@ piece_id = addToStudy(piece, "ex14_cyl1holed") # Maillage # ======== +smesh.SetCurrentStudy(salome.myStudy) + # Creer un maillage hexahedrique # ------------------------------ diff --git a/src/SMESH_SWIG/ex15_cyl2geometry.py b/src/SMESH_SWIG/ex15_cyl2geometry.py index ffd3395c6..5322e9ef5 100644 --- a/src/SMESH_SWIG/ex15_cyl2geometry.py +++ b/src/SMESH_SWIG/ex15_cyl2geometry.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -167,7 +169,7 @@ cpd = cpd + r_element # Compound # -------- -piece = RemoveExtraEdges(MakeCompound(cpd)) +piece = RemoveExtraEdges(MakeCompound(cpd), True) # Ajouter la piece dans l'etude # ----------------------------- @@ -177,6 +179,8 @@ piece_id = addToStudy(piece, "ex15_cyl2geometry") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex16_cyl2complementary.py b/src/SMESH_SWIG/ex16_cyl2complementary.py index 774cc5f7d..f644c22a7 100644 --- a/src/SMESH_SWIG/ex16_cyl2complementary.py +++ b/src/SMESH_SWIG/ex16_cyl2complementary.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -98,6 +100,7 @@ d_element[10] = MakeCut(d_element[10], c_cyl) # -------- piece = RemoveExtraEdges(MakeCompound(d_element)) +piece = MakeGlueFaces(piece, 1e-07) # Add piece in study # ------------------ @@ -107,6 +110,8 @@ piece_id = addToStudy(piece, "ex16_cyl2complementary") # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex17_dome1.py b/src/SMESH_SWIG/ex17_dome1.py index a25de9627..2626431f0 100644 --- a/src/SMESH_SWIG/ex17_dome1.py +++ b/src/SMESH_SWIG/ex17_dome1.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -80,6 +82,8 @@ piece_id = addToStudy(piece, "ex17_dome1") # Maillage # ======== +smesh.SetCurrentStudy(salome.myStudy) + # Maillage hexahedrique # --------------------- diff --git a/src/SMESH_SWIG/ex18_dome2.py b/src/SMESH_SWIG/ex18_dome2.py index f56015619..dc31fe8f8 100644 --- a/src/SMESH_SWIG/ex18_dome2.py +++ b/src/SMESH_SWIG/ex18_dome2.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # from geompy import * @@ -117,6 +119,8 @@ piece_id = addToStudy(piece, "ex18_dome2") # Maillage # ======== +smesh.SetCurrentStudy(salome.myStudy) + # Maillage hexahedrique # --------------------- diff --git a/src/SMESH_SWIG/ex19_sphereINcube.py b/src/SMESH_SWIG/ex19_sphereINcube.py index 510adf800..879596348 100644 --- a/src/SMESH_SWIG/ex19_sphereINcube.py +++ b/src/SMESH_SWIG/ex19_sphereINcube.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ================================== # from geompy import * @@ -74,17 +76,13 @@ f4 = MakePlane(sphere_centre, MakeVectorDXDYDZ( 1, 0, -1), plan_trim) #sphere_decoupee = MakePartition(solids, sphere_outils, [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(sphere_troue,geompy.ShapeType["SOLID"]) -sphere_decoupee = MakePartition(solids, [f1], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"]) -sphere_decoupee = MakePartition(solids, [f2], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"]) -sphere_decoupee = MakePartition(solids, [f3], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"]) -sphere_decoupee = MakePartition(solids, [f4], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"]) - -sphere_partie = geompy.MakeCompound(solids) + +sphere_decoupee = MakePartition([sphere_troue], [f1], [], [], ShapeType["SOLID"]) +sphere_decoupee = MakePartition([sphere_decoupee], [f2], [], [], ShapeType["SOLID"]) +sphere_decoupee = MakePartition([sphere_decoupee], [f3], [], [], ShapeType["SOLID"]) +sphere_decoupee = MakePartition([sphere_decoupee], [f4], [], [], ShapeType["SOLID"]) + +sphere_partie = geompy.MakeCompound([sphere_decoupee]) sphere_partie = GetBlockNearPoint(sphere_decoupee, MakeVertex(-sphere_rayon, 0, 0)) sphere_bloc = RemoveExtraEdges(sphere_partie) @@ -111,17 +109,12 @@ cube_plein = MakeBox(-cube_cote, -cube_cote, -cube_cote, +cube_cote, +cube_co cube_trou = MakeCut(cube_plein, sphere_pleine) #cube_decoupe = MakePartition([cube_trou], sphere_outils, [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(cube_trou,geompy.ShapeType["SOLID"]) -cube_decoupe = MakePartition(solids, [f1], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"]) -cube_decoupe = MakePartition(solids, [f2], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"]) -cube_decoupe = MakePartition(solids, [f3], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"]) -cube_decoupe = MakePartition(solids, [f4], [], [], ShapeType["SOLID"]) -solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"]) +cube_decoupe = MakePartition([cube_trou], [f1], [], [], ShapeType["SOLID"]) +cube_decoupe = MakePartition([cube_decoupe], [f2], [], [], ShapeType["SOLID"]) +cube_decoupe = MakePartition([cube_decoupe], [f3], [], [], ShapeType["SOLID"]) +cube_decoupe = MakePartition([cube_decoupe], [f4], [], [], ShapeType["SOLID"]) -cube_decoupe = geompy.MakeCompound(solids) +cube_decoupe = geompy.MakeCompound([cube_decoupe]) cube_partie = GetBlockNearPoint(cube_decoupe, MakeVertex(-cube_cote, 0, 0)) @@ -167,6 +160,8 @@ UnionList(groupe, groupe_sphere) # Meshing # ======= +smesh.SetCurrentStudy(salome.myStudy) + # Create a hexahedral mesh # ------------------------ diff --git a/src/SMESH_SWIG/ex21_lamp.py b/src/SMESH_SWIG/ex21_lamp.py index f6c3c3789..befd0e1d8 100644 --- a/src/SMESH_SWIG/ex21_lamp.py +++ b/src/SMESH_SWIG/ex21_lamp.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ================================== # from geompy import * @@ -92,6 +94,8 @@ UnionIDs(group, faces) # Create a mesh # ============= +smesh.SetCurrentStudy(salome.myStudy) + # Define a mesh on a geometry # --------------------------- diff --git a/src/SMESH_SWIG/ex24_cylinder.py b/src/SMESH_SWIG/ex24_cylinder.py index 6d9f3077d..91100376b 100644 --- a/src/SMESH_SWIG/ex24_cylinder.py +++ b/src/SMESH_SWIG/ex24_cylinder.py @@ -1,31 +1,30 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ================================== # import math import geompy import smesh - +import salome geo = geompy # Parameters @@ -97,6 +96,8 @@ geo.DifferenceList(group_1, [group_1_box]) # Mesh the blocks with hexahedral # ------------------------------- +smesh.SetCurrentStudy(salome.myStudy) + def discretize(x, y, z, n, s=blocks): p = geo.MakeVertex(x, y, z) e = geo.GetEdgeNearPoint(s, p) diff --git a/src/SMESH_SWIG/ex29_refine.py b/src/SMESH_SWIG/ex29_refine.py index 1e218a8fa..8363ea81a 100644 --- a/src/SMESH_SWIG/ex29_refine.py +++ b/src/SMESH_SWIG/ex29_refine.py @@ -1,24 +1,23 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # ======================================= # Procedure that take a triangulation and split all triangles in 4 others triangles # diff --git a/src/SMESH_SWIG/ex30_groupsOp.py b/src/SMESH_SWIG/ex30_groupsOp.py index af892e7ff..5bab30823 100755 --- a/src/SMESH_SWIG/ex30_groupsOp.py +++ b/src/SMESH_SWIG/ex30_groupsOp.py @@ -1,73 +1,92 @@ - -import sys -import salome -import geompy -import math -import SALOMEDS -import SMESH -import smesh - -salome.salome_init() -aStudyId = salome.myStudy._get_StudyId() - -geompy.init_geom(salome.myStudy) -global Face_1 -Face_1 = geompy.MakeFaceHW(100, 100, 1) -geompy.addToStudy( Face_1, "Face_1" ) - -#smesh.smesh.SetCurrentStudy(aStudyId) -import StdMeshers -pattern = smesh.GetPattern() -Mesh_1 = smesh.Mesh(Face_1) -Regular_1D = Mesh_1.Segment() -Nb_Segments_1 = Regular_1D.NumberOfSegments(10) -Nb_Segments_1.SetDistrType( 0 ) -Quadrangle_2D = Mesh_1.Quadrangle() -isDone = Mesh_1.Compute() - -# groups creation - -aListOfElems = [ 52, 53, 54, 55, 56, 57, - 62, 63, 64, 65, 66, 67, - 72, 73, 74, 75, 76, 77, - 82, 83, 84, 85, 86, 87 ] - -aRedGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Red" ) -aRedGroup.Add( aListOfElems ); -aRedGroup.SetColor( SALOMEDS.Color( 1, 0, 0 ) ) - -aListOfElems = [ 55, 56, 57, 58, 59, - 65, 66, 67, 68, 69, - 75, 76, 77, 78, 79, - 85, 86, 87, 88, 89, - 95, 96, 97, 98, 99, - 105, 106, 107, 108, 109, - 115, 116, 117, 118, 119, - 125, 126, 127, 128, 129 ] - -aGreenGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Green" ) -aGreenGroup.Add( aListOfElems ); -aGreenGroup.SetColor( SALOMEDS.Color( 0, 1, 0 ) ) - -aListOfElems = [ 63, 64, 65, 66, 67, 68, - 73, 74, 75, 76, 77, 78, - 83, 84, 85, 86, 87, 88, - 93, 94, 95, 96, 97, 98, - 103, 104, 105, 106, 107, 108, - 113, 114, 115, 116, 117, 118 ] - -aBlueGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Blue" ) -aBlueGroup.Add( aListOfElems ); -aBlueGroup.SetColor( SALOMEDS.Color( 0, 0, 1 ) ) - -# UnionListOfGroups() -aUnGrp = Mesh_1.UnionListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "UnionGrp" ) - -# IntersectListOfGroups() -aIntGrp=Mesh_1.IntersectListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "IntGrp" ) - -# CutListOfGroups() -aCutGrp=Mesh_1.CutListOfGroups([aRedGroup],[aGreenGroup,aBlueGroup],"CutGrp") - -salome.sg.updateObjBrowser( 1 ) - +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +import sys +import salome +import geompy +import math +import SALOMEDS +import SMESH +import smesh + +salome.salome_init() +aStudyId = salome.myStudy._get_StudyId() + +geompy.init_geom(salome.myStudy) +global Face_1 +Face_1 = geompy.MakeFaceHW(100, 100, 1) +geompy.addToStudy( Face_1, "Face_1" ) + +smesh.SetCurrentStudy(salome.myStudy) +import StdMeshers +pattern = smesh.GetPattern() +Mesh_1 = smesh.Mesh(Face_1) +Regular_1D = Mesh_1.Segment() +Nb_Segments_1 = Regular_1D.NumberOfSegments(10) +Nb_Segments_1.SetDistrType( 0 ) +Quadrangle_2D = Mesh_1.Quadrangle() +isDone = Mesh_1.Compute() + +# groups creation + +aListOfElems = [ 52, 53, 54, 55, 56, 57, + 62, 63, 64, 65, 66, 67, + 72, 73, 74, 75, 76, 77, + 82, 83, 84, 85, 86, 87 ] + +aRedGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Red" ) +aRedGroup.Add( aListOfElems ); +aRedGroup.SetColor( SALOMEDS.Color( 1, 0, 0 ) ) + +aListOfElems = [ 55, 56, 57, 58, 59, + 65, 66, 67, 68, 69, + 75, 76, 77, 78, 79, + 85, 86, 87, 88, 89, + 95, 96, 97, 98, 99, + 105, 106, 107, 108, 109, + 115, 116, 117, 118, 119, + 125, 126, 127, 128, 129 ] + +aGreenGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Green" ) +aGreenGroup.Add( aListOfElems ); +aGreenGroup.SetColor( SALOMEDS.Color( 0, 1, 0 ) ) + +aListOfElems = [ 63, 64, 65, 66, 67, 68, + 73, 74, 75, 76, 77, 78, + 83, 84, 85, 86, 87, 88, + 93, 94, 95, 96, 97, 98, + 103, 104, 105, 106, 107, 108, + 113, 114, 115, 116, 117, 118 ] + +aBlueGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Blue" ) +aBlueGroup.Add( aListOfElems ); +aBlueGroup.SetColor( SALOMEDS.Color( 0, 0, 1 ) ) + +# UnionListOfGroups() +aUnGrp = Mesh_1.UnionListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "UnionGrp" ) + +# IntersectListOfGroups() +aIntGrp=Mesh_1.IntersectListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "IntGrp" ) + +# CutListOfGroups() +aCutGrp=Mesh_1.CutListOfGroups([aRedGroup],[aGreenGroup,aBlueGroup],"CutGrp") + +salome.sg.updateObjBrowser( 1 ) + diff --git a/src/SMESH_SWIG/ex30_tepal.py b/src/SMESH_SWIG/ex30_tepal.py index c73dc872d..ece87736d 100644 --- a/src/SMESH_SWIG/ex30_tepal.py +++ b/src/SMESH_SWIG/ex30_tepal.py @@ -1,6 +1,25 @@ -# CEA/LGLS 2008, Christian Van Wambeke (CEA/LGLS), Francis KLOSS (OCC) -# ==================================================================== +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# ==================================================================== +# import os import geompy @@ -27,6 +46,8 @@ geompy.addToStudy(cylinder, "Cylinder") # Define a mesh on a geometry # --------------------------- +smesh.SetCurrentStudy(salome.myStudy) + m = smesh.Mesh(cylinder) # 2D mesh with BLSURF diff --git a/src/SMESH_SWIG/ex31_dimGroup.py b/src/SMESH_SWIG/ex31_dimGroup.py index 13cd9cf26..ae8daeb0c 100755 --- a/src/SMESH_SWIG/ex31_dimGroup.py +++ b/src/SMESH_SWIG/ex31_dimGroup.py @@ -1,47 +1,67 @@ -import sys -import salome -import geompy -import math -import SALOMEDS -import SMESH -import smesh - -salome.salome_init() -aStudyId = salome.myStudy._get_StudyId() - -geompy.init_geom(salome.myStudy) - -geompy.init_geom(salome.myStudy) -global Box_1 -Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) -geompy.addToStudy( Box_1, "Box_1" ) - -#smesh.smesh.SetCurrentStudy(theStudy) -import StdMeshers -Mesh_1 = smesh.Mesh(Box_1) -Regular_1D = Mesh_1.Segment() -Nb_Segments_1 = Regular_1D.NumberOfSegments(10) -Nb_Segments_1.SetDistrType( 0 ) -Quadrangle_2D = Mesh_1.Quadrangle() -Hexa_3D = Mesh_1.Hexahedron() -isDone = Mesh_1.Compute() - -### CreateDimGroup() - -aListOf3d_1=range(721,821) - -aGrp3D_1=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 1" ) -aGrp3D_1.Add( aListOf3d_1 ) - -aListOf3d_2=range(821, 921) -aGrp3D_2=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 2" ) -aGrp3D_2.Add( aListOf3d_2 ) - -aGrp2D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.FACE, "Faces" ) - -aGrp1D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.EDGE, "Edges" ) - -aGrp0D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.NODE, "Nodes" ) - -salome.sg.updateObjBrowser( 1 ) - +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +import sys +import salome +import geompy +import math +import SALOMEDS +import SMESH +import smesh + +salome.salome_init() +aStudyId = salome.myStudy._get_StudyId() + +geompy.init_geom(salome.myStudy) + +geompy.init_geom(salome.myStudy) +global Box_1 +Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200) +geompy.addToStudy( Box_1, "Box_1" ) + +smesh.SetCurrentStudy(salome.myStudy) +import StdMeshers +Mesh_1 = smesh.Mesh(Box_1) +Regular_1D = Mesh_1.Segment() +Nb_Segments_1 = Regular_1D.NumberOfSegments(10) +Nb_Segments_1.SetDistrType( 0 ) +Quadrangle_2D = Mesh_1.Quadrangle() +Hexa_3D = Mesh_1.Hexahedron() +isDone = Mesh_1.Compute() + +### CreateDimGroup() + +aListOf3d_1=range(721,821) + +aGrp3D_1=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 1" ) +aGrp3D_1.Add( aListOf3d_1 ) + +aListOf3d_2=range(821, 921) +aGrp3D_2=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 2" ) +aGrp3D_2.Add( aListOf3d_2 ) + +aGrp2D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.FACE, "Faces" ) + +aGrp1D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.EDGE, "Edges" ) + +aGrp0D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.NODE, "Nodes" ) + +salome.sg.updateObjBrowser( 1 ) + diff --git a/src/SMESH_SWIG/smesh.py b/src/SMESH_SWIG/smesh.py index dc22bc389..c13a57e8e 100644 --- a/src/SMESH_SWIG/smesh.py +++ b/src/SMESH_SWIG/smesh.py @@ -1,24 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is 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. +# 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 +# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : smesh.py # Author : Francis KLOSS, OCC # Module : SMESH @@ -34,12 +36,34 @@ import geompy import smeshDC from smeshDC import * +# get instance of class smeshDC smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") smesh.init_smesh(salome.myStudy,geompy.geom) -# Export the methods of smeshD +# load plugins +from smeshDC import Mesh, algoCreator +for pluginName in os.environ["SMESH_MeshersList"].split(":"): + + pluginName += "DC" + try: + exec("from %s import *" % pluginName ) + except Exception, e: + print "Exception while loading %s: %s" % ( pluginName, e ) + continue + exec("import %s" % pluginName ) + plugin = eval(pluginName) + + # add methods creating algorithms to Mesh + for k in dir(plugin): + if k[0] == '_':continue + algo = getattr(plugin,k) + if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod"): + if not hasattr( Mesh, algo.meshMethod ): + setattr( Mesh, algo.meshMethod, algoCreator()) + getattr( Mesh, algo.meshMethod ).add( algo ) + +# Export the methods of smeshDC for k in dir(smesh): if k[0] == '_':continue globals()[k]=getattr(smesh,k) del k - diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 7b81262a0..9780503a1 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -1,28 +1,25 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # # File : smesh.py # Author : Francis KLOSS, OCC # Module : SMESH -# + """ \namespace smesh \brief Module smesh @@ -47,10 +44,7 @@ ## @defgroup l3_hypos_1dhyps 1D Meshing Hypotheses ## @defgroup l3_hypos_2dhyps 2D Meshing Hypotheses ## @defgroup l3_hypos_maxvol Max Element Volume hypothesis -## @defgroup l3_hypos_netgen Netgen 2D and 3D hypotheses -## @defgroup l3_hypos_ghs3dh GHS3D Parameters hypothesis -## @defgroup l3_hypos_blsurf BLSURF Parameters hypothesis -## @defgroup l3_hypos_hexotic Hexotic Parameters hypothesis +## @defgroup l3_hypos_quad Quadrangle Parameters hypothesis ## @defgroup l3_hypos_additi Additional Hypotheses ## @} @@ -88,6 +82,7 @@ ## @defgroup l2_modif_tofromqu Convert to/from Quadratic Mesh ## @} +## @defgroup l1_measurements Measurements import salome import geompyDC @@ -95,41 +90,12 @@ import geompyDC import SMESH # This is necessary for back compatibility from SMESH import * -import StdMeshers - import SALOME - -# import NETGENPlugin module if possible -noNETGENPlugin = 0 -try: - import NETGENPlugin -except ImportError: - noNETGENPlugin = 1 - pass +import SALOMEDS ## @addtogroup l1_auxiliary ## @{ -# Types of algorithms -REGULAR = 1 -PYTHON = 2 -COMPOSITE = 3 -SOLE = 0 -SIMPLE = 1 - -MEFISTO = 3 -NETGEN = 4 -GHS3D = 5 -FULL_NETGEN = 6 -NETGEN_2D = 7 -NETGEN_1D2D = NETGEN -NETGEN_1D2D3D = FULL_NETGEN -NETGEN_FULL = FULL_NETGEN -Hexa = 8 -Hexotic = 9 -BLSURF = 10 -GHS3DPRL = 11 - # MirrorType enumeration POINT = SMESH_MeshEditor.POINT AXIS = SMESH_MeshEditor.AXIS @@ -139,213 +105,74 @@ PLANE = SMESH_MeshEditor.PLANE LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH -# Fineness enumeration (for NETGEN) -VeryCoarse = 0 -Coarse = 1 -Moderate = 2 -Fine = 3 -VeryFine = 4 -Custom = 5 - -# Optimization level of GHS3D -None_Optimization, Light_Optimization, Medium_Optimization, Strong_Optimization = 0,1,2,3 - -# Topology treatment way of BLSURF -FromCAD, PreProcess, PreProcessPlus = 0,1,2 +PrecisionConfusion = 1e-07 -# Element size flag of BLSURF -DefaultSize, DefaultGeom, Custom = 0,0,1 +# TopAbs_State enumeration +[TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = range(4) -PrecisionConfusion = 1e-07 +# Methods of splitting a hexahedron into tetrahedra +Hex_5Tet, Hex_6Tet, Hex_24Tet = 1, 2, 3 ## Converts an angle from degrees to radians def DegreesToRadians(AngleInDegrees): from math import pi return AngleInDegrees * pi / 180.0 +import salome_notebook +notebook = salome_notebook.notebook # Salome notebook variable separator var_separator = ":" -# Parametrized substitute for PointStruct -class PointStructStr: - - x = 0 - y = 0 - z = 0 - xStr = "" - yStr = "" - zStr = "" - - def __init__(self, xStr, yStr, zStr): - self.xStr = xStr - self.yStr = yStr - self.zStr = zStr - if isinstance(xStr, str) and notebook.isVariable(xStr): - self.x = notebook.get(xStr) - else: - self.x = xStr - if isinstance(yStr, str) and notebook.isVariable(yStr): - self.y = notebook.get(yStr) - else: - self.y = yStr - if isinstance(zStr, str) and notebook.isVariable(zStr): - self.z = notebook.get(zStr) - else: - self.z = zStr - -# Parametrized substitute for PointStruct (with 6 parameters) -class PointStructStr6: - - x1 = 0 - y1 = 0 - z1 = 0 - x2 = 0 - y2 = 0 - z2 = 0 - xStr1 = "" - yStr1 = "" - zStr1 = "" - xStr2 = "" - yStr2 = "" - zStr2 = "" - - def __init__(self, x1Str, x2Str, y1Str, y2Str, z1Str, z2Str): - self.x1Str = x1Str - self.x2Str = x2Str - self.y1Str = y1Str - self.y2Str = y2Str - self.z1Str = z1Str - self.z2Str = z2Str - if isinstance(x1Str, str) and notebook.isVariable(x1Str): - self.x1 = notebook.get(x1Str) - else: - self.x1 = x1Str - if isinstance(x2Str, str) and notebook.isVariable(x2Str): - self.x2 = notebook.get(x2Str) - else: - self.x2 = x2Str - if isinstance(y1Str, str) and notebook.isVariable(y1Str): - self.y1 = notebook.get(y1Str) - else: - self.y1 = y1Str - if isinstance(y2Str, str) and notebook.isVariable(y2Str): - self.y2 = notebook.get(y2Str) - else: - self.y2 = y2Str - if isinstance(z1Str, str) and notebook.isVariable(z1Str): - self.z1 = notebook.get(z1Str) - else: - self.z1 = z1Str - if isinstance(z2Str, str) and notebook.isVariable(z2Str): - self.z2 = notebook.get(z2Str) - else: - self.z2 = z2Str - -# Parametrized substitute for AxisStruct -class AxisStructStr: - - x = 0 - y = 0 - z = 0 - dx = 0 - dy = 0 - dz = 0 - xStr = "" - yStr = "" - zStr = "" - dxStr = "" - dyStr = "" - dzStr = "" - - def __init__(self, xStr, yStr, zStr, dxStr, dyStr, dzStr): - self.xStr = xStr - self.yStr = yStr - self.zStr = zStr - self.dxStr = dxStr - self.dyStr = dyStr - self.dzStr = dzStr - if isinstance(xStr, str) and notebook.isVariable(xStr): - self.x = notebook.get(xStr) - else: - self.x = xStr - if isinstance(yStr, str) and notebook.isVariable(yStr): - self.y = notebook.get(yStr) - else: - self.y = yStr - if isinstance(zStr, str) and notebook.isVariable(zStr): - self.z = notebook.get(zStr) - else: - self.z = zStr - if isinstance(dxStr, str) and notebook.isVariable(dxStr): - self.dx = notebook.get(dxStr) - else: - self.dx = dxStr - if isinstance(dyStr, str) and notebook.isVariable(dyStr): - self.dy = notebook.get(dyStr) - else: - self.dy = dyStr - if isinstance(dzStr, str) and notebook.isVariable(dzStr): - self.dz = notebook.get(dzStr) - else: - self.dz = dzStr - -# Parametrized substitute for DirStruct -class DirStructStr: - - def __init__(self, pointStruct): - self.pointStruct = pointStruct - -# Returns list of variable values from salome notebook -def ParsePointStruct(Point): - Parameters = 2*var_separator - if isinstance(Point, PointStructStr): - Parameters = str(Point.xStr) + var_separator + str(Point.yStr) + var_separator + str(Point.zStr) - Point = PointStruct(Point.x, Point.y, Point.z) - return Point, Parameters - -# Returns list of variable values from salome notebook -def ParseDirStruct(Dir): - Parameters = 2*var_separator - if isinstance(Dir, DirStructStr): - pntStr = Dir.pointStruct - if isinstance(pntStr, PointStructStr6): - Parameters = str(pntStr.x1Str) + var_separator + str(pntStr.x2Str) + var_separator - Parameters += str(pntStr.y1Str) + var_separator + str(pntStr.y2Str) + var_separator - Parameters += str(pntStr.z1Str) + var_separator + str(pntStr.z2Str) - Point = PointStruct(pntStr.x2 - pntStr.x1, pntStr.y2 - pntStr.y1, pntStr.z2 - pntStr.z1) - else: - Parameters = str(pntStr.xStr) + var_separator + str(pntStr.yStr) + var_separator + str(pntStr.zStr) - Point = PointStruct(pntStr.x, pntStr.y, pntStr.z) - Dir = DirStruct(Point) - return Dir, Parameters - -# Returns list of variable values from salome notebook -def ParseAxisStruct(Axis): - Parameters = 5*var_separator - if isinstance(Axis, AxisStructStr): - Parameters = str(Axis.xStr) + var_separator + str(Axis.yStr) + var_separator + str(Axis.zStr) + var_separator - Parameters += str(Axis.dxStr) + var_separator + str(Axis.dyStr) + var_separator + str(Axis.dzStr) - Axis = AxisStruct(Axis.x, Axis.y, Axis.z, Axis.dx, Axis.dy, Axis.dz) - return Axis, Parameters - -## Return list of variable values from salome notebook -def ParseAngles(list): +## Return list of variable values from salome notebook. +# The last argument, if is callable, is used to modify values got from notebook +def ParseParameters(*args): Result = [] Parameters = "" - for parameter in list: - if isinstance(parameter,str) and notebook.isVariable(parameter): - Result.append(DegreesToRadians(notebook.get(parameter))) - pass - else: - Result.append(parameter) + hasVariables = False + varModifFun=None + if args and callable( args[-1] ): + args, varModifFun = args[:-1], args[-1] + for parameter in args: + + Parameters += str(parameter) + var_separator + + if isinstance(parameter,str): + # check if there is an inexistent variable name + if not notebook.isVariable(parameter): + raise ValueError, "Variable with name '" + parameter + "' doesn't exist!!!" + parameter = notebook.get(parameter) + hasVariables = True + if varModifFun: + parameter = varModifFun(parameter) + pass pass - - Parameters = Parameters + str(parameter) - Parameters = Parameters + var_separator + Result.append(parameter) + pass - Parameters = Parameters[:len(Parameters)-1] - return Result, Parameters - + Parameters = Parameters[:-1] + Result.append( Parameters ) + Result.append( hasVariables ) + return Result + +# Parse parameters converting variables to radians +def ParseAngles(*args): + return ParseParameters( *( args + (DegreesToRadians, ))) + +# Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables. +# Parameters are stored in PointStruct.parameters attribute +def __initPointStruct(point,*args): + point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args) + pass +SMESH.PointStruct.__init__ = __initPointStruct + +# Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables. +# Parameters are stored in AxisStruct.parameters attribute +def __initAxisStruct(ax,*args): + ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args) + pass +SMESH.AxisStruct.__init__ = __initAxisStruct + + def IsEqual(val1, val2, tol=PrecisionConfusion): if abs(val1 - val2) < tol: return True @@ -355,13 +182,33 @@ NO_NAME = "NoName" ## Gets object name def GetName(obj): - ior = salome.orb.object_to_string(obj) - sobj = salome.myStudy.FindObjectIOR(ior) - if sobj is None: - return NO_NAME - else: - attr = sobj.FindAttribute("AttributeName")[1] - return attr.Value() + if obj: + # object not null + if isinstance(obj, SALOMEDS._objref_SObject): + # study object + return obj.GetName() + ior = salome.orb.object_to_string(obj) + if ior: + # CORBA object + studies = salome.myStudyManager.GetOpenStudies() + for sname in studies: + s = salome.myStudyManager.GetStudyByName(sname) + if not s: continue + sobj = s.FindObjectIOR(ior) + if not sobj: continue + return sobj.GetName() + if hasattr(obj, "GetName"): + # unknown CORBA object, having GetName() method + return obj.GetName() + else: + # unknown CORBA object, no GetName() method + return NO_NAME + pass + if hasattr(obj, "GetName"): + # unknown non-CORBA object, having GetName() method + return obj.GetName() + pass + raise RuntimeError, "Null or invalid object" ## Prints error message if a hypothesis was not assigned. def TreatHypoStatus(status, hypName, geomName, isAlgo): @@ -377,13 +224,14 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo): elif status == HYP_NOTCONFORM : reason = "a non-conform mesh would be built" elif status == HYP_ALREADY_EXIST : + if isAlgo: return # it does not influence anything reason = hypType + " of the same dimension is already assigned to this shape" elif status == HYP_BAD_DIM : reason = hypType + " mismatches the shape" elif status == HYP_CONCURENT : reason = "there are concurrent hypotheses on sub-shapes" elif status == HYP_BAD_SUBSHAPE : - reason = "the shape is neither the main one, nor its subshape, nor a valid group" + reason = "the shape is neither the main one, nor its sub-shape, nor a valid group" elif status == HYP_BAD_GEOMETRY: reason = "geometry mismatches the expectation of the algorithm" elif status == HYP_HIDDEN_ALGO: @@ -396,18 +244,76 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo): return hypName = '"' + hypName + '"' geomName= '"' + geomName+ '"' - if status < HYP_UNKNOWN_FATAL: + if status < HYP_UNKNOWN_FATAL and not geomName =='""': print hypName, "was assigned to", geomName,"but", reason - else: + elif not geomName == '""': print hypName, "was not assigned to",geomName,":", reason + else: + print hypName, "was not assigned:", reason pass +## Private method. Add geom (sub-shape of the main shape) into the study if not yet there +def AssureGeomPublished(mesh, geom, name=''): + if not isinstance( geom, geompyDC.GEOM._objref_GEOM_Object ): + return + if not geom.IsSame( mesh.geom ) and \ + not geom.GetStudyEntry() and \ + mesh.smeshpyD.GetCurrentStudy(): + ## set the study + studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId() + if studyID != mesh.geompyD.myStudyId: + mesh.geompyD.init_geom( mesh.smeshpyD.GetCurrentStudy()) + ## get a name + if not name and geom.GetShapeType() != geompyDC.GEOM.COMPOUND: + # for all groups SubShapeName() returns "Compound_-1" + name = mesh.geompyD.SubShapeName(geom, mesh.geom) + if not name: + name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000) + ## publish + mesh.geompyD.addToStudyInFather( mesh.geom, geom, name ) + return + +## Return the first vertex of a geomertical edge by ignoring orienation +def FirstVertexOnCurve(edge): + from geompy import SubShapeAll, ShapeType, KindOfShape, PointCoordinates + vv = SubShapeAll( edge, ShapeType["VERTEX"]) + if not vv: + raise TypeError, "Given object has no vertices" + if len( vv ) == 1: return vv[0] + info = KindOfShape(edge) + xyz = info[1:4] # coords of the first vertex + xyz1 = PointCoordinates( vv[0] ) + xyz2 = PointCoordinates( vv[1] ) + dist1, dist2 = 0,0 + for i in range(3): + dist1 += abs( xyz[i] - xyz1[i] ) + dist2 += abs( xyz[i] - xyz2[i] ) + if dist1 < dist2: + return vv[0] + else: + return vv[1] + # end of l1_auxiliary ## @} # All methods of this class are accessible directly from the smesh.py package. class smeshDC(SMESH._objref_SMESH_Gen): + ## Dump component to the Python script + # This method overrides IDL function to allow default values for the parameters. + def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True): + return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile) + + ## Set mode of DumpPython(), \a historical or \a snapshot. + # In the \a historical mode, the Python Dump script includes all commands + # performed by SMESH engine. In the \a snapshot mode, commands + # relating to objects removed from the Study are excluded from the script + # as well as commands not influencing the current state of meshes + def SetDumpPythonHistorical(self, isHistorical): + if isHistorical: val = "true" + else: val = "false" + SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val) + ## Sets the current study and Geometry component # @ingroup l1_auxiliary def init_smesh(self,theStudy,geompyD): @@ -420,7 +326,9 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @return an instance of Mesh class. # @ingroup l2_construct def Mesh(self, obj=0, name=0): - return Mesh(self,self.geompyD,obj,name) + if isinstance(obj,str): + obj,name = name,obj + return Mesh(self,self.geompyD,obj,name) ## Returns a long value from enumeration # Should be used for SMESH.FunctorType enumeration @@ -428,6 +336,20 @@ class smeshDC(SMESH._objref_SMESH_Gen): def EnumToLong(self,theItem): return theItem._v + ## Returns a string representation of the color. + # To be used with filters. + # @param c color value (SALOMEDS.Color) + # @ingroup l1_controls + def ColorToString(self,c): + val = "" + if isinstance(c, SALOMEDS.Color): + val = "%s;%s;%s" % (c.R, c.G, c.B) + elif isinstance(c, str): + val = c + else: + raise ValueError, "Color value should be of string or SALOMEDS.Color type" + return val + ## Gets PointStruct from vertex # @param theVertex a GEOM object(vertex) # @return SMESH.PointStruct @@ -493,7 +415,6 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @param name a new object name # @ingroup l1_auxiliary def SetName(self, obj, name): - print "obj_name = ", name if isinstance( obj, Mesh ): obj = obj.GetMesh() elif isinstance( obj, Mesh_Algorithm ): @@ -524,6 +445,11 @@ class smeshDC(SMESH._objref_SMESH_Gen): self.geompyD=geompyD self.SetGeomEngine(geompyD) SMESH._objref_SMESH_Gen.SetCurrentStudy(self,theStudy) + global notebook + if theStudy: + notebook = salome_notebook.NoteBook( theStudy ) + else: + notebook = salome_notebook.NoteBook( salome_notebook.PseudoStudyForNoteBook() ) ## Gets the current study # @ingroup l1_auxiliary @@ -550,6 +476,17 @@ class smeshDC(SMESH._objref_SMESH_Gen): aMeshes.append(aMesh) return aMeshes, aStatus + ## Creates a Mesh object(s) importing data from the given SAUV file + # @return a list of Mesh class instances + # @ingroup l2_impexp + def CreateMeshesFromSAUV( self,theFileName ): + aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName) + aMeshes = [] + for iMesh in range(len(aSmeshMeshes)) : + aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh]) + aMeshes.append(aMesh) + return aMeshes, aStatus + ## Creates a Mesh object importing data from the given STL file # @return an instance of Mesh class # @ingroup l2_impexp @@ -558,6 +495,17 @@ class smeshDC(SMESH._objref_SMESH_Gen): aMesh = Mesh(self, self.geompyD, aSmeshMesh) return aMesh + ## Creates Mesh objects importing data from the given CGNS file + # @return an instance of Mesh class + # @ingroup l2_impexp + def CreateMeshesFromCGNS( self, theFileName ): + aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName) + aMeshes = [] + for iMesh in range(len(aSmeshMeshes)) : + aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh]) + aMeshes.append(aMesh) + return aMeshes, aStatus + ## Concatenate the given meshes into one mesh. # @return an instance of Mesh class # @param meshes the meshes to combine into one mesh @@ -567,6 +515,12 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @param allGroups forces creation of groups of all elements def Concatenate( self, meshes, uniteIdenticalGroups, mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False): + if not meshes: return None + for i,m in enumerate(meshes): + if isinstance(m, Mesh): + meshes[i] = m.GetMesh() + mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance) + meshes[0].SetParameters(Parameters) if allGroups: aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups( self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance) @@ -576,6 +530,20 @@ class smeshDC(SMESH._objref_SMESH_Gen): aMesh = Mesh(self, self.geompyD, aSmeshMesh) return aMesh + ## Create a mesh by copying a part of another mesh. + # @param meshPart a part of mesh to copy, either a Mesh, a sub-mesh or a group; + # to copy nodes or elements not contained in any mesh object, + # pass result of Mesh.GetIDSource( list_of_ids, type ) as meshPart + # @param meshName a name of the new mesh + # @param toCopyGroups to create in the new mesh groups the copied elements belongs to + # @param toKeepIDs to preserve IDs of the copied elements or not + # @return an instance of Mesh class + def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False): + if (isinstance( meshPart, Mesh )): + meshPart = meshPart.GetMesh() + mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs ) + return Mesh(self, self.geompyD, mesh) + ## From SMESH_Gen interface # @return the list of integer values # @ingroup l1_auxiliary @@ -597,26 +565,6 @@ class smeshDC(SMESH._objref_SMESH_Gen): def SetBoundaryBoxSegmentation(self, nbSegments): SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments) - ## Concatenate the given meshes into one mesh. - # @return an instance of Mesh class - # @param meshes the meshes to combine into one mesh - # @param uniteIdenticalGroups if true, groups with same names are united, else they are renamed - # @param mergeNodesAndElements if true, equal nodes and elements aremerged - # @param mergeTolerance tolerance for merging nodes - # @param allGroups forces creation of groups of all elements - def Concatenate( self, meshes, uniteIdenticalGroups, - mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False): - mergeTolerance,Parameters = geompyDC.ParseParameters(mergeTolerance) - if allGroups: - aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups( - self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance) - else: - aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate( - self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance) - aSmeshMesh.SetParameters(Parameters) - aMesh = Mesh(self, self.geompyD, aSmeshMesh) - return aMesh - # Filtering. Auxiliary functions: # ------------------------------ @@ -638,26 +586,35 @@ class smeshDC(SMESH._objref_SMESH_Gen): UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision) ## Creates a criterion by the given parameters + # \n Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below) # @param elementType the type of elements(NODE, EDGE, FACE, VOLUME) # @param CritType the type of criterion (FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc.) # @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo} - # @param Treshold the threshold value (range of ids as string, shape, numeric) + # @param Threshold the threshold value (range of ids as string, shape, numeric) # @param UnaryOp FT_LogicalNOT or FT_Undefined # @param BinaryOp a binary logical operation FT_LogicalAND, FT_LogicalOR or # FT_Undefined (must be for the last criterion of all criteria) + # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface, + # FT_LyingOnGeom, FT_CoplanarFaces criteria # @return SMESH.Filter.Criterion + # + # Example of Criteria usage # @ingroup l1_controls def GetCriterion(self,elementType, CritType, Compare = FT_EqualTo, - Treshold="", + Threshold="", UnaryOp=FT_Undefined, - BinaryOp=FT_Undefined): + BinaryOp=FT_Undefined, + Tolerance=1e-07): + if not CritType in SMESH.FunctorType._items: + raise TypeError, "CritType should be of SMESH.FunctorType" aCriterion = self.GetEmptyCriterion() aCriterion.TypeOfElement = elementType aCriterion.Type = self.EnumToLong(CritType) + aCriterion.Tolerance = Tolerance - aTreshold = Treshold + aThreshold = Threshold if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]: aCriterion.Compare = self.EnumToLong(Compare) @@ -667,47 +624,89 @@ class smeshDC(SMESH._objref_SMESH_Gen): aCriterion.Compare = self.EnumToLong(FT_LessThan) elif Compare == ">": aCriterion.Compare = self.EnumToLong(FT_MoreThan) - else: + elif Compare != FT_Undefined: aCriterion.Compare = self.EnumToLong(FT_EqualTo) - aTreshold = Compare + aThreshold = Compare if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface, FT_BelongToCylinder, FT_LyingOnGeom]: - # Checks the treshold - if isinstance(aTreshold, geompyDC.GEOM._objref_GEOM_Object): - aCriterion.ThresholdStr = GetName(aTreshold) - aCriterion.ThresholdID = salome.ObjectToID(aTreshold) + # Checks that Threshold is GEOM object + if isinstance(aThreshold, geompyDC.GEOM._objref_GEOM_Object): + aCriterion.ThresholdStr = GetName(aThreshold) + aCriterion.ThresholdID = aThreshold.GetStudyEntry() + if not aCriterion.ThresholdID: + raise RuntimeError, "Threshold shape must be published" else: - print "Error: The treshold should be a shape." + print "Error: The Threshold should be a shape." return None + if isinstance(UnaryOp,float): + aCriterion.Tolerance = UnaryOp + UnaryOp = FT_Undefined + pass elif CritType == FT_RangeOfIds: - # Checks the treshold - if isinstance(aTreshold, str): - aCriterion.ThresholdStr = aTreshold + # Checks that Threshold is string + if isinstance(aThreshold, str): + aCriterion.ThresholdStr = aThreshold else: - print "Error: The treshold should be a string." + print "Error: The Threshold should be a string." + return None + elif CritType == FT_CoplanarFaces: + # Checks the Threshold + if isinstance(aThreshold, int): + aCriterion.ThresholdID = str(aThreshold) + elif isinstance(aThreshold, str): + ID = int(aThreshold) + if ID < 1: + raise ValueError, "Invalid ID of mesh face: '%s'"%aThreshold + aCriterion.ThresholdID = aThreshold + else: + raise ValueError,\ + "The Threshold should be an ID of mesh face and not '%s'"%aThreshold + elif CritType == FT_ElemGeomType: + # Checks the Threshold + try: + aCriterion.Threshold = self.EnumToLong(aThreshold) + assert( aThreshold in SMESH.GeometryType._items ) + except: + if isinstance(aThreshold, int): + aCriterion.Threshold = aThreshold + else: + print "Error: The Threshold should be an integer or SMESH.GeometryType." + return None + pass + pass + elif CritType == FT_GroupColor: + # Checks the Threshold + try: + aCriterion.ThresholdStr = self.ColorToString(aThreshold) + except: + print "Error: The threshold value should be of SALOMEDS.Color type" return None - elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume, FT_FreeNodes, - FT_FreeFaces, FT_ElemGeomType, FT_GroupColor]: - # At this point the treshold is unnecessary - if aTreshold == FT_LogicalNOT: + pass + elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces, + FT_LinearOrQuadratic, FT_BadOrientedVolume, + FT_BareBorderFace, FT_BareBorderVolume, + FT_OverConstrainedFace, FT_OverConstrainedVolume, + FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]: + # At this point the Threshold is unnecessary + if aThreshold == FT_LogicalNOT: aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT) - elif aTreshold in [FT_LogicalAND, FT_LogicalOR]: - aCriterion.BinaryOp = aTreshold + elif aThreshold in [FT_LogicalAND, FT_LogicalOR]: + aCriterion.BinaryOp = aThreshold else: - # Check treshold + # Check Threshold try: - aTreshold = float(aTreshold) - aCriterion.Threshold = aTreshold + aThreshold = float(aThreshold) + aCriterion.Threshold = aThreshold except: - print "Error: The treshold should be a number." + print "Error: The Threshold should be a number." return None - if Treshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT: + if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT: aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT) - if Treshold in [FT_LogicalAND, FT_LogicalOR]: - aCriterion.BinaryOp = self.EnumToLong(Treshold) + if Threshold in [FT_LogicalAND, FT_LogicalOR]: + aCriterion.BinaryOp = self.EnumToLong(Threshold) if UnaryOp in [FT_LogicalAND, FT_LogicalOR]: aCriterion.BinaryOp = self.EnumToLong(UnaryOp) @@ -721,21 +720,40 @@ class smeshDC(SMESH._objref_SMESH_Gen): # @param elementType the type of elements in the group # @param CritType the type of criterion ( FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc. ) # @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo} - # @param Treshold the threshold value (range of id ids as string, shape, numeric) + # @param Threshold the threshold value (range of id ids as string, shape, numeric) # @param UnaryOp FT_LogicalNOT or FT_Undefined + # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface, + # FT_LyingOnGeom, FT_CoplanarFaces and FT_EqualNodes criteria # @return SMESH_Filter + # + # Example of Filters usage # @ingroup l1_controls def GetFilter(self,elementType, CritType=FT_Undefined, Compare=FT_EqualTo, - Treshold="", - UnaryOp=FT_Undefined): - aCriterion = self.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined) + Threshold="", + UnaryOp=FT_Undefined, + Tolerance=1e-07): + aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance) aFilterMgr = self.CreateFilterManager() aFilter = aFilterMgr.CreateFilter() aCriteria = [] aCriteria.append(aCriterion) aFilter.SetCriteria(aCriteria) + aFilterMgr.UnRegister() + return aFilter + + ## Creates a filter from criteria + # @param criteria a list of criteria + # @return SMESH_Filter + # + # Example of Filters usage + # @ingroup l1_controls + def GetFilterFromCriteria(self,criteria): + aFilterMgr = self.CreateFilterManager() + aFilter = aFilterMgr.CreateFilter() + aFilter.SetCriteria(criteria) + aFilterMgr.UnRegister() return aFilter ## Creates a numerical functor by its type @@ -760,6 +778,10 @@ class smeshDC(SMESH._objref_SMESH_Gen): return aFilterMgr.CreateArea() elif theCriterion == FT_Volume3D: return aFilterMgr.CreateVolume3D() + elif theCriterion == FT_MaxElementLength2D: + return aFilterMgr.CreateMaxElementLength2D() + elif theCriterion == FT_MaxElementLength3D: + return aFilterMgr.CreateMaxElementLength3D() elif theCriterion == FT_MultiConnection: return aFilterMgr.CreateMultiConnection() elif theCriterion == FT_MultiConnection2D: @@ -769,14 +791,146 @@ class smeshDC(SMESH._objref_SMESH_Gen): elif theCriterion == FT_Length2D: return aFilterMgr.CreateLength2D() else: - print "Error: given parameter is not numerucal functor type." + print "Error: given parameter is not numerical functor type." ## Creates hypothesis - # @param - # @param + # @param theHType mesh hypothesis type (string) + # @param theLibName mesh plug-in library name # @return created hypothesis instance def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"): - return SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName ) + hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName ) + + if isinstance( hyp, SMESH._objref_SMESH_Algo ): + return hyp + + # wrap hypothesis methods + #print "HYPOTHESIS", theHType + for meth_name in dir( hyp.__class__ ): + if not meth_name.startswith("Get") and \ + not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ): + method = getattr ( hyp.__class__, meth_name ) + if callable(method): + setattr( hyp, meth_name, hypMethodWrapper( hyp, method )) + + return hyp + + ## Gets the mesh statistic + # @return dictionary "element type" - "count of elements" + # @ingroup l1_meshinfo + def GetMeshInfo(self, obj): + if isinstance( obj, Mesh ): + obj = obj.GetMesh() + d = {} + if hasattr(obj, "GetMeshInfo"): + values = obj.GetMeshInfo() + for i in range(SMESH.Entity_Last._v): + if i < len(values): d[SMESH.EntityType._item(i)]=values[i] + pass + return d + + ## Get minimum distance between two objects + # + # If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed. + # If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1. + # + # @param src1 first source object + # @param src2 second source object + # @param id1 node/element id from the first source + # @param id2 node/element id from the second (or first) source + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return minimum distance value + # @sa GetMinDistance() + # @ingroup l1_measurements + def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False): + result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2) + if result is None: + result = 0.0 + else: + result = result.value + return result + + ## Get measure structure specifying minimum distance data between two objects + # + # If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed. + # If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1. + # + # @param src1 first source object + # @param src2 second source object + # @param id1 node/element id from the first source + # @param id2 node/element id from the second (or first) source + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return Measure structure or None if input data is invalid + # @sa MinDistance() + # @ingroup l1_measurements + def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False): + if isinstance(src1, Mesh): src1 = src1.mesh + if isinstance(src2, Mesh): src2 = src2.mesh + if src2 is None and id2 != 0: src2 = src1 + if not hasattr(src1, "_narrow"): return None + src1 = src1._narrow(SMESH.SMESH_IDSource) + if not src1: return None + if id1 != 0: + m = src1.GetMesh() + e = m.GetMeshEditor() + if isElem1: + src1 = e.MakeIDSource([id1], SMESH.FACE) + else: + src1 = e.MakeIDSource([id1], SMESH.NODE) + pass + if hasattr(src2, "_narrow"): + src2 = src2._narrow(SMESH.SMESH_IDSource) + if src2 and id2 != 0: + m = src2.GetMesh() + e = m.GetMeshEditor() + if isElem2: + src2 = e.MakeIDSource([id2], SMESH.FACE) + else: + src2 = e.MakeIDSource([id2], SMESH.NODE) + pass + pass + aMeasurements = self.CreateMeasurements() + result = aMeasurements.MinDistance(src1, src2) + aMeasurements.UnRegister() + return result + + ## Get bounding box of the specified object(s) + # @param objects single source object or list of source objects + # @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ) + # @sa GetBoundingBox() + # @ingroup l1_measurements + def BoundingBox(self, objects): + result = self.GetBoundingBox(objects) + if result is None: + result = (0.0,)*6 + else: + result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ) + return result + + ## Get measure structure specifying bounding box data of the specified object(s) + # @param objects single source object or list of source objects + # @return Measure structure + # @sa BoundingBox() + # @ingroup l1_measurements + def GetBoundingBox(self, objects): + if isinstance(objects, tuple): + objects = list(objects) + if not isinstance(objects, list): + objects = [objects] + srclist = [] + for o in objects: + if isinstance(o, Mesh): + srclist.append(o.mesh) + elif hasattr(o, "_narrow"): + src = o._narrow(SMESH.SMESH_IDSource) + if src: srclist.append(src) + pass + pass + aMeasurements = self.CreateMeasurements() + result = aMeasurements.BoundingBox(srclist) + aMeasurements.UnRegister() + return result import omniORB #Registering the new proxy for SMESH_Gen @@ -812,16 +966,27 @@ class Mesh: if obj is None: obj = 0 if obj != 0: + objHasName = True if isinstance(obj, geompyDC.GEOM._objref_GEOM_Object): self.geom = obj + # publish geom of mesh (issue 0021122) + if not self.geom.GetStudyEntry() and smeshpyD.GetCurrentStudy(): + objHasName = False + studyID = smeshpyD.GetCurrentStudy()._get_StudyId() + if studyID != geompyD.myStudyId: + geompyD.init_geom( smeshpyD.GetCurrentStudy()) + pass + geo_name = "%s_%s_for_meshing"%(self.geom.GetShapeType(), id(self.geom)%100) + geompyD.addToStudy( self.geom, geo_name ) self.mesh = self.smeshpyD.CreateMesh(self.geom) + elif isinstance(obj, SMESH._objref_SMESH_Mesh): self.SetMesh(obj) else: self.mesh = self.smeshpyD.CreateEmptyMesh() if name != 0: self.smeshpyD.SetName(self.mesh, name) - elif obj != 0: + elif obj != 0 and objHasName: self.smeshpyD.SetName(self.mesh, GetName(obj)) if not self.geom: @@ -829,6 +994,12 @@ class Mesh: self.editor = self.mesh.GetMeshEditor() + # set self to algoCreator's + for attrName in dir(self): + attr = getattr( self, attrName ) + if isinstance( attr, algoCreator ): + setattr( self, attrName, attr.copy( self )) + ## Initializes the Mesh object from an instance of SMESH_Mesh interface # @param theMesh a SMESH_Mesh object # @ingroup l2_construct @@ -857,12 +1028,13 @@ class Mesh: ## Gets the subMesh object associated to a \a theSubObject geometrical object. # The subMesh object gives access to the IDs of nodes and elements. - # @param theSubObject a geometrical object (shape) - # @param theName a name for the submesh + # @param geom a geometrical object (shape) + # @param name a name for the submesh # @return an object of type SMESH_SubMesh, representing a part of mesh, which lies on the given shape # @ingroup l2_submeshes - def GetSubMesh(self, theSubObject, theName): - submesh = self.mesh.GetSubMesh(theSubObject, theName) + def GetSubMesh(self, geom, name): + AssureGeomPublished( self, geom, name ) + submesh = self.mesh.GetSubMesh( geom, name ) return submesh ## Returns the shape associated to the mesh @@ -877,8 +1049,12 @@ class Mesh: def SetShape(self, geom): self.mesh = self.smeshpyD.CreateMesh(geom) + ## Loads mesh from the study after opening the study + def Load(self): + self.mesh.Load() + ## Returns true if the hypotheses are defined well - # @param theSubObject a subshape of a mesh shape + # @param theSubObject a sub-shape of a mesh shape # @return True or False # @ingroup l2_construct def IsReadyToCompute(self, theSubObject): @@ -886,7 +1062,7 @@ class Mesh: ## Returns errors of hypotheses definition. # The list of errors is empty if everything is OK. - # @param theSubObject a subshape of a mesh shape + # @param theSubObject a sub-shape of a mesh shape # @return a list of errors # @ingroup l2_construct def GetAlgoState(self, theSubObject): @@ -917,163 +1093,27 @@ class Mesh: return 0; pass - ## Creates a segment discretization 1D algorithm. - # If the optional \a algo parameter is not set, this algorithm is REGULAR. - # \n If the optional \a geom parameter is not set, this algorithm is global. - # Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param algo the type of the required algorithm. Possible values are: - # - smesh.REGULAR, - # - smesh.PYTHON for discretization via a python function, - # - smesh.COMPOSITE for meshing a set of edges on one face side as a whole. - # @param geom If defined is the subshape to be meshed - # @return an instance of Mesh_Segment or Mesh_Segment_Python, or Mesh_CompositeSegment class - # @ingroup l3_algos_basic - def Segment(self, algo=REGULAR, geom=0): - ## if Segment(geom) is called by mistake - if isinstance( algo, geompyDC.GEOM._objref_GEOM_Object): - algo, geom = geom, algo - if not algo: algo = REGULAR - pass - if algo == REGULAR: - 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) - - ## Enables creation of nodes and segments usable by 2D algoritms. - # The added nodes and segments must be bound to edges and vertices by - # SetNodeOnVertex(), SetNodeOnEdge() and SetMeshElementOnShape() - # If the optional \a geom parameter is not set, this algorithm is global. - # \n Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param geom the subshape to be manually meshed - # @return StdMeshers_UseExisting_1D algorithm that generates nothing - # @ingroup l3_algos_basic - def UseExistingSegments(self, geom=0): - algo = Mesh_UseExisting(1,self,geom) - return algo.GetAlgorithm() - - ## Enables creation of nodes and faces usable by 3D algoritms. - # The added nodes and faces must be bound to geom faces by SetNodeOnFace() - # and SetMeshElementOnShape() - # If the optional \a geom parameter is not set, this algorithm is global. - # \n Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param geom the subshape to be manually meshed - # @return StdMeshers_UseExisting_2D algorithm that generates nothing - # @ingroup l3_algos_basic - def UseExistingFaces(self, geom=0): - algo = Mesh_UseExisting(2,self,geom) - return algo.GetAlgorithm() - - ## Creates a triangle 2D algorithm for faces. - # If the optional \a geom parameter is not set, this algorithm is global. - # \n Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param algo values are: smesh.MEFISTO || smesh.NETGEN_1D2D || smesh.NETGEN_2D || smesh.BLSURF - # @param geom If defined, the subshape to be meshed (GEOM_Object) - # @return an instance of Mesh_Triangle algorithm - # @ingroup l3_algos_basic - def Triangle(self, algo=MEFISTO, geom=0): - ## if Triangle(geom) is called by mistake - if (isinstance(algo, geompyDC.GEOM._objref_GEOM_Object)): - geom = algo - algo = MEFISTO - - return Mesh_Triangle(self, algo, geom) - - ## Creates a quadrangle 2D algorithm for faces. - # If the optional \a geom parameter is not set, this algorithm is global. - # \n Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param geom If defined, the subshape to be meshed (GEOM_Object) - # @return an instance of Mesh_Quadrangle algorithm - # @ingroup l3_algos_basic - def Quadrangle(self, geom=0): - return Mesh_Quadrangle(self, geom) - - ## Creates a tetrahedron 3D algorithm for solids. - # The parameter \a algo permits to choose the algorithm: NETGEN or GHS3D - # If the optional \a geom parameter is not set, this algorithm is global. - # \n Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param algo values are: smesh.NETGEN, smesh.GHS3D, smesh.GHS3DPRL, smesh.FULL_NETGEN - # @param geom If defined, the subshape to be meshed (GEOM_Object) - # @return an instance of Mesh_Tetrahedron algorithm - # @ingroup l3_algos_basic - def Tetrahedron(self, algo=NETGEN, geom=0): - ## if Tetrahedron(geom) is called by mistake - if ( isinstance( algo, geompyDC.GEOM._objref_GEOM_Object)): - algo, geom = geom, algo - if not algo: algo = NETGEN - pass - return Mesh_Tetrahedron(self, algo, geom) - - ## Creates a hexahedron 3D algorithm for solids. - # If the optional \a geom parameter is not set, this algorithm is global. - # \n Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param algo possible values are: smesh.Hexa, smesh.Hexotic - # @param geom If defined, the subshape to be meshed (GEOM_Object) - # @return an instance of Mesh_Hexahedron algorithm - # @ingroup l3_algos_basic - def Hexahedron(self, algo=Hexa, geom=0): - ## if Hexahedron(geom, algo) or Hexahedron(geom) is called by mistake - if ( isinstance(algo, geompyDC.GEOM._objref_GEOM_Object) ): - if geom in [Hexa, Hexotic]: algo, geom = geom, algo - elif geom == 0: algo, geom = Hexa, algo - return Mesh_Hexahedron(self, algo, geom) - - ## Deprecated, used only for compatibility! - # @return an instance of Mesh_Netgen algorithm - # @ingroup l3_algos_basic - def Netgen(self, is3D, geom=0): - return Mesh_Netgen(self, is3D, geom) - - ## Creates a projection 1D algorithm for edges. - # If the optional \a geom parameter is not set, this algorithm is global. - # Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param geom If defined, the subshape to be meshed - # @return an instance of Mesh_Projection1D algorithm - # @ingroup l3_algos_proj - def Projection1D(self, geom=0): - return Mesh_Projection1D(self, geom) - - ## Creates a projection 2D algorithm for faces. - # If the optional \a geom parameter is not set, this algorithm is global. - # Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param geom If defined, the subshape to be meshed - # @return an instance of Mesh_Projection2D algorithm - # @ingroup l3_algos_proj - def Projection2D(self, geom=0): - return Mesh_Projection2D(self, geom) - - ## Creates a projection 3D algorithm for solids. - # If the optional \a geom parameter is not set, this algorithm is global. - # Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param geom If defined, the subshape to be meshed - # @return an instance of Mesh_Projection3D algorithm - # @ingroup l3_algos_proj - def Projection3D(self, geom=0): - return Mesh_Projection3D(self, geom) - - ## Creates a 3D extrusion (Prism 3D) or RadialPrism 3D algorithm for solids. - # If the optional \a geom parameter is not set, this algorithm is global. - # Otherwise, this algorithm defines a submesh based on \a geom subshape. - # @param geom If defined, the subshape to be meshed - # @return an instance of Mesh_Prism3D or Mesh_RadialPrism3D algorithm - # @ingroup l3_algos_radialp l3_algos_3dextr - def Prism(self, geom=0): - shape = geom - if shape==0: - shape = self.geom - nbSolids = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SOLID"] )) - nbShells = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SHELL"] )) - if nbSolids == 0 or nbSolids == nbShells: - return Mesh_Prism3D(self, geom) - return Mesh_RadialPrism3D(self, geom) + ## Evaluates size of prospective mesh on a shape + # @return a list where i-th element is a number of elements of i-th SMESH.EntityType + # To know predicted number of e.g. edges, inquire it this way + # Evaluate()[ EnumToLong( Entity_Edge )] + def Evaluate(self, geom=0): + if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object): + if self.geom == 0: + geom = self.mesh.GetShapeToMesh() + else: + geom = self.geom + return self.smeshpyD.Evaluate(self.mesh, geom) + ## Computes the mesh and returns the status of the computation + # @param geom geomtrical shape on which mesh data should be computed + # @param discardModifs if True and the mesh has been edited since + # a last total re-compute and that may prevent successful partial re-compute, + # then the mesh is cleaned before Compute() # @return True or False # @ingroup l2_construct - def Compute(self, geom=0): + def Compute(self, geom=0, discardModifs=False): if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object): if self.geom == 0: geom = self.mesh.GetShapeToMesh() @@ -1081,6 +1121,8 @@ class Mesh: geom = self.geom ok = False try: + if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693 + self.mesh.Clear() ok = self.smeshpyD.Compute(self.mesh, geom) except SALOME.SALOME_Exception, ex: print "Mesh computation failed, exception caught:" @@ -1090,8 +1132,64 @@ class Mesh: print "Mesh computation failed, exception caught:" traceback.print_exc() if True:#not ok: - errors = self.smeshpyD.GetAlgoState( self.mesh, geom ) allReasons = "" + + # Treat compute errors + computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom ) + for err in computeErrors: + shapeText = "" + if self.mesh.HasShapeToMesh(): + try: + mainIOR = salome.orb.object_to_string(geom) + for sname in salome.myStudyManager.GetOpenStudies(): + s = salome.myStudyManager.GetStudyByName(sname) + if not s: continue + mainSO = s.FindObjectIOR(mainIOR) + if not mainSO: continue + if err.subShapeID == 1: + shapeText = ' on "%s"' % mainSO.GetName() + subIt = s.NewChildIterator(mainSO) + while subIt.More(): + subSO = subIt.Value() + subIt.Next() + obj = subSO.GetObject() + if not obj: continue + go = obj._narrow( geompyDC.GEOM._objref_GEOM_Object ) + if not go: continue + ids = go.GetSubShapeIndices() + if len(ids) == 1 and ids[0] == err.subShapeID: + shapeText = ' on "%s"' % subSO.GetName() + break + if not shapeText: + shape = self.geompyD.GetSubShape( geom, [err.subShapeID]) + if shape: + shapeText = " on %s #%s" % (shape.GetShapeType(), err.subShapeID) + else: + shapeText = " on subshape #%s" % (err.subShapeID) + except: + shapeText = " on subshape #%s" % (err.subShapeID) + errText = "" + stdErrors = ["OK", #COMPERR_OK + "Invalid input mesh", #COMPERR_BAD_INPUT_MESH + "std::exception", #COMPERR_STD_EXCEPTION + "OCC exception", #COMPERR_OCC_EXCEPTION + "SALOME exception", #COMPERR_SLM_EXCEPTION + "Unknown exception", #COMPERR_EXCEPTION + "Memory allocation problem", #COMPERR_MEMORY_PB + "Algorithm failed", #COMPERR_ALGO_FAILED + "Unexpected geometry"]#COMPERR_BAD_SHAPE + if err.code > 0: + if err.code < len(stdErrors): errText = stdErrors[err.code] + else: + errText = "code %s" % -err.code + if errText: errText += ". " + errText += err.comment + if allReasons != "":allReasons += "\n" + allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText) + pass + + # Treat hyp errors + errors = self.smeshpyD.GetAlgoState( self.mesh, geom ) for err in errors: if err.isGlobalAlgo: glob = "global" @@ -1117,34 +1215,45 @@ class Mesh: reason = "For unknown reason."+\ " Revise Mesh.Compute() implementation in smeshDC.py!" pass - if allReasons != "": - allReasons += "\n" - pass - allReasons += reason + if allReasons != "":allReasons += "\n" + allReasons += "- " + reason pass - if allReasons != "": - print '"' + GetName(self.mesh) + '"',"has not been computed:" + if not ok or allReasons != "": + msg = '"' + GetName(self.mesh) + '"' + if ok: msg += " has been computed with warnings" + else: msg += " has not been computed" + if allReasons != "": msg += ":" + else: msg += "." + print msg print allReasons - ok = False - elif not ok: - print '"' + GetName(self.mesh) + '"',"has not been computed." - pass pass - if salome.sg.hasDesktop(): + if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0: smeshgui = salome.ImportComponentGUI("SMESH") - smeshgui.Init(salome.myStudyId) + smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) ) salome.sg.updateObjBrowser(1) pass return ok + ## Return submesh objects list in meshing order + # @return list of list of submesh objects + # @ingroup l2_construct + def GetMeshOrder(self): + return self.mesh.GetMeshOrder() + + ## Return submesh objects list in meshing order + # @return list of list of submesh objects + # @ingroup l2_construct + def SetMeshOrder(self, submeshes): + return self.mesh.SetMeshOrder(submeshes) + ## Removes all nodes and elements # @ingroup l2_construct def Clear(self): self.mesh.Clear() if salome.sg.hasDesktop(): smeshgui = salome.ImportComponentGUI("SMESH") - smeshgui.Init(salome.myStudyId) + smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True ) salome.sg.updateObjBrowser(1) @@ -1154,12 +1263,12 @@ class Mesh: self.mesh.ClearSubMesh(geomId) if salome.sg.hasDesktop(): smeshgui = salome.ImportComponentGUI("SMESH") - smeshgui.Init(salome.myStudyId) + smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True ) salome.sg.updateObjBrowser(1) ## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN - # @param fineness [0,-1] defines mesh fineness + # @param fineness [0.0,1.0] defines mesh fineness # @return True or False # @ingroup l3_algos_basic def AutomaticTetrahedralization(self, fineness=0): @@ -1171,12 +1280,13 @@ class Mesh: self.Triangle().LengthFromEdges() pass if dim > 2 : + from NETGENPluginDC import NETGEN self.Tetrahedron(NETGEN) pass return self.Compute() ## Computes an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron - # @param fineness [0,-1] defines mesh fineness + # @param fineness [0.0, 1.0] defines mesh fineness # @return True or False # @ingroup l3_algos_basic def AutomaticHexahedralization(self, fineness=0): @@ -1206,14 +1316,36 @@ class Mesh: if not geom: geom = self.mesh.GetShapeToMesh() pass + AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName()) status = self.mesh.AddHypothesis(geom, hyp) isAlgo = hyp._narrow( SMESH_Algo ) - TreatHypoStatus( status, GetName( hyp ), GetName( geom ), isAlgo ) + hyp_name = GetName( hyp ) + geom_name = "" + if geom: + geom_name = GetName( geom ) + TreatHypoStatus( status, hyp_name, geom_name, isAlgo ) return status + ## Return True if an algorithm of hypothesis is assigned to a given shape + # @param hyp a hypothesis to check + # @param geom a subhape of mesh geometry + # @return True of False + # @ingroup l2_hypotheses + def IsUsedHypothesis(self, hyp, geom): + if not hyp or not geom: + return False + if isinstance( hyp, Mesh_Algorithm ): + hyp = hyp.GetAlgorithm() + pass + hyps = self.GetHypothesisList(geom) + for h in hyps: + if h.GetId() == hyp.GetId(): + return True + return False + ## Unassigns a hypothesis # @param hyp a hypothesis to unassign - # @param geom a subshape of mesh geometry + # @param geom a sub-shape of mesh geometry # @return SMESH.Hypothesis_Status # @ingroup l2_hypotheses def RemoveHypothesis(self, hyp, geom=0): @@ -1227,7 +1359,7 @@ class Mesh: return status ## Gets the list of hypotheses added on a geometry - # @param geom a subshape of mesh geometry + # @param geom a sub-shape of mesh geometry # @return the sequence of SMESH_Hypothesis # @ingroup l2_hypotheses def GetHypothesisList(self, geom): @@ -1242,54 +1374,95 @@ class Mesh: pass pass - ## Creates a mesh group based on the geometric object \a grp - # and gives a \a name, \n if this parameter is not defined - # the name is the same as the geometric group name \n - # Note: Works like GroupOnGeom(). - # @param grp a geometric group, a vertex, an edge, a face or a solid - # @param name the name of the mesh group - # @return SMESH_GroupOnGeom - # @ingroup l2_grps_create - def Group(self, grp, name=""): - return self.GroupOnGeom(grp, name) - - ## Deprecated, used only for compatibility! Please, use ExportMED() method instead. - # Exports the mesh in a file in MED format and chooses the \a version of MED format - # @param f the file name - # @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2 + ## Exports the mesh in a file in MED format and chooses the \a version of MED format + ## allowing to overwrite the file if it exists or add the exported data to its contents + # @param f is the file name + # @param auto_groups boolean parameter for creating/not creating + # the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; + # the typical use is auto_groups=false. + # @param version MED format version(MED_V2_1 or MED_V2_2) + # @param overwrite boolean parameter for overwriting/not overwriting the file + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportToMED(self, f, version, opt=0): - self.mesh.ExportToMED(f, opt, version) + def ExportMED(self, f, auto_groups=0, version=MED_V2_2, overwrite=1, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite ) + else: + self.mesh.ExportToMEDX(f, auto_groups, version, overwrite) - ## Exports the mesh in a file in MED format + ## Exports the mesh in a file in SAUV format # @param f is the file name # @param auto_groups boolean parameter for creating/not creating # the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; # the typical use is auto_groups=false. - # @param version MED format version(MED_V2_1 or MED_V2_2) # @ingroup l2_impexp - def ExportMED(self, f, auto_groups=0, version=MED_V2_2): - self.mesh.ExportToMED(f, auto_groups, version) + def ExportSAUV(self, f, auto_groups=0): + self.mesh.ExportSAUV(f, auto_groups) ## Exports the mesh in a file in DAT format # @param f the file name + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportDAT(self, f): - self.mesh.ExportDAT(f) + def ExportDAT(self, f, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToDAT( meshPart, f ) + else: + self.mesh.ExportDAT(f) ## Exports the mesh in a file in UNV format # @param f the file name + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportUNV(self, f): - self.mesh.ExportUNV(f) + def ExportUNV(self, f, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToUNV( meshPart, f ) + else: + self.mesh.ExportUNV(f) ## Export the mesh in a file in STL format # @param f the file name # @param ascii defines the file encoding + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp - def ExportSTL(self, f, ascii=1): - self.mesh.ExportSTL(f, ascii) + def ExportSTL(self, f, ascii=1, meshPart=None): + if meshPart: + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + self.mesh.ExportPartToSTL( meshPart, f, ascii ) + else: + self.mesh.ExportSTL(f, ascii) + ## Exports the mesh in a file in CGNS format + # @param f is the file name + # @param overwrite boolean parameter for overwriting/not overwriting the file + # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh + # @ingroup l2_impexp + def ExportCGNS(self, f, overwrite=1, meshPart=None): + if isinstance( meshPart, list ): + meshPart = self.GetIDSource( meshPart, SMESH.ALL ) + if isinstance( meshPart, Mesh ): + meshPart = meshPart.mesh + elif not meshPart: + meshPart = self.mesh + self.mesh.ExportCGNS(meshPart, f, overwrite) + + ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead. + # Exports the mesh in a file in MED format and chooses the \a version of MED format + ## allowing to overwrite the file if it exists or add the exported data to its contents + # @param f the file name + # @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2 + # @param opt boolean parameter for creating/not creating + # the groups Group_On_All_Nodes, Group_On_All_Faces, ... + # @param overwrite boolean parameter for overwriting/not overwriting the file + # @ingroup l2_impexp + def ExportToMED(self, f, version, opt=0, overwrite=1): + self.mesh.ExportToMEDX(f, opt, version, overwrite) # Operations with groups: # ---------------------- @@ -1302,6 +1475,17 @@ class Mesh: def CreateEmptyGroup(self, elementType, name): return self.mesh.CreateGroup(elementType, name) + ## Creates a mesh group based on the geometric object \a grp + # and gives a \a name, \n if this parameter is not defined + # the name is the same as the geometric group name \n + # Note: Works like GroupOnGeom(). + # @param grp a geometric group, a vertex, an edge, a face or a solid + # @param name the name of the mesh group + # @return SMESH_GroupOnGeom + # @ingroup l2_grps_create + def Group(self, grp, name=""): + return self.GroupOnGeom(grp, name) + ## Creates a mesh group based on the geometrical object \a grp # and gives a \a name, \n if this parameter is not defined # the name is the same as the geometrical group name @@ -1312,40 +1496,44 @@ class Mesh: # @return SMESH_GroupOnGeom # @ingroup l2_grps_create def GroupOnGeom(self, grp, name="", typ=None): + AssureGeomPublished( self, grp, name ) if name == "": name = grp.GetName() - - if typ == None: - tgeo = str(grp.GetShapeType()) - if tgeo == "VERTEX": - typ = NODE - elif tgeo == "EDGE": - typ = EDGE - elif tgeo == "FACE": - typ = FACE - elif tgeo == "SOLID": - typ = VOLUME - elif tgeo == "SHELL": - typ = VOLUME - elif tgeo == "COMPOUND": - if len( self.geompyD.GetObjectIDs( grp )) == 0: - print "Mesh.Group: empty geometric group", GetName( grp ) - return 0 - tgeo = self.geompyD.GetType(grp) - if tgeo == geompyDC.ShapeType["VERTEX"]: - typ = NODE - elif tgeo == geompyDC.ShapeType["EDGE"]: - typ = EDGE - elif tgeo == geompyDC.ShapeType["FACE"]: - typ = FACE - elif tgeo == geompyDC.ShapeType["SOLID"]: - typ = VOLUME - - if typ == None: - print "Mesh.Group: bad first argument: expected a group, a vertex, an edge, a face or a solid" - return 0 + if not typ: + typ = self._groupTypeFromShape( grp ) + return self.mesh.CreateGroupFromGEOM(typ, name, grp) + + ## Pivate method to get a type of group on geometry + def _groupTypeFromShape( self, shape ): + tgeo = str(shape.GetShapeType()) + if tgeo == "VERTEX": + typ = NODE + elif tgeo == "EDGE": + typ = EDGE + elif tgeo == "FACE" or tgeo == "SHELL": + typ = FACE + elif tgeo == "SOLID" or tgeo == "COMPSOLID": + typ = VOLUME + elif tgeo == "COMPOUND": + sub = self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SHAPE"]) + if not sub: + raise ValueError,"_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape) + return self._groupTypeFromShape( sub[0] ) else: - return self.mesh.CreateGroupFromGEOM(typ, name, grp) + raise ValueError, \ + "_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape) + return typ + + ## Creates a mesh group with given \a name based on the \a filter which + ## is a special type of group dynamically updating it's contents during + ## mesh modification + # @param typ the type of elements in the group + # @param name the name of the mesh group + # @param filter the filter defining group contents + # @return SMESH_GroupOnFilter + # @ingroup l2_grps_create + def GroupOnFilter(self, typ, name, filter): + return self.mesh.CreateGroupFromFilter(typ, name, filter) ## Creates a mesh group by the given ids of elements # @param groupName the name of the mesh group @@ -1363,8 +1551,10 @@ class Mesh: # @param elementType the type of elements in the group # @param CritType the type of criterion( FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc. ) # @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo} - # @param Treshold the threshold value (range of id ids as string, shape, numeric) + # @param Threshold the threshold value (range of id ids as string, shape, numeric) # @param UnaryOp FT_LogicalNOT or FT_Undefined + # @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface, + # FT_LyingOnGeom, FT_CoplanarFaces criteria # @return SMESH_Group # @ingroup l2_grps_create def MakeGroup(self, @@ -1372,9 +1562,10 @@ class Mesh: elementType, CritType=FT_Undefined, Compare=FT_EqualTo, - Treshold="", - UnaryOp=FT_Undefined): - aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined) + Threshold="", + UnaryOp=FT_Undefined, + Tolerance=1e-07): + aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance) group = self.MakeGroupByCriterion(groupName, aCriterion) return group @@ -1390,6 +1581,7 @@ class Mesh: aCriteria.append(Criterion) aFilter.SetCriteria(aCriteria) group = self.MakeGroupByFilter(groupName, aFilter) + aFilterMgr.UnRegister() return group ## Creates a mesh group by the given criteria (list of criteria) @@ -1402,6 +1594,7 @@ class Mesh: aFilter = aFilterMgr.CreateFilter() aFilter.SetCriteria(theCriteria) group = self.MakeGroupByFilter(groupName, aFilter) + aFilterMgr.UnRegister() return group ## Creates a mesh group by the given filter @@ -1410,29 +1603,11 @@ class Mesh: # @return SMESH_Group # @ingroup l2_grps_create def MakeGroupByFilter(self, groupName, theFilter): - anIds = theFilter.GetElementsId(self.mesh) - anElemType = theFilter.GetElementType() - group = self.MakeGroupByIds(groupName, anElemType, anIds) + group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName) + theFilter.SetMesh( self.mesh ) + group.AddFrom( theFilter ) return group - ## Passes mesh elements through the given filter and return IDs of fitting elements - # @param theFilter SMESH_Filter - # @return a list of ids - # @ingroup l1_controls - def GetIdsFromFilter(self, theFilter): - return theFilter.GetElementsId(self.mesh) - - ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n - # Returns a list of special structures (borders). - # @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes. - # @ingroup l1_controls - def GetFreeBorders(self): - aFilterMgr = self.smeshpyD.CreateFilterManager() - aPredicate = aFilterMgr.CreateFreeEdges() - aPredicate.SetMesh(self.mesh) - aBorders = aPredicate.GetBorders() - return aBorders - ## Removes a group # @ingroup l2_grps_delete def RemoveGroup(self, group): @@ -1472,15 +1647,15 @@ class Mesh: # @ingroup l2_grps_operon def UnionGroups(self, group1, group2, name): return self.mesh.UnionGroups(group1, group2, name) - + ## Produces a union list of groups - # New group is created. All mesh elements that are present in + # New group is created. All mesh elements that are present in # initial groups are added to the new one # @return an instance of SMESH_Group # @ingroup l2_grps_operon def UnionListOfGroups(self, groups, name): return self.mesh.UnionListOfGroups(groups, name) - + ## Prodices an intersection of two groups # A new group is created. All mesh elements that are common # for the two initial groups are added to the new one. @@ -1488,9 +1663,9 @@ class Mesh: # @ingroup l2_grps_operon def IntersectGroups(self, group1, group2, name): return self.mesh.IntersectGroups(group1, group2, name) - + ## Produces an intersection of groups - # New group is created. All mesh elements that are present in all + # New group is created. All mesh elements that are present in all # initial groups simultaneously are added to the new one # @return an instance of SMESH_Group # @ingroup l2_grps_operon @@ -1504,19 +1679,19 @@ class Mesh: # @ingroup l2_grps_operon def CutGroups(self, main_group, tool_group, name): return self.mesh.CutGroups(main_group, tool_group, name) - + ## Produces a cut of groups - # A new group is created. All mesh elements that are present in main groups + # A new group is created. All mesh elements that are present in main groups # but do not present in tool groups are added to the new one # @return an instance of SMESH_Group # @ingroup l2_grps_operon def CutListOfGroups(self, main_groups, tool_groups, name): return self.mesh.CutListOfGroups(main_groups, tool_groups, name) - - ## Produces a group of elements with specified element type using list of existing groups - # A new group is created. System - # 1) extract all nodes on which groups elements are built - # 2) combine all elements of specified dimension laying on these nodes + + ## Produces a group of elements of specified type using list of existing groups + # A new group is created. System + # 1) extracts all nodes on which groups elements are built + # 2) combines all elements of specified dimension laying on these nodes # @return an instance of SMESH_Group # @ingroup l2_grps_operon def CreateDimGroup(self, groups, elem_type, name): @@ -1586,6 +1761,13 @@ class Mesh: def GetMeshEditor(self): return self.mesh.GetMeshEditor() + ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which + # can be passed as argument to a method accepting mesh, group or sub-mesh + # @return an instance of SMESH_IDSource + # @ingroup l1_auxiliary + def GetIDSource(self, ids, elemType): + return self.GetMeshEditor().MakeIDSource(ids, elemType) + ## Gets MED Mesh # @return an instance of SALOME_MED::MESH # @ingroup l1_auxiliary @@ -1596,6 +1778,13 @@ class Mesh: # Get informations about mesh contents: # ------------------------------------ + ## Gets the mesh stattistic + # @return dictionary type element - count of elements + # @ingroup l1_meshinfo + def GetMeshInfo(self, obj = None): + if not obj: obj = self.mesh + return self.smeshpyD.GetMeshInfo(obj) + ## Returns the number of nodes in the mesh # @return an integer value # @ingroup l1_meshinfo @@ -1608,6 +1797,18 @@ class Mesh: def NbElements(self): return self.mesh.NbElements() + ## Returns the number of 0d elements in the mesh + # @return an integer value + # @ingroup l1_meshinfo + def Nb0DElements(self): + return self.mesh.Nb0DElements() + + ## Returns the number of ball discrete elements in the mesh + # @return an integer value + # @ingroup l1_meshinfo + def NbBalls(self): + return self.mesh.NbBalls() + ## Returns the number of edges in the mesh # @return an integer value # @ingroup l1_meshinfo @@ -1664,6 +1865,12 @@ class Mesh: def NbQuadranglesOfOrder(self, elementOrder): return self.mesh.NbQuadranglesOfOrder(elementOrder) + ## Returns the number of biquadratic quadrangles in the mesh + # @return an integer value + # @ingroup l1_meshinfo + def NbBiQuadQuadrangles(self): + return self.mesh.NbBiQuadQuadrangles() + ## Returns the number of polygons in the mesh # @return an integer value # @ingroup l1_meshinfo @@ -1712,6 +1919,12 @@ class Mesh: def NbHexasOfOrder(self, elementOrder): return self.mesh.NbHexasOfOrder(elementOrder) + ## Returns the number of triquadratic hexahedrons in the mesh + # @return an integer value + # @ingroup l1_meshinfo + def NbTriQuadraticHexas(self): + return self.mesh.NbTriQuadraticHexas() + ## Returns the number of pyramids in the mesh # @return an integer value # @ingroup l1_meshinfo @@ -1740,6 +1953,12 @@ class Mesh: def NbPrismsOfOrder(self, elementOrder): return self.mesh.NbPrismsOfOrder(elementOrder) + ## Returns the number of hexagonal prisms in the mesh + # @return an integer value + # @ingroup l1_meshinfo + def NbHexagonalPrisms(self): + return self.mesh.NbHexagonalPrisms() + ## Returns the number of polyhedrons in the mesh # @return an integer value # @ingroup l1_meshinfo @@ -1759,7 +1978,7 @@ class Mesh: return self.mesh.GetElementsId() ## Returns the list of IDs of mesh elements with the given type - # @param elementType the required type of elements + # @param elementType the required type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME) # @return list of integer values # @ingroup l1_meshinfo def GetElementsByType(self, elementType): @@ -1780,9 +1999,15 @@ class Mesh: def GetElementType(self, id, iselem): return self.mesh.GetElementType(id, iselem) + ## Returns the geometric type of mesh element + # @return the value from SMESH::EntityType enumeration + # @ingroup l1_meshinfo + def GetElementGeomType(self, id): + return self.mesh.GetElementGeomType(id) + ## Returns the list of submesh elements IDs - # @param Shape a geom object(subshape) IOR - # Shape must be the subshape of a ShapeToMesh() + # @param Shape a geom object(sub-shape) IOR + # Shape must be the sub-shape of a ShapeToMesh() # @return the list of integer values # @ingroup l1_meshinfo def GetSubMeshElementsId(self, Shape): @@ -1793,22 +2018,22 @@ class Mesh: return self.mesh.GetSubMeshElementsId(ShapeID) ## Returns the list of submesh nodes IDs - # @param Shape a geom object(subshape) IOR - # Shape must be the subshape of a ShapeToMesh() + # @param Shape a geom object(sub-shape) IOR + # Shape must be the sub-shape of a ShapeToMesh() # @param all If true, gives all nodes of submesh elements, otherwise gives only submesh nodes # @return the list of integer values # @ingroup l1_meshinfo def GetSubMeshNodesId(self, Shape, all): if ( isinstance( Shape, geompyDC.GEOM._objref_GEOM_Object)): - ShapeID = Shape.GetSubShapeIndices()[0] + ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape ) else: ShapeID = Shape return self.mesh.GetSubMeshNodesId(ShapeID, all) - ## Returns the list of IDs of submesh elements with the given type - # @param Shape a geom object(subshape) IOR - # Shape must be a subshape of a ShapeToMesh() - # @return the list of integer values + ## Returns type of elements on given shape + # @param Shape a geom object(sub-shape) IOR + # Shape must be a sub-shape of a ShapeToMesh() + # @return element type # @ingroup l1_meshinfo def GetSubMeshElementType(self, Shape): if ( isinstance( Shape, geompyDC.GEOM._objref_GEOM_Object)): @@ -1903,6 +2128,16 @@ class Mesh: def ElemNbFaces(self, id): return self.mesh.ElemNbFaces(id) + ## Returns nodes of given face (counted from zero) for given volumic element. + # @ingroup l1_meshinfo + def GetElemFaceNodes(self,elemId, faceIndex): + return self.mesh.GetElemFaceNodes(elemId, faceIndex) + + ## Returns an element based on all given nodes. + # @ingroup l1_meshinfo + def FindElementByNodes(self,nodes): + return self.mesh.FindElementByNodes(nodes) + ## Returns true if the given element is a polygon # @ingroup l1_meshinfo def IsPoly(self, id): @@ -1913,6 +2148,11 @@ class Mesh: def IsQuadratic(self, id): return self.mesh.IsQuadratic(id) + ## Returns diameter of a ball discrete element or zero in case of an invalid \a id + # @ingroup l1_meshinfo + def GetBallDiameter(self, id): + return self.mesh.GetBallDiameter(id) + ## Returns XYZ coordinates of the barycenter of the given element # \n If there is no element for the given ID - returns an empty list # @return a list of three double values @@ -1920,6 +2160,115 @@ class Mesh: def BaryCenter(self, id): return self.mesh.BaryCenter(id) + ## Passes mesh elements through the given filter and return IDs of fitting elements + # @param theFilter SMESH_Filter + # @return a list of ids + # @ingroup l1_controls + def GetIdsFromFilter(self, theFilter): + theFilter.SetMesh( self.mesh ) + return theFilter.GetIDs() + + ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n + # Returns a list of special structures (borders). + # @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes. + # @ingroup l1_controls + def GetFreeBorders(self): + aFilterMgr = self.smeshpyD.CreateFilterManager() + aPredicate = aFilterMgr.CreateFreeEdges() + aPredicate.SetMesh(self.mesh) + aBorders = aPredicate.GetBorders() + aFilterMgr.UnRegister() + return aBorders + + + # Get mesh measurements information: + # ------------------------------------ + + ## Get minimum distance between two nodes, elements or distance to the origin + # @param id1 first node/element id + # @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed) + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return minimum distance value + # @sa GetMinDistance() + def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False): + aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2) + return aMeasure.value + + ## Get measure structure specifying minimum distance data between two objects + # @param id1 first node/element id + # @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed) + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return Measure structure + # @sa MinDistance() + def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False): + if isElem1: + id1 = self.editor.MakeIDSource([id1], SMESH.FACE) + else: + id1 = self.editor.MakeIDSource([id1], SMESH.NODE) + if id2 != 0: + if isElem2: + id2 = self.editor.MakeIDSource([id2], SMESH.FACE) + else: + id2 = self.editor.MakeIDSource([id2], SMESH.NODE) + pass + else: + id2 = None + + aMeasurements = self.smeshpyD.CreateMeasurements() + aMeasure = aMeasurements.MinDistance(id1, id2) + aMeasurements.UnRegister() + return aMeasure + + ## Get bounding box of the specified object(s) + # @param objects single source object or list of source objects or list of nodes/elements IDs + # @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements, + # @c False specifies that @a objects are nodes + # @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ) + # @sa GetBoundingBox() + def BoundingBox(self, objects=None, isElem=False): + result = self.GetBoundingBox(objects, isElem) + if result is None: + result = (0.0,)*6 + else: + result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ) + return result + + ## Get measure structure specifying bounding box data of the specified object(s) + # @param IDs single source object or list of source objects or list of nodes/elements IDs + # @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements, + # @c False specifies that @a objects are nodes + # @return Measure structure + # @sa BoundingBox() + def GetBoundingBox(self, IDs=None, isElem=False): + if IDs is None: + IDs = [self.mesh] + elif isinstance(IDs, tuple): + IDs = list(IDs) + if not isinstance(IDs, list): + IDs = [IDs] + if len(IDs) > 0 and isinstance(IDs[0], int): + IDs = [IDs] + srclist = [] + for o in IDs: + if isinstance(o, Mesh): + srclist.append(o.mesh) + elif hasattr(o, "_narrow"): + src = o._narrow(SMESH.SMESH_IDSource) + if src: srclist.append(src) + pass + elif isinstance(o, list): + if isElem: + srclist.append(self.editor.MakeIDSource(o, SMESH.FACE)) + else: + srclist.append(self.editor.MakeIDSource(o, SMESH.NODE)) + pass + pass + aMeasurements = self.smeshpyD.CreateMeasurements() + aMeasure = aMeasurements.BoundingBox(srclist) + aMeasurements.UnRegister() + return aMeasure # Mesh edition (SMESH_MeshEditor functionality): # --------------------------------------------- @@ -1938,20 +2287,41 @@ class Mesh: def RemoveNodes(self, IDsOfNodes): return self.editor.RemoveNodes(IDsOfNodes) + ## Removes all orphan (free) nodes from mesh + # @return number of the removed nodes + # @ingroup l2_modif_del + def RemoveOrphanNodes(self): + return self.editor.RemoveOrphanNodes() + ## Add a node to the mesh by coordinates # @return Id of the new node # @ingroup l2_modif_add def AddNode(self, x, y, z): - x,y,z,Parameters = geompyDC.ParseParameters(x,y,z) - self.mesh.SetParameters(Parameters) + x,y,z,Parameters,hasVars = ParseParameters(x,y,z) + if hasVars: self.mesh.SetParameters(Parameters) return self.editor.AddNode( x, y, z) + ## Creates a 0D element on a node with given number. + # @param IDOfNode the ID of node for creation of the element. + # @return the Id of the new 0D element + # @ingroup l2_modif_add + def Add0DElement(self, IDOfNode): + return self.editor.Add0DElement(IDOfNode) + + ## Creates a ball element on a node with given ID. + # @param IDOfNode the ID of node for creation of the element. + # @param diameter the bal diameter. + # @return the Id of the new ball element + # @ingroup l2_modif_add + def AddBall(self, IDOfNode, diameter): + return self.editor.AddBall( IDOfNode, diameter ) + ## Creates a linear or quadratic edge (this is determined # by the number of given nodes). # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description # of MED. \n This description is located by the following link: - # http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3. + # http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3. # @return the Id of the new edge # @ingroup l2_modif_add def AddEdge(self, IDsOfNodes): @@ -1962,7 +2332,7 @@ class Mesh: # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description # of MED. \n This description is located by the following link: - # http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3. + # http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3. # @return the Id of the new face # @ingroup l2_modif_add def AddFace(self, IDsOfNodes): @@ -1980,7 +2350,7 @@ class Mesh: # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description # of MED. \n This description is located by the following link: - # http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3. + # http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3. # @return the Id of the new volumic element # @ingroup l2_modif_add def AddVolume(self, IDsOfNodes): @@ -2099,19 +2469,21 @@ class Mesh: # @return True if succeed else False # @ingroup l2_modif_movenode def MoveNode(self, NodeID, x, y, z): - x,y,z,Parameters = geompyDC.ParseParameters(x,y,z) - self.mesh.SetParameters(Parameters) + x,y,z,Parameters,hasVars = ParseParameters(x,y,z) + if hasVars: self.mesh.SetParameters(Parameters) return self.editor.MoveNode(NodeID, x, y, z) ## Finds the node closest to a point and moves it to a point location # @param x the X coordinate of a point # @param y the Y coordinate of a point # @param z the Z coordinate of a point + # @param NodeID if specified (>0), the node with this ID is moved, + # otherwise, the node closest to point (@a x,@a y,@a z) is moved # @return the ID of a node # @ingroup l2_modif_throughp def MoveClosestNodeToPoint(self, x, y, z, NodeID): - x,y,z,Parameters = geompyDC.ParseParameters(x,y,z) - self.mesh.SetParameters(Parameters) + x,y,z,Parameters,hasVars = ParseParameters(x,y,z) + if hasVars: self.mesh.SetParameters(Parameters) return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID) ## Finds the node closest to a point @@ -2121,8 +2493,31 @@ class Mesh: # @return the ID of a node # @ingroup l2_modif_throughp def FindNodeClosestTo(self, x, y, z): - preview = self.mesh.GetMeshEditPreviewer() - return preview.MoveClosestNodeToPoint(x, y, z, -1) + #preview = self.mesh.GetMeshEditPreviewer() + #return preview.MoveClosestNodeToPoint(x, y, z, -1) + return self.editor.FindNodeClosestTo(x, y, z) + + ## Finds the elements where a point lays IN or ON + # @param x the X coordinate of a point + # @param y the Y coordinate of a point + # @param z the Z coordinate of a point + # @param elementType type of elements to find (SMESH.ALL type + # means elements of any type excluding nodes, discrete and 0D elements) + # @param meshPart a part of mesh (group, sub-mesh) to search within + # @return list of IDs of found elements + # @ingroup l2_modif_throughp + def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None): + if meshPart: + return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType ); + else: + return self.editor.FindElementsByPoint(x, y, z, elementType) + + # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration: + # 0-IN, 1-OUT, 2-ON, 3-UNKNOWN + # TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails. + + def GetPointState(self, x, y, z): + return self.editor.GetPointState(x, y, z) ## Finds the node closest to a point and moves it to a point location # @param x the X coordinate of a point @@ -2169,6 +2564,41 @@ class Mesh: theObject = theObject.GetMesh() return self.editor.ReorientObject(theObject) + ## Reorient faces contained in \a the2DObject. + # @param the2DObject is a mesh, sub-mesh, group or list of IDs of 2D elements + # @param theDirection is a desired direction of normal of \a theFace. + # It can be either a GEOM vector or a list of coordinates [x,y,z]. + # @param theFaceOrPoint defines a face of \a the2DObject whose normal will be + # compared with theDirection. It can be either ID of face or a point + # by which the face will be found. The point can be given as either + # a GEOM vertex or a list of point coordinates. + # @return number of reoriented faces + # @ingroup l2_modif_changori + def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ): + # check the2DObject + if isinstance( the2DObject, Mesh ): + the2DObject = the2DObject.GetMesh() + if isinstance( the2DObject, list ): + the2DObject = self.GetIDSource( the2DObject, SMESH.FACE ) + # check theDirection + if isinstance( theDirection, geompyDC.GEOM._objref_GEOM_Object): + theDirection = self.smeshpyD.GetDirStruct( theDirection ) + if isinstance( theDirection, list ): + theDirection = self.smeshpyD.MakeDirStruct( *theDirection ) + # prepare theFace and thePoint + theFace = theFaceOrPoint + thePoint = PointStruct(0,0,0) + if isinstance( theFaceOrPoint, geompyDC.GEOM._objref_GEOM_Object): + thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint ) + theFace = -1 + if isinstance( theFaceOrPoint, list ): + thePoint = PointStruct( *theFaceOrPoint ) + theFace = -1 + if isinstance( theFaceOrPoint, PointStruct ): + thePoint = theFaceOrPoint + theFace = -1 + return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint ) + ## Fuses the neighbouring triangles into quadrangles. # @param IDsOfElements The triangles to be fused, # @param theCriterion is FT_...; used to choose a neighbour to fuse with. @@ -2181,14 +2611,12 @@ class Mesh: flag = False if isinstance(MaxAngle,str): flag = True - MaxAngle,Parameters = geompyDC.ParseParameters(MaxAngle) - if flag: - MaxAngle = DegreesToRadians(MaxAngle) - if IDsOfElements == []: - IDsOfElements = self.GetElementsId() + MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle) self.mesh.SetParameters(Parameters) + if not IDsOfElements: + IDsOfElements = self.GetElementsId() Functor = 0 - if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ): + if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ): Functor = theCriterion else: Functor = self.smeshpyD.GetFunctor(theCriterion) @@ -2202,6 +2630,8 @@ class Mesh: # @return TRUE in case of success, FALSE otherwise. # @ingroup l2_modif_unitetri def TriToQuadObject (self, theObject, theCriterion, MaxAngle): + MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle) + self.mesh.SetParameters(Parameters) if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() return self.editor.TriToQuadObject(theObject, self.smeshpyD.GetFunctor(theCriterion), MaxAngle) @@ -2255,6 +2685,18 @@ class Mesh: def BestSplit (self, IDOfQuad, theCriterion): return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion)) + ## Splits volumic elements into tetrahedrons + # @param elemIDs either list of elements or mesh or group or submesh + # @param method flags passing splitting method: Hex_5Tet, Hex_6Tet, Hex_24Tet + # Hex_5Tet - split the hexahedron into 5 tetrahedrons, etc + # @ingroup l2_modif_cutquadr + def SplitVolumesIntoTetra(self, elemIDs, method=Hex_5Tet ): + if isinstance( elemIDs, Mesh ): + elemIDs = elemIDs.GetMesh() + if ( isinstance( elemIDs, list )): + elemIDs = self.editor.MakeIDSource(elemIDs, SMESH.VOLUME) + self.editor.SplitVolumesIntoTetra(elemIDs, method) + ## Splits quadrangle faces near triangular facets of volumes # # @ingroup l1_auxiliary @@ -2410,7 +2852,7 @@ class Mesh: MaxNbOfIterations, MaxAspectRatio, Method): if IDsOfElements == []: IDsOfElements = self.GetElementsId() - MaxNbOfIterations,MaxAspectRatio,Parameters = geompyDC.ParseParameters(MaxNbOfIterations,MaxAspectRatio) + MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio) self.mesh.SetParameters(Parameters) return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method) @@ -2444,7 +2886,7 @@ class Mesh: MaxNbOfIterations, MaxAspectRatio, Method): if IDsOfElements == []: IDsOfElements = self.GetElementsId() - MaxNbOfIterations,MaxAspectRatio,Parameters = geompyDC.ParseParameters(MaxNbOfIterations,MaxAspectRatio) + MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio) self.mesh.SetParameters(Parameters) return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method) @@ -2467,17 +2909,86 @@ class Mesh: ## Converts the mesh to quadratic, deletes old elements, replacing # them with quadratic with the same id. + # @param theForce3d new node creation method: + # 0 - the medium node lies at the geometrical entity from which the mesh element is built + # 1 - the medium node lies at the middle of the line segments connecting start and end node of a mesh element + # @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal # @ingroup l2_modif_tofromqu - def ConvertToQuadratic(self, theForce3d): - self.editor.ConvertToQuadratic(theForce3d) + def ConvertToQuadratic(self, theForce3d, theSubMesh=None): + if theSubMesh: + self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh) + else: + self.editor.ConvertToQuadratic(theForce3d) ## Converts the mesh from quadratic to ordinary, # deletes old quadratic elements, \n replacing # them with ordinary mesh elements with the same id. - # @return TRUE in case of success, FALSE otherwise. + # @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal # @ingroup l2_modif_tofromqu - def ConvertFromQuadratic(self): - return self.editor.ConvertFromQuadratic() + def ConvertFromQuadratic(self, theSubMesh=None): + if theSubMesh: + self.editor.ConvertFromQuadraticObject(theSubMesh) + else: + return self.editor.ConvertFromQuadratic() + + ## Creates 2D mesh as skin on boundary faces of a 3D mesh + # @return TRUE if operation has been completed successfully, FALSE otherwise + # @ingroup l2_modif_edit + def Make2DMeshFrom3D(self): + return self.editor. Make2DMeshFrom3D() + + ## Creates missing boundary elements + # @param elements - elements whose boundary is to be checked: + # mesh, group, sub-mesh or list of elements + # if elements is mesh, it must be the mesh whose MakeBoundaryMesh() is called + # @param dimension - defines type of boundary elements to create: + # SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D + # SMESH.BND_1DFROM3D creates mesh edges on all borders of free facets of 3D cells + # @param groupName - a name of group to store created boundary elements in, + # "" means not to create the group + # @param meshName - a name of new mesh to store created boundary elements in, + # "" means not to create the new mesh + # @param toCopyElements - if true, the checked elements will be copied into + # the new mesh else only boundary elements will be copied into the new mesh + # @param toCopyExistingBondary - if true, not only new but also pre-existing + # boundary elements will be copied into the new mesh + # @return tuple (mesh, group) where bondary elements were added to + # @ingroup l2_modif_edit + def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="", + toCopyElements=False, toCopyExistingBondary=False): + if isinstance( elements, Mesh ): + elements = elements.GetMesh() + if ( isinstance( elements, list )): + elemType = SMESH.ALL + if elements: elemType = self.GetElementType( elements[0], iselem=True) + elements = self.editor.MakeIDSource(elements, elemType) + mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName, + toCopyElements,toCopyExistingBondary) + if mesh: mesh = self.smeshpyD.Mesh(mesh) + return mesh, group + + ## + # @brief Creates missing boundary elements around either the whole mesh or + # groups of 2D elements + # @param dimension - defines type of boundary elements to create + # @param groupName - a name of group to store all boundary elements in, + # "" means not to create the group + # @param meshName - a name of a new mesh, which is a copy of the initial + # mesh + created boundary elements; "" means not to create the new mesh + # @param toCopyAll - if true, the whole initial mesh will be copied into + # the new mesh else only boundary elements will be copied into the new mesh + # @param groups - groups of 2D elements to make boundary around + # @retval tuple( long, mesh, groups ) + # long - number of added boundary elements + # mesh - the mesh where elements were added to + # group - the group of boundary elements or None + # + def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="", + toCopyAll=False, groups=[]): + nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName, + toCopyAll,groups) + if mesh: mesh = self.smeshpyD.Mesh(mesh) + return nb, mesh, group ## Renumber mesh nodes # @ingroup l2_modif_renumber @@ -2502,22 +3013,16 @@ class Mesh: # @ingroup l2_modif_extrurev def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance, MakeGroups=False, TotalAngle=False): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if IDsOfElements == []: IDsOfElements = self.GetElementsId() if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) + AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians) + NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance) + Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters + self.mesh.SetParameters(Parameters) if TotalAngle and NbOfSteps: AngleInRadians /= NbOfSteps - NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance) - Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.RotationSweepMakeGroups(IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance) @@ -2525,7 +3030,8 @@ class Mesh: return [] ## Generates new elements by rotation of the elements of object around the axis - # @param theObject object which elements should be sweeped + # @param theObject object which elements should be sweeped. + # It can be a mesh, a sub mesh or a group. # @param Axis the axis of rotation, AxisStruct or line(geom object) # @param AngleInRadians the angle of Rotation # @param NbOfSteps number of steps @@ -2537,22 +3043,16 @@ class Mesh: # @ingroup l2_modif_extrurev def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance, MakeGroups=False, TotalAngle=False): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) + AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians) + NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance) + Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters + self.mesh.SetParameters(Parameters) if TotalAngle and NbOfSteps: AngleInRadians /= NbOfSteps - NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance) - Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.RotationSweepObjectMakeGroups(theObject, Axis, AngleInRadians, NbOfSteps, Tolerance) @@ -2560,7 +3060,8 @@ class Mesh: return [] ## Generates new elements by rotation of the elements of object around the axis - # @param theObject object which elements should be sweeped + # @param theObject object which elements should be sweeped. + # It can be a mesh, a sub mesh or a group. # @param Axis the axis of rotation, AxisStruct or line(geom object) # @param AngleInRadians the angle of Rotation # @param NbOfSteps number of steps @@ -2572,22 +3073,16 @@ class Mesh: # @ingroup l2_modif_extrurev def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance, MakeGroups=False, TotalAngle=False): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) + AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians) + NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance) + Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters + self.mesh.SetParameters(Parameters) if TotalAngle and NbOfSteps: AngleInRadians /= NbOfSteps - NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance) - Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.RotationSweepObject1DMakeGroups(theObject, Axis, AngleInRadians, NbOfSteps, Tolerance) @@ -2595,7 +3090,8 @@ class Mesh: return [] ## Generates new elements by rotation of the elements of object around the axis - # @param theObject object which elements should be sweeped + # @param theObject object which elements should be sweeped. + # It can be a mesh, a sub mesh or a group. # @param Axis the axis of rotation, AxisStruct or line(geom object) # @param AngleInRadians the angle of Rotation # @param NbOfSteps number of steps @@ -2607,22 +3103,16 @@ class Mesh: # @ingroup l2_modif_extrurev def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance, MakeGroups=False, TotalAngle=False): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) + AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians) + NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance) + Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters + self.mesh.SetParameters(Parameters) if TotalAngle and NbOfSteps: AngleInRadians /= NbOfSteps - NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance) - Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.RotationSweepObject2DMakeGroups(theObject, Axis, AngleInRadians, NbOfSteps, Tolerance) @@ -2631,23 +3121,29 @@ class Mesh: ## Generates new elements by extrusion of the elements with given ids # @param IDsOfElements the list of elements ids for extrusion - # @param StepVector vector, defining the direction and value of extrusion + # @param StepVector vector or DirStruct, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones + # @param IsNodes is True if elements with given ids are nodes # @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise # @ingroup l2_modif_extrurev - def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False): + def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False): if IDsOfElements == []: IDsOfElements = self.GetElementsId() if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) - StepVector,StepVectorParameters = ParseDirStruct(StepVector) - NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps) - Parameters = StepVectorParameters + var_separator + Parameters + NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) + Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) if MakeGroups: - return self.editor.ExtrusionSweepMakeGroups(IDsOfElements, StepVector, NbOfSteps) - self.editor.ExtrusionSweep(IDsOfElements, StepVector, NbOfSteps) + if(IsNodes): + return self.editor.ExtrusionSweepMakeGroups0D(IDsOfElements, StepVector, NbOfSteps) + else: + return self.editor.ExtrusionSweepMakeGroups(IDsOfElements, StepVector, NbOfSteps) + if(IsNodes): + self.editor.ExtrusionSweep0D(IDsOfElements, StepVector, NbOfSteps) + else: + self.editor.ExtrusionSweep(IDsOfElements, StepVector, NbOfSteps) return [] ## Generates new elements by extrusion of the elements with given ids @@ -2672,29 +3168,37 @@ class Mesh: return [] ## Generates new elements by extrusion of the elements which belong to the object - # @param theObject the object which elements should be processed - # @param StepVector vector, defining the direction and value of extrusion + # @param theObject the object which elements should be processed. + # It can be a mesh, a sub mesh or a group. + # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones + # @param IsNodes is True if elements which belong to the object are nodes # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise # @ingroup l2_modif_extrurev - def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False): + def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False): if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) - StepVector,StepVectorParameters = ParseDirStruct(StepVector) - NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps) - Parameters = StepVectorParameters + var_separator + Parameters + NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) + Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) if MakeGroups: - return self.editor.ExtrusionSweepObjectMakeGroups(theObject, StepVector, NbOfSteps) - self.editor.ExtrusionSweepObject(theObject, StepVector, NbOfSteps) + if(IsNodes): + return self.editor.ExtrusionSweepObject0DMakeGroups(theObject, StepVector, NbOfSteps) + else: + return self.editor.ExtrusionSweepObjectMakeGroups(theObject, StepVector, NbOfSteps) + if(IsNodes): + self.editor.ExtrusionSweepObject0D(theObject, StepVector, NbOfSteps) + else: + self.editor.ExtrusionSweepObject(theObject, StepVector, NbOfSteps) return [] ## Generates new elements by extrusion of the elements which belong to the object - # @param theObject object which elements should be processed - # @param StepVector vector, defining the direction and value of extrusion + # @param theObject object which elements should be processed. + # It can be a mesh, a sub mesh or a group. + # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups to generate new groups from existing ones # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -2704,9 +3208,8 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) - StepVector,StepVectorParameters = ParseDirStruct(StepVector) - NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps) - Parameters = StepVectorParameters + var_separator + Parameters + NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) + Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.ExtrusionSweepObject1DMakeGroups(theObject, StepVector, NbOfSteps) @@ -2714,8 +3217,9 @@ class Mesh: return [] ## Generates new elements by extrusion of the elements which belong to the object - # @param theObject object which elements should be processed - # @param StepVector vector, defining the direction and value of extrusion + # @param theObject object which elements should be processed. + # It can be a mesh, a sub mesh or a group. + # @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||) # @param NbOfSteps the number of steps # @param MakeGroups forces the generation of new groups from existing ones # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise @@ -2725,15 +3229,63 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)): StepVector = self.smeshpyD.GetDirStruct(StepVector) - StepVector,StepVectorParameters = ParseDirStruct(StepVector) - NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps) - Parameters = StepVectorParameters + var_separator + Parameters + NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps) + Parameters = StepVector.PS.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.ExtrusionSweepObject2DMakeGroups(theObject, StepVector, NbOfSteps) self.editor.ExtrusionSweepObject2D(theObject, StepVector, NbOfSteps) return [] + + + ## Generates new elements by extrusion of the given elements + # The path of extrusion must be a meshed edge. + # @param Base mesh or group, or submesh, or list of ids of elements for extrusion + # @param Path - 1D mesh or 1D sub-mesh, along which proceeds the extrusion + # @param NodeStart the start node from Path. Defines the direction of extrusion + # @param HasAngles allows the shape to be rotated around the path + # to get the resulting mesh in a helical fashion + # @param Angles list of angles in radians + # @param LinearVariation forces the computation of rotation angles as linear + # variation of the given Angles along path steps + # @param HasRefPoint allows using the reference point + # @param RefPoint the point around which the shape is rotated (the mass center of the shape by default). + # The User can specify any point as the Reference Point. + # @param MakeGroups forces the generation of new groups from existing ones + # @param ElemType type of elements for extrusion (if param Base is a mesh) + # @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True, + # only SMESH::Extrusion_Error otherwise + # @ingroup l2_modif_extrurev + def ExtrusionAlongPathX(self, Base, Path, NodeStart, + HasAngles, Angles, LinearVariation, + HasRefPoint, RefPoint, MakeGroups, ElemType): + if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)): + RefPoint = self.smeshpyD.GetPointStruct(RefPoint) + pass + Angles,AnglesParameters,hasVars = ParseAngles(Angles) + Parameters = AnglesParameters + var_separator + RefPoint.parameters + self.mesh.SetParameters(Parameters) + + if (isinstance(Path, Mesh)): Path = Path.GetMesh() + + if isinstance(Base, list): + IDsOfElements = [] + if Base == []: IDsOfElements = self.GetElementsId() + else: IDsOfElements = Base + return self.editor.ExtrusionAlongPathX(IDsOfElements, Path, NodeStart, + HasAngles, Angles, LinearVariation, + HasRefPoint, RefPoint, MakeGroups, ElemType) + else: + if isinstance(Base, Mesh): Base = Base.GetMesh() + if isinstance(Base, SMESH._objref_SMESH_Mesh) or isinstance(Base, SMESH._objref_SMESH_Group) or isinstance(Base, SMESH._objref_SMESH_subMesh): + return self.editor.ExtrusionAlongPathObjX(Base, Path, NodeStart, + HasAngles, Angles, LinearVariation, + HasRefPoint, RefPoint, MakeGroups, ElemType) + else: + raise RuntimeError, "Invalid Base for ExtrusionAlongPathX" + + ## Generates new elements by extrusion of the given elements # The path of extrusion must be a meshed edge. # @param IDsOfElements ids of elements @@ -2742,7 +3294,7 @@ class Mesh: # @param NodeStart the first or the last node on the edge. Defines the direction of extrusion # @param HasAngles allows the shape to be rotated around the path # to get the resulting mesh in a helical fashion - # @param Angles list of angles + # @param Angles list of angles in radians # @param HasRefPoint allows using the reference point # @param RefPoint the point around which the shape is rotated (the mass center of the shape by default). # The User can specify any point as the Reference Point. @@ -2755,8 +3307,6 @@ class Mesh: def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart, HasAngles, Angles, HasRefPoint, RefPoint, MakeGroups=False, LinearVariation=False): - Angles,AnglesParameters = ParseAngles(Angles) - RefPoint,RefPointParameters = ParsePointStruct(RefPoint) if IDsOfElements == []: IDsOfElements = self.GetElementsId() if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)): @@ -2764,11 +3314,12 @@ class Mesh: pass if ( isinstance( PathMesh, Mesh )): PathMesh = PathMesh.GetMesh() + Angles,AnglesParameters,hasVars = ParseAngles(Angles) + Parameters = AnglesParameters + var_separator + RefPoint.parameters + self.mesh.SetParameters(Parameters) if HasAngles and Angles and LinearVariation: Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles ) pass - Parameters = AnglesParameters + var_separator + RefPointParameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.ExtrusionAlongPathMakeGroups(IDsOfElements, PathMesh, PathShape, NodeStart, HasAngles, @@ -2778,7 +3329,8 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # The path of extrusion must be a meshed edge. - # @param theObject the object which elements should be processed + # @param theObject the object which elements should be processed. + # It can be a mesh, a sub mesh or a group. # @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds # @param PathShape shape(edge) defines the sub-mesh for the path # @param NodeStart the first or the last node on the edge. Defines the direction of extrusion @@ -2797,19 +3349,18 @@ class Mesh: def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart, HasAngles, Angles, HasRefPoint, RefPoint, MakeGroups=False, LinearVariation=False): - Angles,AnglesParameters = ParseAngles(Angles) - RefPoint,RefPointParameters = ParsePointStruct(RefPoint) if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)): RefPoint = self.smeshpyD.GetPointStruct(RefPoint) if ( isinstance( PathMesh, Mesh )): PathMesh = PathMesh.GetMesh() + Angles,AnglesParameters,hasVars = ParseAngles(Angles) + Parameters = AnglesParameters + var_separator + RefPoint.parameters + self.mesh.SetParameters(Parameters) if HasAngles and Angles and LinearVariation: Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles ) pass - Parameters = AnglesParameters + var_separator + RefPointParameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.ExtrusionAlongPathObjectMakeGroups(theObject, PathMesh, PathShape, NodeStart, HasAngles, @@ -2820,7 +3371,8 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # The path of extrusion must be a meshed edge. - # @param theObject the object which elements should be processed + # @param theObject the object which elements should be processed. + # It can be a mesh, a sub mesh or a group. # @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds # @param PathShape shape(edge) defines the sub-mesh for the path # @param NodeStart the first or the last node on the edge. Defines the direction of extrusion @@ -2839,19 +3391,18 @@ class Mesh: def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart, HasAngles, Angles, HasRefPoint, RefPoint, MakeGroups=False, LinearVariation=False): - Angles,AnglesParameters = ParseAngles(Angles) - RefPoint,RefPointParameters = ParsePointStruct(RefPoint) if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)): RefPoint = self.smeshpyD.GetPointStruct(RefPoint) if ( isinstance( PathMesh, Mesh )): PathMesh = PathMesh.GetMesh() + Angles,AnglesParameters,hasVars = ParseAngles(Angles) + Parameters = AnglesParameters + var_separator + RefPoint.parameters + self.mesh.SetParameters(Parameters) if HasAngles and Angles and LinearVariation: Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles ) pass - Parameters = AnglesParameters + var_separator + RefPointParameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.ExtrusionAlongPathObject1DMakeGroups(theObject, PathMesh, PathShape, NodeStart, HasAngles, @@ -2862,7 +3413,8 @@ class Mesh: ## Generates new elements by extrusion of the elements which belong to the object # The path of extrusion must be a meshed edge. - # @param theObject the object which elements should be processed + # @param theObject the object which elements should be processed. + # It can be a mesh, a sub mesh or a group. # @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds # @param PathShape shape(edge) defines the sub-mesh for the path # @param NodeStart the first or the last node on the edge. Defines the direction of extrusion @@ -2881,19 +3433,18 @@ class Mesh: def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart, HasAngles, Angles, HasRefPoint, RefPoint, MakeGroups=False, LinearVariation=False): - Angles,AnglesParameters = ParseAngles(Angles) - RefPoint,RefPointParameters = ParsePointStruct(RefPoint) if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)): RefPoint = self.smeshpyD.GetPointStruct(RefPoint) if ( isinstance( PathMesh, Mesh )): PathMesh = PathMesh.GetMesh() + Angles,AnglesParameters,hasVars = ParseAngles(Angles) + Parameters = AnglesParameters + var_separator + RefPoint.parameters + self.mesh.SetParameters(Parameters) if HasAngles and Angles and LinearVariation: Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles ) pass - Parameters = AnglesParameters + var_separator + RefPointParameters - self.mesh.SetParameters(Parameters) if MakeGroups: return self.editor.ExtrusionAlongPathObject2DMakeGroups(theObject, PathMesh, PathShape, NodeStart, HasAngles, @@ -2916,8 +3467,7 @@ class Mesh: IDsOfElements = self.GetElementsId() if ( isinstance( Mirror, geompyDC.GEOM._objref_GEOM_Object)): Mirror = self.smeshpyD.GetAxisStruct(Mirror) - Mirror,Parameters = ParseAxisStruct(Mirror) - self.mesh.SetParameters(Parameters) + self.mesh.SetParameters(Mirror.parameters) if Copy and MakeGroups: return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType) self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy) @@ -2937,10 +3487,9 @@ class Mesh: IDsOfElements = self.GetElementsId() if ( isinstance( Mirror, geompyDC.GEOM._objref_GEOM_Object)): Mirror = self.smeshpyD.GetAxisStruct(Mirror) - Mirror,Parameters = ParseAxisStruct(Mirror) + self.mesh.SetParameters(Mirror.parameters) mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType, MakeGroups, NewMeshName) - mesh.SetParameters(Parameters) return Mesh(self.smeshpyD,self.geompyD,mesh) ## Creates a symmetrical copy of the object @@ -2957,8 +3506,7 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( Mirror, geompyDC.GEOM._objref_GEOM_Object)): Mirror = self.smeshpyD.GetAxisStruct(Mirror) - Mirror,Parameters = ParseAxisStruct(Mirror) - self.mesh.SetParameters(Parameters) + self.mesh.SetParameters(Mirror.parameters) if Copy and MakeGroups: return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType) self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy) @@ -2978,10 +3526,9 @@ class Mesh: theObject = theObject.GetMesh() if (isinstance(Mirror, geompyDC.GEOM._objref_GEOM_Object)): Mirror = self.smeshpyD.GetAxisStruct(Mirror) - Mirror,Parameters = ParseAxisStruct(Mirror) + self.mesh.SetParameters(Mirror.parameters) mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType, MakeGroups, NewMeshName) - mesh.SetParameters(Parameters) return Mesh( self.smeshpyD,self.geompyD,mesh ) ## Translates the elements @@ -2996,8 +3543,7 @@ class Mesh: IDsOfElements = self.GetElementsId() if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)): Vector = self.smeshpyD.GetDirStruct(Vector) - Vector,Parameters = ParseDirStruct(Vector) - self.mesh.SetParameters(Parameters) + self.mesh.SetParameters(Vector.PS.parameters) if Copy and MakeGroups: return self.editor.TranslateMakeGroups(IDsOfElements, Vector) self.editor.Translate(IDsOfElements, Vector, Copy) @@ -3015,9 +3561,8 @@ class Mesh: IDsOfElements = self.GetElementsId() if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)): Vector = self.smeshpyD.GetDirStruct(Vector) - Vector,Parameters = ParseDirStruct(Vector) + self.mesh.SetParameters(Vector.PS.parameters) mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName) - mesh.SetParameters(Parameters) return Mesh ( self.smeshpyD, self.geompyD, mesh ) ## Translates the object @@ -3032,8 +3577,7 @@ class Mesh: theObject = theObject.GetMesh() if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)): Vector = self.smeshpyD.GetDirStruct(Vector) - Vector,Parameters = ParseDirStruct(Vector) - self.mesh.SetParameters(Parameters) + self.mesh.SetParameters(Vector.PS.parameters) if Copy and MakeGroups: return self.editor.TranslateObjectMakeGroups(theObject, Vector) self.editor.TranslateObject(theObject, Vector, Copy) @@ -3051,11 +3595,54 @@ class Mesh: theObject = theObject.GetMesh() if (isinstance(Vector, geompyDC.GEOM._objref_GEOM_Object)): Vector = self.smeshpyD.GetDirStruct(Vector) - Vector,Parameters = ParseDirStruct(Vector) + self.mesh.SetParameters(Vector.PS.parameters) mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName) - mesh.SetParameters(Parameters) return Mesh( self.smeshpyD, self.geompyD, mesh ) + + + ## Scales the object + # @param theObject - the object to translate (mesh, submesh, or group) + # @param thePoint - base point for scale + # @param theScaleFact - list of 1-3 scale factors for axises + # @param Copy - allows copying the translated elements + # @param MakeGroups - forces the generation of new groups from existing + # ones (if Copy) + # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, + # empty list otherwise + def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False): + if ( isinstance( theObject, Mesh )): + theObject = theObject.GetMesh() + if ( isinstance( theObject, list )): + theObject = self.GetIDSource(theObject, SMESH.ALL) + + self.mesh.SetParameters(thePoint.parameters) + + if Copy and MakeGroups: + return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact) + self.editor.Scale(theObject, thePoint, theScaleFact, Copy) + return [] + + ## Creates a new mesh from the translated object + # @param theObject - the object to translate (mesh, submesh, or group) + # @param thePoint - base point for scale + # @param theScaleFact - list of 1-3 scale factors for axises + # @param MakeGroups - forces the generation of new groups from existing ones + # @param NewMeshName - the name of the newly created mesh + # @return instance of Mesh class + def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""): + if (isinstance(theObject, Mesh)): + theObject = theObject.GetMesh() + if ( isinstance( theObject, list )): + theObject = self.GetIDSource(theObject,SMESH.ALL) + + self.mesh.SetParameters(thePoint.parameters) + mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact, + MakeGroups, NewMeshName) + return Mesh( self.smeshpyD, self.geompyD, mesh ) + + + ## Rotates the elements # @param IDsOfElements list of elements ids # @param Axis the axis of rotation (AxisStruct or geom line) @@ -3065,18 +3652,12 @@ class Mesh: # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise # @ingroup l2_modif_trsf def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if IDsOfElements == []: IDsOfElements = self.GetElementsId() if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) - Parameters = AxisParameters + var_separator + Parameters + AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians) + Parameters = Axis.parameters + var_separator + Parameters self.mesh.SetParameters(Parameters) if Copy and MakeGroups: return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians) @@ -3092,21 +3673,15 @@ class Mesh: # @return instance of Mesh class # @ingroup l2_modif_trsf def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if IDsOfElements == []: IDsOfElements = self.GetElementsId() if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) - Parameters = AxisParameters + var_separator + Parameters + AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians) + Parameters = Axis.parameters + var_separator + Parameters + self.mesh.SetParameters(Parameters) mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians, MakeGroups, NewMeshName) - mesh.SetParameters(Parameters) return Mesh( self.smeshpyD, self.geompyD, mesh ) ## Rotates the object @@ -3118,18 +3693,12 @@ class Mesh: # @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise # @ingroup l2_modif_trsf def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if (isinstance(theObject, Mesh)): theObject = theObject.GetMesh() if (isinstance(Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) - Parameters = AxisParameters + ":" + Parameters + AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians) + Parameters = Axis.parameters + ":" + Parameters self.mesh.SetParameters(Parameters) if Copy and MakeGroups: return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians) @@ -3145,21 +3714,15 @@ class Mesh: # @return instance of Mesh class # @ingroup l2_modif_trsf def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""): - flag = False - if isinstance(AngleInRadians,str): - flag = True - AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians) - if flag: - AngleInRadians = DegreesToRadians(AngleInRadians) if (isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if (isinstance(Axis, geompyDC.GEOM._objref_GEOM_Object)): Axis = self.smeshpyD.GetAxisStruct(Axis) - Axis,AxisParameters = ParseAxisStruct(Axis) - Parameters = AxisParameters + ":" + Parameters + AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians) + Parameters = Axis.parameters + ":" + Parameters mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians, MakeGroups, NewMeshName) - mesh.SetParameters(Parameters) + self.mesh.SetParameters(Parameters) return Mesh( self.smeshpyD, self.geompyD, mesh ) ## Finds groups of ajacent nodes within Tolerance. @@ -3172,10 +3735,17 @@ class Mesh: ## Finds groups of ajacent nodes within Tolerance. # @param Tolerance the value of tolerance # @param SubMeshOrGroup SubMesh or Group + # @param exceptNodes list of either SubMeshes, Groups or node IDs to exclude from search # @return the list of groups of nodes # @ingroup l2_modif_trsf - def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance): - return self.editor.FindCoincidentNodesOnPart(SubMeshOrGroup, Tolerance) + def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance, exceptNodes=[]): + if (isinstance( SubMeshOrGroup, Mesh )): + SubMeshOrGroup = SubMeshOrGroup.GetMesh() + if not isinstance( exceptNodes, list): + exceptNodes = [ exceptNodes ] + if exceptNodes and isinstance( exceptNodes[0], int): + exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE)] + return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,exceptNodes) ## Merges nodes # @param GroupsOfNodes the list of groups of nodes @@ -3188,6 +3758,8 @@ class Mesh: # @return a list of groups of equal elements # @ingroup l2_modif_trsf def FindEqualElements (self, MeshOrSubMeshOrGroup): + if ( isinstance( MeshOrSubMeshOrGroup, Mesh )): + MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh() return self.editor.FindEqualElements(MeshOrSubMeshOrGroup) ## Merges elements in each given group. @@ -3265,47 +3837,257 @@ class Mesh: # @ingroup l1_auxiliary def GetLastCreatedElems(self): return self.editor.GetLastCreatedElems() - - ## Creates a hole in a mesh by doubling the nodes of some particular elements + + ## Creates a hole in a mesh by doubling the nodes of some particular elements # @param theNodes identifiers of nodes to be doubled - # @param theModifiedElems identifiers of elements to be updated by the new (doubled) - # nodes. If list of element identifiers is empty then nodes are doubled but + # @param theModifiedElems identifiers of elements to be updated by the new (doubled) + # nodes. If list of element identifiers is empty then nodes are doubled but # they not assigned to elements # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_edit def DoubleNodes(self, theNodes, theModifiedElems): return self.editor.DoubleNodes(theNodes, theModifiedElems) - + ## Creates a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. - # @param theNodes identifiers of node to be doubled + # @param theNodeId identifiers of node to be doubled # @param theModifiedElems identifiers of elements to be updated # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_edit def DoubleNode(self, theNodeId, theModifiedElems): return self.editor.DoubleNode(theNodeId, theModifiedElems) - + ## Creates a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theNodes group of nodes to be doubled # @param theModifiedElems group of elements to be updated. - # @return TRUE if operation has been completed successfully, FALSE otherwise + # @param theMakeGroup forces the generation of a group containing new nodes. + # @return TRUE or a created group if operation has been completed successfully, + # FALSE or None otherwise # @ingroup l2_modif_edit - def DoubleNodeGroup(self, theNodes, theModifiedElems): + def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False): + if theMakeGroup: + return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems) return self.editor.DoubleNodeGroup(theNodes, theModifiedElems) - + ## Creates a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theNodes list of groups of nodes to be doubled # @param theModifiedElems list of groups of elements to be updated. + # @param theMakeGroup forces the generation of a group containing new nodes. # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_edit - def DoubleNodeGroups(self, theNodes, theModifiedElems): + def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False): + if theMakeGroup: + return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems) return self.editor.DoubleNodeGroups(theNodes, theModifiedElems) + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # @param theElems - the list of elements (edges or faces) to be replicated + # The nodes for duplication could be found from these elements + # @param theNodesNot - list of nodes to NOT replicate + # @param theAffectedElems - the list of elements (cells and edges) to which the + # replicated nodes should be associated to. + # @return TRUE if operation has been completed successfully, FALSE otherwise + # @ingroup l2_modif_edit + def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems): + return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # @param theElems - the list of elements (edges or faces) to be replicated + # The nodes for duplication could be found from these elements + # @param theNodesNot - list of nodes to NOT replicate + # @param theShape - shape to detect affected elements (element which geometric center + # located on or inside shape). + # The replicated nodes should be associated to affected elements. + # @return TRUE if operation has been completed successfully, FALSE otherwise + # @ingroup l2_modif_edit + def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape): + return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # This method provided for convenience works as DoubleNodes() described above. + # @param theElems - group of of elements (edges or faces) to be replicated + # @param theNodesNot - group of nodes not to replicated + # @param theAffectedElems - group of elements to which the replicated nodes + # should be associated to. + # @param theMakeGroup forces the generation of a group containing new elements. + # @param theMakeNodeGroup forces the generation of a group containing new nodes. + # @return TRUE or created groups (one or two) if operation has been completed successfully, + # FALSE or None otherwise + # @ingroup l2_modif_edit + def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems, + theMakeGroup=False, theMakeNodeGroup=False): + if theMakeGroup or theMakeNodeGroup: + twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot, + theAffectedElems, + theMakeGroup, theMakeNodeGroup) + if theMakeGroup and theMakeNodeGroup: + return twoGroups + else: + return twoGroups[ int(theMakeNodeGroup) ] + return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # This method provided for convenience works as DoubleNodes() described above. + # @param theElems - group of of elements (edges or faces) to be replicated + # @param theNodesNot - group of nodes not to replicated + # @param theShape - shape to detect affected elements (element which geometric center + # located on or inside shape). + # The replicated nodes should be associated to affected elements. + # @ingroup l2_modif_edit + def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape): + return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # This method provided for convenience works as DoubleNodes() described above. + # @param theElems - list of groups of elements (edges or faces) to be replicated + # @param theNodesNot - list of groups of nodes not to replicated + # @param theAffectedElems - group of elements to which the replicated nodes + # should be associated to. + # @param theMakeGroup forces the generation of a group containing new elements. + # @param theMakeNodeGroup forces the generation of a group containing new nodes. + # @return TRUE or created groups (one or two) if operation has been completed successfully, + # FALSE or None otherwise + # @ingroup l2_modif_edit + def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems, + theMakeGroup=False, theMakeNodeGroup=False): + if theMakeGroup or theMakeNodeGroup: + twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot, + theAffectedElems, + theMakeGroup, theMakeNodeGroup) + if theMakeGroup and theMakeNodeGroup: + return twoGroups + else: + return twoGroups[ int(theMakeNodeGroup) ] + return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # This method provided for convenience works as DoubleNodes() described above. + # @param theElems - list of groups of elements (edges or faces) to be replicated + # @param theNodesNot - list of groups of nodes not to replicated + # @param theShape - shape to detect affected elements (element which geometric center + # located on or inside shape). + # The replicated nodes should be associated to affected elements. + # @return TRUE if operation has been completed successfully, FALSE otherwise + # @ingroup l2_modif_edit + def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape): + return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape) + + ## Double nodes on shared faces between groups of volumes and create flat elements on demand. + # The list of groups must describe a partition of the mesh volumes. + # The nodes of the internal faces at the boundaries of the groups are doubled. + # In option, the internal faces are replaced by flat elements. + # Triangles are transformed in prisms, and quadrangles in hexahedrons. + # @param theDomains - list of groups of volumes + # @param createJointElems - if TRUE, create the elements + # @return TRUE if operation has been completed successfully, FALSE otherwise + def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ): + return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems ) + + ## Double nodes on some external faces and create flat elements. + # Flat elements are mainly used by some types of mechanic calculations. + # + # Each group of the list must be constituted of faces. + # Triangles are transformed in prisms, and quadrangles in hexahedrons. + # @param theGroupsOfFaces - list of groups of faces + # @return TRUE if operation has been completed successfully, FALSE otherwise + def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ): + return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces ) + + def _valueFromFunctor(self, funcType, elemId): + fn = self.smeshpyD.GetFunctor(funcType) + fn.SetMesh(self.mesh) + if fn.GetElementType() == self.GetElementType(elemId, True): + val = fn.GetValue(elemId) + else: + val = 0 + return val + + ## Get length of 1D element. + # @param elemId mesh element ID + # @return element's length value + # @ingroup l1_measurements + def GetLength(self, elemId): + return self._valueFromFunctor(SMESH.FT_Length, elemId) + + ## Get area of 2D element. + # @param elemId mesh element ID + # @return element's area value + # @ingroup l1_measurements + def GetArea(self, elemId): + return self._valueFromFunctor(SMESH.FT_Area, elemId) + + ## Get volume of 3D element. + # @param elemId mesh element ID + # @return element's volume value + # @ingroup l1_measurements + def GetVolume(self, elemId): + return self._valueFromFunctor(SMESH.FT_Volume3D, elemId) + + ## Get maximum element length. + # @param elemId mesh element ID + # @return element's maximum length value + # @ingroup l1_measurements + def GetMaxElementLength(self, elemId): + if self.GetElementType(elemId, True) == SMESH.VOLUME: + ftype = SMESH.FT_MaxElementLength3D + else: + ftype = SMESH.FT_MaxElementLength2D + return self._valueFromFunctor(ftype, elemId) + + ## Get aspect ratio of 2D or 3D element. + # @param elemId mesh element ID + # @return element's aspect ratio value + # @ingroup l1_measurements + def GetAspectRatio(self, elemId): + if self.GetElementType(elemId, True) == SMESH.VOLUME: + ftype = SMESH.FT_AspectRatio3D + else: + ftype = SMESH.FT_AspectRatio + return self._valueFromFunctor(ftype, elemId) + + ## Get warping angle of 2D element. + # @param elemId mesh element ID + # @return element's warping angle value + # @ingroup l1_measurements + def GetWarping(self, elemId): + return self._valueFromFunctor(SMESH.FT_Warping, elemId) + + ## Get minimum angle of 2D element. + # @param elemId mesh element ID + # @return element's minimum angle value + # @ingroup l1_measurements + def GetMinimumAngle(self, elemId): + return self._valueFromFunctor(SMESH.FT_MinimumAngle, elemId) + + ## Get taper of 2D element. + # @param elemId mesh element ID + # @return element's taper value + # @ingroup l1_measurements + def GetTaper(self, elemId): + return self._valueFromFunctor(SMESH.FT_Taper, elemId) + + ## Get skew of 2D element. + # @param elemId mesh element ID + # @return element's skew value + # @ingroup l1_measurements + def GetSkew(self, elemId): + return self._valueFromFunctor(SMESH.FT_Skew, elemId) + ## The mother class to define algorithm, it is not recommended to use it directly. # -# More details. +# For each meshing algorithm, a python class inheriting from class Mesh_Algorithm +# should be defined. This descendant class sould have two attributes defining the way +# it is created by class Mesh (see e.g. class StdMeshersDC_Segment in StdMeshersDC.py). +# - meshMethod attribute defines name of method of class Mesh by calling which the +# python class of algorithm is created. E.g. if in class MyPlugin_Algorithm +# meshMethod = "MyAlgorithm", then an instance of MyPlugin_Algorithm is created +# by the following code: my_algo = mesh.MyAlgorithm() +# - algoType defines name of algorithm type and is used mostly to discriminate +# algorithms that are created by the same method of class Mesh. E.g. if +# MyPlugin_Algorithm.algoType = "MyPLUGIN" then it's creation code can be: +# my_algo = mesh.MyAlgorithm(algo="MyPLUGIN") # @ingroup l2_algorithms class Mesh_Algorithm: # @class Mesh_Algorithm @@ -3366,6 +4148,7 @@ class Mesh_Algorithm: # @return SMESH.SMESH_Algo def FindAlgorithm (self, algoname, smeshpyD): study = smeshpyD.GetCurrentStudy() + if not study: return None #to do: find component by smeshpyD object, not by its data type scomp = study.FindComponent(smeshpyD.ComponentDataType()) if scomp is not None: @@ -3444,20 +4227,22 @@ class Mesh_Algorithm: if geom is None: raise RuntimeError, "Attemp to create " + algo + " algoritm on None shape" self.mesh = mesh - piece = mesh.geom + name = "" if not geom: - self.geom = piece + self.geom = mesh.geom else: self.geom = geom - name = GetName(geom) - if name==NO_NAME: - name = mesh.geompyD.SubShapeName(geom, piece) - mesh.geompyD.addToStudyInFather(piece, geom, name) + AssureGeomPublished( mesh, geom ) + try: + name = GetName(geom) + pass + except: + pass self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName()) - self.algo = algo status = mesh.mesh.AddHypothesis(self.geom, self.algo) - TreatHypoStatus( status, algo.GetName(), GetName(self.geom), True ) + TreatHypoStatus( status, algo.GetName(), name, True ) + return def CompareHyp (self, hyp, args): print "CompareHyp is not implemented for ", self.__class__.__name__, ":", hyp.GetName() @@ -3478,1521 +4263,183 @@ class Mesh_Algorithm: hypo = self.mesh.smeshpyD.CreateHypothesis(hyp, so) a = "" s = "=" - i = 0 - n = len(args) - while i 10: + argStr = argStr[:7]+"..." + if argStr[0] == '[': argStr += ']' + a = a + s + argStr s = "," - i = i + 1 pass + if len(a) > 50: + a = a[:47]+"..." self.mesh.smeshpyD.SetName(hypo, hyp + a) pass + geomName="" + if self.geom: + geomName = GetName(self.geom) status = self.mesh.mesh.AddHypothesis(self.geom, hypo) - TreatHypoStatus( status, GetName(hypo), GetName(self.geom), 0 ) + TreatHypoStatus( status, GetName(hypo), geomName, 0 ) return hypo - -# Public class: Mesh_Segment -# -------------------------- - -## Class to define a segment 1D algorithm for discretization -# -# More details. -# @ingroup l3_algos_basic -class Mesh_Segment(Mesh_Algorithm): - - ## Private constructor. - def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, "Regular_1D") - - ## Defines "LocalLength" hypothesis to cut an edge in several segments with the same length - # @param l for the length of segments that cut an edge - # @param UseExisting if ==true - searches for an existing hypothesis created with - # the same parameters, else (default) - creates a new one - # @param p precision, used for calculation of the number of segments. - # The precision should be a positive, meaningful value within the range [0,1]. - # In general, the number of segments is calculated with the formula: - # nb = ceil((edge_length / l) - p) - # Function ceil rounds its argument to the higher integer. - # So, p=0 means rounding of (edge_length / l) to the higher integer, - # p=0.5 means rounding of (edge_length / l) to the nearest integer, - # p=1 means rounding of (edge_length / l) to the lower integer. - # Default value is 1e-07. - # @return an instance of StdMeshers_LocalLength hypothesis - # @ingroup l3_hypos_1dhyps - def LocalLength(self, l, UseExisting=0, p=1e-07): - hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting, - CompareMethod=self.CompareLocalLength) - hyp.SetLength(l) - hyp.SetPrecision(p) - return hyp - - ## Private method - ## Checks if the given "LocalLength" hypothesis has the same parameters as the given arguments - def CompareLocalLength(self, hyp, args): - if IsEqual(hyp.GetLength(), args[0]): - return IsEqual(hyp.GetPrecision(), args[1]) - return False - - ## Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value - # @param length is optional maximal allowed length of segment, if it is omitted - # the preestimated length is used that depends on geometry size - # @param UseExisting if ==true - searches for an existing hypothesis created with - # the same parameters, else (default) - create a new one - # @return an instance of StdMeshers_MaxLength hypothesis - # @ingroup l3_hypos_1dhyps - def MaxSize(self, length=0.0, UseExisting=0): - hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting) - if length > 0.0: - # set given length - hyp.SetLength(length) - if not UseExisting: - # set preestimated length - gen = self.mesh.smeshpyD - initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so", - self.mesh.GetMesh(), self.mesh.GetShape(), - False) # <- byMesh - preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength) - if preHyp: - hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() ) - pass - pass - hyp.SetUsePreestimatedLength( length == 0.0 ) - return hyp - - ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments - # @param n for the number of segments that cut an edge - # @param s for the scale factor (optional) - # @param UseExisting if ==true - searches for an existing hypothesis created with - # the same parameters, else (default) - create a new one - # @return an instance of StdMeshers_NumberOfSegments hypothesis - # @ingroup l3_hypos_1dhyps - def NumberOfSegments(self, n, s=[], UseExisting=0): - if s == []: - hyp = self.Hypothesis("NumberOfSegments", [n], UseExisting=UseExisting, - CompareMethod=self.CompareNumberOfSegments) - else: - hyp = self.Hypothesis("NumberOfSegments", [n,s], UseExisting=UseExisting, - CompareMethod=self.CompareNumberOfSegments) - hyp.SetDistrType( 1 ) - hyp.SetScaleFactor(s) - hyp.SetNumberOfSegments(n) - return hyp - - ## Private method - ## Checks if the given "NumberOfSegments" hypothesis has the same parameters as the given arguments - def CompareNumberOfSegments(self, hyp, args): - if hyp.GetNumberOfSegments() == args[0]: - if len(args) == 1: - return True - else: - if hyp.GetDistrType() == 1: - if IsEqual(hyp.GetScaleFactor(), args[1]): - return True - return False - - ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length - # @param start defines the length of the first segment - # @param end defines the length of the last segment - # @param UseExisting if ==true - searches for an existing hypothesis created with - # the same parameters, else (default) - creates a new one - # @return an instance of StdMeshers_Arithmetic1D hypothesis - # @ingroup l3_hypos_1dhyps - def Arithmetic1D(self, start, end, UseExisting=0): - hyp = self.Hypothesis("Arithmetic1D", [start, end], UseExisting=UseExisting, - CompareMethod=self.CompareArithmetic1D) - hyp.SetLength(start, 1) - hyp.SetLength(end , 0) - return hyp - - ## Private method - ## Check if the given "Arithmetic1D" hypothesis has the same parameters as the given arguments - def CompareArithmetic1D(self, hyp, args): - if IsEqual(hyp.GetLength(1), args[0]): - if IsEqual(hyp.GetLength(0), args[1]): - return True - return False - - ## Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length - # @param start defines the length of the first segment - # @param end defines the length of the last segment - # @param UseExisting if ==true - searches for an existing hypothesis created with - # the same parameters, else (default) - creates a new one - # @return an instance of StdMeshers_StartEndLength hypothesis - # @ingroup l3_hypos_1dhyps - def StartEndLength(self, start, end, UseExisting=0): - hyp = self.Hypothesis("StartEndLength", [start, end], UseExisting=UseExisting, - CompareMethod=self.CompareStartEndLength) - hyp.SetLength(start, 1) - hyp.SetLength(end , 0) - return hyp - - ## Check if the given "StartEndLength" hypothesis has the same parameters as the given arguments - def CompareStartEndLength(self, hyp, args): - if IsEqual(hyp.GetLength(1), args[0]): - if IsEqual(hyp.GetLength(0), args[1]): - return True - return False - - ## Defines "Deflection1D" hypothesis - # @param d for the deflection - # @param UseExisting if ==true - searches for an existing hypothesis created with - # the same parameters, else (default) - create a new one - # @ingroup l3_hypos_1dhyps - def Deflection1D(self, d, UseExisting=0): - hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting, - CompareMethod=self.CompareDeflection1D) - hyp.SetDeflection(d) - return hyp - - ## Check if the given "Deflection1D" hypothesis has the same parameters as the given arguments - def CompareDeflection1D(self, hyp, args): - return IsEqual(hyp.GetDeflection(), args[0]) - - ## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at - # the opposite side in case of quadrangular faces - # @ingroup l3_hypos_additi - def Propagation(self): - return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp) - - ## Defines "AutomaticLength" hypothesis - # @param fineness for the fineness [0-1] - # @param UseExisting if ==true - searches for an existing hypothesis created with the - # same parameters, else (default) - create a new one - # @ingroup l3_hypos_1dhyps - def AutomaticLength(self, fineness=0, UseExisting=0): - hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting, - CompareMethod=self.CompareAutomaticLength) - hyp.SetFineness( fineness ) - return hyp - - ## Checks if the given "AutomaticLength" hypothesis has the same parameters as the given arguments - def CompareAutomaticLength(self, hyp, args): - return IsEqual(hyp.GetFineness(), args[0]) - - ## Defines "SegmentLengthAroundVertex" hypothesis - # @param length for the segment length - # @param vertex for the length localization: the vertex index [0,1] | vertex object. - # Any other integer value means that the hypothesis will be set on the - # whole 1D shape, where Mesh_Segment algorithm is assigned. - # @param UseExisting if ==true - searches for an existing hypothesis created with - # the same parameters, else (default) - creates a new one - # @ingroup l3_algos_segmarv - def LengthNearVertex(self, length, vertex=0, UseExisting=0): - import types - store_geom = self.geom - if type(vertex) is types.IntType: - if vertex == 0 or vertex == 1: - vertex = self.mesh.geompyD.SubShapeAllSorted(self.geom, geompyDC.ShapeType["VERTEX"])[vertex] - self.geom = vertex - pass - pass - else: - self.geom = vertex - pass - ### 0D algorithm - if self.geom is None: - raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape" - name = GetName(self.geom) - if name == NO_NAME: - piece = self.mesh.geom - name = self.mesh.geompyD.SubShapeName(self.geom, piece) - self.mesh.geompyD.addToStudyInFather(piece, self.geom, name) - algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD) - if algo is None: - algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so") - pass - status = self.mesh.mesh.AddHypothesis(self.geom, algo) - TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True) - ### - hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting, - CompareMethod=self.CompareLengthNearVertex) - self.geom = store_geom - hyp.SetLength( length ) - return hyp - - ## Checks if the given "LengthNearVertex" hypothesis has the same parameters as the given arguments - # @ingroup l3_algos_segmarv - def CompareLengthNearVertex(self, hyp, args): - return IsEqual(hyp.GetLength(), args[0]) - - ## Defines "QuadraticMesh" hypothesis, forcing construction of quadratic edges. - # If the 2D mesher sees that all boundary edges are quadratic, - # it generates quadratic faces, else it generates linear faces using - # medium nodes as if they are vertices. - # The 3D mesher generates quadratic volumes only if all boundary faces - # are quadratic, else it fails. - # + ## Returns entry of the shape to mesh in the study + def MainShapeEntry(self): + if not self.mesh or not self.mesh.GetMesh(): return "" + if not self.mesh.GetMesh().HasShapeToMesh(): return "" + shape = self.mesh.GetShape() + return shape.GetStudyEntry() + + ## Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build + # near mesh boundary. This hypothesis can be used by several 3D algorithms: + # NETGEN 3D, GHS3D, Hexahedron(i,j,k) + # @param thickness total thickness of layers of prisms + # @param numberOfLayers number of layers of prisms + # @param stretchFactor factor (>1.0) of growth of layer thickness towards inside of mesh + # @param ignoreFaces list of geometrical faces (or their ids) not to generate layers on # @ingroup l3_hypos_additi - def QuadraticMesh(self): - hyp = self.Hypothesis("QuadraticMesh", UseExisting=1, CompareMethod=self.CompareEqualHyp) + def ViscousLayers(self, thickness, numberOfLayers, stretchFactor, ignoreFaces=[]): + if not isinstance(self.algo, SMESH._objref_SMESH_3D_Algo): + raise TypeError, "ViscousLayers are supported by 3D algorithms only" + if not "ViscousLayers" in self.GetCompatibleHypothesis(): + raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName() + if ignoreFaces and isinstance( ignoreFaces[0], geompyDC.GEOM._objref_GEOM_Object ): + ignoreFaces = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in ignoreFaces ] + hyp = self.Hypothesis("ViscousLayers", + [thickness, numberOfLayers, stretchFactor, ignoreFaces]) + hyp.SetTotalThickness(thickness) + hyp.SetNumberLayers(numberOfLayers) + hyp.SetStretchFactor(stretchFactor) + hyp.SetIgnoreFaces(ignoreFaces) return hyp -# Public class: Mesh_CompositeSegment -# -------------------------- - -## Defines a segment 1D algorithm for discretization -# -# @ingroup l3_algos_basic -class Mesh_CompositeSegment(Mesh_Segment): - - ## Private constructor. - def __init__(self, mesh, geom=0): - self.Create(mesh, geom, "CompositeSegment_1D") - - -# Public class: Mesh_Segment_Python -# --------------------------------- - -## Defines a segment 1D algorithm for discretization with python function -# -# @ingroup l3_algos_basic -class Mesh_Segment_Python(Mesh_Segment): - - ## Private constructor. - def __init__(self, mesh, geom=0): - import Python1dPlugin - self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so") - - ## Defines "PythonSplit1D" hypothesis - # @param n for the number of segments that cut an edge - # @param func for the python function that calculates the length of all segments - # @param UseExisting if ==true - searches for the existing hypothesis created with - # the same parameters, else (default) - creates a new one + ## Transform a list of ether edges or tuples (edge, 1st_vertex_of_edge) + # into a list acceptable to SetReversedEdges() of some 1D hypotheses # @ingroup l3_hypos_1dhyps - def PythonSplit1D(self, n, func, UseExisting=0): - hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so", - UseExisting=UseExisting, CompareMethod=self.ComparePythonSplit1D) - hyp.SetNumberOfSegments(n) - hyp.SetPythonLog10RatioFunction(func) - return hyp - - ## Checks if the given "PythonSplit1D" hypothesis has the same parameters as the given arguments - def ComparePythonSplit1D(self, hyp, args): - #if hyp.GetNumberOfSegments() == args[0]: - # if hyp.GetPythonLog10RatioFunction() == args[1]: - # return True - return False - -# Public class: Mesh_Triangle -# --------------------------- - -## Defines a triangle 2D algorithm -# -# @ingroup l3_algos_basic -class Mesh_Triangle(Mesh_Algorithm): - - # default values - algoType = 0 - params = 0 - - _angleMeshS = 8 - _gradation = 1.1 - - ## Private constructor. - def __init__(self, mesh, algoType, geom=0): - Mesh_Algorithm.__init__(self) - - self.algoType = algoType - if algoType == MEFISTO: - self.Create(mesh, geom, "MEFISTO_2D") - pass - elif algoType == BLSURF: - import BLSURFPlugin - self.Create(mesh, geom, "BLSURF", "libBLSURFEngine.so") - #self.SetPhysicalMesh() - PAL19680 - elif algoType == NETGEN: - if noNETGENPlugin: - print "Warning: NETGENPlugin module unavailable" - pass - self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so") - pass - elif algoType == NETGEN_2D: - if noNETGENPlugin: - print "Warning: NETGENPlugin module unavailable" - pass - self.Create(mesh, geom, "NETGEN_2D_ONLY", "libNETGENEngine.so") - pass - - ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle - # @param area for the maximum area of each triangle - # @param UseExisting if ==true - searches for an existing hypothesis created with the - # same parameters, else (default) - creates a new one - # - # Only for algoType == MEFISTO || NETGEN_2D - # @ingroup l3_hypos_2dhyps - def MaxElementArea(self, area, UseExisting=0): - if self.algoType == MEFISTO or self.algoType == NETGEN_2D: - hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting, - CompareMethod=self.CompareMaxElementArea) - elif self.algoType == NETGEN: - hyp = self.Parameters(SIMPLE) - hyp.SetMaxElementArea(area) - return hyp - - ## Checks if the given "MaxElementArea" hypothesis has the same parameters as the given arguments - def CompareMaxElementArea(self, hyp, args): - return IsEqual(hyp.GetMaxElementArea(), args[0]) - - ## Defines "LengthFromEdges" hypothesis to build triangles - # based on the length of the edges taken from the wire - # - # Only for algoType == MEFISTO || NETGEN_2D - # @ingroup l3_hypos_2dhyps - def LengthFromEdges(self): - if self.algoType == MEFISTO or self.algoType == NETGEN_2D: - hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp) - return hyp - elif self.algoType == NETGEN: - hyp = self.Parameters(SIMPLE) - hyp.LengthFromEdges() - return hyp - - ## Sets a way to define size of mesh elements to generate. - # @param thePhysicalMesh is: DefaultSize or Custom. - # @ingroup l3_hypos_blsurf - def SetPhysicalMesh(self, thePhysicalMesh=DefaultSize): - # Parameter of BLSURF algo - self.Parameters().SetPhysicalMesh(thePhysicalMesh) - - ## Sets size of mesh elements to generate. - # @ingroup l3_hypos_blsurf - def SetPhySize(self, theVal): - # Parameter of BLSURF algo - self.Parameters().SetPhySize(theVal) - - ## Sets lower boundary of mesh element size (PhySize). - # @ingroup l3_hypos_blsurf - def SetPhyMin(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetPhyMin(theVal) - - ## Sets upper boundary of mesh element size (PhySize). - # @ingroup l3_hypos_blsurf - def SetPhyMax(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetPhyMax(theVal) - - ## Sets a way to define maximum angular deflection of mesh from CAD model. - # @param theGeometricMesh is: DefaultGeom or Custom - # @ingroup l3_hypos_blsurf - def SetGeometricMesh(self, theGeometricMesh=0): - # Parameter of BLSURF algo - if self.Parameters().GetPhysicalMesh() == 0: theGeometricMesh = 1 - self.params.SetGeometricMesh(theGeometricMesh) - - ## Sets angular deflection (in degrees) of a mesh face from CAD surface. - # @ingroup l3_hypos_blsurf - def SetAngleMeshS(self, theVal=_angleMeshS): - # Parameter of BLSURF algo - if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS - self.params.SetAngleMeshS(theVal) - - ## Sets angular deflection (in degrees) of a mesh edge from CAD curve. - # @ingroup l3_hypos_blsurf - def SetAngleMeshC(self, theVal=_angleMeshS): - # Parameter of BLSURF algo - if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS - self.params.SetAngleMeshC(theVal) - - ## Sets lower boundary of mesh element size computed to respect angular deflection. - # @ingroup l3_hypos_blsurf - def SetGeoMin(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetGeoMin(theVal) - - ## Sets upper boundary of mesh element size computed to respect angular deflection. - # @ingroup l3_hypos_blsurf - def SetGeoMax(self, theVal=-1): - # Parameter of BLSURF algo - self.Parameters().SetGeoMax(theVal) - - ## Sets maximal allowed ratio between the lengths of two adjacent edges. - # @ingroup l3_hypos_blsurf - def SetGradation(self, theVal=_gradation): - # Parameter of BLSURF algo - if self.Parameters().GetGeometricMesh() == 0: theVal = self._gradation - self.params.SetGradation(theVal) - - ## Sets topology usage way. - # @param way defines how mesh conformity is assured
                      - #
                    • FromCAD - mesh conformity is assured by conformity of a shape
                    • - #
                    • PreProcess or PreProcessPlus - by pre-processing a CAD model
                    - # @ingroup l3_hypos_blsurf - def SetTopology(self, way): - # Parameter of BLSURF algo - self.Parameters().SetTopology(way) - - ## To respect geometrical edges or not. - # @ingroup l3_hypos_blsurf - def SetDecimesh(self, toIgnoreEdges=False): - # Parameter of BLSURF algo - self.Parameters().SetDecimesh(toIgnoreEdges) - - ## Sets verbosity level in the range 0 to 100. - # @ingroup l3_hypos_blsurf - def SetVerbosity(self, level): - # Parameter of BLSURF algo - self.Parameters().SetVerbosity(level) - - ## Sets advanced option value. - # @ingroup l3_hypos_blsurf - def SetOptionValue(self, optionName, level): - # Parameter of BLSURF algo - self.Parameters().SetOptionValue(optionName,level) - - ## Sets QuadAllowed flag. - # Only for algoType == NETGEN || NETGEN_2D || BLSURF - # @ingroup l3_hypos_netgen l3_hypos_blsurf - def SetQuadAllowed(self, toAllow=True): - if self.algoType == NETGEN_2D: - if toAllow: # add QuadranglePreference - self.Hypothesis("QuadranglePreference", UseExisting=1, CompareMethod=self.CompareEqualHyp) - else: # remove QuadranglePreference - for hyp in self.mesh.GetHypothesisList( self.geom ): - if hyp.GetName() == "QuadranglePreference": - self.mesh.RemoveHypothesis( self.geom, hyp ) - pass - pass - pass - return - if self.Parameters(): - self.params.SetQuadAllowed(toAllow) - return - - ## Defines hypothesis having several parameters - # - # @ingroup l3_hypos_netgen - def Parameters(self, which=SOLE): - if self.params: - return self.params - if self.algoType == NETGEN: - if which == SIMPLE: - self.params = self.Hypothesis("NETGEN_SimpleParameters_2D", [], - "libNETGENEngine.so", UseExisting=0) + def ReversedEdgeIndices(self, reverseList): + resList = [] + geompy = self.mesh.geompyD + for i in reverseList: + if isinstance( i, int ): + s = geompy.SubShapes(self.mesh.geom, [i])[0] + if s.GetShapeType() != geompyDC.GEOM.EDGE: + raise TypeError, "Not EDGE index given" + resList.append( i ) + elif isinstance( i, geompyDC.GEOM._objref_GEOM_Object ): + if i.GetShapeType() != geompyDC.GEOM.EDGE: + raise TypeError, "Not an EDGE given" + resList.append( geompy.GetSubShapeID(self.mesh.geom, i )) + elif len( i ) > 1: + e = i[0] + v = i[1] + if not isinstance( e, geompyDC.GEOM._objref_GEOM_Object ) or \ + not isinstance( v, geompyDC.GEOM._objref_GEOM_Object ): + raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)" + if v.GetShapeType() == geompyDC.GEOM.EDGE and \ + e.GetShapeType() == geompyDC.GEOM.VERTEX: + v,e = e,v + if e.GetShapeType() != geompyDC.GEOM.EDGE or \ + v.GetShapeType() != geompyDC.GEOM.VERTEX: + raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)" + vFirst = FirstVertexOnCurve( e ) + tol = geompy.Tolerance( vFirst )[-1] + if geompy.MinDistance( v, vFirst ) > 1.5*tol: + resList.append( geompy.GetSubShapeID(self.mesh.geom, e )) else: - self.params = self.Hypothesis("NETGEN_Parameters_2D", [], - "libNETGENEngine.so", UseExisting=0) - return self.params - elif self.algoType == MEFISTO: - print "Mefisto algo support no multi-parameter hypothesis" - return None - elif self.algoType == NETGEN_2D: - print "NETGEN_2D_ONLY algo support no multi-parameter hypothesis" - print "NETGEN_2D_ONLY uses 'MaxElementArea' and 'LengthFromEdges' ones" - return None - elif self.algoType == BLSURF: - self.params = self.Hypothesis("BLSURF_Parameters", [], - "libBLSURFEngine.so", UseExisting=0) - return self.params - else: - print "Mesh_Triangle with algo type %s does not have such a parameter, check algo type"%self.algoType - return None - - ## Sets MaxSize - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetMaxSize(self, theSize): - if self.Parameters(): - self.params.SetMaxSize(theSize) - - ## Sets SecondOrder flag - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetSecondOrder(self, theVal): - if self.Parameters(): - self.params.SetSecondOrder(theVal) + raise TypeError, "Item must be either an edge or tuple (edge, 1st_vertex_of_edge)" + return resList - ## Sets Optimize flag - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetOptimize(self, theVal): - if self.Parameters(): - self.params.SetOptimize(theVal) - - ## Sets Fineness - # @param theFineness is: - # VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetFineness(self, theFineness): - if self.Parameters(): - self.params.SetFineness(theFineness) - - ## Sets GrowthRate - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetGrowthRate(self, theRate): - if self.Parameters(): - self.params.SetGrowthRate(theRate) - - ## Sets NbSegPerEdge - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetNbSegPerEdge(self, theVal): - if self.Parameters(): - self.params.SetNbSegPerEdge(theVal) - - ## Sets NbSegPerRadius - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetNbSegPerRadius(self, theVal): - if self.Parameters(): - self.params.SetNbSegPerRadius(theVal) - - ## Sets number of segments overriding value set by SetLocalLength() - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetNumberOfSegments(self, theVal): - self.Parameters(SIMPLE).SetNumberOfSegments(theVal) - ## Sets number of segments overriding value set by SetNumberOfSegments() - # - # Only for algoType == NETGEN - # @ingroup l3_hypos_netgen - def SetLocalLength(self, theVal): - self.Parameters(SIMPLE).SetLocalLength(theVal) - - pass +class Pattern(SMESH._objref_SMESH_Pattern): + def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse): + decrFun = lambda i: i-1 + theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun) + theMesh.SetParameters(Parameters) + return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse ) -# Public class: Mesh_Quadrangle -# ----------------------------- + def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index): + decrFun = lambda i: i-1 + theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun) + theMesh.SetParameters(Parameters) + return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index ) -## Defines a quadrangle 2D algorithm -# -# @ingroup l3_algos_basic -class Mesh_Quadrangle(Mesh_Algorithm): +#Registering the new proxy for Pattern +omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern) - ## Private constructor. - def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, "Quadrangle_2D") - ## Defines "QuadranglePreference" hypothesis, forcing construction - # of quadrangles if the number of nodes on the opposite edges is not the same - # while the total number of nodes on edges is even - # - # @ingroup l3_hypos_additi - def QuadranglePreference(self): - hyp = self.Hypothesis("QuadranglePreference", UseExisting=1, - CompareMethod=self.CompareEqualHyp) - return hyp - ## Defines "TrianglePreference" hypothesis, forcing construction - # of triangles in the refinement area if the number of nodes - # on the opposite edges is not the same - # - # @ingroup l3_hypos_additi - def TrianglePreference(self): - hyp = self.Hypothesis("TrianglePreference", UseExisting=1, - CompareMethod=self.CompareEqualHyp) - return hyp -# Public class: Mesh_Tetrahedron -# ------------------------------ -## Defines a tetrahedron 3D algorithm +## Private class used to bind methods creating algorithms to the class Mesh # -# @ingroup l3_algos_basic -class Mesh_Tetrahedron(Mesh_Algorithm): - - params = 0 - algoType = 0 - - ## Private constructor. - def __init__(self, mesh, algoType, geom=0): - Mesh_Algorithm.__init__(self) - - if algoType == NETGEN: - self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so") - pass - - elif algoType == FULL_NETGEN: - if noNETGENPlugin: - print "Warning: NETGENPlugin module has not been imported." - self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so") - pass - - elif algoType == GHS3D: - import GHS3DPlugin - self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so") - pass - - elif algoType == GHS3DPRL: - import GHS3DPRLPlugin - self.Create(mesh, geom, "GHS3DPRL_3D" , "libGHS3DPRLEngine.so") - pass - - self.algoType = algoType - - ## Defines "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedron - # @param vol for the maximum volume of each tetrahedron - # @param UseExisting if ==true - searches for the existing hypothesis created with - # the same parameters, else (default) - creates a new one - # @ingroup l3_hypos_maxvol - def MaxElementVolume(self, vol, UseExisting=0): - if self.algoType == NETGEN: - hyp = self.Hypothesis("MaxElementVolume", [vol], UseExisting=UseExisting, - CompareMethod=self.CompareMaxElementVolume) - hyp.SetMaxElementVolume(vol) - return hyp - elif self.algoType == FULL_NETGEN: - self.Parameters(SIMPLE).SetMaxElementVolume(vol) - return None - - ## Checks if the given "MaxElementVolume" hypothesis has the same parameters as the given arguments - def CompareMaxElementVolume(self, hyp, args): - return IsEqual(hyp.GetMaxElementVolume(), args[0]) - - ## Defines hypothesis having several parameters - # - # @ingroup l3_hypos_netgen - def Parameters(self, which=SOLE): - if self.params: - return self.params - - if self.algoType == FULL_NETGEN: - if which == SIMPLE: - self.params = self.Hypothesis("NETGEN_SimpleParameters_3D", [], - "libNETGENEngine.so", UseExisting=0) - else: - self.params = self.Hypothesis("NETGEN_Parameters", [], - "libNETGENEngine.so", UseExisting=0) - return self.params - - if self.algoType == GHS3D: - self.params = self.Hypothesis("GHS3D_Parameters", [], - "libGHS3DEngine.so", UseExisting=0) - return self.params - - if self.algoType == GHS3DPRL: - self.params = self.Hypothesis("GHS3DPRL_Parameters", [], - "libGHS3DPRLEngine.so", UseExisting=0) - return self.params - - print "Algo supports no multi-parameter hypothesis" +class algoCreator: + def __init__(self): + self.mesh = None + self.defaultAlgoType = "" + self.algoTypeToClass = {} + + # Stores a python class of algorithm + def add(self, algoClass): + if type( algoClass ).__name__ == 'classobj' and \ + hasattr( algoClass, "algoType"): + self.algoTypeToClass[ algoClass.algoType ] = algoClass + if not self.defaultAlgoType and \ + hasattr( algoClass, "isDefault") and algoClass.isDefault: + self.defaultAlgoType = algoClass.algoType + #print "Add",algoClass.algoType, "dflt",self.defaultAlgoType + + # creates a copy of self and assign mesh to the copy + def copy(self, mesh): + other = algoCreator() + other.defaultAlgoType = self.defaultAlgoType + other.algoTypeToClass = self.algoTypeToClass + other.mesh = mesh + return other + + # creates an instance of algorithm + def __call__(self,algo="",geom=0,*args): + algoType = self.defaultAlgoType + for arg in args + (algo,geom): + if isinstance( arg, geompyDC.GEOM._objref_GEOM_Object ): + geom = arg + if isinstance( arg, str ) and arg: + algoType = arg + if not algoType and self.algoTypeToClass: + algoType = self.algoTypeToClass.keys()[0] + if self.algoTypeToClass.has_key( algoType ): + #print "Create algo",algoType + return self.algoTypeToClass[ algoType ]( self.mesh, geom ) + raise RuntimeError, "No class found for algo type %s" % algoType return None - ## Sets MaxSize - # Parameter of FULL_NETGEN - # @ingroup l3_hypos_netgen - def SetMaxSize(self, theSize): - self.Parameters().SetMaxSize(theSize) - - ## Sets SecondOrder flag - # Parameter of FULL_NETGEN - # @ingroup l3_hypos_netgen - def SetSecondOrder(self, theVal): - self.Parameters().SetSecondOrder(theVal) - - ## Sets Optimize flag - # Parameter of FULL_NETGEN - # @ingroup l3_hypos_netgen - def SetOptimize(self, theVal): - self.Parameters().SetOptimize(theVal) - - ## Sets Fineness - # @param theFineness is: - # VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom - # Parameter of FULL_NETGEN - # @ingroup l3_hypos_netgen - def SetFineness(self, theFineness): - self.Parameters().SetFineness(theFineness) - - ## Sets GrowthRate - # Parameter of FULL_NETGEN - # @ingroup l3_hypos_netgen - def SetGrowthRate(self, theRate): - self.Parameters().SetGrowthRate(theRate) - - ## Sets NbSegPerEdge - # Parameter of FULL_NETGEN - # @ingroup l3_hypos_netgen - def SetNbSegPerEdge(self, theVal): - self.Parameters().SetNbSegPerEdge(theVal) - - ## Sets NbSegPerRadius - # Parameter of FULL_NETGEN - # @ingroup l3_hypos_netgen - def SetNbSegPerRadius(self, theVal): - self.Parameters().SetNbSegPerRadius(theVal) - - ## Sets number of segments overriding value set by SetLocalLength() - # Only for algoType == NETGEN_FULL - # @ingroup l3_hypos_netgen - def SetNumberOfSegments(self, theVal): - self.Parameters(SIMPLE).SetNumberOfSegments(theVal) - - ## Sets number of segments overriding value set by SetNumberOfSegments() - # Only for algoType == NETGEN_FULL - # @ingroup l3_hypos_netgen - def SetLocalLength(self, theVal): - self.Parameters(SIMPLE).SetLocalLength(theVal) - - ## Defines "MaxElementArea" parameter of NETGEN_SimpleParameters_3D hypothesis. - # Overrides value set by LengthFromEdges() - # Only for algoType == NETGEN_FULL - # @ingroup l3_hypos_netgen - def MaxElementArea(self, area): - self.Parameters(SIMPLE).SetMaxElementArea(area) - - ## Defines "LengthFromEdges" parameter of NETGEN_SimpleParameters_3D hypothesis - # Overrides value set by MaxElementArea() - # Only for algoType == NETGEN_FULL - # @ingroup l3_hypos_netgen - def LengthFromEdges(self): - self.Parameters(SIMPLE).LengthFromEdges() - - ## Defines "LengthFromFaces" parameter of NETGEN_SimpleParameters_3D hypothesis - # Overrides value set by MaxElementVolume() - # Only for algoType == NETGEN_FULL - # @ingroup l3_hypos_netgen - def LengthFromFaces(self): - self.Parameters(SIMPLE).LengthFromFaces() - - ## To mesh "holes" in a solid or not. Default is to mesh. - # @ingroup l3_hypos_ghs3dh - def SetToMeshHoles(self, toMesh): - # Parameter of GHS3D - self.Parameters().SetToMeshHoles(toMesh) - - ## Set Optimization level: - # None_Optimization, Light_Optimization, Medium_Optimization, Strong_Optimization. - # Default is Medium_Optimization - # @ingroup l3_hypos_ghs3dh - def SetOptimizationLevel(self, level): - # Parameter of GHS3D - self.Parameters().SetOptimizationLevel(level) - - ## Maximal size of memory to be used by the algorithm (in Megabytes). - # @ingroup l3_hypos_ghs3dh - def SetMaximumMemory(self, MB): - # Advanced parameter of GHS3D - self.Parameters().SetMaximumMemory(MB) - - ## Initial size of memory to be used by the algorithm (in Megabytes) in - # automatic memory adjustment mode. - # @ingroup l3_hypos_ghs3dh - def SetInitialMemory(self, MB): - # Advanced parameter of GHS3D - self.Parameters().SetInitialMemory(MB) - - ## Path to working directory. - # @ingroup l3_hypos_ghs3dh - def SetWorkingDirectory(self, path): - # Advanced parameter of GHS3D - self.Parameters().SetWorkingDirectory(path) - - ## To keep working files or remove them. Log file remains in case of errors anyway. - # @ingroup l3_hypos_ghs3dh - def SetKeepFiles(self, toKeep): - # Advanced parameter of GHS3D and GHS3DPRL - self.Parameters().SetKeepFiles(toKeep) - - ## To set verbose level [0-10].
                      - #
                    • 0 - no standard output, - #
                    • 2 - prints the data, quality statistics of the skin and final meshes and - # indicates when the final mesh is being saved. In addition the software - # gives indication regarding the CPU time. - #
                    • 10 - same as 2 plus the main steps in the computation, quality statistics - # histogram of the skin mesh, quality statistics histogram together with - # the characteristics of the final mesh.
                    - # @ingroup l3_hypos_ghs3dh - def SetVerboseLevel(self, level): - # Advanced parameter of GHS3D - self.Parameters().SetVerboseLevel(level) - - ## To create new nodes. - # @ingroup l3_hypos_ghs3dh - def SetToCreateNewNodes(self, toCreate): - # Advanced parameter of GHS3D - self.Parameters().SetToCreateNewNodes(toCreate) - - ## To use boundary recovery version which tries to create mesh on a very poor - # quality surface mesh. - # @ingroup l3_hypos_ghs3dh - def SetToUseBoundaryRecoveryVersion(self, toUse): - # Advanced parameter of GHS3D - self.Parameters().SetToUseBoundaryRecoveryVersion(toUse) - - ## Sets command line option as text. - # @ingroup l3_hypos_ghs3dh - def SetTextOption(self, option): - # Advanced parameter of GHS3D - self.Parameters().SetTextOption(option) - - ## Sets MED files name and path. - def SetMEDName(self, value): - self.Parameters().SetMEDName(value) - - ## Sets the number of partition of the initial mesh - def SetNbPart(self, value): - self.Parameters().SetNbPart(value) - - ## When big mesh, start tepal in background - def SetBackground(self, value): - self.Parameters().SetBackground(value) - -# Public class: Mesh_Hexahedron -# ------------------------------ - -## Defines a hexahedron 3D algorithm -# -# @ingroup l3_algos_basic -class Mesh_Hexahedron(Mesh_Algorithm): - - params = 0 - algoType = 0 - - ## Private constructor. - def __init__(self, mesh, algoType=Hexa, geom=0): - Mesh_Algorithm.__init__(self) - - self.algoType = algoType - - if algoType == Hexa: - self.Create(mesh, geom, "Hexa_3D") - pass - - elif algoType == Hexotic: - import HexoticPlugin - self.Create(mesh, geom, "Hexotic_3D", "libHexoticEngine.so") - pass - - ## Defines "MinMaxQuad" hypothesis to give three hexotic parameters - # @ingroup l3_hypos_hexotic - def MinMaxQuad(self, min=3, max=8, quad=True): - self.params = self.Hypothesis("Hexotic_Parameters", [], "libHexoticEngine.so", - UseExisting=0) - self.params.SetHexesMinLevel(min) - self.params.SetHexesMaxLevel(max) - self.params.SetHexoticQuadrangles(quad) - return self.params - -# Deprecated, only for compatibility! -# Public class: Mesh_Netgen -# ------------------------------ - -## Defines a NETGEN-based 2D or 3D algorithm -# that needs no discrete boundary (i.e. independent) -# -# This class is deprecated, only for compatibility! -# -# More details. -# @ingroup l3_algos_basic -class Mesh_Netgen(Mesh_Algorithm): - - is3D = 0 - - ## Private constructor. - def __init__(self, mesh, is3D, geom=0): - Mesh_Algorithm.__init__(self) - - if noNETGENPlugin: - print "Warning: NETGENPlugin module has not been imported." - - self.is3D = is3D - if is3D: - self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so") - pass - - else: - self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so") - pass - - ## Defines the hypothesis containing parameters of the algorithm - def Parameters(self): - if self.is3D: - hyp = self.Hypothesis("NETGEN_Parameters", [], - "libNETGENEngine.so", UseExisting=0) - else: - hyp = self.Hypothesis("NETGEN_Parameters_2D", [], - "libNETGENEngine.so", UseExisting=0) - return hyp - -# Public class: Mesh_Projection1D -# ------------------------------ - -## Defines a projection 1D algorithm -# @ingroup l3_algos_proj -# -class Mesh_Projection1D(Mesh_Algorithm): - - ## Private constructor. - def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, "Projection_1D") - - ## Defines "Source Edge" hypothesis, specifying a meshed edge, from where - # a mesh pattern is taken, and, optionally, the association of vertices - # between the source edge and a target edge (to which a hypothesis is assigned) - # @param edge from which nodes distribution is taken - # @param mesh from which nodes distribution is taken (optional) - # @param srcV a vertex of \a edge to associate with \a tgtV (optional) - # @param tgtV a vertex of \a the edge to which the algorithm is assigned, - # to associate with \a srcV (optional) - # @param UseExisting if ==true - searches for the existing hypothesis created with - # the same parameters, else (default) - creates a new one - def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0): - hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV], - UseExisting=0) - #UseExisting=UseExisting, CompareMethod=self.CompareSourceEdge) - hyp.SetSourceEdge( edge ) - if not mesh is None and isinstance(mesh, Mesh): - mesh = mesh.GetMesh() - hyp.SetSourceMesh( mesh ) - hyp.SetVertexAssociation( srcV, tgtV ) - return hyp - - ## Checks if the given "SourceEdge" hypothesis has the same parameters as the given arguments - #def CompareSourceEdge(self, hyp, args): - # # it does not seem to be useful to reuse the existing "SourceEdge" hypothesis - # return False - - -# Public class: Mesh_Projection2D -# ------------------------------ - -## Defines a projection 2D algorithm -# @ingroup l3_algos_proj -# -class Mesh_Projection2D(Mesh_Algorithm): - - ## Private constructor. - def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, "Projection_2D") - - ## Defines "Source Face" hypothesis, specifying a meshed face, from where - # a mesh pattern is taken, and, optionally, the association of vertices - # between the source face and the target face (to which a hypothesis is assigned) - # @param face from which the mesh pattern is taken - # @param mesh from which the mesh pattern is taken (optional) - # @param srcV1 a vertex of \a face to associate with \a tgtV1 (optional) - # @param tgtV1 a vertex of \a the face to which the algorithm is assigned, - # to associate with \a srcV1 (optional) - # @param srcV2 a vertex of \a face to associate with \a tgtV1 (optional) - # @param tgtV2 a vertex of \a the face to which the algorithm is assigned, - # to associate with \a srcV2 (optional) - # @param UseExisting if ==true - forces the search for the existing hypothesis created with - # the same parameters, else (default) - forces the creation a new one - # - # Note: all association vertices must belong to one edge of a face - def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None, - srcV2=None, tgtV2=None, UseExisting=0): - hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2], - UseExisting=0) - #UseExisting=UseExisting, CompareMethod=self.CompareSourceFace) - hyp.SetSourceFace( face ) - if not mesh is None and isinstance(mesh, Mesh): - mesh = mesh.GetMesh() - hyp.SetSourceMesh( mesh ) - hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 ) - return hyp - - ## Checks if the given "SourceFace" hypothesis has the same parameters as the given arguments - #def CompareSourceFace(self, hyp, args): - # # it does not seem to be useful to reuse the existing "SourceFace" hypothesis - # return False - -# Public class: Mesh_Projection3D -# ------------------------------ - -## Defines a projection 3D algorithm -# @ingroup l3_algos_proj -# -class Mesh_Projection3D(Mesh_Algorithm): - - ## Private constructor. - def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, "Projection_3D") - - ## Defines the "Source Shape 3D" hypothesis, specifying a meshed solid, from where - # the mesh pattern is taken, and, optionally, the association of vertices - # between the source and the target solid (to which a hipothesis is assigned) - # @param solid from where the mesh pattern is taken - # @param mesh from where the mesh pattern is taken (optional) - # @param srcV1 a vertex of \a solid to associate with \a tgtV1 (optional) - # @param tgtV1 a vertex of \a the solid where the algorithm is assigned, - # to associate with \a srcV1 (optional) - # @param srcV2 a vertex of \a solid to associate with \a tgtV1 (optional) - # @param tgtV2 a vertex of \a the solid to which the algorithm is assigned, - # to associate with \a srcV2 (optional) - # @param UseExisting - if ==true - searches for the existing hypothesis created with - # the same parameters, else (default) - creates a new one - # - # Note: association vertices must belong to one edge of a solid - def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0, - srcV2=0, tgtV2=0, UseExisting=0): - hyp = self.Hypothesis("ProjectionSource3D", - [solid,mesh,srcV1,tgtV1,srcV2,tgtV2], - UseExisting=0) - #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D) - hyp.SetSource3DShape( solid ) - if not mesh is None and isinstance(mesh, Mesh): - mesh = mesh.GetMesh() - hyp.SetSourceMesh( mesh ) - hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 ) - return hyp - - ## Checks if the given "SourceShape3D" hypothesis has the same parameters as given arguments - #def CompareSourceShape3D(self, hyp, args): - # # seems to be not really useful to reuse existing "SourceShape3D" hypothesis - # return False - - -# Public class: Mesh_Prism -# ------------------------ - -## Defines a 3D extrusion algorithm -# @ingroup l3_algos_3dextr -# -class Mesh_Prism3D(Mesh_Algorithm): - - ## Private constructor. - def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, "Prism_3D") - -# Public class: Mesh_RadialPrism -# ------------------------------- - -## Defines a Radial Prism 3D algorithm -# @ingroup l3_algos_radialp -# -class Mesh_RadialPrism3D(Mesh_Algorithm): - - ## Private constructor. - def __init__(self, mesh, geom=0): - Mesh_Algorithm.__init__(self) - self.Create(mesh, geom, "RadialPrism_3D") - - self.distribHyp = self.Hypothesis("LayerDistribution", UseExisting=0) - self.nbLayers = None - - ## Return 3D hypothesis holding the 1D one - def Get3DHypothesis(self): - return self.distribHyp - - ## Private method creating a 1D hypothesis and storing it in the LayerDistribution - # hypothesis. Returns the created hypothesis - def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"): - #print "OwnHypothesis",hypType - if not self.nbLayers is None: - self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers ) - self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp ) - study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis - hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so) - self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing - self.distribHyp.SetLayerDistribution( hyp ) - return hyp - - ## Defines "NumberOfLayers" hypothesis, specifying the number of layers of - # prisms to build between the inner and outer shells - # @param n number of layers - # @param UseExisting if ==true - searches for the existing hypothesis created with - # the same parameters, else (default) - creates a new one - def NumberOfLayers(self, n, UseExisting=0): - self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp ) - self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting, - CompareMethod=self.CompareNumberOfLayers) - self.nbLayers.SetNumberOfLayers( n ) - return self.nbLayers - - ## Checks if the given "NumberOfLayers" hypothesis has the same parameters as the given arguments - def CompareNumberOfLayers(self, hyp, args): - return IsEqual(hyp.GetNumberOfLayers(), args[0]) - - ## Defines "LocalLength" hypothesis, specifying the segment length - # to build between the inner and the outer shells - # @param l the length of segments - # @param p the precision of rounding - def LocalLength(self, l, p=1e-07): - hyp = self.OwnHypothesis("LocalLength", [l,p]) - hyp.SetLength(l) - hyp.SetPrecision(p) - return hyp - - ## Defines "NumberOfSegments" hypothesis, specifying the number of layers of - # prisms to build between the inner and the outer shells. - # @param n the number of layers - # @param s the scale factor (optional) - def NumberOfSegments(self, n, s=[]): - if s == []: - hyp = self.OwnHypothesis("NumberOfSegments", [n]) - else: - hyp = self.OwnHypothesis("NumberOfSegments", [n,s]) - hyp.SetDistrType( 1 ) - hyp.SetScaleFactor(s) - hyp.SetNumberOfSegments(n) - return hyp - - ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments - # to build between the inner and the outer shells with a length that changes in arithmetic progression - # @param start the length of the first segment - # @param end the length of the last segment - def Arithmetic1D(self, start, end ): - hyp = self.OwnHypothesis("Arithmetic1D", [start, end]) - hyp.SetLength(start, 1) - hyp.SetLength(end , 0) - return hyp - - ## Defines "StartEndLength" hypothesis, specifying distribution of segments - # to build between the inner and the outer shells as geometric length increasing - # @param start for the length of the first segment - # @param end for the length of the last segment - def StartEndLength(self, start, end): - hyp = self.OwnHypothesis("StartEndLength", [start, end]) - hyp.SetLength(start, 1) - hyp.SetLength(end , 0) - return hyp - - ## Defines "AutomaticLength" hypothesis, specifying the number of segments - # to build between the inner and outer shells - # @param fineness defines the quality of the mesh within the range [0-1] - def AutomaticLength(self, fineness=0): - hyp = self.OwnHypothesis("AutomaticLength") - hyp.SetFineness( fineness ) - return hyp - -# Private class: Mesh_UseExisting -# ------------------------------- -class Mesh_UseExisting(Mesh_Algorithm): - - def __init__(self, dim, mesh, geom=0): - if dim == 1: - self.Create(mesh, geom, "UseExisting_1D") - else: - self.Create(mesh, geom, "UseExisting_2D") - - -import salome_notebook -notebook = salome_notebook.notebook - -##Return values of the notebook variables -def ParseParameters(last, nbParams,nbParam, value): - result = None - strResult = "" - counter = 0 - listSize = len(last) - for n in range(0,nbParams): - if n+1 != nbParam: - if counter < listSize: - strResult = strResult + last[counter] - else: - strResult = strResult + "" - else: - if isinstance(value, str): - if notebook.isVariable(value): - result = notebook.get(value) - strResult=strResult+value - else: - raise RuntimeError, "Variable with name '" + value + "' doesn't exist!!!" - else: - strResult=strResult+str(value) - result = value - if nbParams - 1 != counter: - strResult=strResult+var_separator #":" - counter = counter+1 - return result, strResult - -#Wrapper class for StdMeshers_LocalLength hypothesis -class LocalLength(StdMeshers._objref_StdMeshers_LocalLength): - - ## Set Length parameter value - # @param length numerical value or name of variable from notebook - def SetLength(self, length): - length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_LocalLength.GetLastParameters(self),2,1,length) - StdMeshers._objref_StdMeshers_LocalLength.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_LocalLength.SetLength(self,length) - - ## Set Precision parameter value - # @param precision numerical value or name of variable from notebook - def SetPrecision(self, precision): - precision,parameters = ParseParameters(StdMeshers._objref_StdMeshers_LocalLength.GetLastParameters(self),2,2,precision) - StdMeshers._objref_StdMeshers_LocalLength.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_LocalLength.SetPrecision(self, precision) - -#Registering the new proxy for LocalLength -omniORB.registerObjref(StdMeshers._objref_StdMeshers_LocalLength._NP_RepositoryId, LocalLength) - - -#Wrapper class for StdMeshers_LayerDistribution hypothesis -class LayerDistribution(StdMeshers._objref_StdMeshers_LayerDistribution): - - def SetLayerDistribution(self, hypo): - StdMeshers._objref_StdMeshers_LayerDistribution.SetParameters(self,hypo.GetParameters()) - hypo.ClearParameters(); - StdMeshers._objref_StdMeshers_LayerDistribution.SetLayerDistribution(self,hypo) - -#Registering the new proxy for LayerDistribution -omniORB.registerObjref(StdMeshers._objref_StdMeshers_LayerDistribution._NP_RepositoryId, LayerDistribution) - -#Wrapper class for StdMeshers_SegmentLengthAroundVertex hypothesis -class SegmentLengthAroundVertex(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex): - - ## Set Length parameter value - # @param length numerical value or name of variable from notebook - def SetLength(self, length): - length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.GetLastParameters(self),1,1,length) - StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.SetLength(self,length) - -#Registering the new proxy for SegmentLengthAroundVertex -omniORB.registerObjref(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex._NP_RepositoryId, SegmentLengthAroundVertex) - - -#Wrapper class for StdMeshers_Arithmetic1D hypothesis -class Arithmetic1D(StdMeshers._objref_StdMeshers_Arithmetic1D): - - ## Set Length parameter value - # @param length numerical value or name of variable from notebook - # @param isStart true is length is Start Length, otherwise false - def SetLength(self, length, isStart): - nb = 2 - if isStart: - nb = 1 - length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_Arithmetic1D.GetLastParameters(self),2,nb,length) - StdMeshers._objref_StdMeshers_Arithmetic1D.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_Arithmetic1D.SetLength(self,length,isStart) - -#Registering the new proxy for Arithmetic1D -omniORB.registerObjref(StdMeshers._objref_StdMeshers_Arithmetic1D._NP_RepositoryId, Arithmetic1D) - -#Wrapper class for StdMeshers_Deflection1D hypothesis -class Deflection1D(StdMeshers._objref_StdMeshers_Deflection1D): - - ## Set Deflection parameter value - # @param deflection numerical value or name of variable from notebook - def SetDeflection(self, deflection): - deflection,parameters = ParseParameters(StdMeshers._objref_StdMeshers_Deflection1D.GetLastParameters(self),1,1,deflection) - StdMeshers._objref_StdMeshers_Deflection1D.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_Deflection1D.SetDeflection(self,deflection) - -#Registering the new proxy for Deflection1D -omniORB.registerObjref(StdMeshers._objref_StdMeshers_Deflection1D._NP_RepositoryId, Deflection1D) - -#Wrapper class for StdMeshers_StartEndLength hypothesis -class StartEndLength(StdMeshers._objref_StdMeshers_StartEndLength): - - ## Set Length parameter value - # @param length numerical value or name of variable from notebook - # @param isStart true is length is Start Length, otherwise false - def SetLength(self, length, isStart): - nb = 2 - if isStart: - nb = 1 - length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_StartEndLength.GetLastParameters(self),2,nb,length) - StdMeshers._objref_StdMeshers_StartEndLength.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_StartEndLength.SetLength(self,length,isStart) - -#Registering the new proxy for StartEndLength -omniORB.registerObjref(StdMeshers._objref_StdMeshers_StartEndLength._NP_RepositoryId, StartEndLength) - -#Wrapper class for StdMeshers_MaxElementArea hypothesis -class MaxElementArea(StdMeshers._objref_StdMeshers_MaxElementArea): - - ## Set Max Element Area parameter value - # @param area numerical value or name of variable from notebook - def SetMaxElementArea(self, area): - area ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_MaxElementArea.GetLastParameters(self),1,1,area) - StdMeshers._objref_StdMeshers_MaxElementArea.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_MaxElementArea.SetMaxElementArea(self,area) - -#Registering the new proxy for MaxElementArea -omniORB.registerObjref(StdMeshers._objref_StdMeshers_MaxElementArea._NP_RepositoryId, MaxElementArea) - - -#Wrapper class for StdMeshers_MaxElementVolume hypothesis -class MaxElementVolume(StdMeshers._objref_StdMeshers_MaxElementVolume): - - ## Set Max Element Volume parameter value - # @param area numerical value or name of variable from notebook - def SetMaxElementVolume(self, volume): - volume ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_MaxElementVolume.GetLastParameters(self),1,1,volume) - StdMeshers._objref_StdMeshers_MaxElementVolume.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_MaxElementVolume.SetMaxElementVolume(self,volume) - -#Registering the new proxy for MaxElementVolume -omniORB.registerObjref(StdMeshers._objref_StdMeshers_MaxElementVolume._NP_RepositoryId, MaxElementVolume) - - -#Wrapper class for StdMeshers_NumberOfLayers hypothesis -class NumberOfLayers(StdMeshers._objref_StdMeshers_NumberOfLayers): - - ## Set Number Of Layers parameter value - # @param nbLayers numerical value or name of variable from notebook - def SetNumberOfLayers(self, nbLayers): - nbLayers ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_NumberOfLayers.GetLastParameters(self),1,1,nbLayers) - StdMeshers._objref_StdMeshers_NumberOfLayers.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_NumberOfLayers.SetNumberOfLayers(self,nbLayers) - -#Registering the new proxy for NumberOfLayers -omniORB.registerObjref(StdMeshers._objref_StdMeshers_NumberOfLayers._NP_RepositoryId, NumberOfLayers) - -#Wrapper class for StdMeshers_NumberOfSegments hypothesis -class NumberOfSegments(StdMeshers._objref_StdMeshers_NumberOfSegments): - - ## Set Number Of Segments parameter value - # @param nbSeg numerical value or name of variable from notebook - def SetNumberOfSegments(self, nbSeg): - lastParameters = StdMeshers._objref_StdMeshers_NumberOfSegments.GetLastParameters(self) - nbSeg , parameters = ParseParameters(lastParameters,1,1,nbSeg) - StdMeshers._objref_StdMeshers_NumberOfSegments.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_NumberOfSegments.SetNumberOfSegments(self,nbSeg) - - ## Set Scale Factor parameter value - # @param factor numerical value or name of variable from notebook - def SetScaleFactor(self, factor): - factor, parameters = ParseParameters(StdMeshers._objref_StdMeshers_NumberOfSegments.GetLastParameters(self),2,2,factor) - StdMeshers._objref_StdMeshers_NumberOfSegments.SetParameters(self,parameters) - StdMeshers._objref_StdMeshers_NumberOfSegments.SetScaleFactor(self,factor) - -#Registering the new proxy for NumberOfSegments -omniORB.registerObjref(StdMeshers._objref_StdMeshers_NumberOfSegments._NP_RepositoryId, NumberOfSegments) - - -#Wrapper class for NETGENPlugin_Hypothesis hypothesis -class NETGENPlugin_Hypothesis(NETGENPlugin._objref_NETGENPlugin_Hypothesis): - - ## Set Max Size parameter value - # @param maxsize numerical value or name of variable from notebook - def SetMaxSize(self, maxsize): - lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self) - maxsize, parameters = ParseParameters(lastParameters,4,1,maxsize) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetMaxSize(self,maxsize) - - ## Set Growth Rate parameter value - # @param value numerical value or name of variable from notebook - def SetGrowthRate(self, value): - lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self) - value, parameters = ParseParameters(lastParameters,4,2,value) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetGrowthRate(self,value) - - ## Set Number of Segments per Edge parameter value - # @param value numerical value or name of variable from notebook - def SetNbSegPerEdge(self, value): - lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self) - value, parameters = ParseParameters(lastParameters,4,3,value) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetNbSegPerEdge(self,value) - - ## Set Number of Segments per Radius parameter value - # @param value numerical value or name of variable from notebook - def SetNbSegPerRadius(self, value): - lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self) - value, parameters = ParseParameters(lastParameters,4,4,value) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetNbSegPerRadius(self,value) - -#Registering the new proxy for NETGENPlugin_Hypothesis -omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_Hypothesis._NP_RepositoryId, NETGENPlugin_Hypothesis) - - -#Wrapper class for NETGENPlugin_Hypothesis_2D hypothesis -class NETGENPlugin_Hypothesis_2D(NETGENPlugin_Hypothesis,NETGENPlugin._objref_NETGENPlugin_Hypothesis_2D): - pass - -#Registering the new proxy for NETGENPlugin_Hypothesis_2D -omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_Hypothesis_2D._NP_RepositoryId, NETGENPlugin_Hypothesis_2D) - -#Wrapper class for NETGENPlugin_SimpleHypothesis_2D hypothesis -class NETGEN_SimpleParameters_2D(NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D): - - ## Set Number of Segments parameter value - # @param nbSeg numerical value or name of variable from notebook - def SetNumberOfSegments(self, nbSeg): - lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self) - nbSeg, parameters = ParseParameters(lastParameters,2,1,nbSeg) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetNumberOfSegments(self, nbSeg) - - ## Set Local Length parameter value - # @param length numerical value or name of variable from notebook - def SetLocalLength(self, length): - lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self) - length, parameters = ParseParameters(lastParameters,2,1,length) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetLocalLength(self, length) - - ## Set Max Element Area parameter value - # @param area numerical value or name of variable from notebook - def SetMaxElementArea(self, area): - lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self) - area, parameters = ParseParameters(lastParameters,2,2,area) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetMaxElementArea(self, area) - - def LengthFromEdges(self): - lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self) - value = 0; - value, parameters = ParseParameters(lastParameters,2,2,value) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.LengthFromEdges(self) - -#Registering the new proxy for NETGEN_SimpleParameters_2D -omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D._NP_RepositoryId, NETGEN_SimpleParameters_2D) - - -#Wrapper class for NETGENPlugin_SimpleHypothesis_3D hypothesis -class NETGEN_SimpleParameters_3D(NETGEN_SimpleParameters_2D,NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D): - ## Set Max Element Volume parameter value - # @param volume numerical value or name of variable from notebook - def SetMaxElementVolume(self, volume): - lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.GetLastParameters(self) - volume, parameters = ParseParameters(lastParameters,3,3,volume) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.SetMaxElementVolume(self, volume) - - def LengthFromFaces(self): - lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.GetLastParameters(self) - value = 0; - value, parameters = ParseParameters(lastParameters,3,3,value) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.SetParameters(self,parameters) - NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.LengthFromFaces(self) - -#Registering the new proxy for NETGEN_SimpleParameters_3D -omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D._NP_RepositoryId, NETGEN_SimpleParameters_3D) - -class Pattern(SMESH._objref_SMESH_Pattern): +# Private class used to substitute and store variable parameters of hypotheses. +class hypMethodWrapper: + def __init__(self, hyp, method): + self.hyp = hyp + self.method = method + #print "REBIND:", method.__name__ + return - def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse): - flag = False - if isinstance(theNodeIndexOnKeyPoint1,str): - flag = True - theNodeIndexOnKeyPoint1,Parameters = geompyDC.ParseParameters(theNodeIndexOnKeyPoint1) - if flag: - theNodeIndexOnKeyPoint1 -= 1 - theMesh.SetParameters(Parameters) - return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse ) + # call a method of hypothesis with calling SetVarParameter() before + def __call__(self,*args): + if not args: + return self.method( self.hyp, *args ) # hypothesis method with no args - def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index): - flag0 = False - flag1 = False - if isinstance(theNode000Index,str): - flag0 = True - if isinstance(theNode001Index,str): - flag1 = True - theNode000Index,theNode001Index,Parameters = geompyDC.ParseParameters(theNode000Index,theNode001Index) - if flag0: - theNode000Index -= 1 - if flag1: - theNode001Index -= 1 - theMesh.SetParameters(Parameters) - return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index ) + #print "MethWrapper.__call__",self.method.__name__, args + try: + parsed = ParseParameters(*args) # replace variables with their values + self.hyp.SetVarParameter( parsed[-2], self.method.__name__ ) + result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method + except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call + # maybe there is a replaced string arg which is not variable + result = self.method( self.hyp, *args ) + except ValueError, detail: # raised by ParseParameters() + try: + result = self.method( self.hyp, *args ) + except omniORB.CORBA.BAD_PARAM: + raise ValueError, detail # wrong variable name -#Registering the new proxy for Pattern -omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern) + return result diff --git a/src/SMESH_SWIG_WITHIHM/Makefile.am b/src/SMESH_SWIG_WITHIHM/Makefile.am index 69ae00da9..ee0248ac1 100644 --- a/src/SMESH_SWIG_WITHIHM/Makefile.am +++ b/src/SMESH_SWIG_WITHIHM/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH SMESHGUI : GUI for SMESH component # File : Makefile.am # Author : Alexander BORODIN, Open CASCADE S.A.S. @@ -71,9 +69,9 @@ _libSMESH_Swig_la_CPPFLAGS = \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ $(BOOST_CPPFLAGS) \ + -I$(srcdir) \ -I$(srcdir)/../SMESHGUI \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix + -I$(top_builddir)/idl _libSMESH_Swig_la_LDFLAGS = -module _libSMESH_Swig_la_LIBADD = ../SMESHGUI/libSMESH.la \ diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx index 4766864a2..eca22e91e 100644 --- a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : GUI for SMESH component // File : libSMESH_Swig.cxx // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -71,10 +69,10 @@ namespace inline SALOMEDS::SObject_var GetDomainRoot(const SALOMEDS::SComponent_var& theSComponentMesh, - const SALOMEDS::StudyBuilder_var& theStudyBuilder, - CORBA::Long theDomainRootTag, - const QString& theName, - const QString& thePixmap) + const SALOMEDS::StudyBuilder_var& theStudyBuilder, + CORBA::Long theDomainRootTag, + const QString& theName, + const QString& thePixmap) { SALOMEDS::SObject_var aDomainRoot; if (!theSComponentMesh->FindSubObject(theDomainRootTag,aDomainRoot)) { @@ -98,13 +96,13 @@ namespace inline SALOMEDS::SObject_var GetHypothesisRoot(const SALOMEDS::SComponent_var& theSComponentMesh, - const SALOMEDS::StudyBuilder_var& theStudyBuilder) + const SALOMEDS::StudyBuilder_var& theStudyBuilder) { return GetDomainRoot(theSComponentMesh, - theStudyBuilder, - SMESH::Tag_HypothesisRoot, - QObject::tr("SMESH_MEN_HYPOTHESIS"), - "ICON_SMESH_TREE_HYPO"); + theStudyBuilder, + SMESH::Tag_HypothesisRoot, + QObject::tr("SMESH_MEN_HYPOTHESIS"), + "ICON_SMESH_TREE_HYPO"); } @@ -112,13 +110,13 @@ namespace inline SALOMEDS::SObject_var GetAlgorithmsRoot(const SALOMEDS::SComponent_var& theSComponentMesh, - const SALOMEDS::StudyBuilder_var& theStudyBuilder) + const SALOMEDS::StudyBuilder_var& theStudyBuilder) { return GetDomainRoot(theSComponentMesh, - theStudyBuilder, - SMESH::Tag_AlgorithmsRoot, - QObject::tr("SMESH_MEN_ALGORITHMS"), - "ICON_SMESH_TREE_ALGO"); + theStudyBuilder, + SMESH::Tag_AlgorithmsRoot, + QObject::tr("SMESH_MEN_ALGORITHMS"), + "ICON_SMESH_TREE_ALGO"); } @@ -126,17 +124,17 @@ namespace inline SALOMEDS::SObject_var AddToDomain(const std::string& theIOR, - const SALOMEDS::SComponent_var& theSComponentMesh, - const SALOMEDS::StudyBuilder_var& theStudyBuilder, - CORBA::Long theDomainRootTag, - const QString& theDomainName, - const QString& theDomainPixmap) + const SALOMEDS::SComponent_var& theSComponentMesh, + const SALOMEDS::StudyBuilder_var& theStudyBuilder, + CORBA::Long theDomainRootTag, + const QString& theDomainName, + const QString& theDomainPixmap) { SALOMEDS::SObject_var aDomain = GetDomainRoot(theSComponentMesh, - theStudyBuilder, - SMESH::Tag_AlgorithmsRoot, - theDomainName, - theDomainPixmap); + theStudyBuilder, + SMESH::Tag_AlgorithmsRoot, + theDomainName, + theDomainPixmap); // Add New Hypothesis SALOMEDS::SObject_var aSObject = theStudyBuilder->NewObject(aDomain); SALOMEDS::GenericAttribute_var anAttr = theStudyBuilder->FindOrCreateAttribute(aSObject,"AttributePixMap"); @@ -157,42 +155,42 @@ namespace //--------------------------------------------------------------- SALOMEDS::SObject_var AddHypothesis(const std::string& theIOR, - const SALOMEDS::SComponent_var& theSComponentMesh, - const SALOMEDS::StudyBuilder_var& theStudyBuilder) + const SALOMEDS::SComponent_var& theSComponentMesh, + const SALOMEDS::StudyBuilder_var& theStudyBuilder) { return AddToDomain(theIOR, - theSComponentMesh, - theStudyBuilder, - SMESH::Tag_HypothesisRoot, - QObject::tr("SMESH_MEN_HYPOTHESIS"), - "ICON_SMESH_TREE_HYPO"); + theSComponentMesh, + theStudyBuilder, + SMESH::Tag_HypothesisRoot, + QObject::tr("SMESH_MEN_HYPOTHESIS"), + "ICON_SMESH_TREE_HYPO"); } //--------------------------------------------------------------- SALOMEDS::SObject_var AddAlgorithms(const std::string& theIOR, - const SALOMEDS::SComponent_var& theSComponentMesh, - const SALOMEDS::StudyBuilder_var& theStudyBuilder) + const SALOMEDS::SComponent_var& theSComponentMesh, + const SALOMEDS::StudyBuilder_var& theStudyBuilder) { return AddToDomain(theIOR, - theSComponentMesh, - theStudyBuilder, - SMESH::Tag_AlgorithmsRoot, - QObject::tr("SMESH_MEN_ALGORITHMS"), - "ICON_SMESH_TREE_ALGO"); + theSComponentMesh, + theStudyBuilder, + SMESH::Tag_AlgorithmsRoot, + QObject::tr("SMESH_MEN_ALGORITHMS"), + "ICON_SMESH_TREE_ALGO"); } //--------------------------------------------------------------- void SetDomain(const char* theMeshOrSubMeshEntry, - const char* theDomainEntry, - const SALOMEDS::Study_var& theStudy, - const SALOMEDS::StudyBuilder_var& theStudyBuilder, - long theRefOnAppliedDomainTag, - const QString& theAppliedDomainMEN, - const QString& theAppliedDomainICON) + const char* theDomainEntry, + const SALOMEDS::Study_var& theStudy, + const SALOMEDS::StudyBuilder_var& theStudyBuilder, + long theRefOnAppliedDomainTag, + const QString& theAppliedDomainMEN, + const QString& theAppliedDomainICON) { SALOMEDS::SObject_var aMeshOrSubMeshSO = theStudy->FindObjectID(theMeshOrSubMeshEntry); SALOMEDS::SObject_var aHypothesisSO = theStudy->FindObjectID(theDomainEntry); @@ -201,17 +199,17 @@ namespace //Find or Create Applied Hypothesis root SALOMEDS::SObject_var anAppliedDomainSO; if(!aMeshOrSubMeshSO->FindSubObject(theRefOnAppliedDomainTag,anAppliedDomainSO)){ - anAppliedDomainSO = theStudyBuilder->NewObjectToTag(aMeshOrSubMeshSO,theRefOnAppliedDomainTag); - SALOMEDS::GenericAttribute_var anAttr = - theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeName"); - SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr); - aName->SetValue(theAppliedDomainMEN.toLatin1().data()); - anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeSelectable"); - SALOMEDS::AttributeSelectable_var aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr); - aSelAttr->SetSelectable(false); - anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributePixMap"); - SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap(theAppliedDomainICON.toLatin1().data()); + anAppliedDomainSO = theStudyBuilder->NewObjectToTag(aMeshOrSubMeshSO,theRefOnAppliedDomainTag); + SALOMEDS::GenericAttribute_var anAttr = + theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeName"); + SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr); + aName->SetValue(theAppliedDomainMEN.toLatin1().data()); + anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeSelectable"); + SALOMEDS::AttributeSelectable_var aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr); + aSelAttr->SetSelectable(false); + anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributePixMap"); + SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); + aPixmap->SetPixMap(theAppliedDomainICON.toLatin1().data()); } SALOMEDS::SObject_var aSObject = theStudyBuilder->NewObject(anAppliedDomainSO); theStudyBuilder->Addreference(aSObject,aHypothesisSO); @@ -222,34 +220,34 @@ namespace //--------------------------------------------------------------- void SetHypothesis(const char* theMeshOrSubMeshEntry, - const char* theDomainEntry, - const SALOMEDS::Study_var& theStudy, - const SALOMEDS::StudyBuilder_var& theStudyBuilder) + const char* theDomainEntry, + const SALOMEDS::Study_var& theStudy, + const SALOMEDS::StudyBuilder_var& theStudyBuilder) { SetDomain(theMeshOrSubMeshEntry, - theDomainEntry, - theStudy, - theStudyBuilder, - SMESH::Tag_RefOnAppliedHypothesis, - QObject::tr("SMESH_MEN_APPLIED_HYPOTHESIS"), - "ICON_SMESH_TREE_HYPO"); + theDomainEntry, + theStudy, + theStudyBuilder, + SMESH::Tag_RefOnAppliedHypothesis, + QObject::tr("SMESH_MEN_APPLIED_HYPOTHESIS"), + "ICON_SMESH_TREE_HYPO"); } //--------------------------------------------------------------- void SetAlgorithms(const char* theMeshOrSubMeshEntry, - const char* theDomainEntry, - const SALOMEDS::Study_var& theStudy, - const SALOMEDS::StudyBuilder_var& theStudyBuilder) + const char* theDomainEntry, + const SALOMEDS::Study_var& theStudy, + const SALOMEDS::StudyBuilder_var& theStudyBuilder) { SetDomain(theMeshOrSubMeshEntry, - theDomainEntry, - theStudy, - theStudyBuilder, - SMESH::Tag_RefOnAppliedAlgorithms, - QObject::tr("SMESH_MEN_APPLIED_ALGORIHTMS"), - "ICON_SMESH_TREE_ALGO"); + theDomainEntry, + theStudy, + theStudyBuilder, + SMESH::Tag_RefOnAppliedAlgorithms, + QObject::tr("SMESH_MEN_APPLIED_ALGORIHTMS"), + "ICON_SMESH_TREE_ALGO"); } } @@ -271,11 +269,11 @@ SMESH_Swig::SMESH_Swig() Execute() { try { - ORB_INIT &anORBInit = *SINGLETON_::Instance(); - ASSERT(SINGLETON_::IsAlreadyExisting()); - myORB = anORBInit( 0, 0 ); + ORB_INIT &anORBInit = *SINGLETON_::Instance(); + ASSERT(SINGLETON_::IsAlreadyExisting()); + myORB = anORBInit( 0, 0 ); } catch (...) { - INFOS("internal error : orb not found"); + INFOS("internal error : orb not found"); } } }; @@ -301,9 +299,9 @@ SMESH_Swig::Init(int theStudyID) SALOMEDS::SComponent_var& mySComponentMesh; public: TEvent(int theStudyID, - SALOMEDS::Study_var& theStudy, - SALOMEDS::StudyBuilder_var& theStudyBuilder, - SALOMEDS::SComponent_var& theSComponentMesh): + SALOMEDS::Study_var& theStudy, + SALOMEDS::StudyBuilder_var& theStudyBuilder, + SALOMEDS::SComponent_var& theSComponentMesh): myStudyID(theStudyID), myStudy(theStudy), myStudyBuilder(theStudyBuilder), @@ -334,28 +332,28 @@ SMESH_Swig::Init(int theStudyID) SALOMEDS::SComponent_var aSComponent = myStudy->FindComponent("SMESH"); if(aSComponent->_is_nil()){ - bool aLocked = myStudy->GetProperties()->IsLocked(); - if (aLocked) - myStudy->GetProperties()->SetLocked(false); - - aSComponent = myStudyBuilder->NewComponent("SMESH"); - anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributeName"); - aName = SALOMEDS::AttributeName::_narrow(anAttr); - - SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI(); //SRN: BugID IPAL9186, load a SMESH gui if it hasn't been loaded - if (!aSMESHGUI){ - CAM_Module* aModule = anApp->module("Mesh"); - if(!aModule) - aModule = anApp->loadModule("Mesh"); - aSMESHGUI = dynamic_cast(aModule); - } //SRN: BugID IPAL9186: end of a fix - aName->SetValue(aSMESHGUI->moduleName().toLatin1().data()); - anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributePixMap"); - aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); - aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" ); - myStudyBuilder->DefineComponentInstance(aSComponent,aSMESHGen); - if (aLocked) - myStudy->GetProperties()->SetLocked(true); + bool aLocked = myStudy->GetProperties()->IsLocked(); + if (aLocked) + myStudy->GetProperties()->SetLocked(false); + + aSComponent = myStudyBuilder->NewComponent("SMESH"); + anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributeName"); + aName = SALOMEDS::AttributeName::_narrow(anAttr); + + SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI(); //SRN: BugID IPAL9186, load a SMESH gui if it hasn't been loaded + if (!aSMESHGUI){ + CAM_Module* aModule = anApp->module("Mesh"); + if(!aModule) + aModule = anApp->loadModule("Mesh"); + aSMESHGUI = dynamic_cast(aModule); + } //SRN: BugID IPAL9186: end of a fix + aName->SetValue(aSMESHGUI->moduleName().toLatin1().data()); + anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributePixMap"); + aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); + aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" ); + myStudyBuilder->DefineComponentInstance(aSComponent,aSMESHGen); + if (aLocked) + myStudy->GetProperties()->SetLocked(true); } mySComponentMesh = SALOMEDS::SComponent::_narrow(aSComponent); @@ -367,9 +365,9 @@ SMESH_Swig::Init(int theStudyID) MESSAGE("Init"); ProcessVoidEvent(new TEvent(theStudyID, - myStudy, - myStudyBuilder, - mySComponentMesh)); + myStudy, + myStudyBuilder, + mySComponentMesh)); } @@ -414,8 +412,8 @@ const char* SMESH_Swig::AddNewHypothesis(const char* theIOR) MESSAGE("AddNewHypothesis"); SALOMEDS::SObject_var aSObject = ::AddHypothesis(theIOR, - mySComponentMesh, - myStudyBuilder); + mySComponentMesh, + myStudyBuilder); CORBA::String_var anEntry = aSObject->GetID(); return anEntry._retn(); } @@ -427,8 +425,8 @@ const char* SMESH_Swig::AddNewAlgorithms(const char* theIOR) MESSAGE("AddNewAlgorithms"); SALOMEDS::SObject_var aSObject = ::AddAlgorithms(theIOR, - mySComponentMesh, - myStudyBuilder); + mySComponentMesh, + myStudyBuilder); CORBA::String_var anEntry = aSObject->GetID(); return anEntry._retn(); } @@ -453,9 +451,9 @@ void SMESH_Swig::SetHypothesis(const char* theMeshOrSubMeshEntry, const char* theDomainEntry) { ::SetHypothesis(theMeshOrSubMeshEntry, - theDomainEntry, - myStudy, - myStudyBuilder); + theDomainEntry, + myStudy, + myStudyBuilder); } @@ -464,9 +462,9 @@ void SMESH_Swig::SetAlgorithms(const char* theMeshOrSubMeshEntry, const char* theDomainEntry) { ::SetAlgorithms(theMeshOrSubMeshEntry, - theDomainEntry, - myStudy, - myStudyBuilder); + theDomainEntry, + myStudy, + myStudyBuilder); } @@ -599,7 +597,7 @@ void SMESH_Swig::SetName(const char* theEntry, //================================================================================ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry, - const bool theIsComputed, + const bool theIsComputed, const bool isEmpty) { class TEvent: public SALOME_Event @@ -609,8 +607,8 @@ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry, bool myIsComputed, myIsEmpty; public: TEvent(const SALOMEDS::Study_var& theStudy, - const std::string& theMeshEntry, - const bool theIsComputed, + const std::string& theMeshEntry, + const bool theIsComputed, const bool isEmpty): myStudy(theStudy), myMeshEntry(theMeshEntry), @@ -624,13 +622,13 @@ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry, { SALOMEDS::SObject_var aMeshSO = myStudy->FindObjectID(myMeshEntry.c_str()); if(!aMeshSO->_is_nil()) - if(_PTR(SObject) aMesh = ClientFactory::SObject(aMeshSO)) - SMESH::ModifiedMesh(aMesh,myIsComputed,myIsEmpty); + if(_PTR(SObject) aMesh = ClientFactory::SObject(aMeshSO)) + SMESH::ModifiedMesh(aMesh,myIsComputed,myIsEmpty); } }; ProcessVoidEvent(new TEvent(myStudy, - theMeshEntry, - theIsComputed, + theMeshEntry, + theIsComputed, isEmpty)); } diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h index a288506a1..4a7b8e719 100644 --- a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : GUI for SMESH component // File : libSMESH_Swig.h // Author : Nicolas REJNERI, Open CASCADE S.A.S. @@ -27,7 +25,7 @@ #define LIBSMESH_SWIG_H #ifdef WNT -#if defined SMESH_SWIG_EXPORTS +#if defined SMESH_SWIG_EXPORTS || defined _libSMESH_Swig_EXPORTS #define SMESH_SWIG_EXPORT __declspec( dllexport ) #else #define SMESH_SWIG_EXPORT __declspec( dllimport ) diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i index a865a8e95..52d2bb87f 100644 --- a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESHGUI : GUI for SMESH component // File : libSMESH_Swig.i // Author : Nicolas REJNERI, Open CASCADE S.A.S. diff --git a/src/StdMeshers/Makefile.am b/src/StdMeshers/Makefile.am index 8b86e0958..e831115fa 100644 --- a/src/StdMeshers/Makefile.am +++ b/src/StdMeshers/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH StdMeshers : implementaion of SMESH idl descriptions # File : Makefile.in # Author : Julia DOROVSKIKH @@ -32,6 +30,7 @@ salomeinclude_HEADERS = \ StdMeshers_LocalLength.hxx \ StdMeshers_StartEndLength.hxx \ StdMeshers_Arithmetic1D.hxx \ + StdMeshers_FixedPoints1D.hxx \ StdMeshers_NumberOfSegments.hxx \ StdMeshers_Deflection1D.hxx \ StdMeshers_Propagation.hxx \ @@ -49,6 +48,7 @@ salomeinclude_HEADERS = \ StdMeshers_QuadranglePreference.hxx \ StdMeshers_QuadraticMesh.hxx \ StdMeshers_NumberOfLayers.hxx \ + StdMeshers_NumberOfLayers2D.hxx \ StdMeshers_Prism_3D.hxx \ StdMeshers_ProjectionSource1D.hxx \ StdMeshers_ProjectionSource2D.hxx \ @@ -59,6 +59,7 @@ salomeinclude_HEADERS = \ StdMeshers_RadialPrism_3D.hxx \ StdMeshers_ProjectionUtils.hxx \ StdMeshers_LayerDistribution.hxx \ + StdMeshers_LayerDistribution2D.hxx \ StdMeshers_SegmentAroundVertex_0D.hxx \ StdMeshers_SegmentLengthAroundVertex.hxx \ StdMeshers_FaceSide.hxx \ @@ -66,9 +67,18 @@ salomeinclude_HEADERS = \ StdMeshers_UseExisting_1D2D.hxx \ StdMeshers_QuadToTriaAdaptor.hxx \ SMESH_StdMeshers.hxx \ - StdMeshers_TrianglePreference.hxx \ StdMeshers_CompositeHexa_3D.hxx \ - StdMeshers_MaxLength.hxx + StdMeshers_MaxLength.hxx \ + StdMeshers_QuadrangleParams.hxx \ + StdMeshers_RadialQuadrangle_1D2D.hxx \ + StdMeshers_HexaFromSkin_3D.hxx \ + StdMeshers_ImportSource.hxx \ + StdMeshers_Import_1D.hxx \ + StdMeshers_Import_1D2D.hxx \ + StdMeshers_ViscousLayers.hxx \ + StdMeshers_Projection_1D2D.hxx \ + StdMeshers_CartesianParameters3D.hxx \ + StdMeshers_Cartesian_3D.hxx # Libraries targets @@ -78,6 +88,7 @@ dist_libStdMeshers_la_SOURCES = \ StdMeshers_LocalLength.cxx \ StdMeshers_StartEndLength.cxx \ StdMeshers_Arithmetic1D.cxx \ + StdMeshers_FixedPoints1D.cxx \ StdMeshers_NumberOfSegments.cxx \ StdMeshers_Deflection1D.cxx \ StdMeshers_Propagation.cxx \ @@ -95,6 +106,7 @@ dist_libStdMeshers_la_SOURCES = \ StdMeshers_QuadranglePreference.cxx \ StdMeshers_QuadraticMesh.cxx \ StdMeshers_NumberOfLayers.cxx \ + StdMeshers_NumberOfLayers2D.cxx \ StdMeshers_Prism_3D.cxx \ StdMeshers_ProjectionSource1D.cxx \ StdMeshers_ProjectionSource2D.cxx \ @@ -105,25 +117,35 @@ dist_libStdMeshers_la_SOURCES = \ StdMeshers_RadialPrism_3D.cxx \ StdMeshers_ProjectionUtils.cxx \ StdMeshers_LayerDistribution.cxx \ + StdMeshers_LayerDistribution2D.cxx \ StdMeshers_SegmentAroundVertex_0D.cxx \ StdMeshers_SegmentLengthAroundVertex.cxx \ StdMeshers_FaceSide.cxx \ StdMeshers_CompositeSegment_1D.cxx \ StdMeshers_UseExisting_1D2D.cxx \ StdMeshers_QuadToTriaAdaptor.cxx \ - StdMeshers_TrianglePreference.cxx \ StdMeshers_CompositeHexa_3D.cxx \ - StdMeshers_MaxLength.cxx - + StdMeshers_MaxLength.cxx \ + StdMeshers_QuadrangleParams.cxx \ + StdMeshers_RadialQuadrangle_1D2D.cxx \ + StdMeshers_HexaFromSkin_3D.cxx \ + StdMeshers_ImportSource.cxx \ + StdMeshers_Import_1D.cxx \ + StdMeshers_Import_1D2D.cxx \ + StdMeshers_ViscousLayers.cxx \ + StdMeshers_Projection_1D2D.cxx \ + StdMeshers_CartesianParameters3D.cxx \ + StdMeshers_Cartesian_3D.cxx # additionnal information to compil and link file libStdMeshers_la_CPPFLAGS = \ $(CAS_CPPFLAGS) \ $(BOOST_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(KERNEL_CXXFLAGS) \ $(GUI_CXXFLAGS) \ - -I$(srcdir)/../SMESHImpl \ -I$(srcdir)/../MEFISTO2 \ + -I$(srcdir)/../SMESHUtils \ -I$(srcdir)/../SMESH \ -I$(srcdir)/../SMESHDS \ -I$(srcdir)/../SMDS \ @@ -132,8 +154,12 @@ libStdMeshers_la_CPPFLAGS = \ libStdMeshers_la_LDFLAGS = \ ../SMESH/libSMESHimpl.la \ - ../SMESH_I/libSMESHEngine.la \ ../SMESHDS/libSMESHDS.la \ ../MEFISTO2/libMEFISTO2D.la \ $(KERNEL_LDFLAGS) -lSALOMELocalTrace -lOpUtil \ $(CAS_LDPATH) -lTKAdvTools -lTKTopAlgo -lTKG3d + +if WITH_TBB + libStdMeshers_la_CPPFLAGS += $(TBB_INCLUDES) + libStdMeshers_la_LDFLAGS += $(TBB_LIBS) +endif diff --git a/src/StdMeshers/SMESH_StdMeshers.hxx b/src/StdMeshers/SMESH_StdMeshers.hxx index be440c1bd..50e53acdd 100755 --- a/src/StdMeshers/SMESH_StdMeshers.hxx +++ b/src/StdMeshers/SMESH_StdMeshers.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_StdMeshers.hxx // Author : Alexander BORODIN // Module : SMESH @@ -28,7 +29,7 @@ #define _SMESH_StdMeshers_HXX_ #ifdef WNT - #if defined STDMESHERS_EXPORTS + #if defined STDMESHERS_EXPORTS || defined StdMeshers_EXPORTS #define STDMESHERS_EXPORT __declspec( dllexport ) #else #define STDMESHERS_EXPORT __declspec( dllimport ) diff --git a/src/StdMeshers/StdMeshers_Arithmetic1D.cxx b/src/StdMeshers/StdMeshers_Arithmetic1D.cxx index f5ac03c5e..589972c8b 100644 --- a/src/StdMeshers/StdMeshers_Arithmetic1D.cxx +++ b/src/StdMeshers/StdMeshers_Arithmetic1D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Arithmetic1D.cxx // Author : Damien COQUERET, OCC @@ -104,9 +105,32 @@ double StdMeshers_Arithmetic1D::GetLength(bool isStartLength) const */ //============================================================================= +void StdMeshers_Arithmetic1D::SetReversedEdges( std::vector& ids ) +{ + if ( ids != _edgeIDs ) { + _edgeIDs = ids; + + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + ostream & StdMeshers_Arithmetic1D::SaveTo(ostream & save) { - save << _begLength << " " << _endLength; + int listSize = _edgeIDs.size(); + save << _begLength << " " << _endLength << " " << listSize; + + if ( listSize > 0 ) { + for ( int i = 0; i < listSize; i++) + save << " " << _edgeIDs[i]; + save << " " << _objEntry; + } + return save; } @@ -119,12 +143,25 @@ ostream & StdMeshers_Arithmetic1D::SaveTo(ostream & save) istream & StdMeshers_Arithmetic1D::LoadFrom(istream & load) { bool isOK = true; + int intVal; isOK = (load >> _begLength); if (!isOK) load.clear(ios::badbit | load.rdstate()); isOK = (load >> _endLength); + if (!isOK) load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> intVal); + if (isOK && intVal > 0) { + _edgeIDs.reserve( intVal ); + for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) { + isOK = (load >> intVal); + if ( isOK ) _edgeIDs.push_back( intVal ); + } + isOK = (load >> _objEntry); + } + return load; } @@ -177,7 +214,7 @@ bool StdMeshers_Arithmetic1D::SetParametersByMesh(const SMESH_Mesh* theMesh, { const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( i )); Handle(Geom_Curve) C = BRep_Tool::Curve(edge, L, UMin, UMax); - GeomAdaptor_Curve AdaptCurve(C); + GeomAdaptor_Curve AdaptCurve(C, UMin, UMax); vector< double > params; SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS(); @@ -206,6 +243,6 @@ bool StdMeshers_Arithmetic1D::SetParametersByMesh(const SMESH_Mesh* theMesh, bool StdMeshers_Arithmetic1D::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*mesh*/) { - return bool( _begLength = _endLength = dflts._elemLength ); + return ( _begLength = _endLength = dflts._elemLength ); } diff --git a/src/StdMeshers/StdMeshers_Arithmetic1D.hxx b/src/StdMeshers/StdMeshers_Arithmetic1D.hxx index 94952b774..168b6b657 100644 --- a/src/StdMeshers/StdMeshers_Arithmetic1D.hxx +++ b/src/StdMeshers/StdMeshers_Arithmetic1D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Arithmetic1D.hxx // Author : Damien COQUERET, OCC @@ -27,11 +28,15 @@ #ifndef _SMESH_ARITHMETIC1D_HXX_ #define _SMESH_ARITHMETIC1D_HXX_ + + #include "SMESH_StdMeshers.hxx" #include "SMESH_Hypothesis.hxx" #include "Utils_SALOME_Exception.hxx" +#include + class STDMESHERS_EXPORT StdMeshers_Arithmetic1D: public SMESH_Hypothesis { @@ -43,6 +48,14 @@ public: double GetLength(bool isStartLength) const; + void SetReversedEdges( std::vector& ids); + + void SetObjectEntry( const char* entry ) { _objEntry = entry; } + + const char* GetObjectEntry() { return _objEntry.c_str(); } + + const std::vector& GetReversedEdges() const { return _edgeIDs; } + virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); friend std::ostream& operator << (std::ostream & save, StdMeshers_Arithmetic1D & hyp); @@ -64,6 +77,8 @@ public: protected: double _begLength, _endLength; + std::vector _edgeIDs; + std::string _objEntry; }; #endif diff --git a/src/StdMeshers/StdMeshers_AutomaticLength.cxx b/src/StdMeshers/StdMeshers_AutomaticLength.cxx index 95710c94e..d12f51a34 100644 --- a/src/StdMeshers/StdMeshers_AutomaticLength.cxx +++ b/src/StdMeshers/StdMeshers_AutomaticLength.cxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_AutomaticLength.cxx // Author : Edward AGAPOV, OCC // Module : SMESH -// + #include "StdMeshers_AutomaticLength.hxx" #include "SMESH_Mesh.hxx" @@ -116,7 +117,7 @@ namespace { */ //================================================================================ - const double a14divPI = 14. / PI; + const double a14divPI = 14. / M_PI; inline double segLength(double S0, double edgeLen, double minLen ) { @@ -398,5 +399,3 @@ bool StdMeshers_AutomaticLength::SetParametersByDefaults(const TDefaults& /*the // return true; } - - diff --git a/src/StdMeshers/StdMeshers_AutomaticLength.hxx b/src/StdMeshers/StdMeshers_AutomaticLength.hxx index 627003aa6..089b935ac 100644 --- a/src/StdMeshers/StdMeshers_AutomaticLength.hxx +++ b/src/StdMeshers/StdMeshers_AutomaticLength.hxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_AutomaticLength.hxx // Author : Edward AGAPOV, OCC // Module : SMESH - +// #ifndef _SMESH_AutomaticLength_HXX_ #define _SMESH_AutomaticLength_HXX_ diff --git a/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx b/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx new file mode 100644 index 000000000..9446e123d --- /dev/null +++ b/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx @@ -0,0 +1,453 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_CartesianParameters3D.cxx +// Author : Edward AGAPOV +// Module : SMESH +// +#include "StdMeshers_CartesianParameters3D.hxx" + +#include "StdMeshers_NumberOfSegments.hxx" +#include "StdMeshers_Distribution.hxx" +#include "SMESH_Gen.hxx" + +#include "utilities.h" + +#include +#include + +#include + +using namespace std; + +//======================================================================= +//function : StdMeshers_CartesianParameters3D +//purpose : Constructor +//======================================================================= + +StdMeshers_CartesianParameters3D::StdMeshers_CartesianParameters3D(int hypId, + int studyId, + SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, studyId, gen), + _sizeThreshold( 4.0 ) // default according to the customer specification +{ + _name = "CartesianParameters3D"; // used by "Cartesian_3D" + _param_algo_dim = 3; // 3D +} + + +namespace +{ + const char* axisName[3] = { "X", "Y", "Z" }; + + //================================================================================ + /*! + * \brief Checks validity of an axis index, throws in case of invalidity + */ + //================================================================================ + + void checkAxis(const int axis) + { + if ( axis < 0 || axis > 2 ) + throw SALOME_Exception(SMESH_Comment("Invalid axis index ") << axis << + ". Valid axis indices are 0, 1 and 2"); + } + + //================================================================================ + /*! + * \brief Checks validity of spacing data, throws in case of invalidity + */ + //================================================================================ + + void checkGridSpacing(std::vector& spaceFunctions, + std::vector& internalPoints, + const std::string& axis) + throw ( SALOME_Exception ) + { + if ( spaceFunctions.empty() ) + throw SALOME_Exception(SMESH_Comment("Empty space function for ") << axis ); + + for ( size_t i = 1; i < internalPoints.size(); ++i ) + if ( internalPoints[i] - internalPoints[i-1] < 0 ) + throw SALOME_Exception(SMESH_Comment("Wrong order of internal points along ") << axis); + else if ( internalPoints[i] - internalPoints[i-1] < 1e-3 ) + throw SALOME_Exception(SMESH_Comment("Too close internal points along ") << axis ); + + const double tol = Precision::Confusion(); + if ( !internalPoints.empty() && + ( internalPoints.front() < -tol || internalPoints.back() > 1 + tol )) + throw SALOME_Exception(SMESH_Comment("Invalid internal points along ") << axis); + + if ( internalPoints.empty() || internalPoints.front() > tol ) + internalPoints.insert( internalPoints.begin(), 0. ); + if ( internalPoints.size() < 2 || internalPoints.back() < 1 - tol ) + internalPoints.push_back( 1. ); + + if ( internalPoints.size() != spaceFunctions.size() + 1 ) + throw SALOME_Exception + (SMESH_Comment("Numbre of internal points mismatch number of functions for ") << axis); + + for ( size_t i = 0; i < spaceFunctions.size(); ++i ) + spaceFunctions[i] = + StdMeshers_NumberOfSegments::CheckExpressionFunction( spaceFunctions[i], -1 ); + } +} + +//======================================================================= +//function : SetGrid +//purpose : Sets coordinates of node positions along an axes +//======================================================================= + +void StdMeshers_CartesianParameters3D::SetGrid(std::vector& coords, int axis) + throw ( SALOME_Exception ) +{ + checkAxis( axis ); + + if ( coords.size() < 2 ) + throw SALOME_Exception(LOCALIZED("Wrong number of grid coordinates")); + + std::sort( coords.begin(), coords.end() ); + + bool changed = ( _coords[axis] != coords ); + if ( changed ) + { + _coords[axis] = coords; + NotifySubMeshesHypothesisModification(); + } + + _spaceFunctions[axis].clear(); + _internalPoints[axis].clear(); +} + +//======================================================================= +//function : SetGridSpacing +//purpose : Set grid spacing along the three axes +//======================================================================= + +void StdMeshers_CartesianParameters3D::SetGridSpacing(std::vector& xSpaceFuns, + std::vector& xInternalPoints, + const int axis) + throw ( SALOME_Exception ) +{ + checkAxis( axis ); + + checkGridSpacing( xSpaceFuns, xInternalPoints, axisName[axis] ); + + bool changed = ( xSpaceFuns != _spaceFunctions[axis] || + xInternalPoints != _internalPoints[axis] ); + + _spaceFunctions[axis] = xSpaceFuns; + _internalPoints[axis] = xInternalPoints; + _coords[axis].clear(); + + if ( changed ) + NotifySubMeshesHypothesisModification(); +} + +//======================================================================= +//function : SetSizeThreshold +//purpose : Set size threshold +//======================================================================= + +void StdMeshers_CartesianParameters3D::SetSizeThreshold(const double threshold) + throw ( SALOME_Exception ) +{ + if ( threshold <= 1.0 ) + throw SALOME_Exception(LOCALIZED("threshold must be > 1.0")); + + bool changed = fabs( _sizeThreshold - threshold ) > 1e-6; + _sizeThreshold = threshold; + + if ( changed ) + NotifySubMeshesHypothesisModification(); +} + +//======================================================================= +//function : GetGridSpacing +//purpose : return spacing +//======================================================================= + +void StdMeshers_CartesianParameters3D::GetGridSpacing(std::vector& spaceFunctions, + std::vector& internalPoints, + const int axis) const + throw ( SALOME_Exception ) +{ + if ( !IsGridBySpacing(axis) ) + throw SALOME_Exception(LOCALIZED("The grid is defined by coordinates and not by spacing")); + + spaceFunctions = _spaceFunctions[axis]; + internalPoints = _internalPoints[axis]; +} + +//======================================================================= +//function : IsGridBySpacing +//======================================================================= + +bool StdMeshers_CartesianParameters3D::IsGridBySpacing(const int axis) const + throw ( SALOME_Exception ) +{ + checkAxis(axis); + return !_spaceFunctions[axis].empty(); +} + + +//======================================================================= +//function : ComputeCoordinates +//purpose : Computes node coordinates by spacing functions +//======================================================================= + +void StdMeshers_CartesianParameters3D::ComputeCoordinates(const double x0, + const double x1, + vector& spaceFuns, + vector& points, + vector& coords, + const std::string& axis ) + throw ( SALOME_Exception ) +{ + checkGridSpacing( spaceFuns, points, axis ); + + coords.clear(); + for ( size_t i = 0; i < spaceFuns.size(); ++i ) + { + FunctionExpr fun( spaceFuns[i].c_str(), /*convMode=*/-1 ); + + const double p0 = x0 * ( 1. - points[i]) + x1 * points[i]; + const double p1 = x0 * ( 1. - points[i+1]) + x1 * points[i+1]; + const double length = p1 - p0; + + const size_t nbSections = 1000; + const double sectionLen = ( p1 - p0 ) / nbSections; + vector< double > nbSegments( nbSections + 1 ); + nbSegments[ 0 ] = 0.; + + double t, spacing = 0; + for ( size_t i = 1; i <= nbSections; ++i ) + { + t = double( i ) / nbSections; + if ( !fun.value( t, spacing ) || spacing < std::numeric_limits::min() ) + throw SALOME_Exception(LOCALIZED("Invalid spacing function")); + nbSegments[ i ] = nbSegments[ i-1 ] + std::min( 1., sectionLen / spacing ); + } + + const int nbCells = max (1, int(floor(nbSegments.back()+0.5))); + const double corr = nbCells / nbSegments.back(); + + if ( coords.empty() ) coords.push_back( p0 ); + + for ( size_t iCell = 1, i = 1; i <= nbSections; ++i ) + { + if ( nbSegments[i]*corr >= iCell ) + { + t = (i - ( nbSegments[i] - iCell/corr )/( nbSegments[i] - nbSegments[i-1] )) / nbSections; + coords.push_back( p0 + t * length ); + ++iCell; + } + } + const double lastCellLen = coords.back() - coords[ coords.size() - 2 ]; + if ( fabs( coords.back() - p1 ) > 0.5 * lastCellLen ) + coords.push_back ( p1 ); + } +} + +//======================================================================= +//function : GetCoordinates +//purpose : Return coordinates of node positions along the three axes. +// If the grid is defined by spacing functions, the coordinates are computed +//======================================================================= + +void StdMeshers_CartesianParameters3D::GetCoordinates(std::vector& xNodes, + std::vector& yNodes, + std::vector& zNodes, + const Bnd_Box& bndBox) const + throw ( SALOME_Exception ) +{ + double x0,y0,z0, x1,y1,z1; + if ( IsGridBySpacing(0) || IsGridBySpacing(1) || IsGridBySpacing(2)) + { + if ( bndBox.IsVoid() || + bndBox.IsXThin( Precision::Confusion() ) || + bndBox.IsYThin( Precision::Confusion() ) || + bndBox.IsZThin( Precision::Confusion() ) ) + throw SALOME_Exception(LOCALIZED("Invalid bounding box")); + bndBox.Get(x0,y0,z0, x1,y1,z1); + } + + StdMeshers_CartesianParameters3D* me = const_cast(this); + if ( IsGridBySpacing(0) ) + ComputeCoordinates( x0, x1, me->_spaceFunctions[0], me->_internalPoints[0], xNodes, "X" ); + else + xNodes = _coords[0]; + + if ( IsGridBySpacing(1) ) + ComputeCoordinates( y0, y1, me->_spaceFunctions[1], me->_internalPoints[1], yNodes, "Y" ); + else + yNodes = _coords[1]; + + if ( IsGridBySpacing(2) ) + ComputeCoordinates( z0, z1, me->_spaceFunctions[2], me->_internalPoints[2], zNodes, "Z" ); + else + zNodes = _coords[2]; +} + +//======================================================================= +//function : GetGrid +//purpose : Return coordinates of node positions along the three axes +//======================================================================= + +void StdMeshers_CartesianParameters3D::GetGrid(std::vector& coords, int axis) const + throw ( SALOME_Exception ) +{ + if ( IsGridBySpacing(axis) ) + throw SALOME_Exception(LOCALIZED("The grid is defined by spacing and not by coordinates")); + + coords = _coords[axis]; +} + +//======================================================================= +//function : GetSizeThreshold +//purpose : Return size threshold +//======================================================================= + +double StdMeshers_CartesianParameters3D::GetSizeThreshold() const +{ + return _sizeThreshold; +} + +//======================================================================= +//function : IsDefined +//purpose : Return true if parameters are well defined +//======================================================================= + +bool StdMeshers_CartesianParameters3D::IsDefined() const +{ + for ( int i = 0; i < 3; ++i ) + if (_coords[i].empty() && (_spaceFunctions[i].empty() || _internalPoints[i].empty())) + return false; + + return ( _sizeThreshold > 1.0 ); +} + +//======================================================================= +//function : SaveTo +//purpose : store my parameters into a stream +//======================================================================= + +std::ostream & StdMeshers_CartesianParameters3D::SaveTo(std::ostream & save) +{ + save << _sizeThreshold << " "; + + for ( int i = 0; i < 3; ++i ) + { + save << _coords[i].size() << " "; + for ( size_t j = 0; j < _coords[i].size(); ++j ) + save << _coords[i][j] << " "; + + save << _internalPoints[i].size() << " "; + for ( size_t j = 0; j < _internalPoints[i].size(); ++j ) + save << _internalPoints[i][j] << " "; + + save << _spaceFunctions[i].size() << " "; + for ( size_t j = 0; j < _spaceFunctions[i].size(); ++j ) + save << _spaceFunctions[i][j] << " "; + } + + return save; +} + +//======================================================================= +//function : LoadFrom +//purpose : resore my parameters from a stream +//======================================================================= + +std::istream & StdMeshers_CartesianParameters3D::LoadFrom(std::istream & load) +{ + bool ok; + + ok = (load >> _sizeThreshold ); + for ( int ax = 0; ax < 3; ++ax ) + { + if (ok) + { + size_t i = 0; + ok = (load >> i ); + if ( i > 0 && ok ) + { + _coords[ax].resize( i ); + for ( i = 0; i < _coords[ax].size() && ok; ++i ) + ok = (load >> _coords[ax][i] ); + } + } + if (ok) + { + size_t i = 0; + ok = (load >> i ); + if ( i > 0 && ok ) + { + _internalPoints[ax].resize( i ); + for ( i = 0; i < _internalPoints[ax].size() && ok; ++i ) + ok = (load >> _internalPoints[ax][i] ); + } + } + if (ok) + { + size_t i = 0; + ok = (load >> i ); + if ( i > 0 && ok ) + { + _spaceFunctions[ax].resize( i ); + for ( i = 0; i < _spaceFunctions[ax].size() && ok; ++i ) + ok = (load >> _spaceFunctions[ax][i] ); + } + } + } + return load; +} + +//======================================================================= +//function : SetParametersByMesh +//======================================================================= + +bool StdMeshers_CartesianParameters3D::SetParametersByMesh(const SMESH_Mesh* , + const TopoDS_Shape& ) +{ + return false; +} + +//======================================================================= +//function : SetParametersByDefaults +//======================================================================= + +bool StdMeshers_CartesianParameters3D::SetParametersByDefaults(const TDefaults& dflts, + const SMESH_Mesh* /*theMesh*/) +{ + if ( dflts._elemLength > 1e-100 ) + { + vector spacing( 1, SMESH_Comment(dflts._elemLength)); + vector intPnts; + SetGridSpacing( spacing, intPnts, 0 ); + SetGridSpacing( spacing, intPnts, 1 ); + SetGridSpacing( spacing, intPnts, 2 ); + return true; + } + return false; +} + diff --git a/src/StdMeshers/StdMeshers_CartesianParameters3D.hxx b/src/StdMeshers/StdMeshers_CartesianParameters3D.hxx new file mode 100644 index 000000000..682ce4c53 --- /dev/null +++ b/src/StdMeshers/StdMeshers_CartesianParameters3D.hxx @@ -0,0 +1,145 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_CartesianParameters3D.hxx +// Author : Edward AGAPOV +// Module : SMESH +// +#ifndef _SMESH_CartesianParameters3D_HXX_ +#define _SMESH_CartesianParameters3D_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +#include + +class SMESH_Gen; +class Bnd_Box; + +// ========================================================= +/*! + * This hypothesis specifies + * - Definition of the Cartesian grid + * - Size threshold + */ +// ========================================================= + +class STDMESHERS_EXPORT StdMeshers_CartesianParameters3D: public SMESH_Hypothesis +{ +public: + // Constructor + StdMeshers_CartesianParameters3D( int hypId, int studyId, SMESH_Gen * gen ); + + /*! + * Sets coordinates of node positions along an axis (countered from 0) + */ + void SetGrid(std::vector& xNodes, int axis) throw ( SALOME_Exception ); + /*! + * Return coordinates of node positions along the three axes + */ + void GetGrid(std::vector& xNodes, int axis) const throw ( SALOME_Exception ); + + /*! + * \brief Set grid spacing along the three axes + * \param spaceFunctions - functions defining spacing values at given point on axis + * \param internalPoints - points dividing a grid into parts along each direction + * + * Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of + * the shape to mesh + */ + void SetGridSpacing(std::vector& spaceFunctions, + std::vector& internalPoints, + const int axis) throw ( SALOME_Exception ); + + void GetGridSpacing(std::vector& spaceFunctions, + std::vector& internalPoints, + const int axis) const throw ( SALOME_Exception ); + + bool IsGridBySpacing(const int axis) const throw ( SALOME_Exception ); + + /*! + * \brief Computes node coordinates by spacing functions + * \param x0 - lower coordinate + * \param x1 - upper coordinate + * \param spaceFuns - space functions + * \param points - internal points + * \param coords - the computed coordinates + */ + static void ComputeCoordinates(const double x0, + const double x1, + std::vector& spaceFuns, + std::vector& points, + std::vector& coords, + const std::string& axis ) throw (SALOME_Exception); + /*! + * Return coordinates of node positions along the three axes. + * If the grid is defined by spacing functions, the coordinates are computed + */ + void GetCoordinates(std::vector& xNodes, + std::vector& yNodes, + std::vector& zNodes, + const Bnd_Box& bndBox) const throw ( SALOME_Exception ); + /*! + * Set size threshold. A polyhedral cell got by cutting an initial + * hexahedron by geometry boundary is considered small and is removed if + * it's size is \athreshold times less than the size of the initial hexahedron. + */ + void SetSizeThreshold(const double threshold) throw ( SALOME_Exception ); + /*! + * \brief Return size threshold + */ + double GetSizeThreshold() const; + + /*! + * \brief Return true if parameters are well defined + */ + bool IsDefined() const; + + /*! + * \brief Persistence methods + */ + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + + /*! + * \brief Initialize my parameter values by the mesh built on the geometry + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + + /*! + * \brief Initialize my parameter values by default parameters. + */ + virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + + protected: + + std::vector _coords[3]; + std::vector _spaceFunctions[3]; + std::vector _internalPoints[3]; + + double _sizeThreshold; +}; + +#endif + diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx new file mode 100644 index 000000000..c1e57198f --- /dev/null +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx @@ -0,0 +1,2185 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_Cartesian_3D.cxx +// Module : SMESH +// +#include "StdMeshers_Cartesian_3D.hxx" + +#include "SMDS_MeshNode.hxx" +#include "SMESH_Block.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_subMeshEventListener.hxx" +#include "StdMeshers_CartesianParameters3D.hxx" + +#include "utilities.h" +#include "Utils_ExceptHandlers.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#undef WITH_TBB +#ifdef WITH_TBB +#include +//#include +#endif + +using namespace std; + +//#define _MY_DEBUG_ + +#define ELLIPSOLID_WORKAROUND // remove it as soon as http://tracker.dev.opencascade.org/view.php?id=22809 is solved + +#ifdef ELLIPSOLID_WORKAROUND +#include +#include +#include +#endif + +//============================================================================= +/*! + * Constructor + */ +//============================================================================= + +StdMeshers_Cartesian_3D::StdMeshers_Cartesian_3D(int hypId, int studyId, SMESH_Gen * gen) + :SMESH_3D_Algo(hypId, studyId, gen) +{ + _name = "Cartesian_3D"; + _shapeType = (1 << TopAbs_SOLID); // 1 bit /shape type + _compatibleHypothesis.push_back("CartesianParameters3D"); + + _onlyUnaryInput = false; // to mesh all SOLIDs at once + _requireDiscreteBoundary = false; // 2D mesh not needed + _supportSubmeshes = false; // do not use any existing mesh +} + +//============================================================================= +/*! + * Check presence of a hypothesis + */ +//============================================================================= + +bool StdMeshers_Cartesian_3D::CheckHypothesis (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus) +{ + aStatus = SMESH_Hypothesis::HYP_MISSING; + + const list& hyps = GetUsedHypothesis(aMesh, aShape); + list ::const_iterator h = hyps.begin(); + if ( h == hyps.end()) + { + return false; + } + + for ( ; h != hyps.end(); ++h ) + { + if (( _hyp = dynamic_cast( *h ))) + { + aStatus = _hyp->IsDefined() ? HYP_OK : HYP_BAD_PARAMETER; + break; + } + } + + return aStatus == HYP_OK; +} + +namespace +{ + //============================================================================= + // Definitions of internal utils + // -------------------------------------------------------------------------- + enum Transition { + Trans_TANGENT = IntCurveSurface_Tangent, + Trans_IN = IntCurveSurface_In, + Trans_OUT = IntCurveSurface_Out, + Trans_APEX + }; + // -------------------------------------------------------------------------- + /*! + * \brief Data of intersection between a GridLine and a TopoDS_Face + */ + struct IntersectionPoint + { + double _paramOnLine; + mutable Transition _transition; + mutable const SMDS_MeshNode* _node; + mutable size_t _indexOnLine; + + IntersectionPoint(): _node(0) {} + bool operator< ( const IntersectionPoint& o ) const { return _paramOnLine < o._paramOnLine; } + }; + // -------------------------------------------------------------------------- + /*! + * \brief A line of the grid and its intersections with 2D geometry + */ + struct GridLine + { + gp_Lin _line; + double _length; // line length + multiset< IntersectionPoint > _intPoints; + + void RemoveExcessIntPoints( const double tol ); + bool GetIsOutBefore( multiset< IntersectionPoint >::iterator ip, bool prevIsOut ); + }; + // -------------------------------------------------------------------------- + /*! + * \brief Iterator on the parallel grid lines of one direction + */ + struct LineIndexer + { + size_t _size [3]; + size_t _curInd[3]; + size_t _iVar1, _iVar2, _iConst; + string _name1, _name2, _nameConst; + LineIndexer() {} + LineIndexer( size_t sz1, size_t sz2, size_t sz3, + size_t iv1, size_t iv2, size_t iConst, + const string& nv1, const string& nv2, const string& nConst ) + { + _size[0] = sz1; _size[1] = sz2; _size[2] = sz3; + _curInd[0] = _curInd[1] = _curInd[2] = 0; + _iVar1 = iv1; _iVar2 = iv2; _iConst = iConst; + _name1 = nv1; _name2 = nv2; _nameConst = nConst; + } + + size_t I() const { return _curInd[0]; } + size_t J() const { return _curInd[1]; } + size_t K() const { return _curInd[2]; } + void SetIJK( size_t i, size_t j, size_t k ) + { + _curInd[0] = i; _curInd[1] = j; _curInd[2] = k; + } + void operator++() + { + if ( ++_curInd[_iVar1] == _size[_iVar1] ) + _curInd[_iVar1] = 0, ++_curInd[_iVar2]; + } + bool More() const { return _curInd[_iVar2] < _size[_iVar2]; } + size_t LineIndex () const { return _curInd[_iVar1] + _curInd[_iVar2]* _size[_iVar1]; } + size_t LineIndex10 () const { return (_curInd[_iVar1] + 1 ) + _curInd[_iVar2]* _size[_iVar1]; } + size_t LineIndex01 () const { return _curInd[_iVar1] + (_curInd[_iVar2] + 1 )* _size[_iVar1]; } + size_t LineIndex11 () const { return (_curInd[_iVar1] + 1 ) + (_curInd[_iVar2] + 1 )* _size[_iVar1]; } + void SetIndexOnLine (size_t i) { _curInd[ _iConst ] = i; } + size_t NbLines() const { return _size[_iVar1] * _size[_iVar2]; } + }; + // -------------------------------------------------------------------------- + /*! + * \brief Container of GridLine's + */ + struct Grid + { + vector< double > _coords[3]; // coordinates of grid nodes + vector< GridLine > _lines [3]; // in 3 directions + double _tol, _minCellSize; + + vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes + vector< bool > _isBndNode; // is mesh node at intersection with geometry + + size_t CellIndex( size_t i, size_t j, size_t k ) const + { + return i + j*(_coords[0].size()-1) + k*(_coords[0].size()-1)*(_coords[1].size()-1); + } + size_t NodeIndex( size_t i, size_t j, size_t k ) const + { + return i + j*_coords[0].size() + k*_coords[0].size()*_coords[1].size(); + } + size_t NodeIndexDX() const { return 1; } + size_t NodeIndexDY() const { return _coords[0].size(); } + size_t NodeIndexDZ() const { return _coords[0].size() * _coords[1].size(); } + + LineIndexer GetLineIndexer(size_t iDir) const; + + void SetCoordinates(const vector& xCoords, + const vector& yCoords, + const vector& zCoords, + const TopoDS_Shape& shape ); + void ComputeNodes(SMESH_MesherHelper& helper); + }; +#ifdef ELLIPSOLID_WORKAROUND + // -------------------------------------------------------------------------- + /*! + * \brief struct temporary replacing IntCurvesFace_Intersector until + * OCCT bug 0022809 is fixed + * http://tracker.dev.opencascade.org/view.php?id=22809 + */ + struct TMP_IntCurvesFace_Intersector + { + BRepAdaptor_Surface _surf; + double _tol; + BRepIntCurveSurface_Inter _intcs; + vector _points; + BRepTopAdaptor_TopolTool _clsf; + + TMP_IntCurvesFace_Intersector(const TopoDS_Face& face, const double tol) + :_surf( face ), _tol( tol ), _clsf( new BRepAdaptor_HSurface(_surf) ) {} + Bnd_Box Bounding() const { Bnd_Box b; BRepBndLib::Add (_surf.Face(), b); return b; } + void Perform( const gp_Lin& line, const double w0, const double w1 ) + { + _points.clear(); + for ( _intcs.Init( _surf.Face(), line, _tol ); _intcs.More(); _intcs.Next() ) + if ( w0 <= _intcs.W() && _intcs.W() <= w1 ) + _points.push_back( _intcs.Point() ); + } + bool IsDone() const { return true; } + int NbPnt() const { return _points.size(); } + IntCurveSurface_TransitionOnCurve Transition( const int i ) const { return _points[ i-1 ].Transition(); } + double WParameter( const int i ) const { return _points[ i-1 ].W(); } + TopAbs_State ClassifyUVPoint(const gp_Pnt2d& p) { return _clsf.Classify( p, _tol ); } + }; +#define __IntCurvesFace_Intersector TMP_IntCurvesFace_Intersector +#else +#define __IntCurvesFace_Intersector IntCurvesFace_Intersector +#endif + // -------------------------------------------------------------------------- + /*! + * \brief Intersector of TopoDS_Face with all GridLine's + */ + struct FaceGridIntersector + { + TopoDS_Face _face; + Grid* _grid; + Bnd_Box _bndBox; + __IntCurvesFace_Intersector* _surfaceInt; + vector< std::pair< GridLine*, IntersectionPoint > > _intersections; + + FaceGridIntersector(): _grid(0), _surfaceInt(0) {} + void Intersect(); + bool IsInGrid(const Bnd_Box& gridBox); + + void StoreIntersections() + { + for ( size_t i = 0; i < _intersections.size(); ++i ) + _intersections[i].first->_intPoints.insert( _intersections[i].second ); + } + const Bnd_Box& GetFaceBndBox() + { + GetCurveFaceIntersector(); + return _bndBox; + } + __IntCurvesFace_Intersector* GetCurveFaceIntersector() + { + if ( !_surfaceInt ) + { + _surfaceInt = new __IntCurvesFace_Intersector( _face, Precision::PConfusion() ); + _bndBox = _surfaceInt->Bounding(); + if ( _bndBox.IsVoid() ) + BRepBndLib::Add (_face, _bndBox); + } + return _surfaceInt; + } + bool IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const; + }; + // -------------------------------------------------------------------------- + /*! + * \brief Intersector of a surface with a GridLine + */ + struct FaceLineIntersector + { + double _tol; + double _u, _v, _w; // params on the face and the line + Transition _transition; // transition of at intersection (see IntCurveSurface.cdl) + Transition _transIn, _transOut; // IN and OUT transitions depending of face orientation + + gp_Pln _plane; + gp_Cylinder _cylinder; + gp_Cone _cone; + gp_Sphere _sphere; + gp_Torus _torus; + __IntCurvesFace_Intersector* _surfaceInt; + + vector< IntersectionPoint > _intPoints; + + void IntersectWithPlane (const GridLine& gridLine); + void IntersectWithCylinder(const GridLine& gridLine); + void IntersectWithCone (const GridLine& gridLine); + void IntersectWithSphere (const GridLine& gridLine); + void IntersectWithTorus (const GridLine& gridLine); + void IntersectWithSurface (const GridLine& gridLine); + + bool UVIsOnFace() const; + void addIntPoint(const bool toClassify=true); + bool isParamOnLineOK( const double linLength ) + { + return -_tol < _w && _w < linLength + _tol; + } + FaceLineIntersector():_surfaceInt(0) {} + ~FaceLineIntersector() { if (_surfaceInt ) delete _surfaceInt; _surfaceInt = 0; } + }; + // -------------------------------------------------------------------------- + /*! + * \brief Class representing topology of the hexahedron and creating a mesh + * volume basing on analysis of hexahedron intersection with geometry + */ + class Hexahedron + { + // -------------------------------------------------------------------------------- + struct _Face; + struct _Link; + // -------------------------------------------------------------------------------- + struct _Node //!< node either at a hexahedron corner or at GridLine intersection + { + const SMDS_MeshNode* _node; // mesh node at hexahedron corner + const IntersectionPoint* _intPoint; + + _Node(const SMDS_MeshNode* n=0, const IntersectionPoint* ip=0):_node(n), _intPoint(ip) {} + const SMDS_MeshNode* Node() const { return _intPoint ? _intPoint->_node : _node; } + //bool IsCorner() const { return _node; } + }; + // -------------------------------------------------------------------------------- + struct _Link // link connecting two _Node's + { + _Node* _nodes[2]; + vector< _Node> _intNodes; // _Node's at GridLine intersections + vector< _Link > _splits; + vector< _Face*> _faces; + }; + // -------------------------------------------------------------------------------- + struct _OrientedLink + { + _Link* _link; + bool _reverse; + _OrientedLink( _Link* link=0, bool reverse=false ): _link(link), _reverse(reverse) {} + void Reverse() { _reverse = !_reverse; } + int NbResultLinks() const { return _link->_splits.size(); } + _OrientedLink ResultLink(int i) const + { + return _OrientedLink(&_link->_splits[_reverse ? NbResultLinks()-i-1 : i],_reverse); + } + _Node* FirstNode() const { return _link->_nodes[ _reverse ]; } + _Node* LastNode() const { return _link->_nodes[ !_reverse ]; } + }; + // -------------------------------------------------------------------------------- + struct _Face + { + vector< _OrientedLink > _links; + vector< _Link > _polyLinks; // links added to close a polygonal face + }; + // -------------------------------------------------------------------------------- + struct _volumeDef // holder of nodes of a volume mesh element + { + vector< const SMDS_MeshNode* > _nodes; + vector< int > _quantities; + typedef boost::shared_ptr<_volumeDef> Ptr; + void set( const vector< const SMDS_MeshNode* >& nodes, + const vector< int > quant = vector< int >() ) + { _nodes = nodes; _quantities = quant; } + // static Ptr New( const vector< const SMDS_MeshNode* >& nodes, + // const vector< int > quant = vector< int >() ) + // { + // _volumeDef* def = new _volumeDef; + // def->_nodes = nodes; + // def->_quantities = quant; + // return Ptr( def ); + // } + }; + + // topology of a hexahedron + int _nodeShift[8]; + _Node _hexNodes[8]; + _Link _hexLinks[12]; + _Face _hexQuads[6]; + + // faces resulted from hexahedron intersection + vector< _Face > _polygons; + + // computed volume elements + //vector< _volumeDef::Ptr > _volumeDefs; + _volumeDef _volumeDefs; + + Grid* _grid; + double _sizeThreshold, _sideLength[3]; + int _nbCornerNodes, _nbIntNodes, _nbBndNodes; + int _origNodeInd; // index of _hexNodes[0] node within the _grid + size_t _i,_j,_k; + + public: + Hexahedron(const double sizeThreshold, Grid* grid); + int MakeElements(SMESH_MesherHelper& helper); + void ComputeElements(); + void Init() { init( _i, _j, _k ); } + + private: + Hexahedron(const Hexahedron& other ); + void init( size_t i, size_t j, size_t k ); + void init( size_t i ); + int addElements(SMESH_MesherHelper& helper); + bool isInHole() const; + bool checkPolyhedronSize() const; + bool addHexa (); + bool addTetra(); + bool addPenta(); + bool addPyra (); + }; + +#ifdef WITH_TBB + // -------------------------------------------------------------------------- + /*! + * \brief Hexahedron computing volumes in one thread + */ + struct ParallelHexahedron + { + vector< Hexahedron* >& _hexVec; + vector& _index; + ParallelHexahedron( vector< Hexahedron* >& hv, vector& ind): _hexVec(hv), _index(ind) {} + void operator() ( const tbb::blocked_range& r ) const + { + for ( size_t i = r.begin(); i != r.end(); ++i ) + if ( Hexahedron* hex = _hexVec[ _index[i]] ) + hex->ComputeElements(); + } + }; + // -------------------------------------------------------------------------- + /*! + * \brief Structure intersecting certain nb of faces with GridLine's in one thread + */ + struct ParallelIntersector + { + vector< FaceGridIntersector >& _faceVec; + ParallelIntersector( vector< FaceGridIntersector >& faceVec): _faceVec(faceVec){} + void operator() ( const tbb::blocked_range& r ) const + { + for ( size_t i = r.begin(); i != r.end(); ++i ) + _faceVec[i].Intersect(); + } + }; + +#endif + //============================================================================= + // Implementation of internal utils + //============================================================================= + /* + * Remove coincident intersection points + */ + void GridLine::RemoveExcessIntPoints( const double tol ) + { + if ( _intPoints.size() < 2 ) return; + + set< Transition > tranSet; + multiset< IntersectionPoint >::iterator ip1, ip2 = _intPoints.begin(); + while ( ip2 != _intPoints.end() ) + { + tranSet.clear(); + ip1 = ip2++; + while ( ip2->_paramOnLine - ip1->_paramOnLine <= tol && ip2 != _intPoints.end()) + { + tranSet.insert( ip1->_transition ); + tranSet.insert( ip2->_transition ); + _intPoints.erase( ip1 ); + ip1 = ip2++; + } + if ( tranSet.size() > 1 ) // points with different transition coincide + { + bool isIN = tranSet.count( Trans_IN ); + bool isOUT = tranSet.count( Trans_OUT ); + if ( isIN && isOUT ) + (*ip1)._transition = Trans_TANGENT; + else + (*ip1)._transition = isIN ? Trans_IN : Trans_OUT; + } + } + } + //================================================================================ + /* + * Return "is OUT" state for nodes before the given intersection point + */ + bool GridLine::GetIsOutBefore( multiset< IntersectionPoint >::iterator ip, bool prevIsOut ) + { + if ( ip->_transition == Trans_IN ) + return true; + if ( ip->_transition == Trans_OUT ) + return false; + if ( ip->_transition == Trans_APEX ) + { + // singularity point (apex of a cone) + if ( _intPoints.size() == 1 || ip == _intPoints.begin() ) + return true; + multiset< IntersectionPoint >::iterator ipBef = ip, ipAft = ++ip; + if ( ipAft == _intPoints.end() ) + return false; + --ipBef; + if ( ipBef->_transition != ipAft->_transition ) + return ( ipBef->_transition == Trans_OUT ); + return ( ipBef->_transition != Trans_OUT ); + } + return prevIsOut; // _transition == Trans_TANGENT + } + //================================================================================ + /* + * Return an iterator on GridLine's in a given direction + */ + LineIndexer Grid::GetLineIndexer(size_t iDir) const + { + const size_t indices[] = { 1,2,0, 0,2,1, 0,1,2 }; + const string s[] = { "X", "Y", "Z" }; + LineIndexer li( _coords[0].size(), _coords[1].size(), _coords[2].size(), + indices[iDir*3], indices[iDir*3+1], indices[iDir*3+2], + s[indices[iDir*3]], s[indices[iDir*3+1]], s[indices[iDir*3+2]]); + return li; + } + //============================================================================= + /* + * Creates GridLine's of the grid + */ + void Grid::SetCoordinates(const vector& xCoords, + const vector& yCoords, + const vector& zCoords, + const TopoDS_Shape& shape) + { + _coords[0] = xCoords; + _coords[1] = yCoords; + _coords[2] = zCoords; + + // compute tolerance + _minCellSize = Precision::Infinite(); + for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions + { + for ( size_t i = 1; i < _coords[ iDir ].size(); ++i ) + { + double cellLen = _coords[ iDir ][ i ] - _coords[ iDir ][ i-1 ]; + if ( cellLen < _minCellSize ) + _minCellSize = cellLen; + } + } + if ( _minCellSize < Precision::Confusion() ) + throw SMESH_ComputeError (COMPERR_ALGO_FAILED, + SMESH_Comment("Too small cell size: ") << _tol ); + _tol = _minCellSize / 1000.; + + // attune grid extremities to shape bounding box computed by vertices + Bnd_Box shapeBox; + for ( TopExp_Explorer vExp( shape, TopAbs_VERTEX ); vExp.More(); vExp.Next() ) + shapeBox.Add( BRep_Tool::Pnt( TopoDS::Vertex( vExp.Current() ))); + + double sP[6]; // aXmin, aYmin, aZmin, aXmax, aYmax, aZmax + shapeBox.Get(sP[0],sP[1],sP[2],sP[3],sP[4],sP[5]); + double* cP[6] = { &_coords[0].front(), &_coords[1].front(), &_coords[2].front(), + &_coords[0].back(), &_coords[1].back(), &_coords[2].back() }; + for ( int i = 0; i < 6; ++i ) + if ( fabs( sP[i] - *cP[i] ) < _tol ) + *cP[i] = sP[i] + _tol/1000. * ( i < 3 ? +1 : -1 ); + + // create lines + for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions + { + LineIndexer li = GetLineIndexer( iDir ); + _lines[iDir].resize( li.NbLines() ); + double len = _coords[ iDir ].back() - _coords[iDir].front(); + gp_Vec dir( iDir==0, iDir==1, iDir==2 ); + for ( ; li.More(); ++li ) + { + GridLine& gl = _lines[iDir][ li.LineIndex() ]; + gl._line.SetLocation(gp_Pnt(_coords[0][li.I()], _coords[1][li.J()], _coords[2][li.K()])); + gl._line.SetDirection( dir ); + gl._length = len; + } + } + } + //================================================================================ + /* + * Creates all nodes + */ + void Grid::ComputeNodes(SMESH_MesherHelper& helper) + { + // state of each node of the grid relative to the geomerty + const size_t nbGridNodes = _coords[0].size() * _coords[1].size() * _coords[2].size(); + vector< bool > isNodeOut( nbGridNodes, false ); + _nodes.resize( nbGridNodes, 0 ); + _isBndNode.resize( nbGridNodes, false ); + + for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions + { + LineIndexer li = GetLineIndexer( iDir ); + + // find out a shift of node index while walking along a GridLine in this direction + li.SetIndexOnLine( 0 ); + size_t nIndex0 = NodeIndex( li.I(), li.J(), li.K() ); + li.SetIndexOnLine( 1 ); + const size_t nShift = NodeIndex( li.I(), li.J(), li.K() ) - nIndex0; + + const vector & coords = _coords[ iDir ]; + for ( ; li.More(); ++li ) // loop on lines in iDir + { + li.SetIndexOnLine( 0 ); + nIndex0 = NodeIndex( li.I(), li.J(), li.K() ); + + GridLine& line = _lines[ iDir ][ li.LineIndex() ]; + line.RemoveExcessIntPoints( _tol ); + multiset< IntersectionPoint >& intPnts = _lines[ iDir ][ li.LineIndex() ]._intPoints; + multiset< IntersectionPoint >::iterator ip = intPnts.begin(); + + bool isOut = true; + const double* nodeCoord = & coords[0], *coord0 = nodeCoord, *coordEnd = coord0 + coords.size(); + double nodeParam = 0; + for ( ; ip != intPnts.end(); ++ip ) + { + // set OUT state or just skip IN nodes before ip + if ( nodeParam < ip->_paramOnLine - _tol ) + { + isOut = line.GetIsOutBefore( ip, isOut ); + + while ( nodeParam < ip->_paramOnLine - _tol ) + { + if ( isOut ) + isNodeOut[ nIndex0 + nShift * ( nodeCoord-coord0 ) ] = isOut; + if ( ++nodeCoord < coordEnd ) + nodeParam = *nodeCoord - *coord0; + else + break; + } + if ( nodeCoord == coordEnd ) break; + } + // create a mesh node on a GridLine at ip if it does not coincide with a grid node + if ( nodeParam > ip->_paramOnLine + _tol ) + { + li.SetIndexOnLine( 0 ); + double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]}; + xyz[ li._iConst ] += ip->_paramOnLine; + ip->_node = helper.AddNode( xyz[0], xyz[1], xyz[2] ); + ip->_indexOnLine = nodeCoord-coord0-1; + } + // create a mesh node at ip concident with a grid node + else + { + int nodeIndex = nIndex0 + nShift * ( nodeCoord-coord0 ); + if ( ! _nodes[ nodeIndex ] ) + { + li.SetIndexOnLine( nodeCoord-coord0 ); + double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]}; + _nodes[ nodeIndex ] = helper.AddNode( xyz[0], xyz[1], xyz[2] ); + _isBndNode[ nodeIndex ] = true; + } + //ip->_node = _nodes[ nodeIndex ]; + ip->_indexOnLine = nodeCoord-coord0; + if ( ++nodeCoord < coordEnd ) + nodeParam = *nodeCoord - *coord0; + } + } + // set OUT state to nodes after the last ip + for ( ; nodeCoord < coordEnd; ++nodeCoord ) + isNodeOut[ nIndex0 + nShift * ( nodeCoord-coord0 ) ] = true; + } + } + + // Create mesh nodes at !OUT nodes of the grid + + for ( size_t z = 0; z < _coords[2].size(); ++z ) + for ( size_t y = 0; y < _coords[1].size(); ++y ) + for ( size_t x = 0; x < _coords[0].size(); ++x ) + { + size_t nodeIndex = NodeIndex( x, y, z ); + if ( !isNodeOut[ nodeIndex ] && !_nodes[ nodeIndex] ) + _nodes[ nodeIndex ] = helper.AddNode( _coords[0][x], _coords[1][y], _coords[2][z] ); + } + +#ifdef _MY_DEBUG_ + // check validity of transitions + const char* trName[] = { "TANGENT", "IN", "OUT", "APEX" }; + for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions + { + LineIndexer li = GetLineIndexer( iDir ); + for ( ; li.More(); ++li ) + { + multiset< IntersectionPoint >& intPnts = _lines[ iDir ][ li.LineIndex() ]._intPoints; + if ( intPnts.empty() ) continue; + if ( intPnts.size() == 1 ) + { + if ( intPnts.begin()->_transition != Trans_TANGENT && + intPnts.begin()->_transition != Trans_APEX ) + throw SMESH_ComputeError (COMPERR_ALGO_FAILED, + SMESH_Comment("Wrong SOLE transition of GridLine (") + << li._curInd[li._iVar1] << ", " << li._curInd[li._iVar2] + << ") along " << li._nameConst + << ": " << trName[ intPnts.begin()->_transition] ); + } + else + { + if ( intPnts.begin()->_transition == Trans_OUT ) + throw SMESH_ComputeError (COMPERR_ALGO_FAILED, + SMESH_Comment("Wrong START transition of GridLine (") + << li._curInd[li._iVar1] << ", " << li._curInd[li._iVar2] + << ") along " << li._nameConst + << ": " << trName[ intPnts.begin()->_transition ]); + if ( intPnts.rbegin()->_transition == Trans_IN ) + throw SMESH_ComputeError (COMPERR_ALGO_FAILED, + SMESH_Comment("Wrong END transition of GridLine (") + << li._curInd[li._iVar1] << ", " << li._curInd[li._iVar2] + << ") along " << li._nameConst + << ": " << trName[ intPnts.rbegin()->_transition ]); + } + } + } +#endif + } + + //============================================================================= + /* + * Checks if the face is encosed by the grid + */ + bool FaceGridIntersector::IsInGrid(const Bnd_Box& gridBox) + { + double x0,y0,z0, x1,y1,z1; + const Bnd_Box& faceBox = GetFaceBndBox(); + faceBox.Get(x0,y0,z0, x1,y1,z1); + + if ( !gridBox.IsOut( gp_Pnt( x0,y0,z0 )) && + !gridBox.IsOut( gp_Pnt( x1,y1,z1 ))) + return true; + + double X0,Y0,Z0, X1,Y1,Z1; + gridBox.Get(X0,Y0,Z0, X1,Y1,Z1); + double faceP[6] = { x0,y0,z0, x1,y1,z1 }; + double gridP[6] = { X0,Y0,Z0, X1,Y1,Z1 }; + gp_Dir axes[3] = { gp::DX(), gp::DY(), gp::DZ() }; + for ( int iDir = 0; iDir < 6; ++iDir ) + { + if ( iDir < 3 && gridP[ iDir ] <= faceP[ iDir ] ) continue; + if ( iDir >= 3 && gridP[ iDir ] >= faceP[ iDir ] ) continue; + + // check if the face intersects a side of a gridBox + + gp_Pnt p = iDir < 3 ? gp_Pnt( X0,Y0,Z0 ) : gp_Pnt( X1,Y1,Z1 ); + gp_Ax1 norm( p, axes[ iDir % 3 ] ); + if ( iDir < 3 ) norm.Reverse(); + + gp_XYZ O = norm.Location().XYZ(), N = norm.Direction().XYZ(); + + TopLoc_Location loc = _face.Location(); + Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(_face,loc); + if ( !aPoly.IsNull() ) + { + if ( !loc.IsIdentity() ) + { + norm.Transform( loc.Transformation().Inverted() ); + O = norm.Location().XYZ(), N = norm.Direction().XYZ(); + } + const double deflection = aPoly->Deflection(); + + const TColgp_Array1OfPnt& nodes = aPoly->Nodes(); + for ( int i = nodes.Lower(); i <= nodes.Upper(); ++i ) + if (( nodes( i ).XYZ() - O ) * N > _grid->_tol + deflection ) + return false; + } + else + { + BRepAdaptor_Surface surf( _face ); + double u0, u1, v0, v1, du, dv, u, v; + BRepTools::UVBounds( _face, u0, u1, v0, v1); + if ( surf.GetType() == GeomAbs_Plane ) { + du = u1 - u0, dv = v1 - v0; + } + else { + du = surf.UResolution( _grid->_minCellSize / 10. ); + dv = surf.VResolution( _grid->_minCellSize / 10. ); + } + for ( u = u0, v = v0; u <= u1 && v <= v1; u += du, v += dv ) + { + gp_Pnt p = surf.Value( u, v ); + if (( p.XYZ() - O ) * N > _grid->_tol ) + { + TopAbs_State state = GetCurveFaceIntersector()->ClassifyUVPoint(gp_Pnt2d( u, v )); + if ( state == TopAbs_IN || state == TopAbs_ON ) + return false; + } + } + } + } + return true; + } + //============================================================================= + /* + * Intersects TopoDS_Face with all GridLine's + */ + void FaceGridIntersector::Intersect() + { + FaceLineIntersector intersector; + intersector._surfaceInt = GetCurveFaceIntersector(); + intersector._tol = _grid->_tol; + intersector._transOut = _face.Orientation() == TopAbs_REVERSED ? Trans_IN : Trans_OUT; + intersector._transIn = _face.Orientation() == TopAbs_REVERSED ? Trans_OUT : Trans_IN; + + typedef void (FaceLineIntersector::* PIntFun )(const GridLine& gridLine); + PIntFun interFunction; + + BRepAdaptor_Surface surf( _face ); + switch ( surf.GetType() ) { + case GeomAbs_Plane: + intersector._plane = surf.Plane(); + interFunction = &FaceLineIntersector::IntersectWithPlane; + break; + case GeomAbs_Cylinder: + intersector._cylinder = surf.Cylinder(); + interFunction = &FaceLineIntersector::IntersectWithCylinder; + break; + case GeomAbs_Cone: + intersector._cone = surf.Cone(); + interFunction = &FaceLineIntersector::IntersectWithCone; + break; + case GeomAbs_Sphere: + intersector._sphere = surf.Sphere(); + interFunction = &FaceLineIntersector::IntersectWithSphere; + break; + case GeomAbs_Torus: + intersector._torus = surf.Torus(); + interFunction = &FaceLineIntersector::IntersectWithTorus; + break; + default: + interFunction = &FaceLineIntersector::IntersectWithSurface; + } + + _intersections.clear(); + for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions + { + if ( surf.GetType() == GeomAbs_Plane ) + { + // check if all lines in this direction are parallel to a plane + if ( intersector._plane.Axis().IsNormal( _grid->_lines[iDir][0]._line.Position(), + Precision::Angular())) + continue; + // find out a transition, that is the same for all lines of a direction + gp_Dir plnNorm = intersector._plane.Axis().Direction(); + gp_Dir lineDir = _grid->_lines[iDir][0]._line.Direction(); + intersector._transition = + ( plnNorm * lineDir < 0 ) ? intersector._transIn : intersector._transOut; + } + if ( surf.GetType() == GeomAbs_Cylinder ) + { + // check if all lines in this direction are parallel to a cylinder + if ( intersector._cylinder.Axis().IsParallel( _grid->_lines[iDir][0]._line.Position(), + Precision::Angular())) + continue; + } + + // intersect the grid lines with the face + for ( size_t iL = 0; iL < _grid->_lines[iDir].size(); ++iL ) + { + GridLine& gridLine = _grid->_lines[iDir][iL]; + if ( _bndBox.IsOut( gridLine._line )) continue; + + intersector._intPoints.clear(); + (intersector.*interFunction)( gridLine ); + for ( size_t i = 0; i < intersector._intPoints.size(); ++i ) + _intersections.push_back( make_pair( &gridLine, intersector._intPoints[i] )); + } + } + } + //================================================================================ + /* + * Return true if (_u,_v) is on the face + */ + bool FaceLineIntersector::UVIsOnFace() const + { + TopAbs_State state = _surfaceInt->ClassifyUVPoint(gp_Pnt2d( _u,_v )); + return ( state == TopAbs_IN || state == TopAbs_ON ); + } + //================================================================================ + /* + * Store an intersection if it is IN or ON the face + */ + void FaceLineIntersector::addIntPoint(const bool toClassify) + { + if ( !toClassify || UVIsOnFace() ) + { + IntersectionPoint p; + p._paramOnLine = _w; + p._transition = _transition; + _intPoints.push_back( p ); + } + } + //================================================================================ + /* + * Intersect a line with a plane + */ + void FaceLineIntersector::IntersectWithPlane (const GridLine& gridLine) + { + IntAna_IntConicQuad linPlane( gridLine._line, _plane, Precision::Angular()); + _w = linPlane.ParamOnConic(1); + if ( isParamOnLineOK( gridLine._length )) + { + ElSLib::Parameters(_plane, linPlane.Point(1) ,_u,_v); + addIntPoint(); + } + } + //================================================================================ + /* + * Intersect a line with a cylinder + */ + void FaceLineIntersector::IntersectWithCylinder(const GridLine& gridLine) + { + IntAna_IntConicQuad linCylinder( gridLine._line,_cylinder); + if ( linCylinder.IsDone() && linCylinder.NbPoints() > 0 ) + { + _w = linCylinder.ParamOnConic(1); + if ( linCylinder.NbPoints() == 1 ) + _transition = Trans_TANGENT; + else + _transition = _w < linCylinder.ParamOnConic(2) ? _transIn : _transOut; + if ( isParamOnLineOK( gridLine._length )) + { + ElSLib::Parameters(_cylinder, linCylinder.Point(1) ,_u,_v); + addIntPoint(); + } + if ( linCylinder.NbPoints() > 1 ) + { + _w = linCylinder.ParamOnConic(2); + if ( isParamOnLineOK( gridLine._length )) + { + ElSLib::Parameters(_cylinder, linCylinder.Point(2) ,_u,_v); + _transition = ( _transition == Trans_OUT ) ? Trans_IN : Trans_OUT; + addIntPoint(); + } + } + } + } + //================================================================================ + /* + * Intersect a line with a cone + */ + void FaceLineIntersector::IntersectWithCone (const GridLine& gridLine) + { + IntAna_IntConicQuad linCone(gridLine._line,_cone); + if ( !linCone.IsDone() ) return; + gp_Pnt P; + gp_Vec du, dv, norm; + for ( int i = 1; i <= linCone.NbPoints(); ++i ) + { + _w = linCone.ParamOnConic( i ); + if ( !isParamOnLineOK( gridLine._length )) continue; + ElSLib::Parameters(_cone, linCone.Point(i) ,_u,_v); + if ( UVIsOnFace() ) + { + ElSLib::D1( _u, _v, _cone, P, du, dv ); + norm = du ^ dv; + double normSize2 = norm.SquareMagnitude(); + if ( normSize2 > Precision::Angular() * Precision::Angular() ) + { + double cos = norm.XYZ() * gridLine._line.Direction().XYZ(); + cos /= sqrt( normSize2 ); + if ( cos < -Precision::Angular() ) + _transition = _transIn; + else if ( cos > Precision::Angular() ) + _transition = _transOut; + else + _transition = Trans_TANGENT; + } + else + { + _transition = Trans_APEX; + } + addIntPoint( /*toClassify=*/false); + } + } + } + //================================================================================ + /* + * Intersect a line with a sphere + */ + void FaceLineIntersector::IntersectWithSphere (const GridLine& gridLine) + { + IntAna_IntConicQuad linSphere(gridLine._line,_sphere); + if ( linSphere.IsDone() && linSphere.NbPoints() > 0 ) + { + _w = linSphere.ParamOnConic(1); + if ( linSphere.NbPoints() == 1 ) + _transition = Trans_TANGENT; + else + _transition = _w < linSphere.ParamOnConic(2) ? _transIn : _transOut; + if ( isParamOnLineOK( gridLine._length )) + { + ElSLib::Parameters(_sphere, linSphere.Point(1) ,_u,_v); + addIntPoint(); + } + if ( linSphere.NbPoints() > 1 ) + { + _w = linSphere.ParamOnConic(2); + if ( isParamOnLineOK( gridLine._length )) + { + ElSLib::Parameters(_sphere, linSphere.Point(2) ,_u,_v); + _transition = ( _transition == Trans_OUT ) ? Trans_IN : Trans_OUT; + addIntPoint(); + } + } + } + } + //================================================================================ + /* + * Intersect a line with a torus + */ + void FaceLineIntersector::IntersectWithTorus (const GridLine& gridLine) + { + IntAna_IntLinTorus linTorus(gridLine._line,_torus); + if ( !linTorus.IsDone()) return; + gp_Pnt P; + gp_Vec du, dv, norm; + for ( int i = 1; i <= linTorus.NbPoints(); ++i ) + { + _w = linTorus.ParamOnLine( i ); + if ( !isParamOnLineOK( gridLine._length )) continue; + linTorus.ParamOnTorus( i, _u,_v ); + if ( UVIsOnFace() ) + { + ElSLib::D1( _u, _v, _torus, P, du, dv ); + norm = du ^ dv; + double normSize = norm.Magnitude(); + double cos = norm.XYZ() * gridLine._line.Direction().XYZ(); + cos /= normSize; + if ( cos < -Precision::Angular() ) + _transition = _transIn; + else if ( cos > Precision::Angular() ) + _transition = _transOut; + else + _transition = Trans_TANGENT; + addIntPoint( /*toClassify=*/false); + } + } + } + //================================================================================ + /* + * Intersect a line with a non-analytical surface + */ + void FaceLineIntersector::IntersectWithSurface (const GridLine& gridLine) + { + _surfaceInt->Perform( gridLine._line, 0.0, gridLine._length ); + if ( !_surfaceInt->IsDone() ) return; + for ( int i = 1; i <= _surfaceInt->NbPnt(); ++i ) + { + _transition = Transition( _surfaceInt->Transition( i ) ); + _w = _surfaceInt->WParameter( i ); + addIntPoint(/*toClassify=*/false); + } + } + //================================================================================ + /* + * check if its face can be safely intersected in a thread + */ + bool FaceGridIntersector::IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const + { + bool isSafe = true; + + // check surface + TopLoc_Location loc; + Handle(Geom_Surface) surf = BRep_Tool::Surface( _face, loc ); + Handle(Geom_RectangularTrimmedSurface) ts = + Handle(Geom_RectangularTrimmedSurface)::DownCast( surf ); + while( !ts.IsNull() ) { + surf = ts->BasisSurface(); + ts = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf); + } + if ( surf->IsKind( STANDARD_TYPE(Geom_BSplineSurface )) || + surf->IsKind( STANDARD_TYPE(Geom_BezierSurface ))) + if ( !noSafeTShapes.insert((const Standard_Transient*) _face.TShape() ).second ) + isSafe = false; + + double f, l; + TopExp_Explorer exp( _face, TopAbs_EDGE ); + for ( ; exp.More(); exp.Next() ) + { + bool edgeIsSafe = true; + const TopoDS_Edge& e = TopoDS::Edge( exp.Current() ); + // check 3d curve + { + Handle(Geom_Curve) c = BRep_Tool::Curve( e, loc, f, l); + if ( !c.IsNull() ) + { + Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c); + while( !tc.IsNull() ) { + c = tc->BasisCurve(); + tc = Handle(Geom_TrimmedCurve)::DownCast(c); + } + if ( c->IsKind( STANDARD_TYPE(Geom_BSplineCurve )) || + c->IsKind( STANDARD_TYPE(Geom_BezierCurve ))) + edgeIsSafe = false; + } + } + // check 2d curve + if ( edgeIsSafe ) + { + Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( e, surf, loc, f, l); + if ( !c2.IsNull() ) + { + Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2); + while( !tc.IsNull() ) { + c2 = tc->BasisCurve(); + tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2); + } + if ( c2->IsKind( STANDARD_TYPE(Geom2d_BSplineCurve )) || + c2->IsKind( STANDARD_TYPE(Geom2d_BezierCurve ))) + edgeIsSafe = false; + } + } + if ( !edgeIsSafe && !noSafeTShapes.insert((const Standard_Transient*) e.TShape() ).second ) + isSafe = false; + } + return isSafe; + } + //================================================================================ + /*! + * \brief Creates topology of the hexahedron + */ + Hexahedron::Hexahedron(const double sizeThreshold, Grid* grid) + : _grid( grid ), _sizeThreshold( sizeThreshold ), _nbIntNodes(0) + { + _polygons.reserve(100); // to avoid reallocation; + + //set nodes shift within grid->_nodes from the node 000 + size_t dx = _grid->NodeIndexDX(); + size_t dy = _grid->NodeIndexDY(); + size_t dz = _grid->NodeIndexDZ(); + size_t i000 = 0; + size_t i100 = i000 + dx; + size_t i010 = i000 + dy; + size_t i110 = i010 + dx; + size_t i001 = i000 + dz; + size_t i101 = i100 + dz; + size_t i011 = i010 + dz; + size_t i111 = i110 + dz; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V000 )] = i000; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V100 )] = i100; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V010 )] = i010; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V110 )] = i110; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V001 )] = i001; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V101 )] = i101; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V011 )] = i011; + _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V111 )] = i111; + + vector< int > idVec; + // set nodes to links + for ( int linkID = SMESH_Block::ID_Ex00; linkID <= SMESH_Block::ID_E11z; ++linkID ) + { + SMESH_Block::GetEdgeVertexIDs( linkID, idVec ); + _Link& link = _hexLinks[ SMESH_Block::ShapeIndex( linkID )]; + link._nodes[0] = &_hexNodes[ SMESH_Block::ShapeIndex( idVec[0] )]; + link._nodes[1] = &_hexNodes[ SMESH_Block::ShapeIndex( idVec[1] )]; + link._intNodes.reserve( 10 ); // to avoid reallocation + link._splits.reserve( 10 ); + } + + // set links to faces + int interlace[4] = { 0, 3, 1, 2 }; // to walk by links around a face: { u0, 1v, u1, 0v } + for ( int faceID = SMESH_Block::ID_Fxy0; faceID <= SMESH_Block::ID_F1yz; ++faceID ) + { + SMESH_Block::GetFaceEdgesIDs( faceID, idVec ); + _Face& quad = _hexQuads[ SMESH_Block::ShapeIndex( faceID )]; + bool revFace = ( faceID == SMESH_Block::ID_Fxy0 || + faceID == SMESH_Block::ID_Fx1z || + faceID == SMESH_Block::ID_F0yz ); + quad._links.resize(4); + vector<_OrientedLink>::iterator frwLinkIt = quad._links.begin(); + vector<_OrientedLink>::reverse_iterator revLinkIt = quad._links.rbegin(); + for ( int i = 0; i < 4; ++i ) + { + bool revLink = revFace; + if ( i > 1 ) // reverse links u1 and v0 + revLink = !revLink; + _OrientedLink& link = revFace ? *revLinkIt++ : *frwLinkIt++; + link = _OrientedLink( & _hexLinks[ SMESH_Block::ShapeIndex( idVec[interlace[i]] )], + revLink ); + } + } + } + //================================================================================ + /*! + * \brief Copy constructor + */ + Hexahedron::Hexahedron( const Hexahedron& other ) + :_grid( other._grid ), _sizeThreshold( other._sizeThreshold ), _nbIntNodes(0) + { + _polygons.reserve(100); // to avoid reallocation; + + for ( int i = 0; i < 8; ++i ) + _nodeShift[i] = other._nodeShift[i]; + + for ( int i = 0; i < 12; ++i ) + { + const _Link& srcLink = other._hexLinks[ i ]; + _Link& tgtLink = this->_hexLinks[ i ]; + tgtLink._nodes[0] = _hexNodes + ( srcLink._nodes[0] - other._hexNodes ); + tgtLink._nodes[1] = _hexNodes + ( srcLink._nodes[1] - other._hexNodes ); + tgtLink._intNodes.reserve( 10 ); // to avoid reallocation + tgtLink._splits.reserve( 10 ); + } + + for ( int i = 0; i < 6; ++i ) + { + const _Face& srcQuad = other._hexQuads[ i ]; + _Face& tgtQuad = this->_hexQuads[ i ]; + tgtQuad._links.resize(4); + for ( int j = 0; j < 4; ++j ) + { + const _OrientedLink& srcLink = srcQuad._links[ j ]; + _OrientedLink& tgtLink = tgtQuad._links[ j ]; + tgtLink._reverse = srcLink._reverse; + tgtLink._link = _hexLinks + ( srcLink._link - other._hexLinks ); + } + } + } + + //================================================================================ + /*! + * \brief Initializes its data by given grid cell + */ + void Hexahedron::init( size_t i, size_t j, size_t k ) + { + _i = i; _j = j; _k = k; + // set nodes of grid to nodes of the hexahedron and + // count nodes at hexahedron corners located IN and ON geometry + _nbCornerNodes = _nbBndNodes = 0; + _origNodeInd = _grid->NodeIndex( i,j,k ); + for ( int iN = 0; iN < 8; ++iN ) + { + _hexNodes[iN]._node = _grid->_nodes[ _origNodeInd + _nodeShift[iN] ]; + _nbCornerNodes += bool( _hexNodes[iN]._node ); + _nbBndNodes += _grid->_isBndNode[ _origNodeInd + _nodeShift[iN] ]; + } + + _sideLength[0] = _grid->_coords[0][i+1] - _grid->_coords[0][i]; + _sideLength[1] = _grid->_coords[1][j+1] - _grid->_coords[1][j]; + _sideLength[2] = _grid->_coords[2][k+1] - _grid->_coords[2][k]; + + if ( _nbCornerNodes < 8 && _nbIntNodes + _nbCornerNodes > 3) + { + _Link split; + // create sub-links (_splits) by splitting links with _intNodes + for ( int iLink = 0; iLink < 12; ++iLink ) + { + _Link& link = _hexLinks[ iLink ]; + link._splits.clear(); + split._nodes[ 0 ] = link._nodes[0]; + for ( size_t i = 0; i < link._intNodes.size(); ++ i ) + { + if ( split._nodes[ 0 ]->Node() ) + { + split._nodes[ 1 ] = &link._intNodes[i]; + link._splits.push_back( split ); + } + split._nodes[ 0 ] = &link._intNodes[i]; + } + if ( link._nodes[ 1 ]->Node() && split._nodes[ 0 ]->Node() ) + { + split._nodes[ 1 ] = link._nodes[1]; + link._splits.push_back( split ); + } + } + } + } + //================================================================================ + /*! + * \brief Initializes its data by given grid cell (countered from zero) + */ + void Hexahedron::init( size_t iCell ) + { + size_t iNbCell = _grid->_coords[0].size() - 1; + size_t jNbCell = _grid->_coords[1].size() - 1; + _i = iCell % iNbCell; + _j = ( iCell % ( iNbCell * jNbCell )) / iNbCell; + _k = iCell / iNbCell / jNbCell; + init( _i, _j, _k ); + } + + //================================================================================ + /*! + * \brief Compute mesh volumes resulted from intersection of the Hexahedron + */ + void Hexahedron::ComputeElements() + { + Init(); + + if ( _nbCornerNodes + _nbIntNodes < 4 ) + return; + + if ( _nbBndNodes == _nbCornerNodes && isInHole() ) + return; + + _polygons.clear(); + + vector polyhedraNodes; + vector quantities; + + // create polygons from quadrangles and get their nodes + + vector<_Node*> nodes; + nodes.reserve( _nbCornerNodes + _nbIntNodes ); + + _Link polyLink; + polyLink._faces.reserve( 1 ); + + for ( int iF = 0; iF < 6; ++iF ) // loop on 6 sides of a hexahedron + { + const _Face& quad = _hexQuads[ iF ] ; + + _polygons.resize( _polygons.size() + 1 ); + _Face& polygon = _polygons.back(); + polygon._links.clear(); + polygon._polyLinks.clear(); polygon._polyLinks.reserve( 10 ); + + // add splits of a link to a polygon and collect info on nodes + //int nbIn = 0, nbOut = 0, nbCorners = 0; + nodes.clear(); + for ( int iE = 0; iE < 4; ++iE ) // loop on 4 sides of a quadrangle + { + int nbSpits = quad._links[ iE ].NbResultLinks(); + for ( int iS = 0; iS < nbSpits; ++iS ) + { + _OrientedLink split = quad._links[ iE ].ResultLink( iS ); + _Node* n = split.FirstNode(); + if ( !polygon._links.empty() ) + { + _Node* nPrev = polygon._links.back().LastNode(); + if ( nPrev != n ) + { + polyLink._nodes[0] = nPrev; + polyLink._nodes[1] = n; + polygon._polyLinks.push_back( polyLink ); + polygon._links.push_back( _OrientedLink( &polygon._polyLinks.back() )); + nodes.push_back( nPrev ); + } + } + polygon._links.push_back( split ); + nodes.push_back( n ); + } + } + if ( polygon._links.size() > 1 ) + { + _Node* n1 = polygon._links.back().LastNode(); + _Node* n2 = polygon._links.front().FirstNode(); + if ( n1 != n2 ) + { + polyLink._nodes[0] = n1; + polyLink._nodes[1] = n2; + polygon._polyLinks.push_back( polyLink ); + polygon._links.push_back( _OrientedLink( &polygon._polyLinks.back() )); + nodes.push_back( n1 ); + } + // add polygon to its links + for ( size_t iL = 0; iL < polygon._links.size(); ++iL ) + polygon._links[ iL ]._link->_faces.push_back( &polygon ); + // store polygon nodes + quantities.push_back( nodes.size() ); + for ( size_t i = 0; i < nodes.size(); ++i ) + polyhedraNodes.push_back( nodes[i]->Node() ); + } + else + { + _polygons.resize( _polygons.size() - 1 ); + } + } + + // create polygons closing holes in a polyhedron + + // find free links + vector< _OrientedLink* > freeLinks; + for ( size_t iP = 0; iP < _polygons.size(); ++iP ) + { + _Face& polygon = _polygons[ iP ]; + for ( size_t iL = 0; iL < polygon._links.size(); ++iL ) + if ( polygon._links[ iL ]._link->_faces.size() < 2 ) + freeLinks.push_back( & polygon._links[ iL ]); + } + // make closed chains of free links + int nbFreeLinks = freeLinks.size(); + if ( 0 < nbFreeLinks && nbFreeLinks < 3 ) return; + while ( nbFreeLinks > 0 ) + { + nodes.clear(); + _polygons.resize( _polygons.size() + 1 ); + _Face& polygon = _polygons.back(); + polygon._links.clear(); + + // get a remaining link to start from + _OrientedLink* curLink = 0; + for ( size_t iL = 0; iL < freeLinks.size() && !curLink; ++iL ) + if (( curLink = freeLinks[ iL ] )) + freeLinks[ iL ] = 0; + nodes.push_back( curLink->LastNode() ); + polygon._links.push_back( *curLink ); + + // find all links connected to curLink + _Node* curNode = 0; + do + { + curNode = curLink->FirstNode(); + curLink = 0; + for ( size_t iL = 0; iL < freeLinks.size() && !curLink; ++iL ) + if ( freeLinks[ iL ] && freeLinks[ iL ]->LastNode() == curNode ) + { + curLink = freeLinks[ iL ]; + freeLinks[ iL ] = 0; + nodes.push_back( curNode ); + polygon._links.push_back( *curLink ); + } + } while ( curLink ); + + nbFreeLinks -= polygon._links.size(); + + if ( curNode != nodes.front() || polygon._links.size() < 3 ) + return; // closed polygon not found -> invalid polyhedron + + quantities.push_back( nodes.size() ); + for ( size_t i = 0; i < nodes.size(); ++i ) + polyhedraNodes.push_back( nodes[i]->Node() ); + + // add polygon to its links and reverse links + for ( size_t i = 0; i < polygon._links.size(); ++i ) + { + polygon._links[i].Reverse(); + polygon._links[i]._link->_faces.push_back( &polygon ); + } + + //const size_t firstPoly = _polygons.size(); + } + + if ( ! checkPolyhedronSize() ) + { + return; + } + + // create a classic cell if possible + const int nbNodes = _nbCornerNodes + _nbIntNodes; + bool isClassicElem = false; + if ( nbNodes == 8 && _polygons.size() == 6 ) isClassicElem = addHexa(); + else if ( nbNodes == 4 && _polygons.size() == 4 ) isClassicElem = addTetra(); + else if ( nbNodes == 6 && _polygons.size() == 5 ) isClassicElem = addPenta(); + else if ( nbNodes == 5 && _polygons.size() == 5 ) isClassicElem = addPyra (); + if ( !isClassicElem ) + _volumeDefs.set( polyhedraNodes, quantities ); + } + //================================================================================ + /*! + * \brief Create elements in the mesh + */ + int Hexahedron::MakeElements(SMESH_MesherHelper& helper) + { + SMESHDS_Mesh* mesh = helper.GetMeshDS(); + + size_t nbCells[3] = { _grid->_coords[0].size() - 1, + _grid->_coords[1].size() - 1, + _grid->_coords[2].size() - 1 }; + const size_t nbGridCells = nbCells[0] *nbCells [1] * nbCells[2]; + vector< Hexahedron* > intersectedHex( nbGridCells, 0 ); + int nbIntHex = 0; + + // set intersection nodes from GridLine's to links of intersectedHex + int i,j,k, iDirOther[3][2] = {{ 1,2 },{ 0,2 },{ 0,1 }}; + for ( int iDir = 0; iDir < 3; ++iDir ) + { + int dInd[4][3] = { {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} }; + dInd[1][ iDirOther[iDir][0] ] = -1; + dInd[2][ iDirOther[iDir][1] ] = -1; + dInd[3][ iDirOther[iDir][0] ] = -1; dInd[3][ iDirOther[iDir][1] ] = -1; + // loop on GridLine's parallel to iDir + LineIndexer lineInd = _grid->GetLineIndexer( iDir ); + for ( ; lineInd.More(); ++lineInd ) + { + GridLine& line = _grid->_lines[ iDir ][ lineInd.LineIndex() ]; + multiset< IntersectionPoint >::const_iterator ip = line._intPoints.begin(); + for ( ; ip != line._intPoints.end(); ++ip ) + { + if ( !ip->_node ) continue; + lineInd.SetIndexOnLine( ip->_indexOnLine ); + for ( int iL = 0; iL < 4; ++iL ) // loop on 4 cells sharing a link + { + i = int(lineInd.I()) + dInd[iL][0]; + j = int(lineInd.J()) + dInd[iL][1]; + k = int(lineInd.K()) + dInd[iL][2]; + if ( i < 0 || i >= nbCells[0] || + j < 0 || j >= nbCells[1] || + k < 0 || k >= nbCells[2] ) continue; + + const size_t hexIndex = _grid->CellIndex( i,j,k ); + Hexahedron *& hex = intersectedHex[ hexIndex ]; + if ( !hex) + { + hex = new Hexahedron( *this ); + hex->_i = i; + hex->_j = j; + hex->_k = k; + ++nbIntHex; + } + const int iLink = iL + iDir * 4; + hex->_hexLinks[iLink]._intNodes.push_back( _Node( 0, &(*ip) )); + hex->_nbIntNodes++; + } + } + } + } + + // add not split hexadrons to the mesh + int nbAdded = 0; + vector intHexInd( nbIntHex ); + nbIntHex = 0; + for ( size_t i = 0; i < intersectedHex.size(); ++i ) + { + Hexahedron * & hex = intersectedHex[ i ]; + if ( hex ) + { + intHexInd[ nbIntHex++ ] = i; + if ( hex->_nbIntNodes > 0 ) continue; + init( hex->_i, hex->_j, hex->_k ); + } + else + { + init( i ); + } + if ( _nbCornerNodes == 8 && ( _nbBndNodes < _nbCornerNodes || !isInHole() )) + { + // order of _hexNodes is defined by enum SMESH_Block::TShapeID + SMDS_MeshElement* el = + mesh->AddVolume( _hexNodes[0].Node(), _hexNodes[2].Node(), + _hexNodes[3].Node(), _hexNodes[1].Node(), + _hexNodes[4].Node(), _hexNodes[6].Node(), + _hexNodes[7].Node(), _hexNodes[5].Node() ); + mesh->SetMeshElementOnShape( el, helper.GetSubShapeID() ); + ++nbAdded; + if ( hex ) + { + delete hex; + intersectedHex[ i ] = 0; + --nbIntHex; + } + } + else if ( _nbCornerNodes > 3 && !hex ) + { + // all intersection of hex with geometry are at grid nodes + hex = new Hexahedron( *this ); + hex->init( i ); + intHexInd.push_back(0); + intHexInd[ nbIntHex++ ] = i; + } + } + + // add elements resulted from hexadron intersection +#ifdef WITH_TBB + intHexInd.resize( nbIntHex ); + tbb::parallel_for ( tbb::blocked_range( 0, nbIntHex ), + ParallelHexahedron( intersectedHex, intHexInd ), + tbb::simple_partitioner()); // ComputeElements() is called here + for ( size_t i = 0; i < intHexInd.size(); ++i ) + if ( Hexahedron * hex = intersectedHex[ intHexInd[ i ]] ) + nbAdded += hex->addElements( helper ); +#else + for ( size_t i = 0; i < intHexInd.size(); ++i ) + if ( Hexahedron * hex = intersectedHex[ intHexInd[ i ]] ) + { + hex->ComputeElements(); + nbAdded += hex->addElements( helper ); + } +#endif + + for ( size_t i = 0; i < intersectedHex.size(); ++i ) + if ( intersectedHex[ i ] ) + delete intersectedHex[ i ]; + + return nbAdded; + } + + //================================================================================ + /*! + * \brief Adds computed elements to the mesh + */ + int Hexahedron::addElements(SMESH_MesherHelper& helper) + { + int nbAdded = 0; + // add elements resulted from hexahedron intersection + //for ( size_t i = 0; i < _volumeDefs.size(); ++i ) + { + vector< const SMDS_MeshNode* >& nodes = _volumeDefs._nodes; + + if ( !_volumeDefs._quantities.empty() ) + { + helper.AddPolyhedralVolume( nodes, _volumeDefs._quantities ); + } + else + { + switch ( nodes.size() ) + { + case 8: helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3], + nodes[4],nodes[5],nodes[6],nodes[7] ); + break; + case 4: helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3] ); + break; + case 6: helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3], nodes[4],nodes[5] ); + break; + case 5: + helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3],nodes[4] ); + break; + } + } + nbAdded += int ( _volumeDefs._nodes.size() > 0 ); + } + + return nbAdded; + } + //================================================================================ + /*! + * \brief Return true if the element is in a hole + */ + bool Hexahedron::isInHole() const + { + const int ijk[3] = { _i, _j, _k }; + IntersectionPoint curIntPnt; + + // consider a cell to be in a hole if all links in any direction + // comes OUT of geometry + for ( int iDir = 0; iDir < 3; ++iDir ) + { + const vector& coords = _grid->_coords[ iDir ]; + LineIndexer li = _grid->GetLineIndexer( iDir ); + li.SetIJK( _i,_j,_k ); + size_t lineIndex[4] = { li.LineIndex (), + li.LineIndex10(), + li.LineIndex01(), + li.LineIndex11() }; + bool allLinksOut = true, hasLinks = false; + for ( int iL = 0; iL < 4 && allLinksOut; ++iL ) // loop on 4 links parallel to iDir + { + const _Link& link = _hexLinks[ iL + 4*iDir ]; + // check transition of the first node of a link + const IntersectionPoint* firstIntPnt = 0; + if ( link._nodes[0]->Node() ) // 1st node is a hexa corner + { + curIntPnt._paramOnLine = coords[ ijk[ iDir ]] - coords[0]; + const GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]]; + multiset< IntersectionPoint >::const_iterator ip = + line._intPoints.upper_bound( curIntPnt ); + --ip; + firstIntPnt = &(*ip); + } + else if ( !link._intNodes.empty() ) + { + firstIntPnt = link._intNodes[0]._intPoint; + } + + if ( firstIntPnt ) + { + hasLinks = true; + allLinksOut = ( firstIntPnt->_transition == Trans_OUT ); + } + } + if ( hasLinks && allLinksOut ) + return true; + } + return false; + } + + //================================================================================ + /*! + * \brief Return true if a polyhedron passes _sizeThreshold criterion + */ + bool Hexahedron::checkPolyhedronSize() const + { + double volume = 0; + for ( size_t iP = 0; iP < _polygons.size(); ++iP ) + { + const _Face& polygon = _polygons[iP]; + gp_XYZ area (0,0,0); + SMESH_TNodeXYZ p1 ( polygon._links[ 0 ].FirstNode()->Node() ); + for ( size_t iL = 0; iL < polygon._links.size(); ++iL ) + { + SMESH_TNodeXYZ p2 ( polygon._links[ iL ].LastNode()->Node() ); + area += p1 ^ p2; + p1 = p2; + } + volume += p1 * area; + } + volume /= 6; + + double initVolume = _sideLength[0] * _sideLength[1] * _sideLength[2]; + + return volume > initVolume / _sizeThreshold; + } + //================================================================================ + /*! + * \brief Tries to create a hexahedron + */ + bool Hexahedron::addHexa() + { + if ( _polygons[0]._links.size() != 4 || + _polygons[1]._links.size() != 4 || + _polygons[2]._links.size() != 4 || + _polygons[3]._links.size() != 4 || + _polygons[4]._links.size() != 4 || + _polygons[5]._links.size() != 4 ) + return false; + const SMDS_MeshNode* nodes[8]; + int nbN = 0; + for ( int iL = 0; iL < 4; ++iL ) + { + // a base node + nodes[iL] = _polygons[0]._links[iL].FirstNode()->Node(); + ++nbN; + + // find a top node above the base node + _Link* link = _polygons[0]._links[iL]._link; + ASSERT( link->_faces.size() > 1 ); + // a quadrangle sharing with _polygons[0] + _Face* quad = link->_faces[ bool( link->_faces[0] == & _polygons[0] )]; + for ( int i = 0; i < 4; ++i ) + if ( quad->_links[i]._link == link ) + { + // 1st node of a link opposite to in + nodes[iL+4] = quad->_links[(i+2)%4].FirstNode()->Node(); + ++nbN; + break; + } + } + if ( nbN == 8 ) + _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+8 )); + + return nbN == 8; + } + //================================================================================ + /*! + * \brief Tries to create a tetrahedron + */ + bool Hexahedron::addTetra() + { + const SMDS_MeshNode* nodes[4]; + nodes[0] = _polygons[0]._links[0].FirstNode()->Node(); + nodes[1] = _polygons[0]._links[1].FirstNode()->Node(); + nodes[2] = _polygons[0]._links[2].FirstNode()->Node(); + + _Link* link = _polygons[0]._links[0]._link; + ASSERT( link->_faces.size() > 1 ); + + // a triangle sharing with _polygons[0] + _Face* tria = link->_faces[ bool( link->_faces[0] == & _polygons[0] )]; + for ( int i = 0; i < 3; ++i ) + if ( tria->_links[i]._link == link ) + { + nodes[3] = tria->_links[(i+1)%3].LastNode()->Node(); + _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+4 )); + return true; + } + + return false; + } + //================================================================================ + /*! + * \brief Tries to create a pentahedron + */ + bool Hexahedron::addPenta() + { + // find a base triangular face + int iTri = -1; + for ( int iF = 0; iF < 5 && iTri < 0; ++iF ) + if ( _polygons[ iF ]._links.size() == 3 ) + iTri = iF; + if ( iTri < 0 ) return false; + + // find nodes + const SMDS_MeshNode* nodes[6]; + int nbN = 0; + for ( int iL = 0; iL < 3; ++iL ) + { + // a base node + nodes[iL] = _polygons[ iTri ]._links[iL].FirstNode()->Node(); + ++nbN; + + // find a top node above the base node + _Link* link = _polygons[ iTri ]._links[iL]._link; + ASSERT( link->_faces.size() > 1 ); + // a quadrangle sharing with a base triangle + _Face* quad = link->_faces[ bool( link->_faces[0] == & _polygons[ iTri ] )]; + if ( quad->_links.size() != 4 ) return false; + for ( int i = 0; i < 4; ++i ) + if ( quad->_links[i]._link == link ) + { + // 1st node of a link opposite to in + nodes[iL+3] = quad->_links[(i+2)%4].FirstNode()->Node(); + ++nbN; + break; + } + } + if ( nbN == 6 ) + _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+6 )); + + return ( nbN == 6 ); + } + //================================================================================ + /*! + * \brief Tries to create a pyramid + */ + bool Hexahedron::addPyra() + { + // find a base quadrangle + int iQuad = -1; + for ( int iF = 0; iF < 5 && iQuad < 0; ++iF ) + if ( _polygons[ iF ]._links.size() == 4 ) + iQuad = iF; + if ( iQuad < 0 ) return false; + + // find nodes + const SMDS_MeshNode* nodes[5]; + nodes[0] = _polygons[iQuad]._links[0].FirstNode()->Node(); + nodes[1] = _polygons[iQuad]._links[1].FirstNode()->Node(); + nodes[2] = _polygons[iQuad]._links[2].FirstNode()->Node(); + nodes[3] = _polygons[iQuad]._links[3].FirstNode()->Node(); + + _Link* link = _polygons[iQuad]._links[0]._link; + ASSERT( link->_faces.size() > 1 ); + + // a triangle sharing with a base quadrangle + _Face* tria = link->_faces[ bool( link->_faces[0] == & _polygons[ iQuad ] )]; + if ( tria->_links.size() != 3 ) return false; + for ( int i = 0; i < 3; ++i ) + if ( tria->_links[i]._link == link ) + { + nodes[4] = tria->_links[(i+1)%3].LastNode()->Node(); + _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+5 )); + return true; + } + + return false; + } + +} // namespace + +//============================================================================= +/*! + * \brief Generates 3D structured Cartesian mesh in the internal part of + * solid shapes and polyhedral volumes near the shape boundary. + * \param theMesh - mesh to fill in + * \param theShape - a compound of all SOLIDs to mesh + * \retval bool - true in case of success + */ +//============================================================================= + +bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, + const TopoDS_Shape & theShape) +{ + // The algorithm generates the mesh in following steps: + + // 1) Intersection of grid lines with the geometry boundary. + // This step allows to find out if a given node of the initial grid is + // inside or outside the geometry. + + // 2) For each cell of the grid, check how many of it's nodes are outside + // of the geometry boundary. Depending on a result of this check + // - skip a cell, if all it's nodes are outside + // - skip a cell, if it is too small according to the size threshold + // - add a hexahedron in the mesh, if all nodes are inside + // - add a polyhedron in the mesh, if some nodes are inside and some outside + + _computeCanceled = false; + + try + { + Grid grid; + + TopTools_MapOfShape faceMap; + for ( TopExp_Explorer fExp( theShape, TopAbs_FACE ); fExp.More(); fExp.Next() ) + if ( !faceMap.Add( fExp.Current() )) + faceMap.Remove( fExp.Current() ); // remove a face shared by two solids + + Bnd_Box shapeBox; + vector facesItersectors( faceMap.Extent() ); + TopTools_MapIteratorOfMapOfShape faceMppIt( faceMap ); + for ( int i = 0; faceMppIt.More(); faceMppIt.Next(), ++i ) + { + facesItersectors[i]._face = TopoDS::Face( faceMppIt.Key() ); + facesItersectors[i]._grid = &grid; + shapeBox.Add( facesItersectors[i].GetFaceBndBox() ); + } + + vector xCoords, yCoords, zCoords; + _hyp->GetCoordinates( xCoords, yCoords, zCoords, shapeBox ); + + grid.SetCoordinates( xCoords, yCoords, zCoords, theShape ); + + // check if the grid encloses the shape + if ( !_hyp->IsGridBySpacing(0) || + !_hyp->IsGridBySpacing(1) || + !_hyp->IsGridBySpacing(2) ) + { + Bnd_Box gridBox; + gridBox.Add( gp_Pnt( xCoords[0], yCoords[0], zCoords[0] )); + gridBox.Add( gp_Pnt( xCoords.back(), yCoords.back(), zCoords.back() )); + double x0,y0,z0, x1,y1,z1; + shapeBox.Get(x0,y0,z0, x1,y1,z1); + if ( gridBox.IsOut( gp_Pnt( x0,y0,z0 )) || + gridBox.IsOut( gp_Pnt( x1,y1,z1 ))) + for ( size_t i = 0; i < facesItersectors.size(); ++i ) + { + if ( !facesItersectors[i].IsInGrid( gridBox )) + return error("The grid doesn't enclose the geometry"); +#ifdef ELLIPSOLID_WORKAROUND + delete facesItersectors[i]._surfaceInt, facesItersectors[i]._surfaceInt = 0; +#endif + } + } + if ( _computeCanceled ) return false; + +#ifdef WITH_TBB + { // copy partner faces and curves of not thread-safe types + set< const Standard_Transient* > tshapes; + BRepBuilderAPI_Copy copier; + for ( size_t i = 0; i < facesItersectors.size(); ++i ) + { + if ( !facesItersectors[i].IsThreadSafe(tshapes) ) + { + copier.Perform( facesItersectors[i]._face ); + facesItersectors[i]._face = TopoDS::Face( copier ); + } + } + } + // Intersection of grid lines with the geometry boundary. + tbb::parallel_for ( tbb::blocked_range( 0, facesItersectors.size() ), + ParallelIntersector( facesItersectors ), + tbb::simple_partitioner()); +#else + for ( size_t i = 0; i < facesItersectors.size(); ++i ) + facesItersectors[i].Intersect(); +#endif + + // put interesection points onto the GridLine's; this is done after intersection + // to avoid contention of facesItersectors for writing into the same GridLine + // in case of parallel work of facesItersectors + for ( size_t i = 0; i < facesItersectors.size(); ++i ) + facesItersectors[i].StoreIntersections(); + + SMESH_MesherHelper helper( theMesh ); + TopExp_Explorer solidExp (theShape, TopAbs_SOLID); + helper.SetSubShape( solidExp.Current() ); + helper.SetElementsOnShape( true ); + + if ( _computeCanceled ) return false; + + // create nodes on the geometry + grid.ComputeNodes(helper); + + if ( _computeCanceled ) return false; + + // create volume elements + Hexahedron hex( _hyp->GetSizeThreshold(), &grid ); + int nbAdded = hex.MakeElements( helper ); + + SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); + if ( nbAdded > 0 ) + { + // make all SOLIDS computed + if ( SMESHDS_SubMesh* sm1 = meshDS->MeshElements( solidExp.Current()) ) + { + SMDS_ElemIteratorPtr volIt = sm1->GetElements(); + for ( ; solidExp.More() && volIt->more(); solidExp.Next() ) + { + const SMDS_MeshElement* vol = volIt->next(); + sm1->RemoveElement( vol, /*isElemDeleted=*/false ); + meshDS->SetMeshElementOnShape( vol, solidExp.Current() ); + } + } + // make other sub-shapes computed + setSubmeshesComputed( theMesh, theShape ); + } + + // remove free nodes + if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( helper.GetSubShapeID() )) + { + // intersection nodes + for ( int iDir = 0; iDir < 3; ++iDir ) + { + vector< GridLine >& lines = grid._lines[ iDir ]; + for ( size_t i = 0; i < lines.size(); ++i ) + { + multiset< IntersectionPoint >::iterator ip = lines[i]._intPoints.begin(); + for ( ; ip != lines[i]._intPoints.end(); ++ip ) + if ( ip->_node && ip->_node->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode( ip->_node, smDS, /*fromGroups=*/false ); + } + } + // grid nodes + for ( size_t i = 0; i < grid._nodes.size(); ++i ) + if ( !grid._isBndNode[i] ) // nodes on boundary are already removed + if ( grid._nodes[i] && grid._nodes[i]->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode( grid._nodes[i], smDS, /*fromGroups=*/false ); + } + + return nbAdded; + + } + // SMESH_ComputeError is not caught at SMESH_submesh level for an unknown reason + catch ( SMESH_ComputeError& e) + { + return error( SMESH_ComputeErrorPtr( new SMESH_ComputeError( e ))); + } + return false; +} + +//============================================================================= +/*! + * Evaluate + */ +//============================================================================= + +bool StdMeshers_Cartesian_3D::Evaluate(SMESH_Mesh & theMesh, + const TopoDS_Shape & theShape, + MapShapeNbElems& theResMap) +{ + // TODO +// std::vector aResVec(SMDSEntity_Last); +// for(int i=SMDSEntity_Node; igetDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/false); + while ( smIt->more() ) + { + SMESH_subMesh* sm = smIt->next(); + sm->SetIsAlwaysComputed( isComputed ); + } + } + + // -------------------------------------------------------------------------------- + // unsetting _alwaysComputed flag if "Cartesian_3D" was removed + // + virtual void ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* subMeshOfSolid, + SMESH_subMeshEventListenerData* data, + const SMESH_Hypothesis* hyp = 0) + { + if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) + { + setAlwaysComputed( subMeshOfSolid->GetComputeState() == SMESH_subMesh::COMPUTE_OK, + subMeshOfSolid ); + } + else + { + SMESH_Algo* algo3D = subMeshOfSolid->GetAlgo(); + if ( !algo3D || _algoName != algo3D->GetName() ) + setAlwaysComputed( false, subMeshOfSolid ); + } + } + + // -------------------------------------------------------------------------------- + // set the event listener + // + static void SetOn( SMESH_subMesh* subMeshOfSolid, const string& algoName ) + { + subMeshOfSolid->SetEventListener( new _EventListener( algoName ), + /*data=*/0, + subMeshOfSolid ); + } + + }; // struct _EventListener + +} // namespace + +//================================================================================ +/*! + * \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_Cartesian_3D::SetEventListener(SMESH_subMesh* subMesh) +{ + _EventListener::SetOn( subMesh, GetName() ); +} + +//================================================================================ +/*! + * \brief Set _alwaysComputed flag to submeshes of inferior levels to avoid their computing + */ +//================================================================================ + +void StdMeshers_Cartesian_3D::setSubmeshesComputed(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape) +{ + for ( TopExp_Explorer soExp( theShape, TopAbs_SOLID ); soExp.More(); soExp.Next() ) + _EventListener::setAlwaysComputed( true, theMesh.GetSubMesh( soExp.Current() )); +} + diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.hxx b/src/StdMeshers/StdMeshers_Cartesian_3D.hxx new file mode 100644 index 000000000..4aefa321f --- /dev/null +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.hxx @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_Cartesian_3D.hxx +// Module : SMESH +// +#ifndef _SMESH_Cartesian_3D_HXX_ +#define _SMESH_Cartesian_3D_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_3D_Algo.hxx" + +/*! + * \brief A 3D algorithm generating 3D structured Cartesian mesh in the + * internal part of a solid shape and polyhedral volumes near the shape boundary. + * + * Issue 0021336 + */ +class StdMeshers_CartesianParameters3D; + +class STDMESHERS_EXPORT StdMeshers_Cartesian_3D : public SMESH_3D_Algo +{ +public: + StdMeshers_Cartesian_3D(int hypId, int studyId, SMESH_Gen* gen); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + + virtual void SetEventListener(SMESH_subMesh* subMesh); + + private: + + void setSubmeshesComputed(SMESH_Mesh& aMesh, const TopoDS_Shape& theShape ); + + const StdMeshers_CartesianParameters3D* _hyp; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx index 42acee19e..11a3cc57a 100644 --- a/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx @@ -1,24 +1,23 @@ -// SMESH SMESH : implementaion of SMESH idl descriptions +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 // + +// SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_CompositeHexa_3D.cxx // Module : SMESH // Created : Tue Nov 25 11:04:59 2008 @@ -33,7 +32,6 @@ #include "SMESH_Comment.hxx" #include "SMESH_ComputeError.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" @@ -44,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -60,8 +59,8 @@ #ifdef _DEBUG_ -// #define DEB_FACES -// #define DEB_GRID +//#define DEB_FACES +//#define DEB_GRID #define DUMP_VERT(msg,V) \ // { TopoDS_Vertex v = V; gp_Pnt p = BRep_Tool::Pnt(v);\ // cout << msg << "( "<< p.X()<<", "<& edges); _FaceSide* GetSide(const int i); const _FaceSide* GetSide(const int i) const; - int size() { return myChildren.size(); } + int size() const { return myChildren.size(); } int NbVertices() const; TopoDS_Vertex FirstVertex() const; TopoDS_Vertex LastVertex() const; TopoDS_Vertex Vertex(int i) const; + TopoDS_Edge Edge(int i) const; bool Contain( const _FaceSide& side, int* which=0 ) const; bool Contain( const TopoDS_Vertex& vertex ) const; void AppendSide( const _FaceSide& side ); @@ -128,7 +128,6 @@ private: list< _FaceSide > myChildren; int myNbChildren; - //set myVertices; TopTools_MapOfShape myVertices; EQuadSides myID; // debug @@ -155,15 +154,21 @@ public: //** Methods to find and orient faces of 6 sides of the box **// //!< Try to set the side as bottom hirizontal side bool SetBottomSide(const _FaceSide& side, int* sideIndex=0); - //!< Return face adjacent to i-th side of this face - _QuadFaceGrid* FindAdjacentForSide(int i, vector<_QuadFaceGrid>& faces) const; // (0& faces, EBoxSides id) const; //!< Reverse edges in order to have the bottom edge going along axes of the unit box void ReverseEdges(/*int e1, int e2*/); bool IsComplex() const { return !myChildren.empty(); } - typedef SMDS_SetIterator< const _QuadFaceGrid&, TChildren::const_iterator > TChildIterator; + int NbChildren() const { return myChildren.size(); } + + typedef SMDS_SetIterator< const _QuadFaceGrid&, + TChildren::const_iterator, + SMDS::SimpleAccessor, + SMDS::PassAllValueFilter<_QuadFaceGrid> > + TChildIterator; TChildIterator GetChildren() const { return TChildIterator( myChildren.begin(), myChildren.end()); } @@ -179,6 +184,9 @@ public: //** Loading and access to mesh **// //!< Return number of segments on the vertical sides int GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers=false) const; + //!< Return edge on the hirizontal bottom sides + int GetHoriEdges(vector & edges) const; + //!< Return a node by its position const SMDS_MeshNode* GetNode(int iHori, int iVert) const; @@ -206,7 +214,7 @@ public: //** Access to member fields **// private: - bool error(std::string& text, int code = COMPERR_ALGO_FAILED) + bool error(const std::string& text, int code = COMPERR_ALGO_FAILED) { myError = SMESH_ComputeError::New( code, text ); return false; } bool error(const SMESH_ComputeErrorPtr& err) @@ -252,7 +260,7 @@ StdMeshers_CompositeHexa_3D::StdMeshers_CompositeHexa_3D(int hypId, int studyId, :SMESH_3D_Algo(hypId, studyId, gen) { _name = "CompositeHexa_3D"; - _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type } //================================================================================ @@ -271,35 +279,42 @@ bool StdMeshers_CompositeHexa_3D::CheckHypothesis(SMESH_Mesh& aMesh, //================================================================================ /*! - * \brief Computes hexahedral mesh on a box with composite sides - * \param aMesh - mesh to compute - * \param aShape - shape to mesh - * \retval bool - succes sign + * \brief Tries to find 6 sides of a box */ //================================================================================ -bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, - const TopoDS_Shape& theShape) +bool StdMeshers_CompositeHexa_3D::findBoxFaces( const TopoDS_Shape& shape, + list< _QuadFaceGrid >& boxFaces, + _QuadFaceGrid * & fBottom, + _QuadFaceGrid * & fTop, + _QuadFaceGrid * & fFront, + _QuadFaceGrid * & fBack, + _QuadFaceGrid * & fLeft, + _QuadFaceGrid * & fRight) { - SMESH_MesherHelper helper( theMesh ); - _quadraticMesh = helper.IsQuadraticSubMesh( theShape ); - helper.SetElementsOnShape( true ); - - // ------------------------- - // Try to find 6 side faces - // ------------------------- - vector< _QuadFaceGrid > boxFaces; boxFaces.reserve( 6 ); + list< _QuadFaceGrid >::iterator boxFace; TopExp_Explorer exp; - int iFace, nbFaces = 0; - for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces ) + int nbFaces = 0; + for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces ) { _QuadFaceGrid f; if ( !f.Init( TopoDS::Face( exp.Current() ))) return error (COMPERR_BAD_SHAPE); - bool isContinuous = false; - for ( int i=0; i < boxFaces.size() && !isContinuous; ++i ) - isContinuous = boxFaces[ i ].AddContinuousFace( f ); - if ( !isContinuous ) + + _QuadFaceGrid* prevContinuous = 0; + for ( boxFace = boxFaces.begin(); boxFace != boxFaces.end(); ++boxFace ) + { + if ( prevContinuous ) + { + if ( prevContinuous->AddContinuousFace( *boxFace )) + boxFace = --boxFaces.erase( boxFace ); + } + else if ( boxFace->AddContinuousFace( f )) + { + prevContinuous = & (*boxFace); + } + } + if ( !prevContinuous ) boxFaces.push_back( f ); } // Check what we have @@ -310,29 +325,30 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, if ( boxFaces.size() != 6 && nbFaces == 6 ) { // strange ordinary box with continuous faces boxFaces.resize( 6 ); - iFace = 0; - for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++iFace ) - boxFaces[ iFace ].Init( TopoDS::Face( exp.Current() ) ); + boxFace = boxFaces.begin(); + for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++boxFace ) + boxFace->Init( TopoDS::Face( exp.Current() ) ); } // ---------------------------------------- // Find out position of faces within a box // ---------------------------------------- - - _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight; // start from a bottom face - fBottom = &boxFaces[0]; + fBottom = &boxFaces.front(); + fBottom->SetID( B_BOTTOM ); // find vertical faces - fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces ); - fLeft = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces ); - fBack = fBottom->FindAdjacentForSide( Q_TOP, boxFaces ); - fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces ); + fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces, B_FRONT ); + fLeft = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces, B_LEFT ); + fBack = fBottom->FindAdjacentForSide( Q_TOP, boxFaces, B_BACK ); + fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces, B_RIGHT ); // check the found if ( !fFront || !fBack || !fLeft || !fRight ) return error(COMPERR_BAD_SHAPE); - // top face + // find a top face fTop = 0; - for ( int i=1; i < boxFaces.size() && !fTop; ++i ) { - fTop = & boxFaces[ i ]; + for ( boxFace = ++boxFaces.begin(); boxFace != boxFaces.end() && !fTop; ++boxFace ) + { + fTop = & (*boxFace); + fTop->SetID( B_TOP ); if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight ) fTop = 0; } @@ -352,18 +368,39 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, if ( !fTop ) return error(COMPERR_BAD_SHAPE); - fBottom->SetID( B_BOTTOM ); - fBack ->SetID( B_BACK ); - fLeft ->SetID( B_LEFT ); - fFront ->SetID( B_FRONT ); - fRight ->SetID( B_RIGHT ); - fTop ->SetID( B_TOP ); - // orient bottom egde of faces along axes of the unit box fBottom->ReverseEdges(); fBack ->ReverseEdges(); fLeft ->ReverseEdges(); + return true; +} + +//================================================================================ +/*! + * \brief Computes hexahedral mesh on a box with composite sides + * \param aMesh - mesh to compute + * \param aShape - shape to mesh + * \retval bool - succes sign + */ +//================================================================================ + +bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape) +{ + SMESH_MesherHelper helper( theMesh ); + _quadraticMesh = helper.IsQuadraticSubMesh( theShape ); + helper.SetElementsOnShape( true ); + + // ------------------------- + // Try to find 6 side faces + // ------------------------- + list< _QuadFaceGrid > boxFaceContainer; + _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight; + if ( ! findBoxFaces( theShape, boxFaceContainer, + fBottom, fTop, fFront, fBack, fLeft, fRight)) + return false; + // ------------------------------------------ // Fill columns of nodes with existing nodes // ------------------------------------------ @@ -417,7 +454,7 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, // ---------------------------- // Add internal nodes of a box // ---------------------------- - // projection points of internal nodes on box subshapes by which + // projection points of internal nodes on box sub-shapes by which // coordinates of internal nodes are computed vector pointsOnShapes( SMESH_Block::ID_Shell ); @@ -486,7 +523,7 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, } } // faces no more needed, free memory - boxFaces.clear(); + boxFaceContainer.clear(); // ---------------- // Add hexahedrons @@ -508,6 +545,90 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh& theMesh, return true; } +//================================================================================ +/*! + * Evaluate + */ +//================================================================================ + +bool StdMeshers_CompositeHexa_3D::Evaluate(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + MapShapeNbElems& aResMap) +{ + // ------------------------- + // Try to find 6 side faces + // ------------------------- + list< _QuadFaceGrid > boxFaceContainer; + _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight; + if ( ! findBoxFaces( theShape, boxFaceContainer, + fBottom, fTop, fFront, fBack, fLeft, fRight)) + return false; + + // Find a less complex side + _QuadFaceGrid * lessComplexSide = & boxFaceContainer.front(); + list< _QuadFaceGrid >::iterator face = boxFaceContainer.begin(); + for ( ++face; face != boxFaceContainer.end() && lessComplexSide->IsComplex(); ++face ) + if ( face->NbChildren() < lessComplexSide->NbChildren() ) + lessComplexSide = & *face; + + // Get an 1D size of lessComplexSide + int nbSeg1 = 0; + vector edges; + if ( !lessComplexSide->GetHoriEdges(edges) ) + return false; + for ( size_t i = 0; i < edges.size(); ++i ) + { + const vector& nbElems = aResMap[ theMesh.GetSubMesh( edges[i] )]; + if ( !nbElems.empty() ) + nbSeg1 += Max( nbElems[ SMDSEntity_Edge ], nbElems[ SMDSEntity_Quad_Edge ]); + } + + // Get an 1D size of a box side ortogonal to lessComplexSide + int nbSeg2 = 0; + _QuadFaceGrid* ortoSide = + lessComplexSide->FindAdjacentForSide( Q_LEFT, boxFaceContainer, B_UNDEFINED ); + edges.clear(); + if ( !ortoSide || !ortoSide->GetHoriEdges(edges) ) return false; + for ( size_t i = 0; i < edges.size(); ++i ) + { + const vector& nbElems = aResMap[ theMesh.GetSubMesh( edges[i] )]; + if ( !nbElems.empty() ) + nbSeg2 += Max( nbElems[ SMDSEntity_Edge ], nbElems[ SMDSEntity_Quad_Edge ]); + } + + // Get an 2D size of a box side ortogonal to lessComplexSide + int nbFaces = 0, nbQuadFace = 0; + list< TopoDS_Face > sideFaces; + if ( ortoSide->IsComplex() ) + for ( _QuadFaceGrid::TChildIterator child = ortoSide->GetChildren(); child.more(); ) + sideFaces.push_back( child.next().GetFace() ); + else + sideFaces.push_back( ortoSide->GetFace() ); + // + list< TopoDS_Face >::iterator f = sideFaces.begin(); + for ( ; f != sideFaces.end(); ++f ) + { + const vector& nbElems = aResMap[ theMesh.GetSubMesh( *f )]; + if ( !nbElems.empty() ) + { + nbFaces = nbElems[ SMDSEntity_Quadrangle ]; + nbQuadFace = nbElems[ SMDSEntity_Quad_Quadrangle ]; + } + } + + // Fill nb of elements + vector aResVec(SMDSEntity_Last,0); + int nbSeg3 = ( nbFaces + nbQuadFace ) / nbSeg2; + aResVec[SMDSEntity_Node] = (nbSeg1-1) * (nbSeg2-1) * (nbSeg3-1); + aResVec[SMDSEntity_Hexa] = nbSeg1 * nbFaces; + aResVec[SMDSEntity_Quad_Hexa] = nbSeg1 * nbQuadFace; + + aResMap.insert( make_pair( theMesh.GetSubMesh(theShape), aResVec )); + + return true; +} + + //================================================================================ /*! * \brief constructor of non-initialized _QuadFaceGrid @@ -589,12 +710,13 @@ bool _QuadFaceGrid::Init(const TopoDS_Face& f) bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other ) { - for ( int i = 0; i < 4; ++i ) { + for ( int i = 0; i < 4; ++i ) + { const _FaceSide& otherSide = other.GetSide( i ); int iMyCommon; if ( mySides.Contain( otherSide, &iMyCommon ) ) { // check if normals of two faces are collinear at all vertices of a otherSide - const double angleTol = PI / 180 / 2; + const double angleTol = M_PI / 180. / 2.; int iV, nbV = otherSide.NbVertices(), nbCollinear = 0; for ( iV = 0; iV < nbV; ++iV ) { @@ -618,14 +740,28 @@ bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other ) myChildren.push_back( *this ); myFace.Nullify(); } - myChildren.push_back( other ); - int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4; - myChildren.back().SetBottomSide( other.GetSide( otherBottomIndex )); + if ( other.IsComplex() ) + for ( TChildIterator children = other.GetChildren(); children.more(); ) + myChildren.push_back( children.next() ); + else + myChildren.push_back( other ); + + myLeftBottomChild = 0; + //int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4; + //myChildren.back().SetBottomSide( other.GetSide( otherBottomIndex )); + // collect vertices in mySides - mySides.AppendSide( other.GetSide(0) ); - mySides.AppendSide( other.GetSide(1) ); - mySides.AppendSide( other.GetSide(2) ); - mySides.AppendSide( other.GetSide(3) ); + if ( other.IsComplex() ) + for ( TChildIterator children = other.GetChildren(); children.more(); ) + { + const _QuadFaceGrid& child = children.next(); + for ( int i = 0; i < 4; ++i ) + mySides.AppendSide( child.GetSide(i) ); + } + else + for ( int i = 0; i < 4; ++i ) + mySides.AppendSide( other.GetSide(i) ); + return true; } } @@ -680,12 +816,17 @@ bool _QuadFaceGrid::SetBottomSide(const _FaceSide& bottom, int* sideIndex) */ //================================================================================ -_QuadFaceGrid* _QuadFaceGrid::FindAdjacentForSide(int i, vector<_QuadFaceGrid>& faces) const +_QuadFaceGrid* _QuadFaceGrid::FindAdjacentForSide(int i, + list<_QuadFaceGrid>& faces, + EBoxSides id) const { - for ( int iF = 0; iF < faces.size(); ++iF ) { - _QuadFaceGrid* f = &faces[ iF ]; - if ( f != this && f->SetBottomSide( GetSide( i ))) - return f; + const _FaceSide & iSide = GetSide( i ); + list< _QuadFaceGrid >::iterator boxFace = faces.begin(); + for ( ; boxFace != faces.end(); ++boxFace ) + { + _QuadFaceGrid* f = & (*boxFace); + if ( f != this && f->SetBottomSide( iSide )) + return f->SetID( id ), f; } return (_QuadFaceGrid*) 0; } @@ -781,6 +922,13 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) if ( !myGrid.empty() ) return true; + SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS(); + // check that all faces are quadrangular + SMDS_ElemIteratorPtr fIt = faceSubMesh->GetElements(); + while ( fIt->more() ) + if ( fIt->next()->NbNodes() % 4 > 0 ) + return error("Non-quadrangular mesh faces are not allowed on sides of a composite block"); + myIndexer._xSize = 1 + mySides.GetSide( Q_BOTTOM )->GetNbSegments( mesh ); myIndexer._ySize = 1 + mySides.GetSide( Q_LEFT )->GetNbSegments( mesh ); @@ -791,10 +939,8 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) // store the rest nodes row by row - SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS(); - - SMDS_MeshNode dummy(0,0,0); - const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes + const SMDS_MeshNode* dummy = mesh.GetMeshDS()->AddNode(0,0,0); + const SMDS_MeshElement* firstQuad = dummy; // most left face above the last row of found nodes int nbFoundNodes = myIndexer._xSize; while ( nbFoundNodes != myGrid.size() ) @@ -815,7 +961,7 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) TIDSortedElemSet emptySet, avoidSet; avoidSet.insert( firstQuad ); firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet); - if ( firstQuad && !faceSubMesh->Contains( firstQuad )) { + while ( firstQuad && !faceSubMesh->Contains( firstQuad )) { avoidSet.insert( firstQuad ); firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet); } @@ -861,7 +1007,7 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh ) n1up = n2up; } } - + mesh.GetMeshDS()->RemoveNode(dummy); DumpGrid(); // debug return true; @@ -954,21 +1100,22 @@ void _QuadFaceGrid::setBrothers( set< _QuadFaceGrid* >& notLocatedBrothers ) TopoDS_Vertex rightVertex = GetSide( Q_BOTTOM ).LastVertex(); DUMP_VERT("1 right bottom Vertex: ",rightVertex ); set< _QuadFaceGrid* >::iterator brIt, brEnd = notLocatedBrothers.end(); - for ( brIt = notLocatedBrothers.begin(); !myRightBrother && brIt != brEnd; ++brIt ) + for ( brIt = notLocatedBrothers.begin(); brIt != brEnd; ++brIt ) { _QuadFaceGrid* brother = *brIt; TopoDS_Vertex brotherLeftVertex = brother->GetSide( Q_BOTTOM ).FirstVertex(); DUMP_VERT( "brother left bottom: ", brotherLeftVertex ); if ( rightVertex.IsSame( brotherLeftVertex )) { myRightBrother = brother; - notLocatedBrothers.erase( myRightBrother ); + notLocatedBrothers.erase( brIt ); + break; } } // find upper brother TopoDS_Vertex upVertex = GetSide( Q_LEFT ).FirstVertex(); DUMP_VERT("1 left up Vertex: ",upVertex); brIt = notLocatedBrothers.begin(), brEnd = notLocatedBrothers.end(); - for ( ; !myUpBrother && brIt != brEnd; ++brIt ) + for ( ; brIt != brEnd; ++brIt ) { _QuadFaceGrid* brother = *brIt; TopoDS_Vertex brotherLeftVertex = brother->GetSide( Q_BOTTOM ).FirstVertex(); @@ -976,6 +1123,7 @@ void _QuadFaceGrid::setBrothers( set< _QuadFaceGrid* >& notLocatedBrothers ) if ( upVertex.IsSame( brotherLeftVertex )) { myUpBrother = brother; notLocatedBrothers.erase( myUpBrother ); + break; } } // recursive call @@ -1073,6 +1221,35 @@ int _QuadFaceGrid::GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers) const return nbSegs; } +//================================================================================ +/*! + * \brief Return edge on the hirizontal bottom sides + */ +//================================================================================ + +int _QuadFaceGrid::GetHoriEdges(vector & edges) const +{ + if ( myLeftBottomChild ) + { + return myLeftBottomChild->GetHoriEdges( edges ); + } + else + { + const _FaceSide* bottom = mySides.GetSide( Q_BOTTOM ); + int i = 0; + while ( true ) { + TopoDS_Edge e = bottom->Edge( i++ ); + if ( e.IsNull() ) + break; + else + edges.push_back( e ); + } + if ( myRightBrother ) + myRightBrother->GetHoriEdges( edges ); + } + return edges.size(); +} + //================================================================================ /*! * \brief Return a node by its position @@ -1287,7 +1464,6 @@ int _FaceSide::NbVertices() const { if ( myChildren.empty() ) return myVertices.Extent(); -// return myVertices.size(); return myNbChildren + 1; } @@ -1334,6 +1510,23 @@ TopoDS_Vertex _FaceSide::Vertex(int i) const return GetSide(i)->FirstVertex(); } +//================================================================================ +/*! + * \brief Return i-the zero-based edge of the side + */ +//================================================================================ + +TopoDS_Edge _FaceSide::Edge(int i) const +{ + if ( i == 0 && !myEdge.IsNull() ) + return myEdge; + + if ( const _FaceSide* iSide = GetSide( i )) + return iSide->myEdge; + + return TopoDS_Edge(); +} + //======================================================================= //function : Contain //purpose : @@ -1346,9 +1539,6 @@ bool _FaceSide::Contain( const _FaceSide& side, int* which ) const if ( which ) *which = 0; int nbCommon = 0; -// set::iterator v, vEnd = side.myVertices.end(); -// for ( v = side.myVertices.begin(); v != vEnd; ++v ) -// nbCommon += ( myVertices.find( *v ) != myVertices.end() ); TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices ); for ( ; vIt.More(); vIt.Next() ) nbCommon += ( myVertices.Contains( vIt.Key() )); @@ -1372,7 +1562,6 @@ bool _FaceSide::Contain( const _FaceSide& side, int* which ) const bool _FaceSide::Contain( const TopoDS_Vertex& vertex ) const { return myVertices.Contains( vertex ); -// return myVertices.find( ptr( vertex )) != myVertices.end(); } //======================================================================= @@ -1390,7 +1579,6 @@ void _FaceSide::AppendSide( const _FaceSide& side ) } myChildren.push_back( side ); myNbChildren++; - //myVertices.insert( side.myVertices.begin(), side.myVertices.end() ); TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices ); for ( ; vIt.More(); vIt.Next() ) myVertices.Add( vIt.Key() ); diff --git a/src/StdMeshers/StdMeshers_CompositeHexa_3D.hxx b/src/StdMeshers/StdMeshers_CompositeHexa_3D.hxx index 09b687fc1..d5b9f8b4e 100644 --- a/src/StdMeshers/StdMeshers_CompositeHexa_3D.hxx +++ b/src/StdMeshers/StdMeshers_CompositeHexa_3D.hxx @@ -1,29 +1,26 @@ -// SMESH SMESH : implementaion of SMESH idl descriptions +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_CompositeBlock_3D.hxx // Module : SMESH - +// #ifndef _SMESH_CompositeSegment_1D_HXX_ #define _SMESH_CompositeSegment_1D_HXX_ @@ -34,6 +31,7 @@ class SMESH_Mesh; class StdMeshers_FaceSide; class TopoDS_Edge; class TopoDS_Face; +struct _QuadFaceGrid; /*! * \brief Computes hexahedral mesh on a box with composite sides @@ -48,14 +46,25 @@ public: //virtual ~StdMeshers_CompositeHexa_3D(); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); virtual bool CheckHypothesis(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, Hypothesis_Status& aStatus); private: - // private fields + + bool findBoxFaces( const TopoDS_Shape& shape, + list< _QuadFaceGrid >& boxFaceContainer, + _QuadFaceGrid * & fBottom, + _QuadFaceGrid * & fTop, + _QuadFaceGrid * & fFront, + _QuadFaceGrid * & fBack, + _QuadFaceGrid * & fLeft, + _QuadFaceGrid * & fRight); }; #endif diff --git a/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx b/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx index f5cf86cd9..2b5847038 100644 --- a/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx +++ b/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx @@ -1,30 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions -// File : StdMeshers_Regular_1D.cxx -// Moved here from SMESH_Regular_1D.cxx -// Author : Paul RASCLE, EDF +// File : StdMeshers_CompositeSegment_1D.cxx // Module : SMESH -// $Header$ // #include "StdMeshers_CompositeSegment_1D.hxx" #include "StdMeshers_FaceSide.hxx" @@ -73,15 +71,16 @@ namespace { */ //================================================================================ - TopoDS_Edge nextC1Edge(const TopoDS_Edge& edge, - SMESH_Mesh & aMesh, - const bool forward) + TopoDS_Edge nextC1Edge(TopoDS_Edge edge, + SMESH_Mesh & aMesh, + const bool forward) { + if (edge.Orientation() > TopAbs_REVERSED) // INTERNAL + edge.Orientation( TopAbs_FORWARD ); TopoDS_Edge eNext; TopTools_MapOfShape edgeCounter; edgeCounter.Add( edge ); - TopoDS_Vertex v; - v = forward ? TopExp::LastVertex( edge,1 ) : TopExp::FirstVertex( edge,1 ); + TopoDS_Vertex v = forward ? TopExp::LastVertex(edge,true) : TopExp::FirstVertex(edge,true); TopTools_ListIteratorOfListOfShape ancestIt = aMesh.GetAncestors( v ); for ( ; ancestIt.More(); ancestIt.Next() ) { @@ -92,11 +91,11 @@ namespace { if ( edgeCounter.Extent() < 3 && !eNext.IsNull() ) { if ( SMESH_Algo::IsContinuous( edge, eNext )) { // care of orientation - bool reverse; - if ( forward ) - reverse = ( !v.IsSame( TopExp::FirstVertex( eNext, true ))); - else - reverse = ( !v.IsSame( TopExp::LastVertex( eNext, true ))); + if (eNext.Orientation() > TopAbs_REVERSED) // INTERNAL + eNext.Orientation( TopAbs_FORWARD ); + TopoDS_Vertex vn = + forward ? TopExp::FirstVertex(eNext,true) : TopExp::LastVertex(eNext,true); + bool reverse = (!v.IsSame(vn)); if ( reverse ) eNext.Reverse(); return eNext; @@ -151,7 +150,9 @@ namespace { struct VertexNodesRestoringListener : public SMESH_subMeshEventListener { - VertexNodesRestoringListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh + VertexNodesRestoringListener(): + SMESH_subMeshEventListener(0, // won't be deleted by submesh + "StdMeshers_CompositeSegment_1D::VertexNodesRestoringListener") {} /*! * \brief Restore nodes on internal vertices of a complex side @@ -167,17 +168,23 @@ namespace { EventListenerData* data, const SMESH_Hypothesis* /*hyp*/) { - bool hypRemoved = ( eventType == SMESH_subMesh::ALGO_EVENT && - subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK ); - if ( hypRemoved && data ) + if ( data && eventType == SMESH_subMesh::ALGO_EVENT ) { - list::iterator smIt = data->mySubMeshes.begin(); - for ( ; smIt != data->mySubMeshes.end(); ++smIt ) + bool hypRemoved; + if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK ) + hypRemoved = true; + else { + SMESH_Algo* algo = subMesh->GetAlgo(); + hypRemoved = ( string( algo->GetName() ) != StdMeshers_CompositeSegment_1D::AlgoName()); + } + if ( hypRemoved ) { - if ( SMESH_subMesh* sm = *smIt ) { - sm->SetIsAlwaysComputed( false ); - sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - } + list::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: @@ -224,10 +231,19 @@ StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D(int hypId :StdMeshers_Regular_1D(hypId, studyId, gen) { MESSAGE("StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D"); - _name = "CompositeSegment_1D"; + _name = AlgoName(); _EventListener = new VertexNodesRestoringListener(); } +//======================================================================= +//function : AlgoName +//purpose : Returns algo type name +//======================================================================= + +std::string StdMeshers_CompositeSegment_1D::AlgoName() +{ + return "CompositeSegment_1D"; +} //============================================================================= /*! * @@ -251,6 +267,35 @@ StdMeshers_CompositeSegment_1D::~StdMeshers_CompositeSegment_1D() void StdMeshers_CompositeSegment_1D::SetEventListener(SMESH_subMesh* subMesh) { + // issue 0020279. Set "_alwaysComputed" flag to the submeshes of internal + // vertices of composite edge in order to avoid creation of vertices on + // them for the sake of stability. + + // check if "_alwaysComputed" is not yet set + bool isAlwaysComputed = false; + SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false); + while ( !isAlwaysComputed && smIt->more() ) + isAlwaysComputed = smIt->next()->IsAlwaysComputed(); + + if ( !isAlwaysComputed ) + { + // 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 ) { // complex + + // set _alwaysComputed to vertices + for ( int iE = 1; iE < side->NbEdges(); ++iE ) + { + TopoDS_Vertex V = side->FirstVertex( iE ); + SMESH_subMesh* sm = side->GetMesh()->GetSubMesh( V ); + sm->SetIsAlwaysComputed( true ); + } + } + } + // set listener that will remove _alwaysComputed from submeshes at algorithm change subMesh->SetEventListener( _EventListener, 0, subMesh); StdMeshers_Regular_1D::SetEventListener( subMesh ); } @@ -268,14 +313,17 @@ StdMeshers_CompositeSegment_1D::GetFaceSide(SMESH_Mesh& aMesh, const bool ignoreMeshed) { list< TopoDS_Edge > edges; - edges.push_back( anEdge ); + if ( anEdge.Orientation() <= TopAbs_REVERSED ) + edges.push_back( anEdge ); + else + edges.push_back( TopoDS::Edge( anEdge.Oriented( TopAbs_FORWARD ))); // PAL21718 list 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 ); + TopoDS_Edge eNext = nextC1Edge( edges.back(), aMesh, forward ); while ( !eNext.IsNull() ) { if ( ignoreMeshed ) { // eNext must not have computed mesh @@ -289,6 +337,8 @@ StdMeshers_CompositeSegment_1D::GetFaceSide(SMESH_Mesh& aMesh, string(theAlgo->GetName()) != algo->GetName() || hypList != algo->GetUsedHypothesis(aMesh, eNext, false)) break; + if ( std::find( edges.begin(), edges.end(), eNext ) != edges.end() ) + break; if ( forward ) edges.push_back( eNext ); else diff --git a/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx b/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx index 1ec160335..c1beab206 100644 --- a/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx +++ b/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_CompositeSegment_1D.hxx // Module : SMESH -// $Header$ // #ifndef _SMESH_CompositeSegment_1D_HXX_ #define _SMESH_CompositeSegment_1D_HXX_ @@ -43,7 +43,7 @@ public: virtual ~StdMeshers_CompositeSegment_1D(); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); /*! * \brief Sets event listener to submeshes if necessary * \param subMesh - submesh where algo is set @@ -61,6 +61,11 @@ public: const TopoDS_Face& aFace, const bool ignoreMeshed); + /*! + * \brief Returns algo type name + */ + static std::string AlgoName(); + protected: SMESH_subMeshEventListener* _EventListener; }; diff --git a/src/StdMeshers/StdMeshers_Deflection1D.cxx b/src/StdMeshers/StdMeshers_Deflection1D.cxx index 42ad9219a..92e8589e7 100644 --- a/src/StdMeshers/StdMeshers_Deflection1D.cxx +++ b/src/StdMeshers/StdMeshers_Deflection1D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers_Deflection1D : implementaion of SMESH idl descriptions // File : StdMeshers_Deflection1D.cxx // Module : SMESH @@ -203,7 +204,7 @@ bool StdMeshers_Deflection1D::SetParametersByMesh(const SMESH_Mesh* theMesh, { const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE )); Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax ); - GeomAdaptor_Curve AdaptCurve(C); + GeomAdaptor_Curve AdaptCurve(C, UMin, UMax); if ( AdaptCurve.GetType() != GeomAbs_Line ) { vector< double > params; diff --git a/src/StdMeshers/StdMeshers_Deflection1D.hxx b/src/StdMeshers/StdMeshers_Deflection1D.hxx index a3cf19b70..4f7ea0975 100644 --- a/src/StdMeshers/StdMeshers_Deflection1D.hxx +++ b/src/StdMeshers/StdMeshers_Deflection1D.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of SMESH idl descriptions // File : StdMeshers_Deflection1D.hxx // Module : SMESH // - #ifndef _StdMeshers_Deflection1D_HXX_ #define _StdMeshers_Deflection1D_HXX_ diff --git a/src/StdMeshers/StdMeshers_Distribution.cxx b/src/StdMeshers/StdMeshers_Distribution.cxx index f2e591f34..fca2976f7 100644 --- a/src/StdMeshers/StdMeshers_Distribution.cxx +++ b/src/StdMeshers/StdMeshers_Distribution.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of point distribution algorithm // File : StdMeshers_Distribution.cxx // Author : Alexandre SOLOVYOV @@ -303,21 +304,21 @@ double dihotomySolve( Function& f, const double val, const double _start, const } bool buildDistribution( const TCollection_AsciiString& f, const int conv, const double start, const double end, - const int nbSeg, vector& data, const double eps ) + const int nbSeg, vector& data, const double eps ) { FunctionExpr F( f.ToCString(), conv ); return buildDistribution( F, start, end, nbSeg, data, eps ); } bool buildDistribution( const std::vector& f, const int conv, const double start, const double end, - const int nbSeg, vector& data, const double eps ) + const int nbSeg, vector& data, const double eps ) { FunctionTable F( f, conv ); return buildDistribution( F, start, end, nbSeg, data, eps ); } bool buildDistribution( const Function& func, const double start, const double end, const int nbSeg, - vector& data, const double eps ) + vector& data, const double eps ) { if( nbSeg<=0 ) return false; diff --git a/src/StdMeshers/StdMeshers_Distribution.hxx b/src/StdMeshers/StdMeshers_Distribution.hxx index 373305b63..10ba4cde8 100644 --- a/src/StdMeshers/StdMeshers_Distribution.hxx +++ b/src/StdMeshers/StdMeshers_Distribution.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of point distribution algorithm // File : StdMeshers_Distribution.hxx // Author : Alexandre SOLOVYOV @@ -102,16 +103,16 @@ private: STDMESHERS_EXPORT bool buildDistribution( const Function& f, - const double start, const double end, - const int nbSeg, - std::vector& data, - const double eps ); + const double start, const double end, + const int nbSeg, + std::vector& data, + const double eps ); STDMESHERS_EXPORT bool buildDistribution( const TCollection_AsciiString& f, const int conv, const double start, const double end, - const int nbSeg, std::vector& data, const double eps ); + const int nbSeg, std::vector& data, const double eps ); STDMESHERS_EXPORT bool buildDistribution( const std::vector& f, const int conv, const double start, const double end, - const int nbSeg, std::vector& data, const double eps ); + const int nbSeg, std::vector& data, const double eps ); #endif diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 7719b4f6e..13c2d6263 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -1,25 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : StdMeshers_FaceSide.hxx // Created : Wed Jan 31 18:41:25 2007 // Author : Edward AGAPOV (eap) @@ -31,19 +31,21 @@ #include "SMDS_MeshNode.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESHDS_SubMesh.hxx" -//#include "SMESH_Algo.hxx" +#include "SMESH_Algo.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_ComputeError.hxx" #include "SMESH_Block.hxx" #include #include -#include #include #include +#include +#include #include #include +#include #include #include #include @@ -85,30 +87,36 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, 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; + myEdge.resize ( nbEdges ); + myEdgeID.resize ( nbEdges ); + myC2d.resize ( nbEdges ); + myC3dAdaptor.resize( nbEdges ); + myFirst.resize ( nbEdges ); + myLast.resize ( nbEdges ); + myNormPar.resize ( nbEdges ); + myEdgeLength.resize( nbEdges ); + myIsUniform.resize ( nbEdges, true ); + myLength = 0; + myNbPonits = myNbSegments = 0; + myMesh = theMesh; myMissingVertexNodes = false; - myIgnoreMediumNodes = theIgnoreMediumNodes; + myIgnoreMediumNodes = theIgnoreMediumNodes; + myDefaultPnt2d = gp_Pnt2d( 1e+100, 1e+100 ); if ( nbEdges == 0 ) return; SMESHDS_Mesh* meshDS = theMesh->GetMeshDS(); - vector len( nbEdges ); int nbDegen = 0; list::iterator edge = theEdges.begin(); + TopoDS_Iterator vExp; 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]; + int i = theIsForward ? index : nbEdges-index-1; + myEdgeLength[i] = SMESH_Algo::EdgeLength( *edge ); + if ( myEdgeLength[i] < DBL_MIN ) nbDegen++; + myLength += myEdgeLength[i]; myEdge[i] = *edge; + myEdgeID[i] = meshDS->ShapeToIndex( *edge ); if ( !theIsForward ) myEdge[i].Reverse(); if ( theFace.IsNull() ) @@ -128,16 +136,43 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace, myNbPonits += nbN; myNbSegments += sm->NbElements(); } - if ( SMESH_Algo::VertexNode( TopExp::FirstVertex( *edge, 1), meshDS )) + // TopExp::FirstVertex() and TopExp::LastVertex() return NULL from INTERNAL edge + vExp.Initialize( *edge ); + if ( vExp.Value().Orientation() == TopAbs_REVERSED ) vExp.Next(); + if ( SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Value()), 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; + // check if edge has non-uniform parametrization (issue 0020705) + if ( !myC2d[i].IsNull() && myEdgeLength[i] > DBL_MIN) + { + Geom2dAdaptor_Curve A2dC( myC2d[i], + std::min( myFirst[i], myLast[i] ), + std::max( myFirst[i], myLast[i] )); + double p2 = myFirst[i]+(myLast[i]-myFirst[i])/2., p4 = myFirst[i]+(myLast[i]-myFirst[i])/4.; + double d2 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p2 ); + double d4 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p4 ); + //cout<<"len = "<MeshElements( myEdge[i] )) + { + vector< pair< double, const SMDS_MeshNode*> > u2nodeVec; + u2nodeVec.reserve( sm->NbNodes() ); + SMDS_NodeIteratorPtr nItr = sm->GetNodes(); + double paramSize = myLast[i] - myFirst[i]; + double r = myNormPar[i] - prevNormPar; + helper.SetSubShape( myEdge[i] ); + helper.ToFixNodeParameters( true ); + if ( !myIsUniform[i] ) + while ( nItr->more() ) + { + const SMDS_MeshNode* node = nItr->next(); + if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; + double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); + double aLenU = GCPnts_AbscissaPoint::Length + ( const_cast( myC3dAdaptor[i]), myFirst[i], u ); + if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6" + { + u2nodeVec.clear(); + break; + } + double normPar = prevNormPar + r*aLenU/myEdgeLength[i]; + u2nodeVec.push_back( make_pair( normPar, node )); + } + nItr = sm->GetNodes(); + if ( u2nodeVec.empty() ) + while ( nItr->more() ) + { + const SMDS_MeshNode* node = nItr->next(); + if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; + double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); + + // paramSize is signed so orientation is taken into account + double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize; + u2nodeVec.push_back( make_pair( normPar, node )); + } + for ( size_t j = 0; j < u2nodeVec.size(); ++j ) + u2node.insert( u2node.end(), u2nodeVec[j] ); + } + + // Put 2nd vertex node for a last edge if ( i+1 == myEdge.size() ) { - node = SMESH_Algo::VertexNode( VLast, meshDS ); + node = SMESH_Algo::VertexNode( VV[1], 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(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"); - MESSAGE ( "WRONG normPar: "<MeshElements( myEdge[i] )) + { + SMDS_NodeIteratorPtr nItr = sm->GetNodes(); + double paramSize = myLast[i] - myFirst[i]; + double r = myNormPar[i] - prevNormPar; + helper.SetSubShape( myEdge[i] ); + helper.ToFixNodeParameters( true ); + while ( nItr->more() ) + { + const SMDS_MeshNode* node = nItr->next(); + if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; + double u = helper.GetNodeU( myEdge[i], node, 0, ¶mOK ); + + // paramSize is signed so orientation is taken into account + double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize; + u2node.insert( u2node.end(), make_pair( normPar, node )); + } + } + + // Put 2nd vertex node for a last edge + if ( i+1 == myEdge.size() ) { + node = SMESH_Algo::VertexNode( VV[1], meshDS ); + if ( !node ) { + return resultNodes; + } + u2node.insert( u2node.end(), make_pair( 1., node )); + } + } + + // Fill the result vector + + if ( u2node.size() == myNbPonits ) + { + resultNodes.reserve( u2node.size() ); + map< double, const SMDS_MeshNode*>::iterator u2n = u2node.begin(); + for ( ; u2n != u2node.end(); ++u2n ) + resultNodes.push_back( u2n->second ); + } + } + else + { + resultNodes.resize( myPoints.size() ); + for ( size_t i = 0; i < myPoints.size(); ++i ) + resultNodes[i] = myPoints[i].node; + } + + return resultNodes; +} //================================================================================ /*! @@ -362,14 +533,21 @@ void StdMeshers_FaceSide::Reverse() } if ( nbEdges > 1 ) { reverse( myEdge ); + reverse( myEdgeID ); reverse( myC2d ); + reverse( myC3dAdaptor ); reverse( myFirst ); reverse( myLast ); reverse( myNormPar ); + reverse( myEdgeLength ); + reverse( myIsUniform ); + } + if ( nbEdges > 0 ) + { + myNormPar[nbEdges-1]=1.; + myPoints.clear(); + myFalsePoints.clear(); } - myNormPar[nbEdges-1]=1.; - myPoints.clear(); - myFalsePoints.clear(); } //================================================================================ @@ -443,17 +621,19 @@ 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; iValue( myFirst[i] * ( 1 - r ) + myLast[i] * r ); + + double par = myFirst[i] * ( 1 - r ) + myLast[i] * r; + + // check parametrization of curve + if( !myIsUniform[i] ) + { + double aLen3dU = r * myEdgeLength[i] * ( myFirst[i]>myLast[i] ? -1. : 1.); + GCPnts_AbscissaPoint AbPnt + ( const_cast( myC3dAdaptor[i]), aLen3dU, myFirst[i] ); + if( AbPnt.IsDone() ) { + par = AbPnt.Parameter(); + } + } + return myC2d[ i ]->Value(par); + } - return gp_Pnt2d( 1e+100, 1e+100 ); + return myDefaultPnt2d; } //================================================================================ @@ -485,46 +679,97 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace, TError & theError) { TopoDS_Vertex V1; - list< TopoDS_Edge > edges; + list< TopoDS_Edge > edges, internalEdges; list< int > nbEdgesInWires; int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires); // split list of all edges into separate wires TSideVector 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 ) + list< TopoDS_Edge >::iterator from = edges.begin(), to = from; + for ( int iW = 0; iW < nbWires; ++iW, ++nbE ) { - std::advance( to, *nbE++ ); + std::advance( to, *nbE ); + if ( *nbE == 0 ) // Issue 0020676 + { + --nbWires; + --iW; + wires.resize( nbWires ); + continue; + } list< TopoDS_Edge > wireEdges( from, to ); // assure that there is a node on the first vertex // as StdMeshers_FaceSide::GetUVPtStruct() requires - while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), - theMesh.GetMeshDS())) + if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676 { - wireEdges.splice(wireEdges.end(), wireEdges, - wireEdges.begin(), ++wireEdges.begin()); - if ( from->IsSame( wireEdges.front() )) { - theError = TError - ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices")); - return TSideVector(0); + while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true), + theMesh.GetMeshDS())) + { + wireEdges.splice(wireEdges.end(), wireEdges, + wireEdges.begin(), ++wireEdges.begin()); + if ( from->IsSame( wireEdges.front() )) { + theError = TError + ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices")); + return TSideVector(0); + } } } - // find out side orientation, which is important if there are several wires (PAL19080) - bool isForward = true; - if ( nbWires > 1 ) { - TopExp_Explorer e( theFace, TopAbs_EDGE ); - while ( ! e.Current().IsSame( wireEdges.back() )) - e.Next(); - isForward = ( e.Current().Orientation() == wireEdges.back().Orientation() ); + else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire + { + internalEdges.splice( internalEdges.end(), wireEdges, ++wireEdges.begin(), wireEdges.end()); } StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh, - isForward, theIgnoreMediumNodes); + /*isForward=*/true, theIgnoreMediumNodes); wires[ iW ] = StdMeshers_FaceSidePtr( wire ); from = to; } + while ( !internalEdges.empty() ) + { + StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh, + /*isForward=*/true, theIgnoreMediumNodes); + wires.push_back( StdMeshers_FaceSidePtr( wire )); + internalEdges.pop_back(); + } return wires; } +//================================================================================ +/*! + * \brief Return 1st vertex of the i-the edge + */ +//================================================================================ + +TopoDS_Vertex StdMeshers_FaceSide::FirstVertex(int i) const +{ + TopoDS_Vertex v; + if ( i < NbEdges() ) + { + v = myEdge[i].Orientation() <= TopAbs_REVERSED ? // FORWARD || REVERSED + TopExp::FirstVertex( myEdge[i], 1 ) : + TopoDS::Vertex( TopoDS_Iterator( myEdge[i] ).Value() ); + } + return v; +} + +//================================================================================ +/*! + * \brief Return last vertex of the i-the edge + */ +//================================================================================ + +TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const +{ + TopoDS_Vertex v; + if ( i < NbEdges() ) + { + const TopoDS_Edge& edge = i<0 ? myEdge[ NbEdges() + i ] : myEdge[i]; + if ( edge.Orientation() <= TopAbs_REVERSED ) // FORWARD || REVERSED + v = TopExp::LastVertex( edge, 1 ); + else + for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() ) + v = TopoDS::Vertex( vIt.Value() ); + } + return v; +} + diff --git a/src/StdMeshers/StdMeshers_FaceSide.hxx b/src/StdMeshers/StdMeshers_FaceSide.hxx index 202b6a6d4..4a119ed84 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.hxx +++ b/src/StdMeshers/StdMeshers_FaceSide.hxx @@ -1,25 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : StdMeshers_FaceSide.hxx // Created : Wed Jan 31 18:41:25 2007 // Author : Edward AGAPOV (eap) @@ -28,14 +28,13 @@ #ifndef StdMeshers_FaceSide_HeaderFile #define StdMeshers_FaceSide_HeaderFile -#include +#include "SMESH_StdMeshers.hxx" + +#include +#include #include #include -#include -#include - -#include "SMESH_StdMeshers.hxx" -#include "SMESH_Algo.hxx" +#include #include #include @@ -47,7 +46,7 @@ class Adaptor2d_Curve2d; class Adaptor3d_Curve; class BRepAdaptor_CompCurve; class TopoDS_Face; -class SMESH_ComputeError; +struct SMESH_ComputeError; typedef struct uvPtStruct { @@ -63,9 +62,8 @@ typedef struct uvPtStruct class StdMeshers_FaceSide; typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr; -typedef boost::shared_ptr< uvPtStruct > UVPtStructPtr; -typedef std::vector< StdMeshers_FaceSidePtr > TSideVector; -typedef boost::shared_ptr< SMESH_ComputeError > TError; +typedef std::vector< StdMeshers_FaceSidePtr > TSideVector; +typedef boost::shared_ptr< SMESH_ComputeError > TError; //================================================================================ /*! @@ -88,12 +86,17 @@ public: /*! * \brief Wrap several edges. Edges must be properly ordered and oriented. */ - StdMeshers_FaceSide(const TopoDS_Face& theFace, + StdMeshers_FaceSide(const TopoDS_Face& theFace, std::list& theEdges, - SMESH_Mesh* theMesh, - const bool theIsForward, - const bool theIgnoreMediumNodes); - + SMESH_Mesh* theMesh, + const bool theIsForward, + const bool theIgnoreMediumNodes); + /*! + * \brief Simulate a side from a vertex using data from other FaceSide + */ + StdMeshers_FaceSide(const SMDS_MeshNode* theNode, + const gp_Pnt2d thePnt2d, + const StdMeshers_FaceSide* theSide); /*! * \brief Return wires of a face as StdMeshers_FaceSide's */ @@ -119,7 +122,7 @@ public: */ SMESH_Mesh* GetMesh() const { return myMesh; } /*! - * \brief Return true if there vertices without nodes + * \brief Return true if there are vertices without nodes */ bool MissVertexNode() const { return myMissingVertexNodes; } /*! @@ -127,7 +130,8 @@ public: * \param isXConst - true if normalized parameter X is constant * \param constValue - constant parameter value * - * Missing nodes are allowed only on internal vertices + * Missing nodes are allowed only on internal vertices. + * For a closed side, the 1st point repeats at end */ const std::vector& GetUVPtStruct(bool isXConst =0, double constValue =0) const; /*! @@ -136,8 +140,13 @@ public: * \param constValue - constant parameter value */ const std::vector& SimulateUVPtStruct(int nbSeg, - bool isXConst = 0, - double constValue = 0) const; + bool isXConst = 0, + double constValue = 0) const; + /*! + * \brief Return nodes in the order they encounter while walking along the side. + * For a closed side, the 1st point repeats at end + */ + std::vector GetOrderedNodes() const; /*! * \brief Return edge and parameter on edge by normalized parameter */ @@ -162,14 +171,18 @@ public: * \brief Return i-th wrapped edge (count starts from zero) */ const TopoDS_Edge& Edge(int i) const { return myEdge[i]; } + /*! + * \brief Return all edges + */ + const std::vector& Edges() const { return myEdge; } /*! * \brief Return 1st vertex of the i-the edge (count starts from zero) */ - inline TopoDS_Vertex FirstVertex(int i=0) const; + 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; + TopoDS_Vertex LastVertex(int i=-1) const; /*! * \brief Return first normalized parameter of the i-the edge (count starts from zero) */ @@ -193,15 +206,22 @@ public: protected: + + // DON't FORGET to update Reverse() when adding one more vector! std::vector myPoints, myFalsePoints; std::vector myEdge; + std::vector myEdgeID; std::vector myC2d; + std::vector myC3dAdaptor; std::vector myFirst, myLast; std::vector myNormPar; + std::vector myEdgeLength; + std::vector myIsUniform; double myLength; int myNbPonits, myNbSegments; SMESH_Mesh* myMesh; bool myMissingVertexNodes, myIgnoreMediumNodes; + gp_Pnt2d myDefaultPnt2d; }; @@ -237,28 +257,6 @@ inline double StdMeshers_FaceSide::Parameter(double U, TopoDS_Edge & edge) const 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 +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include + +using namespace std; + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_FixedPoints1D::StdMeshers_FixedPoints1D(int hypId, int studyId, + SMESH_Gen * gen) + :SMESH_Hypothesis(hypId, studyId, gen) +{ + _name = "FixedPoints1D"; + _param_algo_dim = 1; + _nbsegs.reserve( 1 ); + _nbsegs.push_back( 1 ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_FixedPoints1D::~StdMeshers_FixedPoints1D() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_FixedPoints1D::SetPoints(std::vector& listParams) + throw(SALOME_Exception) +{ + _params = listParams; + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_FixedPoints1D::SetNbSegments(std::vector& listNbSeg) + throw(SALOME_Exception) +{ + _nbsegs = listNbSeg; + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_FixedPoints1D::SetReversedEdges( std::vector& ids ) +{ + if ( ids != _edgeIDs ) { + _edgeIDs = ids; + + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & StdMeshers_FixedPoints1D::SaveTo(ostream & save) +{ + int listSize = _params.size(); + save << listSize; + if ( listSize > 0 ) { + for ( int i = 0; i < listSize; i++) save << " " << _params[i]; + } + + listSize = _nbsegs.size(); + save << " " << listSize; + if ( listSize > 0 ) { + for ( int i = 0; i < listSize; i++) save << " " << _nbsegs[i]; + } + + listSize = _edgeIDs.size(); + save << " " << listSize; + if ( listSize > 0 ) { + for ( int i = 0; i < listSize; i++) + save << " " << _edgeIDs[i]; + } + + save << " " << _objEntry; + + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & StdMeshers_FixedPoints1D::LoadFrom(istream & load) +{ + bool isOK = true; + int intVal; + double dblVal; + + isOK = (load >> intVal); + if (isOK && intVal > 0) { + _params.clear(); + _params.reserve( intVal ); + for (int i = 0; i < _params.capacity() && isOK; i++) { + isOK = (load >> dblVal); + if ( isOK ) _params.push_back( dblVal ); + } + } + + isOK = (load >> intVal); + if (isOK && intVal > 0) { + _nbsegs.clear(); + _nbsegs.reserve( intVal ); + for (int i = 0; i < _nbsegs.capacity() && isOK; i++) { + isOK = (load >> intVal); + if ( isOK ) _nbsegs.push_back( intVal ); + } + } + + isOK = (load >> intVal); + if (isOK && intVal > 0) { + _edgeIDs.clear(); + _edgeIDs.reserve( intVal ); + for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) { + isOK = (load >> intVal); + if ( isOK ) _edgeIDs.push_back( intVal ); + } + } + + isOK = (load >> _objEntry); + + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +ostream & operator <<(ostream & save, StdMeshers_FixedPoints1D & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +istream & operator >>(istream & load, StdMeshers_FixedPoints1D & hyp) +{ + return hyp.LoadFrom( load ); +} + +//================================================================================ +/*! + * \brief Initialize start and end 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_FixedPoints1D::SetParametersByMesh(const SMESH_Mesh* theMesh, + const TopoDS_Shape& theShape) +{ + if ( !theMesh || theShape.IsNull() ) + return false; + + _nbsegs.reserve( 1 ); + _nbsegs.push_back( 1 ); + return true; +} + +//================================================================================ +/*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_FixedPoints1D::SetParametersByDefaults(const TDefaults& dflts, + const SMESH_Mesh* /*mesh*/) +{ + _nbsegs.reserve( 1 ); + _nbsegs.push_back( 1 ); + return true; +} + diff --git a/src/StdMeshers/StdMeshers_FixedPoints1D.hxx b/src/StdMeshers/StdMeshers_FixedPoints1D.hxx new file mode 100644 index 000000000..384ad9c93 --- /dev/null +++ b/src/StdMeshers/StdMeshers_FixedPoints1D.hxx @@ -0,0 +1,88 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_FixedPoints1D.hxx +// Author : Damien COQUERET, OCC +// Module : SMESH +// +#ifndef _SMESH_FIXEDPOINTS1D_HXX_ +#define _SMESH_FIXEDPOINTS1D_HXX_ + + + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +#include + +class STDMESHERS_EXPORT StdMeshers_FixedPoints1D: + public SMESH_Hypothesis +{ +public: + StdMeshers_FixedPoints1D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_FixedPoints1D(); + + void SetPoints(std::vector& listParams) + throw(SALOME_Exception); + + void SetNbSegments(std::vector& listNbSeg) + throw(SALOME_Exception); + + const std::vector& GetPoints() const { return _params; } + + const std::vector& GetNbSegments() const { return _nbsegs; } + + void SetReversedEdges( std::vector& ids); + + void SetObjectEntry( const char* entry ) { _objEntry = entry; } + + const char* GetObjectEntry() { return _objEntry.c_str(); } + + const std::vector& GetReversedEdges() const { return _edgeIDs; } + + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + friend std::ostream& operator << (std::ostream & save, StdMeshers_FixedPoints1D & hyp); + friend std::istream& operator >> (std::istream & load, StdMeshers_FixedPoints1D & hyp); + + /*! + * \brief Initialize start and end 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); + + /*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ + virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + +protected: + std::vector _params; + std::vector _nbsegs; + std::vector _edgeIDs; + std::string _objEntry; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx new file mode 100644 index 000000000..58a90931c --- /dev/null +++ b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx @@ -0,0 +1,1303 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_HexaFromSkin_3D.cxx +// Created : Wed Jan 27 12:28:07 2010 +// Author : Edward AGAPOV (eap) + +#include "StdMeshers_HexaFromSkin_3D.hxx" + +#include "SMDS_VolumeOfNodes.hxx" +#include "SMDS_VolumeTool.hxx" +#include "SMESH_Block.hxx" +#include "SMESH_MesherHelper.hxx" + +#include + +//#include "utilities.h" +#include + +// Define error message and _MYDEBUG_ if needed +#ifdef _DEBUG_ +#define BAD_MESH_ERR \ + error(SMESH_Comment("Can't detect block-wise structure of the input 2D mesh.\n" \ + __FILE__ ":" )<<__LINE__) +//#define _MYDEBUG_ +#else +#define BAD_MESH_ERR \ + error(SMESH_Comment("Can't detect block-wise structure of the input 2D mesh")) +#endif + + +// Debug output +#ifdef _MYDEBUG_ +#define _DUMP_(msg) cout << msg << endl +#else +#define _DUMP_(msg) +#endif + + +namespace +{ + enum EBoxSides //!< sides of the block + { + B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, NB_BLOCK_SIDES + }; +#ifdef _MYDEBUG_ + const char* SBoxSides[] = //!< names of block sides -- needed for DEBUG only + { + "BOTTOM", "RIGHT", "TOP", "LEFT", "FRONT", "BACK", "UNDEFINED" + }; +#endif + enum EQuadEdge //!< edges of quadrangle side + { + Q_BOTTOM = 0, Q_RIGHT, Q_TOP, Q_LEFT, NB_QUAD_SIDES + }; + + + //================================================================================ + /*! + * \brief return logical coordinates (i.e. min or max) of ends of edge + */ + //================================================================================ + + bool getEdgeEnds(EQuadEdge edge, bool& xMax1, bool& yMax1, bool& xMax2, bool& yMax2 ) + { + xMax1=0, yMax1=0, xMax2=1, yMax2=1; + switch( edge ) + { + case Q_BOTTOM: yMax2 = 0; break; + case Q_RIGHT: xMax1 = 1; break; + case Q_TOP: yMax1 = 1; break; + case Q_LEFT: xMax2 = 0; break; + default: + return false; + } + return true; + } + + //================================================================================ + /*! + * \brief return true if a node is at block corner + * + * This check is valid for simple cases only + */ + //================================================================================ + + bool isCornerNode( const SMDS_MeshNode* n ) + { + int nbF = n ? n->NbInverseElements( SMDSAbs_Face ) : 1; + if ( nbF % 2 ) + return true; + + set nodesInInverseFaces; + SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + nodesInInverseFaces.insert( face->begin_nodes(), face->end_nodes() ); + } + + return nodesInInverseFaces.size() != ( 6 + (nbF/2-1)*3 ); + } + + //================================================================================ + /*! + * \brief check element type + */ + //================================================================================ + + bool isQuadrangle(const SMDS_MeshElement* e) + { + return ( e && e->NbCornerNodes() == 4 ); + } + + //================================================================================ + /*! + * \brief return opposite node of a quadrangle face + */ + //================================================================================ + + const SMDS_MeshNode* oppositeNode(const SMDS_MeshElement* quad, int iNode) + { + return quad->GetNode( (iNode+2) % 4 ); + } + + //================================================================================ + /*! + * \brief Convertor of a pair of integers to a sole index + */ + struct _Indexer + { + int _xSize, _ySize; + _Indexer( int xSize=0, int ySize=0 ): _xSize(xSize), _ySize(ySize) {} + int size() const { return _xSize * _ySize; } + int operator()(int x, int y) const { return y * _xSize + x; } + }; + //================================================================================ + /*! + * \brief Oriented convertor of a pair of integers to a sole index + */ + class _OrientedIndexer : public _Indexer + { + public: + enum OriFlags //!< types of block side orientation + { + REV_X = 1, REV_Y = 2, SWAP_XY = 4, MAX_ORI = REV_X|REV_Y|SWAP_XY + }; + _OrientedIndexer( const _Indexer& indexer, const int oriFlags ): + _Indexer( indexer._xSize, indexer._ySize ), + _xSize (indexer._xSize), _ySize(indexer._ySize), + _xRevFun((oriFlags & REV_X) ? & reverse : & lazy), + _yRevFun((oriFlags & REV_Y) ? & reverse : & lazy), + _swapFun((oriFlags & SWAP_XY ) ? & swap : & lazy) + { + (*_swapFun)( _xSize, _ySize ); + } + //!< Return index by XY + int operator()(int x, int y) const + { + (*_xRevFun)( x, const_cast( _xSize )); + (*_yRevFun)( y, const_cast( _ySize )); + (*_swapFun)( x, y ); + return _Indexer::operator()(x,y); + } + //!< Return index for a corner + int corner(bool xMax, bool yMax) const + { + int x = xMax, y = yMax, size = 2; + (*_xRevFun)( x, size ); + (*_yRevFun)( y, size ); + (*_swapFun)( x, y ); + return _Indexer::operator()(x ? _Indexer::_xSize-1 : 0 , y ? _Indexer::_ySize-1 : 0); + } + int xSize() const { return _xSize; } + int ySize() const { return _ySize; } + private: + _Indexer _indexer; + int _xSize, _ySize; + + typedef void (*TFun)(int& x, int& y); + TFun _xRevFun, _yRevFun, _swapFun; + + static void lazy (int&, int&) {} + static void reverse(int& x, int& size) { x = size - x - 1; } + static void swap (int& x, int& y) { std::swap(x,y); } + }; + //================================================================================ + /*! + * \brief Structure corresponding to the meshed side of block + */ + struct _BlockSide + { + vector _grid; + _Indexer _index; + int _nbBlocksExpected; + int _nbBlocksFound; + +#ifdef _DEBUG_ // want to get SIGSEGV in case of invalid index +#define _grid_access_(pobj, i) pobj->_grid[ ((i) < pobj->_grid.size()) ? i : int(1e100)] +#else +#define _grid_access_(pobj, i) pobj->_grid[ i ] +#endif + //!< Return node at XY + const SMDS_MeshNode* getNode(int x, int y) const { return _grid_access_(this, _index( x,y ));} + //!< Set node at XY + void setNode(int x, int y, const SMDS_MeshNode* n) { _grid_access_(this, _index( x,y )) = n; } + //!< Return an edge + SMESH_OrientedLink getEdge(EQuadEdge edge) const + { + bool x1, y1, x2, y2; getEdgeEnds( edge, x1, y1, x2, y2 ); + return SMESH_OrientedLink( getCornerNode ( x1, y1 ), getCornerNode( x2, y2 )); + } + //!< Return a corner node + const SMDS_MeshNode* getCornerNode(bool isXMax, bool isYMax) const + { + return getNode( isXMax ? _index._xSize-1 : 0 , isYMax ? _index._ySize-1 : 0 ); + } + const SMDS_MeshElement* getCornerFace(const SMDS_MeshNode* cornerNode) const; + //!< True if all blocks this side belongs to have been found + bool isBound() const { return _nbBlocksExpected <= _nbBlocksFound; } + //!< Return coordinates of node at XY + gp_XYZ getXYZ(int x, int y) const { return SMESH_TNodeXYZ( getNode( x, y )); } + //!< Return gravity center of the four corners and the middle node + gp_XYZ getGC() const + { + gp_XYZ xyz = + getXYZ( 0, 0 ) + + getXYZ( _index._xSize-1, 0 ) + + getXYZ( 0, _index._ySize-1 ) + + getXYZ( _index._xSize-1, _index._ySize-1 ) + + getXYZ( _index._xSize/2, _index._ySize/2 ); + return xyz / 5; + } + //!< Return number of mesh faces + int getNbFaces() const { return (_index._xSize-1) * (_index._ySize-1); } + }; + //================================================================================ + /*! + * \brief _BlockSide with changed orientation + */ + struct _OrientedBlockSide + { + _BlockSide* _side; + _OrientedIndexer _index; + + _OrientedBlockSide( _BlockSide* side=0, const int oriFlags=0 ): + _side(side), _index(side ? side->_index : _Indexer(), oriFlags ) {} + //!< return coordinates by XY + gp_XYZ xyz(int x, int y) const + { + return SMESH_TNodeXYZ( _grid_access_(_side, _index( x, y )) ); + } + //!< safely return a node by XY + const SMDS_MeshNode* node(int x, int y) const + { + int i = _index( x, y ); + return ( i < 0 || i >= _side->_grid.size()) ? 0 : _side->_grid[i]; + } + //!< Return an edge + SMESH_OrientedLink edge(EQuadEdge edge) const + { + bool x1, y1, x2, y2; getEdgeEnds( edge, x1, y1, x2, y2 ); + return SMESH_OrientedLink( cornerNode ( x1, y1 ), cornerNode( x2, y2 )); + } + //!< Return a corner node + const SMDS_MeshNode* cornerNode(bool isXMax, bool isYMax) const + { + return _grid_access_(_side, _index.corner( isXMax, isYMax )); + } + //!< return its size in nodes + int getHoriSize() const { return _index.xSize(); } + int getVertSize() const { return _index.ySize(); } + //!< True if _side has been initialized + operator bool() const { return _side; } + //! Direct access to _side + const _BlockSide* operator->() const { return _side; } + _BlockSide* operator->() { return _side; } + }; + //================================================================================ + /*! + * \brief Meshed skin of block + */ + struct _Block + { + _OrientedBlockSide _side[6]; // 6 sides of a sub-block + set _corners; + + const _OrientedBlockSide& getSide(int i) const { return _side[i]; } + bool setSide( int i, const _OrientedBlockSide& s) + { + if (( _side[i] = s )) + { + _corners.insert( s.cornerNode(0,0)); + _corners.insert( s.cornerNode(1,0)); + _corners.insert( s.cornerNode(0,1)); + _corners.insert( s.cornerNode(1,1)); + } + return s; + } + void clear() { for (int i=0;i<6;++i) _side[i]=0; _corners.clear(); } + bool hasSide( const _OrientedBlockSide& s) const + { + if ( s ) for (int i=0;i<6;++i) if ( _side[i] && _side[i]._side == s._side ) return true; + return false; + } + int nbSides() const { int n=0; for (int i=0;i<6;++i) if ( _side[i] ) ++n; return n; } + bool isValid() const; + }; + //================================================================================ + /*! + * \brief Skin mesh possibly containing several meshed blocks + */ + class _Skin + { + public: + + int findBlocks(SMESH_Mesh& mesh); + //!< return i-th block + const _Block& getBlock(int i) const { return _blocks[i]; } + //!< return error description + const SMESH_Comment& error() const { return _error; } + + private: + bool fillSide( _BlockSide& side, + const SMDS_MeshElement* cornerQuad, + const SMDS_MeshNode* cornerNode); + bool fillRowsUntilCorner(const SMDS_MeshElement* quad, + const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + vector& verRow1, + vector& verRow2, + bool alongN1N2 ); + _OrientedBlockSide findBlockSide( EBoxSides startBlockSide, + EQuadEdge sharedSideEdge1, + EQuadEdge sharedSideEdge2, + bool withGeometricAnalysis, + set< _BlockSide* >& sidesAround); + //!< update own data and data of the side bound to block + void setSideBoundToBlock( _BlockSide& side ) + { + if ( side._nbBlocksFound++, side.isBound() ) + for ( int e = 0; e < int(NB_QUAD_SIDES); ++e ) + _edge2sides[ side.getEdge( (EQuadEdge) e ) ].erase( &side ); + } + //!< store reason of error + int error(const SMESH_Comment& reason) { _error = reason; return 0; } + + SMESH_Comment _error; + + list< _BlockSide > _allSides; + vector< _Block > _blocks; + + //map< const SMDS_MeshNode*, set< _BlockSide* > > _corner2sides; + map< SMESH_OrientedLink, set< _BlockSide* > > _edge2sides; + }; + + //================================================================================ + /*! + * \brief Find and return number of submeshes corresponding to blocks + */ + //================================================================================ + + int _Skin::findBlocks(SMESH_Mesh& mesh) + { + SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); + + // Find a node at any block corner + + SMDS_NodeIteratorPtr nIt = meshDS->nodesIterator(/*idInceasingOrder=*/true); + if ( !nIt->more() ) return error("Empty mesh"); + + const SMDS_MeshNode* nCorner = 0; + while ( nIt->more() ) + { + nCorner = nIt->next(); + if ( isCornerNode( nCorner )) + break; + else + nCorner = 0; + } + if ( !nCorner ) + return BAD_MESH_ERR; + + // -------------------------------------------------------------------- + // Find all block sides starting from mesh faces sharing the corner node + // -------------------------------------------------------------------- + + int nbFacesOnSides = 0; + TIDSortedElemSet cornerFaces; // corner faces of found _BlockSide's + list< const SMDS_MeshNode* > corners( 1, nCorner ); + list< const SMDS_MeshNode* >::iterator corner = corners.begin(); + while ( corner != corners.end() ) + { + SMDS_ElemIteratorPtr faceIt = (*corner)->GetInverseElementIterator( SMDSAbs_Face ); + while ( faceIt->more() ) + { + const SMDS_MeshElement* face = faceIt->next(); + if ( !cornerFaces.insert( face ).second ) + continue; // already loaded block side + + if ( !isQuadrangle( face )) + return error("Non-quadrangle elements in the input mesh"); + + if ( _allSides.empty() || !_allSides.back()._grid.empty() ) + _allSides.push_back( _BlockSide() ); + + _BlockSide& side = _allSides.back(); + if ( !fillSide( side, face, *corner ) ) + { + if ( !_error.empty() ) + return false; + } + else + { + for ( int isXMax = 0; isXMax < 2; ++isXMax ) + for ( int isYMax = 0; isYMax < 2; ++isYMax ) + { + const SMDS_MeshNode* nCorner = side.getCornerNode(isXMax,isYMax ); + corners.push_back( nCorner ); + cornerFaces.insert( side.getCornerFace( nCorner )); + } + for ( int e = 0; e < int(NB_QUAD_SIDES); ++e ) + _edge2sides[ side.getEdge( (EQuadEdge) e ) ].insert( &side ); + + nbFacesOnSides += side.getNbFaces(); + } + } + ++corner; + + // find block sides of other domains if any + if ( corner == corners.end() && nbFacesOnSides < mesh.NbQuadrangles() ) + { + while ( nIt->more() ) + { + nCorner = nIt->next(); + if ( isCornerNode( nCorner )) + corner = corners.insert( corner, nCorner ); + } + nbFacesOnSides = mesh.NbQuadrangles(); + } + } + + if ( _allSides.empty() ) + return BAD_MESH_ERR; + if ( _allSides.back()._grid.empty() ) + _allSides.pop_back(); + _DUMP_("Nb detected sides "<< _allSides.size()); + + // --------------------------- + // Organize sides into blocks + // --------------------------- + + // analyse sharing of sides by blocks and sort sides by nb of adjacent sides + int nbBlockSides = 0; // total nb of block sides taking into account their sharing + multimap sortedSides; + { + list < _BlockSide >::iterator sideIt = _allSides.begin(); + for ( ; sideIt != _allSides.end(); ++sideIt ) + { + _BlockSide& side = *sideIt; + bool isSharedSide = true; + int nbAdjacent = 0; + for ( int e = 0; e < int(NB_QUAD_SIDES) && isSharedSide; ++e ) + { + int nbAdj = _edge2sides[ side.getEdge( (EQuadEdge) e ) ].size(); + nbAdjacent += nbAdj; + isSharedSide = ( nbAdj > 2 ); + } + side._nbBlocksFound = 0; + side._nbBlocksExpected = isSharedSide ? 2 : 1; + nbBlockSides += side._nbBlocksExpected; + sortedSides.insert( make_pair( nbAdjacent, & side )); + } + } + + // find sides of each block + int nbBlocks = 0; + while ( nbBlockSides >= 6 ) + { + // get any side not bound to all blocks it belongs to + multimap::iterator i_side = sortedSides.begin(); + while ( i_side != sortedSides.end() && i_side->second->isBound()) + ++i_side; + + // start searching for block sides from the got side + bool ok = true; + if ( _blocks.empty() || _blocks.back()._side[B_FRONT] ) + _blocks.resize( _blocks.size() + 1 ); + + _Block& block = _blocks.back(); + block.setSide( B_FRONT, i_side->second ); + setSideBoundToBlock( *i_side->second ); + nbBlockSides--; + + // edges of adjacent sides of B_FRONT corresponding to front's edges + EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT }; + EQuadEdge edgeOfAdj [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT }; + // first find all sides detectable w/o advanced analysis, + // then repeat the search, which then may pass without advanced analysis + set< _BlockSide* > sidesAround; + for ( int advAnalys = 0; advAnalys < 2; ++advAnalys ) + { + // try to find 4 sides adjacent to a FRONT side + for ( int i = 0; (ok || !advAnalys) && i < NB_QUAD_SIDES; ++i ) + if ( !block._side[i] ) + ok = block.setSide( i, findBlockSide( B_FRONT, edgeOfFront[i], edgeOfAdj[i], + advAnalys, sidesAround)); + // try to find a BACK side by a TOP one + if ( ok || !advAnalys) + if ( !block._side[B_BACK] && block._side[B_TOP] ) + ok = block.setSide( B_BACK, findBlockSide( B_TOP, Q_TOP, Q_TOP, + advAnalys, sidesAround )); + if ( !advAnalys ) ok = true; + } + ok = block.isValid(); + if ( ok ) + { + // check if just found block is same as one of previously found blocks + bool isSame = false; + for ( int i = 1; i < _blocks.size() && !isSame; ++i ) + isSame = ( block._corners == _blocks[i-1]._corners ); + ok = !isSame; + } + + // count the found sides + _DUMP_(endl << "** Block " << _blocks.size() << " valid: " << block.isValid()); + for (int i = 0; i < NB_BLOCK_SIDES; ++i ) + { + _DUMP_("\tSide "<< SBoxSides[i] <<" "<< block._side[ i ]._side); + if ( block._side[ i ] ) + { + if ( ok && i != B_FRONT) + { + setSideBoundToBlock( *block._side[ i ]._side ); + nbBlockSides--; + } + _DUMP_("\t corners "<< + block._side[ i ].cornerNode(0,0)->GetID() << ", " << + block._side[ i ].cornerNode(1,0)->GetID() << ", " << + block._side[ i ].cornerNode(1,1)->GetID() << ", " << + block._side[ i ].cornerNode(0,1)->GetID() << ", "<GetNodeIndex( nCorner ); + const SMDS_MeshNode* nOnEdge = firstQuad->GetNode( (iCorner+1) % 4); + + // find out size of block side + vector horRow1, horRow2, verRow1, verRow2; + if ( !fillRowsUntilCorner( firstQuad, nCorner, nOnEdge, horRow1, horRow2, true ) || + !fillRowsUntilCorner( firstQuad, nCorner, nOnEdge, verRow1, verRow2, false )) + return false; + nbX = horRow1.size(), nbY = verRow1.size(); + + // store found nodes + side._index._xSize = horRow1.size(); + side._index._ySize = verRow1.size(); + side._grid.resize( side._index.size(), NULL ); + + for ( x = 0; x < horRow1.size(); ++x ) + { + side.setNode( x, 0, horRow1[x] ); + side.setNode( x, 1, horRow2[x] ); + } + for ( y = 0; y < verRow1.size(); ++y ) + { + side.setNode( 0, y, verRow1[y] ); + side.setNode( 1, y, verRow2[y] ); + } + } + // Find the rest nodes + + y = 1; // y of the row to fill + TIDSortedElemSet emptySet, avoidSet; + while ( ++y < nbY ) + { + // get next firstQuad in the next row of quadrangles + // + // n2up + // o---o <- y row + // | | + // o---o o o o o <- found nodes + //n1down n2down + // + int i1down, i2down, i2up; + const SMDS_MeshNode* n1down = side.getNode( 0, y-1 ); + const SMDS_MeshNode* n2down = side.getNode( 1, y-1 ); + avoidSet.clear(); avoidSet.insert( firstQuad ); + firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet, + &i1down, &i2down); + if ( !isQuadrangle( firstQuad )) + return BAD_MESH_ERR; + + const SMDS_MeshNode* n2up = oppositeNode( firstQuad, i1down ); + avoidSet.clear(); avoidSet.insert( firstQuad ); + + // find the rest nodes in the y-th row by faces in the row + + x = 1; + while ( ++x < nbX ) + { + const SMDS_MeshElement* quad = SMESH_MeshEditor::FindFaceInSet( n2up, n2down, emptySet, + avoidSet, &i2up, &i2down); + if ( !isQuadrangle( quad )) + return BAD_MESH_ERR; + + n2up = oppositeNode( quad, i2down ); + n2down = oppositeNode( quad, i2up ); + avoidSet.clear(); avoidSet.insert( quad ); + + side.setNode( x, y, n2up ); + } + } + + // check side validity + bool ok = + side.getCornerFace( side.getCornerNode( 0, 0 )) && + side.getCornerFace( side.getCornerNode( 1, 0 )) && + side.getCornerFace( side.getCornerNode( 0, 1 )) && + side.getCornerFace( side.getCornerNode( 1, 1 )); + + return ok; + } + + //================================================================================ + /*! + * \brief Return true if it's possible to make a loop over corner2Sides starting + * from the startSide + */ + //================================================================================ + + bool isClosedChainOfSides( _BlockSide* startSide, + map< const SMDS_MeshNode*, list< _BlockSide* > > & corner2Sides ) + { + // get start and end nodes + const SMDS_MeshNode *n1 = 0, *n2 = 0, *n; + for ( int y = 0; y < 2; ++y ) + for ( int x = 0; x < 2; ++x ) + { + n = startSide->getCornerNode(x,y); + if ( !corner2Sides.count( n )) continue; + if ( n1 ) + n2 = n; + else + n1 = n; + } + if ( !n2 ) return false; + + map< const SMDS_MeshNode*, list< _BlockSide* > >::iterator + c2sides = corner2Sides.find( n1 ); + if ( c2sides == corner2Sides.end() ) return false; + + int nbChainLinks = 1; + n = n1; + _BlockSide* prevSide = startSide; + while ( n != n2 ) + { + // get the next side sharing n + list< _BlockSide* > & sides = c2sides->second; + _BlockSide* nextSide = ( sides.back() == prevSide ? sides.front() : sides.back() ); + if ( nextSide == prevSide ) return false; + + // find the next corner of the nextSide being in corner2Sides + n1 = n; + n = 0; + for ( int y = 0; y < 2 && !n; ++y ) + for ( int x = 0; x < 2; ++x ) + { + n = nextSide->getCornerNode(x,y); + c2sides = corner2Sides.find( n ); + if ( n == n1 || c2sides == corner2Sides.end() ) + n = 0; + else + break; + } + if ( !n ) return false; + + prevSide = nextSide; + nbChainLinks++; + } + + return ( n == n2 && nbChainLinks == NB_QUAD_SIDES ); + } + + //================================================================================ + /*! + * \brief Try to find a block side adjacent to the given side by given edge + */ + //================================================================================ + + _OrientedBlockSide _Skin::findBlockSide( EBoxSides startBlockSide, + EQuadEdge sharedSideEdge1, + EQuadEdge sharedSideEdge2, + bool withGeometricAnalysis, + set< _BlockSide* >& sidesAround) + { + _Block& block = _blocks.back(); + _OrientedBlockSide& side1 = block._side[ startBlockSide ]; + + // get corner nodes of the given block edge + SMESH_OrientedLink edge = side1.edge( sharedSideEdge1 ); + const SMDS_MeshNode* n1 = edge.node1(); + const SMDS_MeshNode* n2 = edge.node2(); + if ( edge._reversed ) swap( n1, n2 ); + + // find all sides sharing both nodes n1 and n2 + set< _BlockSide* > sidesOnEdge = _edge2sides[ edge ]; // copy a set + + // exclude loaded sides of block from sidesOnEdge + for (int i = 0; i < NB_BLOCK_SIDES; ++i ) + if ( block._side[ i ] ) + sidesOnEdge.erase( block._side[ i ]._side ); + + int nbSidesOnEdge = sidesOnEdge.size(); + _DUMP_("nbSidesOnEdge "<< nbSidesOnEdge << " " << n1->GetID() << "-" << n2->GetID() ); + if ( nbSidesOnEdge == 0 ) + return 0; + + _BlockSide* foundSide = 0; + if ( nbSidesOnEdge == 1 ) + { + foundSide = *sidesOnEdge.begin(); + } + else + { + set< _BlockSide* >::iterator sideIt = sidesOnEdge.begin(); + int nbLoadedSides = block.nbSides(); + if ( nbLoadedSides > 1 ) + { + // Find the side having more than 2 corners common with already loaded sides + for (; !foundSide && sideIt != sidesOnEdge.end(); ++sideIt ) + { + _BlockSide* sideI = *sideIt; + int nbCommonCorners = + block._corners.count( sideI->getCornerNode(0,0)) + + block._corners.count( sideI->getCornerNode(1,0)) + + block._corners.count( sideI->getCornerNode(0,1)) + + block._corners.count( sideI->getCornerNode(1,1)); + if ( nbCommonCorners > 2 ) + foundSide = sideI; + } + } + + if ( !foundSide ) + { + if ( !withGeometricAnalysis ) + { + sidesAround.insert( sidesOnEdge.begin(), sidesOnEdge.end() ); + return 0; + } + if ( nbLoadedSides == 1 ) + { + // Issue 0021529. There are at least 2 sides by each edge and + // position of block gravity center is undefined. + // Find a side starting from which we can walk around the startBlockSide + + // fill in corner2Sides + map< const SMDS_MeshNode*, list< _BlockSide* > > corner2Sides; + for ( sideIt = sidesAround.begin(); sideIt != sidesAround.end(); ++sideIt ) + { + _BlockSide* sideI = *sideIt; + corner2Sides[ sideI->getCornerNode(0,0) ].push_back( sideI ); + corner2Sides[ sideI->getCornerNode(1,0) ].push_back( sideI ); + corner2Sides[ sideI->getCornerNode(0,1) ].push_back( sideI ); + corner2Sides[ sideI->getCornerNode(1,1) ].push_back( sideI ); + } + // remove corners of startBlockSide from corner2Sides + set::iterator nIt = block._corners.begin(); + for ( ; nIt != block._corners.end(); ++nIt ) + corner2Sides.erase( *nIt ); + + // select a side + for ( sideIt = sidesOnEdge.begin(); sideIt != sidesOnEdge.end(); ++sideIt ) + { + if ( isClosedChainOfSides( *sideIt, corner2Sides )) + { + foundSide = *sideIt; + break; + } + } + if ( !foundSide ) + return 0; + } + else + { + // Select one of found sides most close to startBlockSide + + gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()), p2 (n2->X(),n2->Y(),n2->Z()); + gp_Vec p1p2( p1, p2 ); + + const SMDS_MeshElement* face1 = side1->getCornerFace( n1 ); + gp_XYZ p1Op = SMESH_TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1))); + gp_Vec side1Dir( p1, p1Op ); + gp_Ax2 pln( p1, p1p2, side1Dir ); // plane with normal p1p2 and X dir side1Dir + _DUMP_(" Select adjacent for "<< side1._side << " - side dir (" + << side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" ); + + map < double , _BlockSide* > angleOfSide; + for (sideIt = sidesOnEdge.begin(); sideIt != sidesOnEdge.end(); ++sideIt ) + { + _BlockSide* sideI = *sideIt; + const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 ); + gp_XYZ p1Op = SMESH_TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1))); + gp_Vec sideIDir( p1, p1Op ); + // compute angle of (sideIDir projection to pln) and (X dir of pln) + gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection()); + double angle = sideIDirProj.Angle( gp::DX2d() ); + if ( angle < 0 ) angle += 2. * M_PI; // angle [0-2*PI] + angleOfSide.insert( make_pair( angle, sideI )); + _DUMP_(" "<< sideI << " - side dir (" + << sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")" + << " angle " << angle); + } + + gp_XYZ gc(0,0,0); // gravity center of already loaded block sides + for (int i = 0; i < NB_BLOCK_SIDES; ++i ) + if ( block._side[ i ] ) + gc += block._side[ i ]._side->getGC(); + gc /= nbLoadedSides; + + gp_Vec gcDir( p1, gc ); + gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection()); + double gcAngle = gcDirProj.Angle( gp::DX2d() ); + foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second; + } + } + _DUMP_(" selected "<< foundSide ); + } + + // Orient the found side correctly + + // corners of found side corresponding to nodes n1 and n2 + bool xMax1, yMax1, xMax2, yMax2; + if ( !getEdgeEnds( sharedSideEdge2, xMax1, yMax1, xMax2, yMax2 )) + return error(SMESH_Comment("Internal error at ")<<__FILE__<<":"<<__LINE__), + _OrientedBlockSide(0); + + for ( int ori = 0; ori < _OrientedIndexer::MAX_ORI+1; ++ori ) + { + _OrientedBlockSide orientedSide( foundSide, ori ); + const SMDS_MeshNode* n12 = orientedSide.cornerNode( xMax1, yMax1); + const SMDS_MeshNode* n22 = orientedSide.cornerNode( xMax2, yMax2); + if ( n1 == n12 && n2 == n22 ) + return orientedSide; + } + error(SMESH_Comment("Failed to orient a block side found by edge ")<& row1, + vector& row2, + const bool alongN1N2 ) + { + const SMDS_MeshNode* corner1 = n1; + + // Store nodes of quad in the rows and find new n1 and n2 to get + // the next face so that new n2 is on block edge + int i1 = quad->GetNodeIndex( n1 ); + int i2 = quad->GetNodeIndex( n2 ); + row1.clear(); row2.clear(); + row1.push_back( n1 ); + if ( alongN1N2 ) + { + row1.push_back( n2 ); + row2.push_back( oppositeNode( quad, i2 )); + row2.push_back( n1 = oppositeNode( quad, i1 )); + } + else + { + row2.push_back( n2 ); + row1.push_back( n2 = oppositeNode( quad, i2 )); + row2.push_back( n1 = oppositeNode( quad, i1 )); + } + + if ( isCornerNode( row1[1] )) + return true; + + // Find the rest nodes + TIDSortedElemSet emptySet, avoidSet; + while ( !isCornerNode( n2 ) ) + { + avoidSet.clear(); avoidSet.insert( quad ); + quad = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2 ); + if ( !isQuadrangle( quad )) + return BAD_MESH_ERR; + + row1.push_back( n2 = oppositeNode( quad, i1 )); + row2.push_back( n1 = oppositeNode( quad, i2 )); + } + return n1 != corner1; + } + + //================================================================================ + /*! + * \brief Return a corner face by a corner node + */ + //================================================================================ + + const SMDS_MeshElement* _BlockSide::getCornerFace(const SMDS_MeshNode* cornerNode) const + { + int x, y, isXMax, isYMax, found = 0; + for ( isXMax = 0; isXMax < 2; ++isXMax ) + { + for ( isYMax = 0; isYMax < 2; ++isYMax ) + { + x = isXMax ? _index._xSize-1 : 0; + y = isYMax ? _index._ySize-1 : 0; + found = ( getNode(x,y) == cornerNode ); + if ( found ) break; + } + if ( found ) break; + } + if ( !found ) return 0; + int dx = isXMax ? -1 : +1; + int dy = isYMax ? -1 : +1; + const SMDS_MeshNode* n1 = getNode(x,y); + const SMDS_MeshNode* n2 = getNode(x+dx,y); + const SMDS_MeshNode* n3 = getNode(x,y+dy); + const SMDS_MeshNode* n4 = getNode(x+dx,y+dy); + return SMDS_Mesh::FindFace(n1, n2, n3, n4 ); + } + + //================================================================================ + /*! + * \brief Checks own validity + */ + //================================================================================ + + bool _Block::isValid() const + { + bool ok = ( nbSides() == 6 ); + + // check only corners depending on side selection + EBoxSides adjacent[4] = { B_BOTTOM, B_RIGHT, B_TOP, B_LEFT }; + EQuadEdge edgeAdj [4] = { Q_TOP, Q_RIGHT, Q_TOP, Q_RIGHT }; + EQuadEdge edgeBack[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT }; + + for ( int i=0; ok && i < NB_QUAD_SIDES; ++i ) + { + SMESH_OrientedLink eBack = _side[ B_BACK ].edge( edgeBack[i] ); + SMESH_OrientedLink eAdja = _side[ adjacent[i] ].edge( edgeAdj[i] ); + ok = ( eBack == eAdja ); + } + return ok; + } + +} // namespace + +//======================================================================= +//function : StdMeshers_HexaFromSkin_3D +//purpose : +//======================================================================= + +StdMeshers_HexaFromSkin_3D::StdMeshers_HexaFromSkin_3D(int hypId, int studyId, SMESH_Gen* gen) + :SMESH_3D_Algo(hypId, studyId, gen) +{ + MESSAGE("StdMeshers_HexaFromSkin_3D::StdMeshers_HexaFromSkin_3D"); + _name = "HexaFromSkin_3D"; +} + +StdMeshers_HexaFromSkin_3D::~StdMeshers_HexaFromSkin_3D() +{ + MESSAGE("StdMeshers_HexaFromSkin_3D::~StdMeshers_HexaFromSkin_3D"); +} + +//================================================================================ +/*! + * \brief Main method, which generates hexaheda + */ +//================================================================================ + +bool StdMeshers_HexaFromSkin_3D::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper) +{ + _Skin skin; + int nbBlocks = skin.findBlocks(aMesh); + if ( nbBlocks == 0 ) + return error( skin.error()); + + vector< vector< const SMDS_MeshNode* > > columns; + int x, xSize, y, ySize, z, zSize; + _Indexer colIndex; + + for ( int i = 0; i < nbBlocks; ++i ) + { + const _Block& block = skin.getBlock( i ); + + // ------------------------------------------ + // Fill columns of nodes with existing nodes + // ------------------------------------------ + + xSize = block.getSide(B_BOTTOM).getHoriSize(); + ySize = block.getSide(B_BOTTOM).getVertSize(); + zSize = block.getSide(B_FRONT ).getVertSize(); + int X = xSize - 1, Y = ySize - 1, Z = zSize - 1; + colIndex = _Indexer( xSize, ySize ); + columns.resize( colIndex.size() ); + + // fill node columns by front and back box sides + for ( x = 0; x < xSize; ++x ) { + vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( x, 0 )]; + vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( x, Y )]; + column0.resize( zSize ); + column1.resize( zSize ); + for ( z = 0; z < zSize; ++z ) { + column0[ z ] = block.getSide(B_FRONT).node( x, z ); + column1[ z ] = block.getSide(B_BACK) .node( x, z ); + } + } + // fill node columns by left and right box sides + for ( y = 1; y < ySize-1; ++y ) { + vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( 0, y )]; + vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( X, y )]; + column0.resize( zSize ); + column1.resize( zSize ); + for ( z = 0; z < zSize; ++z ) { + column0[ z ] = block.getSide(B_LEFT) .node( y, z ); + column1[ z ] = block.getSide(B_RIGHT).node( y, z ); + } + } + // get nodes from top and bottom box sides + for ( x = 1; x < xSize-1; ++x ) { + for ( y = 1; y < ySize-1; ++y ) { + vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )]; + column.resize( zSize ); + column.front() = block.getSide(B_BOTTOM).node( x, y ); + column.back() = block.getSide(B_TOP) .node( x, y ); + } + } + + // ---------------------------- + // Add internal nodes of a box + // ---------------------------- + // projection points of internal nodes on box sub-shapes by which + // coordinates of internal nodes are computed + vector pointOnShape( SMESH_Block::ID_Shell ); + + // projections on vertices are constant + pointOnShape[ SMESH_Block::ID_V000 ] = block.getSide(B_BOTTOM).xyz( 0, 0 ); + pointOnShape[ SMESH_Block::ID_V100 ] = block.getSide(B_BOTTOM).xyz( X, 0 ); + pointOnShape[ SMESH_Block::ID_V010 ] = block.getSide(B_BOTTOM).xyz( 0, Y ); + pointOnShape[ SMESH_Block::ID_V110 ] = block.getSide(B_BOTTOM).xyz( X, Y ); + pointOnShape[ SMESH_Block::ID_V001 ] = block.getSide(B_TOP).xyz( 0, 0 ); + pointOnShape[ SMESH_Block::ID_V101 ] = block.getSide(B_TOP).xyz( X, 0 ); + pointOnShape[ SMESH_Block::ID_V011 ] = block.getSide(B_TOP).xyz( 0, Y ); + pointOnShape[ SMESH_Block::ID_V111 ] = block.getSide(B_TOP).xyz( X, Y ); + + for ( x = 1; x < xSize-1; ++x ) + { + gp_XYZ params; // normalized parameters of internal node within a unit box + params.SetCoord( 1, x / double(X) ); + for ( y = 1; y < ySize-1; ++y ) + { + params.SetCoord( 2, y / double(Y) ); + // column to fill during z loop + vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )]; + // projections on horizontal edges + pointOnShape[ SMESH_Block::ID_Ex00 ] = block.getSide(B_BOTTOM).xyz( x, 0 ); + pointOnShape[ SMESH_Block::ID_Ex10 ] = block.getSide(B_BOTTOM).xyz( x, Y ); + pointOnShape[ SMESH_Block::ID_E0y0 ] = block.getSide(B_BOTTOM).xyz( 0, y ); + pointOnShape[ SMESH_Block::ID_E1y0 ] = block.getSide(B_BOTTOM).xyz( X, y ); + pointOnShape[ SMESH_Block::ID_Ex01 ] = block.getSide(B_TOP).xyz( x, 0 ); + pointOnShape[ SMESH_Block::ID_Ex11 ] = block.getSide(B_TOP).xyz( x, Y ); + pointOnShape[ SMESH_Block::ID_E0y1 ] = block.getSide(B_TOP).xyz( 0, y ); + pointOnShape[ SMESH_Block::ID_E1y1 ] = block.getSide(B_TOP).xyz( X, y ); + // projections on horizontal sides + pointOnShape[ SMESH_Block::ID_Fxy0 ] = block.getSide(B_BOTTOM).xyz( x, y ); + pointOnShape[ SMESH_Block::ID_Fxy1 ] = block.getSide(B_TOP) .xyz( x, y ); + for ( z = 1; z < zSize-1; ++z ) // z loop + { + params.SetCoord( 3, z / double(Z) ); + // projections on vertical edges + pointOnShape[ SMESH_Block::ID_E00z ] = block.getSide(B_FRONT).xyz( 0, z ); + pointOnShape[ SMESH_Block::ID_E10z ] = block.getSide(B_FRONT).xyz( X, z ); + pointOnShape[ SMESH_Block::ID_E01z ] = block.getSide(B_BACK).xyz( 0, z ); + pointOnShape[ SMESH_Block::ID_E11z ] = block.getSide(B_BACK).xyz( X, z ); + // projections on vertical sides + pointOnShape[ SMESH_Block::ID_Fx0z ] = block.getSide(B_FRONT).xyz( x, z ); + pointOnShape[ SMESH_Block::ID_Fx1z ] = block.getSide(B_BACK) .xyz( x, z ); + pointOnShape[ SMESH_Block::ID_F0yz ] = block.getSide(B_LEFT) .xyz( y, z ); + pointOnShape[ SMESH_Block::ID_F1yz ] = block.getSide(B_RIGHT).xyz( y, z ); + + // compute internal node coordinates + gp_XYZ coords; + SMESH_Block::ShellPoint( params, pointOnShape, coords ); + column[ z ] = aHelper->AddNode( coords.X(), coords.Y(), coords.Z() ); + +#ifdef DEB_GRID + // debug + //cout << "----------------------------------------------------------------------"<::max(); + bool isForw = true; + for ( int xMax = 0; xMax < 2; ++xMax ) + for ( int yMax = 0; yMax < 2; ++yMax ) + for ( int zMax = 0; zMax < 2; ++zMax ) + { + x = xMax ? xSize-1 : 1; + y = yMax ? ySize-1 : 1; + z = zMax ? zSize-1 : 1; + vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x-1, y-1 )]; + vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x , y-1 )]; + vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x-1, y )]; + vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x , y )]; + + const SMDS_MeshNode* n000 = col00[z-1]; + const SMDS_MeshNode* n100 = col10[z-1]; + const SMDS_MeshNode* n010 = col01[z-1]; + const SMDS_MeshNode* n110 = col11[z-1]; + const SMDS_MeshNode* n001 = col00[z]; + const SMDS_MeshNode* n101 = col10[z]; + const SMDS_MeshNode* n011 = col01[z]; + const SMDS_MeshNode* n111 = col11[z]; + SMDS_VolumeOfNodes probeVolume (n000,n010,n110,n100, + n001,n011,n111,n101); + SMDS_VolumeTool volTool( &probeVolume ); + double Nx=0.,Ny=0.,Nz=0.; + for ( int iFace = 0; iFace < volTool.NbFaces(); ++iFace ) + { + double nx,ny,nz; + volTool.GetFaceNormal( iFace, nx,ny,nz ); + Nx += nx; + Ny += ny; + Nz += nz; + } + double quality = Nx*Nx + Ny*Ny + Nz*Nz; + if ( quality < badness ) + { + badness = quality; + isForw = volTool.IsForward(); + } + } + + // add elements + for ( x = 0; x < xSize-1; ++x ) { + for ( y = 0; y < ySize-1; ++y ) { + vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x, y )]; + vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x+1, y )]; + vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x, y+1 )]; + vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x+1, y+1 )]; + // bottom face normal of a hexa mush point outside the volume + if ( isForw ) + for ( z = 0; z < zSize-1; ++z ) + aHelper->AddVolume(col00[z], col01[z], col11[z], col10[z], + col00[z+1], col01[z+1], col11[z+1], col10[z+1]); + else + for ( z = 0; z < zSize-1; ++z ) + aHelper->AddVolume(col00[z], col10[z], col11[z], col01[z], + col00[z+1], col10[z+1], col11[z+1], col01[z+1]); + } + } + } // loop on blocks + + return true; +} + +//================================================================================ +/*! + * \brief Evaluate nb of hexa + */ +//================================================================================ + +bool StdMeshers_HexaFromSkin_3D::Evaluate(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap) +{ + _Skin skin; + int nbBlocks = skin.findBlocks(aMesh); + if ( nbBlocks == 0 ) + return error( skin.error()); + + bool secondOrder = aMesh.NbFaces( ORDER_QUADRATIC ); + + int entity = secondOrder ? SMDSEntity_Quad_Hexa : SMDSEntity_Hexa; + vector& nbByType = aResMap[ aMesh.GetSubMesh( aShape )]; + if ( entity >= nbByType.size() ) + nbByType.resize( SMDSEntity_Last, 0 ); + + for ( int i = 0; i < nbBlocks; ++i ) + { + const _Block& block = skin.getBlock( i ); + + int nbX = block.getSide(B_BOTTOM).getHoriSize(); + int nbY = block.getSide(B_BOTTOM).getVertSize(); + int nbZ = block.getSide(B_FRONT ).getVertSize(); + + int nbHexa = (nbX-1) * (nbY-1) * (nbZ-1); + int nbNodes = (nbX-2) * (nbY-2) * (nbZ-2); + if ( secondOrder ) + nbNodes += + (nbX-2) * (nbY-2) * (nbZ-1) + + (nbX-2) * (nbY-1) * (nbZ-2) + + (nbX-1) * (nbY-2) * (nbZ-2); + + + nbByType[ entity ] += nbHexa; + nbByType[ SMDSEntity_Node ] += nbNodes; + } + + return true; +} + +//================================================================================ +/*! + * \brief Abstract method must be defined but does nothing + */ +//================================================================================ + +bool StdMeshers_HexaFromSkin_3D::CheckHypothesis(SMESH_Mesh&, const TopoDS_Shape&, + Hypothesis_Status& aStatus) +{ + aStatus = SMESH_Hypothesis::HYP_OK; + return true; +} + +//================================================================================ +/*! + * \brief Abstract method must be defined but just reports an error as this + * algo is not intended to work with shapes + */ +//================================================================================ + +bool StdMeshers_HexaFromSkin_3D::Compute(SMESH_Mesh&, const TopoDS_Shape&) +{ + return error("Algorithm can't work with geometrical shapes"); +} diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.hxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.hxx new file mode 100644 index 000000000..0912a4d03 --- /dev/null +++ b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_HexaFromSkin_3D.hxx +// Created : Wed Jan 27 12:23:21 2010 +// Author : Edward AGAPOV (eap) +// +#ifndef __StdMeshers_HexaFromSkin_3D_HXX__ +#define __StdMeshers_HexaFromSkin_3D_HXX__ + +#include "SMESH_StdMeshers.hxx" +#include "SMESH_3D_Algo.hxx" + +/*! + * \brief Alorithm generating hexahedral mesh from 2D skin of block + */ + +class STDMESHERS_EXPORT StdMeshers_HexaFromSkin_3D : public SMESH_3D_Algo +{ +public: + StdMeshers_HexaFromSkin_3D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_HexaFromSkin_3D(); + + virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index b36acde9a..92f00af3a 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Hexa_3D.cxx // Moved here from SMESH_Hexa_3D.cxx @@ -26,30 +27,28 @@ // Module : SMESH // #include "StdMeshers_Hexa_3D.hxx" + #include "StdMeshers_CompositeHexa_3D.hxx" #include "StdMeshers_FaceSide.hxx" +#include "StdMeshers_HexaFromSkin_3D.hxx" #include "StdMeshers_Penta_3D.hxx" #include "StdMeshers_Prism_3D.hxx" #include "StdMeshers_Quadrangle_2D.hxx" +#include "StdMeshers_ViscousLayers.hxx" +#include "SMESH_Comment.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" -#include "SMESH_Comment.hxx" -#include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_FacePosition.hxx" -#include "SMDS_VolumeTool.hxx" -#include "SMDS_VolumeOfNodes.hxx" #include #include -#include -#include -#include +#include +#include #include -#include #include "utilities.h" #include "Utils_ExceptHandlers.hxx" @@ -58,11 +57,16 @@ typedef SMESH_Comment TComm; using namespace std; -static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &); +static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, + const TopoDS_Shape &, + SMESH_ProxyMesh* proxyMesh=0); + +static bool EvaluatePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &, + MapShapeNbElems &); //============================================================================= /*! - * + * Constructor */ //============================================================================= @@ -71,12 +75,14 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen) { MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); _name = "Hexa_3D"; - _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type + _requireShape = false; + _compatibleHypothesis.push_back("ViscousLayers"); } //============================================================================= /*! - * + * Destructor */ //============================================================================= @@ -85,27 +91,9 @@ StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D() MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); } -//================================================================================ -/*! - * \brief Clear fields and return the argument - * \param res - the value to return - * \retval bool - the argument value - */ -//================================================================================ - -bool StdMeshers_Hexa_3D::ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res) -{ - for (int i = 0; i < 6; i++) { - delete theQuads[i]; - theQuads[i] = NULL; - } - return res; -} - - //============================================================================= /*! - * + * Retrieves defined hypotheses */ //============================================================================= @@ -124,82 +112,181 @@ bool StdMeshers_Hexa_3D::CheckHypothesis if ( nbFaces != 6 ) return false; */ - aStatus = SMESH_Hypothesis::HYP_OK; - return true; -} -//======================================================================= -//function : isCloser -//purpose : -//======================================================================= + _viscousLayersHyp = NULL; -inline bool isCloser(const int i, const int j, const int nbhoriz, - const FaceQuadStruct* quad, const gp_Pnt2d uv, - double & minDist) -{ - int ij = j * nbhoriz + i; - gp_Pnt2d uv2( quad->uv_grid[ij].u, quad->uv_grid[ij].v ); - double dist = uv.SquareDistance( uv2 ); - if ( dist < minDist ) { - minDist = dist; + const list& hyps = + GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliary=*/false); + list ::const_iterator h = hyps.begin(); + if ( h == hyps.end()) + { + aStatus = SMESH_Hypothesis::HYP_OK; return true; } - return false; -} -//======================================================================= -//function : findIJ -//purpose : return i,j of the node -//======================================================================= + aStatus = HYP_OK; + for ( ; h != hyps.end(); ++h ) + { + string hypName = (*h)->GetName(); + if ( find( _compatibleHypothesis.begin(),_compatibleHypothesis.end(),hypName ) + != _compatibleHypothesis.end() ) + { + _viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h ); + } + else + { + aStatus = HYP_INCOMPATIBLE; + } + } -static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& I, int& J) + if ( !_viscousLayersHyp ) + aStatus = HYP_INCOMPATIBLE; + + return aStatus == HYP_OK; +} + +namespace { - const SMDS_FacePosition* fpos = - static_cast(node->GetPosition().get()); - if ( ! fpos ) return false; - gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() ); - - double minDist = DBL_MAX; - const int nbhoriz = quad->side[0]->NbPoints(); - const int nbvertic = quad->side[1]->NbPoints(); - I = nbhoriz/2; J = nbvertic/2; - int oldI, oldJ; - do { - oldI = I; oldJ = J; - while ( I + 2 < nbhoriz && isCloser( I + 1, J, nbhoriz, quad, uv, minDist )) - I += 1; - if ( I == oldI ) - while ( I - 1 > 0 && isCloser( I - 1, J, nbhoriz, quad, uv, minDist )) - I -= 1; - if ( minDist < DBL_MIN ) - break; + //============================================================================= - while ( J + 2 < nbvertic && isCloser( I, J + 1, nbhoriz, quad, uv, minDist )) - J += 1; - if ( J == oldJ ) - while ( J - 1 > 0 && isCloser( I, J - 1, nbhoriz, quad, uv, minDist )) - J -= 1; - if ( minDist < DBL_MIN ) - break; + typedef boost::shared_ptr< FaceQuadStruct > FaceQuadStructPtr; + + // symbolic names of box sides + enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_NB_SIDES }; + + // symbolic names of sides of quadrangle + enum EQuadSides{ Q_BOTTOM=0, Q_RIGHT, Q_TOP, Q_LEFT, Q_NB_SIDES }; + + //============================================================================= + /*! + * \brief Container of nodes of structured mesh on a qudrangular geom FACE + */ + struct _FaceGrid + { + // face sides + FaceQuadStructPtr _quad; + + // map of (node parameter on EDGE) to (column (vector) of nodes) + TParam2ColumnMap _u2nodesMap; + + // node column's taken form _u2nodesMap taking into account sub-shape orientation + vector _columns; + + // geometry of a cube side + TopoDS_Face _sideF; + + const SMDS_MeshNode* GetNode(int iCol, int iRow) const + { + return _columns[iCol][iRow]; + } + gp_XYZ GetXYZ(int iCol, int iRow) const + { + return SMESH_TNodeXYZ( GetNode( iCol, iRow )); + } + }; - } while ( I != oldI || J != oldJ ); + //================================================================================ + /*! + * \brief Convertor of a pair of integers to a sole index + */ + struct _Indexer + { + int _xSize, _ySize; + _Indexer( int xSize, int ySize ): _xSize(xSize), _ySize(ySize) {} + int size() const { return _xSize * _ySize; } + int operator()(const int x, const int y) const { return y * _xSize + x; } + }; + + //================================================================================ + /*! + * \brief Appends a range of node columns from a map to another map + */ + template< class TMapIterator > + void append( TParam2ColumnMap& toMap, TMapIterator from, TMapIterator to ) + { + const SMDS_MeshNode* lastNode = toMap.rbegin()->second[0]; + const SMDS_MeshNode* firstNode = from->second[0]; + if ( lastNode == firstNode ) + from++; + double u = toMap.rbegin()->first; + for (; from != to; ++from ) + { + u += 1; + TParam2ColumnMap::iterator u2nn = toMap.insert( toMap.end(), make_pair ( u, TNodeColumn())); + u2nn->second.swap( from->second ); + } + } - if ( minDist > DBL_MIN ) { - for (int i = 1; i < nbhoriz - 1; i++) - for (int j = 1; j < nbvertic - 1; j++) - if ( isCloser( i, j, nbhoriz, quad, uv, minDist )) - I = i, J = j; + //================================================================================ + /*! + * \brief Finds FaceQuadStruct having a side equal to a given one and rearranges + * the found FaceQuadStruct::side to have the given side at a Q_BOTTOM place + */ + FaceQuadStructPtr getQuadWithBottom( StdMeshers_FaceSide* side, + FaceQuadStructPtr quad[ 6 ]) + { + FaceQuadStructPtr foundQuad; + for ( int i = 1; i < 6; ++i ) + { + if ( !quad[i] ) continue; + for ( unsigned iS = 0; iS < quad[i]->side.size(); ++iS ) + { + const StdMeshers_FaceSide* side2 = quad[i]->side[iS]; + if (( side->FirstVertex().IsSame( side2->FirstVertex() ) || + side->FirstVertex().IsSame( side2->LastVertex() )) + && + ( side->LastVertex().IsSame( side2->FirstVertex() ) || + side->LastVertex().IsSame( side2->LastVertex() )) + ) + { + if ( iS != Q_BOTTOM ) + { + vector< StdMeshers_FaceSide*> newSides; + for ( unsigned j = iS; j < quad[i]->side.size(); ++j ) + newSides.push_back( quad[i]->side[j] ); + for ( unsigned j = 0; j < iS; ++j ) + newSides.push_back( quad[i]->side[j] ); + quad[i]->side.swap( newSides ); + } + foundQuad.swap(quad[i]); + return foundQuad; + } + } + } + return foundQuad; + } + //================================================================================ + /*! + * \brief Returns true if the 1st base node of sideGrid1 belongs to sideGrid2 + */ + //================================================================================ + + bool beginsAtSide( const _FaceGrid& sideGrid1, + const _FaceGrid& sideGrid2, + SMESH_ProxyMesh::Ptr proxymesh ) + { + const TNodeColumn& col0 = sideGrid2._u2nodesMap.begin()->second; + const TNodeColumn& col1 = sideGrid2._u2nodesMap.rbegin()->second; + const SMDS_MeshNode* n00 = col0.front(); + const SMDS_MeshNode* n01 = col0.back(); + const SMDS_MeshNode* n10 = col1.front(); + const SMDS_MeshNode* n11 = col1.back(); + const SMDS_MeshNode* n = (sideGrid1._u2nodesMap.begin()->second)[0]; + if ( proxymesh ) + { + n00 = proxymesh->GetProxyNode( n00 ); + n10 = proxymesh->GetProxyNode( n10 ); + n01 = proxymesh->GetProxyNode( n01 ); + n11 = proxymesh->GetProxyNode( n11 ); + n = proxymesh->GetProxyNode( n ); + } + return ( n == n00 || n == n01 || n == n10 || n == n11 ); } - return true; } - //============================================================================= /*! - * Hexahedron mesh on hexaedron like form - * -0. - shape and face mesh verification - * -1. - identify faces and vertices of the "cube" - * -2. - Algorithm from: + * Generates hexahedron mesh on hexaedron like form using algorithm from * "Application de l'interpolation transfinie à la création de maillages * C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres * et hexaedres déformés." @@ -215,823 +302,470 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, MESSAGE("StdMeshers_Hexa_3D::Compute"); SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - // 0. - shape and face mesh verification - // 0.1 - shape must be a solid (or a shell) with 6 faces + // Shape verification + // ---------------------- - vector < SMESH_subMesh * >meshFaces; - for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { - SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); - ASSERT(aSubMesh); - meshFaces.push_back(aSubMesh); - } - if (meshFaces.size() != 6) { - //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block"); - static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen()); + // shape must be a solid (or a shell) with 6 faces + TopExp_Explorer exp(aShape,TopAbs_SHELL); + if ( !exp.More() ) + return error(COMPERR_BAD_SHAPE, "No SHELL in the geometry"); + if ( exp.Next(), exp.More() ) + return error(COMPERR_BAD_SHAPE, "More than one SHELL in the geometry"); + + TopTools_IndexedMapOfShape FF; + TopExp::MapShapes( aShape, TopAbs_FACE, FF); + if ( FF.Extent() != 6) + { + static StdMeshers_CompositeHexa_3D compositeHexa(_gen->GetANewId(), 0, _gen); if ( !compositeHexa.Compute( aMesh, aShape )) return error( compositeHexa.GetComputeError() ); return true; } - // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges) - - // tool for working with quadratic elements - SMESH_MesherHelper aTool (aMesh); - _quadraticMesh = aTool.IsQuadraticSubMesh(aShape); - - // cube structure - typedef struct cubeStruct - { - TopoDS_Vertex V000; - TopoDS_Vertex V001; - TopoDS_Vertex V010; - TopoDS_Vertex V011; - TopoDS_Vertex V100; - TopoDS_Vertex V101; - TopoDS_Vertex V110; - TopoDS_Vertex V111; - faceQuadStruct* quad_X0; - faceQuadStruct* quad_X1; - faceQuadStruct* quad_Y0; - faceQuadStruct* quad_Y1; - faceQuadStruct* quad_Z0; - faceQuadStruct* quad_Z1; - Point3DStruct* np; // normalised 3D coordinates - } CubeStruct; - - CubeStruct aCube; - - // bounding faces - FaceQuadStruct* aQuads[6]; - for (int i = 0; i < 6; i++) - aQuads[i] = 0; - - for (int i = 0; i < 6; i++) + // Find sides of a cube + // --------------------- + + FaceQuadStructPtr quad[ 6 ]; + StdMeshers_Quadrangle_2D quadAlgo( _gen->GetANewId(), GetStudyId(), _gen); + for ( int i = 0; i < 6; ++i ) { - TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); - SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); - string algoName = algo->GetName(); - bool isAllQuad = false; - if (algoName == "Quadrangle_2D") { - SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace ); - if ( sm ) { - isAllQuad = true; - SMDS_ElemIteratorPtr eIt = sm->GetElements(); - while ( isAllQuad && eIt->more() ) { - const SMDS_MeshElement* elem = eIt->next(); - isAllQuad = ( elem->NbNodes()==4 ||(_quadraticMesh && elem->NbNodes()==8) ); - } - } - } - if ( ! isAllQuad ) { - SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape); - return ClearAndReturn( aQuads, error(err)); - } - StdMeshers_Quadrangle_2D *quadAlgo = - dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); - ASSERT(quadAlgo); - try { - aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh); - if(!aQuads[i]) { - return error( quadAlgo->GetComputeError()); - } - } - catch(SALOME_Exception & S_ex) { - 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]->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); - // Try to go into penta algorithm 'cause it has been improved. - SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape); - return ClearAndReturn( aQuads, error(err)); - } + if ( !( quad[i] = FaceQuadStructPtr( quadAlgo.CheckNbEdges( aMesh, FF( i+1 ))))) + return error( quadAlgo.GetComputeError() ); + if ( quad[i]->side.size() != 4 ) + return error( COMPERR_BAD_SHAPE, "Not a quadrangular box side" ); } - // 1. - identify faces and vertices of the "cube" - // 1.1 - ancestor maps vertex->edges in the cube - - 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 - - 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 - - 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 - - int _indY0 = 0; - aCube.quad_Y0 = aQuads[_indY0]; - - int _indY1 = GetFaceIndex(aMesh, aShape, meshFaces, - aCube.V010, aCube.V011, aCube.V110, aCube.V111); - aCube.quad_Y1 = aQuads[_indY1]; - - int _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces, - aCube.V000, aCube.V010, aCube.V100, aCube.V110); - aCube.quad_Z0 = aQuads[_indZ0]; - - int _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces, - aCube.V001, aCube.V011, aCube.V101, aCube.V111); - aCube.quad_Z1 = aQuads[_indZ1]; - - int _indX0 = GetFaceIndex(aMesh, aShape, meshFaces, - aCube.V000, aCube.V001, aCube.V010, aCube.V011); - aCube.quad_X0 = aQuads[_indX0]; + _FaceGrid aCubeSide[ 6 ]; - int _indX1 = GetFaceIndex(aMesh, aShape, meshFaces, - aCube.V100, aCube.V101, aCube.V110, aCube.V111); - aCube.quad_X1 = aQuads[_indX1]; + swap( aCubeSide[B_BOTTOM]._quad, quad[0] ); + swap( aCubeSide[B_BOTTOM]._quad->side[ Q_RIGHT],// direct the normal of bottom quad inside cube + aCubeSide[B_BOTTOM]._quad->side[ Q_LEFT ] ); - // 1.7 - get convertion coefs from face 2D normalized to 3D normalized + aCubeSide[B_FRONT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_BOTTOM], quad ); + aCubeSide[B_RIGHT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_RIGHT ], quad ); + aCubeSide[B_BACK ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_TOP ], quad ); + aCubeSide[B_LEFT ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_LEFT ], quad ); + if ( aCubeSide[B_FRONT ]._quad ) + aCubeSide[B_TOP]._quad = getQuadWithBottom( aCubeSide[B_FRONT ]._quad->side[Q_TOP ], quad ); - Conv2DStruct cx0; // for face X=0 - Conv2DStruct cx1; // for face X=1 - Conv2DStruct cy0; - Conv2DStruct cy1; - Conv2DStruct cz0; - Conv2DStruct cz1; + for ( int i = 1; i < 6; ++i ) + if ( !aCubeSide[i]._quad ) + return error( COMPERR_BAD_SHAPE ); - GetConv2DCoefs(*aCube.quad_X0, meshFaces[_indX0]->GetSubShape(), - aCube.V000, aCube.V010, aCube.V011, aCube.V001, cx0); - GetConv2DCoefs(*aCube.quad_X1, meshFaces[_indX1]->GetSubShape(), - aCube.V100, aCube.V110, aCube.V111, aCube.V101, cx1); - GetConv2DCoefs(*aCube.quad_Y0, meshFaces[_indY0]->GetSubShape(), - aCube.V000, aCube.V100, aCube.V101, aCube.V001, cy0); - GetConv2DCoefs(*aCube.quad_Y1, meshFaces[_indY1]->GetSubShape(), - aCube.V010, aCube.V110, aCube.V111, aCube.V011, cy1); - GetConv2DCoefs(*aCube.quad_Z0, meshFaces[_indZ0]->GetSubShape(), - aCube.V000, aCube.V100, aCube.V110, aCube.V010, cz0); - GetConv2DCoefs(*aCube.quad_Z1, meshFaces[_indZ1]->GetSubShape(), - aCube.V001, aCube.V101, aCube.V111, aCube.V011, cz1); + // Make viscous layers + // -------------------- - // 1.8 - create a 3D structure for normalized values - - int nbx = aCube.quad_Z0->side[0]->NbPoints(); - if (cz0.a1 == 0.) nbx = aCube.quad_Z0->side[1]->NbPoints(); - - int nby = aCube.quad_X0->side[0]->NbPoints(); - if (cx0.a1 == 0.) nby = aCube.quad_X0->side[1]->NbPoints(); - - 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]; + SMESH_ProxyMesh::Ptr proxymesh; + if ( _viscousLayersHyp ) + { + proxymesh = _viscousLayersHyp->Compute( aMesh, aShape, /*makeN2NMap=*/ true ); + if ( !proxymesh ) + return false; + } - // 1.9 - store node indexes of faces + // Check if there are triangles on cube sides + // ------------------------------------------- + if ( aMesh.NbTriangles() > 0 ) { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape()); - - faceQuadStruct *quad = aCube.quad_X0; - int i = 0; // j = x/face , k = y/face - int nbdown = quad->side[0]->NbPoints(); - int nbright = quad->side[1]->NbPoints(); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - - while(itf->more()) { - const SMDS_MeshNode * node = itf->next(); - if(aTool.IsMedium(node)) - continue; - if ( !findIJ( node, quad, i1, j1 )) - return ClearAndReturn( aQuads, false ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } - - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) { - int ij1 = j1 * nbdown + i1; - int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face - int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); + for ( int i = 0; i < 6; ++i ) + { + const TopoDS_Face& sideF = aCubeSide[i]._quad->face; + if ( SMESHDS_SubMesh* smDS = meshDS->MeshElements( sideF )) + { + bool isAllQuad = true; + SMDS_ElemIteratorPtr fIt = smDS->GetElements(); + while ( fIt->more() && isAllQuad ) + { + const SMDS_MeshElement* f = fIt->next(); + isAllQuad = ( f->NbCornerNodes() == 4 ); + } + if ( !isAllQuad ) + { + SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape, proxymesh.get()); + return error( err ); + } } + } } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape()); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - - faceQuadStruct *quad = aCube.quad_X1; - int i = nbx - 1; // j = x/face , k = y/face - 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; - if ( !findIJ( node, quad, i1, j1 )) - return ClearAndReturn( aQuads, false ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + // Check presence of regular grid mesh on FACEs of the cube + // ------------------------------------------------------------ - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) { - int ij1 = j1 * nbdown + i1; - int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face - int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } - } + // tool creating quadratic elements if needed + SMESH_MesherHelper helper (aMesh); + _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + for ( int i = 0; i < 6; ++i ) { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape()); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - - faceQuadStruct *quad = aCube.quad_Y0; - int j = 0; // i = x/face , k = y/face - 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; - if ( !findIJ( node, quad, i1, j1 )) - return ClearAndReturn( aQuads, false ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; + const TopoDS_Face& F = aCubeSide[i]._quad->face; + StdMeshers_FaceSide* baseQuadSide = aCubeSide[i]._quad->side[ Q_BOTTOM ]; + list baseEdges( baseQuadSide->Edges().begin(), baseQuadSide->Edges().end() ); + + // assure correctness of node positions on baseE: + // helper.GetNodeU() will fix positions if they are wrong + helper.ToFixNodeParameters( true ); + for ( int iE = 0; iE < baseQuadSide->NbEdges(); ++iE ) + { + const TopoDS_Edge& baseE = baseQuadSide->Edge( iE ); + if ( SMESHDS_SubMesh* smDS = meshDS->MeshElements( baseE )) + { + bool ok; + helper.SetSubShape( baseE ); + SMDS_ElemIteratorPtr eIt = smDS->GetElements(); + while ( eIt->more() ) + { + const SMDS_MeshElement* e = eIt->next(); + // expect problems on a composite side + try { helper.GetNodeU( baseE, e->GetNode(0), e->GetNode(1), &ok); } + catch (...) {} + try { helper.GetNodeU( baseE, e->GetNode(1), e->GetNode(0), &ok); } + catch (...) {} + } + } } - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) { - int ij1 = j1 * nbdown + i1; - int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face - int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } + // load grid + bool ok = + helper.LoadNodeColumns( aCubeSide[i]._u2nodesMap, F, baseEdges, meshDS, proxymesh.get()); + if ( ok ) + { + // check if the loaded grid corresponds to nb of quadrangles on the FACE + const SMESHDS_SubMesh* faceSubMesh = + proxymesh ? proxymesh->GetSubMesh( F ) : meshDS->MeshElements( F ); + const int nbQuads = faceSubMesh->NbElements(); + const int nbHor = aCubeSide[i]._u2nodesMap.size() - 1; + const int nbVer = aCubeSide[i]._u2nodesMap.begin()->second.size() - 1; + ok = ( nbQuads == nbHor * nbVer ); + } + if ( !ok ) + { + SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape, proxymesh.get()); + return error( err ); + } } + // Orient loaded grids of cube sides along axis of the unitary cube coord system + bool isReverse[6]; + isReverse[B_BOTTOM] = beginsAtSide( aCubeSide[B_BOTTOM], aCubeSide[B_RIGHT ], proxymesh ); + isReverse[B_TOP ] = beginsAtSide( aCubeSide[B_TOP ], aCubeSide[B_RIGHT ], proxymesh ); + isReverse[B_FRONT ] = beginsAtSide( aCubeSide[B_FRONT ], aCubeSide[B_RIGHT ], proxymesh ); + isReverse[B_BACK ] = beginsAtSide( aCubeSide[B_BACK ], aCubeSide[B_RIGHT ], proxymesh ); + isReverse[B_LEFT ] = beginsAtSide( aCubeSide[B_LEFT ], aCubeSide[B_BACK ], proxymesh ); + isReverse[B_RIGHT ] = beginsAtSide( aCubeSide[B_RIGHT ], aCubeSide[B_BACK ], proxymesh ); + for ( int i = 0; i < 6; ++i ) { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape()); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - - faceQuadStruct *quad = aCube.quad_Y1; - int j = nby - 1; // i = x/face , k = y/face - 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; - if ( !findIJ( node, quad, i1, j1 )) - return ClearAndReturn( aQuads, false ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; - } + aCubeSide[i]._columns.resize( aCubeSide[i]._u2nodesMap.size() ); - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) { - int ij1 = j1 * nbdown + i1; - int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face - int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } + int iFwd = 0, iRev = aCubeSide[i]._columns.size()-1; + int* pi = isReverse[i] ? &iRev : &iFwd; + TParam2ColumnMap::iterator u2nn = aCubeSide[i]._u2nodesMap.begin(); + for ( ; iFwd < aCubeSide[i]._columns.size(); --iRev, ++iFwd, ++u2nn ) + aCubeSide[i]._columns[ *pi ].swap( u2nn->second ); + + aCubeSide[i]._u2nodesMap.clear(); } + + if ( proxymesh ) + for ( int i = 0; i < 6; ++i ) + for ( unsigned j = 0; j < aCubeSide[i]._columns.size(); ++j) + for ( unsigned k = 0; k < aCubeSide[i]._columns[j].size(); ++k) + { + const SMDS_MeshNode* & n = aCubeSide[i]._columns[j][k]; + n = proxymesh->GetProxyNode( n ); + } - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape()); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - - faceQuadStruct *quad = aCube.quad_Z0; - int k = 0; // i = x/face , j = y/face - 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; - if ( !findIJ( node, quad, i1, j1 )) - return ClearAndReturn( aQuads, false ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; + // 4) Create internal nodes of the cube + // ------------------------------------- + + helper.SetSubShape( aShape ); + helper.SetElementsOnShape(true); + + // shortcuts to sides + _FaceGrid* fBottom = & aCubeSide[ B_BOTTOM ]; + _FaceGrid* fRight = & aCubeSide[ B_RIGHT ]; + _FaceGrid* fTop = & aCubeSide[ B_TOP ]; + _FaceGrid* fLeft = & aCubeSide[ B_LEFT ]; + _FaceGrid* fFront = & aCubeSide[ B_FRONT ]; + _FaceGrid* fBack = & aCubeSide[ B_BACK ]; + + // cube size measured in nb of nodes + int x, xSize = fBottom->_columns.size() , X = xSize - 1; + int y, ySize = fLeft->_columns.size() , Y = ySize - 1; + int z, zSize = fLeft->_columns[0].size(), Z = zSize - 1; + + // columns of internal nodes "rising" from nodes of fBottom + _Indexer colIndex( xSize, ySize ); + vector< vector< const SMDS_MeshNode* > > columns( colIndex.size() ); + + // fill node columns by front and back box sides + for ( x = 0; x < xSize; ++x ) { + vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( x, 0 )]; + vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( x, Y )]; + column0.resize( zSize ); + column1.resize( zSize ); + for ( z = 0; z < zSize; ++z ) { + column0[ z ] = fFront->GetNode( x, z ); + column1[ z ] = fBack ->GetNode( x, z ); } - - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) { - int ij1 = j1 * nbdown + i1; - int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face - int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } } - - { - const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape()); - - SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes(); - - faceQuadStruct *quad = aCube.quad_Z1; - int k = nbz - 1; // i = x/face , j = y/face - 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; - if ( !findIJ( node, quad, i1, j1 )) - return ClearAndReturn( aQuads, false ); - int ij1 = j1 * nbdown + i1; - quad->uv_grid[ij1].node = node; + // fill node columns by left and right box sides + for ( y = 1; y < ySize-1; ++y ) { + vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( 0, y )]; + vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( X, y )]; + column0.resize( zSize ); + column1.resize( zSize ); + for ( z = 0; z < zSize; ++z ) { + column0[ z ] = fLeft ->GetNode( y, z ); + column1[ z ] = fRight->GetNode( y, z ); } - - for (int i1 = 0; i1 < nbdown; i1++) - for (int j1 = 0; j1 < nbright; j1++) { - int ij1 = j1 * nbdown + i1; - int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face - int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face - int ijk = k * nbx * nby + j * nbx + i; - //MESSAGE(" "<uv_grid[ij1].node; - //SCRUTE(np[ijk].nodeId); - } } - - // 2.0 - for each node of the cube: - // - get the 8 points 3D = 8 vertices of the cube - // - get the 12 points 3D on the 12 edges of the cube - // - get the 6 points 3D on the 6 faces with their ID - // - compute the point 3D - // - store the point 3D in SMESHDS, store its ID in 3D structure - - int shapeID = meshDS->ShapeToIndex( aShape ); - - Pt3 p000, p001, p010, p011, p100, p101, p110, p111; - Pt3 px00, px01, px10, px11; - Pt3 p0y0, p0y1, p1y0, p1y1; - Pt3 p00z, p01z, p10z, p11z; - Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz; - - GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - - for (int i = 1; i < nbx - 1; i++) { - for (int j = 1; j < nby - 1; j++) { - for (int k = 1; k < nbz - 1; k++) { - // *** seulement maillage regulier - // 12 points on edges - GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS); - GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS); - GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS); - - GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS); - - GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS); - GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS); - - // 12 points on faces - GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS); - GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS); - GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS); - GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS); - GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS); - GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS); - - int ijk = k * nbx * nby + j * nbx + i; - double x = double (i) / double (nbx - 1); // *** seulement - double y = double (j) / double (nby - 1); // *** maillage - double z = double (k) / double (nbz - 1); // *** regulier - - Pt3 X; - for (int i = 0; i < 3; i++) { - X[i] = (1 - x) * p0yz[i] + x * p1yz[i] - + (1 - y) * px0z[i] + y * px1z[i] - + (1 - z) * pxy0[i] + z * pxy1[i] - - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i]) - - x * ((1 - y) * p10z[i] + y * p11z[i]) - - (1 - y) * ((1 - z) * px00[i] + z * px01[i]) - - y * ((1 - z) * px10[i] + z * px11[i]) - - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i]) - - z * ((1 - x) * p0y1[i] + x * p1y1[i]) - + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i]) - + y * ((1 - z) * p010[i] + z * p011[i])) - + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i]) - + y * ((1 - z) * p110[i] + z * p111[i])); - } - - SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]); - np[ijk].node = node; - meshDS->SetNodeInVolume(node, shapeID); - } + // get nodes from top and bottom box sides + for ( x = 1; x < xSize-1; ++x ) { + for ( y = 1; y < ySize-1; ++y ) { + vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )]; + column.resize( zSize ); + column.front() = fBottom->GetNode( x, y ); + column.back() = fTop ->GetNode( x, y ); } } - // find orientation of furute volumes according to MED convention - vector< bool > forward( nbx * nby ); - SMDS_VolumeTool vTool; - for (int i = 0; i < nbx - 1; i++) { - for (int j = 0; j < nby - 1; j++) { - int n1 = j * nbx + i; - int n2 = j * nbx + i + 1; - int n3 = (j + 1) * nbx + i + 1; - int n4 = (j + 1) * nbx + i; - int n5 = nbx * nby + j * nbx + i; - int n6 = nbx * nby + j * nbx + i + 1; - int n7 = nbx * nby + (j + 1) * nbx + i + 1; - int n8 = nbx * nby + (j + 1) * nbx + i; - - SMDS_VolumeOfNodes tmpVol (np[n1].node,np[n2].node,np[n3].node,np[n4].node, - np[n5].node,np[n6].node,np[n7].node,np[n8].node); - vTool.Set( &tmpVol ); - forward[ n1 ] = vTool.IsForward(); + // projection points of the internal node on cube sub-shapes by which + // coordinates of the internal node are computed + vector pointsOnShapes( SMESH_Block::ID_Shell ); + + // projections on vertices are constant + pointsOnShapes[ SMESH_Block::ID_V000 ] = fBottom->GetXYZ( 0, 0 ); + pointsOnShapes[ SMESH_Block::ID_V100 ] = fBottom->GetXYZ( X, 0 ); + pointsOnShapes[ SMESH_Block::ID_V010 ] = fBottom->GetXYZ( 0, Y ); + pointsOnShapes[ SMESH_Block::ID_V110 ] = fBottom->GetXYZ( X, Y ); + pointsOnShapes[ SMESH_Block::ID_V001 ] = fTop->GetXYZ( 0, 0 ); + pointsOnShapes[ SMESH_Block::ID_V101 ] = fTop->GetXYZ( X, 0 ); + pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y ); + pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y ); + + for ( x = 1; x < xSize-1; ++x ) + { + gp_XYZ params; // normalized parameters of internal node within a unit box + params.SetCoord( 1, x / double(X) ); + for ( y = 1; y < ySize-1; ++y ) + { + params.SetCoord( 2, y / double(Y) ); + // a column to fill in during z loop + vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )]; + // projection points on horizontal edges + pointsOnShapes[ SMESH_Block::ID_Ex00 ] = fBottom->GetXYZ( x, 0 ); + pointsOnShapes[ SMESH_Block::ID_Ex10 ] = fBottom->GetXYZ( x, Y ); + pointsOnShapes[ SMESH_Block::ID_E0y0 ] = fBottom->GetXYZ( 0, y ); + pointsOnShapes[ SMESH_Block::ID_E1y0 ] = fBottom->GetXYZ( X, y ); + pointsOnShapes[ SMESH_Block::ID_Ex01 ] = fTop->GetXYZ( x, 0 ); + pointsOnShapes[ SMESH_Block::ID_Ex11 ] = fTop->GetXYZ( x, Y ); + pointsOnShapes[ SMESH_Block::ID_E0y1 ] = fTop->GetXYZ( 0, y ); + pointsOnShapes[ SMESH_Block::ID_E1y1 ] = fTop->GetXYZ( X, y ); + // projection points on horizontal faces + pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = fBottom->GetXYZ( x, y ); + pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop ->GetXYZ( x, y ); + for ( z = 1; z < zSize-1; ++z ) // z loop + { + params.SetCoord( 3, z / double(Z) ); + // projection points on vertical edges + pointsOnShapes[ SMESH_Block::ID_E00z ] = fFront->GetXYZ( 0, z ); + pointsOnShapes[ SMESH_Block::ID_E10z ] = fFront->GetXYZ( X, z ); + pointsOnShapes[ SMESH_Block::ID_E01z ] = fBack->GetXYZ( 0, z ); + pointsOnShapes[ SMESH_Block::ID_E11z ] = fBack->GetXYZ( X, z ); + // projection points on vertical faces + pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z ); + pointsOnShapes[ SMESH_Block::ID_Fx1z ] = fBack ->GetXYZ( x, z ); + pointsOnShapes[ SMESH_Block::ID_F0yz ] = fLeft ->GetXYZ( y, z ); + pointsOnShapes[ SMESH_Block::ID_F1yz ] = fRight->GetXYZ( y, z ); + + // compute internal node coordinates + gp_XYZ coords; + SMESH_Block::ShellPoint( params, pointsOnShapes, coords ); + column[ z ] = helper.AddNode( coords.X(), coords.Y(), coords.Z() ); + + } } } - //2.1 - for each node of the cube (less 3 *1 Faces): - // - store hexahedron in SMESHDS - MESSAGE("Storing hexahedron into the DS"); - for (int i = 0; i < nbx - 1; i++) { - for (int j = 0; j < nby - 1; j++) { - bool isForw = forward.at( j * nbx + i ); - for (int k = 0; k < nbz - 1; k++) { - int n1 = k * nbx * nby + j * nbx + i; - int n2 = k * nbx * nby + j * nbx + i + 1; - int n3 = k * nbx * nby + (j + 1) * nbx + i + 1; - int n4 = k * nbx * nby + (j + 1) * nbx + i; - int n5 = (k + 1) * nbx * nby + j * nbx + i; - int n6 = (k + 1) * nbx * nby + j * nbx + i + 1; - int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1; - int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i; - - SMDS_MeshVolume * elt; - if ( isForw ) { - 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 = aTool.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); - } - - meshDS->SetMeshElementOnShape(elt, shapeID); + // side data no more needed, free memory + for ( int i = 0; i < 6; ++i ) + aCubeSide[i]._columns.clear(); + + // 5) Create hexahedrons + // --------------------- + + for ( x = 0; x < xSize-1; ++x ) { + for ( y = 0; y < ySize-1; ++y ) { + vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x, y )]; + vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x+1, y )]; + vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x, y+1 )]; + vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x+1, y+1 )]; + for ( z = 0; z < zSize-1; ++z ) + { + // bottom face normal of a hexa mush point outside the volume + helper.AddVolume(col00[z], col01[z], col11[z], col10[z], + col00[z+1], col01[z+1], col11[z+1], col10[z+1]); } } } - if ( np ) delete [] np; - 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) -{ - int ijk = k * nbx * nby + j * nbx + i; - const SMDS_MeshNode * node = np[ijk].node; - p[0] = node->X(); - p[1] = node->Y(); - p[2] = node->Z(); - //MESSAGE(" "<&meshFaces, - const TopoDS_Vertex & V0, - const TopoDS_Vertex & V1, - const TopoDS_Vertex & V2, const TopoDS_Vertex & V3) -{ - //MESSAGE("StdMeshers_Hexa_3D::GetFaceIndex"); - int faceIndex = -1; - for (int i = 1; i < 6; i++) - { - const TopoDS_Shape & aFace = meshFaces[i]->GetSubShape(); - //const TopoDS_Face& F = TopoDS::Face(aFace); - TopTools_IndexedMapOfShape M; - TopExp::MapShapes(aFace, TopAbs_VERTEX, M); - bool verticesInShape = false; - if (M.Contains(V0)) - if (M.Contains(V1)) - if (M.Contains(V2)) - if (M.Contains(V3)) - verticesInShape = true; - if (verticesInShape) - { - faceIndex = i; - break; - } - } - ASSERT(faceIndex > 0); - //SCRUTE(faceIndex); - return faceIndex; -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -TopoDS_Edge - StdMeshers_Hexa_3D::EdgeNotInFace(SMESH_Mesh & aMesh, - const TopoDS_Shape & aShape, - const TopoDS_Face & aFace, - const TopoDS_Vertex & aVertex, - const TopTools_IndexedDataMapOfShapeListOfShape & MS) -{ - //MESSAGE("StdMeshers_Hexa_3D::EdgeNotInFace"); - TopTools_IndexedDataMapOfShapeListOfShape MF; - TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, MF); - const TopTools_ListOfShape & ancestorsInSolid = MS.FindFromKey(aVertex); - const TopTools_ListOfShape & ancestorsInFace = MF.FindFromKey(aVertex); -// SCRUTE(ancestorsInSolid.Extent()); -// SCRUTE(ancestorsInFace.Extent()); - ASSERT(ancestorsInSolid.Extent() == 6); // 6 (edges doublees) - ASSERT(ancestorsInFace.Extent() == 2); - - TopoDS_Edge E; - E.Nullify(); - TopTools_ListIteratorOfListOfShape its(ancestorsInSolid); - for (; its.More(); its.Next()) - { - TopoDS_Shape ancestor = its.Value(); - TopTools_ListIteratorOfListOfShape itf(ancestorsInFace); - bool isInFace = false; - for (; itf.More(); itf.Next()) - { - TopoDS_Shape ancestorInFace = itf.Value(); - if (ancestorInFace.IsSame(ancestor)) - { - isInFace = true; - break; - } - } - if (!isInFace) - { - E = TopoDS::Edge(ancestor); - break; - } - } - return E; + return true; } //============================================================================= /*! - * + * Evaluate */ //============================================================================= -void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad, - const TopoDS_Shape & aShape, - const TopoDS_Vertex & V0, - const TopoDS_Vertex & V1, - const TopoDS_Vertex & V2, const TopoDS_Vertex & V3, Conv2DStruct & conv) +bool StdMeshers_Hexa_3D::Evaluate(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap) { -// 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; -// } - VA = quad.side[0]->FirstVertex(); - VB = quad.side[0]->LastVertex(); + vector < SMESH_subMesh * >meshFaces; + TopTools_SequenceOfShape aFaces; + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { + aFaces.Append(exp.Current()); + SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current()); + ASSERT(aSubMesh); + meshFaces.push_back(aSubMesh); + } + if (meshFaces.size() != 6) { + //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block"); + static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen()); + return compositeHexa.Evaluate(aMesh, aShape, aResMap); + } + + int i = 0; + for(; i<6; i++) { + //TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); + TopoDS_Shape aFace = aFaces.Value(i+1); + SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); + if( !algo ) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + string algoName = algo->GetName(); + bool isAllQuad = false; + if (algoName == "Quadrangle_2D") { + MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + if( nbtri == 0 ) + isAllQuad = true; + } + if ( ! isAllQuad ) { + return EvaluatePentahedralMesh(aMesh, aShape, aResMap); + } + } - int a1, b1, c1, a2, b2, c2; - if (VA.IsSame(V0)) - if (VB.IsSame(V1)) - { - a1 = 1; - b1 = 0; - c1 = 0; // x - a2 = 0; - b2 = 1; - c2 = 0; // y - } - else - { - ASSERT(VB.IsSame(V3)); - a1 = 0; - b1 = 1; - c1 = 0; // y - a2 = 1; - b2 = 0; - c2 = 0; // x - } - if (VA.IsSame(V1)) - if (VB.IsSame(V2)) - { - a1 = 0; - b1 = -1; - c1 = 1; // 1-y - a2 = 1; - b2 = 0; - c2 = 0; // x - } - else - { - ASSERT(VB.IsSame(V0)); - a1 = -1; - b1 = 0; - c1 = 1; // 1-x - a2 = 0; - b2 = 1; - c2 = 0; // y - } - if (VA.IsSame(V2)) - if (VB.IsSame(V3)) - { - a1 = -1; - b1 = 0; - c1 = 1; // 1-x - a2 = 0; - b2 = -1; - c2 = 1; // 1-y - } - else - { - ASSERT(VB.IsSame(V1)); - a1 = 0; - b1 = -1; - c1 = 1; // 1-y - a2 = -1; - b2 = 0; - c2 = 1; // 1-x - } - if (VA.IsSame(V3)) - if (VB.IsSame(V0)) - { - a1 = 0; - b1 = 1; - c1 = 0; // y - a2 = -1; - b2 = 0; - c2 = 1; // 1-x - } - else - { - ASSERT(VB.IsSame(V2)); - a1 = 1; - b1 = 0; - c1 = 0; // x - a2 = 0; - b2 = -1; - c2 = 1; // 1-y - } -// MESSAGE("X = " << c1 << "+ " << a1 << "*x + " << b1 << "*y"); -// MESSAGE("Y = " << c2 << "+ " << a2 << "*x + " << b2 << "*y"); - conv.a1 = a1; - conv.b1 = b1; - conv.c1 = c1; - conv.a2 = a2; - conv.b2 = b2; - conv.c2 = c2; - - int nbdown = quad.side[0]->NbPoints(); - int nbright = quad.side[1]->NbPoints(); - conv.ia = int (a1); - conv.ib = int (b1); - conv.ic = - int (c1 * a1 * a1) * (nbdown - 1) + int (c1 * b1 * b1) * (nbright - 1); - conv.ja = int (a2); - conv.jb = int (b2); - conv.jc = - int (c2 * a2 * a2) * (nbdown - 1) + int (c2 * b2 * b2) * (nbright - 1); -// MESSAGE("I " << conv.ia << " " << conv.ib << " " << conv.ic); -// MESSAGE("J " << conv.ja << " " << conv.jb << " " << conv.jc); + // find number of 1d elems for 1 face + int nb1d = 0; + TopTools_MapOfShape Edges1; + bool IsQuadratic = false; + bool IsFirst = true; + for (TopExp_Explorer exp(aFaces.Value(1), TopAbs_EDGE); exp.More(); exp.Next()) { + Edges1.Add(exp.Current()); + SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current()); + if( sm ) { + MapShapeNbElemsItr anIt = aResMap.find(sm); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + if(IsFirst) { + IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); + IsFirst = false; + } + } + } + // find face opposite to 1 face + int OppNum = 0; + for(i=2; i<=6; i++) { + bool IsOpposite = true; + for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) { + if( Edges1.Contains(exp.Current()) ) { + IsOpposite = false; + break; + } + } + if(IsOpposite) { + OppNum = i; + break; + } + } + // find number of 2d elems on side faces + int nb2d = 0; + for(i=2; i<=6; i++) { + if( i == OppNum ) continue; + MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] ); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + } + + MapShapeNbElemsItr anIt = aResMap.find( meshFaces[0] ); + std::vector aVec = (*anIt).second; + int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + int nb0d_face0 = aVec[SMDSEntity_Node]; + + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iside[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 ]; - } + static StdMeshers_HexaFromSkin_3D * algo = 0; + if ( !algo ) { + SMESH_Gen* gen = aMesh.GetGen(); + algo = new StdMeshers_HexaFromSkin_3D( gen->GetANewId(), 0, gen ); } - return TopoDS_Vertex(); + algo->InitComputeError(); + algo->Compute( aMesh, aHelper ); + return error( algo->GetComputeError()); } -//modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f -/////////////////////////////////////////////////////////////////////////////// -//ZZ -//#include - //======================================================================= //function : ComputePentahedralMesh //purpose : //======================================================================= -SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh & aMesh, - const TopoDS_Shape & aShape) +SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + SMESH_ProxyMesh* proxyMesh) { - //printf(" ComputePentahedralMesh HERE\n"); - // - bool bOK; SMESH_ComputeErrorPtr err = SMESH_ComputeError::New(); - //int iErr; + if ( proxyMesh ) + { + err->myName = COMPERR_BAD_INPUT_MESH; + err->myComment = "Can't build pentahedral mesh on viscous layers"; + return err; + } + bool bOK; StdMeshers_Penta_3D anAlgo; // bOK=anAlgo.Compute(aMesh, aShape); @@ -1047,6 +781,7 @@ SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh & aMesh, } SMESH_Hypothesis::Hypothesis_Status aStatus; if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) { + aPrism3D->InitComputeError(); bOK = aPrism3D->Compute( aMesh, aShape ); err = aPrism3D->GetComputeError(); } @@ -1055,3 +790,31 @@ SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh & aMesh, } +//======================================================================= +//function : EvaluatePentahedralMesh +//purpose : +//======================================================================= + +bool EvaluatePentahedralMesh(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap) +{ + StdMeshers_Penta_3D anAlgo; + bool bOK = anAlgo.Evaluate(aMesh, aShape, aResMap); + + //err = anAlgo.GetComputeError(); + //if ( !bOK && anAlgo.ErrorStatus() == 5 ) + if( !bOK ) { + 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 ) ) { + return aPrism3D->Evaluate(aMesh, aShape, aResMap); + } + } + + return bOK; +} diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.hxx b/src/StdMeshers/StdMeshers_Hexa_3D.hxx index 24927ef5a..48f1eebbe 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.hxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Hexa_3D.hxx // Moved here from SMESH_Hexa_3D.hxx @@ -31,39 +32,12 @@ #include "SMESH_StdMeshers.hxx" #include "SMESH_3D_Algo.hxx" -#include "SMESH_Mesh.hxx" -#include "StdMeshers_Quadrangle_2D.hxx" -#include "Utils_SALOME_Exception.hxx" - -#include "SMESH_MesherHelper.hxx" - -class TopTools_IndexedMapOfShape; - -typedef struct point3Dstruct -{ - const SMDS_MeshNode * node; -} Point3DStruct; -typedef double Pt3[3]; -typedef struct conv2dstruct -{ - double a1; // X = a1*x + b1*y + c1 - double b1; // Y = a2*x + b2*y + c2 - double c1; // a1, b1 a2, b2 in {-1,0,1} - double a2; // c1, c2 in {0,1} - double b2; - double c2; - int ia; // I = ia*i + ib*j + ic - int ib; - int ic; - int ja; // J = ja*i + jb*j + jc - int jb; - int jc; -} Conv2DStruct; +class StdMeshers_ViscousLayers; +class SMESH_MesherHelper; -class STDMESHERS_EXPORT StdMeshers_Hexa_3D: - public SMESH_3D_Algo +class STDMESHERS_EXPORT StdMeshers_Hexa_3D : public SMESH_3D_Algo { public: StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen* gen); @@ -73,45 +47,16 @@ public: const TopoDS_Shape& aShape, SMESH_Hypothesis::Hypothesis_Status& aStatus); - virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) - /*throw (SALOME_Exception)*/; - - static TopoDS_Vertex OppositeVertex(const TopoDS_Vertex& aVertex, - const TopTools_IndexedMapOfShape& aQuads0Vertices, - FaceQuadStruct* aQuads[6]); + virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); -protected: - TopoDS_Edge - EdgeNotInFace(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - const TopoDS_Face& aFace, - const TopoDS_Vertex& aVertex, - const TopTools_IndexedDataMapOfShapeListOfShape& MS); + virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper); - int GetFaceIndex(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - const std::vector& meshFaces, - const TopoDS_Vertex& V0, - const TopoDS_Vertex& V1, - const TopoDS_Vertex& V2, - const TopoDS_Vertex& V3); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); - void GetConv2DCoefs(const faceQuadStruct& quad, - const TopoDS_Shape& aShape, - const TopoDS_Vertex& V0, - const TopoDS_Vertex& V1, - const TopoDS_Vertex& V2, - const TopoDS_Vertex& V3, - Conv2DStruct& conv); - - void GetPoint(Pt3 p, - int i, int j, int k, - int nbx, int nby, int nbz, - Point3DStruct *np, - const SMESHDS_Mesh* meshDS); +protected: - bool ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res); + const StdMeshers_ViscousLayers* _viscousLayersHyp; }; #endif diff --git a/src/StdMeshers/StdMeshers_ImportSource.cxx b/src/StdMeshers/StdMeshers_ImportSource.cxx new file mode 100644 index 000000000..e93b83a61 --- /dev/null +++ b/src/StdMeshers/StdMeshers_ImportSource.cxx @@ -0,0 +1,490 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH StdMeshers_ImportSource1D : implementaion of SMESH idl descriptions +// File : StdMeshers_ImportSource1D.cxx +// Module : SMESH +// +#include "StdMeshers_ImportSource.hxx" + +#include "SMESHDS_GroupOnGeom.hxx" +#include "SMESHDS_Mesh.hxx" +#include "SMESH_Algo.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_subMeshEventListener.hxx" + +#include "utilities.h" + +#include + +#include + +using namespace std; + +//============================================================================= +/*! + * Creates StdMeshers_ImportSource1D + */ +//============================================================================= + +StdMeshers_ImportSource1D::StdMeshers_ImportSource1D(int hypId, + int studyId, + SMESH_Gen * gen) + :SMESH_Hypothesis(hypId, studyId, gen), + _toCopyMesh(false), + _toCopyGroups(false) +{ + _name = "ImportSource1D"; + _param_algo_dim = 1; // is used by StdMeshers_Import_1D; +} + +//============================================================================= +/*! + * Creates StdMeshers_ImportSource2D + */ +//============================================================================= + +StdMeshers_ImportSource2D::StdMeshers_ImportSource2D(int hypId, + int studyId, + SMESH_Gen * gen) + :StdMeshers_ImportSource1D(hypId, studyId, gen) +{ + _name = "ImportSource2D"; + _param_algo_dim = 2; // is used by StdMeshers_Import_2D; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_ImportSource1D::~StdMeshers_ImportSource1D() +{ +} +//============================================================================= +/*! + * Sets groups to import elements from + */ +//============================================================================= + +void StdMeshers_ImportSource1D::SetGroups(const std::vector& groups) +{ + if (_groups != groups) + { + _groups = groups; + NotifySubMeshesHypothesisModification(); + } +} + +void StdMeshers_ImportSource1D::SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups) +{ + if ( !toCopyMesh ) toCopyGroups = false; + if ( _toCopyMesh != toCopyMesh || _toCopyGroups != toCopyGroups ) + { + _toCopyMesh = toCopyMesh; _toCopyGroups = toCopyGroups; + NotifySubMeshesHypothesisModification(); + } +} +void StdMeshers_ImportSource1D::GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const +{ + toCopyMesh = _toCopyMesh; toCopyGroups = _toCopyGroups; +} + +namespace +{ + //================================================================================ + /*! + * \brief Return only alive groups + */ + //================================================================================ + + vector getValidGroups(const vector& groups, + StudyContextStruct* studyContext) + { + vector okGroups; + for ( int i = 0; i < groups.size(); ++i ) + { + try + { + // we expect SIGSEGV on a dead group + OCC_CATCH_SIGNALS; + SMESH_Group* okGroup = 0; + map::iterator itm = itm = studyContext->mapMesh.begin(); + for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++) + { + SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups(); + while ( gIt->more() && !okGroup ) + if ( gIt->next() == groups[i] ) + okGroup = groups[i]; + } + if ( okGroup ) + okGroups.push_back( okGroup ); + } + catch(...) + { + } + } + return okGroups; + } + //================================================================================ + /*! + * \brief Pack meshes into a pair of ints + */ + //================================================================================ + + pair getResMapKey(const SMESHDS_Mesh& srcMesh, const SMESHDS_Mesh& tgtMesh) + { + return make_pair( srcMesh.GetPersistentId() , tgtMesh.GetPersistentId() ); + } + //================================================================================ + /*! + * \brief Return a target mesh by a pair of ints + */ + //================================================================================ + + SMESH_Mesh* getTgtMeshByKey( const pair & resMapKey, + StudyContextStruct* studyContext) + { + int tgtID = resMapKey.second; + SMESH_Mesh* tgtMesh = 0; + map::iterator itm = itm = studyContext->mapMesh.begin(); + for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++) + { + tgtMesh = (*itm).second; + if ( tgtMesh->GetMeshDS()->GetPersistentId() != tgtID ) + tgtMesh = 0; + } + return tgtMesh; + } + //================================================================================ + /*! + * \brief Return a target mesh by a pair of ints + */ + //================================================================================ + + int getSrcMeshID( const pair & resMapKey ) + { + return resMapKey.first; + } +} + +//============================================================================= +/*! + * Returns groups to import elements from + */ +//============================================================================= + +const std::vector& StdMeshers_ImportSource1D::GetGroups() const +{ + // filter off deleted groups + vector okGroups = getValidGroups( _groups, + _gen->GetStudyContext(_studyId) ); + if ( okGroups.size() != _groups.size() ) + ((StdMeshers_ImportSource1D*)this)->_groups = okGroups; + + return _groups; +} + +//================================================================================ +/*! + * \brief Return source meshes + */ +//================================================================================ + +std::vector StdMeshers_ImportSource1D::GetSourceMeshes() const +{ + // GetPersistentId()'s of meshes + set meshIDs; + const vector& groups = GetGroups(); + if ( !groups.empty() ) + { + for ( unsigned i = 0; i < groups.size(); ++i ) + { + const SMESHDS_GroupBase* gDS = groups[i]->GetGroupDS(); + int id = gDS->GetMesh()->GetPersistentId(); + meshIDs.insert( id ); + } + } + else + { + if ( _resultGroups.empty() ) + ((StdMeshers_ImportSource1D*)this)->RestoreGroups(_groups); + TResGroupMap::const_iterator key_groups = _resultGroups.begin(); + for ( ; key_groups != _resultGroups.end(); ++key_groups ) + meshIDs.insert( getSrcMeshID( key_groups->first )); + } + + // Find corresponding meshes + vector meshes; + if ( !meshIDs.empty() ) + { + StudyContextStruct* studyContext = _gen->GetStudyContext(_studyId); + for ( set::iterator id = meshIDs.begin(); id != meshIDs.end(); ++id ) + { + map::iterator itm = itm = studyContext->mapMesh.begin(); + for ( ; itm != studyContext->mapMesh.end(); itm++) + { + SMESH_Mesh* mesh = (*itm).second; + if ( mesh->GetMeshDS()->GetPersistentId() == *id ) + { + meshes.push_back( mesh ); + break; + } + } + } + } + return meshes; +} + +//================================================================================ +/*! + * \brief Return submeshes whose events affect the target mesh + */ +//================================================================================ + +std::vector +StdMeshers_ImportSource1D::GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const +{ + if ( !srcMesh->HasShapeToMesh() ) + { + SMESH_Mesh* srcM = const_cast< SMESH_Mesh* >( srcMesh ); + return vector(1, srcM->GetSubMesh( srcM->GetShapeToMesh())); + } + set shapeIDs; + const vector& groups = GetGroups(); + const SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS(); + for ( size_t i = 0; i < groups.size(); ++i ) + { + SMESHDS_GroupBase * grDS = groups[i]->GetGroupDS(); + if ( grDS->GetMesh() != srcMeshDS ) + continue; + if ( SMESHDS_GroupOnGeom* gog = dynamic_cast( grDS )) + { + shapeIDs.insert( srcMeshDS->ShapeToIndex( gog->GetShape() )); + } + else + { + SMDS_ElemIteratorPtr elIt = grDS->GetElements(); + while ( elIt->more() ) + shapeIDs.insert( elIt->next()->getshapeId() ); + } + } + if ( !shapeIDs.empty() && *shapeIDs.begin() < 1 ) + { + shapeIDs.erase( shapeIDs.begin() ); + shapeIDs.insert( 1 ); + } + + vector smVec( shapeIDs.size()); + set::iterator sID = shapeIDs.begin(); + for ( int i = 0; sID != shapeIDs.end(); ++sID, ++i ) + smVec[i] = srcMesh->GetSubMeshContaining( *sID ); + + return smVec; +} + +//============================================================================= +/*! + * Save _toCopyMesh and _toCopyGroups to a stream + */ +//============================================================================= + +ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save) +{ + resultGroupsToIntVec(); + + save << " " << _toCopyMesh << " " << _toCopyGroups; + save << " " << _resultGroupsStorage.size(); + for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i ) + save << " " << _resultGroupsStorage[i]; + + return save; +} + +//============================================================================= +/*! + * Load _toCopyMesh and _toCopyGroups from a stream + */ +//============================================================================= + +istream & StdMeshers_ImportSource1D::LoadFrom(istream & load) +{ + load >> _toCopyMesh >> _toCopyGroups; + + _resultGroupsStorage.clear(); + int val; + if ( load >> val ) + { + _resultGroupsStorage.reserve(val); + while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val ) + _resultGroupsStorage.push_back( val ); + } + return load; +} + +//================================================================================ +/*! + * \brief Convert result groups into _resultGroupsStorage + */ +//================================================================================ + +void StdMeshers_ImportSource1D::resultGroupsToIntVec() +{ + _resultGroupsStorage.clear(); + + // store result groups + TResGroupMap::iterator key2groups = _resultGroups.begin(); + for ( ; key2groups != _resultGroups.end(); ++key2groups ) + { + const pair& key = key2groups->first; + const vector& groups = key2groups->second; + // mesh ids, nb groups + _resultGroupsStorage.push_back( key.first ); + _resultGroupsStorage.push_back( key.second ); + _resultGroupsStorage.push_back( groups.size() ); + for ( unsigned i = 0; i < groups.size(); ++i ) + { + // store group names as sequence of ints each standing for a char + // of a name; that is to avoid pb with names containing white spaces + string name = groups[i]->GetGroupDS()->GetStoreName(); + _resultGroupsStorage.push_back( name.size() ); + for ( unsigned j = 0; j < name.size(); ++j ) + _resultGroupsStorage.push_back( name[j] ); + } + } +} + +//================================================================================ +/*! + * \brief Restore source groups and result groups by _resultGroupsStorage + */ +//================================================================================ + +void StdMeshers_ImportSource1D::RestoreGroups(const std::vector& groups) +{ + _groups = groups; + + _resultGroups.clear(); + int i = 0; + while ( i < _resultGroupsStorage.size() ) + { + int key1 = _resultGroupsStorage[i++]; + int key2 = _resultGroupsStorage[i++]; + pair resMapKey( key1, key2 ); + SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId)); + // restore mesh ids at least + _resultGroups.insert( make_pair (resMapKey,vector() )); + + int nbGroups = _resultGroupsStorage[i++]; + for ( int j = 0; j < nbGroups; ++j ) + { + string::size_type nameSize = _resultGroupsStorage[i++]; + string groupName(nameSize, '\0'); + for ( unsigned k = 0; k < nameSize; ++k ) + groupName[k] = (char) _resultGroupsStorage[i++]; + + // find a group by name + if ( mesh ) + { + SMESH_Group* group = 0; + SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups(); + while ( !group && gIt->more() ) + { + group = gIt->next(); + if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() ) + group = 0; + } + if ( group ) + _resultGroups[ resMapKey ].push_back( group ); + } + } + } +} + +//================================================================================ +/*! + * \brief Remember groups imported from other mesh + * \param groups - result groups + * \param srcMesh - source mesh + * \param tgtMesh - destination mesh + */ +//================================================================================ + +void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector& groups, + const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh) +{ + _resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups; +} + +//================================================================================ +/*! + * \brief Return groups imported from other mesh + * \param srcMesh - source mesh + * \param tgtMesh - destination mesh + * \retval const std::vector& - groups + */ +//================================================================================ + +std::vector* +StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh) +{ + TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh )); + if ( key2groups == _resultGroups.end() ) + return 0; + vector vec = getValidGroups((*key2groups).second, + _gen->GetStudyContext(_studyId) ); + if ( vec.size() != key2groups->second.size()) + key2groups->second = vec; + + return & key2groups->second; +} + +//================================================================================ +/*! + * \brief Initialize ImportSource value by the mesh built on the geometry + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&) +{ + return false; +} + +//================================================================================ +/*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* ) +{ + return false; +} diff --git a/src/StdMeshers/StdMeshers_ImportSource.hxx b/src/StdMeshers/StdMeshers_ImportSource.hxx new file mode 100644 index 000000000..d3347de15 --- /dev/null +++ b/src/StdMeshers/StdMeshers_ImportSource.hxx @@ -0,0 +1,99 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH StdMeshers : implementaion of SMESH idl descriptions +// File : StdMeshers_ImportSource1D.hxx +// Module : SMESH +// +#ifndef _StdMeshers_ImportSource_HXX_ +#define _StdMeshers_ImportSource_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +#include +#include + +class SMESH_Group; +class SMESHDS_Mesh; +class SMESH_subMesh; + +//============================================================================== +/*! + * \brief Stores groups to import elements from + */ +//============================================================================== + +class STDMESHERS_EXPORT StdMeshers_ImportSource1D : public SMESH_Hypothesis +{ + public: + StdMeshers_ImportSource1D(int hypId, int studyId, SMESH_Gen * gen); + virtual ~ StdMeshers_ImportSource1D(); + + void SetGroups(const std::vector& groups); + const std::vector& GetGroups() const; + + void SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups); + void GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const; + + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + void RestoreGroups(const std::vector& groups); + + void StoreResultGroups(const std::vector& groups, + const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh); + std::vector* GetResultGroups(const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh); + + std::vector GetSourceMeshes() const; + std::vector GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const; + +private: + + std::vector _groups; + bool _toCopyMesh, _toCopyGroups; + + // groups imported using this hypothesis + typedef std::map< std::pair, std::vector > TResGroupMap; + TResGroupMap _resultGroups; + std::vector _resultGroupsStorage; // persistent representation of _resultGroups + + void resultGroupsToIntVec(); +}; + +//============================================================================== +/*! + * \brief Redefines name and dimension of inherited StdMeshers_ImportSource1D + */ +//============================================================================== + +class STDMESHERS_EXPORT StdMeshers_ImportSource2D : public StdMeshers_ImportSource1D +{ + public: + StdMeshers_ImportSource2D(int hypId, int studyId, SMESH_Gen * gen); +}; +#endif diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx new file mode 100644 index 000000000..b8a5076b8 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D.cxx @@ -0,0 +1,1055 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_Import_1D.cxx +// Module : SMESH +// +#include "StdMeshers_Import_1D.hxx" +#include "StdMeshers_ImportSource.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESHDS_Mesh.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_subMeshEventListener.hxx" + +#include "Utils_SALOME_Exception.hxx" +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +//============================================================================= +/*! + * Creates StdMeshers_Import_1D + */ +//============================================================================= + +StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen * gen) + :SMESH_1D_Algo(hypId, studyId, gen), _sourceHyp(0) +{ + MESSAGE("StdMeshers_Import_1D::StdMeshers_Import_1D"); + _name = "Import_1D"; + _shapeType = (1 << TopAbs_EDGE); + + _compatibleHypothesis.push_back("ImportSource1D"); +} + +//============================================================================= +/*! + * Check presence of a hypothesis + */ +//============================================================================= + +bool StdMeshers_Import_1D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + _sourceHyp = 0; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + if ( hyps.size() == 0 ) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + if ( hyps.size() > 1 ) + { + aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST; + return false; + } + + const SMESHDS_Hypothesis *theHyp = hyps.front(); + + string hypName = theHyp->GetName(); + + if (hypName == _compatibleHypothesis.front()) + { + _sourceHyp = (StdMeshers_ImportSource1D *)theHyp; + aStatus = SMESH_Hypothesis::HYP_OK; + return true; + } + + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + return true; +} + +//================================================================================ +namespace // INTERNAL STUFF +//================================================================================ +{ + int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, SMESH_Mesh* tgtMesh); + + enum _ListenerDataType + { + WAIT_HYP_MODIF=1, // data indicating awaiting for valid parameters of src hyp + LISTEN_SRC_MESH, // data storing submesh depending on source mesh state + SRC_HYP // data storing ImportSource hyp + }; + //================================================================================ + /*! + * \brief _ListenerData holding ImportSource hyp holding in its turn + * imported groups + */ + struct _ListenerData : public SMESH_subMeshEventListenerData + { + const StdMeshers_ImportSource1D* _srcHyp; + _ListenerData(const StdMeshers_ImportSource1D* h, _ListenerDataType type=SRC_HYP): + SMESH_subMeshEventListenerData(/*isDeletable=*/true), _srcHyp(h) + { + myType = type; + } + }; + //================================================================================ + /*! + * \brief Comparator of sub-meshes + */ + struct _SubLess + { + bool operator()(const SMESH_subMesh* sm1, const SMESH_subMesh* sm2 ) const + { + if ( sm1 == sm2 ) return false; + if ( !sm1 || !sm2 ) return sm1 < sm2; + const TopoDS_Shape& s1 = sm1->GetSubShape(); + const TopoDS_Shape& s2 = sm2->GetSubShape(); + TopAbs_ShapeEnum t1 = s1.IsNull() ? TopAbs_SHAPE : s1.ShapeType(); + TopAbs_ShapeEnum t2 = s2.IsNull() ? TopAbs_SHAPE : s2.ShapeType(); + if ( t1 == t2) + return (sm1 < sm2); + return t1 < t2; // to have: face < edge + } + }; + //================================================================================ + /*! + * \brief Container of data dedicated to one source mesh + */ + struct _ImportData + { + const SMESH_Mesh* _srcMesh; + StdMeshers_Import_1D::TNodeNodeMap _n2n; + StdMeshers_Import_1D::TElemElemMap _e2e; + + set< SMESH_subMesh*, _SubLess > _subM; // submeshes relating to this srcMesh + set< SMESH_subMesh*, _SubLess > _copyMeshSubM; // submeshes requesting mesh copying + set< SMESH_subMesh*, _SubLess > _copyGroupSubM; // submeshes requesting group copying + set< SMESH_subMesh*, _SubLess > _computedSubM; + + SMESHDS_SubMesh* _importMeshSubDS; // submesh storing a copy of _srcMesh + int _importMeshSubID; // id of _importMeshSubDS + + _ImportData(const SMESH_Mesh* srcMesh=0): + _srcMesh(srcMesh), _importMeshSubDS(0),_importMeshSubID(-1) {} + + void removeImportedMesh( SMESHDS_Mesh* meshDS ) + { + if ( !_importMeshSubDS ) return; + SMDS_ElemIteratorPtr eIt = _importMeshSubDS->GetElements(); + while ( eIt->more() ) + meshDS->RemoveFreeElement( eIt->next(), _importMeshSubDS, /*fromGroups=*/false ); + SMDS_NodeIteratorPtr nIt = _importMeshSubDS->GetNodes(); + while ( nIt->more() ) + meshDS->RemoveFreeNode( nIt->next(), _importMeshSubDS, /*fromGroups=*/false ); + _n2n.clear(); + _e2e.clear(); + } + void removeGroups( SMESH_subMesh* subM, const StdMeshers_ImportSource1D* srcHyp ) + { + if ( !srcHyp ) return; + SMESH_Mesh* tgtMesh = subM->GetFather(); + const SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); + const SMESHDS_Mesh* srcMeshDS = _srcMesh->GetMeshDS(); + vector* groups = + const_cast(srcHyp)->GetResultGroups(*srcMeshDS,*tgtMeshDS); + if ( groups ) + { + for ( unsigned i = 0; i < groups->size(); ++i ) + tgtMesh->RemoveGroup( groups->at(i)->GetGroupDS()->GetID() ); + groups->clear(); + } + } + void trackHypParams( SMESH_subMesh* sm, const StdMeshers_ImportSource1D* srcHyp ) + { + if ( !srcHyp ) return; + bool toCopyMesh, toCopyGroups; + srcHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups); + + if ( toCopyMesh )_copyMeshSubM.insert( sm ); + else _copyMeshSubM.erase( sm ); + + if ( toCopyGroups ) _copyGroupSubM.insert( sm ); + else _copyGroupSubM.erase( sm ); + } + void addComputed( SMESH_subMesh* sm ) + { + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true, + /*complexShapeFirst=*/true); + while ( smIt->more() ) + { + sm = smIt->next(); + switch ( sm->GetSubShape().ShapeType() ) + { + case TopAbs_EDGE: + case TopAbs_FACE: + _subM.insert( sm ); + if ( !sm->IsEmpty() ) + _computedSubM.insert( sm ); + case TopAbs_VERTEX: + break; + default:; + } + } + } + }; + //================================================================================ + /*! + * Listener notified on events relating to imported submesh + */ + class _Listener : public SMESH_subMeshEventListener + { + typedef map< SMESH_Mesh*, list< _ImportData > > TMesh2ImpData; + TMesh2ImpData _tgtMesh2ImportData; + + _Listener():SMESH_subMeshEventListener(/*isDeletable=*/false, + "StdMeshers_Import_1D::_Listener") {} + + public: + // return poiter to a static listener + static _Listener* get() { static _Listener theListener; return &theListener; } + + static _ImportData* getImportData(const SMESH_Mesh* srcMesh, SMESH_Mesh* tgtMesh); + + static void storeImportSubmesh(SMESH_subMesh* importSub, + const SMESH_Mesh* srcMesh, + const StdMeshers_ImportSource1D* srcHyp); + + virtual void ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* subMesh, + SMESH_subMeshEventListenerData* data, + const SMESH_Hypothesis* hyp); + void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data ); + void clearSubmesh ( SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub ); + + // mark sm as missing src hyp with valid groups + static void waitHypModification(SMESH_subMesh* sm) + { + sm->SetEventListener + (get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm); + } + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Find or create ImportData for given meshes + */ + _ImportData* _Listener::getImportData(const SMESH_Mesh* srcMesh, + SMESH_Mesh* tgtMesh) + { + list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh]; + list< _ImportData >::iterator d = dList.begin(); + for ( ; d != dList.end(); ++d ) + if ( d->_srcMesh == srcMesh ) + return &*d; + dList.push_back(_ImportData(srcMesh)); + return &dList.back(); + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Remember an imported sub-mesh and set needed even listeners + * \param importSub - submesh computed by Import algo + * \param srcMesh - source mesh + * \param srcHyp - ImportSource hypothesis + */ + void _Listener::storeImportSubmesh(SMESH_subMesh* importSub, + const SMESH_Mesh* srcMesh, + const StdMeshers_ImportSource1D* srcHyp) + { + // set listener to hear events of the submesh computed by "Import" algo + importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub ); + + // set listeners to hear events of the source mesh + SMESH_subMesh* smToNotify = importSub; + vector smToListen = srcHyp->GetSourceSubMeshes( srcMesh ); + for ( size_t i = 0; i < smToListen.size(); ++i ) + { + SMESH_subMeshEventListenerData* data = new _ListenerData(srcHyp, LISTEN_SRC_MESH); + data->mySubMeshes.push_back( smToNotify ); + importSub->SetEventListener( get(), data, smToListen[i] ); + } + // remember the submesh importSub and its sub-submeshes + _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather()); + iData->trackHypParams( importSub, srcHyp ); + iData->addComputed( importSub ); + if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 ) + { + SMESH_Mesh* tgtMesh = importSub->GetFather(); + iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh); + iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID ); + } + } + //-------------------------------------------------------------------------------- + /*! + * \brief Remove imported mesh and/or groups if needed + * \param sm - submesh loosing Import algo + * \param data - data holding imported groups + */ + void _Listener::removeSubmesh( SMESH_subMesh* sm, _ListenerData* data ) + { + list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ]; + list< _ImportData >::iterator d = dList.begin(); + for ( ; d != dList.end(); ++d ) + if ( (*d)._subM.erase( sm )) + { + d->_computedSubM.erase( sm ); + bool rmMesh = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty(); + bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh; + if ( rmMesh ) + d->removeImportedMesh( sm->GetFather()->GetMeshDS() ); + if ( rmGroups && data ) + d->removeGroups( sm, data->_srcHyp ); + } + } + //-------------------------------------------------------------------------------- + /*! + * \brief Clear submeshes and remove imported mesh and/or groups if necessary + * \param sm - cleared submesh + * \param data - data holding imported groups + */ + void _Listener::clearSubmesh(SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub) + { + list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ]; + list< _ImportData >::iterator d = dList.begin(); + for ( ; d != dList.end(); ++d ) + { + if ( !d->_subM.count( sm )) continue; + if ( (*d)._computedSubM.erase( sm ) ) + { + bool copyMesh = !d->_copyMeshSubM.empty(); + if ( copyMesh || clearAllSub ) + { + // remove imported mesh and groups + d->removeImportedMesh( sm->GetFather()->GetMeshDS() ); + + if ( data ) + d->removeGroups( sm, data->_srcHyp ); + + // clear the rest submeshes + if ( !d->_computedSubM.empty() ) + { + d->_computedSubM.clear(); + set< SMESH_subMesh*, _SubLess>::iterator sub = d->_subM.begin(); + for ( ; sub != d->_subM.end(); ++sub ) + { + SMESH_subMesh* subM = *sub; + _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() ); + if ( hypData ) + d->removeGroups( sm, hypData->_srcHyp ); + + subM->ComputeStateEngine( SMESH_subMesh::CLEAN ); + if ( subM->GetSubShape().ShapeType() == TopAbs_FACE ) + subM->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN ); + } + } + } + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + if ( sm->GetSubShape().ShapeType() == TopAbs_FACE ) + sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN ); + } + if ( data ) + d->trackHypParams( sm, data->_srcHyp ); + d->_n2n.clear(); + d->_e2e.clear(); + } + } + //-------------------------------------------------------------------------------- + /*! + * \brief Remove imported mesh and/or groups + */ + void _Listener::ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* subMesh, + SMESH_subMeshEventListenerData* data, + const SMESH_Hypothesis* /*hyp*/) + { + if ( data && data->myType == WAIT_HYP_MODIF ) + { + // event of Import submesh + if ( SMESH_subMesh::MODIF_HYP == event && + SMESH_subMesh::ALGO_EVENT == eventType ) + { + // re-call SetEventListener() to take into account valid parameters + // of ImportSource hypothesis + if ( SMESH_Algo* algo = subMesh->GetAlgo() ) + algo->SetEventListener( subMesh ); + } + } + else if ( data && data->myType == LISTEN_SRC_MESH ) + { + // event of source mesh + if ( SMESH_subMesh::COMPUTE_EVENT == eventType ) + { + switch ( event ) { + case SMESH_subMesh::CLEAN: + // source mesh cleaned -> clean target mesh + clearSubmesh( data->mySubMeshes.front(), (_ListenerData*) data, /*all=*/true ); + break; + case SMESH_subMesh::SUBMESH_COMPUTED: { + // source mesh computed -> reset FAILED state of Import submeshes to + // READY_TO_COMPUTE + SMESH_Mesh* srcMesh = subMesh->GetFather(); + if ( srcMesh->NbEdges() > 0 || srcMesh->NbFaces() > 0 ) + { + SMESH_Mesh* m = data->mySubMeshes.front()->GetFather(); + if ( SMESH_subMesh* sm1 = m->GetSubMeshContaining(1)) + { + sm1->ComputeStateEngine(SMESH_subMesh::SUBMESH_COMPUTED ); + sm1->ComputeSubMeshStateEngine( SMESH_subMesh::SUBMESH_COMPUTED ); + } + } + break; + } + default:; + } + } + } + else // event of Import submesh + { + // find out what happens: import hyp modified or removed + bool removeImport = false, modifHyp = false; + if ( SMESH_subMesh::ALGO_EVENT == eventType ) + modifHyp = true; + if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK ) + { + removeImport = true; + } + else if (( SMESH_subMesh::REMOVE_ALGO == event || + SMESH_subMesh::REMOVE_FATHER_ALGO == event ) && + SMESH_subMesh::ALGO_EVENT == eventType ) + { + SMESH_Algo* algo = subMesh->GetAlgo(); + removeImport = ( strncmp( "Import", algo->GetName(), 6 ) != 0 ); + } + + if ( removeImport ) + { + // treate removal of Import algo from subMesh + removeSubmesh( subMesh, (_ListenerData*) data ); + } + else if ( modifHyp || + ( SMESH_subMesh::CLEAN == event && + SMESH_subMesh::COMPUTE_EVENT == eventType)) + { + // treate modification of ImportSource hypothesis + clearSubmesh( subMesh, (_ListenerData*) data, /*all=*/false ); + } + else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event && + SMESH_subMesh::COMPUTE_EVENT == eventType ) + { + // check compute state of all submeshes impoting from same src mesh; + // this is to take into account 1D computed submeshes hidden by 2D import algo; + // else source mesh is not copied as _subM.size != _computedSubM.size() + list< _ImportData > & dList = _tgtMesh2ImportData[ subMesh->GetFather() ]; + list< _ImportData >::iterator d = dList.begin(); + for ( ; d != dList.end(); ++d ) + if ( d->_subM.count( subMesh )) + { + set::iterator smIt = d->_subM.begin(); + for( ; smIt != d->_subM.end(); ++smIt ) + if ( (*smIt)->IsMeshComputed() ) + d->_computedSubM.insert( *smIt); + } + } + } + } + + //================================================================================ + /*! + * \brief Return an ID of submesh to store nodes and elements of a copied mesh + */ + //================================================================================ + + int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, + SMESH_Mesh* tgtMesh) + { + // To get SMESH_subMesh corresponding to srcMeshDS we need to have a shape + // for which SMESHDS_Mesh::IsGroupOfSubShapes() returns true. + // And this shape must be different from sub-shapes of the main shape. + // So we create a compound containing + // 1) some sub-shapes of SMESH_Mesh::PseudoShape() corresponding to + // srcMeshDS->GetPersistentId() + // 2) the 1-st vertex of the main shape to assure + // SMESHDS_Mesh::IsGroupOfSubShapes(shape)==true + TopoDS_Shape shapeForSrcMesh; + TopTools_IndexedMapOfShape pseudoSubShapes; + TopExp::MapShapes( SMESH_Mesh::PseudoShape(), pseudoSubShapes ); + + // index of pseudoSubShapes corresponding to srcMeshDS + int subIndex = srcMeshDS->GetPersistentId() % pseudoSubShapes.Extent(); + int nbSubShapes = 1 + srcMeshDS->GetPersistentId() / pseudoSubShapes.Extent(); + + // try to find already present shapeForSrcMesh + SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); + for ( int i = tgtMeshDS->MaxShapeIndex(); i > 0 && shapeForSrcMesh.IsNull(); --i ) + { + const TopoDS_Shape& s = tgtMeshDS->IndexToShape(i); + if ( s.ShapeType() != TopAbs_COMPOUND ) break; + TopoDS_Iterator sSubIt( s ); + for ( int iSub = 0; iSub < nbSubShapes && sSubIt.More(); ++iSub, sSubIt.Next() ) + if ( pseudoSubShapes( subIndex+iSub ).IsSame( sSubIt.Value())) + if ( iSub+1 == nbSubShapes ) + { + shapeForSrcMesh = s; + break; + } + } + if ( shapeForSrcMesh.IsNull() ) + { + // make a new shapeForSrcMesh + BRep_Builder aBuilder; + TopoDS_Compound comp; + aBuilder.MakeCompound( comp ); + shapeForSrcMesh = comp; + for ( int iSub = 0; iSub < nbSubShapes; ++iSub ) + aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub )); + TopExp_Explorer vExp( tgtMeshDS->ShapeToMesh(), TopAbs_VERTEX ); + aBuilder.Add( comp, vExp.Current() ); + } + SMESH_subMesh* sm = tgtMesh->GetSubMesh( shapeForSrcMesh ); + SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + if ( !smDS ) + smDS = tgtMeshDS->NewSubMesh( sm->GetId() ); + + // make ordinary submesh from a complex one + if ( smDS->IsComplexSubmesh() ) + { + list< const SMESHDS_SubMesh* > subSM; + SMESHDS_SubMeshIteratorPtr smIt = smDS->GetSubMeshIterator(); + while ( smIt->more() ) subSM.push_back( smIt->next() ); + list< const SMESHDS_SubMesh* >::iterator sub = subSM.begin(); + for ( ; sub != subSM.end(); ++sub) + smDS->RemoveSubMesh( *sub ); + } + return sm->GetId(); + } + + //================================================================================ + /*! + * \brief Return a submesh to store nodes and elements of a copied mesh + * and set event listeners in order to clear + * imported mesh and groups as soon as submesh state requires it + */ + //================================================================================ + + SMESHDS_SubMesh* getSubmeshForCopiedMesh(const SMESH_Mesh* srcMesh, + SMESH_Mesh* tgtMesh, + const TopoDS_Shape& tgtShape, + StdMeshers_Import_1D::TNodeNodeMap*& n2n, + StdMeshers_Import_1D::TElemElemMap*& e2e, + bool & toCopyGroups) + { + StdMeshers_Import_1D::getMaps( srcMesh, tgtMesh, n2n,e2e ); + + _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh); + + SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape ); + iData->addComputed( importedSM ); + if ( iData->_computedSubM.size() != iData->_subM.size() ) + return 0; // not all submeshes computed yet + + toCopyGroups = !iData->_copyGroupSubM.empty(); + + if ( !iData->_copyMeshSubM.empty()) + { + // make submesh to store a copied mesh + int smID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(), tgtMesh ); + SMESHDS_SubMesh* subDS = tgtMesh->GetMeshDS()->NewSubMesh( smID ); + + iData->_importMeshSubID = smID; + iData->_importMeshSubDS = subDS; + return subDS; + } + return 0; + } + +} // namespace + + +//============================================================================= +/*! + * Import elements from the other mesh + */ +//============================================================================= + +bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + SMESH_MesherHelper helper(theMesh); + helper.SetSubShape(theShape); + SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS(); + + const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape ); + const double edgeTol = BRep_Tool::Tolerance( geomEdge ); + const int shapeID = tgtMesh->ShapeToIndex( geomEdge ); + + set subShapeIDs; + subShapeIDs.insert( shapeID ); + + // get nodes on vertices + list < SMESH_TNodeXYZ > vertexNodes; + list < SMESH_TNodeXYZ >::iterator vNIt; + TopExp_Explorer vExp( theShape, TopAbs_VERTEX ); + for ( ; vExp.More(); vExp.Next() ) + { + const TopoDS_Vertex& v = TopoDS::Vertex( vExp.Current() ); + if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second ) + continue; // closed edge + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) + { + _gen->Compute(theMesh,v,/*anUpward=*/true); + n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) return false; // very strange + } + vertexNodes.push_back( SMESH_TNodeXYZ( n )); + } + + // import edges from groups + TNodeNodeMap* n2n; + TElemElemMap* e2e; + for ( int iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + + const int meshID = srcGroup->GetMesh()->GetPersistentId(); + const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID ); + if ( !srcMesh ) continue; + getMaps( srcMesh, &theMesh, n2n, e2e ); + + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + vector newNodes; + SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); + double u; + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* edge = srcElems->next(); + // find or create nodes of a new edge + newNodes.resize( edge->NbNodes() ); + newNodes.back() = 0; + SMDS_MeshElement::iterator node = edge->begin_nodes(); + for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) + { + TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; + if ( n2nIt->second ) + { + if ( !subShapeIDs.count( n2nIt->second->getshapeId() )) + break; + } + else + { + // find an existing vertex node + for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) + if ( vNIt->SquareDistance( *node ) < 10 * edgeTol * edgeTol) + { + (*n2nIt).second = vNIt->_node; + vertexNodes.erase( vNIt ); + break; + } + } + if ( !n2nIt->second ) + { + // find out if node lies on theShape + tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); + if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true )) + { + SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); + n2nIt->second = newNode; + tgtMesh->SetNodeOnEdge( newNode, shapeID, u ); + } + } + if ( !(newNodes[i] = n2nIt->second )) + break; + } + if ( !newNodes.back() ) + continue; // not all nodes of edge lie on theShape + + // make a new edge + SMDS_MeshElement * newEdge; + if ( newNodes.size() == 3 ) + newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] ); + else + newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]); + tgtMesh->SetMeshElementOnShape( newEdge, shapeID ); + e2e->insert( make_pair( edge, newEdge )); + } + helper.GetMeshDS()->RemoveNode(tmpNode); + } + if ( n2n->empty()) + return error("Empty source groups"); + + // check if the whole geom edge is covered by imported segments; + // the check consist in passing by segments from one vetrex node to another + bool isEdgeMeshed = false; + if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape )) + { + const TopoDS_Vertex& v = ( vExp.ReInit(), TopoDS::Vertex( vExp.Current() )); + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh ); + const SMDS_MeshElement* seg = 0; + SMDS_ElemIteratorPtr segIt = n->GetInverseElementIterator(SMDSAbs_Edge); + while ( segIt->more() && !seg ) + if ( !tgtSM->Contains( seg = segIt->next())) + seg = 0; + int nbPassedSegs = 0; + while ( seg ) + { + ++nbPassedSegs; + const SMDS_MeshNode* n2 = seg->GetNode(0); + n = ( n2 == n ? seg->GetNode(1) : n2 ); + if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + break; + const SMDS_MeshElement* seg2 = 0; + segIt = n->GetInverseElementIterator(SMDSAbs_Edge); + while ( segIt->more() && !seg2 ) + if ( seg == ( seg2 = segIt->next())) + seg2 = 0; + seg = seg2; + } + if (nbPassedSegs > 0 && tgtSM->NbElements() > nbPassedSegs ) + return error( "Source elements overlap one another"); + + isEdgeMeshed = ( tgtSM->NbElements() == nbPassedSegs && + n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ); + } + if ( !isEdgeMeshed ) + return error( "Source elements don't cover totally the geometrical edge" ); + + // copy meshes + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape ); + + return true; +} + +//================================================================================ +/*! + * \brief Copy mesh and groups + */ +//================================================================================ + +void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh, + SMESH_Mesh & tgtMesh, + StdMeshers_ImportSource1D* srcHyp, + const TopoDS_Shape& tgtShape) +{ + // get submesh to store the imported mesh + TNodeNodeMap* n2n; + TElemElemMap* e2e; + bool toCopyGroups; + SMESHDS_SubMesh* tgtSubMesh = + getSubmeshForCopiedMesh( srcMesh, &tgtMesh, tgtShape, n2n, e2e, toCopyGroups ); + if ( !tgtSubMesh || tgtSubMesh->NbNodes() + tgtSubMesh->NbElements() > 0 ) + return; // not to copy srcMeshDS twice + + SMESHDS_Mesh* tgtMeshDS = tgtMesh.GetMeshDS(); + SMESH_MeshEditor additor( &tgtMesh ); + + // 1. Copy mesh + + vector newNodes; + const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); + SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator(); + while ( eIt->more() ) + { + const SMDS_MeshElement* elem = eIt->next(); + TElemElemMap::iterator e2eIt = e2e->insert( make_pair( elem, (SMDS_MeshElement*)0 )).first; + if ( e2eIt->second ) continue; // already copied by Compute() + newNodes.resize( elem->NbNodes() ); + SMDS_MeshElement::iterator node = elem->begin_nodes(); + for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) + { + TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; + if ( !n2nIt->second ) + { + (*n2nIt).second = tgtMeshDS->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); + tgtSubMesh->AddNode( n2nIt->second ); + } + newNodes[i] = n2nIt->second; + } + const SMDS_MeshElement* newElem = + tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false ); + if ( !newElem ) + { + newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly()); + tgtSubMesh->AddElement( newElem ); + } + if ( toCopyGroups ) + (*e2eIt).second = newElem; + } + // copy free nodes + if ( srcMeshDS->NbNodes() > n2n->size() ) + { + SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator(); + while( nIt->more() ) + { + const SMDS_MeshNode* node = nIt->next(); + if ( node->NbInverseElements() == 0 ) + { + const SMDS_MeshNode* newNode = tgtMeshDS->AddNode( node->X(), node->Y(), node->Z()); + n2n->insert( make_pair( node, newNode )); + tgtSubMesh->AddNode( newNode ); + } + } + } + + // 2. Copy groups + + vector resultGroups; + if ( toCopyGroups ) + { + // collect names of existing groups to assure uniqueness of group names within a type + map< SMDSAbs_ElementType, set > namesByType; + SMESH_Mesh::GroupIteratorPtr groupIt = tgtMesh.GetGroups(); + while ( groupIt->more() ) + { + SMESH_Group* tgtGroup = groupIt->next(); + namesByType[ tgtGroup->GetGroupDS()->GetType() ].insert( tgtGroup->GetName() ); + } + if (srcMesh) + { + SMESH_Mesh::GroupIteratorPtr groupIt = srcMesh->GetGroups(); + while ( groupIt->more() ) + { + SMESH_Group* srcGroup = groupIt->next(); + SMESHDS_GroupBase* srcGroupDS = srcGroup->GetGroupDS(); + string name = srcGroup->GetName(); + int nb = 1; + while ( !namesByType[ srcGroupDS->GetType() ].insert( name ).second ) + name = SMESH_Comment(srcGroup->GetName()) << "_imported_" << nb++; + SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str(), nb ); + SMESHDS_Group* newGroupDS = (SMESHDS_Group*)newGroup->GetGroupDS(); + resultGroups.push_back( newGroup ); + + eIt = srcGroupDS->GetElements(); + if ( srcGroupDS->GetType() == SMDSAbs_Node ) + while (eIt->more()) + { + TNodeNodeMap::iterator n2nIt = n2n->find((const SMDS_MeshNode*) eIt->next() ); + if ( n2nIt != n2n->end() && n2nIt->second ) + newGroupDS->SMDSGroup().Add((*n2nIt).second ); + } + else + while (eIt->more()) + { + TElemElemMap::iterator e2eIt = e2e->find( eIt->next() ); + if ( e2eIt != e2e->end() && e2eIt->second ) + newGroupDS->SMDSGroup().Add((*e2eIt).second ); + } + } + } + } + n2n->clear(); + e2e->clear(); + + // Remember created groups in order to remove them as soon as the srcHyp is + // modified or something other similar happens. This imformation must be persistent, + // for that store them in a hypothesis as it stores its values in the file anyway + srcHyp->StoreResultGroups( resultGroups, *srcMeshDS, *tgtMeshDS ); +} + +//============================================================================= +/*! + * \brief Set needed event listeners and create a submesh for a copied mesh + * + * This method is called only if a submesh has HYP_OK algo_state. + */ +//============================================================================= + +void StdMeshers_Import_1D::setEventListener(SMESH_subMesh* subMesh, + StdMeshers_ImportSource1D* sourceHyp) +{ + if ( sourceHyp ) + { + vector srcMeshes = sourceHyp->GetSourceMeshes(); + if ( srcMeshes.empty() ) + _Listener::waitHypModification( subMesh ); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + // set a listener to remove the imported mesh and groups + _Listener::storeImportSubmesh( subMesh, srcMeshes[i], sourceHyp ); + } +} +void StdMeshers_Import_1D::SetEventListener(SMESH_subMesh* subMesh) +{ + if ( !_sourceHyp ) + { + const TopoDS_Shape& tgtShape = subMesh->GetSubShape(); + SMESH_Mesh* tgtMesh = subMesh->GetFather(); + Hypothesis_Status aStatus; + CheckHypothesis( *tgtMesh, tgtShape, aStatus ); + } + setEventListener( subMesh, _sourceHyp ); +} + +void StdMeshers_Import_1D::SubmeshRestored(SMESH_subMesh* subMesh) +{ + SetEventListener(subMesh); +} + +//============================================================================= +/*! + * Predict nb of mesh entities created by Compute() + */ +//============================================================================= + +bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh, + const TopoDS_Shape & theShape, + MapShapeNbElems& aResMap) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + vector aVec(SMDSEntity_Last,0); + + bool toCopyMesh, toCopyGroups; + _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups); + if ( toCopyMesh ) // the whole mesh is copied + { + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + { + SMESH_subMesh* sm = getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]); + if ( !sm || aResMap.count( sm )) continue; // already counted + aVec.assign( SMDSEntity_Last, 0); + const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo(); + for (int i = 0; i < SMDSEntity_Last; i++) + aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i); + } + } + else + { + SMESH_MesherHelper helper(theMesh); + + const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape ); + const double edgeTol = helper.MaxTolerance( geomEdge ); + + // take into account nodes on vertices + TopExp_Explorer vExp( theShape, TopAbs_VERTEX ); + for ( ; vExp.More(); vExp.Next() ) + theMesh.GetSubMesh( vExp.Current())->Evaluate( aResMap ); + + // count edges imported from groups + int nbEdges = 0, nbQuadEdges = 0; + for ( int iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* edge = srcElems->next(); + // find out if edge is located on geomEdge by projecting + // a middle of edge to geomEdge + SMESH_TNodeXYZ p1( edge->GetNode(0)); + SMESH_TNodeXYZ p2( edge->GetNode(1)); + gp_XYZ middle = ( p1 + p2 ) / 2.; + tmpNode->setXYZ( middle.X(), middle.Y(), middle.Z()); + double u = 0; + if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true )) + ++( edge->IsQuadratic() ? nbQuadEdges : nbEdges); + } + helper.GetMeshDS()->RemoveNode(tmpNode); + } + + int nbNodes = nbEdges + 2 * nbQuadEdges - 1; + + aVec[SMDSEntity_Node ] = nbNodes; + aVec[SMDSEntity_Edge ] = nbEdges; + aVec[SMDSEntity_Quad_Edge] = nbQuadEdges; + } + + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(make_pair(sm,aVec)); + + return true; +} + +//================================================================================ +/*! + * \brief Return node-node and element-element maps for import of geiven source mesh + */ +//================================================================================ + +void StdMeshers_Import_1D::getMaps(const SMESH_Mesh* srcMesh, + SMESH_Mesh* tgtMesh, + TNodeNodeMap*& n2n, + TElemElemMap*& e2e) +{ + _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh); + n2n = &iData->_n2n; + e2e = &iData->_e2e; + if ( iData->_copyMeshSubM.empty() ) + { + n2n->clear(); + e2e->clear(); + } +} + +//================================================================================ +/*! + * \brief Return submesh corresponding to the copied mesh + */ +//================================================================================ + +SMESH_subMesh* StdMeshers_Import_1D::getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh, + SMESH_Mesh& srcMesh ) +{ + _ImportData* iData = _Listener::getImportData(&srcMesh,&tgtMesh); + if ( iData->_copyMeshSubM.empty() ) return 0; + SMESH_subMesh* sm = tgtMesh.GetSubMeshContaining( iData->_importMeshSubID ); + return sm; +} + diff --git a/src/StdMeshers/StdMeshers_Import_1D.hxx b/src/StdMeshers/StdMeshers_Import_1D.hxx new file mode 100644 index 000000000..b71b90564 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D.hxx @@ -0,0 +1,81 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// Module : SMESH +// +#ifndef _SMESH_Import_1D_HXX_ +#define _SMESH_Import_1D_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_1D_Algo.hxx" +#include "SMDS_MeshElement.hxx" + +class StdMeshers_ImportSource1D; + +/*! + * \brief Copy elements from other the mesh + */ +class STDMESHERS_EXPORT StdMeshers_Import_1D: public SMESH_1D_Algo +{ +public: + StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen* gen); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + + virtual void SetEventListener(SMESH_subMesh* subMesh); + virtual void SubmeshRestored(SMESH_subMesh* subMesh); + + // internal utilities + + typedef std::map TNodeNodeMap; + typedef std::map TElemElemMap; + + static void getMaps(const SMESH_Mesh* srcMesh, + SMESH_Mesh* tgtMesh, + TNodeNodeMap*& n2n, + TElemElemMap*& e2e); + + static void importMesh(const SMESH_Mesh* srcMesh, + SMESH_Mesh & tgtMesh, + StdMeshers_ImportSource1D* srcHyp, + const TopoDS_Shape& tgtShape); + + static void setEventListener( SMESH_subMesh* subMesh, + StdMeshers_ImportSource1D* sourceHyp ); + + static SMESH_subMesh* getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh, + SMESH_Mesh& srcMesh ); + + private: + + StdMeshers_ImportSource1D* _sourceHyp; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx new file mode 100644 index 000000000..8180f0a02 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D2D.cxx @@ -0,0 +1,778 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_Import_1D2D.cxx +// Module : SMESH +// +#include "StdMeshers_Import_1D2D.hxx" + +#include "StdMeshers_Import_1D.hxx" +#include "StdMeshers_ImportSource.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESHDS_Mesh.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" + +#include "Utils_SALOME_Exception.hxx" +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; + +namespace +{ + double getMinElemSize2( const SMESHDS_GroupBase* srcGroup ) + { + double minSize2 = 1e100; + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* face = srcElems->next(); + int nbN = face->NbCornerNodes(); + + SMESH_TNodeXYZ prevN( face->GetNode( nbN-1 )); + for ( int i = 0; i < nbN; ++i ) + { + SMESH_TNodeXYZ n( face->GetNode( i ) ); + double size2 = ( n - prevN ).SquareModulus(); + minSize2 = std::min( minSize2, size2 ); + prevN = n; + } + } + return minSize2; + } +} + +//============================================================================= +/*! + * Creates StdMeshers_Import_1D2D + */ +//============================================================================= + +StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen * gen) + :SMESH_2D_Algo(hypId, studyId, gen), _sourceHyp(0) +{ + MESSAGE("StdMeshers_Import_1D2D::StdMeshers_Import_1D2D"); + _name = "Import_1D2D"; + _shapeType = (1 << TopAbs_FACE); + + _compatibleHypothesis.push_back("ImportSource2D"); + _requireDiscreteBoundary = false; +} + +//============================================================================= +/*! + * Check presence of a hypothesis + */ +//============================================================================= + +bool StdMeshers_Import_1D2D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + _sourceHyp = 0; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + if ( hyps.size() == 0 ) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + if ( hyps.size() > 1 ) + { + aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST; + return false; + } + + const SMESHDS_Hypothesis *theHyp = hyps.front(); + + string hypName = theHyp->GetName(); + + if (hypName == _compatibleHypothesis.front()) + { + _sourceHyp = (StdMeshers_ImportSource1D *)theHyp; + aStatus = SMESH_Hypothesis::HYP_OK; + return true; + } + + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + return true; +} + +namespace +{ + /*! + * \brief OrientedLink additionally storing a medium node + */ + struct TLink : public SMESH_OrientedLink + { + const SMDS_MeshNode* _medium; + TLink( const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* medium=0) + : SMESH_OrientedLink( n1,n2 ), _medium( medium ) {} + }; +} + +//============================================================================= +/*! + * Import elements from the other mesh + */ +//============================================================================= + +bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + bool allGroupsEmpty = true; + for ( size_t iG = 0; iG < srcGroups.size() && allGroupsEmpty; ++iG ) + allGroupsEmpty = srcGroups[iG]->GetGroupDS()->IsEmpty(); + if ( allGroupsEmpty ) + return error("No faces in source groups"); + + SMESH_MesherHelper helper(theMesh); + helper.SetSubShape(theShape); + SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS(); + + const TopoDS_Face& geomFace = TopoDS::Face( theShape ); + const double faceTol = helper.MaxTolerance( geomFace ); + const int shapeID = tgtMesh->ShapeToIndex( geomFace ); + const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 ); + + Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace ); + const bool reverse = + ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED ); + gp_Pnt p; gp_Vec du, dv; + + set subShapeIDs; + subShapeIDs.insert( shapeID ); + + // get nodes on vertices + list < SMESH_TNodeXYZ > vertexNodes; + list < SMESH_TNodeXYZ >::iterator vNIt; + TopExp_Explorer exp( theShape, TopAbs_VERTEX ); + for ( ; exp.More(); exp.Next() ) + { + const TopoDS_Vertex& v = TopoDS::Vertex( exp.Current() ); + if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second ) + continue; + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) + { + _gen->Compute(theMesh,v,/*anUpward=*/true); + n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) return false; // very strange + } + vertexNodes.push_back( SMESH_TNodeXYZ( n )); + } + + // to count now many times a link between nodes encounters + map linkCount; + map::iterator link2Nb; + double minGroupTol = Precision::Infinite(); + + // ========================= + // Import faces from groups + // ========================= + + StdMeshers_Import_1D::TNodeNodeMap* n2n; + StdMeshers_Import_1D::TElemElemMap* e2e; + vector newNodes; + for ( size_t iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + + const int meshID = srcGroup->GetMesh()->GetPersistentId(); + const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID ); + if ( !srcMesh ) continue; + StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e ); + + const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup )); + minGroupTol = std::min( groupTol, minGroupTol ); + + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); + gp_XY uv( Precision::Infinite(), Precision::Infinite() ); + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* face = srcElems->next(); + // find or create nodes of a new face + newNodes.resize( face->NbNodes() ); + newNodes.back() = 0; + int nbCreatedNodes = 0; + SMDS_MeshElement::iterator node = face->begin_nodes(); + for ( size_t i = 0; i < newNodes.size(); ++i, ++node ) + { + StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; + if ( n2nIt->second ) + { + if ( !subShapeIDs.count( n2nIt->second->getshapeId() )) + break; + } + else + { + // find an existing vertex node + for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) + if ( vNIt->SquareDistance( *node ) < groupTol * groupTol) + { + (*n2nIt).second = vNIt->_node; + vertexNodes.erase( vNIt ); + break; + } + } + if ( !n2nIt->second ) + { + // find out if node lies on theShape + tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); + uv.SetCoord( Precision::Infinite(), Precision::Infinite() ); + if ( helper.CheckNodeUV( geomFace, tmpNode, uv, groupTol, /*force=*/true )) + { + SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); + n2nIt->second = newNode; + tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() ); + nbCreatedNodes++; + } + } + if ( !(newNodes[i] = n2nIt->second )) + break; + } + if ( !newNodes.back() ) + continue; // not all nodes of the face lie on theShape + + // try to find already created face + SMDS_MeshElement * newFace = 0; + if ( nbCreatedNodes == 0 && + tgtMesh->FindElement(newNodes, SMDSAbs_Face, /*noMedium=*/false)) + continue; // repeated face in source groups already created + + // check future face orientation + if ( toCheckOri ) + { + int iNode = -1; + gp_Vec geomNorm; + do + { + uv = helper.GetNodeUV( geomFace, newNodes[++iNode] ); + surface->D1( uv.X(),uv.Y(), p, du,dv ); + geomNorm = reverse ? dv^du : du^dv; + } + while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes()); + + int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() ); + int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() ); + + SMESH_TNodeXYZ prevNode( newNodes[iPrev] ); + SMESH_TNodeXYZ curNode ( newNodes[iNode] ); + SMESH_TNodeXYZ nextNode( newNodes[iNext] ); + gp_Vec n1n0( prevNode - curNode); + gp_Vec n1n2( nextNode - curNode ); + gp_Vec meshNorm = n1n2 ^ n1n0; + + if ( geomNorm * meshNorm < 0 ) + std::reverse( newNodes.begin(), newNodes.end() ); + } + + // make a new face + switch ( newNodes.size() ) + { + case 3: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] ); + break; + case 4: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] ); + break; + case 6: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], + newNodes[3], newNodes[4], newNodes[5]); + break; + case 8: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3], + newNodes[4], newNodes[5], newNodes[6], newNodes[7]); + break; + default: continue; + } + tgtMesh->SetMeshElementOnShape( newFace, shapeID ); + e2e->insert( make_pair( face, newFace )); + + // collect links + int nbNodes = face->NbCornerNodes(); + const SMDS_MeshNode* medium = 0; + for ( int i = 0; i < nbNodes; ++i ) + { + const SMDS_MeshNode* n1 = newNodes[i]; + const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbNodes ]; + if ( newFace->IsQuadratic() ) + medium = newNodes[i+nbNodes]; + link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first; + ++link2Nb->second; + // if ( link2Nb->second == 1 ) + // { + // // measure link length + // double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 ); + // if ( len2 < minGroupTol ) + // minGroupTol = len2; + // } + } + } + helper.GetMeshDS()->RemoveNode(tmpNode); + } + + // ========================================================== + // Put nodes on geom edges and create edges on them; + // check if the whole geom face is covered by imported faces + // ========================================================== + + vector< TopoDS_Edge > edges; + for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() ) + if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( exp.Current() )).second ) + edges.push_back( TopoDS::Edge( exp.Current() )); + + // use large tolerance for projection of nodes to edges because of + // BLSURF mesher specifics (issue 0020918, Study2.hdf) + const double projTol = minGroupTol; + + bool isFaceMeshed = false; + SMESHDS_SubMesh* tgtFaceSM = tgtMesh->MeshElements( theShape ); + if ( tgtFaceSM ) + { + // the imported mesh is valid if all external links (encountered once) + // lie on geom edges + subShapeIDs.erase( shapeID ); // to contain edges and vertices only + double u, f, l; + for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb) + { + const TLink& link = (*link2Nb).first; + int nbFaces = link2Nb->second; + if ( nbFaces == 1 ) + { + // check if a not shared link lies on face boundary + bool nodesOnBoundary = true; + list< TopoDS_Shape > bndShapes; + for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN ) + { + const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2(); + if ( !subShapeIDs.count( n->getshapeId() )) + { + for ( size_t iE = 0; iE < edges.size(); ++iE ) + if ( helper.CheckNodeU( edges[iE], n, u=0, projTol, /*force=*/true )) + { + BRep_Tool::Range(edges[iE],f,l); + if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol ) + // duplicated node on vertex + return error("Source elements overlap one another"); + tgtFaceSM->RemoveNode( n, /*isNodeDeleted=*/false ); + tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u ); + break; + } + nodesOnBoundary = subShapeIDs.count( n->getshapeId()); + } + if ( nodesOnBoundary ) + { + TopoDS_Shape s = helper.GetSubShapeByNode( n, tgtMesh ); + if ( s.ShapeType() == TopAbs_VERTEX ) + bndShapes.push_front( s ); // vertex first + else + bndShapes.push_back( s ); // edges last + } + } + if ( !nodesOnBoundary ) + { + error("free internal link"); // just for an easier debug + break; + } + if ( bndShapes.front().ShapeType() == TopAbs_EDGE && + bndShapes.front() != bndShapes.back() ) + // link nodes on different geom edges + return error(COMPERR_BAD_INPUT_MESH, "Source nodes mismatch target vertices"); + + // find geom edge the link is on + if ( bndShapes.back().ShapeType() != TopAbs_EDGE ) + { + // find geom edge by two vertices + TopoDS_Shape geomEdge = helper.GetCommonAncestor( bndShapes.back(), + bndShapes.front(), + theMesh, TopAbs_EDGE ); + if ( geomEdge.IsNull() ) + { + error("free internal link"); + break; // vertices belong to different edges + } + bndShapes.push_back( geomEdge ); + } + + // create an edge if not yet exists + newNodes.resize(2); + newNodes[0] = link.node1(), newNodes[1] = link.node2(); + const SMDS_MeshElement* edge = tgtMesh->FindElement( newNodes, SMDSAbs_Edge ); + if ( edge ) continue; + + if ( link._reversed ) std::swap( newNodes[0], newNodes[1] ); + if ( link._medium ) + { + newNodes.push_back( link._medium ); + edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] ); + + TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back()); + helper.CheckNodeU( geomEdge, link._medium, u, projTol, /*force=*/true ); + tgtFaceSM->RemoveNode( link._medium, /*isNodeDeleted=*/false ); + tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u ); + } + else + { + edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]); + } + if ( !edge ) + return false; + + tgtMesh->SetMeshElementOnShape( edge, bndShapes.back() ); + } + else if ( nbFaces > 2 ) + { + return error( COMPERR_BAD_INPUT_MESH, "Non-manifold source mesh"); + } + } + isFaceMeshed = ( link2Nb == linkCount.end() && !linkCount.empty()); + if ( isFaceMeshed ) + { + // check that source faces do not overlap: + // there must be only two edges sharing each vertex and bound to sub-edges of theShape + SMESH_MeshEditor editor( &theMesh ); + set::iterator subID = subShapeIDs.begin(); + for ( ; subID != subShapeIDs.end(); ++subID ) + { + const TopoDS_Shape& s = tgtMesh->IndexToShape( *subID ); + if ( s.ShapeType() != TopAbs_VERTEX ) continue; + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( TopoDS::Vertex(s), tgtMesh ); + SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(SMDSAbs_Edge); + int nbEdges = 0; + while ( eIt->more() ) + { + const SMDS_MeshElement* edge = eIt->next(); + int sId = editor.FindShape( edge ); + nbEdges += subShapeIDs.count( sId ); + } + if ( nbEdges < 2 ) + return false; // weird + if ( nbEdges > 2 ) + return error( COMPERR_BAD_INPUT_MESH, "Source elements overlap one another"); + } + } + } + if ( !isFaceMeshed ) + return error( COMPERR_BAD_INPUT_MESH, + "Source elements don't cover totally the geometrical face" ); + + if ( helper.HasSeam() ) + { + // links on seam edges are shared by two faces, so no edges were created on them + // by the previous detection of 2D mesh boundary + for ( size_t iE = 0; iE < edges.size(); ++iE ) + { + if ( !helper.IsRealSeam( edges[iE] )) continue; + const TopoDS_Edge& seamEdge = edges[iE]; + // to find nodes lying on the seamEdge we check nodes of mesh faces sharing a node on one + // of its vertices; after finding another node on seamEdge we continue the same way + // until finding all nodes. + TopoDS_Vertex seamVertex = helper.IthVertex( 0, seamEdge ); + const SMDS_MeshNode* vertNode = SMESH_Algo::VertexNode( seamVertex, tgtMesh ); + set< const SMDS_MeshNode* > checkedNodes; checkedNodes.insert( vertNode ); + set< const SMDS_MeshElement* > checkedFaces; + // as a face can have more than one node on the seamEdge, there is a difficulty in selecting + // one of those nodes to treat next; so we simply find all nodes on the seamEdge and + // then sort them by U on edge + typedef list< pair< double, const SMDS_MeshNode* > > TUNodeList; + TUNodeList nodesOnSeam; + double u = helper.GetNodeU( seamEdge, vertNode ); + nodesOnSeam.push_back( make_pair( u, vertNode )); + TUNodeList::iterator u2nIt = nodesOnSeam.begin(); + for ( ; u2nIt != nodesOnSeam.end(); ++u2nIt ) + { + const SMDS_MeshNode* startNode = (*u2nIt).second; + SMDS_ElemIteratorPtr faceIt = startNode->GetInverseElementIterator( SMDSAbs_Face ); + while ( faceIt->more() ) + { + const SMDS_MeshElement* face = faceIt->next(); + if ( !checkedFaces.insert( face ).second ) continue; + for ( int i = 0, nbNodes = face->NbCornerNodes(); i < nbNodes; ++i ) + { + const SMDS_MeshNode* n = face->GetNode( i ); + if ( n == startNode || !checkedNodes.insert( n ).second ) continue; + if ( helper.CheckNodeU( seamEdge, n, u=0, projTol, /*force=*/true )) + nodesOnSeam.push_back( make_pair( u, n )); + } + } + } + // sort the found nodes by U on the seamEdge; most probably they are in a good order, + // so we can use the hint to spead-up map filling + map< double, const SMDS_MeshNode* > u2nodeMap; + for ( u2nIt = nodesOnSeam.begin(); u2nIt != nodesOnSeam.end(); ++u2nIt ) + u2nodeMap.insert( u2nodeMap.end(), *u2nIt ); + + // create edges + { + SMESH_MesherHelper seamHelper( theMesh ); + seamHelper.SetSubShape( edges[ iE ]); + seamHelper.SetElementsOnShape( true ); + + if ( (*checkedFaces.begin())->IsQuadratic() ) + for ( set< const SMDS_MeshElement* >::iterator fIt = checkedFaces.begin(); + fIt != checkedFaces.end(); ++fIt ) + seamHelper.AddTLinks( static_cast( *fIt )); + + map< double, const SMDS_MeshNode* >::iterator n1, n2, u2nEnd = u2nodeMap.end(); + for ( n2 = u2nodeMap.begin(), n1 = n2++; n2 != u2nEnd; ++n1, ++n2 ) + { + const SMDS_MeshNode* node1 = n1->second; + const SMDS_MeshNode* node2 = n2->second; + seamHelper.AddEdge( node1, node2 ); + if ( node2->getshapeId() == helper.GetSubShapeID() ) + { + tgtFaceSM->RemoveNode( node2, /*isNodeDeleted=*/false ); + tgtMesh->SetNodeOnEdge( const_cast( node2 ), seamEdge, n2->first ); + } + } + } + } // loop on edges to find seam ones + } // if ( helper.HasSeam() ) + + // notify sub-meshes of edges on computation + for ( size_t iE = 0; iE < edges.size(); ++iE ) + { + SMESH_subMesh * sm = theMesh.GetSubMesh( edges[iE] ); + if ( BRep_Tool::Degenerated( edges[iE] )) + sm->SetIsAlwaysComputed( true ); + sm->ComputeStateEngine(SMESH_subMesh::CHECK_COMPUTE_STATE); + if ( sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK ) + return error(SMESH_Comment("Failed to create segments on the edge ") + << tgtMesh->ShapeToIndex( edges[iE ])); + } + + // ============ + // Copy meshes + // ============ + + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( size_t i = 0; i < srcMeshes.size(); ++i ) + StdMeshers_Import_1D::importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape ); + + return true; +} + +//============================================================================= +/*! + * \brief Set needed event listeners and create a submesh for a copied mesh + * + * This method is called only if a submesh has HYP_OK algo_state. + */ +//============================================================================= + +void StdMeshers_Import_1D2D::SetEventListener(SMESH_subMesh* subMesh) +{ + if ( !_sourceHyp ) + { + const TopoDS_Shape& tgtShape = subMesh->GetSubShape(); + SMESH_Mesh* tgtMesh = subMesh->GetFather(); + Hypothesis_Status aStatus; + CheckHypothesis( *tgtMesh, tgtShape, aStatus ); + } + StdMeshers_Import_1D::setEventListener( subMesh, _sourceHyp ); +} +void StdMeshers_Import_1D2D::SubmeshRestored(SMESH_subMesh* subMesh) +{ + SetEventListener(subMesh); +} + +//============================================================================= +/*! + * Predict nb of mesh entities created by Compute() + */ +//============================================================================= + +bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh, + const TopoDS_Shape & theShape, + MapShapeNbElems& aResMap) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + vector aVec(SMDSEntity_Last,0); + + bool toCopyMesh, toCopyGroups; + _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups); + if ( toCopyMesh ) // the whole mesh is copied + { + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + { + SMESH_subMesh* sm = StdMeshers_Import_1D::getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]); + if ( !sm || aResMap.count( sm )) continue; // already counted + const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo(); + for (int i = 0; i < SMDSEntity_Last; i++) + aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i); + } + } + else + { + // std-like iterator used to get coordinates of nodes of mesh element + typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator; + + SMESH_MesherHelper helper(theMesh); + helper.SetSubShape(theShape); + + const TopoDS_Face& geomFace = TopoDS::Face( theShape ); + + // take into account nodes on vertices + TopExp_Explorer exp( theShape, TopAbs_VERTEX ); + for ( ; exp.More(); exp.Next() ) + theMesh.GetSubMesh( exp.Current())->Evaluate( aResMap ); + + // to count now many times a link between nodes encounters, + // negative nb additionally means that a link is quadratic + map linkCount; + map::iterator link2Nb; + + // count faces and nodes imported from groups + set allNodes; + gp_XY uv; + double minGroupTol = 1e100; + for ( int iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup )); + minGroupTol = std::min( groupTol, minGroupTol ); + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + SMDS_MeshNode *tmpNode =helper.AddNode(0,0,0); + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* face = srcElems->next(); + // find out if face is located on geomEdge by projecting + // a gravity center of face to geomFace + gp_XYZ gc(0,0,0); + gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes(); + tmpNode->setXYZ( gc.X(), gc.Y(), gc.Z()); + if ( helper.CheckNodeUV( geomFace, tmpNode, uv, groupTol, /*force=*/true )) + { + ++aVec[ face->GetEntityType() ]; + + // collect links + int nbConers = face->NbCornerNodes(); + for ( int i = 0; i < face->NbNodes(); ++i ) + { + const SMDS_MeshNode* n1 = face->GetNode(i); + allNodes.insert( n1 ); + if ( i < nbConers ) + { + const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbConers ); + link2Nb = linkCount.insert( make_pair( SMESH_TLink( n1, n2 ), 0)).first; + if ( (*link2Nb).second ) + link2Nb->second += (link2Nb->second < 0 ) ? -1 : 1; + else + link2Nb->second += ( face->IsQuadratic() ) ? -1 : 1; + } + } + } + } + helper.GetMeshDS()->RemoveNode(tmpNode); + } + + int nbNodes = allNodes.size(); + allNodes.clear(); + + // count nodes and edges on geom edges + + double u; + for ( exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next() ) + { + TopoDS_Edge geomEdge = TopoDS::Edge( exp.Current() ); + SMESH_subMesh* sm = theMesh.GetSubMesh( geomEdge ); + vector& edgeVec = aResMap[sm]; + if ( edgeVec.empty() ) + { + edgeVec.resize(SMDSEntity_Last,0); + for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ) + { + const SMESH_TLink& link = (*link2Nb).first; + int nbFacesOfLink = Abs( link2Nb->second ); + bool eraseLink = ( nbFacesOfLink != 1 ); + if ( nbFacesOfLink == 1 ) + { + if ( helper.CheckNodeU( geomEdge, link.node1(), u, minGroupTol, /*force=*/true )&& + helper.CheckNodeU( geomEdge, link.node2(), u, minGroupTol, /*force=*/true )) + { + bool isQuadratic = ( link2Nb->second < 0 ); + ++edgeVec[ isQuadratic ? SMDSEntity_Quad_Edge : SMDSEntity_Edge ]; + ++edgeVec[ SMDSEntity_Node ]; + --nbNodes; + eraseLink = true; + } + } + if ( eraseLink ) + linkCount.erase(link2Nb++); + else + link2Nb++; + } + if ( edgeVec[ SMDSEntity_Node] > 0 ) + --edgeVec[ SMDSEntity_Node ]; // for one node on vertex + } + else if ( !helper.IsSeamShape( geomEdge ) || + geomEdge.Orientation() == TopAbs_FORWARD ) + { + nbNodes -= 1+edgeVec[ SMDSEntity_Node ]; + } + } + + aVec[SMDSEntity_Node] = nbNodes; + } + + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(make_pair(sm,aVec)); + + return true; +} diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.hxx b/src/StdMeshers/StdMeshers_Import_1D2D.hxx new file mode 100644 index 000000000..fc3a89d85 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D2D.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// Module : SMESH +// +#ifndef _SMESH_Import_2D_HXX_ +#define _SMESH_Import_2D_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_2D_Algo.hxx" +#include "SMDS_MeshElement.hxx" + +class StdMeshers_ImportSource1D; + +/*! + * \brief Copy elements from other the mesh + */ +class STDMESHERS_EXPORT StdMeshers_Import_1D2D: public SMESH_2D_Algo +{ +public: + StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen* gen); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + + virtual void SetEventListener(SMESH_subMesh* subMesh); + virtual void SubmeshRestored(SMESH_subMesh* subMesh); + + private: + + StdMeshers_ImportSource1D* _sourceHyp; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_LayerDistribution.cxx b/src/StdMeshers/StdMeshers_LayerDistribution.cxx index 8e5987e6b..06693566b 100644 --- a/src/StdMeshers/StdMeshers_LayerDistribution.cxx +++ b/src/StdMeshers/StdMeshers_LayerDistribution.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_LayerDistribution.cxx // Author : Edward AGAPOV diff --git a/src/StdMeshers/StdMeshers_LayerDistribution.hxx b/src/StdMeshers/StdMeshers_LayerDistribution.hxx index aca054d4f..921d06bd3 100644 --- a/src/StdMeshers/StdMeshers_LayerDistribution.hxx +++ b/src/StdMeshers/StdMeshers_LayerDistribution.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_LayerDistribution.hxx // Author : Edward AGAPOV diff --git a/src/StdMeshers/StdMeshers_LayerDistribution2D.cxx b/src/StdMeshers/StdMeshers_LayerDistribution2D.cxx new file mode 100644 index 000000000..581e43613 --- /dev/null +++ b/src/StdMeshers/StdMeshers_LayerDistribution2D.cxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : idl implementation based on 'SMESH' unit's classes +// File : StdMeshers_LayerDistribution2D.cxx +// Author : Edward AGAPOV +// Module : SMESH +// +#include "StdMeshers_LayerDistribution2D.hxx" + +#include "utilities.h" + + +//============================================================================= +/*! + * StdMeshers_LayerDistribution2D::StdMeshers_LayerDistribution2D + * + * Constructor + */ +//============================================================================= + +StdMeshers_LayerDistribution2D::StdMeshers_LayerDistribution2D(int hypId, + int studyId, + SMESH_Gen * gen) + : StdMeshers_LayerDistribution(hypId, studyId, gen) +{ + _name = "LayerDistribution2D"; // used by RadialQuadrangle_1D2D + _param_algo_dim = 2; // 2D + myHyp = 0; +} + +//============================================================================= +/*! + * StdMeshers_LayerDistribution2D::~StdMeshers_LayerDistribution2D + * + * Destructor + */ +//============================================================================= + +StdMeshers_LayerDistribution2D::~StdMeshers_LayerDistribution2D() +{ + MESSAGE( "StdMeshers_LayerDistribution2D::~StdMeshers_LayerDistribution2D" ); +} diff --git a/src/StdMeshers/StdMeshers_LayerDistribution2D.hxx b/src/StdMeshers/StdMeshers_LayerDistribution2D.hxx new file mode 100644 index 000000000..f3ae9b290 --- /dev/null +++ b/src/StdMeshers/StdMeshers_LayerDistribution2D.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_LayerDistribution2D.hxx +// Author : Edward AGAPOV +// Module : SMESH +// +#ifndef _SMESH_LayerDistribution2D_HXX_ +#define _SMESH_LayerDistribution2D_HXX_ + +#include "StdMeshers_LayerDistribution.hxx" + + +// ========================================================= +// ========================================================= +/*! + * This hypothesis is used by "Radial quadrangle" algorithm. + * It specifies 1D hypothesis defining distribution of segments + * between the internal and the external surfaces. + */ +// ========================================================= +// ========================================================= + +class STDMESHERS_EXPORT StdMeshers_LayerDistribution2D + :public StdMeshers_LayerDistribution +{ +public: + // Constructor + StdMeshers_LayerDistribution2D(int hypId, int studyId, SMESH_Gen* gen); + // Destructor + virtual ~StdMeshers_LayerDistribution2D(); + +}; + +#endif + diff --git a/src/StdMeshers/StdMeshers_LengthFromEdges.cxx b/src/StdMeshers/StdMeshers_LengthFromEdges.cxx index cad6e9186..317b43d05 100644 --- a/src/StdMeshers/StdMeshers_LengthFromEdges.cxx +++ b/src/StdMeshers/StdMeshers_LengthFromEdges.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_LengthFromEdges.cxx // Moved here from SMESH_LengthFromEdges.cxx diff --git a/src/StdMeshers/StdMeshers_LengthFromEdges.hxx b/src/StdMeshers/StdMeshers_LengthFromEdges.hxx index cb52638e5..a80a1e72c 100644 --- a/src/StdMeshers/StdMeshers_LengthFromEdges.hxx +++ b/src/StdMeshers/StdMeshers_LengthFromEdges.hxx @@ -1,31 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_LengthFromEdges.hxx // Moved here from SMESH_LengthFromEdges.hxx // Author : Paul RASCLE, EDF // Module : SMESH // - #ifndef _SMESH_LENGTHFROMEDGES_HXX_ #define _SMESH_LENGTHFROMEDGES_HXX_ diff --git a/src/StdMeshers/StdMeshers_LocalLength.cxx b/src/StdMeshers/StdMeshers_LocalLength.cxx index d74abe9fd..0706f9ef2 100644 --- a/src/StdMeshers/StdMeshers_LocalLength.cxx +++ b/src/StdMeshers/StdMeshers_LocalLength.cxx @@ -1,31 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_LocalLength.cxx // Moved here from SMESH_LocalLength.cxx // Author : Paul RASCLE, EDF // Module : SMESH // - #include "StdMeshers_LocalLength.hxx" #include "SMESH_Mesh.hxx" @@ -216,7 +216,7 @@ bool StdMeshers_LocalLength::SetParametersByMesh(const SMESH_Mesh* theMesh, { const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE )); Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax ); - GeomAdaptor_Curve AdaptCurve(C); + GeomAdaptor_Curve AdaptCurve(C, UMin, UMax); vector< double > params; SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS(); @@ -244,6 +244,6 @@ bool StdMeshers_LocalLength::SetParametersByMesh(const SMESH_Mesh* theMesh, bool StdMeshers_LocalLength::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*theMesh*/) { - return bool( _length = dflts._elemLength ); + return ( _length = dflts._elemLength ); } diff --git a/src/StdMeshers/StdMeshers_LocalLength.hxx b/src/StdMeshers/StdMeshers_LocalLength.hxx index 1c8d72b27..6232e127c 100644 --- a/src/StdMeshers/StdMeshers_LocalLength.hxx +++ b/src/StdMeshers/StdMeshers_LocalLength.hxx @@ -1,31 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_LocalLength.hxx // Moved here from SMESH_LocalLength.hxx // Author : Paul RASCLE, EDF // Module : SMESH // - #ifndef _SMESH_LOCALLENGTH_HXX_ #define _SMESH_LOCALLENGTH_HXX_ diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx index 453398149..fe637c65a 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MEFISTO_2D.cxx // Moved here from SMESH_MEFISTO_2D.cxx @@ -50,8 +51,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -63,6 +66,10 @@ #include #include +#include +#include +#include + using namespace std; //============================================================================= @@ -230,6 +237,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh Z nutysu = 1; // 1: il existe un fonction areteideale_() // Z nutysu=0; // 0: on utilise aretmx R aretmx = _edgeLength; // longueur max aretes future triangulation + if ( _hypMaxElementArea ) + aretmx *= 1.5; nblf = nbWires; @@ -282,6 +291,90 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh return isOk; } + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_MEFISTO_2D::Evaluate(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap) +{ + MESSAGE("StdMeshers_MEFISTO_2D::Evaluate"); + + TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD)); + + double aLen = 0.0; + int NbSeg = 0; + bool IsQuadratic = false; + bool IsFirst = true; + TopExp_Explorer exp(F,TopAbs_EDGE); + for(; exp.More(); exp.Next()) { + TopoDS_Edge E = TopoDS::Edge(exp.Current()); + MapShapeNbElemsItr anIt = aResMap.find( aMesh.GetSubMesh(E) ); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + int nbe = Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + NbSeg += nbe; + if(IsFirst) { + IsQuadratic = ( aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge] ); + IsFirst = false; + } + double a,b; + TopLoc_Location L; + Handle(Geom_Curve) C = BRep_Tool::Curve(E,L,a,b); + gp_Pnt P1; + C->D0(a,P1); + double dp = (b-a)/nbe; + for(int i=1; i<=nbe; i++) { + gp_Pnt P2; + C->D0(a+i*dp,P2); + aLen += P1.Distance(P2); + P1 = P2; + } + } + if(NbSeg<1) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED, + "Submesh can not be evaluated",this)); + return false; + } + aLen = aLen/NbSeg; // middle length + + _edgeLength = Precision::Infinite(); + double tmpLength = Min( _edgeLength, aLen ); + + GProp_GProps G; + BRepGProp::SurfaceProperties(aShape,G); + double anArea = G.Mass(); + + int nbFaces = Precision::IsInfinite( tmpLength ) ? 0 : + (int)( anArea/(tmpLength*tmpLength*sqrt(3.)/4) ); + int nbNodes = (int) ( nbFaces*3 - (NbSeg-1)*2 ) / 6; + + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = epos->GetUParameter(); if ( u < umin ) umin = u; @@ -514,8 +607,31 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, // set UV uvslf[m].x = uvPt->u * scalex; uvslf[m].y = uvPt->v * scaley; - if ( uvPt->node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + switch ( uvPt->node->GetPosition()->GetTypeOfPosition()) + { + case SMDS_TOP_VERTEX: mOnVertex.push_back( m ); + break; + case SMDS_TOP_EDGE: + // In order to detect degenerated faces easily, we replace + // nodes on a degenerated edge by node on the vertex of that edge + if ( myTool->IsDegenShape( uvPt->node->getshapeId() )) + { + int edgeID = uvPt->node->getshapeId(); + SMESH_subMesh* edgeSM = myTool->GetMesh()->GetSubMeshContaining( edgeID ); + SMESH_subMeshIteratorPtr smIt = edgeSM->getDependsOnIterator( /*includeSelf=*/0, + /*complexShapeFirst=*/0); + if ( smIt->more() ) + { + SMESH_subMesh* vertexSM = smIt->next(); + SMDS_NodeIteratorPtr nIt = vertexSM->GetSubMeshDS()->GetNodes(); + if ( nIt->more() ) + mefistoToDS[m] = nIt->next(); + } + } + break; + default:; + } m++; } @@ -526,7 +642,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, int m = *mIt; if ( iW && !VWMap.IsEmpty()) { // except outer wire // avoid passing same uv point for a vertex common to 2 wires - int vID = mefistoToDS[m]->GetPosition()->GetShapeId(); + int vID = mefistoToDS[m]->getshapeId(); TopoDS_Vertex V = TopoDS::Vertex( myTool->GetMeshDS()->IndexToShape( vID )); if ( fixCommonVertexUV( uvslf[m], V, F, VWMap, *myTool->GetMesh(), scalex, scaley, _quadraticMesh )) { @@ -542,6 +658,9 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector & wires, fixOverlappedLinkUV (uvslf[ mB ], uvslf[ m ], uvslf[ mA ]); } } +// cout << "MEFISTO INPUT************" << endl; +// for ( int i =0; i < m; ++i ) +// cout << i << ": \t" << uvslf[i].x << ", " << uvslf[i].y << " Node " << mefistoToDS[i]->GetID()<< endl; return true; } @@ -688,13 +807,17 @@ void StdMeshers_MEFISTO_2D::StoreResult(Z nbst, R2 * uvst, Z nbt, Z * nust, const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] - 1 ]; const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] - 1 ]; - SMDS_MeshElement * elt; - if (triangleIsWellOriented) - elt = myTool->AddFace(n1, n2, n3); - else - elt = myTool->AddFace(n1, n3, n2); - - meshDS->SetMeshElementOnShape(elt, faceID); + // avoid creating degenetrated faces + bool isDegen = ( myTool->HasDegeneratedEdges() && ( n1 == n2 || n1 == n3 || n2 == n3 )); + if ( !isDegen ) + { + SMDS_MeshElement * elt; + if (triangleIsWellOriented) + elt = myTool->AddFace(n1, n2, n3); + else + elt = myTool->AddFace(n1, n3, n2); + meshDS->SetMeshElementOnShape(elt, faceID); + } m++; } diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx index fba4b2d34..0dce86135 100644 --- a/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx +++ b/src/StdMeshers/StdMeshers_MEFISTO_2D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MEFISTO_2D.hxx // Moved here from SMESH_MEFISTO_2D.hxx @@ -55,25 +56,28 @@ public: SMESH_Hypothesis::Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); typedef boost::shared_ptr< StdMeshers_FaceSide> StdMeshers_FaceSidePtr; typedef std::vector< StdMeshers_FaceSidePtr > TWireVector; bool LoadPoints(TWireVector & wires, - R2* uvslf, - std::vector< const SMDS_MeshNode*>& mefistoToDS, + 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); + const TopoDS_Face& aFace, + double& scalex, + double& scaley); void StoreResult (Z nbst, R2* uvst, Z nbt, Z* nust, - std::vector< const SMDS_MeshNode*>& mefistoToDS, + std::vector< const SMDS_MeshNode*>& mefistoToDS, double scalex, double scaley); - + protected: double _edgeLength; double _maxElementArea; diff --git a/src/StdMeshers/StdMeshers_MaxElementArea.cxx b/src/StdMeshers/StdMeshers_MaxElementArea.cxx index 36e40e172..e42dd783c 100644 --- a/src/StdMeshers/StdMeshers_MaxElementArea.cxx +++ b/src/StdMeshers/StdMeshers_MaxElementArea.cxx @@ -1,31 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MaxElementArea.cxx // Moved here from SMESH_MaxElementArea.cxx // Author : Paul RASCLE, EDF // Module : SMESH // - #include "StdMeshers_MaxElementArea.hxx" #include "SMESH_ControlsDef.hxx" @@ -195,6 +195,6 @@ bool StdMeshers_MaxElementArea::SetParametersByMesh(const SMESH_Mesh* theMesh, bool StdMeshers_MaxElementArea::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*theMesh*/) { - return bool( _maxArea = dflts._elemLength*dflts._elemLength ); + return ( _maxArea = dflts._elemLength*dflts._elemLength ); } diff --git a/src/StdMeshers/StdMeshers_MaxElementArea.hxx b/src/StdMeshers/StdMeshers_MaxElementArea.hxx index 095067363..f7ea305ad 100644 --- a/src/StdMeshers/StdMeshers_MaxElementArea.hxx +++ b/src/StdMeshers/StdMeshers_MaxElementArea.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MaxElementArea.hxx // Moved here from SMESH_MaxElementArea.hxx diff --git a/src/StdMeshers/StdMeshers_MaxElementVolume.cxx b/src/StdMeshers/StdMeshers_MaxElementVolume.cxx index 435213aad..b70bdfa52 100644 --- a/src/StdMeshers/StdMeshers_MaxElementVolume.cxx +++ b/src/StdMeshers/StdMeshers_MaxElementVolume.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MaxElementVolume.cxx // Moved here from SMESH_MaxElementVolume.cxx @@ -206,6 +207,6 @@ bool StdMeshers_MaxElementVolume::SetParametersByMesh(const SMESH_Mesh* theMes bool StdMeshers_MaxElementVolume::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*theMesh*/) { - return bool( _maxVolume = dflts._elemLength*dflts._elemLength*dflts._elemLength ); + return ( _maxVolume = dflts._elemLength*dflts._elemLength*dflts._elemLength ); } diff --git a/src/StdMeshers/StdMeshers_MaxElementVolume.hxx b/src/StdMeshers/StdMeshers_MaxElementVolume.hxx index 6395fd419..27d332b32 100644 --- a/src/StdMeshers/StdMeshers_MaxElementVolume.hxx +++ b/src/StdMeshers/StdMeshers_MaxElementVolume.hxx @@ -1,30 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MaxElementVolume.hxx // Moved here from SMESH_MaxElementVolume.hxx // Author : Paul RASCLE, EDF // Module : SMESH - +// #ifndef _SMESH_MAXELEMENTVOLUME_HXX_ #define _SMESH_MAXELEMENTVOLUME_HXX_ diff --git a/src/StdMeshers/StdMeshers_MaxLength.cxx b/src/StdMeshers/StdMeshers_MaxLength.cxx index 475e56ae5..9597001f5 100644 --- a/src/StdMeshers/StdMeshers_MaxLength.cxx +++ b/src/StdMeshers/StdMeshers_MaxLength.cxx @@ -1,27 +1,26 @@ -// SMESH SMESH : implementaion of SMESH idl descriptions +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 // + +// SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MaxLength.cxx // Module : SMESH - +// #include "StdMeshers_MaxLength.hxx" #include "SMESH_Mesh.hxx" @@ -208,7 +207,7 @@ bool StdMeshers_MaxLength::SetParametersByMesh(const SMESH_Mesh* theMesh, { const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE )); Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax ); - GeomAdaptor_Curve AdaptCurve(C); + GeomAdaptor_Curve AdaptCurve(C, UMin, UMax); vector< double > params; SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS(); @@ -237,6 +236,6 @@ bool StdMeshers_MaxLength::SetParametersByDefaults(const TDefaults& dflts, //_preestimation = ( dflts._elemLength > 0.); if ( dflts._elemLength > 0. ) _preestimated = dflts._elemLength; - return bool( _length = dflts._elemLength ); + return ( _length = dflts._elemLength ); } diff --git a/src/StdMeshers/StdMeshers_MaxLength.hxx b/src/StdMeshers/StdMeshers_MaxLength.hxx index 23d94a9f2..7ea21e110 100644 --- a/src/StdMeshers/StdMeshers_MaxLength.hxx +++ b/src/StdMeshers/StdMeshers_MaxLength.hxx @@ -1,27 +1,26 @@ -// SMESH SMESH : implementaion of SMESH idl descriptions +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 +// +// SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_MaxLength.hxx // Module : SMESH - +// #ifndef _SMESH_MaxLength_HXX_ #define _SMESH_MaxLength_HXX_ diff --git a/src/StdMeshers/StdMeshers_NotConformAllowed.cxx b/src/StdMeshers/StdMeshers_NotConformAllowed.cxx index 66c58f13c..54a986b06 100644 --- a/src/StdMeshers/StdMeshers_NotConformAllowed.cxx +++ b/src/StdMeshers/StdMeshers_NotConformAllowed.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of SMESH idl descriptions // File : StdMeshers_NotConformAllowed.cxx // Author : Paul RASCLE, EDF diff --git a/src/StdMeshers/StdMeshers_NotConformAllowed.hxx b/src/StdMeshers/StdMeshers_NotConformAllowed.hxx index ddcfcb445..d52574b59 100644 --- a/src/StdMeshers/StdMeshers_NotConformAllowed.hxx +++ b/src/StdMeshers/StdMeshers_NotConformAllowed.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of SMESH idl descriptions // File : StdMeshers_NotConformAllowed.hxx // Author : Paul RASCLE, EDF diff --git a/src/StdMeshers/StdMeshers_NumberOfLayers.cxx b/src/StdMeshers/StdMeshers_NumberOfLayers.cxx index 604ee185a..9026f2252 100644 --- a/src/StdMeshers/StdMeshers_NumberOfLayers.cxx +++ b/src/StdMeshers/StdMeshers_NumberOfLayers.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_NumberOfLayers.cxx // Author : Edward AGAPOV @@ -171,7 +172,7 @@ bool StdMeshers_NumberOfLayers::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh) { if ( dflts._elemLength ) - return bool( theMesh ? _nbLayers = int( theMesh->GetShapeDiagonalSize() / dflts._elemLength/ 2.) : 0); + return theMesh ? (_nbLayers = int( theMesh->GetShapeDiagonalSize() / dflts._elemLength/ 2.)) : 0; return false; } diff --git a/src/StdMeshers/StdMeshers_NumberOfLayers.hxx b/src/StdMeshers/StdMeshers_NumberOfLayers.hxx index ebaae84a9..dc7d60cde 100644 --- a/src/StdMeshers/StdMeshers_NumberOfLayers.hxx +++ b/src/StdMeshers/StdMeshers_NumberOfLayers.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_NumberOfLayers.hxx // Author : Edward AGAPOV diff --git a/src/StdMeshers/StdMeshers_NumberOfLayers2D.cxx b/src/StdMeshers/StdMeshers_NumberOfLayers2D.cxx new file mode 100644 index 000000000..776c42f7b --- /dev/null +++ b/src/StdMeshers/StdMeshers_NumberOfLayers2D.cxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : idl implementation based on 'SMESH' unit's classes +// File : StdMeshers_NumberOfLayers2D.cxx +// Author : Edward AGAPOV +// Module : SMESH +// +#include "StdMeshers_NumberOfLayers2D.hxx" + +#include "utilities.h" + + +//============================================================================= +/*! + * StdMeshers_NumberOfLayers2D::StdMeshers_NumberOfLayers2D + * + * Constructor + */ +//============================================================================= + +StdMeshers_NumberOfLayers2D::StdMeshers_NumberOfLayers2D(int hypId, + int studyId, + SMESH_Gen * gen) + : StdMeshers_NumberOfLayers(hypId, studyId, gen) +{ + _name = "NumberOfLayers2D"; // used by RadialQuadrangle_1D2D + _param_algo_dim = 2; // 2D + _nbLayers = 1; +} + +//============================================================================= +/*! + * StdMeshers_NumberOfLayers2D::~StdMeshers_NumberOfLayers2D + * + * Destructor + */ +//============================================================================= + +StdMeshers_NumberOfLayers2D::~StdMeshers_NumberOfLayers2D() +{ + MESSAGE( "StdMeshers_NumberOfLayers2D::~StdMeshers_NumberOfLayers2D" ); +} + diff --git a/src/StdMeshers/StdMeshers_NumberOfLayers2D.hxx b/src/StdMeshers/StdMeshers_NumberOfLayers2D.hxx new file mode 100644 index 000000000..eef7395eb --- /dev/null +++ b/src/StdMeshers/StdMeshers_NumberOfLayers2D.hxx @@ -0,0 +1,52 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_NumberOfLayers2D.hxx +// Author : Edward AGAPOV +// Module : SMESH +// +#ifndef _SMESH_NumberOfLayers2D_HXX_ +#define _SMESH_NumberOfLayers2D_HXX_ + +#include "StdMeshers_NumberOfLayers.hxx" + + +// ========================================================= +// ========================================================= +/*! + * This hypothesis is used by "Radial quadrangle" algorithm. + * It specifies number of segments between the internal + * and the external surfaces. + */ +// ========================================================= +// ========================================================= + +class STDMESHERS_EXPORT StdMeshers_NumberOfLayers2D + : public StdMeshers_NumberOfLayers +{ +public: + // Constructor + StdMeshers_NumberOfLayers2D(int hypId, int studyId, SMESH_Gen* gen); + // Destructor + virtual ~StdMeshers_NumberOfLayers2D(); +}; + +#endif + diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx index 90c50a0bb..d9d1362d0 100644 --- a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_NumberOfSegments.cxx // Moved here from SMESH_NumberOfSegments.cxx @@ -30,6 +31,7 @@ #include "StdMeshers_Distribution.hxx" #include "SMESHDS_SubMesh.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_Comment.hxx" #include #include @@ -49,6 +51,8 @@ #include #endif +#include + using namespace std; const double PRECISION = 1e-7; @@ -233,11 +237,11 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector& table) #ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; #endif - val = pow( 10.0, val ); + val = pow( 10.0, val ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - throw SALOME_Exception( LOCALIZED( "invalid value")); - return; + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + throw SALOME_Exception( LOCALIZED( "invalid value")); + return; } } else if( _convMode==1 && val<0.0 ) @@ -303,7 +307,7 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr ) if( !name.IsNull() ) { if( name->GetName()!="t" ) - res = false; + res = false; } else res = isCorrectArg( sub ); @@ -317,10 +321,12 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr ) */ //================================================================================ bool process( const TCollection_AsciiString& str, int convMode, - bool& syntax, bool& args, - bool& non_neg, bool& non_zero, - bool& singulars, double& sing_point ) + bool& syntax, bool& args, + bool& non_neg, bool& non_zero, + bool& singulars, double& sing_point ) { + Kernel_Utils::Localizer loc; + bool parsed_ok = true; Handle( ExprIntrp_GenExp ) myExpr; try { @@ -359,19 +365,20 @@ bool process( const TCollection_AsciiString& str, int convMode, double t = double(i)/double(max), val; if( !f.value( t, val ) ) { - sing_point = t; - singulars = true; - break; + sing_point = t; + singulars = true; + break; } if( val<0 ) { - non_neg = false; - break; + non_neg = false; + break; } if( val>PRECISION ) - non_zero = true; + non_zero = true; } } + return res && non_neg && non_zero && ( !singulars ); } @@ -388,8 +395,27 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr) _distrType = DT_ExprFunc; //throw SALOME_Exception(LOCALIZED("not an expression function distribution")); + string func = CheckExpressionFunction( expr, _convMode ); + if( _func != func ) + { + _func = func; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : CheckExpressionFunction +//purpose : Checks validity of the expression of the function f(t), e.g. "sin(t)". +// In case of validity returns a cleaned expression +//======================================================================= + +std::string +StdMeshers_NumberOfSegments::CheckExpressionFunction( const std::string& expr, + const int convMode) + throw (SALOME_Exception) +{ // remove white spaces - TCollection_AsciiString str((Standard_CString)expr); + TCollection_AsciiString str((Standard_CString)expr.c_str()); str.RemoveAll(' '); str.RemoveAll('\t'); str.RemoveAll('\r'); @@ -397,15 +423,15 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr) bool syntax, args, non_neg, singulars, non_zero; double sing_point; - bool res = process( str, _convMode, syntax, args, non_neg, non_zero, singulars, sing_point ); + bool res = process( str, convMode, syntax, args, non_neg, non_zero, singulars, sing_point ); if( !res ) { if( !syntax ) - throw SALOME_Exception(LOCALIZED("invalid expression syntax")); + throw SALOME_Exception(SMESH_Comment("invalid expression syntax: ") << str ); if( !args ) throw SALOME_Exception(LOCALIZED("only 't' may be used as function argument")); if( !non_neg ) - throw SALOME_Exception(LOCALIZED("only non-negative function can be used as density")); + throw SALOME_Exception(LOCALIZED("only non-negative function can be used")); if( singulars ) { char buf[1024]; @@ -413,17 +439,10 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr) throw SALOME_Exception( buf ); } if( !non_zero ) - throw SALOME_Exception(LOCALIZED("f(t)=0 cannot be used as density")); - - return; - } - - string func = expr; - if( _func != func ) - { - _func = func; - NotifySubMeshesHypothesisModification(); + throw SALOME_Exception(LOCALIZED("f(t)=0 cannot be used")); } + + return str.ToCString(); } //================================================================================ @@ -481,6 +500,7 @@ int StdMeshers_NumberOfSegments::ConversionMode() const ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save) { + int listSize = _edgeIDs.size(); save << _numberOfSegments << " " << (int)_distrType; switch (_distrType) { @@ -503,6 +523,13 @@ ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save) if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc) save << " " << _convMode; + + if ( _distrType != DT_Regular && listSize > 0 ) { + save << " " << listSize; + for ( int i = 0; i < listSize; i++ ) + save << " " << _edgeIDs[i]; + save << " " << _objEntry; + } return save; } @@ -619,6 +646,18 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load) load.clear(ios::badbit | load.rdstate()); } + // load reversed edges IDs + int intVal; + isOK = (load >> intVal); + if ( isOK && _distrType != DT_Regular && intVal > 0 ) { + _edgeIDs.reserve( intVal ); + for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) { + isOK = (load >> intVal); + if ( isOK ) _edgeIDs.push_back( intVal ); + } + isOK = (load >> _objEntry); + } + return load; } @@ -692,6 +731,21 @@ bool StdMeshers_NumberOfSegments::SetParametersByMesh(const SMESH_Mesh* theMes bool StdMeshers_NumberOfSegments::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*theMesh*/) { - return bool(_numberOfSegments = dflts._nbSegments ); + return (_numberOfSegments = dflts._nbSegments ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_NumberOfSegments::SetReversedEdges( std::vector& ids ) +{ + if ( ids != _edgeIDs ) { + _edgeIDs = ids; + + NotifySubMeshesHypothesisModification(); + } } diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.hxx b/src/StdMeshers/StdMeshers_NumberOfSegments.hxx index 1be5b9176..a232c5871 100644 --- a/src/StdMeshers/StdMeshers_NumberOfSegments.hxx +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_NumberOfSegments.hxx // Moved here from SMESH_NumberOfSegments.hxx @@ -141,6 +142,15 @@ public: const char* GetExpressionFunction() const throw (SALOME_Exception); + /*! + * \brief Checks validity of the expression of the function f(t), e.g. "sin(t)". + * In case of validity returns a cleaned expression + * \param convMode - 0 for "Exponent mode", 1 for "Cut negative mode" + */ + static std::string CheckExpressionFunction( const std::string& expr, + const int convMode) + throw (SALOME_Exception); + /*! * \brief Set conversion mode. When it is 0, it means "exponent mode": * the function of distribution of density is used as an exponent of 10, i,e, 10^f(t). @@ -161,6 +171,13 @@ public: int ConversionMode() const throw (SALOME_Exception); + void SetReversedEdges( std::vector& ids); + + void SetObjectEntry( const char* entry ) { _objEntry = entry; } + + const char* GetObjectEntry() { return _objEntry.c_str(); } + + const std::vector& GetReversedEdges() const { return _edgeIDs; } /*! * \brief Initialize number of segments by the mesh built on the geometry @@ -188,6 +205,8 @@ protected: std::vector _table, _distr; //!< the table for DT_TabFunc, a sequence of pairs of numbers std::string _func; //!< the expression of the function for DT_ExprFunc int _convMode; //!< flag of conversion mode: 0=exponent, 1=cut negative + std::vector _edgeIDs; //!< list of reversed edges ids + std::string _objEntry; //!< Entry of the main object to reverse edges }; #endif diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx index 93bb7fd5c..29c935a64 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.cxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers_Penta_3D implementaion of SMESH idl descriptions // File : StdMeshers_Penta_3D.cxx // Module : SMESH @@ -34,7 +35,7 @@ #include "SMDS_VolumeTool.hxx" #include "SMESHDS_SubMesh.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" #include "SMESH_Comment.hxx" @@ -46,6 +47,8 @@ #include #include #include +#include +#include #include #include #include @@ -67,7 +70,7 @@ enum { NB_WALL_FACES = 4 }; //purpose : //======================================================================= StdMeshers_Penta_3D::StdMeshers_Penta_3D() -: myErrorStatus(SMESH_ComputeError::New()) + : myErrorStatus(SMESH_ComputeError::New()) { myTol3D=0.1; myWallNodesMaps.resize( SMESH_Block::NbFaces() ); @@ -89,7 +92,7 @@ StdMeshers_Penta_3D::~StdMeshers_Penta_3D() //purpose : //======================================================================= bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) + const TopoDS_Shape& aShape) { MESSAGE("StdMeshers_Penta_3D::Compute()"); // @@ -103,10 +106,6 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, return bOK; } - SMESH_MesherHelper helper(aMesh); - myTool = &helper; - myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape); - // MakeBlock(); if (!myErrorStatus->IsOK()) { @@ -117,6 +116,12 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, if (!myErrorStatus->IsOK()) { return bOK; } + + // now unnecessary faces removed, we can load medium nodes + SMESH_MesherHelper helper(aMesh); + myTool = &helper; + myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape); + // MakeNodes(); if (!myErrorStatus->IsOK()) { @@ -230,7 +235,7 @@ void StdMeshers_Penta_3D::MakeNodes() // if ( SMESH_Block::IsEdgeID (aSID)) { const SMDS_EdgePosition* epos = - static_cast(aNode->GetPosition().get()); + static_cast(aNode->GetPosition()); myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords ); } else { @@ -258,11 +263,11 @@ void StdMeshers_Penta_3D::MakeNodes() SMESH_Block::TShapeID wallFaceID[ NB_WALL_FACES ] = { SMESH_Block::ID_Fx0z, SMESH_Block::ID_Fx1z, SMESH_Block::ID_F0yz, SMESH_Block::ID_F1yz - }; + }; SMESH_Block::TShapeID baseEdgeID[ NB_WALL_FACES ] = { SMESH_Block::ID_Ex00, SMESH_Block::ID_Ex10, SMESH_Block::ID_E0y0, SMESH_Block::ID_E1y0 - }; + }; for ( i = 0; i < NB_WALL_FACES ; ++i ) { int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ i ]); bool ok = LoadIJNodes (myWallNodesMaps[ fIndex ], @@ -420,7 +425,7 @@ void StdMeshers_Penta_3D::MakeNodes() ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID); if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); - return; + return; } // aTN.SetShapeSupportID(aSSID); @@ -428,13 +433,13 @@ void StdMeshers_Penta_3D::MakeNodes() aTN.SetBaseNodeID(iBNID); // if (aSSID!=SMESH_Block::ID_NONE){ - // try to find the node - const TopoDS_Shape& aS=myBlock.Shape((int)aSSID); - FindNodeOnShape(aS, aCoords, i, aTN); + // try to find the node + const TopoDS_Shape& aS=myBlock.Shape((int)aSSID); + FindNodeOnShape(aS, aCoords, i, aTN); } else{ - // create node and get it id - CreateNode (bIsUpperLayer, aCoords, aTN); + // create node and get its id + CreateNode (bIsUpperLayer, aCoords, aTN); // if ( bIsUpperLayer ) { const SMDS_MeshNode* n = aTN.Node(); @@ -467,39 +472,12 @@ void StdMeshers_Penta_3D::MakeNodes() } if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeNodes() "); - return; + return; } // myTNodes[ij]=aTN; } } - //DEB - /* - { - int iSSID, iBNID, aID; - // - for (i=0; iGetID(); - aX=aNode->X(); - aY=aNode->Y(); - aZ=aNode->Z(); - printf("*** j:%d BNID#%d iSSID:%d ID:%d { %lf %lf %lf }, { %lf %lf %lf }\n", - j, iBNID, iSSID, aID, aXYZ.X(), aXYZ.Y(), aXYZ.Z(), aX, aY, aZ); - } - } - } - */ - //DEB t } @@ -509,9 +487,9 @@ void StdMeshers_Penta_3D::MakeNodes() //======================================================================= void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, - const gp_XYZ& aParams, + const gp_XYZ& aParams, const int z, - StdMeshers_TNode& aTN) + StdMeshers_TNode& aTN) { double aX, aY, aZ, aD, aTol2, minD; gp_Pnt aP1, aP2; @@ -630,16 +608,16 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ& aBase } else { // this variant is better for other cases -// SMESH_MesherHelper helper( *GetMesh() ); -// const TopoDS_Edge & edge = TopoDS::Edge( myBlock.Shape( edgeVec[ TOP ])); -// double u1 = helper.GetNodeU( edge, n1 ); -// double u2 = helper.GetNodeU( edge, n2 ); -// double u = ( 1. - r ) * u1 + r * u2; -// gp_XYZ topNodeParams; -// myBlock.Block().EdgeParameters( edgeVec[ TOP ], u, topNodeParams ); -// myBlock.Block().EdgePoint( edgeVec[ TOP ], -// topNodeParams, -// myShapeXYZ[ edgeVec[ TOP ]]); + // SMESH_MesherHelper helper( *GetMesh() ); + // const TopoDS_Edge & edge = TopoDS::Edge( myBlock.Shape( edgeVec[ TOP ])); + // double u1 = helper.GetNodeU( edge, n1 ); + // double u2 = helper.GetNodeU( edge, n2 ); + // double u = ( 1. - r ) * u1 + r * u2; + // gp_XYZ topNodeParams; + // myBlock.Block().EdgeParameters( edgeVec[ TOP ], u, topNodeParams ); + // myBlock.Block().EdgePoint( edgeVec[ TOP ], + // topNodeParams, + // myShapeXYZ[ edgeVec[ TOP ]]); } // base edge @@ -671,8 +649,8 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() const StdMeshers_TNode& aTN = myTNodes[ij]; aSSID=aTN.ShapeSupportID(); if (aSSID==SMESH_Block::ID_NONE) { - SMDS_MeshNode* aNode = (SMDS_MeshNode*)aTN.Node(); - meshDS->SetNodeInVolume(aNode, shapeID); + SMDS_MeshNode* aNode = (SMDS_MeshNode*)aTN.Node(); + meshDS->SetNodeInVolume(aNode, shapeID); } } } @@ -698,22 +676,16 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() if ( aN.size() < nbFaceNodes * 2 ) aN.resize( nbFaceNodes * 2 ); // - k=0; - aItNodes=pE0->nodesIterator(); - while (aItNodes->more()) { - //const SMDS_MeshElement* pNode = aItNodes->next(); - const SMDS_MeshNode* pNode = - static_cast (aItNodes->next()); - if(myTool->IsMedium(pNode)) - continue; + for ( k=0; kGetNode(k); +// if(myTool->IsMedium(pNode)) +// continue; aID0 = pNode->GetID(); aJ[k] = GetIndexOnLayer(aID0); if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh"); - return; + return; } - // - ++k; } // bool forward = true; @@ -721,15 +693,15 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() i1=i; i2=i+1; for(j=0; jGetMeshDS(); @@ -820,7 +790,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() itn = aSM0->GetNodes(); aNbNodes = aSM0->NbNodes(); //printf("** aNbNodes=%d\n", aNbNodes); - + myTool->SetSubShape( aFxy1 ); // to set medium nodes to aFxy1 // // set elements on aFxy1 vector aNodes1; @@ -849,7 +819,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() aJ = GetIndexOnLayer(aID0); if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); - return; + return; } // ij = aLevel*myJSize + aJ; @@ -861,16 +831,17 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() SMDS_MeshFace * face = 0; switch ( aNbNodes ) { case 3: - face = faceHelper.AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); + face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); break; case 4: - face = faceHelper.AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); + face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); break; default: continue; } meshDS->SetMeshElementOnShape(face, aFxy1); } + myTool->SetSubShape( myShape ); // update compute state of top face submesh aSubMesh1->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); @@ -878,7 +849,8 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1() // assure that mesh on the top face will be cleaned when it is cleaned // on the bottom face SMESH_subMesh* volSM = pMesh->GetSubMesh( myTool->GetSubShape() ); - volSM->SetEventListener( new SMESH_subMeshEventListener(true), + volSM->SetEventListener( new SMESH_subMeshEventListener(true, // deletable by SMESH_subMesh + "StdMeshers_Penta_3D"), SMESH_subMeshEventListenerData::MakeData( aSubMesh1 ), aSubMesh0 ); // translate CLEAN event of aSubMesh0 to aSubMesh1 } @@ -937,8 +909,8 @@ void StdMeshers_Penta_3D::MakeConnectingMap() //purpose : //======================================================================= void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, - const gp_XYZ& aParams, - StdMeshers_TNode& aTN) + const gp_XYZ& aParams, + StdMeshers_TNode& aTN) { double aX, aY, aZ; // @@ -947,15 +919,15 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, SMDS_MeshNode* pNode=NULL; aTN.SetNode(pNode); // -// if (bIsUpperLayer) { -// // point on face Fxy1 -// const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_Fxy1); -// myBlock.Point(aParams, aS, aP); -// } -// else { -// // point inside solid -// myBlock.Point(aParams, aP); -// } + // if (bIsUpperLayer) { + // // point on face Fxy1 + // const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_Fxy1); + // myBlock.Point(aParams, aS, aP); + // } + // else { + // // point inside solid + // myBlock.Point(aParams, aP); + // } if (bIsUpperLayer) { double u = aParams.X(), v = aParams.Y(); double u1 = ( 1. - u ), v1 = ( 1. - v ); @@ -973,11 +945,11 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() ); } // -// iErr=myBlock.ErrorStatus(); -// if (iErr) { -// myErrorStatus=12; // can not find the node point; -// return; -// } + // iErr=myBlock.ErrorStatus(); + // if (iErr) { + // myErrorStatus=12; // can not find the node point; + // return; + // } // aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); // @@ -985,7 +957,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, SMESHDS_Mesh* pMeshDS = pMesh->GetMeshDS(); // pNode = pMeshDS->AddNode(aX, aY, aZ); - + aTN.SetNode(pNode); } @@ -994,42 +966,42 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer, //purpose : //======================================================================= void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer, - const SMESH_Block::TShapeID aBNSSID, - SMESH_Block::TShapeID& aSSID) + const SMESH_Block::TShapeID aBNSSID, + SMESH_Block::TShapeID& aSSID) { switch (aBNSSID) { - case SMESH_Block::ID_V000: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V001 : SMESH_Block::ID_E00z; - break; - case SMESH_Block::ID_V100: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V101 : SMESH_Block::ID_E10z; - break; - case SMESH_Block::ID_V110: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V111 : SMESH_Block::ID_E11z; - break; - case SMESH_Block::ID_V010: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V011 : SMESH_Block::ID_E01z; - break; - case SMESH_Block::ID_Ex00: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z; - break; - case SMESH_Block::ID_Ex10: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z; - break; - case SMESH_Block::ID_E0y0: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz; - break; - case SMESH_Block::ID_E1y0: - aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz; - break; - case SMESH_Block::ID_Fxy0: - aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ? Shape_ID_Fxy1 : Shape_ID_NONE; - break; - default: - aSSID=SMESH_Block::ID_NONE; - myErrorStatus->myName=10; // Can not find supporting shape ID - myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D"; - break; + case SMESH_Block::ID_V000: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V001 : SMESH_Block::ID_E00z; + break; + case SMESH_Block::ID_V100: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V101 : SMESH_Block::ID_E10z; + break; + case SMESH_Block::ID_V110: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V111 : SMESH_Block::ID_E11z; + break; + case SMESH_Block::ID_V010: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V011 : SMESH_Block::ID_E01z; + break; + case SMESH_Block::ID_Ex00: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z; + break; + case SMESH_Block::ID_Ex10: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z; + break; + case SMESH_Block::ID_E0y0: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz; + break; + case SMESH_Block::ID_E1y0: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz; + break; + case SMESH_Block::ID_Fxy0: + aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ? Shape_ID_Fxy1 : Shape_ID_NONE; + break; + default: + aSSID=SMESH_Block::ID_NONE; + myErrorStatus->myName=10; // Can not find supporting shape ID + myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D"; + break; } return; } @@ -1066,25 +1038,25 @@ void StdMeshers_Penta_3D::MakeBlock() const SMDS_MeshElement * pElement = itf->next(); aElementType = pElement->GetType(); if (aElementType==SMDSAbs_Face) { - iNbNodes = pElement->NbNodes(); - if ( iNbNodes==3 || (myCreateQuadratic && iNbNodes==6) ) { - aFTr = aF; - ++iCnt; - if (iCnt>1) { - // \begin{E.A.} - // The current algorithm fails if there is more that one - // face wich contains triangles ... - // In that case, replace return by break to try another - // method (coded in "if (iCnt != 1) { ... }") - // + iNbNodes = pElement->NbNodes(); + if ( iNbNodes==3 || (pElement->IsQuadratic() && iNbNodes==6) ) { + aFTr = aF; + ++iCnt; + if (iCnt>1) { + // \begin{E.A.} + // The current algorithm fails if there is more that one + // face wich contains triangles ... + // In that case, replace return by break to try another + // method (coded in "if (iCnt != 1) { ... }") + // // MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); - // myErrorStatus=5; // more than one face has triangulation - // return; - break; - // \end{E.A.} - } - break; // next face - } + // myErrorStatus=5; // more than one face has triangulation + // return; + break; + // \end{E.A.} + } + break; // next face + } } } } @@ -1153,85 +1125,85 @@ void StdMeshers_Penta_3D::MakeBlock() int has_only_quad_f6 = 1; // for (i=1; i<=iNbF; ++i) { - int ok = 1; - const TopoDS_Shape& aF = aM(i); - SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF); - SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); - SMDS_ElemIteratorPtr itf = aSM->GetElements(); - while(itf->more()) { - const SMDS_MeshElement * pElement = itf->next(); - aElementType = pElement->GetType(); - if (aElementType==SMDSAbs_Face) { - iNbNodes = pElement->NbNodes(); - if ( iNbNodes!=4 ) { - ok = 0; - break ; - } - } - } - if (i==1) has_only_quad_f1 = ok ; - if (i==2) has_only_quad_f2 = ok ; - if (i==3) has_only_quad_f3 = ok ; - if (i==4) has_only_quad_f4 = ok ; - if (i==5) has_only_quad_f5 = ok ; - if (i==6) has_only_quad_f6 = ok ; + int ok = 1; + const TopoDS_Shape& aF = aM(i); + SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF); + SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS(); + SMDS_ElemIteratorPtr itf = aSM->GetElements(); + while(itf->more()) { + const SMDS_MeshElement * pElement = itf->next(); + aElementType = pElement->GetType(); + if (aElementType==SMDSAbs_Face) { + iNbNodes = pElement->NbNodes(); + if ( iNbNodes!=4 ) { + ok = 0; + break ; + } + } + } + if (i==1) has_only_quad_f1 = ok ; + if (i==2) has_only_quad_f2 = ok ; + if (i==3) has_only_quad_f3 = ok ; + if (i==4) has_only_quad_f4 = ok ; + if (i==5) has_only_quad_f5 = ok ; + if (i==6) has_only_quad_f6 = ok ; } // TopTools_IndexedMapOfShape aE; TopExp::MapShapes(myShape, TopAbs_EDGE, aE); int iNbE = aE.Extent(); if (iNbE == 12) { - // - int nb_e01 = pMesh->GetSubMeshContaining(aE(1))->GetSubMeshDS()->NbElements(); - int nb_e02 = pMesh->GetSubMeshContaining(aE(2))->GetSubMeshDS()->NbElements(); - int nb_e03 = pMesh->GetSubMeshContaining(aE(3))->GetSubMeshDS()->NbElements(); - int nb_e04 = pMesh->GetSubMeshContaining(aE(4))->GetSubMeshDS()->NbElements(); - int nb_e05 = pMesh->GetSubMeshContaining(aE(5))->GetSubMeshDS()->NbElements(); - int nb_e06 = pMesh->GetSubMeshContaining(aE(6))->GetSubMeshDS()->NbElements(); - int nb_e07 = pMesh->GetSubMeshContaining(aE(7))->GetSubMeshDS()->NbElements(); - int nb_e08 = pMesh->GetSubMeshContaining(aE(8))->GetSubMeshDS()->NbElements(); - int nb_e09 = pMesh->GetSubMeshContaining(aE(9))->GetSubMeshDS()->NbElements(); - int nb_e10 = pMesh->GetSubMeshContaining(aE(10))->GetSubMeshDS()->NbElements(); - int nb_e11 = pMesh->GetSubMeshContaining(aE(11))->GetSubMeshDS()->NbElements(); - int nb_e12 = pMesh->GetSubMeshContaining(aE(12))->GetSubMeshDS()->NbElements(); - // - int nb_ok = 0 ; - // - if ( (nb_e01==nb_e03) && (nb_e03==nb_e05) && (nb_e05==nb_e07) ) { - if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f3 && has_only_quad_f4 ) { - if ( (nb_e09==nb_e10) && (nb_e08==nb_e06) && (nb_e11==nb_e12) && (nb_e04==nb_e02) ) { - if (nb_f5==nb_f6) { - nb_ok += 1; - aFTr = aM(5); - } - } - } - } - if ( (nb_e02==nb_e04) && (nb_e04==nb_e06) && (nb_e06==nb_e08) ) { - if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f5 && has_only_quad_f6 ) { - if ( (nb_e01==nb_e03) && (nb_e10==nb_e12) && (nb_e05==nb_e07) && (nb_e09==nb_e11) ) { - if (nb_f3==nb_f4) { - nb_ok += 1; - aFTr = aM(3); - } - } - } - } - if ( (nb_e09==nb_e10) && (nb_e10==nb_e11) && (nb_e11==nb_e12) ) { - if ( has_only_quad_f3 && has_only_quad_f4 && has_only_quad_f5 && has_only_quad_f6 ) { - if ( (nb_e01==nb_e05) && (nb_e02==nb_e06) && (nb_e03==nb_e07) && (nb_e04==nb_e08) ) { - if (nb_f1==nb_f2) { - nb_ok += 1; - aFTr = aM(1); - } - } - } - } - // - if ( nb_ok == 1 ) { - isOK = 1; - } - // + // + int nb_e01 = pMesh->GetSubMeshContaining(aE(1))->GetSubMeshDS()->NbElements(); + int nb_e02 = pMesh->GetSubMeshContaining(aE(2))->GetSubMeshDS()->NbElements(); + int nb_e03 = pMesh->GetSubMeshContaining(aE(3))->GetSubMeshDS()->NbElements(); + int nb_e04 = pMesh->GetSubMeshContaining(aE(4))->GetSubMeshDS()->NbElements(); + int nb_e05 = pMesh->GetSubMeshContaining(aE(5))->GetSubMeshDS()->NbElements(); + int nb_e06 = pMesh->GetSubMeshContaining(aE(6))->GetSubMeshDS()->NbElements(); + int nb_e07 = pMesh->GetSubMeshContaining(aE(7))->GetSubMeshDS()->NbElements(); + int nb_e08 = pMesh->GetSubMeshContaining(aE(8))->GetSubMeshDS()->NbElements(); + int nb_e09 = pMesh->GetSubMeshContaining(aE(9))->GetSubMeshDS()->NbElements(); + int nb_e10 = pMesh->GetSubMeshContaining(aE(10))->GetSubMeshDS()->NbElements(); + int nb_e11 = pMesh->GetSubMeshContaining(aE(11))->GetSubMeshDS()->NbElements(); + int nb_e12 = pMesh->GetSubMeshContaining(aE(12))->GetSubMeshDS()->NbElements(); + // + int nb_ok = 0 ; + // + if ( (nb_e01==nb_e03) && (nb_e03==nb_e05) && (nb_e05==nb_e07) ) { + if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f3 && has_only_quad_f4 ) { + if ( (nb_e09==nb_e10) && (nb_e08==nb_e06) && (nb_e11==nb_e12) && (nb_e04==nb_e02) ) { + if (nb_f5==nb_f6) { + nb_ok += 1; + aFTr = aM(5); + } + } + } + } + if ( (nb_e02==nb_e04) && (nb_e04==nb_e06) && (nb_e06==nb_e08) ) { + if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f5 && has_only_quad_f6 ) { + if ( (nb_e01==nb_e03) && (nb_e10==nb_e12) && (nb_e05==nb_e07) && (nb_e09==nb_e11) ) { + if (nb_f3==nb_f4) { + nb_ok += 1; + aFTr = aM(3); + } + } + } + } + if ( (nb_e09==nb_e10) && (nb_e10==nb_e11) && (nb_e11==nb_e12) ) { + if ( has_only_quad_f3 && has_only_quad_f4 && has_only_quad_f5 && has_only_quad_f6 ) { + if ( (nb_e01==nb_e05) && (nb_e02==nb_e06) && (nb_e03==nb_e07) && (nb_e04==nb_e08) ) { + if (nb_f1==nb_f2) { + nb_ok += 1; + aFTr = aM(1); + } + } + } + } + // + if ( nb_ok == 1 ) { + isOK = 1; + } + // } } if (!isOK) { @@ -1284,11 +1256,11 @@ void StdMeshers_Penta_3D::MakeBlock() const TopoDS_Edge& aE=TopoDS::Edge(aEx); TopExp::Vertices(aE, aV[0], aV[1]); for (i=0; i<2; ++i) { - if (!aV[i].IsSame(aV000)) { - aV001=aV[i]; - bFound=!bFound; - break; - } + if (!aV[i].IsSame(aV000)) { + aV001=aV[i]; + bFound=!bFound; + break; + } } } } @@ -1365,8 +1337,8 @@ void StdMeshers_Penta_3D::CheckData() iNb=aM.Extent(); if (iNb!=iNbEx[i]){ MESSAGE("StdMeshers_Penta_3D::CheckData() "); - myErrorStatus->myName=4; // number of subshape is not compatible - myErrorStatus->myComment="Wrong number of subshapes of a block"; + myErrorStatus->myName=4; // number of sub-shape is not compatible + myErrorStatus->myComment="Wrong number of sub-shapes of a block"; return; } } @@ -1432,7 +1404,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, SMESHDS_SubMesh* smVft = theMesh->MeshElements( vft ); if (!smFace || !smb || !smt || !sm1 || !sm2 || !smVfb || !smVlb || !smVft ) { MESSAGE( "NULL submesh " <NbNodes() != smt->NbNodes() || sm1->NbNodes() != sm2->NbNodes() ) { @@ -1453,13 +1425,13 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4; if( nf != smFace->NbNodes() ) { MESSAGE( "Wrong nb face nodes: " << - sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); + sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); return false; } } else { MESSAGE( "Wrong nb face nodes: " << - sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); + sm1->NbNodes()<<" "<NbNodes()<<" "<NbNodes()); return false; } } @@ -1494,7 +1466,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, if(myTool->IsMedium(node)) continue; const SMDS_EdgePosition* pos = - dynamic_cast( node->GetPosition().get() ); + dynamic_cast( node->GetPosition() ); if ( !pos ) { return false; } @@ -1517,7 +1489,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, if(myTool->IsMedium(node)) continue; const SMDS_EdgePosition* pos = - dynamic_cast( node->GetPosition().get() ); + dynamic_cast( node->GetPosition() ); if ( !pos ) { return false; } @@ -1594,7 +1566,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes, } } else if ( (nbFaceNodes==3 || (myCreateQuadratic && nbFaceNodes==6) ) && - n3 == par_nVec_1->second[ row ] ) { + n3 == par_nVec_1->second[ row ] ) { n1 = n3; } else { @@ -1678,7 +1650,7 @@ SMESH_ComputeErrorPtr StdMeshers_SMESHBlock::GetError() const 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; + case 6: text = "Can't detect block sub-shapes. Not a block?"; break; } if (!text.empty()) err->myName = myErrorStatus; @@ -1701,8 +1673,8 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell) //purpose : //======================================================================= void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell, - const TopoDS_Vertex& theV000, - const TopoDS_Vertex& theV001) + const TopoDS_Vertex& theV000, + const TopoDS_Vertex& theV001) { myErrorStatus=0; // @@ -1723,7 +1695,7 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell, //purpose : //======================================================================= void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, - gp_XYZ& theXYZ) + gp_XYZ& theXYZ) { ComputeParameters(thePnt, myShell, theXYZ); } @@ -1733,7 +1705,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, //purpose : //======================================================================= void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, - const TopoDS_Shape& theShape, + const TopoDS_Shape& theShape, gp_XYZ& theXYZ) { myErrorStatus=0; @@ -1771,7 +1743,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, return; } if ( SMESH_Block::IsEdgeID( aID )) - bOk = myTBlock.EdgeParameters( aID, theU, theXYZ ); + bOk = myTBlock.EdgeParameters( aID, theU, theXYZ ); if (!bOk) { myErrorStatus=4; // problems with computation Parameters return; @@ -1782,8 +1754,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, //function : Point //purpose : //======================================================================= - void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, - gp_Pnt& aP3D) +void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, gp_Pnt& aP3D) { TopoDS_Shape aS; // @@ -1794,9 +1765,9 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU, //function : Point //purpose : //======================================================================= - void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, - const TopoDS_Shape& theShape, - gp_Pnt& aP3D) +void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, + const TopoDS_Shape& theShape, + gp_Pnt& aP3D) { myErrorStatus = 0; // @@ -1882,3 +1853,112 @@ const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID) } +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= +bool StdMeshers_Penta_3D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + MESSAGE("StdMeshers_Penta_3D::Evaluate()"); + + // find face contains only triangles + vector < SMESH_subMesh * >meshFaces; + TopTools_SequenceOfShape aFaces; + int NumBase = 0, i = 0; + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { + i++; + aFaces.Append(exp.Current()); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); + meshFaces.push_back(aSubMesh); + MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]); + if( anIt == aResMap.end() ) { + NumBase = 0; + break; + } + std::vector aVec = (*anIt).second; + int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + int nbqua = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + if( nbtri>0 && nbqua==0 ) { + NumBase = i; + } + } + + if(NumBase==0) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; imyName = COMPERR_ALGO_FAILED; + myErrorStatus->myComment = "Submesh can not be evaluated"; + return false; + } + + // find number of 1d elems for base face + int nb1d = 0; + TopTools_MapOfShape Edges1; + for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) { + Edges1.Add(exp.Current()); + SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current()); + if( sm ) { + MapShapeNbElemsItr anIt = aResMap.find(sm); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + } + } + // find face opposite to base face + int OppNum = 0; + for(i=1; i<=6; i++) { + if(i==NumBase) continue; + bool IsOpposite = true; + for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) { + if( Edges1.Contains(exp.Current()) ) { + IsOpposite = false; + break; + } + } + if(IsOpposite) { + OppNum = i; + break; + } + } + // find number of 2d elems on side faces + int nb2d = 0; + for(i=1; i<=6; i++) { + if( i==OppNum || i==NumBase ) continue; + MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] ); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + } + + MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] ); + std::vector aVec = (*anIt).second; + int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + int nb0d_face0 = aVec[SMDSEntity_Node]; + + anIt = aResMap.find( meshFaces[OppNum-1] ); + for(i=SMDSEntity_Node; i aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i > StdMeshers_IJNodeMap; @@ -57,26 +59,26 @@ public: void Load (const TopoDS_Shell& theShell); void Load (const TopoDS_Shell& theShell, - const TopoDS_Vertex& theV000, - const TopoDS_Vertex& theV001); + const TopoDS_Vertex& theV000, + const TopoDS_Vertex& theV001); void ComputeParameters(const gp_Pnt& thePnt, - gp_XYZ& theXYZ); + gp_XYZ& theXYZ); void ComputeParameters(const gp_Pnt& thePnt, - const TopoDS_Shape& theShape, - gp_XYZ& theXYZ); + const TopoDS_Shape& theShape, + gp_XYZ& theXYZ); void ComputeParameters(const double& theU, - const TopoDS_Shape& theShape, - gp_XYZ& theXYZ); + const TopoDS_Shape& theShape, + gp_XYZ& theXYZ); void Point(const gp_XYZ& theParams, - gp_Pnt& thePnt); + gp_Pnt& thePnt); void Point(const gp_XYZ& theParams, - const TopoDS_Shape& theShape, - gp_Pnt& thePnt); + const TopoDS_Shape& theShape, + gp_Pnt& thePnt); int ShapeID(const TopoDS_Shape& theShape); @@ -204,6 +206,9 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D { // The key of theIJNodes map is a normalized parameter of each // 0-the node on theBaseEdge. + bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + protected: // methods @@ -219,17 +224,17 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D { std::vector*& aCol2); void ShapeSupportID(const bool theIsUpperLayer, - const SMESH_Block::TShapeID theBNSSID, - SMESH_Block::TShapeID& theSSID); + const SMESH_Block::TShapeID theBNSSID, + SMESH_Block::TShapeID& theSSID); void FindNodeOnShape(const TopoDS_Shape& aS, - const gp_XYZ& aParams, + const gp_XYZ& aParams, const int z, - StdMeshers_TNode& aTN); + StdMeshers_TNode& aTN); void CreateNode(const bool theIsUpperLayer, - const gp_XYZ& aParams, - StdMeshers_TNode& aTN); + const gp_XYZ& aParams, + StdMeshers_TNode& aTN); void ClearMeshOnFxy1(); diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 2ab01d917..c4c421c80 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -1,25 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : StdMeshers_Prism_3D.cxx // Module : SMESH // Created : Fri Oct 20 11:37:07 2006 @@ -28,7 +28,7 @@ #include "StdMeshers_Prism_3D.hxx" #include "StdMeshers_ProjectionUtils.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMDS_VolumeTool.hxx" #include "SMDS_VolumeOfNodes.hxx" #include "SMDS_EdgePosition.hxx" @@ -37,12 +37,18 @@ #include "utilities.h" #include +#include #include #include +#include #include #include #include +#include +#include #include +#include +#include using namespace std; @@ -149,6 +155,152 @@ namespace { } params.push_back( parLast ); // 1. } + + //================================================================================ + /*! + * \brief Return coordinate system for z-th layer of nodes + */ + //================================================================================ + + gp_Ax2 getLayerCoordSys(const int z, + const vector< const TNodeColumn* >& columns, + int& xColumn) + { + // gravity center of a layer + gp_XYZ O(0,0,0); + int vertexCol = -1; + for ( int i = 0; i < columns.size(); ++i ) + { + O += gpXYZ( (*columns[ i ])[ z ]); + if ( vertexCol < 0 && + columns[ i ]->front()->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + vertexCol = i; + } + O /= columns.size(); + + // Z axis + gp_Vec Z(0,0,0); + int iPrev = columns.size()-1; + for ( int i = 0; i < columns.size(); ++i ) + { + gp_Vec v1( O, gpXYZ( (*columns[ iPrev ])[ z ])); + gp_Vec v2( O, gpXYZ( (*columns[ i ] )[ z ])); + Z += v1 ^ v2; + iPrev = i; + } + + if ( vertexCol >= 0 ) + { + O = gpXYZ( (*columns[ vertexCol ])[ z ]); + } + if ( xColumn < 0 || xColumn >= columns.size() ) + { + // select a column for X dir + double maxDist = 0; + for ( int i = 0; i < columns.size(); ++i ) + { + double dist = ( O - gpXYZ((*columns[ i ])[ z ])).SquareModulus(); + if ( dist > maxDist ) + { + xColumn = i; + maxDist = dist; + } + } + } + + // X axis + gp_Vec X( O, gpXYZ( (*columns[ xColumn ])[ z ])); + + return gp_Ax2( O, Z, X); + } + + //================================================================================ + /*! + * \brief Removes submeshes meshed with regular grid from given list + * \retval int - nb of removed submeshes + */ + //================================================================================ + + int removeQuasiQuads(list< SMESH_subMesh* >& notQuadSubMesh) + { + int oldNbSM = notQuadSubMesh.size(); + SMESHDS_Mesh* mesh = notQuadSubMesh.front()->GetFather()->GetMeshDS(); + list< SMESH_subMesh* >::iterator smIt = notQuadSubMesh.begin(); +#define __NEXT_SM { ++smIt; continue; } + while ( smIt != notQuadSubMesh.end() ) + { + SMESH_subMesh* faceSm = *smIt; + SMESHDS_SubMesh* faceSmDS = faceSm->GetSubMeshDS(); + int nbQuads = faceSmDS->NbElements(); + if ( nbQuads == 0 ) __NEXT_SM; + + // get oredered edges + list< TopoDS_Edge > orderedEdges; + list< int > nbEdgesInWires; + TopoDS_Vertex V000; + int nbWires = SMESH_Block::GetOrderedEdges( TopoDS::Face( faceSm->GetSubShape() ), + V000, orderedEdges, nbEdgesInWires ); + if ( nbWires != 1 || nbEdgesInWires.front() <= 4 ) + __NEXT_SM; + + // get nb of segements on edges + list nbSegOnEdge; + list< TopoDS_Edge >::iterator edge = orderedEdges.begin(); + for ( ; edge != orderedEdges.end(); ++edge ) + { + if ( SMESHDS_SubMesh* edgeSmDS = mesh->MeshElements( *edge )) + nbSegOnEdge.push_back( edgeSmDS->NbElements() ); + else + nbSegOnEdge.push_back(0); + } + + // unite nbSegOnEdge of continues edges + int nbEdges = nbEdgesInWires.front(); + list::iterator nbSegIt = nbSegOnEdge.begin(); + for ( edge = orderedEdges.begin(); edge != orderedEdges.end(); ) + { + const TopoDS_Edge& e1 = *edge++; + const TopoDS_Edge& e2 = ( edge == orderedEdges.end() ? orderedEdges.front() : *edge ); + if ( SMESH_Algo::IsContinuous( e1, e2 )) + { + // common vertex of continues edges must be shared by two 2D mesh elems of geom face + TopoDS_Vertex vCommon = TopExp::LastVertex( e1, true ); + const SMDS_MeshNode* vNode = SMESH_Algo::VertexNode( vCommon, mesh ); + int nbF = 0; + if ( vNode ) + { + SMDS_ElemIteratorPtr fIt = vNode->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + nbF += faceSmDS->Contains( fIt->next() ); + } + list::iterator nbSegIt1 = nbSegIt++; + if ( !vNode || nbF == 2 ) // !vNode - two edges can be meshed as one + { + // unite + if ( nbSegIt == nbSegOnEdge.end() ) nbSegIt = nbSegOnEdge.begin(); + *nbSegIt += *nbSegIt1; + nbSegOnEdge.erase( nbSegIt1 ); + --nbEdges; + } + } + else + { + ++nbSegIt; + } + } + vector nbSegVec( nbSegOnEdge.begin(), nbSegOnEdge.end()); + if ( nbSegVec.size() == 4 && + nbSegVec[0] == nbSegVec[2] && + nbSegVec[1] == nbSegVec[3] && + nbSegVec[0] * nbSegVec[1] == nbQuads + ) + smIt = notQuadSubMesh.erase( smIt ); + else + __NEXT_SM; + } + + return oldNbSM - notQuadSubMesh.size(); + } } //======================================================================= @@ -160,7 +312,7 @@ StdMeshers_Prism_3D::StdMeshers_Prism_3D(int hypId, int studyId, SMESH_Gen* gen) :SMESH_3D_Algo(hypId, studyId, gen) { _name = "Prism_3D"; - _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit per shape type + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit per shape type myProjectTriangles = false; } @@ -232,7 +384,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh myHelper->IsQuadraticSubMesh( theShape ); - // Analyse mesh and geomerty to find block subshapes and submeshes + // Analyse mesh and geomerty to find block sub-shapes and submeshes if ( !myBlock.Init( myHelper, theShape )) return error( myBlock.GetError()); @@ -255,75 +407,115 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh // Projections on the top and bottom faces are taken from nodes existing // on these faces; find correspondence between bottom and top nodes myBotToColumnMap.clear(); - if ( !assocOrProjBottom2Top() ) // it also fill myBotToColumnMap + if ( !assocOrProjBottom2Top() ) // it also fills myBotToColumnMap return false; // Create nodes inside the block - // loop on nodes inside the bottom face - TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin(); - for ( ; bot_column != myBotToColumnMap.end(); ++bot_column ) + // try to use transformation (issue 0020680) + vector trsf; + if ( myBlock.GetLayersTransformation(trsf)) { - const TNode& tBotNode = bot_column->first; // bottom TNode - if ( tBotNode.GetPositionType() != SMDS_TOP_FACE ) - continue; // node is not inside face - - // column nodes; middle part of the column are zero pointers - TNodeColumn& column = bot_column->second; - - // bottom node parameters and coords - myShapeXYZ[ ID_BOT_FACE ] = tBotNode.GetCoords(); - gp_XYZ botParams = tBotNode.GetParams(); - - // compute top node parameters - myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() ); - gp_XYZ topParams = botParams; - topParams.SetZ( 1 ); - if ( column.size() > 2 ) { - gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ]; - if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams )) - return error(TCom("Can't compute normalized parameters ") - << "for node " << column.back()->GetID() - << " on the face #"<< column.back()->GetPosition()->GetShapeId() ); - } + // loop on nodes inside the bottom face + TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin(); + for ( ; bot_column != myBotToColumnMap.end(); ++bot_column ) + { + const TNode& tBotNode = bot_column->first; // bottom TNode + if ( tBotNode.GetPositionType() != SMDS_TOP_FACE ) + continue; // node is not inside face + + // column nodes; middle part of the column are zero pointers + TNodeColumn& column = bot_column->second; + TNodeColumn::iterator columnNodes = column.begin(); + for ( int z = 0; columnNodes != column.end(); ++columnNodes, ++z) + { + const SMDS_MeshNode* & node = *columnNodes; + if ( node ) continue; // skip bottom or top node - // vertical loop - TNodeColumn::iterator columnNodes = column.begin(); - for ( int z = 0; columnNodes != column.end(); ++columnNodes, ++z) + gp_XYZ coords = tBotNode.GetCoords(); + trsf[z-1].Transforms( coords ); + node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() ); + meshDS->SetNodeInVolume( node, volumeID ); + } + } // loop on bottom nodes + } + else // use block approach + { + // loop on nodes inside the bottom face + TNode prevBNode; + TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin(); + for ( ; bot_column != myBotToColumnMap.end(); ++bot_column ) { - const SMDS_MeshNode* & node = *columnNodes; - if ( node ) continue; // skip bottom or top node - - // params of a node to create - double rz = (double) z / (double) ( column.size() - 1 ); - gp_XYZ params = botParams * ( 1 - rz ) + topParams * rz; - - // set coords on all faces and nodes - const int nbSideFaces = 4; - int sideFaceIDs[nbSideFaces] = { SMESH_Block::ID_Fx0z, - SMESH_Block::ID_Fx1z, - SMESH_Block::ID_F0yz, - SMESH_Block::ID_F1yz }; - for ( int iF = 0; iF < nbSideFaces; ++iF ) - if ( !setFaceAndEdgesXYZ( sideFaceIDs[ iF ], params, z )) - return false; - - // compute coords for a new node - gp_XYZ coords; - if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords )) - return error("Can't compute coordinates by normalized parameters"); - - SHOWYXZ("TOPFacePoint ",myShapeXYZ[ ID_TOP_FACE]); - SHOWYXZ("BOT Node "<< tBotNode.myNode->GetID(),gpXYZ(tBotNode.myNode)); - SHOWYXZ("ShellPoint ",coords); - - // create a node - node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() ); - meshDS->SetNodeInVolume( node, volumeID ); - } - } // loop on bottom nodes + const TNode& tBotNode = bot_column->first; // bottom TNode + if ( tBotNode.GetPositionType() != SMDS_TOP_FACE ) + continue; // node is not inside face + + // column nodes; middle part of the column are zero pointers + TNodeColumn& column = bot_column->second; + + // compute bottom node parameters + gp_XYZ paramHint(-1,-1,-1); + if ( prevBNode.IsNeighbor( tBotNode )) + paramHint = prevBNode.GetParams(); + if ( !myBlock.ComputeParameters( tBotNode.GetCoords(), tBotNode.ChangeParams(), + ID_BOT_FACE, paramHint )) + return error(TCom("Can't compute normalized parameters for node ") + << tBotNode.myNode->GetID() << " on the face #" + << myBlock.SubMesh( ID_BOT_FACE )->GetId() ); + prevBNode = tBotNode; + + myShapeXYZ[ ID_BOT_FACE ] = tBotNode.GetCoords(); + gp_XYZ botParams = tBotNode.GetParams(); + + // compute top node parameters + myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() ); + gp_XYZ topParams = botParams; + topParams.SetZ( 1 ); + if ( column.size() > 2 ) { + gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ]; + if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams )) + return error(TCom("Can't compute normalized parameters ") + << "for node " << column.back()->GetID() + << " on the face #"<< column.back()->getshapeId() ); + } + // vertical loop + TNodeColumn::iterator columnNodes = column.begin(); + for ( int z = 0; columnNodes != column.end(); ++columnNodes, ++z) + { + const SMDS_MeshNode* & node = *columnNodes; + if ( node ) continue; // skip bottom or top node + + // params of a node to create + double rz = (double) z / (double) ( column.size() - 1 ); + gp_XYZ params = botParams * ( 1 - rz ) + topParams * rz; + + // set coords on all faces and nodes + const int nbSideFaces = 4; + int sideFaceIDs[nbSideFaces] = { SMESH_Block::ID_Fx0z, + SMESH_Block::ID_Fx1z, + SMESH_Block::ID_F0yz, + SMESH_Block::ID_F1yz }; + for ( int iF = 0; iF < nbSideFaces; ++iF ) + if ( !setFaceAndEdgesXYZ( sideFaceIDs[ iF ], params, z )) + return false; + + // compute coords for a new node + gp_XYZ coords; + if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords )) + return error("Can't compute coordinates by normalized parameters"); + + SHOWYXZ("TOPFacePoint ",myShapeXYZ[ ID_TOP_FACE]); + SHOWYXZ("BOT Node "<< tBotNode.myNode->GetID(),gpXYZ(tBotNode.myNode)); + SHOWYXZ("ShellPoint ",coords); + + // create a node + node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() ); + meshDS->SetNodeInVolume( node, volumeID ); + } + } // loop on bottom nodes + } // Create volumes @@ -347,7 +539,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh { const SMDS_MeshNode* n = face->GetNode( i ); if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { - bot_column = myBotToColumnMap.find( n ); + TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n ); if ( bot_column == myBotToColumnMap.end() ) return error(TCom("No nodes found above node ") << n->GetID() ); columns[ i ] = & bot_column->second; @@ -362,10 +554,129 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh AddPrisms( columns, myHelper ); } // loop on bottom mesh faces + + // clear data + myBotToColumnMap.clear(); + myBlock.Clear(); return true; } + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_Prism_3D::Evaluate(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + MapShapeNbElems& aResMap) +{ + // find face contains only triangles + vector < SMESH_subMesh * >meshFaces; + TopTools_SequenceOfShape aFaces; + int NumBase = 0, i = 0, NbQFs = 0; + for (TopExp_Explorer exp(theShape, TopAbs_FACE); exp.More(); exp.Next()) { + i++; + aFaces.Append(exp.Current()); + SMESH_subMesh *aSubMesh = theMesh.GetSubMesh(exp.Current()); + meshFaces.push_back(aSubMesh); + MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i-1]); + if( anIt==aResMap.end() ) { + SMESH_ComputeErrorPtr& smError = aSubMesh->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + std::vector aVec = (*anIt).second; + int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + int nbqua = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + if( nbtri==0 && nbqua>0 ) { + NbQFs++; + } + if( nbtri>0 ) { + NumBase = i; + } + } + + if(NbQFs<4) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + + if(NumBase==0) NumBase = 1; // only quads => set 1 faces as base + + // find number of 1d elems for base face + int nb1d = 0; + TopTools_MapOfShape Edges1; + for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) { + Edges1.Add(exp.Current()); + SMESH_subMesh *sm = theMesh.GetSubMesh(exp.Current()); + if( sm ) { + MapShapeNbElemsItr anIt = aResMap.find(sm); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + } + } + // find face opposite to base face + int OppNum = 0; + for(i=1; i<=6; i++) { + if(i==NumBase) continue; + bool IsOpposite = true; + for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) { + if( Edges1.Contains(exp.Current()) ) { + IsOpposite = false; + break; + } + } + if(IsOpposite) { + OppNum = i; + break; + } + } + // find number of 2d elems on side faces + int nb2d = 0; + for(i=1; i<=6; i++) { + if( i==OppNum || i==NumBase ) continue; + MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] ); + if( anIt == aResMap.end() ) continue; + std::vector aVec = (*anIt).second; + nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + } + + MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] ); + std::vector aVec = (*anIt).second; + bool IsQuadratic = (aVec[SMDSEntity_Quad_Triangle]>aVec[SMDSEntity_Triangle]) || + (aVec[SMDSEntity_Quad_Quadrangle]>aVec[SMDSEntity_Quadrangle]); + int nb2d_face0_3 = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + int nb2d_face0_4 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + int nb0d_face0 = aVec[SMDSEntity_Node]; + int nb1d_face0_int = ( nb2d_face0_3*3 + nb2d_face0_4*4 - nb1d ) / 2; + + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i & columns, SMESH_MesherHelper* helper) { - SMESHDS_Mesh * meshDS = helper->GetMeshDS(); - int shapeID = helper->GetSubShapeID(); - int nbNodes = columns.size(); int nbZ = columns[0]->size(); if ( nbZ < 2 ) return; @@ -390,87 +698,103 @@ void StdMeshers_Prism_3D::AddPrisms( vector & columns, int z = 1; switch ( nbNodes ) { case 3: { - const SMDS_MeshNode* botNodes[3] = { (*columns[0])[z-1], - (*columns[1])[z-1], - (*columns[2])[z-1] }; - const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z], - (*columns[1])[z], - (*columns[2])[z] }; - SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], - topNodes[0], topNodes[1], topNodes[2]); - vTool.Set( &tmpVol ); + SMDS_VolumeOfNodes tmpPenta ( (*columns[0])[z-1], // bottom + (*columns[1])[z-1], + (*columns[2])[z-1], + (*columns[0])[z], // top + (*columns[1])[z], + (*columns[2])[z] ); + vTool.Set( &tmpPenta ); isForward = vTool.IsForward(); break; } case 4: { - const SMDS_MeshNode* botNodes[4] = { (*columns[0])[z-1], (*columns[1])[z-1], - (*columns[2])[z-1], (*columns[3])[z-1] }; - const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z], - (*columns[2])[z], (*columns[3])[z] }; - SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], botNodes[3], - topNodes[0], topNodes[1], topNodes[2], topNodes[3]); - vTool.Set( &tmpVol ); + SMDS_VolumeOfNodes tmpHex( (*columns[0])[z-1], (*columns[1])[z-1], // bottom + (*columns[2])[z-1], (*columns[3])[z-1], + (*columns[0])[z], (*columns[1])[z], // top + (*columns[2])[z], (*columns[3])[z] ); + vTool.Set( &tmpHex ); isForward = vTool.IsForward(); break; } + default: + const int di = (nbNodes+1) / 3; + SMDS_VolumeOfNodes tmpVol ( (*columns[0] )[z-1], + (*columns[di] )[z-1], + (*columns[2*di])[z-1], + (*columns[0] )[z], + (*columns[di] )[z], + (*columns[2*di])[z] ); + vTool.Set( &tmpVol ); + isForward = vTool.IsForward(); } // vertical loop on columns - for ( z = 1; z < nbZ; ++z ) - { - SMDS_MeshElement* vol = 0; - switch ( nbNodes ) { - case 3: { - const SMDS_MeshNode* botNodes[3] = { (*columns[0])[z-1], - (*columns[1])[z-1], - (*columns[2])[z-1] }; - const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z], - (*columns[1])[z], - (*columns[2])[z] }; - if ( isForward ) - vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2], - topNodes[0], topNodes[1], topNodes[2]); - else - vol = helper->AddVolume( topNodes[0], topNodes[1], topNodes[2], - botNodes[0], botNodes[1], botNodes[2]); - break; - } - case 4: { - const SMDS_MeshNode* botNodes[4] = { (*columns[0])[z-1], (*columns[1])[z-1], - (*columns[2])[z-1], (*columns[3])[z-1] }; - const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z], - (*columns[2])[z], (*columns[3])[z] }; - if ( isForward ) - vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2], botNodes[3], - topNodes[0], topNodes[1], topNodes[2], topNodes[3]); - else - vol = helper->AddVolume( topNodes[0], topNodes[1], topNodes[2], topNodes[3], - botNodes[0], botNodes[1], botNodes[2], botNodes[3]); - break; - } - default: - // polyhedron - vector nodes( 2*nbNodes + 4*nbNodes); - vector quantities( 2 + nbNodes, 4 ); - quantities[0] = quantities[1] = nbNodes; - columns.resize( nbNodes + 1 ); - columns[ nbNodes ] = columns[ 0 ]; + helper->SetElementsOnShape( true ); + + switch ( nbNodes ) { + + case 3: { // ---------- pentahedra + const int i1 = isForward ? 1 : 2; + const int i2 = isForward ? 2 : 1; + for ( z = 1; z < nbZ; ++z ) + helper->AddVolume( (*columns[0 ])[z-1], // bottom + (*columns[i1])[z-1], + (*columns[i2])[z-1], + (*columns[0 ])[z], // top + (*columns[i1])[z], + (*columns[i2])[z] ); + break; + } + case 4: { // ---------- hexahedra + const int i1 = isForward ? 1 : 3; + const int i3 = isForward ? 3 : 1; + for ( z = 1; z < nbZ; ++z ) + helper->AddVolume( (*columns[0])[z-1], (*columns[i1])[z-1], // bottom + (*columns[2])[z-1], (*columns[i3])[z-1], + (*columns[0])[z], (*columns[i1])[z], // top + (*columns[2])[z], (*columns[i3])[z] ); + break; + } + case 6: { // ---------- octahedra + const int iBase1 = isForward ? -1 : 0; + const int iBase2 = isForward ? 0 :-1; + for ( z = 1; z < nbZ; ++z ) + helper->AddVolume( (*columns[0])[z+iBase1], (*columns[1])[z+iBase1], // bottom or top + (*columns[2])[z+iBase1], (*columns[3])[z+iBase1], + (*columns[4])[z+iBase1], (*columns[5])[z+iBase1], + (*columns[0])[z+iBase2], (*columns[1])[z+iBase2], // top or bottom + (*columns[2])[z+iBase2], (*columns[3])[z+iBase2], + (*columns[4])[z+iBase2], (*columns[5])[z+iBase2] ); + break; + } + default: // ---------- polyhedra + vector quantities( 2 + nbNodes, 4 ); + quantities[0] = quantities[1] = nbNodes; + columns.resize( nbNodes + 1 ); + columns[ nbNodes ] = columns[ 0 ]; + const int i1 = isForward ? 1 : 3; + const int i3 = isForward ? 3 : 1; + const int iBase1 = isForward ? -1 : 0; + const int iBase2 = isForward ? 0 :-1; + vector nodes( 2*nbNodes + 4*nbNodes); + for ( z = 1; z < nbZ; ++z ) + { for ( int i = 0; i < nbNodes; ++i ) { - nodes[ i ] = (*columns[ i ])[z-1]; // bottom - nodes[ i+nbNodes ] = (*columns[ i ])[z ]; // top + nodes[ i ] = (*columns[ i ])[z+iBase1]; // bottom or top + nodes[ 2*nbNodes-i-1 ] = (*columns[ i ])[z+iBase2]; // top or bottom // side - int di = 2*nbNodes + 4*i - 1; - nodes[ di ] = (*columns[i ])[z-1]; - nodes[ di+1 ] = (*columns[i+1])[z-1]; - nodes[ di+2 ] = (*columns[i+1])[z ]; - nodes[ di+3 ] = (*columns[i ])[z ]; + int di = 2*nbNodes + 4*i; + nodes[ di+0 ] = (*columns[i ])[z ]; + nodes[ di+i1] = (*columns[i+1])[z ]; + nodes[ di+2 ] = (*columns[i+1])[z-1]; + nodes[ di+i3] = (*columns[i ])[z-1]; } - vol = meshDS->AddPolyhedralVolume( nodes, quantities ); + helper->AddPolyhedralVolume( nodes, quantities ); } - if ( vol && shapeID > 0 ) - meshDS->SetMeshElementOnShape( vol, shapeID ); - } + + } // switch ( nbNodes ) } //================================================================================ @@ -498,6 +822,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() botSMDS->NbElements() != topSMDS->NbElements() || botSMDS->NbNodes() != topSMDS->NbNodes()) { + MESSAGE("nb elem bot " << botSMDS->NbElements() << " top " << topSMDS->NbElements()); + MESSAGE("nb node bot " << botSMDS->NbNodes() << " top " << topSMDS->NbNodes()); if ( myBlock.HasNotQuadElemOnTop() ) return error(TCom("Mesh on faces #") << botSM->GetId() <<" and #"<< topSM->GetId() << " seems different" ); @@ -535,7 +861,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() // Fill myBotToColumnMap int zSize = myBlock.VerticalSize(); - TNode prevTNode; + //TNode prevTNode; TNodeNodeMap::iterator bN_tN = n2nMap.begin(); for ( ; bN_tN != n2nMap.end(); ++bN_tN ) { @@ -543,19 +869,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top() const SMDS_MeshNode* topNode = bN_tN->second; if ( botNode->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE ) continue; // wall columns are contained in myBlock - // compute bottom node params - TNode bN( botNode ); - if ( zSize > 2 ) { - gp_XYZ paramHint(-1,-1,-1); - if ( prevTNode.IsNeighbor( bN )) - paramHint = prevTNode.GetParams(); - if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), - ID_BOT_FACE, paramHint )) - return error(TCom("Can't compute normalized parameters for node ") - << botNode->GetID() << " on the face #"<< botSM->GetId() ); - prevTNode = bN; - } // create node column + TNode bN( botNode ); TNode2ColumnMap::iterator bN_col = myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first; TNodeColumn & column = bN_col->second; @@ -681,7 +996,7 @@ bool StdMeshers_Prism_3D::projectBottomToTop() //================================================================================ /*! - * \brief Set projection coordinates of a node to a face and it's subshapes + * \brief Set projection coordinates of a node to a face and it's sub-shapes * \param faceID - the face given by in-block ID * \param params - node normalized parameters * \retval bool - is a success @@ -696,10 +1011,10 @@ bool StdMeshers_Prism_3D::setFaceAndEdgesXYZ( const int faceID, const gp_XYZ& pa SMESH_Block::GetFaceEdgesIDs( faceID, edgeVec ); myBlock.EdgePoint( edgeVec[ BASE ], params, myShapeXYZ[ edgeVec[ BASE ]]); - myBlock.EdgePoint( edgeVec[ TOP ], params, myShapeXYZ[ edgeVec[ TOP ]]); + myBlock.EdgePoint( edgeVec[ TOP ], params, myShapeXYZ[ edgeVec[ TOP ]]); SHOWYXZ("\nparams ", params); - SHOWYXZ("TOP is "< 0 && nbNotQuad != 2 ) - return error(COMPERR_BAD_SHAPE, - TCom("More than 2 not quadrilateral faces: ") - < 2 ) + { return error(COMPERR_BAD_INPUT_MESH, TCom("More than 2 faces with not quadrangle elements: ") < 0 && nbNotQuad != 2 ) + { + // Issue 0020843 - one of side faces is quasi-quadrilateral. + // Remove from notQuadGeomSubMesh faces meshed with regular grid + nbQuasiQuads = removeQuasiQuads( notQuadGeomSubMesh ); + nbNotQuad -= nbQuasiQuads; + if ( nbNotQuad > 0 && nbNotQuad != 2 ) + return error(COMPERR_BAD_SHAPE, + TCom("More than 2 not quadrilateral faces: ") + < 1 ); + MESSAGE("myNotQuadOnTop " << myNotQuadOnTop << " nbNotQuadMeshed " << nbNotQuadMeshed); // ---------------------------------------------------------- @@ -994,24 +1330,47 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // Get ordered bottom edges list< TopoDS_Edge > orderedEdges; - list< int > nbVertexInWires; + list< int > nbEInW; SMESH_Block::GetOrderedEdges( TopoDS::Face( botSM->GetSubShape().Reversed() ), - V000, orderedEdges, nbVertexInWires ); -// if ( nbVertexInWires.size() != 1 ) + V000, orderedEdges, nbEInW ); +// if ( nbEInW.size() != 1 ) // RETURN_BAD_RESULT("Wrong prism geometry"); // Get Wall faces corresponding to the ordered bottom edges list< TopoDS_Face > wallFaces; - if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, wallFaces)) + if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, nbEInW, wallFaces)) return error(COMPERR_BAD_SHAPE, "Can't find side faces"); + // check that the found top and bottom faces are opposite + { + for (TopExp_Explorer edge(botSM->GetSubShape(), TopAbs_EDGE); edge.More(); edge.Next()) + if ( helper->IsSubShape( edge.Current(), topSM->GetSubShape() )) + return error(notQuadGeomSubMesh.empty() ? COMPERR_BAD_INPUT_MESH : COMPERR_BAD_SHAPE, + "Non-quadrilateral faces are not opposite"); + } + + // Protect from a distorted block (test 3D_mesh_HEXA3D/B7 on 32bit platform) + // check that all wall faces have an edge common with the top face + { + list< TopoDS_Face >::iterator faceIt = wallFaces.begin(); + for ( ; faceIt != wallFaces.end(); ++faceIt ) + { + bool hasCommon = false; + for (TopExp_Explorer edge(*faceIt, TopAbs_EDGE); !hasCommon && edge.More(); edge.Next()) + if ( helper->IsSubShape( edge.Current(), topSM->GetSubShape() )) + hasCommon = true; + if ( !hasCommon ) + return error(COMPERR_BAD_SHAPE); + } + } + // Find columns of wall nodes and calculate edges' lengths // -------------------------------------------------------- myParam2ColumnMaps.clear(); myParam2ColumnMaps.resize( orderedEdges.size() ); // total nb edges - int iE, nbEdges = nbVertexInWires.front(); // nb outer edges + int iE, nbEdges = nbEInW.front(); // nb outer edges vector< double > edgeLength( nbEdges ); map< double, int > len2edgeMap; @@ -1057,11 +1416,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // columns for vertices // 1 const SMDS_MeshNode* n0 = faceColumns.begin()->second.front(); - id = n0->GetPosition()->GetShapeId(); + id = n0->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward ); // 2 const SMDS_MeshNode* n1 = faceColumns.rbegin()->second.front(); - id = n1->GetPosition()->GetShapeId(); + id = n1->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward ); // SHOWYXZ("\np1 F "<second.front() )); // SHOWYXZ("p2 F "<second.front() )); @@ -1113,9 +1472,12 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, int nbSplit = i_nb->second; vector< double > params; splitParams( nbSplit, &myParam2ColumnMaps[ iE ], params ); - bool isForward = ( edgeIt->Orientation() == TopAbs_FORWARD ); + const bool isForward = + StdMeshers_PrismAsBlock::IsForwardEdge( myHelper->GetMeshDS(), + myParam2ColumnMaps[iE], + *edgeIt, SMESH_Block::ID_Fx0z ); for ( int i = 0; i < nbSplit; ++i ) { - double f = ( isForward ? params[ i ] : params[ nbSplit - i-1 ]); + double f = ( isForward ? params[ i ] : params[ nbSplit - i-1 ]); double l = ( isForward ? params[ i+1 ] : params[ nbSplit - i ]); TSideFace* comp = new TSideFace( myHelper, wallFaceIds[ iSide ], *faceIt, *edgeIt, @@ -1236,6 +1598,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, break; } } + //sideFace->dumpNodes( 4 ); // debug } // horizontal faces geometry { @@ -1270,11 +1633,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, // columns for vertices const SMDS_MeshNode* n0 = cols->begin()->second.front(); - id = n0->GetPosition()->GetShapeId(); + id = n0->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( cols, isForward ); const SMDS_MeshNode* n1 = cols->rbegin()->second.front(); - id = n1->GetPosition()->GetShapeId(); + id = n1->getshapeId(); myShapeIndex2ColumnMap[ id ] = make_pair( cols, !isForward ); } } @@ -1301,7 +1664,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper, const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* node) const { - int sID = node->GetPosition()->GetShapeId(); + int sID = node->getshapeId(); map >::const_iterator col_frw = myShapeIndex2ColumnMap.find( sID ); @@ -1315,6 +1678,89 @@ const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* n return 0; } +//======================================================================= +//function : GetLayersTransformation +//purpose : Return transformations to get coordinates of nodes of each layer +// by nodes of the bottom. Layer is a set of nodes at a certain step +// from bottom to top. +//======================================================================= + +bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector & trsf) const +{ + const int zSize = VerticalSize(); + if ( zSize < 3 ) return true; + trsf.resize( zSize - 2 ); + + // Select some node columns by which we will define coordinate system of layers + + vector< const TNodeColumn* > columns; + { + const TopoDS_Shape& baseFace = Shape(ID_BOT_FACE); + list< TopoDS_Edge > orderedEdges; + list< int > nbEdgesInWires; + GetOrderedEdges( TopoDS::Face( baseFace ), TopoDS_Vertex(), orderedEdges, nbEdgesInWires ); + bool isReverse; + list< TopoDS_Edge >::iterator edgeIt = orderedEdges.begin(); + for ( int iE = 0; iE < nbEdgesInWires.front(); ++iE, ++edgeIt ) + { + if ( BRep_Tool::Degenerated( *edgeIt )) continue; + const TParam2ColumnMap* u2colMap = + GetParam2ColumnMap( myHelper->GetMeshDS()->ShapeToIndex( *edgeIt ), isReverse ); + if ( !u2colMap ) return false; + isReverse = ( edgeIt->Orientation() == TopAbs_REVERSED ); + double f = u2colMap->begin()->first, l = u2colMap->rbegin()->first; + if ( isReverse ) swap ( f, l ); + const int nbCol = 5; + for ( int i = 0; i < nbCol; ++i ) + { + double u = f + i/double(nbCol) * ( l - f ); + const TNodeColumn* col = & getColumn( u2colMap, u )->second; + if ( columns.empty() || col != columns.back() ) + columns.push_back( col ); + } + } + } + + // Find tolerance to check transformations + + double tol2; + { + Bnd_B3d bndBox; + for ( int i = 0; i < columns.size(); ++i ) + bndBox.Add( gpXYZ( columns[i]->front() )); + tol2 = bndBox.SquareExtent() * 1e-5; + } + + // Compute transformations + + int xCol = -1; + gp_Trsf fromCsZ, toCs0; + gp_Ax3 cs0 = getLayerCoordSys(0, columns, xCol ); + //double dist0 = cs0.Location().Distance( gpXYZ( (*columns[0])[0])); + toCs0.SetTransformation( cs0 ); + for ( int z = 1; z < zSize-1; ++z ) + { + gp_Ax3 csZ = getLayerCoordSys(z, columns, xCol ); + //double distZ = csZ.Location().Distance( gpXYZ( (*columns[0])[z])); + fromCsZ.SetTransformation( csZ ); + fromCsZ.Invert(); + gp_Trsf& t = trsf[ z-1 ]; + t = fromCsZ * toCs0; + //t.SetScaleFactor( distZ/dist0 ); - it does not work properly, wrong base point + + // check a transformation + for ( int i = 0; i < columns.size(); ++i ) + { + gp_Pnt p0 = gpXYZ( (*columns[i])[0] ); + gp_Pnt pz = gpXYZ( (*columns[i])[z] ); + t.Transforms( p0.ChangeCoord() ); + if ( p0.SquareDistance( pz ) > tol2 ) + return false; + } + } + return true; +} + //================================================================================ /*! * \brief Check curve orientation of a bootom edge @@ -1322,7 +1768,7 @@ const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* n * \param columnsMap - node columns map of side face * \param bottomEdge - the bootom edge * \param sideFaceID - side face in-block ID - * \retval bool - true if orientation coinside with in-block froward orientation + * \retval bool - true if orientation coinside with in-block forward orientation */ //================================================================================ @@ -1332,7 +1778,7 @@ bool StdMeshers_PrismAsBlock::IsForwardEdge(SMESHDS_Mesh* meshDS, const int sideFaceID) { bool isForward = false; - if ( TAssocTool::IsClosedEdge( bottomEdge )) + if ( SMESH_MesherHelper::IsClosedEdge( bottomEdge )) { isForward = ( bottomEdge.Orientation() == TopAbs_FORWARD ); } @@ -1350,41 +1796,59 @@ bool StdMeshers_PrismAsBlock::IsForwardEdge(SMESHDS_Mesh* meshDS, } //================================================================================ - /*! - * \brief Find wall faces by bottom edges - * \param mesh - the mesh - * \param mainShape - the prism - * \param bottomFace - the bottom face - * \param bottomEdges - edges bounding the bottom face - * \param wallFaces - faces list to fill in - */ +/*! + * \brief Find wall faces by bottom edges + * \param mesh - the mesh + * \param mainShape - the prism + * \param bottomFace - the bottom face + * \param bottomEdges - edges bounding the bottom face + * \param wallFaces - faces list to fill in + */ //================================================================================ -bool StdMeshers_PrismAsBlock::GetWallFaces( SMESH_Mesh* mesh, - const TopoDS_Shape & mainShape, - const TopoDS_Shape & bottomFace, - const std::list< TopoDS_Edge >& bottomEdges, - std::list< TopoDS_Face >& wallFaces) +bool StdMeshers_PrismAsBlock::GetWallFaces( SMESH_Mesh* mesh, + const TopoDS_Shape & mainShape, + const TopoDS_Shape & bottomFace, + std::list< TopoDS_Edge >& bottomEdges, + std::list< int > & nbEInW, + std::list< TopoDS_Face >& wallFaces) { wallFaces.clear(); TopTools_IndexedMapOfShape faceMap; TopExp::MapShapes( mainShape, TopAbs_FACE, faceMap ); - list< TopoDS_Edge >::const_iterator edge = bottomEdges.begin(); - for ( ; edge != bottomEdges.end(); ++edge ) + list< TopoDS_Edge >::iterator edge = bottomEdges.begin(); + std::list< int >::iterator nbE = nbEInW.begin(); + int iE = 0; + while ( edge != bottomEdges.end() ) { - TopTools_ListIteratorOfListOfShape ancestIt = mesh->GetAncestors( *edge ); - for ( ; ancestIt.More(); ancestIt.Next() ) + ++iE; + if ( BRep_Tool::Degenerated( *edge )) { - const TopoDS_Shape& ancestor = ancestIt.Value(); - if ( ancestor.ShapeType() == TopAbs_FACE && // face - !bottomFace.IsSame( ancestor ) && // not bottom - faceMap.FindIndex( ancestor )) // belongs to the prism + edge = bottomEdges.erase( edge ); + --iE; + --(*nbE); + } + else + { + PShapeIteratorPtr fIt = myHelper->GetAncestors( *edge, *mesh, TopAbs_FACE ); + while ( fIt->more() ) { - wallFaces.push_back( TopoDS::Face( ancestor )); - break; + const TopoDS_Shape* face = fIt->next(); + if ( !bottomFace.IsSame( *face ) && // not bottom + faceMap.FindIndex( *face )) // belongs to the prism + { + wallFaces.push_back( TopoDS::Face( *face )); + break; + } } + ++edge; + } + if ( iE == *nbE ) + { + iE = 0; + ++nbE; } } return ( wallFaces.size() == bottomEdges.size() ); @@ -1610,8 +2074,6 @@ double StdMeshers_PrismAsBlock::TSideFace::GetColumns(const double U, r = 0.5; } else { -// if ( !myIsForward ) -// std::swap( col1, col2 ); double uf = col1->first; double ul = col2->first; r = ( u - uf ) / ( ul - uf ); @@ -1631,8 +2093,8 @@ double StdMeshers_PrismAsBlock::TSideFace::GetColumns(const double U, gp_Pnt StdMeshers_PrismAsBlock::TSideFace::Value(const Standard_Real U, const Standard_Real V) const { - double u; if ( !myComponents.empty() ) { + double u; TSideFace * comp = GetComponent(U,u); return comp->Value( u, V ); } @@ -1644,7 +2106,41 @@ gp_Pnt StdMeshers_PrismAsBlock::TSideFace::Value(const Standard_Real U, const SMDS_MeshNode* n2 = 0; const SMDS_MeshNode* n3 = 0; const SMDS_MeshNode* n4 = 0; - gp_XYZ pnt; + + // BEGIN issue 0020680: EDF 1252 SMESH: Bad cell created by Radial prism in center of torus + // Workaround for a wrongly located point returned by mySurface.Value() for + // UV located near boundary of BSpline surface. + // To bypass the problem, we take point from 3D curve of edge. + // It solves pb of the bloc_fiss_new.py + const double tol = 1e-3; + if ( V < tol || V+tol >= 1. ) + { + n1 = V < tol ? u_col1->second.front() : u_col1->second.back(); + n3 = V < tol ? u_col2->second.front() : u_col2->second.back(); + TopoDS_Edge edge; + if ( V < tol ) + { + edge = myBaseEdge; + } + else + { + TopoDS_Shape s = myHelper->GetSubShapeByNode( n1, myHelper->GetMeshDS() ); + if ( s.ShapeType() != TopAbs_EDGE ) + s = myHelper->GetSubShapeByNode( n3, myHelper->GetMeshDS() ); + if ( s.ShapeType() == TopAbs_EDGE ) + edge = TopoDS::Edge( s ); + } + if ( !edge.IsNull() ) + { + double u1 = myHelper->GetNodeU( edge, n1 ); + double u3 = myHelper->GetNodeU( edge, n3 ); + double u = u1 * ( 1 - hR ) + u3 * hR; + TopLoc_Location loc; double f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve( edge,loc,f,l ); + return curve->Value( u ).Transformed( loc ); + } + } + // END issue 0020680: EDF 1252 SMESH: Bad cell created by Radial prism in center of torus vR = getRAndNodes( & u_col1->second, V, n1, n2 ); vR = getRAndNodes( & u_col2->second, V, n3, n4 ); @@ -1658,8 +2154,9 @@ gp_Pnt StdMeshers_PrismAsBlock::TSideFace::Value(const Standard_Real U, gp_XY uv34 = uv3 * ( 1 - vR ) + uv4 * vR; gp_XY uv = uv12 * ( 1 - hR ) + uv34 * hR; - - return mySurface.Value( uv.X(), uv.Y() ); + + gp_Pnt p = mySurface.Value( uv.X(), uv.Y() ); + return p; } @@ -1720,25 +2217,18 @@ TopoDS_Edge StdMeshers_PrismAsBlock::TSideFace::GetEdge(const int iEdge) const TopoDS_Shape V2 = myHelper->GetSubShapeByNode( node, meshDS ); if ( V2.ShapeType() == TopAbs_VERTEX && !V2.IsSame( V1 )) { - TopTools_ListIteratorOfListOfShape ancestIt = - myHelper->GetMesh()->GetAncestors( V1 ); - for ( ; ancestIt.More(); ancestIt.Next() ) - { - const TopoDS_Shape & ancestor = ancestIt.Value(); - if ( ancestor.ShapeType() == TopAbs_EDGE ) - for ( TopExp_Explorer e( ancestor, TopAbs_VERTEX ); e.More(); e.Next() ) - if ( V2.IsSame( e.Current() )) - return TopoDS::Edge( ancestor ); - } + TopoDS_Shape ancestor = myHelper->GetCommonAncestor( V1, V2, *myHelper->GetMesh(), TopAbs_EDGE); + if ( !ancestor.IsNull() ) + return TopoDS::Edge( ancestor ); } return TopoDS_Edge(); } //================================================================================ /*! - * \brief Fill block subshapes + * \brief Fill block sub-shapes * \param shapeMap - map to fill in - * \retval int - nb inserted subshapes + * \retval int - nb inserted sub-shapes */ //================================================================================ @@ -1837,6 +2327,28 @@ int StdMeshers_PrismAsBlock::TSideFace::InsertSubShapes(TBlockShapes& shapeMap) return nbInserted; } +//================================================================================ +/*! + * \brief Dump ids of nodes of sides + */ +//================================================================================ + +void StdMeshers_PrismAsBlock::TSideFace::dumpNodes(int nbNodes) const +{ +#ifdef _DEBUG_ + cout << endl << "NODES OF FACE "; SMESH_Block::DumpShapeID( myID, cout ) << endl; + THorizontalEdgeAdaptor* hSize0 = (THorizontalEdgeAdaptor*) HorizCurve(0); + cout << "Horiz side 0: "; hSize0->dumpNodes(nbNodes); cout << endl; + THorizontalEdgeAdaptor* hSize1 = (THorizontalEdgeAdaptor*) HorizCurve(1); + cout << "Horiz side 1: "; hSize1->dumpNodes(nbNodes); cout << endl; + TVerticalEdgeAdaptor* vSide0 = (TVerticalEdgeAdaptor*) VertiCurve(0); + cout << "Verti side 0: "; vSide0->dumpNodes(nbNodes); cout << endl; + TVerticalEdgeAdaptor* vSide1 = (TVerticalEdgeAdaptor*) VertiCurve(1); + cout << "Verti side 1: "; vSide1->dumpNodes(nbNodes); cout << endl; + delete hSize0; delete hSize1; delete vSide0; delete vSide1; +#endif +} + //================================================================================ /*! * \brief Creates TVerticalEdgeAdaptor @@ -1867,6 +2379,22 @@ gp_Pnt StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::Value(const Standard_Real return gpXYZ(n1) * ( 1 - r ) + gpXYZ(n2) * r; } +//================================================================================ +/*! + * \brief Dump ids of nodes + */ +//================================================================================ + +void StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::dumpNodes(int nbNodes) const +{ +#ifdef _DEBUG_ + for ( int i = 0; i < nbNodes && i < myNodeColumn->size(); ++i ) + cout << (*myNodeColumn)[i]->GetID() << " "; + if ( nbNodes < myNodeColumn->size() ) + cout << myNodeColumn->back()->GetID(); +#endif +} + //================================================================================ /*! * \brief Return coordinates for the given normalized parameter @@ -1880,6 +2408,50 @@ gp_Pnt StdMeshers_PrismAsBlock::THorizontalEdgeAdaptor::Value(const Standard_Rea return mySide->TSideFace::Value( U, myV ); } +//================================================================================ +/*! + * \brief Dump ids of first nodes and the last one + */ +//================================================================================ + +void StdMeshers_PrismAsBlock::THorizontalEdgeAdaptor::dumpNodes(int nbNodes) const +{ +#ifdef _DEBUG_ + // Not bedugged code. Last node is sometimes incorrect + const TSideFace* side = mySide; + double u = 0; + if ( mySide->IsComplex() ) + side = mySide->GetComponent(0,u); + + TParam2ColumnIt col, col2; + TParam2ColumnMap* u2cols = side->GetColumns(); + side->GetColumns( u , col, col2 ); + + int j, i = myV ? mySide->ColumnHeight()-1 : 0; + + const SMDS_MeshNode* n = 0; + const SMDS_MeshNode* lastN + = side->IsForward() ? u2cols->rbegin()->second[ i ] : u2cols->begin()->second[ i ]; + for ( j = 0; j < nbNodes && n != lastN; ++j ) + { + n = col->second[ i ]; + cout << n->GetID() << " "; + if ( side->IsForward() ) + ++col; + else + --col; + } + + // last node + u = 1; + if ( mySide->IsComplex() ) + side = mySide->GetComponent(1,u); + + side->GetColumns( u , col, col2 ); + if ( n != col->second[ i ] ) + cout << col->second[ i ]->GetID(); +#endif +} //================================================================================ /*! * \brief Return UV on pcurve for the given normalized parameter diff --git a/src/StdMeshers/StdMeshers_Prism_3D.hxx b/src/StdMeshers/StdMeshers_Prism_3D.hxx index 0eb4db1d0..8c1e6fa78 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.hxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Prism_3D.hxx // Module : SMESH @@ -46,6 +47,7 @@ #include #include #include +#include class SMESHDS_SubMesh; @@ -58,7 +60,7 @@ typedef std::vector TNodeColumn; // map of bottom nodes to the column of nodes above them // (the column includes the bottom nodes) -typedef std::map< TNode, TNodeColumn > TNode2ColumnMap; +typedef std::map< TNode, TNodeColumn > TNode2ColumnMap; typedef std::map< double, TNodeColumn > TParam2ColumnMap; typedef std::map< double, TNodeColumn >::const_iterator TParam2ColumnIt; @@ -73,18 +75,18 @@ typedef TopTools_IndexedMapOfOrientedShape TBlockShapes; struct TNode { const SMDS_MeshNode* myNode; - gp_XYZ myParams; + mutable gp_XYZ myParams; gp_XYZ GetCoords() const { return gp_XYZ( myNode->X(), myNode->Y(), myNode->Z() ); } gp_XYZ GetParams() const { return myParams; } - gp_XYZ& ChangeParams() { return myParams; } + gp_XYZ& ChangeParams() const { return myParams; } bool HasParams() const { return myParams.X() >= 0.0; } SMDS_TypeOfPosition GetPositionType() const { return myNode ? myNode->GetPosition()->GetTypeOfPosition() : SMDS_TOP_UNSPEC; } bool IsNeighbor( const TNode& other ) const; TNode(const SMDS_MeshNode* node = 0): myNode(node), myParams(-1,-1,-1) {} - bool operator < (const TNode& other) const { return myNode < other.myNode; } + bool operator < (const TNode& other) const { return myNode->GetID() < other.myNode->GetID(); } }; // =============================================================== @@ -92,7 +94,7 @@ struct TNode * \brief Tool analyzing and giving access to a prism geometry * treating it like a block, i.e. the four side faces are * emulated by division/uniting of missing/excess faces. - * It also manage associations between block subshapes and a mesh. + * It also manage associations between block sub-shapes and a mesh. */ // =============================================================== @@ -122,6 +124,11 @@ public: */ SMESH_ComputeErrorPtr GetError() const { return myError; } + /*! + * \brief Free allocated memory + */ + void Clear(); + /*! * \brief Return number of nodes on every vertical edge * \retval int - number of nodes including end nodes @@ -141,16 +148,26 @@ public: * \brief Return TParam2ColumnMap for a base edge * \param baseEdgeID - base edge SMESHDS Index * \param isReverse - columns in-block orientation - * \retval const TParam2ColumnMap& - map + * \retval const TParam2ColumnMap* - map */ - const TParam2ColumnMap& GetParam2ColumnMap(const int baseEdgeID, - bool & isReverse) + const TParam2ColumnMap* GetParam2ColumnMap(const int baseEdgeID, + bool & isReverse) const { - std::pair< TParam2ColumnMap*, bool > & col_frw = - myShapeIndex2ColumnMap[ baseEdgeID ]; + std::map< int, std::pair< TParam2ColumnMap*, bool > >::const_iterator i_mo = + myShapeIndex2ColumnMap.find( baseEdgeID ); + if ( i_mo == myShapeIndex2ColumnMap.end() ) return 0; + + const std::pair< TParam2ColumnMap*, bool >& col_frw = i_mo->second; isReverse = !col_frw.second; - return * col_frw.first; + return col_frw.first; } + + /*! + * \brief Return transformations to get coordinates of nodes of each internal layer + * by nodes of the bottom. Layer is a set of nodes at a certain step + * from bottom to top. + */ + bool GetLayersTransformation(std::vector & trsf) const; /*! * \brief Return pointer to mesh @@ -190,7 +207,7 @@ public: /*! * \brief Return in-block ID of a shape - * \param shape - block subshape + * \param shape - block sub-shape * \retval int - ID or zero if the shape has no ID */ int ShapeID(const TopoDS_Shape& shape) const @@ -216,11 +233,12 @@ public: * \param bottomEdges - edges bounding the bottom face * \param wallFaces - faces list to fill in */ - static bool GetWallFaces( SMESH_Mesh* mesh, - const TopoDS_Shape & mainShape, - const TopoDS_Shape & bottomFace, - const std::list< TopoDS_Edge >& bottomEdges, - std::list< TopoDS_Face >& wallFaces); + bool GetWallFaces( SMESH_Mesh* mesh, + const TopoDS_Shape & mainShape, + const TopoDS_Shape & bottomFace, + std::list< TopoDS_Edge >& bottomEdges, + std::list< int > & nbEInW, + std::list< TopoDS_Face >& wallFaces); private: @@ -284,6 +302,8 @@ private: int InsertSubShapes( TBlockShapes& shapeMap ) const; // redefine Adaptor methods gp_Pnt Value(const Standard_Real U,const Standard_Real V) const; + // debug + void dumpNodes(int nbNodes) const; }; // -------------------------------------------------------------------- @@ -299,6 +319,8 @@ private: gp_Pnt Value(const Standard_Real U) const; Standard_Real FirstParameter() const { return 0; } Standard_Real LastParameter() const { return 1; } + // debug + void dumpNodes(int nbNodes) const; }; // -------------------------------------------------------------------- @@ -316,6 +338,8 @@ private: gp_Pnt Value(const Standard_Real U) const; Standard_Real FirstParameter() const { return 0; } Standard_Real LastParameter() const { return 1; } + // debug + void dumpNodes(int nbNodes) const; }; // -------------------------------------------------------------------- @@ -337,20 +361,19 @@ private: Standard_Real FirstParameter() const { return 0; } Standard_Real LastParameter() const { return 1; } }; - // -------------------------------------------------------------------- - bool myNotQuadOnTop; - SMESH_MesherHelper* myHelper; - TBlockShapes myShapeIDMap; + bool myNotQuadOnTop; + SMESH_MesherHelper* myHelper; + TBlockShapes myShapeIDMap; + SMESH_ComputeErrorPtr myError; // container of 4 side faces - TSideFace* mySide; + TSideFace* mySide; // node columns for each base edge - std::vector< TParam2ColumnMap > myParam2ColumnMaps; + std::vector< TParam2ColumnMap > myParam2ColumnMaps; // to find a column for a node by edge SMESHDS Index std::map< int, std::pair< TParam2ColumnMap*, bool > > myShapeIndex2ColumnMap; - SMESH_ComputeErrorPtr myError; /*! * \brief store error and comment and then return ( error == COMPERR_OK ) */ @@ -358,7 +381,6 @@ private: myError = SMESH_ComputeError::New(error,comment); return myError->IsOK(); } - //std::vector< SMESH_subMesh* > mySubMeshesVec; // submesh by in-block id }; // ============================================= @@ -379,6 +401,9 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + /*! * \brief Enable removal of quadrangles from the bottom face and * triangles creation there by projection from the top @@ -415,7 +440,7 @@ private: bool projectBottomToTop(); /*! - * \brief Set projection coordinates of a node to a face and it's subshapes + * \brief Set projection coordinates of a node to a face and it's sub-shapes * \param faceID - the face given by in-block ID * \param params - node normalized parameters * \retval bool - is a success @@ -429,12 +454,11 @@ private: StdMeshers_PrismAsBlock myBlock; SMESH_MesherHelper* myHelper; - std::vector myShapeXYZ; // point on each sub-shape + std::vector myShapeXYZ; // point on each sub-shape of the block // map of bottom nodes to the column of nodes above them // (the column includes the bottom node) - typedef std::map< TNode, TNodeColumn > TNode2ColumnMap; - TNode2ColumnMap myBotToColumnMap; + TNode2ColumnMap myBotToColumnMap; }; #endif diff --git a/src/StdMeshers/StdMeshers_ProjectionSource1D.cxx b/src/StdMeshers/StdMeshers_ProjectionSource1D.cxx index 8a2052071..cf1a41ee3 100644 --- a/src/StdMeshers/StdMeshers_ProjectionSource1D.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionSource1D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_ProjectionSource1D.cxx // Author : Edward AGAPOV @@ -126,9 +127,10 @@ void StdMeshers_ProjectionSource1D::SetVertexAssociation(const TopoDS_Shape& sou void StdMeshers_ProjectionSource1D::SetSourceMesh(SMESH_Mesh* mesh) { - if ( _sourceMesh != mesh ) + if ( _sourceMesh != mesh ) { + _sourceMesh = mesh; NotifySubMeshesHypothesisModification(); - _sourceMesh = mesh; + } } //============================================================================= diff --git a/src/StdMeshers/StdMeshers_ProjectionSource1D.hxx b/src/StdMeshers/StdMeshers_ProjectionSource1D.hxx index 301dedf30..ddd82f673 100644 --- a/src/StdMeshers/StdMeshers_ProjectionSource1D.hxx +++ b/src/StdMeshers/StdMeshers_ProjectionSource1D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionSource1D.hxx // Author : Edward AGAPOV diff --git a/src/StdMeshers/StdMeshers_ProjectionSource2D.cxx b/src/StdMeshers/StdMeshers_ProjectionSource2D.cxx index a1393fc79..479bdd6ec 100644 --- a/src/StdMeshers/StdMeshers_ProjectionSource2D.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionSource2D.cxx @@ -1,32 +1,34 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_ProjectionSource2D.cxx // Author : Edward AGAPOV // Module : SMESH - +// #include "StdMeshers_ProjectionSource2D.hxx" #include "SMESH_Mesh.hxx" +#include "StdMeshers_ProjectionUtils.hxx" #include "utilities.h" @@ -102,17 +104,27 @@ void StdMeshers_ProjectionSource2D::SetVertexAssociation(const TopoDS_Shape& sou throw ( SALOME_Exception ) { if ( sourceVertex1.IsNull() != targetVertex1.IsNull() || - sourceVertex2.IsNull() != targetVertex2.IsNull() || - sourceVertex1.IsNull() != targetVertex2.IsNull() ) - throw SALOME_Exception(LOCALIZED("Two or none pairs of vertices must be provided")); + sourceVertex2.IsNull() != targetVertex2.IsNull() ) + throw SALOME_Exception(LOCALIZED("Vertices must be provided in couples")); + + if ( sourceVertex1.IsNull() != sourceVertex2.IsNull() ) + { + // possibly there is only 1 vertex in the face + if ( !_sourceFace.IsNull() && + StdMeshers_ProjectionUtils::Count( _sourceFace, TopAbs_VERTEX, /*ignoreSame=*/true) != 1 ) + throw SALOME_Exception(LOCALIZED("Two or none pairs of vertices must be provided")); + } - if ( !sourceVertex1.IsNull() ) { + if ( !sourceVertex1.IsNull() ) if ( sourceVertex1.ShapeType() != TopAbs_VERTEX || - sourceVertex2.ShapeType() != TopAbs_VERTEX || - targetVertex1.ShapeType() != TopAbs_VERTEX || + targetVertex1.ShapeType() != TopAbs_VERTEX ) + throw SALOME_Exception(LOCALIZED("Wrong shape type")); + + if ( !sourceVertex2.IsNull() ) + if ( sourceVertex2.ShapeType() != TopAbs_VERTEX || targetVertex2.ShapeType() != TopAbs_VERTEX ) throw SALOME_Exception(LOCALIZED("Wrong shape type")); - } + if ( !_sourceVertex1.IsSame( sourceVertex1 ) || !_sourceVertex2.IsSame( sourceVertex2 ) || @@ -136,9 +148,10 @@ void StdMeshers_ProjectionSource2D::SetVertexAssociation(const TopoDS_Shape& sou void StdMeshers_ProjectionSource2D::SetSourceMesh(SMESH_Mesh* mesh) { - if ( _sourceMesh != mesh ) + if ( _sourceMesh != mesh ) { + _sourceMesh = mesh; NotifySubMeshesHypothesisModification(); - _sourceMesh = mesh; + } } //============================================================================= diff --git a/src/StdMeshers/StdMeshers_ProjectionSource2D.hxx b/src/StdMeshers/StdMeshers_ProjectionSource2D.hxx index a23d4c494..978321147 100644 --- a/src/StdMeshers/StdMeshers_ProjectionSource2D.hxx +++ b/src/StdMeshers/StdMeshers_ProjectionSource2D.hxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionSource2D.hxx // Author : Edward AGAPOV // Module : SMESH - +// #ifndef _SMESH_ProjectionSource2D_HXX_ #define _SMESH_ProjectionSource2D_HXX_ diff --git a/src/StdMeshers/StdMeshers_ProjectionSource3D.cxx b/src/StdMeshers/StdMeshers_ProjectionSource3D.cxx index b77808f36..f90b4eed3 100644 --- a/src/StdMeshers/StdMeshers_ProjectionSource3D.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionSource3D.cxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_ProjectionSource3D.cxx // Author : Edward AGAPOV // Module : SMESH - +// #include "StdMeshers_ProjectionSource3D.hxx" #include "utilities.h" @@ -135,9 +136,10 @@ void StdMeshers_ProjectionSource3D::SetVertexAssociation(const TopoDS_Shape& sou void StdMeshers_ProjectionSource3D::SetSourceMesh(SMESH_Mesh* mesh) { - if ( _sourceMesh != mesh ) + if ( _sourceMesh != mesh ) { + _sourceMesh = mesh; NotifySubMeshesHypothesisModification(); - _sourceMesh = mesh; + } } //============================================================================= diff --git a/src/StdMeshers/StdMeshers_ProjectionSource3D.hxx b/src/StdMeshers/StdMeshers_ProjectionSource3D.hxx index fd6848aec..6098f1816 100644 --- a/src/StdMeshers/StdMeshers_ProjectionSource3D.hxx +++ b/src/StdMeshers/StdMeshers_ProjectionSource3D.hxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionSource3D.hxx // Author : Edward AGAPOV // Module : SMESH - +// #ifndef _SMESH_ProjectionSource3D_HXX_ #define _SMESH_ProjectionSource3D_HXX_ diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index 2bf6ac4be..3053be90d 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionUtils.cxx // Created : Fri Oct 27 10:24:28 2006 @@ -34,15 +35,15 @@ #include "SMESH_Block.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Hypothesis.hxx" -#include "SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" #include "SMDS_EdgePosition.hxx" #include "utilities.h" +#include #include #include #include @@ -52,6 +53,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -60,20 +64,22 @@ #include #include #include -#include -#include + +#include using namespace std; #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; } -#define SHOW_VERTEX(v,msg) // { \ -// if ( v.IsNull() ) cout << msg << " NULL SHAPE" << endl; \ -// else if (v.ShapeType() == TopAbs_VERTEX) {\ -// gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( v ));\ -// cout << msg << (v).TShape().operator->()<<" ( " <()<ShapeToIndex(S), theMeshDS[1]->ShapeToIndex(S) ); + return long(S.TShape().operator->()); + } + + //================================================================================ + /*! + * \brief Write shape for debug purposes + */ + //================================================================================ + + bool _StoreBadShape(const TopoDS_Shape& shape) + { +#ifdef _DEBUG_ + const char* type[] ={"COMPOUND","COMPSOLID","SOLID","SHELL","FACE","WIRE","EDGE","VERTEX"}; + BRepTools::Write( shape, SMESH_Comment("/tmp/") << type[shape.ShapeType()] << "_" + << shape.TShape().operator->() << ".brep"); +#endif + return false; + } + //================================================================================ /*! * \brief Reverse order of edges in a list and their orientation @@ -94,31 +127,24 @@ namespace { */ //================================================================================ - void Reverse( list< TopoDS_Edge > & edges, const int nbEdges ) + void Reverse( list< TopoDS_Edge > & edges, const int nbEdges, const int firstEdge=0) { SHOW_LIST("BEFORE REVERSE", edges); list< TopoDS_Edge >::iterator eIt = edges.begin(); - if ( edges.size() == nbEdges ) - { - edges.reverse(); - } - else // reverse only the given nb of edges + std::advance( eIt, firstEdge ); + list< TopoDS_Edge >::iterator eBackIt = eIt; + for ( int i = 0; i < nbEdges; ++i, ++eBackIt ) + eBackIt->Reverse(); // reverse edge + // reverse list + --eBackIt; + while ( eIt != eBackIt ) { - // look for the last edge to be reversed - list< TopoDS_Edge >::iterator eBackIt = edges.begin(); - for ( int i = 1; i < nbEdges; ++i ) - ++eBackIt; - // reverse - while ( eIt != eBackIt ) { - std::swap( *eIt, *eBackIt ); - SHOW_LIST("# AFTER SWAP", edges) + std::swap( *eIt, *eBackIt ); + SHOW_LIST("# AFTER SWAP", edges) if ( (++eIt) != eBackIt ) --eBackIt; - } } - for ( eIt = edges.begin(); eIt != edges.end(); ++eIt ) - eIt->Reverse(); SHOW_LIST("ATFER REVERSE", edges) } @@ -162,8 +188,7 @@ namespace { if ( nbEdges == 2 && IsPropagationPossible( theMesh1, theMesh2 ) ) { list< TopoDS_Edge >::iterator eIt2 = ++edges2.begin(); // 2nd edge of the 2nd face - TopoDS_Edge edge2 = - StdMeshers_ProjectionUtils::GetPropagationEdge( theMesh1, *eIt2, edges1.front() ).second; + TopoDS_Edge edge2 = HERE::GetPropagationEdge( theMesh1, *eIt2, edges1.front() ).second; if ( !edge2.IsNull() ) { // propagation found for the second edge Reverse( edges2, nbEdges ); return true; @@ -202,14 +227,200 @@ namespace { } return TopoDS_Shape(); } -} + + //================================================================================ + /*! + * \brief Find association of groups at top and bottom of prism + */ + //================================================================================ + + bool AssocGroupsByPropagation(const TopoDS_Shape& theGroup1, + const TopoDS_Shape& theGroup2, + SMESH_Mesh& theMesh, + HERE::TShapeShapeMap& theMap) + { + // If groups are on top and bottom of prism then we can associate + // them using "vertical" (or "side") edges and faces of prism since + // they connect corresponding vertices and edges of groups. + + TopTools_IndexedMapOfShape subshapes1, subshapes2; + TopExp::MapShapes( theGroup1, subshapes1 ); + TopExp::MapShapes( theGroup2, subshapes2 ); + TopTools_ListIteratorOfListOfShape ancestIt; + + // Iterate on vertices of group1 to find corresponding vertices in group2 + // and associate adjacent edges and faces + + TopTools_MapOfShape verticShapes; + TopExp_Explorer vExp1( theGroup1, TopAbs_VERTEX ); + for ( ; vExp1.More(); vExp1.Next() ) + { + const TopoDS_Vertex& v1 = TopoDS::Vertex( vExp1.Current() ); + if ( theMap.IsBound( v1 )) continue; // already processed + + // Find "vertical" edge ending in v1 and whose other vertex belongs to group2 + TopoDS_Shape verticEdge, v2; + ancestIt.Initialize( theMesh.GetAncestors( v1 )); + for ( ; verticEdge.IsNull() && ancestIt.More(); ancestIt.Next() ) + { + if ( ancestIt.Value().ShapeType() != TopAbs_EDGE ) continue; + v2 = HERE::GetNextVertex( TopoDS::Edge( ancestIt.Value() ), v1 ); + if ( subshapes2.Contains( v2 )) + verticEdge = ancestIt.Value(); + } + if ( verticEdge.IsNull() ) + return false; + + HERE::InsertAssociation( v1, v2, theMap); + + // Associate edges by vertical faces sharing the found vertical edge + ancestIt.Initialize( theMesh.GetAncestors( verticEdge ) ); + for ( ; ancestIt.More(); ancestIt.Next() ) + { + if ( ancestIt.Value().ShapeType() != TopAbs_FACE ) continue; + if ( !verticShapes.Add( ancestIt.Value() )) continue; + const TopoDS_Face& face = TopoDS::Face( ancestIt.Value() ); + + // get edges of the face + TopoDS_Edge edgeGr1, edgeGr2, verticEdge2; + list< TopoDS_Edge > edges; list< int > nbEdgesInWire; + SMESH_Block::GetOrderedEdges( face, v1, edges, nbEdgesInWire); + if ( nbEdgesInWire.front() != 4 ) + return _StoreBadShape( face ); + list< TopoDS_Edge >::iterator edge = edges.begin(); + if ( verticEdge.IsSame( *edge )) { + edgeGr2 = *(++edge); + verticEdge2 = *(++edge); + edgeGr1 = *(++edge); + } else { + edgeGr1 = *(edge++); + verticEdge2 = *(edge++); + edgeGr2 = *(edge++); + } + + HERE::InsertAssociation( edgeGr1, edgeGr2.Reversed(), theMap); + } + } + + // Associate faces + TopoDS_Iterator gr1It( theGroup1 ); + if ( gr1It.Value().ShapeType() == TopAbs_FACE ) + { + // find a boundary edge of group1 to start from + TopoDS_Shape bndEdge = StdMeshers_ProjectionUtils::GetBoundaryEdge( theGroup1, theMesh ); + if ( bndEdge.IsNull() ) + return false; + + list< TopoDS_Shape > edges(1, bndEdge); + list< TopoDS_Shape >::iterator edge1 = edges.begin(); + for ( ; edge1 != edges.end(); ++edge1 ) + { + // there must be one or zero not associated faces between ancestors of edge + // belonging to theGroup1 + TopoDS_Shape face1; + ancestIt.Initialize( theMesh.GetAncestors( *edge1 ) ); + for ( ; ancestIt.More() && face1.IsNull(); ancestIt.Next() ) { + if ( ancestIt.Value().ShapeType() == TopAbs_FACE && + !theMap.IsBound( ancestIt.Value() ) && + subshapes1.Contains( ancestIt.Value() )) + face1 = ancestIt.Value(); + + // add edges of face1 to start searching for adjacent faces from + for ( TopExp_Explorer e(face1, TopAbs_EDGE); e.More(); e.Next()) + if ( !edge1->IsSame( e.Current() )) + edges.push_back( e.Current() ); + } + if ( !face1.IsNull() ) { + // find the corresponding face of theGroup2 + TopoDS_Shape edge2 = theMap( *edge1 ); + TopoDS_Shape face2; + ancestIt.Initialize( theMesh.GetAncestors( edge2 ) ); + for ( ; ancestIt.More() && face2.IsNull(); ancestIt.Next() ) { + if ( ancestIt.Value().ShapeType() == TopAbs_FACE && + !theMap.IsBound( ancestIt.Value(), /*is2nd=*/true ) && + subshapes2.Contains( ancestIt.Value() )) + face2 = ancestIt.Value(); + } + if ( face2.IsNull() ) + return false; + + HERE::InsertAssociation( face1, face2, theMap); + } + } + } + return true; + } + + //================================================================================ + /*! + * \brief Return true if uv position of the vIndex-th vertex of edge on face is close + * enough to given uv + */ + //================================================================================ + + bool sameVertexUV( const TopoDS_Edge& edge, + const TopoDS_Face& face, + const int& vIndex, + const gp_Pnt2d& uv, + const double& tol2d ) + { + TopoDS_Vertex VV[2]; + TopExp::Vertices( edge, VV[0], VV[1], true); + gp_Pnt2d v1UV = BRep_Tool::Parameters( VV[vIndex], face); + double dist2d = v1UV.Distance( uv ); + return dist2d < tol2d; + } + + //================================================================================ + /*! + * \brief Returns an EDGE suitable for search of initial vertex association + */ + //================================================================================ + + TopoDS_Shape getOuterEdge( const TopoDS_Shape theShape1, SMESH_Mesh& mesh ) + { + TopoDS_Shape edge; + if ( theShape1.ShapeType() == TopAbs_COMPOUND ) + { + TopoDS_Iterator it( theShape1 ); + if ( it.Value().ShapeType() == TopAbs_FACE ) // group of FACEs + { + // look for a boundary EDGE of a group + edge = StdMeshers_ProjectionUtils::GetBoundaryEdge( theShape1, mesh ); + if ( !edge.IsNull() ) + return edge; + } + } + edge = theShape1; + TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE; + if ( expF.More() ) { + for ( ; expF.More(); expF.Next() ) { + edge.Nullify(); + TopoDS_Shape wire = + StdMeshers_ProjectionUtils::OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE ); + for ( expE.Init( wire, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() ) + if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() ))) + edge = expE.Current(); + if ( !edge.IsNull() ) + break; + } + } else if (edge.ShapeType() != TopAbs_EDGE) { // no faces + edge.Nullify(); + for ( expE.Init( theShape1, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() ) + if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() ))) + edge = expE.Current(); + } + return edge; + } + +} // namespace //======================================================================= /*! - * \brief Looks for association of all subshapes of two shapes - * \param theShape1 - shape 1 + * \brief Looks for association of all sub-shapes of two shapes + * \param theShape1 - target shape * \param theMesh1 - mesh built on shape 1 - * \param theShape2 - shape 2 + * \param theShape2 - source shape * \param theMesh2 - mesh built on shape 2 * \param theAssociation - association map to be filled that may * contain association of one or two pairs of vertices @@ -223,8 +434,31 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the SMESH_Mesh* theMesh2, TShapeShapeMap & theMap) { + // Structure of this long function is following + // 1) Group->group projection: theShape1 is a group member, + // theShape2 is a group. We find a group theShape1 is in and recall self. + // 2) Accosiate same shapes with different location (partners). + // 3) If vertex association is given, perform accosiation according to shape type: + // switch ( ShapeType ) { + // case TopAbs_EDGE: + // case ...: + // } + // 4) else try to accosiate in different ways: + // a) accosiate shapes by propagation and other simple cases + // switch ( ShapeType ) { + // case TopAbs_EDGE: + // case ...: + // } + // b) find association of a couple of vertices and recall self. + // + + theMeshDS[0] = theMesh1->GetMeshDS(); // debug + theMeshDS[1] = theMesh2->GetMeshDS(); + + // ================================================================================= + // 1) Is it the case of associating a group member -> another group? (PAL16202, 16203) + // ================================================================================= if ( theShape1.ShapeType() != theShape2.ShapeType() ) { - // is it the case of a group member -> another group? (PAL16202, 16203) TopoDS_Shape group1, group2; if ( theShape1.ShapeType() == TopAbs_COMPOUND ) { group1 = theShape1; @@ -240,11 +474,34 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the return FindSubShapeAssociation(group1, theMesh1, group2, theMesh2, theMap ); } - bool bidirect = ( !theShape1.IsSame( theShape2 )); + // ============ + // 2) Is partner? + // ============ + bool partner = theShape1.IsPartner( theShape2 ); + TopTools_DataMapIteratorOfDataMapOfShapeShape vvIt( theMap._map1to2 ); + for ( ; partner && vvIt.More(); vvIt.Next() ) + partner = vvIt.Key().IsPartner( vvIt.Value() ); + + if ( partner ) // Same shape with different location + { + // recursively associate all sub-shapes of theShape1 and theShape2 + typedef list< pair< TopoDS_Shape, TopoDS_Shape > > TShapePairsList; + TShapePairsList shapesQueue( 1, make_pair( theShape1, theShape2 )); + TShapePairsList::iterator s1_s2 = shapesQueue.begin(); + for ( ; s1_s2 != shapesQueue.end(); ++s1_s2 ) + { + InsertAssociation( s1_s2->first, s1_s2->second, theMap ); + TopoDS_Iterator s1It( s1_s2->first), s2It( s1_s2->second ); + for ( ; s1It.More(); s1It.Next(), s2It.Next() ) + shapesQueue.push_back( make_pair( s1It.Value(), s2It.Value() )); + } + return true; + } + if ( !theMap.IsEmpty() ) { //====================================================================== - // HAS initial vertex association + // 3) HAS initial vertex association //====================================================================== switch ( theShape1.ShapeType() ) { // ---------------------------------------------------------------------- @@ -254,14 +511,16 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the RETURN_BAD_RESULT("Wrong map extent " << theMap.Extent() ); TopoDS_Edge edge1 = TopoDS::Edge( theShape1 ); TopoDS_Edge edge2 = TopoDS::Edge( theShape2 ); + if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD ); + if ( edge2.Orientation() >= TopAbs_INTERNAL ) edge2.Orientation( TopAbs_FORWARD ); TopoDS_Vertex VV1[2], VV2[2]; TopExp::Vertices( edge1, VV1[0], VV1[1] ); TopExp::Vertices( edge2, VV2[0], VV2[1] ); int i1 = 0, i2 = 0; if ( theMap.IsBound( VV1[ i1 ] )) i1 = 1; if ( theMap.IsBound( VV2[ i2 ] )) i2 = 1; - InsertAssociation( VV1[ i1 ], VV2[ i2 ], theMap, bidirect); - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + InsertAssociation( VV1[ i1 ], VV2[ i2 ], theMap ); + InsertAssociation( theShape1, theShape2, theMap ); return true; } // ---------------------------------------------------------------------- @@ -269,6 +528,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // ---------------------------------------------------------------------- TopoDS_Face face1 = TopoDS::Face( theShape1 ); TopoDS_Face face2 = TopoDS::Face( theShape2 ); + if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD ); + if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD ); TopoDS_Vertex VV1[2], VV2[2]; // find a not closed edge of face1 both vertices of which are associated @@ -298,12 +559,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the list< TopoDS_Edge >::iterator eIt2 = edges2.begin(); for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) { - InsertAssociation( *eIt1, *eIt2, theMap, bidirect); + InsertAssociation( *eIt1, *eIt2, theMap ); VV1[0] = TopExp::FirstVertex( *eIt1, true ); VV2[0] = TopExp::FirstVertex( *eIt2, true ); - InsertAssociation( VV1[0], VV2[0], theMap, bidirect); + InsertAssociation( VV1[0], VV2[0], theMap ); } - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + InsertAssociation( theShape1, theShape2, theMap ); return true; } // ---------------------------------------------------------------------- @@ -311,11 +572,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the case TopAbs_SOLID: { // ---------------------------------------------------------------------- TopoDS_Vertex VV1[2], VV2[2]; - // find a not closed edge of shape1 both vertices of which are associated + // try to find a not closed edge of shape1 both vertices of which are associated TopoDS_Edge edge1; TopExp_Explorer exp ( theShape1, TopAbs_EDGE ); for ( ; VV2[ 1 ].IsNull() && exp.More(); exp.Next() ) { edge1 = TopoDS::Edge( exp.Current() ); + if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD ); TopExp::Vertices( edge1 , VV1[0], VV1[1] ); if ( theMap.IsBound( VV1[0] )) { VV2[ 0 ] = TopoDS::Vertex( theMap( VV1[0] )); @@ -325,11 +587,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } if ( VV2[ 1 ].IsNull() ) // 2 bound vertices not found RETURN_BAD_RESULT("2 bound vertices not found" ); + // get an edge2 of theShape2 corresponding to edge1 TopoDS_Edge edge2 = GetEdgeByVertices( theMesh2, VV2[ 0 ], VV2[ 1 ]); if ( edge2.IsNull() ) RETURN_BAD_RESULT("GetEdgeByVertices() failed"); - // build map of edge to faces if shapes are not subshapes of main ones + // build map of edge to faces if shapes are not sub-shapes of main ones bool isSubOfMain = false; if ( SMESHDS_SubMesh * sm = theMesh1->GetMeshDS()->MeshElements( theShape1 )) isSubOfMain = !sm->IsComplexSubmesh(); @@ -382,7 +645,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopExp::Vertices( edge1, VV1[0], VV1[1], true ); TopExp::Vertices( edge2, VV2[0], VV2[1], true ); F2 = FF2[ 0 ]; // (F2 !) - if ( !VV1[ 0 ].IsSame( theMap( VV2[ 0 ]))) { + if ( !VV1[ 0 ].IsSame( theMap( VV2[ 0 ], /*is2=*/true))) { edge2.Reverse(); if ( FF2[ 1 ].IsNull() ) F2.Reverse(); @@ -392,7 +655,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopTools_MapOfShape boundEdges; - // association of face subshapes and neighbour faces + // association of face sub-shapes and neighbour faces list< pair < TopoDS_Face, TopoDS_Edge > > FE1, FE2; list< pair < TopoDS_Face, TopoDS_Edge > >::iterator fe1, fe2; FE1.push_back( make_pair( TopoDS::Face( F1 ), edge1 )); @@ -409,7 +672,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the list< TopoDS_Edge > edges1, edges2; int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); - InsertAssociation( face1, face2, theMap, bidirect); // assoc faces + InsertAssociation( face1, face2, theMap ); // assoc faces MESSAGE("Assoc FACE " << theMesh1->GetMeshDS()->ShapeToIndex( face1 )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( face2 )); if ( nbE == 2 && (edge1.IsSame( edges1.front())) != (edge2.IsSame( edges2.front()))) @@ -421,12 +684,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) { if ( !boundEdges.Add( *eIt1 )) continue; // already associated - InsertAssociation( *eIt1, *eIt2, theMap, bidirect); // assoc edges + InsertAssociation( *eIt1, *eIt2, theMap ); // assoc edges MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( *eIt1 )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( *eIt2 )); VV1[0] = TopExp::FirstVertex( *eIt1, true ); VV2[0] = TopExp::FirstVertex( *eIt2, true ); - InsertAssociation( VV1[0], VV2[0], theMap, bidirect); // assoc vertices + InsertAssociation( VV1[0], VV2[0], theMap ); // assoc vertices MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[0] )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( VV2[0] )); @@ -439,7 +702,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } } } - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + InsertAssociation( theShape1, theShape2, theMap ); return true; } // ---------------------------------------------------------------------- @@ -478,7 +741,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !initAssocOK ) { // for shell association there must be an edge with both vertices bound TopoDS_Vertex v1, v2; - TopExp::Vertices( TopoDS::Edge( it1.Value()), v1, v2 ); + TopExp::Vertices( TopoDS::Edge( it1.Value().Oriented(TopAbs_FORWARD)), v1, v2 ); initAssocOK = ( theMap.IsBound( v1 ) && theMap.IsBound( v2 )); } } @@ -561,7 +824,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TShapeShapeMap tmpMap; ok = FindSubShapeAssociation( comp[0], theMesh1, comp[1], theMesh2, tmpMap ); if ( ok ) { - TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt( tmpMap ); + TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt( tmpMap._map1to2 ); for ( ; mapIt.More(); mapIt.Next() ) theMap.Bind( mapIt.Key(), mapIt.Value()); } @@ -620,13 +883,13 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopoDS_Edge e1 = TopoDS::Edge( edges1.First() ); v2e[0].UnBind( V[0] ); v2e[1].UnBind( V[1] ); - InsertAssociation( e0, e1, theMap, bidirect ); + InsertAssociation( e0, e1, theMap ); MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0 )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1 )); V[0] = GetNextVertex( e0, V[0] ); V[1] = GetNextVertex( e1, V[1] ); if ( !V[0].IsNull() ) { - InsertAssociation( V[0], V[1], theMap, bidirect ); + InsertAssociation( V[0], V[1], theMap ); MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( V[0] )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( V[1] )); } @@ -652,9 +915,9 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } else { v1n = v1e1; e1b = edges1.First(); e1n = edges1.Last(); } - InsertAssociation( e0b, e1b, theMap, bidirect ); - InsertAssociation( e0n, e1n, theMap, bidirect ); - InsertAssociation( v0n, v1n, theMap, bidirect ); + InsertAssociation( e0b, e1b, theMap ); + InsertAssociation( e0n, e1n, theMap ); + InsertAssociation( v0n, v1n, theMap ); MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0b )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1b )); MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0n )<< @@ -681,7 +944,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } // end case of available initial vertex association //====================================================================== - // NO INITIAL VERTEX ASSOCIATION + // 4) NO INITIAL VERTEX ASSOCIATION //====================================================================== switch ( theShape1.ShapeType() ) { @@ -698,24 +961,25 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopoDS_Vertex VV1[2], VV2[2]; TopExp::Vertices( edge1, VV1[0], VV1[1], true ); TopExp::Vertices( prpEdge, VV2[0], VV2[1], true ); - InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap, bidirect); - InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap, bidirect); + InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap ); + InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap ); if ( VV1[0].IsSame( VV1[1] ) || // one of edges is closed VV2[0].IsSame( VV2[1] ) ) { - InsertAssociation( edge1, prpEdge, theMap, bidirect); // insert with a proper orientation + InsertAssociation( edge1, prpEdge, theMap ); // insert with a proper orientation } - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + InsertAssociation( theShape1, theShape2, theMap ); return true; // done } } - if ( IsClosedEdge( edge1 ) && IsClosedEdge( edge2 )) + if ( SMESH_MesherHelper::IsClosedEdge( edge1 ) && + SMESH_MesherHelper::IsClosedEdge( edge2 )) { // TODO: find out a proper orientation (is it possible?) - InsertAssociation( edge1, edge2, theMap, bidirect); // insert with a proper orientation + InsertAssociation( edge1, edge2, theMap ); // insert with a proper orientation InsertAssociation( TopExp::FirstVertex(edge1), TopExp::FirstVertex(edge2), - theMap, bidirect); - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + theMap ); + InsertAssociation( theShape1, theShape2, theMap ); return true; // done } break; // try by vertex closeness @@ -727,6 +991,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the { TopoDS_Face face1 = TopoDS::Face(theShape1); TopoDS_Face face2 = TopoDS::Face(theShape2); + if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD ); + if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD ); TopoDS_Edge edge1, edge2; // get outer edge of theShape1 edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_EDGE )); @@ -737,6 +1003,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the pair step_edge = GetPropagationEdge( theMesh1, edge2, edge1 ); if ( !step_edge.second.IsNull() ) { // propagation found propag_edges.insert( step_edge ); + if ( step_edge.first == 1 ) break; // most close found } } if ( !propag_edges.empty() ) // propagation found @@ -748,25 +1015,26 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the list< TopoDS_Edge > edges1, edges2; int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 ); if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); - if ( nbE == 2 ) // only 2 edges + // take care of proper association of propagated edges + bool same1 = edge1.IsSame( edges1.front() ); + bool same2 = edge2.IsSame( edges2.front() ); + if ( same1 != same2 ) { - // take care of proper association of propagated edges - bool same1 = edge1.IsSame( edges1.front() ); - bool same2 = edge2.IsSame( edges2.front() ); - if ( same1 != same2 ) - Reverse(edges2, nbE); + Reverse(edges2, nbE); + if ( nbE != 2 ) // 2 degen edges of 4 (issue 0021144) + edges2.splice( edges2.end(), edges2, edges2.begin()); } // store association list< TopoDS_Edge >::iterator eIt1 = edges1.begin(); list< TopoDS_Edge >::iterator eIt2 = edges2.begin(); for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) { - InsertAssociation( *eIt1, *eIt2, theMap, bidirect); + InsertAssociation( *eIt1, *eIt2, theMap ); VV1[0] = TopExp::FirstVertex( *eIt1, true ); VV2[0] = TopExp::FirstVertex( *eIt2, true ); - InsertAssociation( VV1[0], VV2[0], theMap, bidirect); + InsertAssociation( VV1[0], VV2[0], theMap ); } - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + InsertAssociation( theShape1, theShape2, theMap ); return true; } } @@ -775,25 +1043,16 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the case TopAbs_COMPOUND: { // ---------------------------------------------------------------------- if ( IsPropagationPossible( theMesh1, theMesh2 )) { - // find a boundary edge for theShape1 - TopoDS_Edge E; - for(TopExp_Explorer exp(theShape1, TopAbs_EDGE); exp.More(); exp.Next() ) { - E = TopoDS::Edge( exp.Current() ); - int NbFacesFromShape1 = 0; - const TopTools_ListOfShape& EAncestors = theMesh1->GetAncestors(E); - TopTools_ListIteratorOfListOfShape itea(EAncestors); - for(; itea.More(); itea.Next()) { - if( itea.Value().ShapeType() != TopAbs_FACE ) continue; - TopoDS_Face face = TopoDS::Face(itea.Value()); - for(TopExp_Explorer expf(theShape1, TopAbs_FACE); expf.More(); expf.Next() ) { - if(face.IsSame(expf.Current())) { - NbFacesFromShape1++; - break; - } - } - } - if(NbFacesFromShape1==1) break; - } + + // try to accosiate all using propagation + if ( AssocGroupsByPropagation( theShape1, theShape2, *theMesh1, theMap )) + return true; + + // find a boundary edge of theShape1 + TopoDS_Edge E = GetBoundaryEdge( theShape1, *theMesh1 ); + if ( E.IsNull() ) + break; // try by vertex closeness + // find association for vertices of edge E TopoDS_Vertex VV1[2], VV2[2]; for(TopExp_Explorer eexp(E, TopAbs_VERTEX); eexp.More(); eexp.Next()) { @@ -838,8 +1097,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } } if ( !VV1[1].IsNull() ) { - InsertAssociation( VV1[0], VV2[0], theMap, bidirect); - InsertAssociation( VV1[1], VV2[1], theMap, bidirect); + InsertAssociation( VV1[0], VV2[0], theMap ); + InsertAssociation( VV1[1], VV2[1], theMap ); return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap); } } @@ -848,25 +1107,52 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the default:; } - // Find association by closeness of vertices - // ------------------------------------------ + // 4.b) Find association by closeness of vertices + // ---------------------------------------------- TopTools_IndexedMapOfShape vMap1, vMap2; TopExp::MapShapes( theShape1, TopAbs_VERTEX, vMap1 ); TopExp::MapShapes( theShape2, TopAbs_VERTEX, vMap2 ); + TopoDS_Vertex VV1[2], VV2[2]; if ( vMap1.Extent() != vMap2.Extent() ) RETURN_BAD_RESULT("Different nb of vertices"); if ( vMap1.Extent() == 1 ) { - InsertAssociation( vMap1(1), vMap2(1), theMap, bidirect); + InsertAssociation( vMap1(1), vMap2(1), theMap ); if ( theShape1.ShapeType() == TopAbs_EDGE ) { - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + InsertAssociation( theShape1, theShape2, theMap ); return true; } return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap); } + // Try to associate by common vertices of an edge + for ( int i = 1; i <= vMap1.Extent(); ++i ) + { + const TopoDS_Shape& v1 = vMap1(i); + if ( vMap2.Contains( v1 )) + { + // find an egde sharing v1 and sharing at the same time another common vertex + PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( v1, *theMesh1, TopAbs_EDGE); + bool edgeFound = false; + while ( edgeIt->more() && !edgeFound ) + { + TopoDS_Edge edge = TopoDS::Edge( edgeIt->next()->Oriented(TopAbs_FORWARD)); + TopExp::Vertices(edge, VV1[0], VV1[1]); + if ( !VV1[0].IsSame( VV1[1] )) + edgeFound = ( vMap2.Contains( VV1[ v1.IsSame(VV1[0]) ? 1:0])); + } + if ( edgeFound ) + { + InsertAssociation( VV1[0], VV1[0], theMap ); + InsertAssociation( VV1[1], VV1[1], theMap ); + if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) + return true; + } + } + } + // Find transformation to make the shapes be of similar size at same location Bnd_Box box[2]; @@ -888,30 +1174,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // Find 2 closest vertices - TopoDS_Vertex VV1[2], VV2[2]; // get 2 linked vertices of shape 1 not belonging to an inner wire of a face - TopoDS_Shape edge = theShape1; - TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE; - if ( expF.More() ) { - for ( ; expF.More(); expF.Next() ) { - edge.Nullify(); - TopoDS_Shape wire = OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE ); - for ( expE.Init( wire, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() ) - if ( !IsClosedEdge( TopoDS::Edge( expE.Current() ))) - edge = expE.Current(); - if ( !edge.IsNull() ) - break; - } - } else if (edge.ShapeType() != TopAbs_EDGE) { // no faces - edge.Nullify(); - for ( expE.Init( theShape1, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() ) - if ( !IsClosedEdge( TopoDS::Edge( expE.Current() ))) - edge = expE.Current(); - } + TopoDS_Shape edge = getOuterEdge( theShape1, *theMesh1 ); if ( edge.IsNull() || edge.ShapeType() != TopAbs_EDGE ) RETURN_BAD_RESULT("Edge not found"); - TopExp::Vertices( TopoDS::Edge( edge ), VV1[0], VV1[1]); + TopExp::Vertices( TopoDS::Edge( edge.Oriented(TopAbs_FORWARD)), VV1[0], VV1[1]); if ( VV1[0].IsSame( VV1[1] )) RETURN_BAD_RESULT("Only closed edges"); @@ -933,14 +1201,14 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } } - InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap, bidirect); - InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap, bidirect); + InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap ); + InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap ); MESSAGE("Initial assoc VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 0 ] )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 0 ] )<< "\nand VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 1 ] )<< " to " << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 1 ] )); if ( theShape1.ShapeType() == TopAbs_EDGE ) { - InsertAssociation( theShape1, theShape2, theMap, bidirect ); + InsertAssociation( theShape1, theShape2, theMap ); return true; } @@ -953,75 +1221,153 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the * \param face1 - face 1 * \param VV1 - vertices of face 1 * \param face2 - face 2 - * \param VV2 - vertices of face 2 associated with oned of face 1 + * \param VV2 - vertices of face 2 associated with ones of face 1 * \param edges1 - out list of edges of face 1 * \param edges2 - out list of edges of face 2 * \retval int - nb of edges in an outer wire in a success case, else zero */ //================================================================================ -int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, - TopoDS_Vertex VV1[2], - const TopoDS_Face& face2, - TopoDS_Vertex VV2[2], +int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, + TopoDS_Vertex VV1[2], + const TopoDS_Face& face2, + TopoDS_Vertex VV2[2], list< TopoDS_Edge > & edges1, list< TopoDS_Edge > & edges2) { - edges1.clear(); - edges2.clear(); - - list< int > nbVInW1, nbVInW2; - if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbVInW1) != - SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbVInW2) ) - RETURN_BAD_RESULT("Different number of wires in faces "); - - if ( nbVInW1.front() != nbVInW2.front() ) - RETURN_BAD_RESULT("Different number of edges in faces: " << - nbVInW1.front() << " != " << nbVInW2.front()); - - // Define if we need to reverse one of wires to make edges in lists match each other - - bool reverse = false; - - list< TopoDS_Edge >::iterator eBackIt; - if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) { - reverse = true; - eBackIt = --edges1.end(); - // check if the second vertex belongs to the first or last edge in the wire - if ( !VV1[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) { - bool KO = true; // belongs to none - if ( nbVInW1.size() > 1 ) { // several wires - eBackIt = edges1.begin(); - for ( int i = 1; i < nbVInW1.front(); ++i ) ++eBackIt; - KO = !VV1[1].IsSame( TopExp::FirstVertex( *eBackIt, true )); + bool OK = false; + list< int > nbEInW1, nbEInW2; + int i_ok_wire_algo = -1; + for ( int outer_wire_algo = 0; outer_wire_algo < 2 && !OK; ++outer_wire_algo ) + { + edges1.clear(); + edges2.clear(); + + if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, outer_wire_algo) != + SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, outer_wire_algo) ) + CONT_BAD_RESULT("Different number of wires in faces "); + + if ( nbEInW1 != nbEInW2 ) + CONT_BAD_RESULT("Different number of edges in faces: " << + nbEInW1.front() << " != " << nbEInW2.front()); + + i_ok_wire_algo = outer_wire_algo; + + // Define if we need to reverse one of wires to make edges in lists match each other + + bool reverse = false; + + list< TopoDS_Edge >::iterator edgeIt; + if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) { + reverse = true; + edgeIt = --edges1.end(); + // check if the second vertex belongs to the first or last edge in the wire + if ( !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { + bool KO = true; // belongs to none + if ( nbEInW1.size() > 1 ) { // several wires + edgeIt = edges1.begin(); + std::advance( edgeIt, nbEInW1.front()-1 ); + KO = !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); + } + if ( KO ) + CONT_BAD_RESULT("GetOrderedEdges() failed"); } - if ( KO ) - RETURN_BAD_RESULT("GetOrderedEdges() failed"); } - } - eBackIt = --edges2.end(); - if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) { - reverse = !reverse; - // check if the second vertex belongs to the first or last edge in the wire - if ( !VV2[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) { - bool KO = true; // belongs to none - if ( nbVInW2.size() > 1 ) { // several wires - eBackIt = edges2.begin(); - for ( int i = 1; i < nbVInW2.front(); ++i ) ++eBackIt; - KO = !VV2[1].IsSame( TopExp::FirstVertex( *eBackIt, true )); + edgeIt = --edges2.end(); + if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) { + reverse = !reverse; + // check if the second vertex belongs to the first or last edge in the wire + if ( !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { + bool KO = true; // belongs to none + if ( nbEInW2.size() > 1 ) { // several wires + edgeIt = edges2.begin(); + std::advance( edgeIt, nbEInW2.front()-1 ); + KO = !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); + } + if ( KO ) + CONT_BAD_RESULT("GetOrderedEdges() failed"); } - if ( KO ) - RETURN_BAD_RESULT("GetOrderedEdges() failed"); } - } - if ( reverse ) + if ( reverse ) + { + Reverse( edges2 , nbEInW2.front()); + if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) != + ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true )))) + CONT_BAD_RESULT("GetOrderedEdges() failed"); + } + OK = true; + + } // loop algos getting an outer wire + + // Try to orient all (if !OK) or only internal wires (issue 0020996) by UV similarity + if (( !OK || nbEInW1.size() > 1 ) && i_ok_wire_algo > -1 ) { - Reverse( edges2 , nbVInW2.front()); - if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) != - ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true )))) - RETURN_BAD_RESULT("GetOrderedEdges() failed"); + // Check that Vec(VV1[0],VV1[1]) in 2D on face1 is the same + // as Vec(VV2[0],VV2[1]) on face2 + double vTol = BRep_Tool::Tolerance( VV1[0] ); + BRepAdaptor_Surface surface1( face1, false ); + double vTolUV = + surface1.UResolution( vTol ) + surface1.VResolution( vTol ); // let's be tolerant + gp_Pnt2d v0f1UV = BRep_Tool::Parameters( VV1[0], face1 ); + gp_Pnt2d v0f2UV = BRep_Tool::Parameters( VV2[0], face2 ); + gp_Pnt2d v1f1UV = BRep_Tool::Parameters( VV1[1], face1 ); + gp_Pnt2d v1f2UV = BRep_Tool::Parameters( VV2[1], face2 ); + gp_Vec2d v01f1Vec( v0f1UV, v1f1UV ); + gp_Vec2d v01f2Vec( v0f2UV, v1f2UV ); + if ( Abs( v01f1Vec.X()-v01f2Vec.X()) < vTolUV && + Abs( v01f1Vec.Y()-v01f2Vec.Y()) < vTolUV ) + { + if ( !OK /*i_ok_wire_algo != 1*/ ) + { + edges1.clear(); + edges2.clear(); + SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, i_ok_wire_algo); + SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, i_ok_wire_algo); + } + gp_XY dUV = v0f2UV.XY() - v0f1UV.XY(); // UV shift between 2 faces + // skip edges of the outer wire (if the outer wire is OK) + list< int >::iterator nbEInW = nbEInW1.begin(); + list< TopoDS_Edge >::iterator edge1Beg = edges1.begin(), edge2Beg = edges2.begin(); + if ( OK ) + { + for ( int i = 0; i < *nbEInW; ++i ) + ++edge1Beg, ++edge2Beg; + ++nbEInW; + } + for ( ; nbEInW != nbEInW1.end(); ++nbEInW ) // loop on wires + { + // reach an end of edges of a current wire + list< TopoDS_Edge >::iterator edge1End = edge1Beg, edge2End = edge2Beg; + for ( int i = 0; i < *nbEInW; ++i ) + ++edge1End, ++edge2End; + // rotate edges2 untill coincident with edges1 in 2D + v0f1UV = BRep_Tool::Parameters( TopExp::FirstVertex(*edge1Beg,true), face1 ); + v1f1UV = BRep_Tool::Parameters( TopExp::LastVertex (*edge1Beg,true), face1 ); + v0f1UV.ChangeCoord() += dUV; + v1f1UV.ChangeCoord() += dUV; + int i = *nbEInW; + while ( --i > 0 && !sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + edges2.splice( edge2End, edges2, edge2Beg++ ); // move edge2Beg to place before edge2End + if ( sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + { + if ( nbEInW == nbEInW1.begin() ) + OK = true; // OK is for the first wire + // reverse edges2 if needed + if ( !sameVertexUV( *edge2Beg, face2, 1, v1f1UV, vTolUV )) + { + Reverse( edges2 , *nbEInW, distance( edges2.begin(),edge2Beg )); + // set correct edge2End + edge2End = edges2.begin(); + std::advance( edge2End, std::accumulate( nbEInW1.begin(), nbEInW, *nbEInW)); + } + } + // prepare to the next wire loop + edge1Beg = edge1End, edge2Beg = edge2End; + } + } } - return nbVInW2.front(); + + return OK ? nbEInW1.front() : 0; } //======================================================================= @@ -1030,30 +1376,29 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, //======================================================================= void StdMeshers_ProjectionUtils::InitVertexAssociation( const SMESH_Hypothesis* theHyp, - TShapeShapeMap & theAssociationMap, - const TopoDS_Shape& theTargetShape) + TShapeShapeMap & theAssociationMap) { string hypName = theHyp->GetName(); if ( hypName == "ProjectionSource1D" ) { const StdMeshers_ProjectionSource1D * hyp = static_cast( theHyp ); if ( hyp->HasVertexAssociation() ) - InsertAssociation( hyp->GetSourceVertex(),hyp->GetTargetVertex(),theAssociationMap); + InsertAssociation( hyp->GetTargetVertex(),hyp->GetSourceVertex(),theAssociationMap ); } else if ( hypName == "ProjectionSource2D" ) { const StdMeshers_ProjectionSource2D * hyp = static_cast( theHyp ); if ( hyp->HasVertexAssociation() ) { - InsertAssociation( hyp->GetSourceVertex(1),hyp->GetTargetVertex(1),theAssociationMap); - InsertAssociation( hyp->GetSourceVertex(2),hyp->GetTargetVertex(2),theAssociationMap); + InsertAssociation( hyp->GetTargetVertex(1),hyp->GetSourceVertex(1),theAssociationMap); + InsertAssociation( hyp->GetTargetVertex(2),hyp->GetSourceVertex(2),theAssociationMap); } } else if ( hypName == "ProjectionSource3D" ) { const StdMeshers_ProjectionSource3D * hyp = static_cast( theHyp ); if ( hyp->HasVertexAssociation() ) { - InsertAssociation( hyp->GetSourceVertex(1),hyp->GetTargetVertex(1),theAssociationMap); - InsertAssociation( hyp->GetSourceVertex(2),hyp->GetTargetVertex(2),theAssociationMap); + InsertAssociation( hyp->GetTargetVertex(1),hyp->GetSourceVertex(1),theAssociationMap); + InsertAssociation( hyp->GetTargetVertex(2),hyp->GetSourceVertex(2),theAssociationMap); } } } @@ -1061,24 +1406,21 @@ void StdMeshers_ProjectionUtils::InitVertexAssociation( const SMESH_Hypothesis* //======================================================================= /*! * \brief Inserts association theShape1 <-> theShape2 to TShapeShapeMap - * \param theShape1 - shape 1 - * \param theShape2 - shape 2 + * \param theShape1 - target shape + * \param theShape2 - source shape * \param theAssociationMap - association map * \retval bool - true if there was no association for these shapes before */ //======================================================================= -bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape1, - const TopoDS_Shape& theShape2, - TShapeShapeMap & theAssociationMap, - const bool theBidirectional) +bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape1, // tgt + const TopoDS_Shape& theShape2, // src + TShapeShapeMap & theAssociationMap) { if ( !theShape1.IsNull() && !theShape2.IsNull() ) { - SHOW_VERTEX(theShape1,"Assoc "); - SHOW_VERTEX(theShape2," to "); + SHOW_SHAPE(theShape1,"Assoc "); + SHOW_SHAPE(theShape2," to "); bool isNew = ( theAssociationMap.Bind( theShape1, theShape2 )); - if ( theBidirectional ) - theAssociationMap.Bind( theShape2, theShape1 ); return isNew; } else { @@ -1087,44 +1429,6 @@ bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape return false; } -//======================================================================= -//function : IsSubShape -//purpose : -//======================================================================= - -bool StdMeshers_ProjectionUtils::IsSubShape( const TopoDS_Shape& shape, - SMESH_Mesh* aMesh ) -{ - if ( shape.IsNull() || !aMesh ) - return false; - return - aMesh->GetMeshDS()->ShapeToIndex( shape ) || - // PAL16202 - shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ); -} - -//======================================================================= -//function : IsSubShape -//purpose : -//======================================================================= - -bool StdMeshers_ProjectionUtils::IsSubShape( const TopoDS_Shape& shape, - const TopoDS_Shape& mainShape ) -{ - if ( !shape.IsNull() && !mainShape.IsNull() ) - { - for ( TopExp_Explorer exp( mainShape, shape.ShapeType()); - exp.More(); - exp.Next() ) - if ( shape.IsSame( exp.Current() )) - return true; - } - SCRUTE((shape.IsNull())); - SCRUTE((mainShape.IsNull())); - return false; -} - - //======================================================================= /*! * \brief Finds an edge by its vertices in a main shape of the mesh @@ -1210,7 +1514,7 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, const TopoDS_Edge& theEdge, const TopoDS_Edge& fromEdge) { - SMESH_IndexedMapOfShape aChain; + TopTools_IndexedMapOfShape aChain; int step = 0; // List of edges, added to chain on the previous cycle pass @@ -1286,7 +1590,7 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMesh, * \param mesh1 - mesh containing elements on the first face * \param face2 - the second face * \param mesh2 - mesh containing elements on the second face - * \param assocMap - map associating subshapes of the faces + * \param assocMap - map associating sub-shapes of the faces * \param node1To2Map - map containing found matching nodes * \retval bool - is a success */ @@ -1330,24 +1634,25 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, // 1. Nodes of corresponding links: // get 2 matching edges, try to find not seam ones - TopoDS_Edge edge1, edge2, seam1, seam2; + TopoDS_Edge edge1, edge2, seam1, seam2, anyEdge1, anyEdge2; TopExp_Explorer eE( OuterShape( face2, TopAbs_WIRE ), TopAbs_EDGE ); do { // edge 2 TopoDS_Edge e2 = TopoDS::Edge( eE.Current() ); eE.Next(); // edge 1 - if ( !assocMap.IsBound( e2 )) + if ( !assocMap.IsBound( e2, /*is2nd=*/true )) RETURN_BAD_RESULT("Association not found for edge " << meshDS2->ShapeToIndex( e2 )); - TopoDS_Edge e1 = TopoDS::Edge( assocMap( e2 )); - if ( !IsSubShape( e1, face1 )) + TopoDS_Edge e1 = TopoDS::Edge( assocMap( e2, /*is2nd=*/true )); + if ( !helper1.IsSubShape( e1, face1 )) RETURN_BAD_RESULT("Wrong association, edge " << meshDS1->ShapeToIndex( e1 ) << - " isn't a subshape of face " << meshDS1->ShapeToIndex( face1 )); + " isn't a sub-shape of face " << meshDS1->ShapeToIndex( face1 )); // check that there are nodes on edges SMESHDS_SubMesh * eSM1 = meshDS1->MeshElements( e1 ); SMESHDS_SubMesh * eSM2 = meshDS2->MeshElements( e2 ); bool nodesOnEdges = ( eSM1 && eSM2 && eSM1->NbNodes() && eSM2->NbNodes() ); // check that the nodes on edges belong to faces + // (as NETGEN ignores nodes on the degenerated geom edge) bool nodesOfFaces = false; if ( nodesOnEdges ) { const SMDS_MeshNode* n1 = eSM1->GetNodes()->next(); @@ -1364,18 +1669,25 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, edge1 = e1; edge2 = e2; } } + else { + anyEdge1 = e1; anyEdge2 = e2; + } } while ( edge2.IsNull() && eE.More() ); // if ( edge2.IsNull() ) { edge1 = seam1; edge2 = seam2; } - if ( edge2.IsNull() ) RETURN_BAD_RESULT("No matching edges with nodes found"); + bool hasNodesOnEdge = (! edge2.IsNull() ); + if ( !hasNodesOnEdge ) { + // 0020338 - nb segments == 1 + edge1 = anyEdge1; edge2 = anyEdge2; + } // get 2 matching vertices TopoDS_Vertex V2 = TopExp::FirstVertex( TopoDS::Edge( edge2 )); - if ( !assocMap.IsBound( V2 )) + if ( !assocMap.IsBound( V2, /*is2nd=*/true )) RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 )); - TopoDS_Vertex V1 = TopoDS::Vertex( assocMap( V2 )); + TopoDS_Vertex V1 = TopoDS::Vertex( assocMap( V2, /*is2nd=*/true )); // nodes on vertices const SMDS_MeshNode* vNode1 = SMESH_Algo::VertexNode( V1, meshDS1 ); @@ -1387,35 +1699,52 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, const SMDS_MeshNode* nullNode = 0; vector< const SMDS_MeshNode*> eNode1( 2, nullNode ); vector< const SMDS_MeshNode*> eNode2( 2, nullNode ); - int nbNodeToGet = 1; - if ( IsClosedEdge( edge1 ) || IsClosedEdge( edge2 ) ) - nbNodeToGet = 2; - for ( int is2 = 0; is2 < 2; ++is2 ) + if ( hasNodesOnEdge ) { - TopoDS_Edge & edge = is2 ? edge2 : edge1; - SMESHDS_Mesh * smDS = is2 ? meshDS2 : meshDS1; - SMESHDS_SubMesh* edgeSM = smDS->MeshElements( edge ); - // nodes linked with ones on vertices - const SMDS_MeshNode* vNode = is2 ? vNode2 : vNode1; - vector< const SMDS_MeshNode*>& eNode = is2 ? eNode2 : eNode1; - int nbGotNode = 0; - SMDS_ElemIteratorPtr vElem = vNode->GetInverseElementIterator(); - while ( vElem->more() && nbGotNode != nbNodeToGet ) { - const SMDS_MeshElement* elem = vElem->next(); - if ( elem->GetType() == SMDSAbs_Edge && edgeSM->Contains( elem )) - eNode[ nbGotNode++ ] = - ( elem->GetNode(0) == vNode ) ? elem->GetNode(1) : elem->GetNode(0); - } - if ( nbGotNode > 1 ) // sort found nodes by param on edge + int nbNodeToGet = 1; + if ( helper1.IsClosedEdge( edge1 ) || helper2.IsClosedEdge( edge2 ) ) + nbNodeToGet = 2; + for ( int is2 = 0; is2 < 2; ++is2 ) { - SMESH_MesherHelper* helper = is2 ? &helper2 : &helper1; - double u0 = helper->GetNodeU( edge, eNode[ 0 ]); - double u1 = helper->GetNodeU( edge, eNode[ 1 ]); - if ( u0 > u1 ) std::swap( eNode[ 0 ], eNode[ 1 ]); + TopoDS_Edge & edge = is2 ? edge2 : edge1; + SMESHDS_Mesh * smDS = is2 ? meshDS2 : meshDS1; + SMESHDS_SubMesh* edgeSM = smDS->MeshElements( edge ); + // nodes linked with ones on vertices + const SMDS_MeshNode* vNode = is2 ? vNode2 : vNode1; + vector< const SMDS_MeshNode*>& eNode = is2 ? eNode2 : eNode1; + int nbGotNode = 0; + SMDS_ElemIteratorPtr vElem = vNode->GetInverseElementIterator(SMDSAbs_Edge); + while ( vElem->more() && nbGotNode != nbNodeToGet ) { + const SMDS_MeshElement* elem = vElem->next(); + if ( edgeSM->Contains( elem )) + eNode[ nbGotNode++ ] = + ( elem->GetNode(0) == vNode ) ? elem->GetNode(1) : elem->GetNode(0); + } + if ( nbGotNode > 1 ) // sort found nodes by param on edge + { + SMESH_MesherHelper* helper = is2 ? &helper2 : &helper1; + double u0 = helper->GetNodeU( edge, eNode[ 0 ]); + double u1 = helper->GetNodeU( edge, eNode[ 1 ]); + if ( u0 > u1 ) std::swap( eNode[ 0 ], eNode[ 1 ]); + } + if ( nbGotNode == 0 ) + RETURN_BAD_RESULT("Found no nodes on edge " << smDS->ShapeToIndex( edge ) << + " linked to " << vNode ); } - if ( nbGotNode == 0 ) - RETURN_BAD_RESULT("Found no nodes on edge " << smDS->ShapeToIndex( edge ) << - " linked to " << vNode ); + } + else // 0020338 - nb segments == 1 + { + // get 2 other matching vertices + V2 = TopExp::LastVertex( TopoDS::Edge( edge2 )); + if ( !assocMap.IsBound( V2, /*is2nd=*/true )) + RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 )); + V1 = TopoDS::Vertex( assocMap( V2, /*is2nd=*/true )); + + // nodes on vertices + eNode1[0] = SMESH_Algo::VertexNode( V1, meshDS1 ); + eNode2[0] = SMESH_Algo::VertexNode( V2, meshDS2 ); + if ( !eNode1[0] ) RETURN_BAD_RESULT("No node on vertex #" << meshDS1->ShapeToIndex( V1 )); + if ( !eNode2[0] ) RETURN_BAD_RESULT("No node on vertex #" << meshDS2->ShapeToIndex( V2 )); } // 2. face sets @@ -1461,7 +1790,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, const SMDS_MeshElement* f = ( iF ? f2 : f1 ); for ( int i = 0; !notSeamNode[ iF ] && i < f->NbNodes(); ++i ) { const SMDS_MeshNode* node = f->GetNode( i ); - if ( !helper->IsSeamShape( node->GetPosition()->GetShapeId() )) + if ( !helper->IsSeamShape( node->getshapeId() )) notSeamNode[ iF ] = node; } } @@ -1494,7 +1823,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, notInSet.insert( f2 ); for ( int i = 0; i < nbNodes; ++i ) { const SMDS_MeshNode* n1 = faceToKeep->GetNode( i ); - const SMDS_MeshNode* n2 = faceToKeep->GetNode( i+1 ); + const SMDS_MeshNode* n2 = faceToKeep->GetNode(( i+1 ) % nbNodes ); f1 = SMESH_MeshEditor::FindFaceInSet( n1, n2, inSet, notInSet ); if ( f1 ) elems.insert( f1 ); @@ -1529,7 +1858,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, while ( nIt->more() ) { const SMDS_MeshNode* node = nIt->next(); const SMDS_EdgePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); } if ( pos2nodes.size() != edgeSM->NbNodes() ) @@ -1561,9 +1890,9 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, // associate matching nodes on the last vertices V2 = TopExp::LastVertex( TopoDS::Edge( edge2 )); - if ( !assocMap.IsBound( V2 )) + if ( !assocMap.IsBound( V2, /*is2nd=*/true )) RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 )); - V1 = TopoDS::Vertex( assocMap( V2 )); + V1 = TopoDS::Vertex( assocMap( V2, /*is2nd=*/true )); vNode1 = SMESH_Algo::VertexNode( V1, meshDS1 ); vNode2 = SMESH_Algo::VertexNode( V2, meshDS2 ); if ( !vNode1 ) RETURN_BAD_RESULT("No node on vertex #" << meshDS1->ShapeToIndex( V1 )); @@ -1581,25 +1910,12 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, return true; } -//================================================================================ -/*! - * \brief Check if the first and last vertices of an edge are the same - * \param anEdge - the edge to check - * \retval bool - true if same - */ -//================================================================================ - -bool StdMeshers_ProjectionUtils::IsClosedEdge( const TopoDS_Edge& anEdge ) -{ - return TopExp::FirstVertex( anEdge ).IsSame( TopExp::LastVertex( anEdge )); -} - //================================================================================ /*! - * \brief Return any subshape of a face belonging to the outer wire + * \brief Return any sub-shape of a face belonging to the outer wire * \param face - the face - * \param type - type of subshape to return - * \retval TopoDS_Shape - the found subshape + * \param type - type of sub-shape to return + * \retval TopoDS_Shape - the found sub-shape */ //================================================================================ @@ -1632,7 +1948,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter SMESH_Mesh* mesh = sm->GetFather(); SMESH_Gen* gen = mesh->GetGen(); - SMESH_Algo* algo = gen->GetAlgo( *mesh, sm->GetSubShape() ); + SMESH_Algo* algo = sm->GetAlgo(); if ( !algo ) { if ( sm->GetSubShape().ShapeType() != TopAbs_COMPOUND ) @@ -1695,12 +2011,12 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter } //================================================================================ - /*! - * \brief Count nb of subshapes - * \param shape - the shape - * \param type - the type of subshapes to count - * \retval int - the calculated number - */ +/*! + * \brief Count nb of sub-shapes + * \param shape - the shape + * \param type - the type of sub-shapes to count + * \retval int - the calculated number + */ //================================================================================ int StdMeshers_ProjectionUtils::Count(const TopoDS_Shape& shape, @@ -1720,7 +2036,37 @@ int StdMeshers_ProjectionUtils::Count(const TopoDS_Shape& shape, } } -namespace { +//================================================================================ +/*! + * \brief Return a boundary EDGE of edgeContainer + */ +//================================================================================ + +TopoDS_Edge StdMeshers_ProjectionUtils::GetBoundaryEdge(const TopoDS_Shape& edgeContainer, + const SMESH_Mesh& mesh) +{ + TopTools_IndexedMapOfShape facesOfEdgeContainer, facesNearEdge; + TopExp::MapShapes( edgeContainer, TopAbs_FACE, facesOfEdgeContainer ); + + if ( !facesOfEdgeContainer.IsEmpty() ) + for ( TopExp_Explorer exp(edgeContainer, TopAbs_EDGE); exp.More(); exp.Next() ) + { + const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); + facesNearEdge.Clear(); + PShapeIteratorPtr faceIt = SMESH_MesherHelper::GetAncestors( edge, mesh, TopAbs_FACE ); + while ( const TopoDS_Shape* face = faceIt->next() ) + if ( facesOfEdgeContainer.Contains( *face )) + if ( facesNearEdge.Add( *face ) && facesNearEdge.Extent() > 1 ) + break; + if ( facesNearEdge.Extent() == 1 ) + return edge; + } + + return TopoDS_Edge(); +} + + +namespace { // Definition of event listeners SMESH_subMeshEventListener* GetSrcSubMeshListener(); @@ -1733,8 +2079,8 @@ namespace { struct HypModifWaiter: SMESH_subMeshEventListener { - HypModifWaiter():SMESH_subMeshEventListener(0){} // won't be deleted by submesh - + HypModifWaiter():SMESH_subMeshEventListener(false,// won't be deleted by submesh + "StdMeshers_ProjectionUtils::HypModifWaiter") {} void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh, EventListenerData*, const SMESH_Hypothesis*) { @@ -1744,9 +2090,7 @@ namespace { // 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() )) + if ( SMESH_Algo* algo = subMesh->GetAlgo() ) algo->SetEventListener( subMesh ); } } @@ -1768,7 +2112,8 @@ namespace { //================================================================================ SMESH_subMeshEventListener* GetSrcSubMeshListener() { - static SMESH_subMeshEventListener srcListener(0); // won't be deleted by submesh + static SMESH_subMeshEventListener srcListener(false, // won't be deleted by submesh + "StdMeshers_ProjectionUtils::SrcSubMeshListener"); return &srcListener; } } @@ -1787,7 +2132,7 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh, SMESH_Mesh* srcMesh) { // Set listener that resets an event listener on source submesh when - // "ProjectionSource*D" hypothesis is modified + // "ProjectionSource*D" hypothesis is modified since source shape can be changed subMesh->SetEventListener( GetHypModifWaiter(),0,subMesh); // Set an event listener to submesh of the source shape @@ -1802,18 +2147,21 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh, if ( srcShapeSM->GetSubMeshDS() && srcShapeSM->GetSubMeshDS()->IsComplexSubmesh() ) { // source shape is a group - TopExp_Explorer it(srcShapeSM->GetSubShape(), // explore the group into subshapes... + TopExp_Explorer it(srcShapeSM->GetSubShape(), // explore the group into sub-shapes... subMesh->GetSubShape().ShapeType()); // ...of target shape type for (; it.More(); it.Next()) { SMESH_subMesh* srcSM = srcMesh->GetSubMesh( it.Current() ); - SMESH_subMeshEventListenerData* data = - srcSM->GetEventListenerData(GetSrcSubMeshListener()); - if ( data ) - data->mySubMeshes.push_back( subMesh ); - else - data = SMESH_subMeshEventListenerData::MakeData( subMesh ); - subMesh->SetEventListener ( GetSrcSubMeshListener(), data, srcSM ); + if ( srcSM != subMesh ) + { + SMESH_subMeshEventListenerData* data = + srcSM->GetEventListenerData(GetSrcSubMeshListener()); + if ( data ) + data->mySubMeshes.push_back( subMesh ); + else + data = SMESH_subMeshEventListenerData::MakeData( subMesh ); + subMesh->SetEventListener ( GetSrcSubMeshListener(), data, srcSM ); + } } } else diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.hxx b/src/StdMeshers/StdMeshers_ProjectionUtils.hxx index 6ca881c88..685536a4d 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.hxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionUtils.hxx // Created : Thu Oct 26 15:37:24 2006 @@ -44,6 +45,29 @@ class SMESH_Hypothesis; class SMESH_subMesh; class TopTools_IndexedDataMapOfShapeListOfShape; +/*! + * \brief Struct used instead of a sole TopTools_DataMapOfShapeShape to avoid + * problems with bidirectional bindings + */ +struct StdMeshers_ShapeShapeBiDirectionMap +{ + TopTools_DataMapOfShapeShape _map1to2, _map2to1; + + // convension: s1 - target, s2 - source + bool Bind( const TopoDS_Shape& s1, const TopoDS_Shape& s2 ) + { _map1to2.Bind( s1, s2 ); return _map2to1.Bind( s2, s1 ); } + bool IsBound( const TopoDS_Shape& s, const bool isShape2=false ) const + { return (isShape2 ? _map2to1 : _map1to2).IsBound( s ); } + bool IsEmpty() const { return _map1to2.IsEmpty(); } + int Extent() const { return _map1to2.Extent(); } + void Clear() { _map1to2.Clear(); _map2to1.Clear(); } + const TopoDS_Shape& operator()( const TopoDS_Shape& s, const bool isShape2=false ) const + { // if we get a Standard_NoSuchObject here, it means that the calling code + // passes incorrect isShape2 + return (isShape2 ? _map2to1 : _map1to2)( s ); + } +}; + /*! * \brief Class encapsulating methods common to Projection algorithms */ @@ -51,12 +75,12 @@ class StdMeshers_ProjectionUtils { public: - typedef TopTools_DataMapOfShapeShape TShapeShapeMap; + typedef StdMeshers_ShapeShapeBiDirectionMap TShapeShapeMap; typedef TopTools_IndexedDataMapOfShapeListOfShape TAncestorMap; typedef std::map TNodeNodeMap; /*! - * \brief Looks for association of all subshapes of two shapes + * \brief Looks for association of all sub-shapes of two shapes * \param theShape1 - shape 1 * \param theMesh1 - mesh built on shape 1 * \param theShape2 - shape 2 @@ -81,10 +105,10 @@ class StdMeshers_ProjectionUtils * \param edges2 - out list of edges of face 2 * \retval int - nb of edges in an outer wire in a success case, else zero */ - static int FindFaceAssociation(const TopoDS_Face& face1, - TopoDS_Vertex VV1[2], - const TopoDS_Face& face2, - TopoDS_Vertex VV2[2], + static int FindFaceAssociation(const TopoDS_Face& face1, + TopoDS_Vertex VV1[2], + const TopoDS_Face& face2, + TopoDS_Vertex VV2[2], std::list< TopoDS_Edge > & edges1, std::list< TopoDS_Edge > & edges2); @@ -95,25 +119,19 @@ class StdMeshers_ProjectionUtils * \param theTargetShape - the shape theHyp assigned to */ static void InitVertexAssociation( const SMESH_Hypothesis* theHyp, - TShapeShapeMap & theAssociationMap, - const TopoDS_Shape& theTargetShape); + TShapeShapeMap & theAssociationMap); /*! * \brief Inserts association theShape1 <-> theShape2 to TShapeShapeMap - * \param theShape1 - shape 1 - * \param theShape2 - shape 2 + * \param theShape1 - target shape + * \param theShape2 - source shape * \param theAssociationMap - association map * \param theBidirectional - if false, inserts theShape1 -> theShape2 association * \retval bool - true if there was no association for these shapes before */ - static bool InsertAssociation( const TopoDS_Shape& theShape1, - const TopoDS_Shape& theShape2, - TShapeShapeMap & theAssociationMap, - const bool theBidirectional=true); - - static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh ); - - static bool IsSubShape( const TopoDS_Shape& shape, const TopoDS_Shape& mainShape ); + static bool InsertAssociation( const TopoDS_Shape& theShape1, // target + const TopoDS_Shape& theShape2, // source + TShapeShapeMap & theAssociationMap); /*! * \brief Finds an edge by its vertices in a main shape of the mesh @@ -151,7 +169,7 @@ class StdMeshers_ProjectionUtils * \param mesh1 - mesh containing elements on the first face * \param face2 - the second face * \param mesh2 - mesh containing elements on the second face - * \param assocMap - map associating subshapes of the faces + * \param assocMap - map associating sub-shapes of the faces * \param nodeIn2OutMap - map containing found matching nodes * \retval bool - is a success */ @@ -162,17 +180,10 @@ class StdMeshers_ProjectionUtils const TShapeShapeMap & assocMap, TNodeNodeMap & nodeIn2OutMap); /*! - * \brief Check if the first and last vertices of an edge are the same - * \param anEdge - the edge to check - * \retval bool - true if same - */ - static bool IsClosedEdge( const TopoDS_Edge& anEdge ); - - /*! - * \brief Return any subshape of a face belonging to the outer wire + * \brief Return any sub-shape of a face belonging to the outer wire * \param face - the face - * \param type - type of subshape to return - * \retval TopoDS_Shape - the found subshape + * \param type - type of sub-shape to return + * \retval TopoDS_Shape - the found sub-shape */ static TopoDS_Shape OuterShape( const TopoDS_Face& face, TopAbs_ShapeEnum type); @@ -186,9 +197,9 @@ class StdMeshers_ProjectionUtils static bool MakeComputed(SMESH_subMesh * sm, const int iterationNb = 0); /*! - * \brief Count nb of subshapes + * \brief Count nb of sub-shapes * \param shape - the shape - * \param type - the type of subshapes to count + * \param type - the type of sub-shapes to count * \param ignoreSame - if true, use map not to count same shapes, esle use explorer * \retval int - the calculated number */ @@ -206,6 +217,11 @@ class StdMeshers_ProjectionUtils TopoDS_Shape srcShape, SMESH_Mesh* srcMesh); + /*! + * \brief Return a boundary EDGE of edgeContainer + */ + static TopoDS_Edge GetBoundaryEdge(const TopoDS_Shape& edgeContainer, + const SMESH_Mesh& mesh); }; #endif diff --git a/src/StdMeshers/StdMeshers_Projection_1D.cxx b/src/StdMeshers/StdMeshers_Projection_1D.cxx index 4fd7c5d8d..778b57c0e 100644 --- a/src/StdMeshers/StdMeshers_Projection_1D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_1D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Projection_1D.cxx // Module : SMESH @@ -67,7 +68,7 @@ StdMeshers_Projection_1D::StdMeshers_Projection_1D(int hypId, int studyId, SMESH :SMESH_1D_Algo(hypId, studyId, gen) { _name = "Projection_1D"; - _shapeType = (1 << TopAbs_EDGE); // 1 bit per shape type + _shapeType = (1 << TopAbs_EDGE); // 1 bit per shape type _compatibleHypothesis.push_back("ProjectionSource1D"); _sourceHypo = 0; @@ -128,25 +129,25 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh& if ( _sourceHypo->HasVertexAssociation() ) { // source and target vertices - if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh ) || - !TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh ) || - !TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), - _sourceHypo->GetSourceEdge() )) + if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh ) || + !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh ) || + !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(), + _sourceHypo->GetSourceEdge() )) { aStatus = HYP_BAD_PARAMETER; - SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh ))); - SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh ))); - SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), - _sourceHypo->GetSourceEdge() ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(), + _sourceHypo->GetSourceEdge() ))); } // PAL16202 - else + else { - bool isSub = TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), aShape ); + bool isSub = SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), aShape ); if ( !_sourceHypo->IsCompoundSource() ) { if ( !isSub ) { aStatus = HYP_BAD_PARAMETER; - SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), aShape))); + SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), aShape))); } } else if ( isSub ) { @@ -159,7 +160,7 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh& { const TopoDS_Shape& ancestor = ancestIt.Value(); if ( ancestor.ShapeType() == TopAbs_EDGE && - TAssocTool::IsSubShape( ancestor, _sourceHypo->GetSourceEdge() )) + SMESH_MesherHelper::IsSubShape( ancestor, _sourceHypo->GetSourceEdge() )) { if ( sharingEdge.IsNull() || ancestor.IsSame( sharingEdge )) sharingEdge = ancestor; @@ -175,11 +176,11 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh& } } // check source edge - if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ) || + if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ) || ( srcMesh == tgtMesh && aShape == _sourceHypo->GetSourceEdge() )) { aStatus = HYP_BAD_PARAMETER; - SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ))); SCRUTE((srcMesh == tgtMesh)); SCRUTE(( aShape == _sourceHypo->GetSourceEdge() )); } @@ -209,14 +210,14 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); // --------------------------- - // Make subshapes association + // Make sub-shapes association // --------------------------- TopoDS_Edge srcEdge, tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD)); TopoDS_Shape srcShape = _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD); TAssocTool::TShapeShapeMap shape2ShapeMap; - TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtEdge ); + TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcShape, srcMesh, shape2ShapeMap) || !shape2ShapeMap.IsBound( tgtEdge )) @@ -372,6 +373,97 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& return true; } + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_Projection_1D::Evaluate(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + MapShapeNbElems& aResMap) +{ + if ( !_sourceHypo ) + return false; + + SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); + SMESH_Mesh * tgtMesh = & theMesh; + if ( !srcMesh ) + srcMesh = tgtMesh; + + //SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); + + // --------------------------- + // Make sub-shapes association + // --------------------------- + + TopoDS_Edge srcEdge, tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD)); + TopoDS_Shape srcShape = _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD); + + TAssocTool::TShapeShapeMap shape2ShapeMap; + TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); + if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcShape, srcMesh, + shape2ShapeMap) || + !shape2ShapeMap.IsBound( tgtEdge )) + return error("Vertices association failed" ); + + srcEdge = TopoDS::Edge( shape2ShapeMap( tgtEdge ).Oriented(TopAbs_FORWARD)); +// cout << " srcEdge #" << srcMesh->GetMeshDS()->ShapeToIndex( srcEdge ) +// << " tgtEdge #" << tgtMesh->GetMeshDS()->ShapeToIndex( tgtEdge ) << endl; + + TopoDS_Vertex tgtV[2], srcV[2]; + TopExp::Vertices( tgtEdge, tgtV[0], tgtV[1] ); + TopExp::Vertices( srcEdge, srcV[0], srcV[1] ); + + // ---------------------------------------------- + // Assure that mesh on a source edge is computed + // ---------------------------------------------- + + SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcEdge ); + //SMESH_subMesh* tgtSubMesh = tgtMesh->GetSubMesh( tgtEdge ); + + if ( tgtMesh == srcMesh ) { + if ( !TAssocTool::MakeComputed( srcSubMesh )) + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); + } + else { + if ( !srcSubMesh->IsMeshComputed() ) + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); + } + // ----------------------------------------------- + // Find out nodes distribution on the source edge + // ----------------------------------------------- + + //double srcLength = EdgeLength( srcEdge ); + //double tgtLength = EdgeLength( tgtEdge ); + + vector< double > params; // sorted parameters of nodes on the source edge + if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params )) + return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge"); + + int nbNodes = params.size(); + + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetSubMeshDS()->GetElements(); + if ( elemIt->more() ) + quadratic = elemIt->next()->IsQuadratic(); + if(quadratic) + aVec[SMDSEntity_Quad_Edge] = (nbNodes-1)/2; + else + aVec[SMDSEntity_Edge] = nbNodes - 1; + + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(std::make_pair(sm,aVec)); + + return true; +} + + //============================================================================= /*! * \brief Sets a default event listener to submesh of the source edge diff --git a/src/StdMeshers/StdMeshers_Projection_1D.hxx b/src/StdMeshers/StdMeshers_Projection_1D.hxx index 52f76e170..5ef640170 100644 --- a/src/StdMeshers/StdMeshers_Projection_1D.hxx +++ b/src/StdMeshers/StdMeshers_Projection_1D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Projection_1D.hxx // Module : SMESH @@ -46,6 +47,9 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + /*! * \brief Sets a default event listener to submesh of the source edge * \param whenSetToSubMesh - submesh where algo is set diff --git a/src/StdMeshers/StdMeshers_Projection_1D2D.cxx b/src/StdMeshers/StdMeshers_Projection_1D2D.cxx new file mode 100644 index 000000000..efe6bf034 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Projection_1D2D.cxx @@ -0,0 +1,264 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_Projection_1D2D.cxx +// Module : SMESH +// Author : Edward AGAPOV (eap) +// +#include "StdMeshers_Projection_1D2D.hxx" + +#include "SMESH_Gen.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMeshEventListener.hxx" +#include "StdMeshers_FaceSide.hxx" +#include "StdMeshers_ProjectionSource2D.hxx" +#include "StdMeshers_ProjectionUtils.hxx" + +#include +#include + +using namespace std; + +namespace +{ + // -------------------------------------------------------------------------------- + /*! + * \brief an event listener updating submehses of EDGEs according to + * events on the target FACE submesh + */ + struct EventProparatorToEdges : public SMESH_subMeshEventListener + { + EventProparatorToEdges(): SMESH_subMeshEventListener(/*isDeletable=*/false, + "Projection_1D2D::EventProparatorToEdges") + {} + static EventProparatorToEdges* Instance() { static EventProparatorToEdges E; return &E; } + + static void Set(SMESH_subMesh* faceSubMesh) + { + SMESH_subMeshEventListenerData* edgeSubMeshes = + new SMESH_subMeshEventListenerData(/*isDeletable=*/true); + SMESH_Mesh* mesh = faceSubMesh->GetFather(); + TopExp_Explorer eExp( faceSubMesh->GetSubShape(), TopAbs_EDGE ); + for ( ; eExp.More(); eExp.Next() ) + edgeSubMeshes->mySubMeshes.push_back( mesh->GetSubMesh( eExp.Current() )); + + // set a listener + faceSubMesh->SetEventListener( Instance(), edgeSubMeshes, faceSubMesh ); + } + }; + // -------------------------------------------------------------------------------- + /*! + * \brief Structure used to temporary remove EventProparatorToEdges from faceSubMesh + * in order to prevent propagation of CLEAN event from FACE to EDGEs during + * StdMeshers_Projection_1D2D::Compute(). The CLEAN event is emmited by Pattern mapper + * and causes removal of faces generated on adjacent FACEs. + */ + struct UnsetterOfEventProparatorToEdges + { + SMESH_subMesh* _faceSubMesh; + UnsetterOfEventProparatorToEdges( SMESH_subMesh* faceSubMesh ):_faceSubMesh(faceSubMesh) + { + faceSubMesh->DeleteEventListener( EventProparatorToEdges::Instance() ); + } + ~UnsetterOfEventProparatorToEdges() + { + EventProparatorToEdges::Set(_faceSubMesh); + } + }; +} + +//======================================================================= +//function : StdMeshers_Projection_1D2D +//purpose : +//======================================================================= + +StdMeshers_Projection_1D2D::StdMeshers_Projection_1D2D(int hypId, int studyId, SMESH_Gen* gen) + :StdMeshers_Projection_2D(hypId, studyId, gen) +{ + _name = "Projection_1D2D"; + _requireDiscreteBoundary = false; + _supportSubmeshes = true; +} + +//======================================================================= +//function : Compute +//purpose : +//======================================================================= + +bool StdMeshers_Projection_1D2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape) +{ + UnsetterOfEventProparatorToEdges eventBarrier( theMesh.GetSubMesh( theShape )); + + if ( !StdMeshers_Projection_2D::Compute(theMesh, theShape)) + return false; + + SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); + + SMESHDS_SubMesh * faceSubMesh = meshDS->MeshElements( theShape ); + if ( !faceSubMesh || faceSubMesh->NbElements() == 0 ) return false; + _quadraticMesh = faceSubMesh->GetElements()->next()->IsQuadratic(); + + SMESH_MesherHelper helper( theMesh ); + helper.SetSubShape( theShape ); + + TopoDS_Face F = TopoDS::Face( theShape ); + TError err; + TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh, + /*ignoreMediumNodes=*/false, err); + if ( err && !err->IsOK() ) + return error( err ); + + for ( size_t iWire = 0; iWire < wires.size(); ++iWire ) + { + vector nodes = wires[ iWire ]->GetOrderedNodes(); + if ( nodes.empty() ) + return error("Wrong nodes on a wire"); + + // check that all nodes are shared by faces generated on F + for ( size_t i = 0; i < nodes.size(); ++i ) + { + SMDS_ElemIteratorPtr fIt = nodes[i]->GetInverseElementIterator(SMDSAbs_Face); + bool faceFound = false; + while ( !faceFound && fIt->more() ) + faceFound = ( helper.GetSubShapeID() == fIt->next()->getshapeId() ); + if ( !faceFound ) + return error("The existing 1D mesh mismatches the generated 2D mesh"); + } + + const bool checkExisting = ( wires[ iWire ]->NbSegments() || helper.HasSeam() ); + + if ( _quadraticMesh ) + { + for ( size_t i = 2; i < nodes.size(); i += 2 ) + { + if ( checkExisting && meshDS->FindEdge( nodes[i-2], nodes[i], nodes[i-1])) + continue; + SMDS_MeshElement* e = meshDS->AddEdge( nodes[i-2], nodes[i], nodes[i-1] ); + meshDS->SetMeshElementOnShape( e, nodes[i-1]->getshapeId() ); + } + } + else + { + int edgeID = meshDS->ShapeToIndex( wires[ iWire ]->Edge(0) ); + for ( size_t i = 1; i < nodes.size(); ++i ) + { + if ( checkExisting && meshDS->FindEdge( nodes[i-1], nodes[i])) + continue; + SMDS_MeshElement* e = meshDS->AddEdge( nodes[i-1], nodes[i] ); + if ( nodes[i-1]->getshapeId() != edgeID && + nodes[i ]->getshapeId() != edgeID ) + { + edgeID = helper.GetMediumPos( nodes[i-1], nodes[i] ).first; + if ( edgeID < 1 ) edgeID = helper.GetSubShapeID(); + } + meshDS->SetMeshElementOnShape( e, edgeID ); + } + } + } + + return true; +} + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_Projection_1D2D::Evaluate(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + MapShapeNbElems& aResMap) +{ + if ( !StdMeshers_Projection_2D::Evaluate(theMesh,theShape,aResMap)) + return false; + + TopoDS_Shape srcFace = _sourceHypo->GetSourceFace(); + SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); + if ( !srcMesh ) srcMesh = & theMesh; + SMESH_subMesh* srcFaceSM = srcMesh->GetSubMesh( srcFace ); + + typedef StdMeshers_ProjectionUtils SPU; + SPU::TShapeShapeMap shape2ShapeMap; + SPU::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); + if ( !SPU::FindSubShapeAssociation( theShape, &theMesh, srcFace, srcMesh, shape2ShapeMap)) + return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" ); + + MapShapeNbElems srcResMap; + if ( !srcFaceSM->IsMeshComputed() ) + _gen->Evaluate( *srcMesh, srcFace, srcResMap); + + SMESH_subMeshIteratorPtr smIt = srcFaceSM->getDependsOnIterator(/*includeSelf=*/false, + /*complexShapeFirst=*/true); + while ( smIt->more() ) + { + SMESH_subMesh* srcSM = smIt->next(); + TopAbs_ShapeEnum shapeType = srcSM->GetSubShape().ShapeType(); + if ( shapeType == TopAbs_EDGE ) + { + std::vector aVec; + SMESHDS_SubMesh* srcSubMeshDS = srcSM->GetSubMeshDS(); + if ( srcSubMeshDS && srcSubMeshDS->NbElements() ) + { + aVec.resize(SMDSEntity_Last, 0); + SMDS_ElemIteratorPtr eIt = srcSubMeshDS->GetElements(); + _quadraticMesh = ( eIt->more() && eIt->next()->IsQuadratic() ); + + aVec[SMDSEntity_Node] = srcSubMeshDS->NbNodes(); + aVec[_quadraticMesh ? SMDSEntity_Quad_Edge : SMDSEntity_Edge] = srcSubMeshDS->NbElements(); + } + else + { + if ( srcResMap.empty() ) + if ( !_gen->Evaluate( *srcMesh, srcSM->GetSubShape(), srcResMap )) + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not evaluatable"); + aVec = srcResMap[ srcSM ]; + if ( aVec.empty() ) + return error(COMPERR_BAD_INPUT_MESH,"Source mesh is wrongly evaluated"); + } + TopoDS_Shape tgtEdge = shape2ShapeMap( srcSM->GetSubShape(), /*isSrc=*/true ); + SMESH_subMesh* tgtSM = theMesh.GetSubMesh( tgtEdge ); + aResMap.insert(std::make_pair(tgtSM,aVec)); + } + if ( shapeType == TopAbs_VERTEX ) break; + } + + return true; +} + +//======================================================================= +//function : SetEventListener +//purpose : Sets a default event listener to submesh of the source face. +// faceSubMesh - submesh where algo is set +// After being set, event listener is notified on each event of a submesh. +// This method is called when a submesh gets HYP_OK algo_state. +// Arranges that CLEAN event is translated from source submesh to +// the faceSubMesh submesh. +//======================================================================= + +void StdMeshers_Projection_1D2D::SetEventListener(SMESH_subMesh* faceSubMesh) +{ + // set a listener of events on a source submesh + StdMeshers_Projection_2D::SetEventListener(faceSubMesh); + + // set a listener to the target FACE submesh in order to update submehses + // of EDGEs according to events on the target FACE submesh + EventProparatorToEdges::Set( faceSubMesh ); +} + diff --git a/src/StdMeshers/StdMeshers_Projection_1D2D.hxx b/src/StdMeshers/StdMeshers_Projection_1D2D.hxx new file mode 100644 index 000000000..9e7715c82 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Projection_1D2D.hxx @@ -0,0 +1,52 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_Projection_1D2D.hxx +// Module : SMESH +// +#ifndef _SMESH_Projection_1D2D_HXX_ +#define _SMESH_Projection_1D2D_HXX_ + +#include "StdMeshers_Projection_2D.hxx" + +class STDMESHERS_EXPORT StdMeshers_Projection_1D2D: public StdMeshers_Projection_2D +{ +public: + StdMeshers_Projection_1D2D(int hypId, int studyId, SMESH_Gen* gen); + + virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + /*! + * \brief Sets a default event listener to submesh of the source face + * \param whenSetToSubMesh - submesh where algo is set + * + * After being set, event listener is notified on each event of a submesh. + * This method is called when a submesh gets HYP_OK algo_state. + * Arranges that CLEAN event is translated from source submesh to + * the whenSetToSubMesh submesh. + */ + virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh); +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index ed6027268..b4734fa0c 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Projection_2D.cxx // Module : SMESH @@ -29,18 +30,20 @@ #include "StdMeshers_ProjectionSource2D.hxx" #include "StdMeshers_ProjectionUtils.hxx" +#include "StdMeshers_FaceSide.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" #include "SMESHDS_Hypothesis.hxx" #include "SMESHDS_SubMesh.hxx" #include "SMESH_Block.hxx" +#include "SMESH_Comment.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_Pattern.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" -#include "SMESH_Comment.hxx" -#include "SMDS_EdgePosition.hxx" #include "utilities.h" @@ -50,6 +53,8 @@ #include #include #include +#include +#include using namespace std; @@ -67,7 +72,7 @@ StdMeshers_Projection_2D::StdMeshers_Projection_2D(int hypId, int studyId, SMESH :SMESH_2D_Algo(hypId, studyId, gen) { _name = "Projection_2D"; - _shapeType = (1 << TopAbs_FACE); // 1 bit per shape type + _shapeType = (1 << TopAbs_FACE); // 1 bit per shape type _compatibleHypothesis.push_back("ProjectionSource2D"); _sourceHypo = 0; @@ -130,40 +135,40 @@ bool StdMeshers_Projection_2D::CheckHypothesis(SMESH_Mesh& TopoDS_Shape edge = TAssocTool::GetEdgeByVertices ( srcMesh, _sourceHypo->GetSourceVertex(1), _sourceHypo->GetSourceVertex(2) ); if ( edge.IsNull() || - !TAssocTool::IsSubShape( edge, srcMesh ) || - !TAssocTool::IsSubShape( edge, _sourceHypo->GetSourceFace() )) + !SMESH_MesherHelper::IsSubShape( edge, srcMesh ) || + !SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() )) { theStatus = HYP_BAD_PARAMETER; SCRUTE((edge.IsNull())); - SCRUTE((TAssocTool::IsSubShape( edge, srcMesh ))); - SCRUTE((TAssocTool::IsSubShape( edge, _sourceHypo->GetSourceFace() ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, srcMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() ))); } else { // target vertices edge = TAssocTool::GetEdgeByVertices ( tgtMesh, _sourceHypo->GetTargetVertex(1), _sourceHypo->GetTargetVertex(2) ); - if ( edge.IsNull() || !TAssocTool::IsSubShape( edge, tgtMesh )) + if ( edge.IsNull() || !SMESH_MesherHelper::IsSubShape( edge, tgtMesh )) { theStatus = HYP_BAD_PARAMETER; SCRUTE((edge.IsNull())); - SCRUTE((TAssocTool::IsSubShape( edge, tgtMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, tgtMesh ))); } // PAL16203 else if ( !_sourceHypo->IsCompoundSource() && - !TAssocTool::IsSubShape( edge, theShape )) + !SMESH_MesherHelper::IsSubShape( edge, theShape )) { theStatus = HYP_BAD_PARAMETER; - SCRUTE((TAssocTool::IsSubShape( edge, theShape ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, theShape ))); } } } // check a source face - if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ) || + if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ) || ( srcMesh == tgtMesh && theShape == _sourceHypo->GetSourceFace() )) { theStatus = HYP_BAD_PARAMETER; - SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ))); SCRUTE((srcMesh == tgtMesh)); SCRUTE(( theShape == _sourceHypo->GetSourceFace() )); } @@ -177,22 +182,29 @@ bool StdMeshers_Projection_2D::CheckHypothesis(SMESH_Mesh& namespace { - //================================================================================ /*! * \brief define if a node is new or old - * \param node - node to check - * \retval bool - true if the node existed before Compute() is called + * \param node - node to check + * \retval bool - true if the node existed before Compute() is called */ //================================================================================ - bool isOldNode( const SMDS_MeshNode* node ) + bool isOldNode( const SMDS_MeshNode* node/*, const bool is1DComputed*/ ) { // old nodes are shared by edges and new ones are shared // only by faces created by mapper - SMDS_ElemIteratorPtr invEdge = node->GetInverseElementIterator(SMDSAbs_Edge); - bool isOld = invEdge->more(); - return isOld; + //if ( is1DComputed ) + { + bool isOld = node->NbInverseElements(SMDSAbs_Edge) > 0; + return isOld; + } + // else + // { + // SMDS_ElemIteratorPtr invFace = node->GetInverseElementIterator(SMDSAbs_Face); + // bool isNew = invFace->more(); + // return !isNew; + // } } //================================================================================ @@ -211,7 +223,7 @@ namespace { void Release() { sm = 0; } // mesh will not be removed static void Clean( SMESH_subMesh* sm, bool withSub=true ) { - if ( !sm ) return; + if ( !sm || !sm->GetSubMeshDS() ) return; // PAL16567, 18920. Remove face nodes as well // switch ( sm->GetSubShape().ShapeType() ) { // case TopAbs_VERTEX: @@ -339,7 +351,7 @@ namespace { RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() << " pos type " << node->GetPosition()->GetTypeOfPosition()); const SMDS_EdgePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); u2nodes.insert( make_pair( pos->GetUParameter(), node )); seamNodes.insert( node ); } @@ -354,8 +366,406 @@ namespace { } // bool getBoundaryNodes() + //================================================================================ + /*! + * \brief Preform projection in case if tgtFace.IsPartner( srcFace ) and in case + * if projection by transformation is possible + */ + //================================================================================ + + bool projectPartner(const TopoDS_Face& tgtFace, + const TopoDS_Face& srcFace, + SMESH_Mesh * tgtMesh, + SMESH_Mesh * srcMesh, + const TAssocTool::TShapeShapeMap& shape2ShapeMap) + { + MESSAGE("projectPartner"); + const double tol = 1.e-7*srcMesh->GetMeshDS()->getMaxDim(); + + gp_Trsf trsf; // transformation to get location of target nodes from source ones + if ( tgtFace.IsPartner( srcFace )) + { + gp_Trsf srcTrsf = srcFace.Location(); + gp_Trsf tgtTrsf = tgtFace.Location(); + trsf = srcTrsf.Inverted() * tgtTrsf; + } + else + { + // Try to find the transformation + + // make any local coord systems of src and tgt faces + vector srcPP, tgtPP; // 3 points on face boundaries to make axes of CS + SMESH_subMesh * srcSM = srcMesh->GetSubMesh( srcFace ); + SMESH_subMeshIteratorPtr smIt = srcSM->getDependsOnIterator(/*includeSelf=*/false,false); + srcSM = smIt->next(); // sm of a vertex + while ( smIt->more() && srcPP.size() < 3 ) + { + srcSM = smIt->next(); + SMESHDS_SubMesh* srcSmds = srcSM->GetSubMeshDS(); + if ( !srcSmds ) continue; + SMDS_NodeIteratorPtr nIt = srcSmds->GetNodes(); + while ( nIt->more() ) + { + SMESH_TNodeXYZ p ( nIt->next()); + bool pOK = false; + switch ( srcPP.size() ) + { + case 0: pOK = true; break; + + case 1: pOK = ( srcPP[0].SquareDistance( p ) > 10*tol ); break; + + case 2: + { + gp_Vec p0p1( srcPP[0], srcPP[1] ), p0p( srcPP[0], p ); + // pOK = !p0p1.IsParallel( p0p, tol ); + pOK = !p0p1.IsParallel( p0p, 3.14/20 ); // angle min 18 degrees + break; + } + } + if ( !pOK ) + continue; + + // find corresponding point on target shape + pOK = false; + gp_Pnt tgtP; + const TopoDS_Shape& tgtShape = shape2ShapeMap( srcSM->GetSubShape(), /*isSrc=*/true ); + if ( tgtShape.ShapeType() == TopAbs_VERTEX ) + { + tgtP = BRep_Tool::Pnt( TopoDS::Vertex( tgtShape )); + pOK = true; + //cout << "V - nS " << p._node->GetID() << " - nT " << SMESH_Algo::VertexNode(TopoDS::Vertex( tgtShape),tgtMesh->GetMeshDS())->GetID() << endl; + } + else if ( tgtPP.size() > 0 ) + { + if ( SMESHDS_SubMesh* tgtSmds = tgtMesh->GetMeshDS()->MeshElements( tgtShape )) + { + double srcDist = srcPP[0].Distance( p ); + double eTol = BRep_Tool::Tolerance( TopoDS::Edge( tgtShape )); + if (eTol < tol) eTol = tol; + SMDS_NodeIteratorPtr nItT = tgtSmds->GetNodes(); + while ( nItT->more() && !pOK ) + { + const SMDS_MeshNode* n = nItT->next(); + tgtP = SMESH_TNodeXYZ( n ); + pOK = ( fabs( srcDist - tgtPP[0].Distance( tgtP )) < 2*eTol ); + //cout << "E - nS " << p._node->GetID() << " - nT " << n->GetID()<< " OK - " << pOK<< " " << fabs( srcDist - tgtPP[0].Distance( tgtP ))<< " tol " << eTol<< endl; + } + } + } + if ( !pOK ) + continue; + + srcPP.push_back( p ); + tgtPP.push_back( tgtP ); + } + } + if ( srcPP.size() != 3 ) + return false; + + // make transformation + gp_Trsf fromTgtCS, toSrcCS; // from/to global CS + gp_Ax2 srcCS( srcPP[0], gp_Vec( srcPP[0], srcPP[1] ), gp_Vec( srcPP[0], srcPP[2])); + gp_Ax2 tgtCS( tgtPP[0], gp_Vec( tgtPP[0], tgtPP[1] ), gp_Vec( tgtPP[0], tgtPP[2])); + toSrcCS .SetTransformation( gp_Ax3( srcCS )); + fromTgtCS.SetTransformation( gp_Ax3( tgtCS )); + fromTgtCS.Invert(); + + trsf = fromTgtCS * toSrcCS; + } + + // Fill map of src to tgt nodes with nodes on edges + + map src2tgtNodes; + map::iterator srcN_tgtN; + + for ( TopExp_Explorer srcEdge( srcFace, TopAbs_EDGE); srcEdge.More(); srcEdge.Next() ) + { + const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge.Current(), /*isSrc=*/true ); + + map< double, const SMDS_MeshNode* > srcNodes, tgtNodes; + if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMesh->GetMeshDS(), + TopoDS::Edge( srcEdge.Current() ), + /*ignoreMediumNodes = */true, + srcNodes ) + || + !SMESH_Algo::GetSortedNodesOnEdge( tgtMesh->GetMeshDS(), + TopoDS::Edge( tgtEdge ), + /*ignoreMediumNodes = */true, + tgtNodes ) + || + srcNodes.size() != tgtNodes.size()) + return false; + + if ( !tgtEdge.IsPartner( srcEdge.Current() )) + { + // check that transformation is OK by three nodes + gp_Pnt p0S = SMESH_TNodeXYZ( (srcNodes.begin()) ->second); + gp_Pnt p1S = SMESH_TNodeXYZ( (srcNodes.rbegin()) ->second); + gp_Pnt p2S = SMESH_TNodeXYZ( (++srcNodes.begin())->second); + + gp_Pnt p0T = SMESH_TNodeXYZ( (tgtNodes.begin()) ->second); + gp_Pnt p1T = SMESH_TNodeXYZ( (tgtNodes.rbegin()) ->second); + gp_Pnt p2T = SMESH_TNodeXYZ( (++tgtNodes.begin())->second); + + // transform source points, they must coincide with target ones + if ( p0T.SquareDistance( p0S.Transformed( trsf )) > tol || + p1T.SquareDistance( p1S.Transformed( trsf )) > tol || + p2T.SquareDistance( p2S.Transformed( trsf )) > tol ) + { + //cout << "KO trsf, 3 dist: " + //<< p0T.SquareDistance( p0S.Transformed( trsf ))<< ", " + //<< p1T.SquareDistance( p1S.Transformed( trsf ))<< ", " + //<< p2T.SquareDistance( p2S.Transformed( trsf ))<< ", "<::iterator u_tn = tgtNodes.begin(); + map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin(); + for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn) + src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second )); + } + + // Make new faces + + // prepare the helper to adding quadratic elements if necessary + SMESH_MesherHelper helper( *tgtMesh ); + helper.SetSubShape( tgtFace ); + helper.IsQuadraticSubMesh( tgtFace ); + helper.SetElementsOnShape( true ); + + SMESH_MesherHelper srcHelper( *srcMesh ); + srcHelper.SetSubShape( srcFace ); + + const SMDS_MeshNode* nullNode = 0; + + // indices of nodes to create properly oriented faces + int tri1 = 1, tri2 = 2, quad1 = 1, quad3 = 3; + if ( trsf.Form() != gp_Identity ) + std::swap( tri1, tri2 ), std::swap( quad1, quad3 ); + + SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace ); + SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements(); + vector< const SMDS_MeshNode* > tgtNodes; + while ( elemIt->more() ) // loop on all mesh faces on srcFace + { + const SMDS_MeshElement* elem = elemIt->next(); + const int nbN = elem->NbCornerNodes(); + tgtNodes.resize( nbN ); + for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element + { + const SMDS_MeshNode* srcNode = elem->GetNode(i); + srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first; + if ( srcN_tgtN->second == nullNode ) + { + // create a new node + gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf ); + SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); + srcN_tgtN->second = n; + + gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode, + elem->GetNode( helper.WrapIndex(i+1,nbN))); + n->SetPosition( new SMDS_FacePosition( srcUV.X(), srcUV.Y() )); + } + tgtNodes[i] = srcN_tgtN->second; + } + // create a new face + switch ( nbN ) + { + case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break; + case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break; + } + } + return true; + + } // bool projectPartner() + + //================================================================================ + /*! + * \brief Preform projection in case if the faces are similar in 2D space + */ + //================================================================================ + + bool projectBy2DSimilarity(const TopoDS_Face& tgtFace, + const TopoDS_Face& srcFace, + SMESH_Mesh * tgtMesh, + SMESH_Mesh * srcMesh, + const TAssocTool::TShapeShapeMap& shape2ShapeMap, + const bool is1DComputed) + { + // 1) Preparation + + // get ordered src EDGEs + TError err; + TSideVector srcWires = + StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*ignoreMediumNodes = */false, err); + if ( err && !err->IsOK() ) + return false; + + // make corresponding sequence of tgt EDGEs + TSideVector tgtWires( srcWires.size() ); + for ( unsigned iW = 0; iW < srcWires.size(); ++iW ) + { + list< TopoDS_Edge > tgtEdges; + StdMeshers_FaceSidePtr srcWire = srcWires[iW]; + TopTools_IndexedMapOfShape edgeMap; // to detect seam edges + for ( int iE = 0; iE < srcWire->NbEdges(); ++iE ) + { + tgtEdges.push_back( TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ), /*isSrc=*/true))); + // reverse a seam edge encountered for the second time + const int oldExtent = edgeMap.Extent(); + edgeMap.Add( tgtEdges.back() ); + if ( oldExtent == edgeMap.Extent() ) + tgtEdges.back().Reverse(); + } + tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh, + /*theIsForward = */ true, + /*theIgnoreMediumNodes = */false)); + if ( is1DComputed && + srcWires[iW]->GetUVPtStruct().size() != + tgtWires[iW]->GetUVPtStruct().size()) + return false; + } + + // 2) Find transformation + + gp_Trsf2d trsf; + { + // get 2 pairs of corresponding UVs + gp_Pnt2d srcP0 = srcWires[0]->Value2d(0.0); + gp_Pnt2d srcP1 = srcWires[0]->Value2d(0.333); + gp_Pnt2d tgtP0 = tgtWires[0]->Value2d(0.0); + gp_Pnt2d tgtP1 = tgtWires[0]->Value2d(0.333); + + // make transformation + gp_Trsf2d fromTgtCS, toSrcCS; // from/to global CS + gp_Ax2d srcCS( srcP0, gp_Vec2d( srcP0, srcP1 )); + gp_Ax2d tgtCS( tgtP0, gp_Vec2d( tgtP0, tgtP1 )); + toSrcCS .SetTransformation( srcCS ); + fromTgtCS.SetTransformation( tgtCS ); + fromTgtCS.Invert(); + + trsf = fromTgtCS * toSrcCS; + + // check transformation + const double tol = 1e-5 * gp_Vec2d( srcP0, srcP1 ).Magnitude(); + for ( double u = 0.12; u < 1.; u += 0.1 ) + { + gp_Pnt2d srcUV = srcWires[0]->Value2d( u ); + gp_Pnt2d tgtUV = tgtWires[0]->Value2d( u ); + gp_Pnt2d tgtUV2 = srcUV.Transformed( trsf ); + if ( tgtUV.Distance( tgtUV2 ) > tol ) + return false; + } + } + + // 3) Projection + + typedef map TN2NMap; + TN2NMap src2tgtNodes; + TN2NMap::iterator srcN_tgtN; + + // fill src2tgtNodes in with nodes on EDGEs + for ( unsigned iW = 0; iW < srcWires.size(); ++iW ) + if ( is1DComputed ) + { + const vector& srcUVs = srcWires[iW]->GetUVPtStruct(); + const vector& tgtUVs = tgtWires[iW]->GetUVPtStruct(); + for ( unsigned i = 0; i < srcUVs.size(); ++i ) + src2tgtNodes.insert( make_pair( srcUVs[i].node, tgtUVs[i].node )); + } + else + { + for ( int iE = 0; iE < srcWires[iW]->NbEdges(); ++iE ) + { + TopoDS_Vertex srcV = srcWires[iW]->FirstVertex(iE); + TopoDS_Vertex tgtV = tgtWires[iW]->FirstVertex(iE); + const SMDS_MeshNode* srcNode = SMESH_Algo::VertexNode( srcV, srcMesh->GetMeshDS() ); + const SMDS_MeshNode* tgtNode = SMESH_Algo::VertexNode( tgtV, tgtMesh->GetMeshDS() ); + if ( tgtNode && srcNode ) + src2tgtNodes.insert( make_pair( srcNode, tgtNode )); + } + } + + // make elements + + SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace ); + + SMESH_MesherHelper helper( *tgtMesh ); + helper.SetSubShape( tgtFace ); + if ( is1DComputed ) + helper.IsQuadraticSubMesh( tgtFace ); + else + helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); + helper.SetElementsOnShape( true ); + Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace ); + SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); + + SMESH_MesherHelper srcHelper( *srcMesh ); + srcHelper.SetSubShape( srcFace ); + + const SMDS_MeshNode* nullNode = 0; + + SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements(); + vector< const SMDS_MeshNode* > tgtNodes; + bool uvOK; + while ( elemIt->more() ) // loop on all mesh faces on srcFace + { + const SMDS_MeshElement* elem = elemIt->next(); + const int nbN = elem->NbCornerNodes(); + tgtNodes.resize( nbN ); + for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element + { + const SMDS_MeshNode* srcNode = elem->GetNode(i); + srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first; + if ( srcN_tgtN->second == nullNode ) + { + // create a new node + gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode, + elem->GetNode( helper.WrapIndex(i+1,nbN)), &uvOK); + gp_Pnt2d tgtUV = srcUV.Transformed( trsf ); + gp_Pnt tgtP = tgtSurface->Value( tgtUV.X(), tgtUV.Y() ); + SMDS_MeshNode* n = tgtMeshDS->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); + switch ( srcNode->GetPosition()->GetTypeOfPosition() ) + { + case SMDS_TOP_FACE: { + tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), tgtUV.X(), tgtUV.Y() ); + break; + } + case SMDS_TOP_EDGE: { + TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() ); + TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true )); + tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge )); + double U = srcHelper.GetNodeU( TopoDS::Edge( srcEdge ), srcNode ); + helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion()); + n->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition( U ))); + break; + } + case SMDS_TOP_VERTEX: { + TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() ); + TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true ); + tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV )); + break; + } + } + srcN_tgtN->second = n; + } + tgtNodes[i] = srcN_tgtN->second; + } + // create a new face (with reversed orientation) + switch ( nbN ) + { + case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break; + case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break; + } + } + return true; + + } // bool projectBy2DSimilarity(...) + } // namespace + //======================================================================= //function : Compute //purpose : @@ -363,6 +773,7 @@ namespace { bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape) { + MESSAGE("Projection_2D Compute"); if ( !_sourceHypo ) return false; @@ -374,14 +785,14 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); // --------------------------- - // Make subshapes association + // Make sub-shapes association // --------------------------- TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD)); TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD); TAssocTool::TShapeShapeMap shape2ShapeMap; - TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtFace ); + TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh, shape2ShapeMap) || !shape2ShapeMap.IsBound( tgtFace )) @@ -405,197 +816,274 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); } - // -------------------- - // Prepare to mapping - // -------------------- - - SMESH_MesherHelper helper( theMesh ); - helper.SetSubShape( tgtFace ); - - // Check if node projection to a face is needed - Bnd_B2d uvBox; - SMDS_ElemIteratorPtr faceIt = srcSubMesh->GetSubMeshDS()->GetElements(); - for ( int nbN = 0; nbN < 3 && faceIt->more(); ) { - const SMDS_MeshElement* face = faceIt->next(); - SMDS_ElemIteratorPtr nodeIt = face->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { - nbN++; - uvBox.Add( helper.GetNodeUV( srcFace, node )); - } - } - } - const bool toProjectNodes = ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN ); - - // Load pattern from the source face - SMESH_Pattern mapper; - mapper.Load( srcMesh, srcFace, toProjectNodes ); - if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - 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 - // and flag needed to call mapper.Apply() - - TopoDS_Vertex srcV1 = TopoDS::Vertex( mapper.GetSubShape( 1 )); - if ( srcV1.IsNull() ) - RETURN_BAD_RESULT("Mesh is not bound to the face"); - if ( !shape2ShapeMap.IsBound( srcV1 )) - RETURN_BAD_RESULT("Not associated vertices, srcV1 " << srcV1.TShape().operator->() ); - TopoDS_Vertex tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1 )); - - if ( !TAssocTool::IsSubShape( srcV1, srcFace )) - RETURN_BAD_RESULT("Wrong srcV1 " << srcV1.TShape().operator->()); - if ( !TAssocTool::IsSubShape( tgtV1, tgtFace )) - RETURN_BAD_RESULT("Wrong tgtV1 " << tgtV1.TShape().operator->()); - - // try to find out orientation by order of edges - bool reverse = false; - list< TopoDS_Edge > tgtEdges, srcEdges; - list< int > nbEdgesInWires; - SMESH_Block::GetOrderedEdges( tgtFace, tgtV1, tgtEdges, nbEdgesInWires); - SMESH_Block::GetOrderedEdges( srcFace, srcV1, srcEdges, nbEdgesInWires); - if ( nbEdgesInWires.front() > 1 ) // possible to find out + // =========== + // Projection + // =========== + + // find out if EDGEs are meshed or not + bool is1DComputed = false; + SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(/*includeSelf=*/false, + /*complexShapeFirst=*/true); + while ( smIt->more() && !is1DComputed ) { - TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front(); - TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 ); - reverse = ( ! srcE1.IsSame( srcE1bis )); + SMESH_subMesh* sm = smIt->next(); + if ( sm->GetSubShape().ShapeType() == TopAbs_EDGE ) + is1DComputed = sm->IsMeshComputed(); } - else if ( nbEdgesInWires.front() == 1 ) + + bool done = false; + + if ( !done ) { - // TODO::Compare orientation of curves in a sole edge - //RETURN_BAD_RESULT("Not implemented case"); + // try to project from the same face with different location + done = projectPartner( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap ); } - else + if ( !done ) { - RETURN_BAD_RESULT("Bad result from SMESH_Block::GetOrderedEdges()"); + // projection in case if the faces are similar in 2D space + done = projectBy2DSimilarity( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap, is1DComputed); } - // -------------------- - // Perform 2D mapping - // -------------------- - - // Compute mesh on a target face + if ( !done ) + { + // -------------------- + // Prepare to mapping + // -------------------- + + SMESH_MesherHelper helper( theMesh ); + helper.SetSubShape( tgtFace ); + + // Check if node projection to a face is needed + Bnd_B2d uvBox; + SMDS_ElemIteratorPtr faceIt = srcSubMesh->GetSubMeshDS()->GetElements(); + int nbFaceNodes = 0; + for ( ; nbFaceNodes < 3 && faceIt->more(); ) { + const SMDS_MeshElement* face = faceIt->next(); + SMDS_ElemIteratorPtr nodeIt = face->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { + nbFaceNodes++; + uvBox.Add( helper.GetNodeUV( srcFace, node )); + } + } + } + const bool toProjectNodes = + ( nbFaceNodes > 0 && ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN )); + + // Load pattern from the source face + SMESH_Pattern mapper; + mapper.Load( srcMesh, srcFace, toProjectNodes ); + if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) + 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 + // and flag needed to call mapper.Apply() + + TopoDS_Vertex srcV1 = TopoDS::Vertex( mapper.GetSubShape( 1 )); + if ( srcV1.IsNull() ) + RETURN_BAD_RESULT("Mesh is not bound to the face"); + if ( !shape2ShapeMap.IsBound( srcV1, /*isSrc=*/true )) + RETURN_BAD_RESULT("Not associated vertices, srcV1 " << srcV1.TShape().operator->() ); + TopoDS_Vertex tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true )); + + if ( !SMESH_MesherHelper::IsSubShape( srcV1, srcFace )) + RETURN_BAD_RESULT("Wrong srcV1 " << srcV1.TShape().operator->()); + if ( !SMESH_MesherHelper::IsSubShape( tgtV1, tgtFace )) + RETURN_BAD_RESULT("Wrong tgtV1 " << tgtV1.TShape().operator->()); + + // try to find out orientation by order of edges + bool reverse = false; + list< TopoDS_Edge > tgtEdges, srcEdges; + list< int > nbEdgesInWires; + SMESH_Block::GetOrderedEdges( tgtFace, tgtV1, tgtEdges, nbEdgesInWires); + SMESH_Block::GetOrderedEdges( srcFace, srcV1, srcEdges, nbEdgesInWires); + if ( nbEdgesInWires.front() > 1 ) // possible to find out + { + TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front(); + TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 ); + reverse = ( ! srcE1.IsSame( srcE1bis )); + } + else if ( nbEdgesInWires.front() == 1 ) + { + // TODO::Compare orientation of curves in a sole edge + //RETURN_BAD_RESULT("Not implemented case"); + } + else + { + RETURN_BAD_RESULT("Bad result from SMESH_Block::GetOrderedEdges()"); + } - mapper.Apply( tgtFace, tgtV1, reverse ); - if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - return error("Can't apply source mesh pattern to the face"); + // -------------------- + // Perform 2D mapping + // -------------------- - // Create the mesh + // Compute mesh on a target face - const bool toCreatePolygons = false, toCreatePolyedrs = false; - mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs ); - if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) - return error("Can't make mesh by source mesh pattern"); + mapper.Apply( tgtFace, tgtV1, reverse ); + if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) + return error("Can't apply source mesh pattern to the face"); - // it will remove mesh built by pattern mapper on edges and vertices - // in failure case - MeshCleaner cleaner( tgtSubMesh ); + // Create the mesh - // ------------------------------------------------------------------------- - // mapper doesn't take care of nodes already existing on edges and vertices, - // so we must merge nodes created by it with existing ones - // ------------------------------------------------------------------------- + const bool toCreatePolygons = false, toCreatePolyedrs = false; + mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs ); + if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) + return error("Can't make mesh by source mesh pattern"); - SMESH_MeshEditor editor( tgtMesh ); - SMESH_MeshEditor::TListOfListOfNodes groupsOfNodes; + // it will remove mesh built by pattern mapper on edges and vertices + // in failure case + MeshCleaner cleaner( tgtSubMesh ); - // Make groups of nodes to merge + // ------------------------------------------------------------------------- + // mapper doesn't take care of nodes already existing on edges and vertices, + // so we must merge nodes created by it with existing ones + // ------------------------------------------------------------------------- - // loop on edge and vertex submeshes of a target face - SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(false,false); - while ( smIt->more() ) - { - SMESH_subMesh* sm = smIt->next(); - SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + SMESH_MeshEditor::TListOfListOfNodes groupsOfNodes; - // Sort new and old nodes of a submesh separately + // Make groups of nodes to merge - bool isSeam = helper.IsRealSeam( sm->GetId() ); + // loop on edge and vertex submeshes of a target face + smIt = tgtSubMesh->getDependsOnIterator(/*includeSelf=*/false,/*complexShapeFirst=*/false); + while ( smIt->more() ) + { + SMESH_subMesh* sm = smIt->next(); + SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + if ( !smDS || smDS->NbNodes() == 0 ) + continue; + //if ( !is1DComputed && sm->GetSubShape().ShapeType() == TopAbs_EDGE ) + //break; - enum { NEW_NODES = 0, OLD_NODES }; - map< double, const SMDS_MeshNode* > u2nodesMaps[2], u2nodesOnSeam; - map< double, const SMDS_MeshNode* >::iterator u_oldNode, u_newNode, u_newOnSeam, newEnd; - set< const SMDS_MeshNode* > seamNodes; + // Sort new and old nodes of a submesh separately - // mapper puts on a seam edge nodes from 2 edges - if ( isSeam && ! getBoundaryNodes ( sm, tgtFace, u2nodesOnSeam, seamNodes )) - RETURN_BAD_RESULT("getBoundaryNodes() failed"); + bool isSeam = helper.IsRealSeam( sm->GetId() ); - SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); - while ( nIt->more() ) - { - const SMDS_MeshNode* node = nIt->next(); - bool isOld = isOldNode( node ); + enum { NEW_NODES = 0, OLD_NODES }; + map< double, const SMDS_MeshNode* > u2nodesMaps[2], u2nodesOnSeam; + map< double, const SMDS_MeshNode* >::iterator u_oldNode, u_newNode, u_newOnSeam, newEnd; + set< const SMDS_MeshNode* > seamNodes; - if ( !isOld && isSeam ) { // new node on a seam edge - if ( seamNodes.find( node ) != seamNodes.end()) - continue; // node is already in the map - } + // mapper puts on a seam edge nodes from 2 edges + if ( isSeam && ! getBoundaryNodes ( sm, tgtFace, u2nodesOnSeam, seamNodes )) + RETURN_BAD_RESULT("getBoundaryNodes() failed"); - // sort nodes on edges by their position - map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[isOld ? OLD_NODES : NEW_NODES]; - switch ( node->GetPosition()->GetTypeOfPosition() ) + SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); + while ( nIt->more() ) { - case SMDS_TOP_VERTEX: { - pos2nodes.insert( make_pair( 0, node )); - break; - } - case SMDS_TOP_EDGE: { - const SMDS_EdgePosition* pos = - static_cast(node->GetPosition().get()); - pos2nodes.insert( make_pair( pos->GetUParameter(), node )); - break; + const SMDS_MeshNode* node = nIt->next(); + bool isOld = isOldNode( node ); + + if ( !isOld && isSeam ) { // new node on a seam edge + if ( seamNodes.count( node ) ) + continue; // node is already in the map + } + + // sort nodes on edges by their position + map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[isOld ? OLD_NODES : NEW_NODES]; + switch ( node->GetPosition()->GetTypeOfPosition() ) + { + case SMDS_TOP_VERTEX: { + if ( !is1DComputed && !pos2nodes.empty() ) + u2nodesMaps[isOld ? NEW_NODES : OLD_NODES].insert( make_pair( 0, node )); + else + pos2nodes.insert( make_pair( 0, node )); + break; + } + case SMDS_TOP_EDGE: { + const SMDS_EdgePosition* pos = + static_cast(node->GetPosition()); + pos2nodes.insert( make_pair( pos->GetUParameter(), node )); + break; + } + default: + RETURN_BAD_RESULT("Wrong node position type: "<< + node->GetPosition()->GetTypeOfPosition()); + } } - default: - RETURN_BAD_RESULT("Wrong node position type: "<< - node->GetPosition()->GetTypeOfPosition()); + const bool mergeNewToOld = + ( u2nodesMaps[ NEW_NODES ].size() == u2nodesMaps[ OLD_NODES ].size() ); + const bool mergeSeamToNew = + ( u2nodesMaps[ NEW_NODES ].size() == u2nodesOnSeam.size() ); + + if ( !mergeNewToOld ) + if ( u2nodesMaps[ NEW_NODES ].size() > 0 && + u2nodesMaps[ OLD_NODES ].size() > 0 ) + { + u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); + newEnd = u2nodesMaps[ OLD_NODES ].end(); + for ( ; u_oldNode != newEnd; ++u_oldNode ) + _badInputElements.push_back( u_oldNode->second ); + return error( COMPERR_BAD_INPUT_MESH, + SMESH_Comment( "Existing mesh mismatches the projected 2D mesh on " ) + << ( sm->GetSubShape().ShapeType() == TopAbs_EDGE ? "edge" : "vertex" ) + << " #" << sm->GetId() ); + } + if ( isSeam && !mergeSeamToNew ) { + //RETURN_BAD_RESULT + MESSAGE("Different nb of old and seam nodes " << + u2nodesMaps[ OLD_NODES ].size() << " != " << u2nodesOnSeam.size()); } + // Make groups of nodes to merge + u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); + u_newNode = u2nodesMaps[ NEW_NODES ].begin(); + newEnd = u2nodesMaps[ NEW_NODES ].end(); + u_newOnSeam = u2nodesOnSeam.begin(); + if ( mergeNewToOld ) + for ( ; u_newNode != newEnd; ++u_newNode, ++u_oldNode ) + { + groupsOfNodes.push_back( list< const SMDS_MeshNode* >() ); + groupsOfNodes.back().push_back( u_oldNode->second ); + groupsOfNodes.back().push_back( u_newNode->second ); + if ( mergeSeamToNew ) + groupsOfNodes.back().push_back( (u_newOnSeam++)->second ); + } + else if ( mergeSeamToNew ) + for ( ; u_newNode != newEnd; ++u_newNode, ++u_newOnSeam ) + { + groupsOfNodes.push_back( list< const SMDS_MeshNode* >() ); + groupsOfNodes.back().push_back( u_newNode->second ); + groupsOfNodes.back().push_back( u_newOnSeam->second ); + } } - if ( u2nodesMaps[ NEW_NODES ].size() != u2nodesMaps[ OLD_NODES ].size() ) + + // Merge + + SMESH_MeshEditor editor( tgtMesh ); + int nbFaceBeforeMerge = tgtSubMesh->GetSubMeshDS()->NbElements(); + editor.MergeNodes( groupsOfNodes ); + int nbFaceAtferMerge = tgtSubMesh->GetSubMeshDS()->NbElements(); + if ( nbFaceBeforeMerge != nbFaceAtferMerge ) + return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces"); + + // ---------------------------------------------------------------- + // The mapper can't create quadratic elements, so convert if needed + // ---------------------------------------------------------------- + + faceIt = srcSubMesh->GetSubMeshDS()->GetElements(); + bool srcIsQuad = faceIt->next()->IsQuadratic(); + faceIt = tgtSubMesh->GetSubMeshDS()->GetElements(); + bool tgtIsQuad = faceIt->next()->IsQuadratic(); + if ( srcIsQuad && !tgtIsQuad ) { - if ( u2nodesMaps[ NEW_NODES ].size() == 0 && - sm->GetSubShape().ShapeType() == TopAbs_EDGE && - helper.IsDegenShape( sm->GetId() ) ) - // NPAL15894 (tt88bis.py) - project mesh built by NETGEN_1d_2D that - // does not make segments/nodes on degenerated edges - continue; + TIDSortedElemSet tgtFaces; + faceIt = tgtSubMesh->GetSubMeshDS()->GetElements(); + while ( faceIt->more() ) + tgtFaces.insert( tgtFaces.end(), faceIt->next() ); - RETURN_BAD_RESULT("Different nb of old and new nodes on shape #"<< sm->GetId() <<" "<< - u2nodesMaps[ OLD_NODES ].size() << " != " << - u2nodesMaps[ NEW_NODES ].size()); + editor.ConvertToQuadratic(/*theForce3d=*/false, tgtFaces); } - if ( isSeam && u2nodesMaps[ OLD_NODES ].size() != u2nodesOnSeam.size() ) { - RETURN_BAD_RESULT("Different nb of old and seam nodes " << - u2nodesMaps[ OLD_NODES ].size() << " != " << u2nodesOnSeam.size()); - } - // Make groups of nodes to merge - u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); - u_newNode = u2nodesMaps[ NEW_NODES ].begin(); - newEnd = u2nodesMaps[ NEW_NODES ].end(); - u_newOnSeam = u2nodesOnSeam.begin(); - for ( ; u_newNode != newEnd; ++u_newNode, ++u_oldNode ) { - groupsOfNodes.push_back( list< const SMDS_MeshNode* >() ); - groupsOfNodes.back().push_back( u_oldNode->second ); - groupsOfNodes.back().push_back( u_newNode->second ); - if ( isSeam ) - groupsOfNodes.back().push_back( (u_newOnSeam++)->second ); - } - } - // Merge + cleaner.Release(); // not to remove mesh + + } // end of projection using Pattern mapping - int nbFaceBeforeMerge = tgtSubMesh->GetSubMeshDS()->NbElements(); - editor.MergeNodes( groupsOfNodes ); - int nbFaceAtferMerge = tgtSubMesh->GetSubMeshDS()->NbElements(); - if ( nbFaceBeforeMerge != nbFaceAtferMerge ) - return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces"); // --------------------------- // Check elements orientation // --------------------------- - TopoDS_Face face = tgtFace; + TopoDS_Face face = TopoDS::Face( theShape ); if ( !theMesh.IsMainShape( tgtFace )) { // find the main shape @@ -627,6 +1115,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // Fix orientation if ( SMESH_Algo::IsReversedSubMesh( face, meshDS )) { + SMESH_MeshEditor editor( tgtMesh ); SMDS_ElemIteratorPtr eIt = meshDS->MeshElements( face )->GetElements(); while ( eIt->more() ) { const SMDS_MeshElement* e = eIt->next(); @@ -635,11 +1124,77 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } } - cleaner.Release(); // do not remove mesh + return true; +} + + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_Projection_2D::Evaluate(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + MapShapeNbElems& aResMap) +{ + if ( !_sourceHypo ) + return false; + + SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); + SMESH_Mesh * tgtMesh = & theMesh; + if ( !srcMesh ) + srcMesh = tgtMesh; + + // --------------------------- + // Make sub-shapes association + // --------------------------- + + TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD)); + TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD); + + TAssocTool::TShapeShapeMap shape2ShapeMap; + TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap ); + if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh, + shape2ShapeMap) || + !shape2ShapeMap.IsBound( tgtFace )) + return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" ); + + TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD)); + + // ------------------------------------------------------- + // Assure that mesh on a source Face is computed/evaluated + // ------------------------------------------------------- + + std::vector aVec; + + SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcFace ); + if ( srcSubMesh->IsMeshComputed() ) + { + aVec.resize( SMDSEntity_Last, 0 ); + aVec[SMDSEntity_Node] = srcSubMesh->GetSubMeshDS()->NbNodes(); + + SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements(); + while ( elemIt->more() ) + aVec[ elemIt->next()->GetEntityType() ]++; + } + else + { + MapShapeNbElems tmpResMap; + MapShapeNbElems& srcResMap = (srcMesh == tgtMesh) ? aResMap : tmpResMap; + if ( !_gen->Evaluate( *srcMesh, srcShape, srcResMap )) + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not evaluatable"); + aVec = srcResMap[ srcSubMesh ]; + if ( aVec.empty() ) + return error(COMPERR_BAD_INPUT_MESH,"Source mesh is wrongly evaluated"); + } + + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(std::make_pair(sm,aVec)); return true; } + //============================================================================= /*! * \brief Sets a default event listener to submesh of the source face diff --git a/src/StdMeshers/StdMeshers_Projection_2D.hxx b/src/StdMeshers/StdMeshers_Projection_2D.hxx index 006db8344..3d1bd1808 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.hxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Projection_2D.hxx // Module : SMESH @@ -44,6 +45,9 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + /*! * \brief Sets a default event listener to submesh of the source face * \param whenSetToSubMesh - submesh where algo is set diff --git a/src/StdMeshers/StdMeshers_Projection_3D.cxx b/src/StdMeshers/StdMeshers_Projection_3D.cxx index 7d657ac4e..76c29c822 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Projection_3D.cxx // Module : SMESH @@ -30,19 +31,18 @@ #include "StdMeshers_ProjectionUtils.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_VolumeTool.hxx" #include "SMESHDS_Hypothesis.hxx" #include "SMESHDS_SubMesh.hxx" #include "SMESH_Block.hxx" +#include "SMESH_Comment.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_Pattern.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" -#include "SMESH_MesherHelper.hxx" -#include "SMESH_Comment.hxx" -#include "SMDS_VolumeTool.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "utilities.h" @@ -69,7 +69,7 @@ StdMeshers_Projection_3D::StdMeshers_Projection_3D(int hypId, int studyId, SMESH :SMESH_3D_Algo(hypId, studyId, gen) { _name = "Projection_3D"; - _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit per shape type + _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit per shape type _compatibleHypothesis.push_back("ProjectionSource3D"); _sourceHypo = 0; @@ -142,12 +142,12 @@ bool StdMeshers_Projection_3D::CheckHypothesis(SMESH_Mesh& TopoDS_Shape edge = TAssocTool::GetEdgeByVertices ( srcMesh, _sourceHypo->GetSourceVertex(1), _sourceHypo->GetSourceVertex(2) ); if ( edge.IsNull() || - !TAssocTool::IsSubShape( edge, srcMesh ) || - !TAssocTool::IsSubShape( edge, _sourceHypo->GetSource3DShape() )) + !SMESH_MesherHelper::IsSubShape( edge, srcMesh ) || + !SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSource3DShape() )) { SCRUTE((edge.IsNull())); - SCRUTE((TAssocTool::IsSubShape( edge, srcMesh ))); - SCRUTE((TAssocTool::IsSubShape( edge, _sourceHypo->GetSource3DShape() ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, srcMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSource3DShape() ))); aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER; } else @@ -156,21 +156,21 @@ bool StdMeshers_Projection_3D::CheckHypothesis(SMESH_Mesh& edge = TAssocTool::GetEdgeByVertices ( tgtMesh, _sourceHypo->GetTargetVertex(1), _sourceHypo->GetTargetVertex(2) ); if ( edge.IsNull() || - !TAssocTool::IsSubShape( edge, tgtMesh ) || - !TAssocTool::IsSubShape( edge, aShape )) + !SMESH_MesherHelper::IsSubShape( edge, tgtMesh ) || + !SMESH_MesherHelper::IsSubShape( edge, aShape )) { SCRUTE((edge.IsNull())); - SCRUTE((TAssocTool::IsSubShape( edge, tgtMesh ))); - SCRUTE((TAssocTool::IsSubShape( edge, aShape ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, tgtMesh ))); + SCRUTE((SMESH_MesherHelper::IsSubShape( edge, aShape ))); aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER; } } } // check a source shape - if ( !TAssocTool::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh ) || + if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh ) || ( srcMesh == tgtMesh && aShape == _sourceHypo->GetSource3DShape())) { - SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh))); + SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh))); SCRUTE((srcMesh == tgtMesh)); SCRUTE((aShape == _sourceHypo->GetSource3DShape())); aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER; @@ -264,12 +264,12 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 ); if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 )) - return error("Association of subshapes failed" ); + return error("Association of sub-shapes failed" ); srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 )); srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 )); - if ( !TAssocTool::IsSubShape( srcV000, srcShell ) || - !TAssocTool::IsSubShape( srcV100, srcShell )) - return error("Incorrect association of subshapes" ); + if ( !SMESH_MesherHelper::IsSubShape( srcV000, srcShell ) || + !SMESH_MesherHelper::IsSubShape( srcV100, srcShell )) + return error("Incorrect association of sub-shapes" ); } // Load 2 SMESH_Block's with src and tgt shells @@ -277,20 +277,20 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS SMESH_Block srcBlock, tgtBlock; TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes; if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes )) - return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?"); + return error(COMPERR_BAD_SHAPE, "Can't detect block sub-shapes. Not a block?"); if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes )) - return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?"); + return error(COMPERR_BAD_SHAPE, "Can't detect block sub-shapes. Not a block?"); // Find matching nodes of src and tgt shells TNodeNodeMap src2tgtNodeMap; for ( int fId = SMESH_Block::ID_FirstF; fId < SMESH_Block::ID_Shell; ++fId ) { - // Corresponding subshapes + // Corresponding sub-shapes TopoDS_Face srcFace = TopoDS::Face( scrShapes( fId )); TopoDS_Face tgtFace = TopoDS::Face( tgtShapes( fId )); - if ( _sourceHypo->HasVertexAssociation() ) { // associate face subshapes + if ( _sourceHypo->HasVertexAssociation() ) { // associate face sub-shapes shape2ShapeMap.Clear(); vector< int > edgeIdVec; SMESH_Block::GetFaceEdgesIDs( fId, edgeIdVec ); @@ -309,9 +309,9 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS TNodeNodeMap faceMatchingNodes; if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh, shape2ShapeMap, faceMatchingNodes )) - return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #") - << srcMeshDS->ShapeToIndex( srcFace ) << " and " - << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" ); + 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() ); @@ -407,11 +407,13 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS nodes[6], nodes[7], id, force3d); break; default: // polyhedron - const SMDS_PolyhedralVolumeOfNodes * poly = - dynamic_cast( srcVol ); + const SMDS_VtkVolume * poly = + dynamic_cast( srcVol ); if ( !poly ) RETURN_BAD_RESULT("Unexpected volume type"); - tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() ); + if ( !poly->IsPoly()) + RETURN_BAD_RESULT("Unexpected volume type"); + tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuantities() ); } if ( tgtVol ) { tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() ); @@ -421,6 +423,104 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS return true; } + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_Projection_3D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + if ( !_sourceHypo ) + return false; + + SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); + SMESH_Mesh * tgtMesh = & aMesh; + if ( !srcMesh ) + srcMesh = tgtMesh; + + // get shell from shape3D + TopoDS_Shell srcShell, tgtShell; + TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL ); + int nbShell; + for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell ) + srcShell = TopoDS::Shell( exp.Current() ); + if ( nbShell != 1 ) + return error(COMPERR_BAD_SHAPE, + SMESH_Comment("Source 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 error(COMPERR_BAD_SHAPE, + SMESH_Comment("Target shape must have 1 shell but not ") << nbShell); + + // Check that shapes are blocks + if ( TAssocTool::Count( tgtShell, TopAbs_FACE , 1 ) != 6 || + TAssocTool::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 || + TAssocTool::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 ) + return error(COMPERR_BAD_SHAPE, "Target shape is not a block"); + if ( TAssocTool::Count( srcShell, TopAbs_FACE , 1 ) != 6 || + TAssocTool::Count( srcShell, TopAbs_EDGE , 1 ) != 12 || + TAssocTool::Count( srcShell, TopAbs_WIRE , 1 ) != 6 ) + return error(COMPERR_BAD_SHAPE, "Source shape is not a block"); + + // Assure that mesh on a source shape is computed + + SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() ); + + if ( !srcSubMesh->IsMeshComputed() ) + return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); + + + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetSubMeshDS()->NbNodes(); + + //bool quadratic = false; + SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements(); + while ( elemIt->more() ) { + const SMDS_MeshElement* E = elemIt->next(); + if( E->NbNodes()==4 ) { + aVec[SMDSEntity_Tetra]++; + } + else if( E->NbNodes()==5 ) { + aVec[SMDSEntity_Pyramid]++; + } + else if( E->NbNodes()==6 ) { + aVec[SMDSEntity_Penta]++; + } + else if( E->NbNodes()==8 ) { + aVec[SMDSEntity_Hexa]++; + } + else if( E->NbNodes()==10 && E->IsQuadratic() ) { + aVec[SMDSEntity_Quad_Tetra]++; + } + else if( E->NbNodes()==13 && E->IsQuadratic() ) { + aVec[SMDSEntity_Quad_Pyramid]++; + } + else if( E->NbNodes()==15 && E->IsQuadratic() ) { + aVec[SMDSEntity_Quad_Penta]++; + } + else if( E->NbNodes()==20 && E->IsQuadratic() ) { + aVec[SMDSEntity_Quad_Hexa]++; + } + else { + aVec[SMDSEntity_Polyhedra]++; + } + } + + SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); + aResMap.insert(std::make_pair(sm,aVec)); + + return true; +} + + //============================================================================= /*! * \brief Sets a default event listener to submesh of the source shape diff --git a/src/StdMeshers/StdMeshers_Projection_3D.hxx b/src/StdMeshers/StdMeshers_Projection_3D.hxx index 7f4200ef4..03e8c4838 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.hxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Projection_3D.hxx // Module : SMESH @@ -44,6 +45,9 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + /*! * \brief Sets a default event listener to submesh of the source shape * \param whenSetToSubMesh - submesh where algo is set diff --git a/src/StdMeshers/StdMeshers_Propagation.cxx b/src/StdMeshers/StdMeshers_Propagation.cxx index c6b9b015f..0550c86a7 100644 --- a/src/StdMeshers/StdMeshers_Propagation.cxx +++ b/src/StdMeshers/StdMeshers_Propagation.cxx @@ -1,34 +1,36 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Propagation.cxx // Module : SMESH - +// #include "StdMeshers_Propagation.hxx" #include "utilities.h" #include "SMDS_SetIterator.hxx" #include "SMESH_Algo.hxx" +#include "SMESH_Gen.hxx" #include "SMESH_HypoFilter.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" @@ -39,7 +41,7 @@ #include #define DBGMSG(txt) \ -// cout << txt << endl; + // cout << txt << endl; using namespace std; @@ -266,7 +268,7 @@ namespace { for (; itA.More(); itA.Next()) { // there are objects of different type among the ancestors of edge - if ( itA.Value().ShapeType() != TopAbs_WIRE || !checkedShapes.Add( itA.Value() )) + if ( itA.Value().ShapeType() != TopAbs_WIRE /*|| !checkedShapes.Add( itA.Value() )*/) continue; // Get ordered edges and find index of anE in a sequence @@ -288,8 +290,7 @@ namespace { continue; // too few edges } else if ( edges.size() == 4 ) { - int oppIndex = edgeIndex + 2; - if ( oppIndex > 3 ) oppIndex -= 4; + int oppIndex = ( edgeIndex + 2 ) % 4; anOppE = edges[ oppIndex ]; } else { @@ -346,6 +347,10 @@ namespace { oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); oppData->SetState( IN_CHAIN ); DBGMSG( "set IN_CHAIN on " << oppSM->GetId() ); + if ( oppSM->GetAlgoState() != SMESH_subMesh::HYP_OK ) + // make oppSM check algo state + if ( SMESH_Algo* algo = mesh->GetGen()->GetAlgo( *mesh, anOppE )) + oppSM->AlgoStateEngine(SMESH_subMesh::ADD_FATHER_ALGO,algo); } else { oppData->SetState( LAST_IN_CHAIN ); @@ -444,7 +449,8 @@ namespace { //================================================================================ PropagationMgr::PropagationMgr() - : SMESH_subMeshEventListener( false ) // won't be deleted by submesh + : SMESH_subMeshEventListener( false, // won't be deleted by submesh + "StdMeshers_Propagation::PropagationMgr") {} //================================================================================ /*! @@ -454,6 +460,7 @@ namespace { void PropagationMgr::Set(SMESH_subMesh * submesh) { + if ( findData( submesh )) return; DBGMSG( "PropagationMgr::Set() on " << submesh->GetId() ); EventListenerData* data = new PropagationMgrData(); submesh->SetEventListener( getListener(), data, submesh ); diff --git a/src/StdMeshers/StdMeshers_Propagation.hxx b/src/StdMeshers/StdMeshers_Propagation.hxx index b02f9aebe..5a72d72a5 100644 --- a/src/StdMeshers/StdMeshers_Propagation.hxx +++ b/src/StdMeshers/StdMeshers_Propagation.hxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Propagation.hxx // Module : SMESH - +// #ifndef _SMESH_PROPAGATION_HXX_ #define _SMESH_PROPAGATION_HXX_ diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx index 620bad81c..5764cc6ea 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx @@ -1,59 +1,370 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : StdMeshers_QuadToTriaAdaptor.cxx // Module : SMESH // Created : Wen May 07 16:37:07 2008 // Author : Sergey KUUL (skl) -// + #include "StdMeshers_QuadToTriaAdaptor.hxx" -//#include -//#include +#include "SMDS_SetIterator.hxx" + +#include "SMESH_Algo.hxx" +#include "SMESH_MesherHelper.hxx" + +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -typedef NCollection_Array1 StdMeshers_Array1OfSequenceOfInteger; +#include +#include +using namespace std; -//======================================================================= -//function : StdMeshers_QuadToTriaAdaptor -//purpose : -//======================================================================= +enum EQuadNature { NOT_QUAD, QUAD, DEGEN_QUAD, PYRAM_APEX = 4, TRIA_APEX = 0 }; -StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor() +// std-like iterator used to get coordinates of nodes of mesh element +typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator; + +namespace { + //================================================================================ + /*! + * \brief Return true if two nodes of triangles are equal + */ + //================================================================================ + + bool EqualTriangles(const SMDS_MeshElement* F1,const SMDS_MeshElement* F2) + { + return + ( F1->GetNode(1)==F2->GetNode(2) && F1->GetNode(2)==F2->GetNode(1) ) || + ( F1->GetNode(1)==F2->GetNode(1) && F1->GetNode(2)==F2->GetNode(2) ); + } + //================================================================================ + /*! + * \brief Return true if two adjacent pyramids are too close one to another + * so that a tetrahedron to built between them would have too poor quality + */ + //================================================================================ + + bool TooCloseAdjacent( const SMDS_MeshElement* PrmI, + const SMDS_MeshElement* PrmJ, + const bool hasShape) + { + const SMDS_MeshNode* nApexI = PrmI->GetNode(4); + const SMDS_MeshNode* nApexJ = PrmJ->GetNode(4); + if ( nApexI == nApexJ || + nApexI->getshapeId() != nApexJ->getshapeId() ) + return false; + + // Find two common base nodes and their indices within PrmI and PrmJ + const SMDS_MeshNode* baseNodes[2] = { 0,0 }; + int baseNodesIndI[2], baseNodesIndJ[2]; + for ( int i = 0; i < 4 ; ++i ) + { + int j = PrmJ->GetNodeIndex( PrmI->GetNode(i)); + if ( j >= 0 ) + { + int ind = baseNodes[0] ? 1:0; + if ( baseNodes[ ind ]) + return false; // pyramids with a common base face + baseNodes [ ind ] = PrmI->GetNode(i); + baseNodesIndI[ ind ] = i; + baseNodesIndJ[ ind ] = j; + } + } + if ( !baseNodes[1] ) return false; // not adjacent + + // Get normals of triangles sharing baseNodes + gp_XYZ apexI = SMESH_TNodeXYZ( nApexI ); + gp_XYZ apexJ = SMESH_TNodeXYZ( nApexJ ); + gp_XYZ base1 = SMESH_TNodeXYZ( baseNodes[0]); + gp_XYZ base2 = SMESH_TNodeXYZ( baseNodes[1]); + gp_Vec baseVec( base1, base2 ); + gp_Vec baI( base1, apexI ); + gp_Vec baJ( base1, apexJ ); + gp_Vec nI = baseVec.Crossed( baI ); + gp_Vec nJ = baseVec.Crossed( baJ ); + + // Check angle between normals + double angle = nI.Angle( nJ ); + bool tooClose = ( angle < 15. * M_PI / 180. ); + + // Check if pyramids collide + if ( !tooClose && baI * baJ > 0 ) + { + // find out if nI points outside of PrmI or inside + int dInd = baseNodesIndI[1] - baseNodesIndI[0]; + bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0; + + // find out sign of projection of nJ to baI + double proj = baI * nJ; + + tooClose = isOutI ? proj > 0 : proj < 0; + } + + // Check if PrmI and PrmJ are in same domain + if ( tooClose && !hasShape ) + { + // check order of baseNodes within pyramids, it must be opposite + int dInd; + dInd = baseNodesIndI[1] - baseNodesIndI[0]; + bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0; + dInd = baseNodesIndJ[1] - baseNodesIndJ[0]; + bool isOutJ = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0; + if ( isOutJ == isOutI ) + return false; // other domain + + // direct both normals outside pyramid + ( isOutI ? nJ : nI ).Reverse(); + + // check absence of a face separating domains between pyramids + TIDSortedElemSet emptySet, avoidSet; + int i1, i2; + while ( const SMDS_MeshElement* f = + SMESH_MeshEditor::FindFaceInSet( baseNodes[0], baseNodes[1], + emptySet, avoidSet, &i1, &i2 )) + { + avoidSet.insert( f ); + + // face node other than baseNodes + int otherNodeInd = 0; + while ( otherNodeInd == i1 || otherNodeInd == i2 ) otherNodeInd++; + const SMDS_MeshNode* otherFaceNode = f->GetNode( otherNodeInd ); + + if ( otherFaceNode == nApexI || otherFaceNode == nApexJ ) + continue; // f is a temporary triangle + + // check if f is a base face of either of pyramids + if ( f->NbCornerNodes() == 4 && + ( PrmI->GetNodeIndex( otherFaceNode ) >= 0 || + PrmJ->GetNodeIndex( otherFaceNode ) >= 0 )) + continue; // f is a base quadrangle + + // check projections of face direction (baOFN) to triange normals (nI and nJ) + gp_Vec baOFN( base1, SMESH_TNodeXYZ( otherFaceNode )); + if ( nI * baOFN > 0 && nJ * baOFN > 0 ) + { + tooClose = false; // f is between pyramids + break; + } + } + } + + return tooClose; + } + + //================================================================================ + /*! + * \brief Move medium nodes of merged quadratic pyramids + */ + //================================================================================ + + void UpdateQuadraticPyramids(const set& commonApex, + SMESHDS_Mesh* meshDS) + { + typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TStdElemIterator; + TStdElemIterator itEnd; + + // shift of node index to get medium nodes between the 4 base nodes and the apex + const int base2MediumShift = 9; + + set::const_iterator nIt = commonApex.begin(); + for ( ; nIt != commonApex.end(); ++nIt ) + { + SMESH_TNodeXYZ apex( *nIt ); + + vector< const SMDS_MeshElement* > pyrams // pyramids sharing the apex node + ( TStdElemIterator( apex._node->GetInverseElementIterator( SMDSAbs_Volume )), itEnd ); + + // Select medium nodes to keep and medium nodes to remove + + typedef map < const SMDS_MeshNode*, const SMDS_MeshNode*, TIDCompare > TN2NMap; + TN2NMap base2medium; // to keep + vector< const SMDS_MeshNode* > nodesToRemove; + + for ( unsigned i = 0; i < pyrams.size(); ++i ) + for ( int baseIndex = 0; baseIndex < PYRAM_APEX; ++baseIndex ) + { + SMESH_TNodeXYZ base = pyrams[i]->GetNode( baseIndex ); + const SMDS_MeshNode* medium = pyrams[i]->GetNode( baseIndex + base2MediumShift ); + TN2NMap::iterator b2m = base2medium.insert( make_pair( base._node, medium )).first; + if ( b2m->second != medium ) + { + nodesToRemove.push_back( medium ); + } + else + { + // move the kept medium node + gp_XYZ newXYZ = 0.5 * ( apex + base ); + meshDS->MoveNode( medium, newXYZ.X(), newXYZ.Y(), newXYZ.Z() ); + } + } + + // Within pyramids, replace nodes to remove by nodes to keep + + for ( unsigned i = 0; i < pyrams.size(); ++i ) + { + vector< const SMDS_MeshNode* > nodes( pyrams[i]->begin_nodes(), + pyrams[i]->end_nodes() ); + for ( int baseIndex = 0; baseIndex < PYRAM_APEX; ++baseIndex ) + { + const SMDS_MeshNode* base = pyrams[i]->GetNode( baseIndex ); + nodes[ baseIndex + base2MediumShift ] = base2medium[ base ]; + } + meshDS->ChangeElementNodes( pyrams[i], &nodes[0], nodes.size()); + } + + // Remove the replaced nodes + + if ( !nodesToRemove.empty() ) + { + SMESHDS_SubMesh * sm = meshDS->MeshElements( nodesToRemove[0]->getshapeId() ); + for ( unsigned i = 0; i < nodesToRemove.size(); ++i ) + meshDS->RemoveFreeNode( nodesToRemove[i], sm, /*fromGroups=*/false); + } + } + } + } +//================================================================================ +/*! + * \brief Merge the two pyramids (i.e. fuse their apex) and others already merged with them + */ +//================================================================================ + +void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement* PrmI, + const SMDS_MeshElement* PrmJ, + set & nodesToMove) +{ + const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove + //int nbJ = Nrem->NbInverseElements( SMDSAbs_Volume ); + SMESH_TNodeXYZ Pj( Nrem ); + + // an apex node to make common to all merged pyramids + SMDS_MeshNode* CommonNode = const_cast(PrmI->GetNode(4)); + if ( CommonNode == Nrem ) return; // already merged + //int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume ); + SMESH_TNodeXYZ Pi( CommonNode ); + gp_XYZ Pnew = /*( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);*/ 0.5 * ( Pi + Pj ); + CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() ); + + nodesToMove.insert( CommonNode ); + nodesToMove.erase ( Nrem ); + + typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TStdElemIterator; + TStdElemIterator itEnd; + + // find and remove coincided faces of merged pyramids + vector< const SMDS_MeshElement* > inverseElems + // copy inverse elements to avoid iteration on changing container + ( TStdElemIterator( CommonNode->GetInverseElementIterator(SMDSAbs_Face)), itEnd); + for ( unsigned i = 0; i < inverseElems.size(); ++i ) + { + const SMDS_MeshElement* FI = inverseElems[i]; + const SMDS_MeshElement* FJEqual = 0; + SMDS_ElemIteratorPtr triItJ = Nrem->GetInverseElementIterator(SMDSAbs_Face); + while ( !FJEqual && triItJ->more() ) + { + const SMDS_MeshElement* FJ = triItJ->next(); + if ( EqualTriangles( FJ, FI )) + FJEqual = FJ; + } + if ( FJEqual ) + { + removeTmpElement( FI ); + removeTmpElement( FJEqual ); + myRemovedTrias.insert( FI ); + myRemovedTrias.insert( FJEqual ); + } + } + + // set the common apex node to pyramids and triangles merged with J + inverseElems.assign( TStdElemIterator( Nrem->GetInverseElementIterator()), itEnd ); + for ( unsigned i = 0; i < inverseElems.size(); ++i ) + { + const SMDS_MeshElement* elem = inverseElems[i]; + vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() ); + nodes[ elem->GetType() == SMDSAbs_Volume ? PYRAM_APEX : TRIA_APEX ] = CommonNode; + GetMeshDS()->ChangeElementNodes( elem, &nodes[0], nodes.size()); + } + ASSERT( Nrem->NbInverseElements() == 0 ); + GetMeshDS()->RemoveFreeNode( Nrem, + GetMeshDS()->MeshElements( Nrem->getshapeId()), + /*fromGroups=*/false); +} + +//================================================================================ +/*! + * \brief Merges adjacent pyramids + */ +//================================================================================ + +void StdMeshers_QuadToTriaAdaptor::MergeAdjacent(const SMDS_MeshElement* PrmI, + set& nodesToMove) +{ + TIDSortedElemSet adjacentPyrams; + bool mergedPyrams = false; + for(int k=0; k<4; k++) // loop on 4 base nodes of PrmI + { + const SMDS_MeshNode* n = PrmI->GetNode(k); + SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume ); + while ( vIt->more() ) + { + const SMDS_MeshElement* PrmJ = vIt->next(); + if ( PrmJ->NbCornerNodes() != 5 || !adjacentPyrams.insert( PrmJ ).second ) + continue; + if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, GetMesh()->HasShapeToMesh() )) + { + MergePiramids( PrmI, PrmJ, nodesToMove ); + mergedPyrams = true; + // container of inverse elements can change + vIt = n->GetInverseElementIterator( SMDSAbs_Volume ); + } + } + } + if ( mergedPyrams ) + { + TIDSortedElemSet::iterator prm; + for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm) + MergeAdjacent( *prm, nodesToMove ); + } +} + +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + +StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor(): + myElemSearcher(0) +{ +} //================================================================================ /*! @@ -62,39 +373,47 @@ StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor() //================================================================================ StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor() -{} - +{ + // temporary faces are deleted by ~SMESH_ProxyMesh() + if ( myElemSearcher ) delete myElemSearcher; + myElemSearcher=0; +} //======================================================================= //function : FindBestPoint -//purpose : Auxilare for Compute() +//purpose : Return a point P laying on the line (PC,V) so that triangle +// (P, P1, P2) to be equilateral as much as possible // V - normal to (P1,P2,PC) //======================================================================= + static gp_Pnt FindBestPoint(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& PC, const gp_Vec& V) { - double a = P1.Distance(P2); - double b = P1.Distance(PC); - double c = P2.Distance(PC); + gp_Pnt Pbest = PC; + const double a = P1.Distance(P2); + const double b = P1.Distance(PC); + const double c = P2.Distance(PC); if( a < (b+c)/2 ) - return PC; - else { - // find shift along V in order to a became equal to (b+c)/2 - double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 ); - gp_Dir aDir(V); - gp_Pnt Pbest( PC.X() + aDir.X()*shift, PC.Y() + aDir.Y()*shift, - PC.Z() + aDir.Z()*shift ); return Pbest; + else { + // find shift along V in order a to became equal to (b+c)/2 + const double Vsize = V.Magnitude(); + if ( fabs( Vsize ) > std::numeric_limits::min() ) + { + const double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 ); + Pbest.ChangeCoord() += shift * V.XYZ() / Vsize; + } } + return Pbest; } - //======================================================================= //function : HasIntersection3 //purpose : Auxilare for HasIntersection() // find intersection point between triangle (P1,P2,P3) // and segment [PC,P] //======================================================================= + static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) { @@ -113,7 +432,7 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, return false; if( IAICQ.NbPoints() == 1 ) { gp_Pnt PIn = IAICQ.Point(1); - double preci = 1.e-6; + const double preci = 1.e-10 * P.Distance(PC); // check if this point is internal for segment [PC,P] bool IsExternal = ( (PC.X()-PIn.X())*(P.X()-PIn.X()) > preci ) || @@ -126,32 +445,34 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, gp_Vec V1(PIn,P1); gp_Vec V2(PIn,P2); gp_Vec V3(PIn,P3); - if( V1.Magnitude()(myElemSearcher); + + //SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); //cout<<" CheckIntersection: meshDS->NbFaces() = "<NbFaces()<MeshElements(aShapeFace); - if ( aSubMeshDSFace ) { - SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - while ( iteratorElem->more() ) { // loop on elements on a face - const SMDS_MeshElement* face = iteratorElem->next(); - Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; - SMDS_ElemIteratorPtr nodeIt = face->nodesIterator(); - if( !face->IsQuadratic() ) { - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z())); - } - } - else { - int nn = 0; - while ( nodeIt->more() ) { - nn++; - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z())); - if(nn==face->NbNodes()/2) break; - } - } - if( HasIntersection(P, PC, Pres, aContour) ) { - res = true; - double tmp = PC.Distance(Pres); - if(tmp suspectElems; + searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); + + for ( int i = 0; i < suspectElems.size(); ++i ) + { + const SMDS_MeshElement* face = suspectElems[i]; + if ( face == NotCheckedFace ) continue; + Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; + for ( int i = 0; i < face->NbCornerNodes(); ++i ) + aContour->Append( SMESH_TNodeXYZ( face->GetNode(i) )); + if( HasIntersection(P, PC, Pres, aContour) ) { + res = true; + double tmp = PC.Distance(Pres); + if(tmpnodesIterator(); - const SMDS_MeshNode* Ns1[3]; - int k = 0; - while( nIt->more() ) { - Ns1[k] = static_cast( nIt->next() ); - k++; - } - nIt = F2->nodesIterator(); - const SMDS_MeshNode* Ns2[3]; - k = 0; - while( nIt->more() ) { - Ns2[k] = static_cast( nIt->next() ); - k++; - } - if( ( Ns1[1]==Ns2[1] && Ns1[2]==Ns2[2] ) || - ( Ns1[1]==Ns2[2] && Ns1[2]==Ns2[1] ) ) - return true; - return false; -} - - -//======================================================================= -//function : IsDegenarate -//purpose : Auxilare for Preparation() -//======================================================================= -static int IsDegenarate(const Handle(TColgp_HArray1OfPnt)& PN) +int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face, + Handle(TColgp_HArray1OfPnt)& PN, + Handle(TColgp_HArray1OfVec)& VN, + vector& FNodes, + gp_Pnt& PC, + gp_Vec& VNorm, + const SMDS_MeshElement** volumes) { - int i = 1; - for(; i<4; i++) { - int j = i+1; - for(; j<=4; j++) { - if( PN->Value(i).Distance(PN->Value(j)) < 1.e-6 ) - return j; - } + if( face->NbCornerNodes() != 4 ) + { + return NOT_QUAD; } - return 0; -} - -//======================================================================= -//function : Preparation -//purpose : Auxilare for Compute() -// : Return 0 if given face is not quad, -// 1 if given face is quad, -// 2 if given face is degenerate quad (two nodes are coincided) -//======================================================================= -int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face, - Handle(TColgp_HArray1OfPnt) PN, - Handle(TColgp_HArray1OfVec) VN, - std::vector& FNodes, - gp_Pnt& PC, gp_Vec& VNorm) -{ int i = 0; - double xc=0., yc=0., zc=0.; - SMDS_ElemIteratorPtr nodeIt = face->nodesIterator(); - if( !face->IsQuadratic() ) { - if( face->NbNodes() != 4 ) - return 0; - while ( nodeIt->more() ) { - i++; - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - FNodes[i-1] = node; - PN->SetValue( i, gp_Pnt(node->X(), node->Y(), node->Z()) ); - xc += node->X(); - yc += node->Y(); - zc += node->Z(); - } - } - else { - if( face->NbNodes() != 8) - return 0; - while ( nodeIt->more() ) { - i++; - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - FNodes[i-1] = node; - PN->SetValue( i, gp_Pnt(node->X(), node->Y(), node->Z()) ); - xc += node->X(); - yc += node->Y(); - zc += node->Z(); - if(i==4) break; - } + gp_XYZ xyzC(0., 0., 0.); + for ( i = 0; i < 4; ++i ) + { + gp_XYZ p = SMESH_TNodeXYZ( FNodes[i] = face->GetNode(i) ); + PN->SetValue( i+1, p ); + xyzC += p; } + PC = xyzC/4; int nbp = 4; @@ -362,7 +627,7 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face, hasdeg = true; gp_Pnt Pdeg = PN->Value(i); - std::list< const SMDS_MeshNode* >::iterator itdg = myDegNodes.begin(); + list< const SMDS_MeshNode* >::iterator itdg = myDegNodes.begin(); const SMDS_MeshNode* DegNode = 0; for(; itdg!=myDegNodes.end(); itdg++) { const SMDS_MeshNode* N = (*itdg); @@ -385,24 +650,15 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face, FNodes[i-1] = FNodes[i]; } nbp = 3; - //PC = gp_Pnt( PN->Value(1).X() + PN.Value } - PC = gp_Pnt(xc/4., yc/4., zc/4.); - //cout<<" PC("<SetValue(5,PN->Value(1)); PN->SetValue(nbp+1,PN->Value(1)); - //FNodes[4] = FNodes[0]; FNodes[nbp] = FNodes[0]; // find normal direction - //gp_Vec V1(PC,PN->Value(4)); gp_Vec V1(PC,PN->Value(nbp)); gp_Vec V2(PC,PN->Value(1)); VNorm = V1.Crossed(V2); - //VN->SetValue(4,VNorm); VN->SetValue(nbp,VNorm); - //for(i=1; i<4; i++) { for(i=1; iValue(i)); V2 = gp_Vec(PC,PN->Value(i+1)); @@ -410,9 +666,37 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face, VN->SetValue(i,Vtmp); VNorm += Vtmp; } + + // find volumes sharing the face + if ( volumes ) + { + volumes[0] = volumes[1] = 0; + SMDS_ElemIteratorPtr vIt = FNodes[0]->GetInverseElementIterator( SMDSAbs_Volume ); + while ( vIt->more() ) + { + const SMDS_MeshElement* vol = vIt->next(); + bool volSharesAllNodes = true; + for ( int i = 1; i < face->NbNodes() && volSharesAllNodes; ++i ) + volSharesAllNodes = ( vol->GetNodeIndex( FNodes[i] ) >= 0 ); + if ( volSharesAllNodes ) + volumes[ volumes[0] ? 1 : 0 ] = vol; + // we could additionally check that vol has all FNodes in its one face using SMDS_VolumeTool + } + // define volume position relating to the face normal + if ( volumes[0] ) + { + // get volume gc + SMDS_ElemIteratorPtr nodeIt = volumes[0]->nodesIterator(); + gp_XYZ volGC(0,0,0); + volGC = accumulate( TXyzIterator(nodeIt), TXyzIterator(), volGC ) / volumes[0]->NbNodes(); + + if ( VNorm * gp_Vec( PC, volGC ) < 0 ) + swap( volumes[0], volumes[1] ); + } + } + //cout<<" VNorm("< myPyramids; + + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_MesherHelper helper(aMesh); + helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); + + if ( myElemSearcher ) delete myElemSearcher; + if ( aProxyMesh ) + myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape)); + else + myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher(); + + const SMESHDS_SubMesh * aSubMeshDSFace; + Handle(TColgp_HArray1OfPnt) PN = new TColgp_HArray1OfPnt(1,5); + Handle(TColgp_HArray1OfVec) VN = new TColgp_HArray1OfVec(1,4); + vector FNodes(5); + gp_Pnt PC; + gp_Vec VNorm; + + for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) + { const TopoDS_Shape& aShapeFace = exp.Current(); - const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements( aShapeFace ); - if ( aSubMeshDSFace ) { - bool isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS ); + if ( aProxyMesh ) + aSubMeshDSFace = aProxyMesh->GetSubMesh( aShapeFace ); + else + aSubMeshDSFace = meshDS->MeshElements( aShapeFace ); + + vector trias, quads; + bool hasNewTrias = false; + + if ( aSubMeshDSFace ) + { + bool isRev = false; + if ( helper.NbAncestors( aShapeFace, aMesh, aShape.ShapeType() ) > 1 ) + isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS ); SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - while ( iteratorElem->more() ) { // loop on elements on a face + while ( iteratorElem->more() ) // loop on elements on a geometrical face + { const SMDS_MeshElement* face = iteratorElem->next(); - //cout<GetID() = "<GetID()< FNodes(5); - gp_Pnt PC; - gp_Vec VNorm; - int stat = Preparation(face, PN, VN, FNodes, PC, VNorm); - if(stat==0) - continue; + // preparation step to get face info + int stat = Preparation(face, PN, VN, FNodes, PC, VNorm); + switch ( stat ) + { + case NOT_QUAD: - if(stat==2) { - // degenerate face - // add triangles to result map - std::list aList; - SMDS_FaceOfNodes* NewFace; - if(!isRev) - NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[1], FNodes[2] ); - else - NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[2], FNodes[1] ); - aList.push_back(NewFace); - myResMap.insert(make_pair(face,aList)); - continue; - } + trias.push_back( face ); + break; - if(!isRev) VNorm.Reverse(); - double xc = 0., yc = 0., zc = 0.; - int i = 1; - for(; i<=4; i++) { - gp_Pnt Pbest; - if(!isRev) - Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i).Reversed()); - else - Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i)); - xc += Pbest.X(); - yc += Pbest.Y(); - zc += Pbest.Z(); - } - gp_Pnt PCbest(xc/4., yc/4., zc/4.); - - // check PCbest - double height = PCbest.Distance(PC); - if(height<1.e-6) { - // create new PCbest using a bit shift along VNorm - PCbest = gp_Pnt( PC.X() + VNorm.X()*0.001, - PC.Y() + VNorm.Y()*0.001, - PC.Z() + VNorm.Z()*0.001); - } - else { - // check possible intersection with other faces - gp_Pnt Pint; - bool check = CheckIntersection(PCbest, PC, Pint, aMesh, aShape, aShapeFace); - if(check) { - //cout<<"--PC("<AddFace( FNodes[0], FNodes[1], FNodes[2] ); + else + NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] ); + storeTmpElement( NewFace ); + trias.push_back ( NewFace ); + quads.push_back( face ); + hasNewTrias = true; + break; } - else { - gp_Vec VB(PC,PCbest); - gp_Pnt PCbestTmp(PC.X()+VB.X()*3, PC.X()+VB.X()*3, PC.X()+VB.X()*3); - bool check = CheckIntersection(PCbestTmp, PC, Pint, aMesh, aShape, aShapeFace); - if(check) { - double dist = PC.Distance(Pint)/3.; - if(distValue(i), PN->Value(i+1), PC, VN->Value(i).Reversed()); + else + Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i)); + xc += Pbest.X(); + yc += Pbest.Y(); + zc += Pbest.Z(); + } + gp_Pnt PCbest(xc/4., yc/4., zc/4.); + + // check PCbest + double height = PCbest.Distance(PC); + if(height<1.e-6) { + // create new PCbest using a bit shift along VNorm + PCbest = PC.XYZ() + VNorm.XYZ() * 0.001; + } + else { + // check possible intersection with other faces + gp_Pnt Pint; + bool check = CheckIntersection(PCbest, PC, Pint, aMesh, aShape, face); + if(check) { + //cout<<"--PC("<AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); - // add triangles to result map - std::list aList; - for(i=0; i<4; i++) { - SMDS_FaceOfNodes* NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i], FNodes[i+1] ); - aList.push_back(NewFace); + // create node for PCbest + SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); + + // add triangles to result map + for(i=0; i<4; i++) + { + trias.push_back ( meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] )); + storeTmpElement( trias.back() ); + } + // create a pyramid + if ( isRev ) swap( FNodes[1], FNodes[3]); + SMDS_MeshVolume* aPyram = + helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); + myPyramids.push_back(aPyram); + + quads.push_back( face ); + hasNewTrias = true; + break; + + } // case QUAD: + + } // switch ( stat ) + } // end loop on elements on a face submesh + + bool sourceSubMeshIsProxy = false; + if ( aProxyMesh ) + { + // move proxy sub-mesh from other proxy mesh to this + sourceSubMeshIsProxy = takeProxySubMesh( aShapeFace, aProxyMesh ); + // move also tmp elements added in mesh + takeTmpElemsInMesh( aProxyMesh ); + } + if ( hasNewTrias ) + { + SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh( aShapeFace ); + prxSubMesh->ChangeElements( trias.begin(), trias.end() ); + + // delete tmp quadrangles removed from aProxyMesh + if ( sourceSubMeshIsProxy ) + { + for ( unsigned i = 0; i < quads.size(); ++i ) + removeTmpElement( quads[i] ); + + delete myElemSearcher; + myElemSearcher = + SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape)); } - myResMap.insert(make_pair(face,aList)); - // create pyramid - SMDS_MeshVolume* aPyram = - meshDS->AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); - myMapFPyram.insert(make_pair(face,aPyram)); - } // end loop on elements on a face + } } } // end for(TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) { - return Compute2ndPart(aMesh); + return Compute2ndPart(aMesh, myPyramids); } - -//======================================================================= -//function : Compute -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Computes pyramids in mesh with no shape + */ +//================================================================================ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) { - myResMap.clear(); - myMapFPyram.clear(); + SMESH_ProxyMesh::setMesh( aMesh ); + SMESH_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Triangle ); + SMESH_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Quad_Triangle ); + if ( aMesh.NbQuadrangles() < 1 ) + return false; - SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + vector myPyramids; + SMESH_MesherHelper helper(aMesh); + helper.IsQuadraticSubMesh(aMesh.GetShapeToMesh()); + helper.SetElementsOnShape( true ); - SMDS_FaceIteratorPtr itFace = meshDS->facesIterator(); + if ( !myElemSearcher ) + myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher(); + SMESH_ElementSearcher* searcher = const_cast(myElemSearcher); - while(itFace->more()) { - const SMDS_MeshElement* face = itFace->next(); + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh(); + + SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(/*idInceasingOrder=*/true); + while( fIt->more()) + { + const SMDS_MeshElement* face = fIt->next(); if ( !face ) continue; - //cout<GetID() = "<GetID()< FNodes(5); + vector FNodes(5); gp_Pnt PC; gp_Vec VNorm; - - int stat = Preparation(face, PN, VN, FNodes, PC, VNorm); - if(stat==0) + const SMDS_MeshElement* volumes[2]; + int what = Preparation(face, PN, VN, FNodes, PC, VNorm, volumes); + if ( what == NOT_QUAD ) continue; + if ( volumes[0] && volumes[1] ) + continue; // face is shared by two volumes - no space for a pyramid - if(stat==2) { + if ( what == DEGEN_QUAD ) + { // degenerate face - // add triangles to result map - std::list aList; - SMDS_FaceOfNodes* NewFace; - // check orientation + // add a triangle to the proxy mesh + SMDS_MeshFace* NewFace; - double tmp = PN->Value(1).Distance(PN->Value(2)) + - PN->Value(2).Distance(PN->Value(3)); - gp_Dir tmpDir(VNorm); - gp_Pnt Ptmp1( PC.X() + tmpDir.X()*tmp*1.e6, - PC.Y() + tmpDir.Y()*tmp*1.e6, - PC.Z() + tmpDir.Z()*tmp*1.e6 ); - gp_Pnt Ptmp2( PC.X() + tmpDir.Reversed().X()*tmp*1.e6, - PC.Y() + tmpDir.Reversed().Y()*tmp*1.e6, - PC.Z() + tmpDir.Reversed().Z()*tmp*1.e6 ); + // check orientation + double tmp = PN->Value(1).Distance(PN->Value(2)) + PN->Value(2).Distance(PN->Value(3)); + // far points in VNorm direction + gp_Pnt Ptmp1 = PC.XYZ() + VNorm.XYZ() * tmp * 1.e6; + gp_Pnt Ptmp2 = PC.XYZ() - VNorm.XYZ() * tmp * 1.e6; // check intersection for Ptmp1 and Ptmp2 bool IsRev = false; bool IsOK1 = false; @@ -586,29 +946,19 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) double dist1 = RealLast(); double dist2 = RealLast(); gp_Pnt Pres1,Pres2; - SMDS_FaceIteratorPtr itf = meshDS->facesIterator(); - while(itf->more()) { - const SMDS_MeshElement* F = itf->next(); + + gp_Ax1 line( PC, VNorm ); + vector< const SMDS_MeshElement* > suspectElems; + searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); + + for ( int iF = 0; iF < suspectElems.size(); ++iF ) { + const SMDS_MeshElement* F = suspectElems[iF]; if(F==face) continue; Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; - SMDS_ElemIteratorPtr nodeIt = F->nodesIterator(); - if( !F->IsQuadratic() ) { - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z())); - } - } - else { - int nn = 0; - while ( nodeIt->more() ) { - nn++; - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z())); - if(nn==face->NbNodes()/2) break; - } - } + for ( int i = 0; i < 4; ++i ) + aContour->Append( SMESH_TNodeXYZ( F->GetNode(i) )); gp_Pnt PPP; - if( HasIntersection(Ptmp1, PC, PPP, aContour) ) { + if( !volumes[0] && HasIntersection(Ptmp1, PC, PPP, aContour) ) { IsOK1 = true; double tmp = PC.Distance(PPP); if(tmpAddFace( FNodes[0], FNodes[1], FNodes[2] ); else - NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[2], FNodes[1] ); - aList.push_back(NewFace); - myResMap.insert(make_pair(face,aList)); + NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] ); + storeTmpElement( NewFace ); + prxSubMesh->AddElement( NewFace ); continue; } - - double xc = 0., yc = 0., zc = 0.; + + // Case of non-degenerated quadrangle + + // Find pyramid peak + + gp_XYZ PCbest(0., 0., 0.); // pyramid peak int i = 1; for(; i<=4; i++) { gp_Pnt Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i)); - xc += Pbest.X(); - yc += Pbest.Y(); - zc += Pbest.Z(); + PCbest += Pbest.XYZ(); } - gp_Pnt PCbest(xc/4., yc/4., zc/4.); - double height = PCbest.Distance(PC); - if(height<1.e-6) { + PCbest /= 4; + + double height = PC.Distance(PCbest); // pyramid height to precise + if ( height < 1.e-6 ) { // create new PCbest using a bit shift along VNorm - PCbest = gp_Pnt( PC.X() + VNorm.X()*0.001, - PC.Y() + VNorm.Y()*0.001, - PC.Z() + VNorm.Z()*0.001); - height = PCbest.Distance(PC); + PCbest = PC.XYZ() + VNorm.XYZ() * 0.001; + height = PC.Distance(PCbest); + if ( height < std::numeric_limits::min() ) + return false; // batterfly element } - //cout<<" PCbest("<Value(1).Distance(PN->Value(3)) + - PN->Value(2).Distance(PN->Value(4)); - gp_Dir tmpDir(V1); - gp_Pnt Ptmp1( PC.X() + tmpDir.X()*tmp*1.e6, - PC.Y() + tmpDir.Y()*tmp*1.e6, - PC.Z() + tmpDir.Z()*tmp*1.e6 ); - gp_Pnt Ptmp2( PC.X() + tmpDir.Reversed().X()*tmp*1.e6, - PC.Y() + tmpDir.Reversed().Y()*tmp*1.e6, - PC.Z() + tmpDir.Reversed().Z()*tmp*1.e6 ); - // check intersection for Ptmp1 and Ptmp2 - bool IsRev = false; - bool IsOK1 = false; - bool IsOK2 = false; - double dist1 = RealLast(); - double dist2 = RealLast(); - gp_Pnt Pres1,Pres2; - SMDS_FaceIteratorPtr itf = meshDS->facesIterator(); - while(itf->more()) { - const SMDS_MeshElement* F = itf->next(); + + // Restrict pyramid height by intersection with other faces + gp_Vec tmpDir(PC,PCbest); tmpDir.Normalize(); + double tmp = PN->Value(1).Distance(PN->Value(3)) + PN->Value(2).Distance(PN->Value(4)); + // far points: in (PC, PCbest) direction and vice-versa + gp_Pnt farPnt[2] = { PC.XYZ() + tmpDir.XYZ() * tmp * 1.e6, + PC.XYZ() - tmpDir.XYZ() * tmp * 1.e6 }; + // check intersection for farPnt1 and farPnt2 + bool intersected[2] = { false, false }; + double dist [2] = { RealLast(), RealLast() }; + gp_Pnt intPnt[2]; + + gp_Ax1 line( PC, tmpDir ); + vector< const SMDS_MeshElement* > suspectElems; + searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); + + for ( int iF = 0; iF < suspectElems.size(); ++iF ) + { + const SMDS_MeshElement* F = suspectElems[iF]; if(F==face) continue; Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; - SMDS_ElemIteratorPtr nodeIt = F->nodesIterator(); - if( !F->IsQuadratic() ) { - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z())); - } - } - else { - int nn = 0; - while ( nodeIt->more() ) { - nn++; - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z())); - if(nn==face->NbNodes()/2) break; - } - } - gp_Pnt PPP; - if( HasIntersection(Ptmp1, PC, PPP, aContour) ) { - IsOK1 = true; - double tmp = PC.Distance(PPP); - if(tmpNbNodes() / ( F->IsQuadratic() ? 2 : 1 ); + for ( i = 0; i < nbN; ++i ) + aContour->Append( SMESH_TNodeXYZ( F->GetNode(i) )); + gp_Pnt intP; + for ( int isRev = 0; isRev < 2; ++isRev ) + { + if( !volumes[isRev] && HasIntersection(farPnt[isRev], PC, intP, aContour) ) { + intersected[isRev] = true; + double d = PC.Distance( intP ); + if( d < dist[isRev] ) + { + intPnt[isRev] = intP; + dist [isRev] = d; + } } } } - if( IsOK1 && !IsOK2 ) { - // using existed direction - double tmp = PC.Distance(Pres1)/3.; - if( height > tmp ) { - height = tmp; - PCbest = gp_Pnt( PC.X() + tmpDir.X()*height, - PC.Y() + tmpDir.Y()*height, - PC.Z() + tmpDir.Z()*height ); - } - } - else if( !IsOK1 && IsOK2 ) { - // using opposite direction - IsRev = true; - double tmp = PC.Distance(Pres2)/3.; - if( height > tmp ) height = tmp; - PCbest = gp_Pnt( PC.X() + tmpDir.Reversed().X()*height, - PC.Y() + tmpDir.Reversed().Y()*height, - PC.Z() + tmpDir.Reversed().Z()*height ); - } - else { // IsOK1 && IsOK2 - double tmp1 = PC.Distance(Pres1)/3.; - double tmp2 = PC.Distance(Pres2)/3.; - if(tmp1 tmp1 ) { - height = tmp1; - PCbest = gp_Pnt( PC.X() + tmpDir.X()*height, - PC.Y() + tmpDir.Y()*height, - PC.Z() + tmpDir.Z()*height ); - } - } - else { - // using opposite direction - IsRev = true; - if( height > tmp2 ) height = tmp2; - PCbest = gp_Pnt( PC.X() + tmpDir.Reversed().X()*height, - PC.Y() + tmpDir.Reversed().Y()*height, - PC.Z() + tmpDir.Reversed().Z()*height ); - } - } + // Create one or two pyramids + + for ( int isRev = 0; isRev < 2; ++isRev ) + { + if( !intersected[isRev] ) continue; + double pyramidH = Min( height, PC.Distance(intPnt[isRev])/3.); + PCbest = PC.XYZ() + tmpDir.XYZ() * (isRev ? -pyramidH : pyramidH); - // create node for PCbest - SMDS_MeshNode* NewNode = meshDS->AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); - // add triangles to result map - std::list aList; - for(i=0; i<4; i++) { - SMDS_FaceOfNodes* NewFace; - if(IsRev) - NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i], FNodes[i+1] ); + // create node for PCbest + SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); + + // add triangles to result map + for(i=0; i<4; i++) { + SMDS_MeshFace* NewFace; + if(isRev) + NewFace = meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] ); + else + NewFace = meshDS->AddFace( NewNode, FNodes[i+1], FNodes[i] ); + storeTmpElement( NewFace ); + prxSubMesh->AddElement( NewFace ); + } + // create a pyramid + SMDS_MeshVolume* aPyram; + if(isRev) + aPyram = helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); else - NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i+1], FNodes[i] ); - aList.push_back(NewFace); + aPyram = helper.AddVolume( FNodes[0], FNodes[3], FNodes[2], FNodes[1], NewNode ); + myPyramids.push_back(aPyram); } - myResMap.insert(make_pair(face,aList)); - // create pyramid - SMDS_MeshVolume* aPyram; - if(IsRev) - aPyram = meshDS->AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); - else - aPyram = meshDS->AddVolume( FNodes[0], FNodes[3], FNodes[2], FNodes[1], NewNode ); - myMapFPyram.insert(make_pair(face,aPyram)); - } // end loop on elements on a face + } // end loop on all faces - return Compute2ndPart(aMesh); + return Compute2ndPart(aMesh, myPyramids); } +//================================================================================ +/*! + * \brief Update created pyramids and faces to avoid their intersection + */ +//================================================================================ -//======================================================================= -//function : Compute2ndPart -//purpose : -//======================================================================= - -bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) +bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh, + const vector& myPyramids) { + if(myPyramids.empty()) + return true; + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId(); - // check intersections between created pyramids - int NbPyram = myMapFPyram.size(); - //cout<<"NbPyram = "<(myElemSearcher); - std::vector< const SMDS_MeshElement* > Pyrams(NbPyram); - std::vector< const SMDS_MeshElement* > Faces(NbPyram); - std::map< const SMDS_MeshElement*, - const SMDS_MeshElement* >::iterator itp = myMapFPyram.begin(); - int i = 0; - for(; itp!=myMapFPyram.end(); itp++, i++) { - Faces[i] = (*itp).first; - Pyrams[i] = (*itp).second; - } - StdMeshers_Array1OfSequenceOfInteger MergesInfo(0,NbPyram-1); - for(i=0; i nodesToMove; + + // check adjacent pyramids + + for ( i = 0; i < myPyramids.size(); ++i ) + { + const SMDS_MeshElement* PrmI = myPyramids[i]; + MergeAdjacent( PrmI, nodesToMove ); } - for(i=0; inodesIterator(); - std::vector Ps1(5); - const SMDS_MeshNode* Ns1[5]; - int k = 0; - while( nIt->more() ) { - const SMDS_MeshNode* node = static_cast( nIt->next() ); - Ns1[k] = node; - Ps1[k] = gp_Pnt(node->X(), node->Y(), node->Z()); - k++; - } - bool NeedMove = false; - for(int j=i+1; jChangeElementNodes(Prm2, Ns2, 5); - // update pyramids for J - for(k=2; k<=nbJ; k++) { - const SMDS_MeshElement* tmpPrm = Pyrams[aMergesJ.Value(k)]; - SMDS_ElemIteratorPtr tmpIt = tmpPrm->nodesIterator(); - const SMDS_MeshNode* Ns[5]; - int m = 0; - while( tmpIt->more() ) { - Ns[m] = static_cast( tmpIt->next() ); - m++; - } - Ns[4] = CommonNode; - meshDS->ChangeElementNodes(tmpPrm, Ns, 5); - } + if ( hasInt ) + { + // count common nodes of base faces of two pyramids + int nbc = 0; + for (k=0; k<4; k++) + nbc += int ( PrmI->GetNodeIndex( PrmJ->GetNode(k) ) >= 0 ); - // update MergesInfo - for(k=1; k<=nbI; k++) { - int num = aMergesI.Value(k); - const TColStd_SequenceOfInteger& aSeq = MergesInfo.Value(num); - TColStd_SequenceOfInteger tmpSeq; - int m = 1; - for(; m<=aSeq.Length(); m++) { - tmpSeq.Append(aSeq.Value(m)); - } - for(m=1; m<=nbJ; m++) { - tmpSeq.Append(aMergesJ.Value(m)); - } - MergesInfo.SetValue(num,tmpSeq); - } - for(k=1; k<=nbJ; k++) { - int num = aMergesJ.Value(k); - const TColStd_SequenceOfInteger& aSeq = MergesInfo.Value(num); - TColStd_SequenceOfInteger tmpSeq; - int m = 1; - for(; m<=aSeq.Length(); m++) { - tmpSeq.Append(aSeq.Value(m)); - } - for(m=1; m<=nbI; m++) { - tmpSeq.Append(aMergesI.Value(m)); - } - MergesInfo.SetValue(num,tmpSeq); - } + if ( nbc == 4 ) + continue; // pyrams have a common base face - // update triangles for aMergesJ - for(k=1; k<=nbJ; k++) { - std::list< std::list< const SMDS_MeshNode* > > aFNodes; - std::list< const SMDS_MeshElement* > aFFaces; - int num = aMergesJ.Value(k); - std::map< const SMDS_MeshElement*, - std::list >::iterator itrm = myResMap.find(Faces[num]); - std::list trias = (*itrm).second; - std::list::iterator itt = trias.begin(); - for(; itt!=trias.end(); itt++) { - int nn = -1; - SMDS_ElemIteratorPtr nodeIt = (*itt)->nodesIterator(); - const SMDS_MeshNode* NF[3]; - while ( nodeIt->more() ) { - nn++; - NF[nn] = static_cast( nodeIt->next() ); - } - NF[0] = CommonNode; - SMDS_FaceOfNodes* Ftria = const_cast< SMDS_FaceOfNodes*>( (*itt) ); - Ftria->ChangeNodes(NF, 3); - } + if(nbc>0) + { + // Merge the two pyramids and others already merged with them + MergePiramids( PrmI, PrmJ, nodesToMove ); } + else { // nbc==0 - // check and remove coincided faces - TColStd_SequenceOfInteger IdRemovedTrias; - int i1 = 1; - for(; i1<=nbI; i1++) { - int numI = aMergesI.Value(i1); - std::map< const SMDS_MeshElement*, - std::list >::iterator itrmI = myResMap.find(Faces[numI]); - std::list triasI = (*itrmI).second; - std::list::iterator ittI = triasI.begin(); - int nbfI = triasI.size(); - std::vector FsI(nbfI); - k = 0; - for(; ittI!=triasI.end(); ittI++) { - FsI[k] = (*ittI); - k++; + // decrease height of pyramids + gp_XYZ PCi(0,0,0), PCj(0,0,0); + for(k=0; k<4; k++) { + PCi += PsI[k].XYZ(); + PCj += PsJ[k].XYZ(); } - int i2 = 0; - for(; i2 >::iterator itrmJ = myResMap.find(Faces[numJ]); - std::list triasJ = (*itrmJ).second; - std::list::iterator ittJ = triasJ.begin(); - int nbfJ = triasJ.size(); - std::vector FsJ(nbfJ); - k = 0; - for(; ittJ!=triasJ.end(); ittJ++) { - FsJ[k] = (*ittJ); - k++; - } - int j2 = 0; - for(; j2GetID() ); - IdRemovedTrias.Append( FJ->GetID() ); - FsI[i2] = 0; - FsJ[j2] = 0; - std::list new_triasI; - for(k=0; k new_triasJ; - for(k=0; kRemoveNode(Nrem); - } - else { // nbc==0 - //cout<<"decrease height of pyramids"<(PrmI->GetNode(4)); + aNode1->setXYZ( PCi.X()+VN1.X(), PCi.Y()+VN1.Y(), PCi.Z()+VN1.Z() ); + SMDS_MeshNode* aNode2 = const_cast(PrmJ->GetNode(4)); + aNode2->setXYZ( PCj.X()+VN2.X(), PCj.Y()+VN2.Y(), PCj.Z()+VN2.Z() ); + nodesToMove.insert( aNode1 ); + nodesToMove.insert( aNode2 ); } - gp_Pnt PC1(xc1/4.,yc1/4.,zc1/4.); - gp_Pnt PC2(xc2/4.,yc2/4.,zc2/4.); - gp_Vec VN1(PC1,Ps1[4]); - gp_Vec VI1(PC1,Pint); - gp_Vec VN2(PC2,Ps2[4]); - gp_Vec VI2(PC2,Pint); - double ang1 = fabs(VN1.Angle(VI1)); - double ang2 = fabs(VN2.Angle(VI2)); - double h1,h2; - if(ang1>PI/3.) - h1 = VI1.Magnitude()/2; - else - h1 = VI1.Magnitude()*cos(ang1); - if(ang2>PI/3.) - h2 = VI2.Magnitude()/2; + // fix intersections that could appear after apex movement + MergeAdjacent( PrmI, nodesToMove ); + MergeAdjacent( PrmJ, nodesToMove ); + + } // end if(hasInt) + } // loop on suspectPyrams + } // loop on 4 base nodes of PrmI + + } // loop on all pyramids + + if( !nodesToMove.empty() && !meshDS->IsEmbeddedMode() ) + { + set::iterator n = nodesToMove.begin(); + for ( ; n != nodesToMove.end(); ++n ) + meshDS->MoveNode( *n, (*n)->X(), (*n)->Y(), (*n)->Z() ); + } + + // move medium nodes of merged quadratic pyramids + if ( myPyramids[0]->IsQuadratic() ) + UpdateQuadraticPyramids( nodesToMove, GetMeshDS() ); + + // erase removed triangles from the proxy mesh + if ( !myRemovedTrias.empty() ) + { + for ( int i = 0; i <= meshDS->MaxShapeIndex(); ++i ) + if ( SMESH_ProxyMesh::SubMesh* sm = findProxySubMesh(i)) + { + vector faces; + faces.reserve( sm->NbElements() ); + SMDS_ElemIteratorPtr fIt = sm->GetElements(); + while ( fIt->more() ) + { + const SMDS_MeshElement* tria = fIt->next(); + set::iterator rmTria = myRemovedTrias.find( tria ); + if ( rmTria != myRemovedTrias.end() ) + myRemovedTrias.erase( rmTria ); else - h2 = VI2.Magnitude()*cos(ang2); - double coef1 = 0.5; - if(ang1(Ns1[4]); - VN1.Scale(coef1); - aNode1->setXYZ( PC1.X()+VN1.X(), PC1.Y()+VN1.Y(), PC1.Z()+VN1.Z() ); - SMDS_MeshNode* aNode2 = const_cast(Ns2[4]); - VN2.Scale(coef2); - aNode2->setXYZ( PC2.X()+VN2.X(), PC2.Y()+VN2.Y(), PC2.Z()+VN2.Z() ); - NeedMove = true; + faces.push_back( tria ); } - } // end if(hasInt) - else { - //cout<<" no intersec for i="< + +#include #include #include -class STDMESHERS_EXPORT StdMeshers_QuadToTriaAdaptor +#include + +/*! + * \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids + */ +class STDMESHERS_EXPORT StdMeshers_QuadToTriaAdaptor : public SMESH_ProxyMesh { public: - StdMeshers_QuadToTriaAdaptor(); ~StdMeshers_QuadToTriaAdaptor(); - bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_ProxyMesh* aProxyMesh=0); bool Compute(SMESH_Mesh& aMesh); - std::list GetTriangles(const SMDS_MeshElement* aFace); + const TopoDS_Shape& GetShape() const { return myShape; } protected: - //bool CheckDegenerate(const SMDS_MeshElement* aFace); - int Preparation(const SMDS_MeshElement* face, - Handle(TColgp_HArray1OfPnt) PN, - Handle(TColgp_HArray1OfVec) VN, + Handle_TColgp_HArray1OfPnt& PN, + Handle_TColgp_HArray1OfVec& VN, std::vector& FNodes, - gp_Pnt& PC, gp_Vec& VNorm); + gp_Pnt& PC, gp_Vec& VNorm, + const SMDS_MeshElement** volumes=0); bool CheckIntersection(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - const TopoDS_Shape& NotCheckedFace); + const SMDS_MeshElement* NotCheckedFace); - bool Compute2ndPart(SMESH_Mesh& aMesh); + bool Compute2ndPart(SMESH_Mesh& aMesh, + const std::vector& pyramids); - std::map< const SMDS_MeshElement*, std::list > myResMap; - std::map< const SMDS_MeshElement*, const SMDS_MeshElement* > myMapFPyram; - std::list< const SMDS_MeshNode* > myDegNodes; + void MergePiramids( const SMDS_MeshElement* PrmI, + const SMDS_MeshElement* PrmJ, + std::set & nodesToMove); + + void MergeAdjacent(const SMDS_MeshElement* PrmI, + std::set& nodesToMove); + + + TopoDS_Shape myShape; + std::set myRemovedTrias; + std::list< const SMDS_MeshNode* > myDegNodes; + const SMESH_ElementSearcher* myElemSearcher; }; #endif diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.cxx b/src/StdMeshers/StdMeshers_QuadrangleParams.cxx new file mode 100644 index 000000000..13a7f48ff --- /dev/null +++ b/src/StdMeshers/StdMeshers_QuadrangleParams.cxx @@ -0,0 +1,175 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_QuadrangleParams.cxx +// Author : Sergey KUUL, OCC +// Module : SMESH + +#include "StdMeshers_QuadrangleParams.hxx" + +#include "SMESH_Algo.hxx" +#include "SMESH_Mesh.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +//============================================================================= +/*! + * + */ +//============================================================================= +StdMeshers_QuadrangleParams::StdMeshers_QuadrangleParams(int hypId, int studyId, + SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, studyId, gen) +{ + _name = "QuadrangleParams"; + _param_algo_dim = 2; + _triaVertexID = -1; + _quadType = QUAD_STANDARD; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +StdMeshers_QuadrangleParams::~StdMeshers_QuadrangleParams() +{ +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void StdMeshers_QuadrangleParams::SetTriaVertex (int id) +{ + if (id != _triaVertexID) { + _triaVertexID = id; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void StdMeshers_QuadrangleParams::SetQuadType (StdMeshers_QuadType type) +{ + if (type != _quadType) { + _quadType = type; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= +ostream & StdMeshers_QuadrangleParams::SaveTo(ostream & save) +{ + if (_objEntry.size() == 0) + save << _triaVertexID << " UNDEFINED " << int(_quadType); + else + save << _triaVertexID << " " << _objEntry << " " << int(_quadType); + return save; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +istream & StdMeshers_QuadrangleParams::LoadFrom(istream & load) +{ + bool isOK = true; + isOK = (load >> _triaVertexID); + if (!isOK) + load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> _objEntry); + if (!isOK) + load.clear(ios::badbit | load.rdstate()); + + int type; + isOK = (load >> type); + if (isOK) + _quadType = StdMeshers_QuadType(type); + + return load; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +ostream & operator <<(ostream & save, StdMeshers_QuadrangleParams & hyp) +{ + return hyp.SaveTo( save ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +istream & operator >>(istream & load, StdMeshers_QuadrangleParams & hyp) +{ + return hyp.LoadFrom( load ); +} + +//================================================================================ +/*! + * \brief Redifined method + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ +bool StdMeshers_QuadrangleParams::SetParametersByMesh(const SMESH_Mesh* theMesh, + const TopoDS_Shape& theShape) +{ + if ( !theMesh || theShape.IsNull() ) + return false; + + return true; +} + +//================================================================================ +/*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ +bool StdMeshers_QuadrangleParams::SetParametersByDefaults(const TDefaults& dflts, + const SMESH_Mesh* /*mesh*/) +{ + return true; +} diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.hxx b/src/StdMeshers/StdMeshers_QuadrangleParams.hxx new file mode 100644 index 000000000..6bf9c2a22 --- /dev/null +++ b/src/StdMeshers/StdMeshers_QuadrangleParams.hxx @@ -0,0 +1,86 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_QuadrangleParams.hxx +// Author : Sergey KUUL, OCC +// Module : SMESH + +#ifndef _SMESH_QUADRANGLEPARAMS_HXX_ +#define _SMESH_QUADRANGLEPARAMS_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +enum StdMeshers_QuadType + { + QUAD_STANDARD, + QUAD_TRIANGLE_PREF, + QUAD_QUADRANGLE_PREF, + QUAD_QUADRANGLE_PREF_REVERSED, + QUAD_REDUCED, + QUAD_NB_TYPES + }; + +class STDMESHERS_EXPORT StdMeshers_QuadrangleParams: + public SMESH_Hypothesis +{ +public: + StdMeshers_QuadrangleParams(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_QuadrangleParams(); + + void SetTriaVertex (int id); + int GetTriaVertex() const { return _triaVertexID; } + + void SetObjectEntry (const char* entry) { _objEntry = entry; } + const char* GetObjectEntry() { return _objEntry.c_str(); } + + void SetQuadType (StdMeshers_QuadType type); + StdMeshers_QuadType GetQuadType() const { return _quadType; } + + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + friend std::ostream& operator << (std::ostream & save, + StdMeshers_QuadrangleParams & hyp); + friend std::istream& operator >> (std::istream & load, + StdMeshers_QuadrangleParams & hyp); + + /*! + * \brief Initialize start and end 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); + + /*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ + virtual bool SetParametersByDefaults(const TDefaults& dflts, + const SMESH_Mesh* theMesh=0); + +protected: + int _triaVertexID; + std::string _objEntry; + StdMeshers_QuadType _quadType; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_QuadranglePreference.cxx b/src/StdMeshers/StdMeshers_QuadranglePreference.cxx index cf3986e38..8ecb551a5 100644 --- a/src/StdMeshers/StdMeshers_QuadranglePreference.cxx +++ b/src/StdMeshers/StdMeshers_QuadranglePreference.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers_QuadranglePreference : implementaion of SMESH idl descriptions // File : StdMeshers_QuadranglePreference.cxx // Module : SMESH - +// #include "StdMeshers_QuadranglePreference.hxx" #include "utilities.h" @@ -40,7 +41,7 @@ StdMeshers_QuadranglePreference::StdMeshers_QuadranglePreference(int hyp :SMESH_Hypothesis(hypId, studyId, gen) { _name = "QuadranglePreference"; - _param_algo_dim = -2; // auxiliary used by StdMeshers_Quadrangle_2D + _param_algo_dim = -2; // auxiliary used by NETGEN 2D } //============================================================================= @@ -75,27 +76,6 @@ istream & StdMeshers_QuadranglePreference::LoadFrom(istream & load) return load; } -//============================================================================= -/*! - * - */ -//============================================================================= - -ostream & operator <<(ostream & save, StdMeshers_QuadranglePreference & hyp) -{ - return hyp.SaveTo( save ); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -istream & operator >>(istream & load, StdMeshers_QuadranglePreference & hyp) -{ - return hyp.LoadFrom( load ); -} //================================================================================ /*! * \brief Initialize my parameter values by the mesh built on the geometry diff --git a/src/StdMeshers/StdMeshers_QuadranglePreference.hxx b/src/StdMeshers/StdMeshers_QuadranglePreference.hxx index ec641d15a..184072509 100644 --- a/src/StdMeshers/StdMeshers_QuadranglePreference.hxx +++ b/src/StdMeshers/StdMeshers_QuadranglePreference.hxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of SMESH idl descriptions // File : StdMeshers_QuadranglePreference.hxx // Module : SMESH - +// #ifndef _StdMeshers_QuadranglePreference_HXX_ #define _StdMeshers_QuadranglePreference_HXX_ @@ -45,8 +46,6 @@ class STDMESHERS_EXPORT StdMeshers_QuadranglePreference:public SMESH_Hypothesis virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); - friend std::ostream & operator <<(std::ostream & save, StdMeshers_QuadranglePreference & hyp); - friend std::istream & operator >>(std::istream & load, StdMeshers_QuadranglePreference & hyp); /*! * \brief Initialize my parameter values by the mesh built on the geometry diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 3a137b109..3842b4733 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -1,35 +1,35 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : StdMeshers_Quadrangle_2D.cxx -// Moved here from SMESH_Quadrangle_2D.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ -// + #include "StdMeshers_Quadrangle_2D.hxx" #include "StdMeshers_FaceSide.hxx" +#include "StdMeshers_QuadrangleParams.hxx" + #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" @@ -42,15 +42,17 @@ #include "SMDS_EdgePosition.hxx" #include "SMDS_FacePosition.hxx" -#include -#include #include #include #include #include #include +#include #include #include +#include +#include +#include #include #include "utilities.h" @@ -75,15 +77,17 @@ typedef SMESH_Comment TComm; */ //============================================================================= -StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMESH_Gen* gen) +StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, + SMESH_Gen* gen) : SMESH_2D_Algo(hypId, studyId, gen) { MESSAGE("StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D"); _name = "Quadrangle_2D"; _shapeType = (1 << TopAbs_FACE); + _compatibleHypothesis.push_back("QuadrangleParams"); _compatibleHypothesis.push_back("QuadranglePreference"); _compatibleHypothesis.push_back("TrianglePreference"); - myTool = 0; + myHelper = 0; } //============================================================================= @@ -111,25 +115,75 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis bool isOk = true; aStatus = SMESH_Hypothesis::HYP_OK; - - const list &hyps = GetUsedHypothesis(aMesh, aShape, false); - const SMESHDS_Hypothesis *theHyp = 0; - - if(hyps.size() > 0){ - theHyp = *hyps.begin(); - if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) { - myQuadranglePreference= true; - myTrianglePreference= false; + const list & hyps = + GetUsedHypothesis(aMesh, aShape, false); + const SMESHDS_Hypothesis * aHyp = 0; + + myTriaVertexID = -1; + myQuadType = QUAD_STANDARD; + myQuadranglePreference = false; + myTrianglePreference = false; + + bool isFirstParams = true; + + // First assigned hypothesis (if any) is processed now + if (hyps.size() > 0) { + aHyp = hyps.front(); + if (strcmp("QuadrangleParams", aHyp->GetName()) == 0) { + const StdMeshers_QuadrangleParams* aHyp1 = + (const StdMeshers_QuadrangleParams*)aHyp; + myTriaVertexID = aHyp1->GetTriaVertex(); + myQuadType = aHyp1->GetQuadType(); + if (myQuadType == QUAD_QUADRANGLE_PREF || + myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + myQuadranglePreference = true; + else if (myQuadType == QUAD_TRIANGLE_PREF) + myTrianglePreference = true; + } + else if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) { + isFirstParams = false; + myQuadranglePreference = true; + } + else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ + isFirstParams = false; + myTrianglePreference = true; } - else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){ - myQuadranglePreference= false; - myTrianglePreference= true; + else { + isFirstParams = false; } } - else { - myQuadranglePreference = false; - myTrianglePreference = false; + + // Second(last) assigned hypothesis (if any) is processed now + if (hyps.size() > 1) { + aHyp = hyps.back(); + if (isFirstParams) { + if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) { + myQuadranglePreference = true; + myTrianglePreference = false; + myQuadType = QUAD_STANDARD; + } + else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ + myQuadranglePreference = false; + myTrianglePreference = true; + myQuadType = QUAD_STANDARD; + } + } + else { + const StdMeshers_QuadrangleParams* aHyp2 = + (const StdMeshers_QuadrangleParams*)aHyp; + myTriaVertexID = aHyp2->GetTriaVertex(); + + if (!myQuadranglePreference && !myTrianglePreference) { // priority of hypos + myQuadType = aHyp2->GetQuadType(); + if (myQuadType == QUAD_QUADRANGLE_PREF || + myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + myQuadranglePreference = true; + else if (myQuadType == QUAD_TRIANGLE_PREF) + myTrianglePreference = true; + } + } } + return isOk; } @@ -148,17 +202,18 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); aMesh.GetSubMesh(aShape); - SMESH_MesherHelper helper(aMesh); - myTool = &helper; + SMESH_MesherHelper helper (aMesh); + myHelper = &helper; - _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); + _quadraticMesh = myHelper->IsQuadraticSubMesh(aShape); + myNeedSmooth = false; - FaceQuadStruct *quad = CheckNbEdges( aMesh, aShape ); - std::auto_ptr quadDeleter( quad ); // to delete quad at exit from Compute() + FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); + std::auto_ptr quadDeleter (quad); // to delete quad at exit from Compute() if (!quad) return false; - if(myQuadranglePreference) { + if (myQuadranglePreference) { int n1 = quad->side[0]->NbPoints(); int n2 = quad->side[1]->NbPoints(); int n3 = quad->side[2]->NbPoints(); @@ -166,9 +221,28 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, int nfull = n1+n2+n3+n4; int ntmp = nfull/2; ntmp = ntmp*2; - if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) { + if (nfull == ntmp && ((n1 != n3) || (n2 != n4))) { // special path for using only quandrangle faces bool ok = ComputeQuadPref(aMesh, aShape, quad); + if ( ok && myNeedSmooth ) + Smooth( quad ); + return ok; + } + } + else if (myQuadType == QUAD_REDUCED) { + int n1 = quad->side[0]->NbPoints(); + int n2 = quad->side[1]->NbPoints(); + int n3 = quad->side[2]->NbPoints(); + int n4 = quad->side[3]->NbPoints(); + int n13 = n1 - n3; + int n24 = n2 - n4; + int n13tmp = n13/2; n13tmp = n13tmp*2; + int n24tmp = n24/2; n24tmp = n24tmp*2; + if ((n1 == n3 && n2 != n4 && n24tmp == n24) || + (n2 == n4 && n1 != n3 && n13tmp == n13)) { + bool ok = ComputeReduced(aMesh, aShape, quad); + if ( ok && myNeedSmooth ) + Smooth( quad ); return ok; } } @@ -193,7 +267,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, Handle(Geom_Surface) S = BRep_Tool::Surface(F); // internal mesh nodes - int i, j, geomFaceID = meshDS->ShapeToIndex( F ); + int i, j, geomFaceID = meshDS->ShapeToIndex(F); for (i = 1; i < nbhoriz - 1; i++) { for (j = 1; j < nbvertic - 1; j++) { int ij = j * nbhoriz + i; @@ -237,18 +311,20 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, b = quad->uv_grid[j * nbhoriz + i + 1].node; c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node; d = quad->uv_grid[(j + 1) * nbhoriz + i].node; - SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); + if (face) { + meshDS->SetMeshElementOnShape(face, geomFaceID); + } } } - const vector& uv_e0 = quad->side[0]->GetUVPtStruct(true,0 ); + const vector& uv_e0 = quad->side[0]->GetUVPtStruct(true,0); const vector& uv_e1 = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 ); + const vector& uv_e2 = quad->side[2]->GetUVPtStruct(true,1); const vector& uv_e3 = quad->side[3]->GetUVPtStruct(false,0); - if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) - return error( COMPERR_BAD_INPUT_MESH ); + if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty()) + return error(COMPERR_BAD_INPUT_MESH); double eps = Precision::Confusion(); @@ -312,9 +388,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); - SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, b, c); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near - 1 < ilow) @@ -323,9 +398,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = quad->uv_grid[nbhoriz + near - 1].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ - SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if (!myTrianglePreference){ + SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -339,9 +414,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e3[1].node; else d = quad->uv_grid[nbhoriz + k - 1].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); - SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -402,9 +476,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); - SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, b, c); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near + 1 > iup) @@ -412,9 +485,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ - SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if (!myTrianglePreference){ + SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -427,9 +500,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e1[nbright - 2].node; else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); - SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -476,9 +548,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); - SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, b, c); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near - 1 < jlow) @@ -487,9 +558,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = quad->uv_grid[nbhoriz*near - 2].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ - SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if (!myTrianglePreference){ + SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -502,9 +573,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e0[nbdown - 2].node; else d = quad->uv_grid[nbhoriz*k - 2].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); - SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -548,9 +618,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } if (near == g) { // make triangle - //SMDS_MeshFace* face = meshDS->AddFace(a, b, c); - SMDS_MeshFace* face = myTool->AddFace(a, b, c); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, b, c); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near + 1 > jup) @@ -558,9 +627,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*(near + 1) + 1].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ - SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + if (!myTrianglePreference){ + SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -573,9 +642,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = uv_e2[1].node; else d = quad->uv_grid[nbhoriz*(k + 1) + 1].node; - //SMDS_MeshFace* face = meshDS->AddFace(a, c, d); - SMDS_MeshFace* face = myTool->AddFace(a, c, d); - meshDS->SetMeshElementOnShape(face, geomFaceID); + SMDS_MeshFace* face = myHelper->AddFace(a, c, d); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -584,10 +652,129 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, } } + if ( myNeedSmooth ) + Smooth( quad ); + bool isOk = true; return isOk; } + +//============================================================================= +/*! + * Evaluate + */ +//============================================================================= + +bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) + +{ + aMesh.GetSubMesh(aShape); + + std::vector aNbNodes(4); + bool IsQuadratic = false; + if (!CheckNbEdgesForEvaluate(aMesh, aShape, aResMap, aNbNodes, IsQuadratic)) { + std::vector aResVec(SMDSEntity_Last); + for (int i=SMDSEntity_Node; iGetComputeError(); + smError.reset(new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + + if (myQuadranglePreference) { + int n1 = aNbNodes[0]; + int n2 = aNbNodes[1]; + int n3 = aNbNodes[2]; + int n4 = aNbNodes[3]; + 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 + return EvaluateQuadPref(aMesh, aShape, aNbNodes, aResMap, IsQuadratic); + //return true; + } + } + + int nbdown = aNbNodes[0]; + int nbup = aNbNodes[2]; + + int nbright = aNbNodes[1]; + int nbleft = aNbNodes[3]; + + int nbhoriz = Min(nbdown, nbup); + int nbvertic = Min(nbright, nbleft); + + int dh = Max(nbdown, nbup) - nbhoriz; + int dv = Max(nbright, nbleft) - nbvertic; + + //int kdh = 0; + //if (dh>0) kdh = 1; + //int kdv = 0; + //if (dv>0) kdv = 1; + + int nbNodes = (nbhoriz-2)*(nbvertic-2); + //int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2; + int nbFaces3 = dh + dv; + //if (kdh==1 && kdv==1) nbFaces3 -= 2; + //if (dh>0 && dv>0) nbFaces3 -= 2; + //int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv); + int nbFaces4 = (nbhoriz-1)*(nbvertic-1); + + std::vector aVec(SMDSEntity_Last); + for (int i=SMDSEntity_Node; i= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD ); const bool ignoreMediumNodes = _quadraticMesh; // verify 1 wire only, with 4 edges @@ -613,50 +801,157 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes FaceQuadStruct* quad = new FaceQuadStruct; quad->uv_grid = 0; quad->side.reserve(nbEdgesInWire.front()); + quad->face = F; 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, + if (nbEdgesInWire.front() == 3) // exactly 3 edges + { + SMESH_Comment comment; + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + if (myTriaVertexID == -1) + { + comment << "No Base vertex parameter provided for a trilateral geometrical face"; + } + else + { + TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID)); + if (!V.IsNull()) { + TopoDS_Edge E1,E2,E3; + for (; edgeIt != edges.end(); ++edgeIt) { + TopoDS_Edge E = *edgeIt; + TopoDS_Vertex VF, VL; + TopExp::Vertices(E, VF, VL, true); + if (VF.IsSame(V)) + E1 = E; + else if (VL.IsSame(V)) + E3 = E; + else + E2 = E; + } + if (!E1.IsNull() && !E2.IsNull() && !E3.IsNull()) + { + quad->side.push_back(new StdMeshers_FaceSide(F, E1, &aMesh, true, ignoreMediumNodes)); + quad->side.push_back(new StdMeshers_FaceSide(F, E2, &aMesh, true, ignoreMediumNodes)); + quad->side.push_back(new StdMeshers_FaceSide(F, E3, &aMesh, false,ignoreMediumNodes)); + const vector& UVPSleft = quad->side[0]->GetUVPtStruct(true,0); + /* vector& UVPStop = */quad->side[1]->GetUVPtStruct(false,1); + /* vector& UVPSright = */quad->side[2]->GetUVPtStruct(true,1); + const SMDS_MeshNode* aNode = UVPSleft[0].node; + gp_Pnt2d aPnt2d(UVPSleft[0].u, UVPSleft[0].v); + quad->side.push_back(new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1])); + return quad; + } + } + comment << "Invalid Base vertex parameter: " << myTriaVertexID << " is not among ["; + TopTools_MapOfShape vMap; + for (TopExp_Explorer v(aShape, TopAbs_VERTEX); v.More(); v.Next()) + if (vMap.Add(v.Current())) + comment << meshDS->ShapeToIndex(v.Current()) << (vMap.Extent()==3 ? "]" : ", "); + } + error(comment); + delete quad; + return quad = 0; + } + else if (nbEdgesInWire.front() == 4) // exactly 4 edges + { + for (; edgeIt != edges.end(); ++edgeIt, nbSides++) + quad->side.push_back(new StdMeshers_FaceSide(F, *edgeIt, &aMesh, nbSides 4 ) { // more than 4 edges - try to unite some + else if (nbEdgesInWire.front() > 4) // more than 4 edges - try to unite some + { list< TopoDS_Edge > sideEdges; - while ( !edges.empty()) { + vector< int > degenSides; + while (!edges.empty()) { sideEdges.clear(); - sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end() + sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end() bool sameSide = true; - while ( !edges.empty() && sameSide ) { - sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ); - if ( sameSide ) - sideEdges.splice( sideEdges.end(), edges, edges.begin()); + while (!edges.empty() && sameSide) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); } - if ( nbSides == 0 ) { // go backward from the first edge + if (nbSides == 0) { // go backward from the first edge sameSide = true; - while ( !edges.empty() && sameSide ) { - sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ); - if ( sameSide ) - sideEdges.splice( sideEdges.begin(), edges, --edges.end()); + while (!edges.empty() && sameSide) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); } } - quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh, + if ( sideEdges.size() == 1 && BRep_Tool::Degenerated( sideEdges.front() )) + degenSides.push_back( nbSides ); + + quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh, nbSidesside.size(); ++i ) + quad->side[i]->Reverse(); + + for ( int i = degenSides.size()-1; i > -1; --i ) + { + StdMeshers_FaceSide* degenSide = quad->side[ degenSides[ i ]]; + delete degenSide; + quad->side.erase( quad->side.begin() + degenSides[ i ] ); + } + for ( unsigned i = TOP_SIDE; i < quad->side.size(); ++i ) + quad->side[i]->Reverse(); + + nbSides -= degenSides.size(); + } + // issue 20222. Try to unite only edges shared by two same faces + if (nbSides < 4) { + // delete found sides + { FaceQuadStruct cleaner(*quad); } + quad->side.clear(); + quad->side.reserve(nbEdgesInWire.front()); + nbSides = 0; + + SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire); + while (!edges.empty()) { + sideEdges.clear(); + sideEdges.splice(sideEdges.end(), edges, edges.begin()); + bool sameSide = true; + while (!edges.empty() && sameSide) { + sameSide = + SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) && + twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); + } + if (nbSides == 0) { // go backward from the first edge + sameSide = true; + while (!edges.empty() && sameSide) { + sameSide = + SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) && + twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); + } + } + quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh, + nbSidesside[i]->NbEdges(); ++e ) - MESSAGE ( myTool->GetMeshDS()->ShapeToIndex( quad->side[i]->Edge( e )) << " " ); - MESSAGE ( ")\n" ); + MESSAGE ("StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:\n"); + for (int i = 0; i < nbSides; ++i) { + MESSAGE (" ("); + for (int e = 0; e < quad->side[i]->NbEdges(); ++e) + MESSAGE (myHelper->GetMeshDS()->ShapeToIndex(quad->side[i]->Edge(e)) << " "); + MESSAGE (")\n"); } //cout << endl; #endif - if ( !nbSides ) + if (!nbSides) nbSides = nbEdgesInWire.front(); error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides); delete quad; @@ -666,6 +961,193 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes return quad; } + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap, + std::vector& aNbNodes, + bool& IsQuadratic) + +{ + const TopoDS_Face & F = TopoDS::Face(aShape); + + // verify 1 wire only, with 4 edges + TopoDS_Vertex V; + list< TopoDS_Edge > edges; + list< int > nbEdgesInWire; + int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire); + if (nbWire != 1) { + return false; + } + + aNbNodes.resize(4); + + int nbSides = 0; + list< TopoDS_Edge >::iterator edgeIt = edges.begin(); + SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if (anIt==aResMap.end()) { + return false; + } + std::vector aVec = (*anIt).second; + IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); + if (nbEdgesInWire.front() == 3) { // exactly 3 edges + if (myTriaVertexID>0) { + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID)); + if (!V.IsNull()) { + TopoDS_Edge E1,E2,E3; + for (; edgeIt != edges.end(); ++edgeIt) { + TopoDS_Edge E = TopoDS::Edge(*edgeIt); + TopoDS_Vertex VF, VL; + TopExp::Vertices(E, VF, VL, true); + if (VF.IsSame(V)) + E1 = E; + else if (VL.IsSame(V)) + E3 = E; + else + E2 = E; + } + SMESH_subMesh * sm = aMesh.GetSubMesh(E1); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if (anIt==aResMap.end()) return false; + std::vector aVec = (*anIt).second; + if (IsQuadratic) + aNbNodes[0] = (aVec[SMDSEntity_Node]-1)/2 + 2; + else + aNbNodes[0] = aVec[SMDSEntity_Node] + 2; + sm = aMesh.GetSubMesh(E2); + anIt = aResMap.find(sm); + if (anIt==aResMap.end()) return false; + aVec = (*anIt).second; + if (IsQuadratic) + aNbNodes[1] = (aVec[SMDSEntity_Node]-1)/2 + 2; + else + aNbNodes[1] = aVec[SMDSEntity_Node] + 2; + sm = aMesh.GetSubMesh(E3); + anIt = aResMap.find(sm); + if (anIt==aResMap.end()) return false; + aVec = (*anIt).second; + if (IsQuadratic) + aNbNodes[2] = (aVec[SMDSEntity_Node]-1)/2 + 2; + else + aNbNodes[2] = aVec[SMDSEntity_Node] + 2; + aNbNodes[3] = aNbNodes[1]; + aNbNodes.resize(5); + nbSides = 4; + } + } + } + if (nbEdgesInWire.front() == 4) { // exactly 4 edges + for (; edgeIt != edges.end(); edgeIt++) { + SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if (anIt==aResMap.end()) { + return false; + } + std::vector aVec = (*anIt).second; + if (IsQuadratic) + aNbNodes[nbSides] = (aVec[SMDSEntity_Node]-1)/2 + 2; + else + aNbNodes[nbSides] = aVec[SMDSEntity_Node] + 2; + nbSides++; + } + } + else if (nbEdgesInWire.front() > 4) { // more than 4 edges - try to unite some + 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) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); + } + if (nbSides == 0) { // go backward from the first edge + sameSide = true; + while (!edges.empty() && sameSide) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); + } + } + list::iterator ite = sideEdges.begin(); + aNbNodes[nbSides] = 1; + for (; ite!=sideEdges.end(); ite++) { + SMESH_subMesh * sm = aMesh.GetSubMesh(*ite); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if (anIt==aResMap.end()) { + return false; + } + std::vector aVec = (*anIt).second; + if (IsQuadratic) + aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1; + else + aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1; + } + ++nbSides; + } + // issue 20222. Try to unite only edges shared by two same faces + if (nbSides < 4) { + nbSides = 0; + SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire); + while (!edges.empty()) { + sideEdges.clear(); + sideEdges.splice(sideEdges.end(), edges, edges.begin()); + bool sameSide = true; + while (!edges.empty() && sameSide) { + sameSide = + SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) && + twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); + } + if (nbSides == 0) { // go backward from the first edge + sameSide = true; + while (!edges.empty() && sameSide) { + sameSide = + SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) && + twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); + } + } + list::iterator ite = sideEdges.begin(); + aNbNodes[nbSides] = 1; + for (; ite!=sideEdges.end(); ite++) { + SMESH_subMesh * sm = aMesh.GetSubMesh(*ite); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if (anIt==aResMap.end()) { + return false; + } + std::vector aVec = (*anIt).second; + if (IsQuadratic) + aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1; + else + aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1; + } + ++nbSides; + } + } + } + if (nbSides != 4) { + if (!nbSides) + nbSides = nbEdgesInWire.front(); + error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides); + return false; + } + + return true; +} + + //============================================================================= /*! * CheckAnd2Dcompute @@ -681,13 +1163,12 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); - if(!quad) return 0; + if (!quad) return 0; // set normalized grid on unit square in parametric domain bool stat = SetNormalizedGrid(aMesh, aShape, quad); - if(!stat) { - if(!quad) - delete quad; + if (!stat) { + if (quad) delete quad; quad = 0; } @@ -711,13 +1192,21 @@ faceQuadStruct::~faceQuadStruct() namespace { inline const vector& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg) { - bool isXConst = ( i == BOTTOM_SIDE || i == TOP_SIDE ); - double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1; + bool isXConst = (i == BOTTOM_SIDE || i == TOP_SIDE); + double constValue = (i == BOTTOM_SIDE || i == LEFT_SIDE) ? 0 : 1; return quad->isEdgeOut[i] ? quad->side[i]->SimulateUVPtStruct(nbSeg,isXConst,constValue) : quad->side[i]->GetUVPtStruct(isXConst,constValue); } + inline gp_UV CalcUV(double x, double y, + const gp_UV& a0,const gp_UV& a1,const gp_UV& a2,const gp_UV& a3, + const gp_UV& p0,const gp_UV& p1,const gp_UV& p2,const gp_UV& p3) + { + return + ((1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3 ) - + ((1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3); + } } //============================================================================= @@ -730,10 +1219,10 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, const TopoDS_Shape& aShape, FaceQuadStruct* & quad) //throw (SALOME_Exception) { - // Algorithme décrit dans "Génération automatique de maillages" - // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85 - // traitement dans le domaine paramétrique 2d u,v - // transport - projection sur le carré unité + // Algorithme décrit dans "Génération automatique de maillages" + // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85 + // traitement dans le domaine paramétrique 2d u,v + // transport - projection sur le carré unité // MESSAGE("StdMeshers_Quadrangle_2D::SetNormalizedGrid"); // const TopoDS_Face& F = TopoDS::Face(aShape); @@ -764,14 +1253,17 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, UVPtStruct *uv_grid = quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz]; - const vector& uv_e0 = GetUVPtStructIn( quad, 0, nbhoriz - 1 ); - const vector& uv_e1 = GetUVPtStructIn( quad, 1, nbvertic - 1 ); - const vector& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 ); - const vector& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 ); + const vector& uv_e0 = GetUVPtStructIn(quad, 0, nbhoriz - 1); + const vector& uv_e1 = GetUVPtStructIn(quad, 1, nbvertic - 1); + const vector& uv_e2 = GetUVPtStructIn(quad, 2, nbhoriz - 1); + const vector& uv_e3 = GetUVPtStructIn(quad, 3, nbvertic - 1); - if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) - //return error( "Can't find nodes on sides"); - return error( COMPERR_BAD_INPUT_MESH ); + if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty()) + //return error("Can't find nodes on sides"); + return error(COMPERR_BAD_INPUT_MESH); + + if ( myNeedSmooth ) + UpdateDegenUV( quad ); // nodes Id on "in" edges if (! quad->isEdgeOut[0]) { @@ -804,17 +1296,15 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, } // normalized 2d values on grid - for (int i = 0; i < nbhoriz; i++) - { - for (int j = 0; j < nbvertic; j++) - { + for (int i = 0; i < nbhoriz; i++) { + for (int j = 0; j < nbvertic; j++) { int ij = j * nbhoriz + i; // --- droite i cste : x = x0 + y(x1-x0) - double x0 = uv_e0[i].normParam; // bas - sud - double x1 = uv_e2[i].normParam; // haut - nord + double x0 = uv_e0[i].normParam; // bas - sud + double x1 = uv_e2[i].normParam; // haut - nord // --- droite j cste : y = y0 + x(y1-y0) - double y0 = uv_e3[j].normParam; // gauche-ouest - double y1 = uv_e1[j].normParam; // droite - est + double y0 = uv_e3[j].normParam; // gauche-ouest + double y1 = uv_e1[j].normParam; // droite - est // --- intersection : x=x0+(y0+x(y1-y0))(x1-x0) double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); double y = y0 + x * (y1 - y0); @@ -826,15 +1316,13 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, } // 4 --- projection on 2d domain (u,v) - gp_UV a0( uv_e0.front().u, uv_e0.front().v ); - gp_UV a1( uv_e0.back().u, uv_e0.back().v ); - gp_UV a2( uv_e2.back().u, uv_e2.back().v ); - gp_UV a3( uv_e2.front().u, uv_e2.front().v ); + gp_UV a0(uv_e0.front().u, uv_e0.front().v); + gp_UV a1(uv_e0.back().u, uv_e0.back().v); + gp_UV a2(uv_e2.back().u, uv_e2.back().v); + gp_UV a3(uv_e2.front().u, uv_e2.front().v); - for (int i = 0; i < nbhoriz; i++) - { - for (int j = 0; j < nbvertic; j++) - { + for (int i = 0; i < nbhoriz; i++) { + for (int j = 0; j < nbvertic; j++) { int ij = j * nbhoriz + i; double x = uv_grid[ij].x; double y = uv_grid[ij].y; @@ -849,8 +1337,7 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, gp_UV p2 = quad->side[2]->Value2d(param_2).XY(); gp_UV p3 = quad->side[3]->Value2d(param_3).XY(); - gp_UV uv = (1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3; - uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3; + gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3); uv_grid[ij].u = uv.X(); uv_grid[ij].v = uv.Y(); @@ -867,11 +1354,11 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, static void ShiftQuad(FaceQuadStruct* quad, const int num, bool) { StdMeshers_FaceSide* side[4] = { quad->side[0], quad->side[1], quad->side[2], quad->side[3] }; - for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i ) { - int id = ( i + num ) % NB_SIDES; - bool wasForward = ( i < TOP_SIDE ); - bool newForward = ( id < TOP_SIDE ); - if ( wasForward != newForward ) + for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i) { + int id = (i + num) % NB_SIDES; + bool wasForward = (i < TOP_SIDE); + bool newForward = (id < TOP_SIDE); + if (wasForward != newForward) side[ i ]->Reverse(); quad->side[ id ] = side[ i ]; } @@ -887,9 +1374,9 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1, const gp_UV& a0, const gp_UV& a1, const gp_UV& a2, const gp_UV& a3) { - const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0 ); + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); @@ -905,9 +1392,7 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1, gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(param_t).XY(); gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(param_l).XY(); - gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x); - - uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3; + gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3); return uv; } @@ -922,27 +1407,12 @@ static gp_UV CalcUV2(double x, double y, const gp_UV& a0, const gp_UV& a1, const gp_UV& a2, const gp_UV& a3) { - const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0 ); - const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); - const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); + gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(x).XY(); + gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(y).XY(); + gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(x).XY(); + gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(y).XY(); - //double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); - //double y = y0 + x * (y1 - y0); - - double param_b = uv_eb[0].normParam + x * (uv_eb.back().normParam - uv_eb[0].normParam); - double param_t = uv_et[0].normParam + x * (uv_et.back().normParam - uv_et[0].normParam); - double param_r = uv_er[0].normParam + y * (uv_er.back().normParam - uv_er[0].normParam); - double param_l = uv_el[0].normParam + y * (uv_el.back().normParam - uv_el[0].normParam); - - gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(param_b).XY(); - gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(param_r).XY(); - gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(param_t).XY(); - gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(param_l).XY(); - - gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x); - - uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3; + gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3); return uv; } @@ -962,20 +1432,14 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, // of meshing after implementation new variant // for bug 0016220 from Mantis. bool OldVersion = false; + if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + OldVersion = true; SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); const TopoDS_Face& F = TopoDS::Face(aShape); Handle(Geom_Surface) S = BRep_Tool::Surface(F); -// const TopoDS_Wire& W = BRepTools::OuterWire(F); bool WisF = true; -// if(W.Orientation()==TopAbs_FORWARD) -// WisF = true; - //if(WisF) cout<<"W is FORWARD"<ShapeToIndex( F ); + int i,j,geomFaceID = meshDS->ShapeToIndex(F); int nb = quad->side[0]->NbPoints(); int nr = quad->side[1]->NbPoints(); @@ -984,8 +1448,8 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, int dh = abs(nb-nt); int dv = abs(nr-nl); - if( dh>=dv ) { - if( nt>nb ) { + if (dh>=dv) { + if (nt>nb) { // it is a base case => not shift quad but me be replacement is need ShiftQuad(quad,0,WisF); } @@ -995,7 +1459,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, } } else { - if( nr>nl ) { + if (nr>nl) { // we have to shift quad on 1 ShiftQuad(quad,1,WisF); } @@ -1044,7 +1508,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, // 0------------0 // 0 bottom 1 - if(dh>dv) { + if (dh>dv) { addv = (dh-dv)/2; nbv = nbv + addv; } @@ -1053,79 +1517,84 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, nbh = nbh + addh; } - const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0 ); + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); + if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl) + return error(COMPERR_BAD_INPUT_MESH); + + if ( myNeedSmooth ) + UpdateDegenUV( quad ); + // arrays for normalized params //cout<<"Dump B:"<X()<<","<Y()<<","<Z()<<")"<0) { + if (dl>0) { // add top nodes - for(i=1; i<=dl; i++) + for (i=1; i<=dl; i++) NodesL.SetValue(i+1,nl,uv_et[i].node); // create and add needed nodes TColgp_SequenceOfXY UVtmp; - for(i=1; i<=dl; i++) { + for (i=1; i<=dl; i++) { double x0 = npt.Value(i+1); double x1 = x0; // diagonal node @@ -1136,9 +1605,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesL.SetValue(i+1,1,N); - if(UVL.Length()AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesL.SetValue(i+1,j,N); - if( i==dl ) UVtmp.Append(UV); + if (i==dl) UVtmp.Append(UV); } } - for(i=1; i<=UVtmp.Length() && UVL.Length()X()<<","<Y()<<","<Z()<<")"; // } // cout<AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), + myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), NodesL.Value(i+1,j+1), NodesL.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } } else { // fill UVL using c2d - for(i=1; i0) { + if (dr>0) { // add top nodes - for(i=1; i<=dr; i++) + for (i=1; i<=dr; i++) NodesR.SetValue(i+1,1,uv_et[nt-1-i].node); // create and add needed nodes TColgp_SequenceOfXY UVtmp; - for(i=1; i<=dr; i++) { + for (i=1; i<=dr; i++) { double x0 = npt.Value(nt-i); double x1 = x0; // diagonal node @@ -1207,9 +1676,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesR.SetValue(i+1,nr,N); - if(UVR.Length()AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesR.SetValue(i+1,j,N); - if( i==dr ) UVtmp.Prepend(UV); + if (i==dr) UVtmp.Prepend(UV); } } - for(i=1; i<=UVtmp.Length() && UVR.Length()AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), + myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), NodesR.Value(i+1,j+1), NodesR.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } } else { // fill UVR using c2d - for(i=1; iAddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesC.SetValue(i,nbv-nnn+j,N); + if ( j==1 ) + UVT.Append( UV ); } } // add diagonal layers //cout<<"UVL.Length()="<Value(u,v); + gp_UV A2 = UVR.Value(nbv-nnn); + gp_UV A3 = UVL.Value(nbv-nnn); + for (i=1; iValue(UV.X(),UV.Y()); SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnFace(N, geomFaceID, u, v); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y()); NodesC.SetValue(j,i+1,N); } } // create faces - for(i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), + myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } @@ -1324,58 +1800,55 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, // step1: create faces for bottom rectangle domain StdMeshers_Array2OfNode NodesBRD(1,nb,1,nnn-1); // fill UVL and UVR using c2d - for(j=0; jValue(u,v); + for (j=2; jValue(UV.X(),UV.Y()); SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnFace(N, geomFaceID, u, v); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y()); NodesBRD.SetValue(j,i+1,N); - } } - for(j=1; jAddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j), + myHelper->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j), NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i,j+1), + myHelper->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i,j+1), NodesBRD.Value(i+1,j+1), NodesBRD.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } - int drl = abs(nr-nl); // create faces for region C StdMeshers_Array2OfNode NodesC(1,nb,1,drl+1+addv); // add nodes from previous region - for(j=1; j<=nb; j++) { + for (j=1; j<=nb; j++) { NodesC.SetValue(j,1,NodesBRD.Value(j,nnn-1)); } - if( (drl+addv) > 0 ) { + if ((drl+addv) > 0) { int n1,n2; - if(nr>nl) { + if (nr>nl) { n1 = 1; n2 = drl + 1; TColgp_SequenceOfXY UVtmp; double drparam = npr.Value(nr) - npr.Value(nnn-1); double dlparam = npl.Value(nnn) - npl.Value(nnn-1); double y0,y1; - for(i=1; i<=drl; i++) { + for (i=1; i<=drl; i++) { // add existed nodes from right edge NodesC.SetValue(nb,i+1,uv_er[nnn+i-2].node); //double dtparam = npt.Value(i+1); @@ -1383,7 +1856,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, double dpar = (y1 - npr.Value(nnn-1))/drparam; y0 = npl.Value(nnn-1) + dpar*dlparam; // param on left edge double dy = y1 - y0; - for(j=1; jValue(UV.X(),UV.Y()); @@ -1419,14 +1892,14 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, double drparam = npr.Value(nnn) - npr.Value(nnn-1); double y0 = npl.Value(nnn-1); double y1 = npr.Value(nnn-1); - for(i=1; i<=drl; i++) { + for (i=1; i<=drl; i++) { // add existed nodes from right edge NodesC.SetValue(1,i+1,uv_el[nnn+i-2].node); y0 = npl.Value(nnn+i-1); // param on left edge double dpar = (y0 - npl.Value(nnn-1))/dlparam; y1 = npr.Value(nnn-1) + dpar*drparam; // param on right edge double dy = y1 - y0; - for(j=2; j<=nb; j++) { + for (j=2; j<=nb; j++) { double x = npb.Value(j)*npt.Value(nt-i); double y = y0 + dy*x; gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3); @@ -1438,13 +1911,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, } double dy0 = (1-y0)/(addv+1); double dy1 = (1-y1)/(addv+1); - for(i=1; i<=addv; i++) { + for (i=1; i<=addv; i++) { double yy0 = y0 + dy0*i; double yy1 = y1 + dy1*i; double dyy = yy1 - yy0; - for(j=1; j<=nb; j++) { + for (j=1; j<=nb; j++) { double x = npt.Value(i+1) + - npb.Value(j) * ( npt.Value(nt-i-drl) - npt.Value(i+1) ); + npb.Value(j) * (npt.Value(nt-i-drl) - npt.Value(i+1)); double y = yy0 + dyy*x; gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3); gp_Pnt P = S->Value(UV.X(),UV.Y()); @@ -1455,55 +1928,55 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, } } // create faces - for(j=1; j<=drl+addv; j++) { - for(i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), + myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } // end nr=n2; i--) { + for (i=drl+addv; i>=n2; i--) { nnn++; NodesLast.SetValue(nnn,1,NodesC.Value(nb,i)); } - for(i=1; iAddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1), + myHelper->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1), NodesLast.Value(i+1,2), NodesLast.Value(i,2)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = - myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i,2), + myHelper->AddFace(NodesLast.Value(i,1), NodesLast.Value(i,2), NodesLast.Value(i+1,2), NodesLast.Value(i+1,2)); - meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } - } // if( (drl+addv) > 0 ) + } // if ((drl+addv) > 0) } // end new version implementation @@ -1511,34 +1984,1470 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, return isOk; } -//============================================================================= -/*! Split quadrangle in to 2 triangles by smallest diagonal - * + +//======================================================================= +/*! + * Evaluate only quandrangle faces */ -//============================================================================= -void StdMeshers_Quadrangle_2D::SplitQuad(SMESHDS_Mesh *theMeshDS, - int theFaceID, - const SMDS_MeshNode* theNode1, - const SMDS_MeshNode* theNode2, - const SMDS_MeshNode* theNode3, - const SMDS_MeshNode* theNode4) +//======================================================================= + +bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, + const TopoDS_Shape& aShape, + std::vector& aNbNodes, + MapShapeNbElems& aResMap, + bool IsQuadratic) { - gp_Pnt a(theNode1->X(),theNode1->Y(),theNode1->Z()); - gp_Pnt b(theNode2->X(),theNode2->Y(),theNode2->Z()); - gp_Pnt c(theNode3->X(),theNode3->Y(),theNode3->Z()); - gp_Pnt d(theNode4->X(),theNode4->Y(),theNode4->Z()); - SMDS_MeshFace* face; - if(a.Distance(c) > b.Distance(d)){ - face = myTool->AddFace(theNode2, theNode4 , theNode1); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); - face = myTool->AddFace(theNode2, theNode3, theNode4); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); + // Auxilary key in order to keep old variant + // of meshing after implementation new variant + // for bug 0016220 from Mantis. + bool OldVersion = false; + if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + OldVersion = true; + + const TopoDS_Face& F = TopoDS::Face(aShape); + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + + int nb = aNbNodes[0]; + int nr = aNbNodes[1]; + int nt = aNbNodes[2]; + int nl = aNbNodes[3]; + int dh = abs(nb-nt); + int dv = abs(nr-nl); + if (dh>=dv) { + if (nt>nb) { + // it is a base case => not shift + } + else { + // we have to shift on 2 + nb = aNbNodes[2]; + nr = aNbNodes[3]; + nt = aNbNodes[0]; + nl = aNbNodes[1]; + } } - else{ - face = myTool->AddFace(theNode1, theNode2 ,theNode3); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); - face = myTool->AddFace(theNode1, theNode3, theNode4); - theMeshDS->SetMeshElementOnShape(face, theFaceID ); + else { + if (nr>nl) { + // we have to shift quad on 1 + nb = aNbNodes[3]; + nr = aNbNodes[0]; + nt = aNbNodes[1]; + nl = aNbNodes[2]; + } + else { + // we have to shift quad on 3 + nb = aNbNodes[1]; + nr = aNbNodes[2]; + nt = aNbNodes[3]; + nl = aNbNodes[0]; + } + } + + dh = abs(nb-nt); + dv = abs(nr-nl); + int nbh = Max(nb,nt); + int nbv = Max(nr,nl); + int addh = 0; + int addv = 0; + + if (dh>dv) { + addv = (dh-dv)/2; + nbv = nbv + addv; + } + else { // dv>=dh + addh = (dv-dh)/2; + nbh = nbh + addh; + } + + int dl,dr; + if (OldVersion) { + // add some params to right and left after the first param + // insert to right + dr = nbv - nr; + // insert to left + dl = nbv - nl; + } + + int nnn = Min(nr,nl); + + int nbNodes = 0; + int nbFaces = 0; + if (OldVersion) { + // step1: create faces for left domain + if (dl>0) { + nbNodes += dl*(nl-1); + nbFaces += dl*(nl-1); + } + // step2: create faces for right domain + if (dr>0) { + nbNodes += dr*(nr-1); + nbFaces += dr*(nr-1); + } + // step3: create faces for central domain + nbNodes += (nb-2)*(nnn-1) + (nbv-nnn-1)*(nb-2); + nbFaces += (nb-1)*(nbv-1); + } + else { // New version (!OldVersion) + nbNodes += (nnn-2)*(nb-2); + nbFaces += (nnn-2)*(nb-1); + int drl = abs(nr-nl); + nbNodes += drl*(nb-1) + addv*nb; + nbFaces += (drl+addv)*(nb-1) + (nt-1); + } // end new version implementation + + std::vector aVec(SMDSEntity_Last); + for (int i=SMDSEntity_Node; iX(),theNode1->Y(),theNode1->Z()); + gp_Pnt b(theNode2->X(),theNode2->Y(),theNode2->Z()); + gp_Pnt c(theNode3->X(),theNode3->Y(),theNode3->Z()); + gp_Pnt d(theNode4->X(),theNode4->Y(),theNode4->Z()); + SMDS_MeshFace* face; + if (a.Distance(c) > b.Distance(d)){ + face = myHelper->AddFace(theNode2, theNode4 , theNode1); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); + face = myHelper->AddFace(theNode2, theNode3, theNode4); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); + + } + else{ + face = myHelper->AddFace(theNode1, theNode2 ,theNode3); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); + face = myHelper->AddFace(theNode1, theNode3, theNode4); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); + } +} + +namespace +{ + enum uvPos { UV_A0, UV_A1, UV_A2, UV_A3, UV_B, UV_R, UV_T, UV_L, UV_SIZE }; + + inline SMDS_MeshNode* makeNode( UVPtStruct & uvPt, + const double y, + FaceQuadStruct* quad, + const gp_UV* UVs, + SMESH_MesherHelper* helper, + Handle(Geom_Surface) S) + { + const vector& uv_eb = quad->side[BOTTOM_SIDE]->GetUVPtStruct(); + const vector& uv_et = quad->side[TOP_SIDE ]->GetUVPtStruct(); + double rBot = ( uv_eb.size() - 1 ) * uvPt.normParam; + double rTop = ( uv_et.size() - 1 ) * uvPt.normParam; + int iBot = int( rBot ); + int iTop = int( rTop ); + double xBot = uv_eb[ iBot ].normParam + ( rBot - iBot ) * ( uv_eb[ iBot+1 ].normParam - uv_eb[ iBot ].normParam ); + double xTop = uv_et[ iTop ].normParam + ( rTop - iTop ) * ( uv_et[ iTop+1 ].normParam - uv_et[ iTop ].normParam ); + double x = xBot + y * ( xTop - xBot ); + + gp_UV uv = CalcUV(/*x,y=*/x, y, + /*a0,...=*/UVs[UV_A0], UVs[UV_A1], UVs[UV_A2], UVs[UV_A3], + /*p0=*/quad->side[BOTTOM_SIDE]->Value2d( x ).XY(), + /*p1=*/UVs[ UV_R ], + /*p2=*/quad->side[TOP_SIDE ]->Value2d( x ).XY(), + /*p3=*/UVs[ UV_L ]); + gp_Pnt P = S->Value( uv.X(), uv.Y() ); + uvPt.u = uv.X(); + uvPt.v = uv.Y(); + return helper->AddNode(P.X(), P.Y(), P.Z(), 0, uv.X(), uv.Y() ); + } + + void reduce42( const vector& curr_base, + vector& next_base, + const int j, + int & next_base_len, + FaceQuadStruct* quad, + gp_UV* UVs, + const double y, + SMESH_MesherHelper* helper, + Handle(Geom_Surface)& S) + { + // add one "HH": nodes a,b,c,d,e and faces 1,2,3,4,5,6 + // + // .-----a-----b i + 1 + // |\ 5 | 6 /| + // | \ | / | + // | c--d--e | + // |1 |2 |3 |4 | + // | | | | | + // .--.--.--.--. i + // + // j j+2 j+4 + + // a (i + 1, j + 2) + const SMDS_MeshNode*& Na = next_base[ ++next_base_len ].node; + if ( !Na ) + Na = makeNode( next_base[ next_base_len ], y, quad, UVs, helper, S ); + + // b (i + 1, j + 4) + const SMDS_MeshNode*& Nb = next_base[ ++next_base_len ].node; + if ( !Nb ) + Nb = makeNode( next_base[ next_base_len ], y, quad, UVs, helper, S ); + + // c + double u = (curr_base[j + 2].u + next_base[next_base_len - 2].u) / 2.0; + double v = (curr_base[j + 2].v + next_base[next_base_len - 2].v) / 2.0; + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nc = helper->AddNode(P.X(), P.Y(), P.Z(), 0, u, v); + + // d + u = (curr_base[j + 2].u + next_base[next_base_len - 1].u) / 2.0; + v = (curr_base[j + 2].v + next_base[next_base_len - 1].v) / 2.0; + P = S->Value(u,v); + SMDS_MeshNode* Nd = helper->AddNode(P.X(), P.Y(), P.Z(), 0, u, v); + + // e + u = (curr_base[j + 2].u + next_base[next_base_len].u) / 2.0; + v = (curr_base[j + 2].v + next_base[next_base_len].v) / 2.0; + P = S->Value(u,v); + SMDS_MeshNode* Ne = helper->AddNode(P.X(), P.Y(), P.Z(), 0, u, v); + + // Faces + helper->AddFace(curr_base[j + 0].node, + curr_base[j + 1].node, Nc, + next_base[next_base_len - 2].node); + + helper->AddFace(curr_base[j + 1].node, + curr_base[j + 2].node, Nd, Nc); + + helper->AddFace(curr_base[j + 2].node, + curr_base[j + 3].node, Ne, Nd); + + helper->AddFace(curr_base[j + 3].node, + curr_base[j + 4].node, Nb, Ne); + + helper->AddFace(Nc, Nd, Na, next_base[next_base_len - 2].node); + + helper->AddFace(Nd, Ne, Nb, Na); + } + + void reduce31( const vector& curr_base, + vector& next_base, + const int j, + int & next_base_len, + FaceQuadStruct* quad, + gp_UV* UVs, + const double y, + SMESH_MesherHelper* helper, + Handle(Geom_Surface)& S) + { + // add one "H": nodes b,c,e and faces 1,2,4,5 + // + // .---------b i + 1 + // |\ 5 /| + // | \ / | + // | c---e | + // |1 |2 |4 | + // | | | | + // .--.---.--. i + // + // j j+1 j+2 j+3 + + // b (i + 1, j + 3) + const SMDS_MeshNode*& Nb = next_base[ ++next_base_len ].node; + if ( !Nb ) + Nb = makeNode( next_base[ next_base_len ], y, quad, UVs, helper, S ); + + // c and e + double u1 = (curr_base[ j ].u + next_base[ next_base_len-1 ].u ) / 2.0; + double u2 = (curr_base[ j+3 ].u + next_base[ next_base_len ].u ) / 2.0; + double u3 = (u2 - u1) / 3.0; + // + double v1 = (curr_base[ j ].v + next_base[ next_base_len-1 ].v ) / 2.0; + double v2 = (curr_base[ j+3 ].v + next_base[ next_base_len ].v ) / 2.0; + double v3 = (v2 - v1) / 3.0; + // c + double u = u1 + u3; + double v = v1 + v3; + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nc = helper->AddNode( P.X(), P.Y(), P.Z(), 0, u, v ); + // e + u = u1 + u3 + u3; + v = v1 + v3 + v3; + P = S->Value(u,v); + SMDS_MeshNode* Ne = helper->AddNode( P.X(), P.Y(), P.Z(), 0, u, v ); + + // Faces + // 1 + helper->AddFace( curr_base[ j + 0 ].node, + curr_base[ j + 1 ].node, + Nc, + next_base[ next_base_len - 1 ].node); + // 2 + helper->AddFace( curr_base[ j + 1 ].node, + curr_base[ j + 2 ].node, Ne, Nc); + // 4 + helper->AddFace( curr_base[ j + 2 ].node, + curr_base[ j + 3 ].node, Nb, Ne); + // 5 + helper->AddFace(Nc, Ne, Nb, + next_base[ next_base_len - 1 ].node); + } + + typedef void (* PReduceFunction) ( const vector& curr_base, + vector& next_base, + const int j, + int & next_base_len, + FaceQuadStruct* quad, + gp_UV* UVs, + const double y, + SMESH_MesherHelper* helper, + Handle(Geom_Surface)& S); + +} // namespace + +//======================================================================= +/*! + * Implementation of Reduced algorithm (meshing with quadrangles only) + */ +//======================================================================= +bool StdMeshers_Quadrangle_2D::ComputeReduced (SMESH_Mesh & aMesh, + const TopoDS_Shape& aShape, + FaceQuadStruct* quad) +{ + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + const TopoDS_Face& F = TopoDS::Face(aShape); + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + int i,j,geomFaceID = meshDS->ShapeToIndex(F); + + int nb = quad->side[0]->NbPoints(); + int nr = quad->side[1]->NbPoints(); + int nt = quad->side[2]->NbPoints(); + int nl = quad->side[3]->NbPoints(); + + // Simple Reduce 10->8->6->4 (3 steps) Multiple Reduce 10->4 (1 step) + // + // .-----.-----.-----.-----. .-----.-----.-----.-----. + // | / \ | / \ | | / \ | / \ | + // | / .--.--. \ | | / \ | / \ | + // | / / | \ \ | | / .----.----. \ | + // .---.---.---.---.---.---. | / / \ | / \ \ | + // | / / \ | / \ \ | | / / \ | / \ \ | + // | / / .-.-. \ \ | | / / .---.---. \ \ | + // | / / / | \ \ \ | | / / / \ | / \ \ \ | + // .--.--.--.--.--.--.--.--. | / / / \ | / \ \ \ | + // | / / / \ | / \ \ \ | | / / / .-.-. \ \ \ | + // | / / / .-.-. \ \ \ | | / / / / | \ \ \ \ | + // | / / / / | \ \ \ \ | | / / / / | \ \ \ \ | + // .-.-.-.--.--.--.--.-.-.-. .-.-.-.--.--.--.--.-.-.-. + + bool MultipleReduce = false; + { + int nb1 = nb; + int nr1 = nr; + int nt1 = nt; + + if (nr == nl) { + if (nb < nt) { + nt1 = nb; + nb1 = nt; + } + } + else if (nb == nt) { + nr1 = nb; // and == nt + if (nl < nr) { + nt1 = nl; + nb1 = nr; + } + else { + nt1 = nr; + nb1 = nl; + } + } + else { + return false; + } + + // number of rows and columns + int nrows = nr1 - 1; + int ncol_top = nt1 - 1; + int ncol_bot = nb1 - 1; + // number of rows needed to reduce ncol_bot to ncol_top using simple 3->1 "tree" (see below) + int nrows_tree31 = int( log( (double)(ncol_bot / ncol_top) ) / log((double) 3 )); // = log x base 3 + if ( nrows < nrows_tree31 ) + MultipleReduce = true; + } + + if (MultipleReduce) { // == ComputeQuadPref QUAD_QUADRANGLE_PREF_REVERSED + //================================================== + int dh = abs(nb-nt); + int dv = abs(nr-nl); + + if (dh >= dv) { + if (nt > nb) { + // it is a base case => not shift quad but may be replacement is need + ShiftQuad(quad,0,true); + } + else { + // we have to shift quad on 2 + ShiftQuad(quad,2,true); + } + } + else { + if (nr > nl) { + // we have to shift quad on 1 + ShiftQuad(quad,1,true); + } + else { + // we have to shift quad on 3 + ShiftQuad(quad,3,true); + } + } + + nb = quad->side[0]->NbPoints(); + nr = quad->side[1]->NbPoints(); + nt = quad->side[2]->NbPoints(); + nl = quad->side[3]->NbPoints(); + dh = abs(nb-nt); + dv = abs(nr-nl); + int nbh = Max(nb,nt); + int nbv = Max(nr,nl); + int addh = 0; + int addv = 0; + + if (dh>dv) { + addv = (dh-dv)/2; + nbv = nbv + addv; + } + else { // dv>=dh + addh = (dv-dh)/2; + nbh = nbh + addh; + } + + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); + const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); + const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); + + if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl) + return error(COMPERR_BAD_INPUT_MESH); + + if ( myNeedSmooth ) + UpdateDegenUV( quad ); + + // arrays for normalized params + TColStd_SequenceOfReal npb, npr, npt, npl; + for (j = 0; j < nb; j++) { + npb.Append(uv_eb[j].normParam); + } + for (i = 0; i < nr; i++) { + npr.Append(uv_er[i].normParam); + } + for (j = 0; j < nt; j++) { + npt.Append(uv_et[j].normParam); + } + for (i = 0; i < nl; i++) { + npl.Append(uv_el[i].normParam); + } + + int dl,dr; + // orientation of face and 3 main domain for future faces + // 0 top 1 + // 1------------1 + // | | | | + // | | | | + // | L | | R | + // left | | | | rigth + // | / \ | + // | / C \ | + // |/ \| + // 0------------0 + // 0 bottom 1 + + // add some params to right and left after the first param + // insert to right + dr = nbv - nr; + double dpr = (npr.Value(2) - npr.Value(1))/(dr+1); + for (i=1; i<=dr; i++) { + npr.InsertAfter(1,npr.Value(2)-dpr); + } + // insert to left + dl = nbv - nl; + dpr = (npl.Value(2) - npl.Value(1))/(dl+1); + for (i=1; i<=dl; i++) { + npl.InsertAfter(1,npl.Value(2)-dpr); + } + + gp_XY a0 (uv_eb.front().u, uv_eb.front().v); + gp_XY a1 (uv_eb.back().u, uv_eb.back().v); + gp_XY a2 (uv_et.back().u, uv_et.back().v); + gp_XY a3 (uv_et.front().u, uv_et.front().v); + + int nnn = Min(nr,nl); + // auxilary sequence of XY for creation of nodes + // in the bottom part of central domain + // it's length must be == nbv-nnn-1 + TColgp_SequenceOfXY UVL; + TColgp_SequenceOfXY UVR; + //================================================== + + // step1: create faces for left domain + StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl); + // add left nodes + for (j=1; j<=nl; j++) + NodesL.SetValue(1,j,uv_el[j-1].node); + if (dl>0) { + // add top nodes + for (i=1; i<=dl; i++) + NodesL.SetValue(i+1,nl,uv_et[i].node); + // create and add needed nodes + TColgp_SequenceOfXY UVtmp; + for (i=1; i<=dl; i++) { + double x0 = npt.Value(i+1); + double x1 = x0; + // diagonal node + double y0 = npl.Value(i+1); + double y1 = npr.Value(i+1); + gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3); + gp_Pnt P = S->Value(UV.X(),UV.Y()); + SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesL.SetValue(i+1,1,N); + if (UVL.Length()Value(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesL.SetValue(i+1,j,N); + if (i==dl) UVtmp.Append(UV); + } + } + for (i=1; i<=UVtmp.Length() && UVL.Length()AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + } + else { + // fill UVL using c2d + for (i=1; i0) { + // add top nodes + for (i=1; i<=dr; i++) + NodesR.SetValue(i+1,1,uv_et[nt-1-i].node); + // create and add needed nodes + TColgp_SequenceOfXY UVtmp; + for (i=1; i<=dr; i++) { + double x0 = npt.Value(nt-i); + double x1 = x0; + // diagonal node + double y0 = npl.Value(i+1); + double y1 = npr.Value(i+1); + gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3); + gp_Pnt P = S->Value(UV.X(),UV.Y()); + SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesR.SetValue(i+1,nr,N); + if (UVR.Length()Value(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesR.SetValue(i+1,j,N); + if (i==dr) UVtmp.Prepend(UV); + } + } + for (i=1; i<=UVtmp.Length() && UVR.Length()AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + } + else { + // fill UVR using c2d + for (i=1; iValue(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesC.SetValue(i,nbv-nnn+j,N); + } + } + // add diagonal layers + for (i=1; iValue(u,v); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, u, v); + NodesC.SetValue(j,i+1,N); + } + } + // create faces + for (i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + // TODO ??? + } // end Multiple Reduce implementation + else { // Simple Reduce (!MultipleReduce) + //========================================================= + if (nr == nl) { + if (nt < nb) { + // it is a base case => not shift quad + //ShiftQuad(quad,0,true); + } + else { + // we have to shift quad on 2 + ShiftQuad(quad,2,true); + } + } + else { + if (nl > nr) { + // we have to shift quad on 1 + ShiftQuad(quad,1,true); + } + else { + // we have to shift quad on 3 + ShiftQuad(quad,3,true); + } + } + + nb = quad->side[0]->NbPoints(); + nr = quad->side[1]->NbPoints(); + nt = quad->side[2]->NbPoints(); + nl = quad->side[3]->NbPoints(); + + // number of rows and columns + int nrows = nr - 1; // and also == nl - 1 + int ncol_top = nt - 1; + int ncol_bot = nb - 1; + int npair_top = ncol_top / 2; + // maximum number of bottom elements for "linear" simple reduce 4->2 + int max_lin42 = ncol_top + npair_top * 2 * nrows; + // maximum number of bottom elements for "linear" simple reduce 3->1 + int max_lin31 = ncol_top + ncol_top * 2 * nrows; + // maximum number of bottom elements for "tree" simple reduce 4->2 + int max_tree42 = 0; + // number of rows needed to reduce ncol_bot to ncol_top using simple 4->2 "tree" + int nrows_tree42 = int( log( (double)(ncol_bot / ncol_top) )/log((double)2) ); // needed to avoid overflow at pow(2) while computing max_tree42 + if (nrows_tree42 < nrows) { + max_tree42 = npair_top * pow(2.0, nrows + 1); + if ( ncol_top > npair_top * 2 ) { + int delta = ncol_bot - max_tree42; + for (int irow = 1; irow < nrows; irow++) { + int nfour = delta / 4; + delta -= nfour * 2; + } + if (delta <= (ncol_top - npair_top * 2)) + max_tree42 = ncol_bot; + } + } + // maximum number of bottom elements for "tree" simple reduce 3->1 + //int max_tree31 = ncol_top * pow(3.0, nrows); + bool is_lin_31 = false; + bool is_lin_42 = false; + bool is_tree_31 = false; + bool is_tree_42 = false; + int max_lin = max_lin42; + if (ncol_bot > max_lin42) { + if (ncol_bot <= max_lin31) { + is_lin_31 = true; + max_lin = max_lin31; + } + } + else { + // if ncol_bot is a 3*n or not 2*n + if ((ncol_bot/3)*3 == ncol_bot || (ncol_bot/2)*2 != ncol_bot) { + is_lin_31 = true; + max_lin = max_lin31; + } + else { + is_lin_42 = true; + } + } + if (ncol_bot > max_lin) { // not "linear" + is_tree_31 = (ncol_bot > max_tree42); + if (ncol_bot <= max_tree42) { + if ((ncol_bot/3)*3 == ncol_bot || (ncol_bot/2)*2 != ncol_bot) { + is_tree_31 = true; + } + else { + is_tree_42 = true; + } + } + } + + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); + const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); + const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); + + if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl) + return error(COMPERR_BAD_INPUT_MESH); + + myHelper->SetElementsOnShape( true ); + + gp_UV uv[ UV_SIZE ]; + uv[ UV_A0 ].SetCoord( uv_eb.front().u, uv_eb.front().v); + uv[ UV_A1 ].SetCoord( uv_eb.back().u, uv_eb.back().v ); + uv[ UV_A2 ].SetCoord( uv_et.back().u, uv_et.back().v ); + uv[ UV_A3 ].SetCoord( uv_et.front().u, uv_et.front().v); + + vector curr_base = uv_eb, next_base; + + UVPtStruct nullUVPtStruct; nullUVPtStruct.node = 0; + + int curr_base_len = nb; + int next_base_len = 0; + + if ( true ) + { // ------------------------------------------------------------------ + // New algorithm implemented by request of IPAL22856 + // "2D quadrangle mesher of reduced type works wrong" + // http://bugtracker.opencascade.com/show_bug.cgi?id=22856 + + // the algorithm is following: all reduces are centred in horizontal + // direction and are distributed among all rows + + if (ncol_bot > max_tree42) { + is_lin_31 = true; + } + else { + if ((ncol_top/3)*3 == ncol_top ) { + is_lin_31 = true; + } + else { + is_lin_42 = true; + } + } + + const int col_top_size = is_lin_42 ? 2 : 1; + const int col_base_size = is_lin_42 ? 4 : 3; + + // Compute nb of "columns" (like in "linear" simple reducing) in all rows + + vector nb_col_by_row; + + int delta_all = nb - nt; + int delta_one_col = nrows * 2; + int nb_col = delta_all / delta_one_col; + int remainder = delta_all - nb_col * delta_one_col; + if (remainder > 0) { + nb_col++; + } + if ( nb_col * col_top_size >= nt ) // == "tree" reducing situation + { + // top row is full (all elements reduced), add "columns" one by one + // in rows below until all bottom elements are reduced + nb_col = ( nt - 1 ) / col_top_size; + nb_col_by_row.resize( nrows, nb_col ); + int nbrows_not_full = nrows - 1; + int cur_top_size = nt - 1; + remainder = delta_all - nb_col * delta_one_col; + while ( remainder > 0 ) + { + delta_one_col = nbrows_not_full * 2; + int nb_col_add = remainder / delta_one_col; + cur_top_size += 2 * nb_col_by_row[ nbrows_not_full ]; + int nb_col_free = cur_top_size / col_top_size - nb_col_by_row[ nbrows_not_full-1 ]; + if ( nb_col_add > nb_col_free ) + nb_col_add = nb_col_free; + for ( int irow = 0; irow < nbrows_not_full; ++irow ) + nb_col_by_row[ irow ] += nb_col_add; + nbrows_not_full --; + remainder -= nb_col_add * delta_one_col; + } + } + else // == "linear" reducing situation + { + nb_col_by_row.resize( nrows, nb_col ); + if (remainder > 0) + for ( int irow = remainder / 2; irow < nrows; ++irow ) + nb_col_by_row[ irow ]--; + } + + // Make elements + + PReduceFunction reduceFunction = & ( is_lin_42 ? reduce42 : reduce31 ); + + const int reduce_grp_size = is_lin_42 ? 4 : 3; + + for (i = 1; i < nr; i++) // layer by layer + { + nb_col = nb_col_by_row[ i-1 ]; + int nb_next = curr_base_len - nb_col * 2; + if (nb_next < nt) nb_next = nt; + + const double y = uv_el[ i ].normParam; + + if ( i + 1 == nr ) // top + { + next_base = uv_et; + } + else + { + next_base.clear(); + next_base.resize( nb_next, nullUVPtStruct ); + next_base.front() = uv_el[i]; + next_base.back() = uv_er[i]; + + // compute normalized param u + double du = 1. / ( nb_next - 1 ); + next_base[0].normParam = 0.; + for ( j = 1; j < nb_next; ++j ) + next_base[j].normParam = next_base[j-1].normParam + du; + } + uv[ UV_L ].SetCoord( next_base.front().u, next_base.front().v ); + uv[ UV_R ].SetCoord( next_base.back().u, next_base.back().v ); + + int free_left = ( curr_base_len - 1 - nb_col * col_base_size ) / 2; + int free_middle = curr_base_len - 1 - nb_col * col_base_size - 2 * free_left; + + // not reduced left elements + for (j = 0; j < free_left; j++) + { + // f (i + 1, j + 1) + const SMDS_MeshNode*& Nf = next_base[++next_base_len].node; + if ( !Nf ) + Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S ); + + myHelper->AddFace(curr_base[ j ].node, + curr_base[ j+1 ].node, + Nf, + next_base[ next_base_len-1 ].node); + } + + for (int icol = 1; icol <= nb_col; icol++) + { + // add "H" + reduceFunction( curr_base, next_base, j, next_base_len, quad, uv, y, myHelper, S ); + + j += reduce_grp_size; + + // elements in the middle of "columns" added for symmetry + if ( free_middle > 0 && ( nb_col % 2 == 0 ) && icol == nb_col / 2 ) + { + for (int imiddle = 1; imiddle <= free_middle; imiddle++) { + // f (i + 1, j + imiddle) + const SMDS_MeshNode*& Nf = next_base[++next_base_len].node; + if ( !Nf ) + Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S ); + + myHelper->AddFace(curr_base[ j-1+imiddle ].node, + curr_base[ j +imiddle ].node, + Nf, + next_base[ next_base_len-1 ].node); + } + j += free_middle; + } + } + + // not reduced right elements + for (; j < curr_base_len-1; j++) { + // f (i + 1, j + 1) + const SMDS_MeshNode*& Nf = next_base[++next_base_len].node; + if ( !Nf ) + Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S ); + + myHelper->AddFace(curr_base[ j ].node, + curr_base[ j+1 ].node, + Nf, + next_base[ next_base_len-1 ].node); + } + + curr_base_len = next_base_len + 1; + next_base_len = 0; + curr_base.swap( next_base ); + } + + } + else if ( is_tree_42 || is_tree_31 ) + { + // "tree" simple reduce "42": 2->4->8->16->32->... + // + // .-------------------------------.-------------------------------. nr + // | \ | / | + // | \ .---------------.---------------. / | + // | | | | | + // .---------------.---------------.---------------.---------------. + // | \ | / | \ | / | + // | \ .-------.-------. / | \ .-------.-------. / | + // | | | | | | | | | + // .-------.-------.-------.-------.-------.-------.-------.-------. i + // |\ | /|\ | /|\ | /|\ | /| + // | \.---.---./ | \.---.---./ | \.---.---./ | \.---.---./ | + // | | | | | | | | | | | | | | | | | + // .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. + // |\ | /|\ | /|\ | /|\ | /|\ | /|\ | /|\ | /|\ | /| + // | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | + // | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + // .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. 1 + // 1 j nb + + // "tree" simple reduce "31": 1->3->9->27->... + // + // .-----------------------------------------------------. nr + // | \ / | + // | .-----------------. | + // | | | | + // .-----------------.-----------------.-----------------. + // | \ / | \ / | \ / | + // | .-----. | .-----. | .-----. | i + // | | | | | | | | | | + // .-----.-----.-----.-----.-----.-----.-----.-----.-----. + // |\ /|\ /|\ /|\ /|\ /|\ /|\ /|\ /|\ /| + // | .-. | .-. | .-. | .-. | .-. | .-. | .-. | .-. | .-. | + // | | | | | | | | | | | | | | | | | | | | | | | | | | | | + // .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. 1 + // 1 j nb + + PReduceFunction reduceFunction = & ( is_tree_42 ? reduce42 : reduce31 ); + + const int reduce_grp_size = is_tree_42 ? 4 : 3; + + for (i = 1; i < nr; i++) // layer by layer + { + // to stop reducing, if number of nodes reaches nt + int delta = curr_base_len - nt; + + // to calculate normalized parameter, we must know number of points in next layer + int nb_reduce_groups = (curr_base_len - 1) / reduce_grp_size; + int nb_next = nb_reduce_groups * (reduce_grp_size-2) + (curr_base_len - nb_reduce_groups*reduce_grp_size); + if (nb_next < nt) nb_next = nt; + + const double y = uv_el[ i ].normParam; + + if ( i + 1 == nr ) // top + { + next_base = uv_et; + } + else + { + next_base.clear(); + next_base.resize( nb_next, nullUVPtStruct ); + next_base.front() = uv_el[i]; + next_base.back() = uv_er[i]; + + // compute normalized param u + double du = 1. / ( nb_next - 1 ); + next_base[0].normParam = 0.; + for ( j = 1; j < nb_next; ++j ) + next_base[j].normParam = next_base[j-1].normParam + du; + } + uv[ UV_L ].SetCoord( next_base.front().u, next_base.front().v ); + uv[ UV_R ].SetCoord( next_base.back().u, next_base.back().v ); + + for (j = 0; j+reduce_grp_size < curr_base_len && delta > 0; j+=reduce_grp_size, delta-=2) + { + reduceFunction( curr_base, next_base, j, next_base_len, quad, uv, y, myHelper, S ); + } + + // not reduced side elements (if any) + for (; j < curr_base_len-1; j++) + { + // f (i + 1, j + 1) + const SMDS_MeshNode*& Nf = next_base[++next_base_len].node; + if ( !Nf ) + Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S ); + + myHelper->AddFace(curr_base[ j ].node, + curr_base[ j+1 ].node, + Nf, + next_base[ next_base_len-1 ].node); + } + curr_base_len = next_base_len + 1; + next_base_len = 0; + curr_base.swap( next_base ); + } + } // end "tree" simple reduce + + else if ( is_lin_42 || is_lin_31 ) { + // "linear" simple reduce "31": 2->6->10->14 + // + // .-----------------------------.-----------------------------. nr + // | \ / | \ / | + // | .---------. | .---------. | + // | | | | | | | + // .---------.---------.---------.---------.---------.---------. + // | / \ / \ | / \ / \ | + // | / .-----. \ | / .-----. \ | i + // | / | | \ | / | | \ | + // .-----.-----.-----.-----.-----.-----.-----.-----.-----.-----. + // | / / \ / \ \ | / / \ / \ \ | + // | / / .-. \ \ | / / .-. \ \ | + // | / / / \ \ \ | / / / \ \ \ | + // .--.----.---.-----.---.-----.-.--.----.---.-----.---.-----.-. 1 + // 1 j nb + + // "linear" simple reduce "42": 4->8->12->16 + // + // .---------------.---------------.---------------.---------------. nr + // | \ | / | \ | / | + // | \ .-------.-------. / | \ .-------.-------. / | + // | | | | | | | | | + // .-------.-------.-------.-------.-------.-------.-------.-------. + // | / \ | / \ | / \ | / \ | + // | / \.----.----./ \ | / \.----.----./ \ | i + // | / | | | \ | / | | | \ | + // .-----.----.----.----.----.-----.-----.----.----.----.----.-----. + // | / / \ | / \ \ | / / \ | / \ \ | + // | / / .-.-. \ \ | / / .-.-. \ \ | + // | / / / | \ \ \ | / / / | \ \ \ | + // .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. 1 + // 1 j nb + + // nt = 5, nb = 7, nr = 4 + //int delta_all = 2; + //int delta_one_col = 6; + //int nb_col = 0; + //int remainder = 2; + //if (remainder > 0) nb_col++; + //nb_col = 1; + //int free_left = 1; + //free_left += 2; + //int free_middle = 4; + + int delta_all = nb - nt; + int delta_one_col = (nr - 1) * 2; + int nb_col = delta_all / delta_one_col; + int remainder = delta_all - nb_col * delta_one_col; + if (remainder > 0) { + nb_col++; + } + const int col_top_size = is_lin_42 ? 2 : 1; + int free_left = ((nt - 1) - nb_col * col_top_size) / 2; + free_left += nr - 2; + int free_middle = (nr - 2) * 2; + if (remainder > 0 && nb_col == 1) { + int nb_rows_short_col = remainder / 2; + int nb_rows_thrown = (nr - 1) - nb_rows_short_col; + free_left -= nb_rows_thrown; + } + + // nt = 5, nb = 17, nr = 4 + //int delta_all = 12; + //int delta_one_col = 6; + //int nb_col = 2; + //int remainder = 0; + //int free_left = 2; + //int free_middle = 4; + + PReduceFunction reduceFunction = & ( is_lin_42 ? reduce42 : reduce31 ); + + const int reduce_grp_size = is_lin_42 ? 4 : 3; + + for (i = 1; i < nr; i++, free_middle -= 2, free_left -= 1) // layer by layer + { + // to calculate normalized parameter, we must know number of points in next layer + int nb_next = curr_base_len - nb_col * 2; + if (remainder > 0 && i > remainder / 2) + // take into account short "column" + nb_next += 2; + if (nb_next < nt) nb_next = nt; + + const double y = uv_el[ i ].normParam; + + if ( i + 1 == nr ) // top + { + next_base = uv_et; + } + else + { + next_base.clear(); + next_base.resize( nb_next, nullUVPtStruct ); + next_base.front() = uv_el[i]; + next_base.back() = uv_er[i]; + + // compute normalized param u + double du = 1. / ( nb_next - 1 ); + next_base[0].normParam = 0.; + for ( j = 1; j < nb_next; ++j ) + next_base[j].normParam = next_base[j-1].normParam + du; + } + uv[ UV_L ].SetCoord( next_base.front().u, next_base.front().v ); + uv[ UV_R ].SetCoord( next_base.back().u, next_base.back().v ); + + // not reduced left elements + for (j = 0; j < free_left; j++) + { + // f (i + 1, j + 1) + const SMDS_MeshNode*& Nf = next_base[++next_base_len].node; + if ( !Nf ) + Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S ); + + myHelper->AddFace(curr_base[ j ].node, + curr_base[ j+1 ].node, + Nf, + next_base[ next_base_len-1 ].node); + } + + for (int icol = 1; icol <= nb_col; icol++) { + + if (remainder > 0 && icol == nb_col && i > remainder / 2) + // stop short "column" + break; + + // add "H" + reduceFunction( curr_base, next_base, j, next_base_len, quad, uv, y, myHelper, S ); + + j += reduce_grp_size; + + // not reduced middle elements + if (icol < nb_col) { + if (remainder > 0 && icol == nb_col - 1 && i > remainder / 2) + // pass middle elements before stopped short "column" + break; + + int free_add = free_middle; + if (remainder > 0 && icol == nb_col - 1) + // next "column" is short + free_add -= (nr - 1) - (remainder / 2); + + for (int imiddle = 1; imiddle <= free_add; imiddle++) { + // f (i + 1, j + imiddle) + const SMDS_MeshNode*& Nf = next_base[++next_base_len].node; + if ( !Nf ) + Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S ); + + myHelper->AddFace(curr_base[ j-1+imiddle ].node, + curr_base[ j +imiddle ].node, + Nf, + next_base[ next_base_len-1 ].node); + } + j += free_add; + } + } + + // not reduced right elements + for (; j < curr_base_len-1; j++) { + // f (i + 1, j + 1) + const SMDS_MeshNode*& Nf = next_base[++next_base_len].node; + if ( !Nf ) + Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S ); + + myHelper->AddFace(curr_base[ j ].node, + curr_base[ j+1 ].node, + Nf, + next_base[ next_base_len-1 ].node); + } + + curr_base_len = next_base_len + 1; + next_base_len = 0; + curr_base.swap( next_base ); + } + + } // end "linear" simple reduce + + else { + return false; + } + } // end Simple Reduce implementation + + bool isOk = true; + return isOk; +} + +//================================================================================ +namespace // data for smoothing +{ + struct TSmoothNode; + // -------------------------------------------------------------------------------- + /*! + * \brief Structure used to check validity of node position after smoothing. + * It holds two nodes connected to a smoothed node and belonging to + * one mesh face + */ + struct TTriangle + { + TSmoothNode* _n1; + TSmoothNode* _n2; + TTriangle( TSmoothNode* n1=0, TSmoothNode* n2=0 ): _n1(n1), _n2(n2) {} + + inline bool IsForward( gp_UV uv ) const; + }; + // -------------------------------------------------------------------------------- + /*! + * \brief Data of a smoothed node + */ + struct TSmoothNode + { + gp_XY _uv; + vector< TTriangle > _triangles; // if empty, then node is not movable + }; + // -------------------------------------------------------------------------------- + inline bool TTriangle::IsForward( gp_UV uv ) const + { + gp_Vec2d v1( uv, _n1->_uv ), v2( uv, _n2->_uv ); + double d = v1 ^ v2; + return d > 1e-100; + } +} + +//================================================================================ +/*! + * \brief Set UV of nodes on degenerated VERTEXes in the middle of degenerated EDGE + * + * WARNING: this method must be called AFTER retrieving UVPtStruct's from quad + */ +//================================================================================ + +void StdMeshers_Quadrangle_2D::UpdateDegenUV(FaceQuadStruct* quad) +{ + for ( unsigned i = 0; i < quad->side.size(); ++i ) + { + StdMeshers_FaceSide* side = quad->side[i]; + const vector& uvVec = side->GetUVPtStruct(); + + // find which end of the side is on degenerated shape + int degenInd = -1; + if ( myHelper->IsDegenShape( uvVec[0].node->getshapeId() )) + degenInd = 0; + else if ( myHelper->IsDegenShape( uvVec.back().node->getshapeId() )) + degenInd = uvVec.size() - 1; + else + continue; + + // find another side sharing the degenerated shape + bool isPrev = ( degenInd == 0 ); + if ( i >= TOP_SIDE ) + isPrev = !isPrev; + int i2 = ( isPrev ? ( i + 3 ) : ( i + 1 )) % 4; + StdMeshers_FaceSide* side2 = quad->side[ i2 ]; + const vector& uvVec2 = side2->GetUVPtStruct(); + int degenInd2 = -1; + if ( uvVec[ degenInd ].node == uvVec2[0].node ) + degenInd2 = 0; + else if ( uvVec[ degenInd ].node == uvVec2.back().node ) + degenInd2 = uvVec2.size() - 1; + else + throw SALOME_Exception( LOCALIZED( "Logical error" )); + + // move UV in the middle + uvPtStruct& uv1 = const_cast( uvVec [ degenInd ]); + uvPtStruct& uv2 = const_cast( uvVec2[ degenInd2 ]); + uv1.u = uv2.u = 0.5 * ( uv1.u + uv2.u ); + uv1.v = uv2.v = 0.5 * ( uv1.v + uv2.v ); + } +} + +//================================================================================ +/*! + * \brief Perform smoothing of 2D elements on a FACE with ignored degenerated EDGE + */ +//================================================================================ + +void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct* quad) +{ + if ( !myNeedSmooth ) return; + + // Get nodes to smooth + + typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap; + TNo2SmooNoMap smooNoMap; + + const TopoDS_Face& geomFace = TopoDS::Face( myHelper->GetSubShape() ); + SMESHDS_Mesh* meshDS = myHelper->GetMeshDS(); + SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( geomFace ); + SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); + while ( nIt->more() ) // loop on nodes bound to a FACE + { + const SMDS_MeshNode* node = nIt->next(); + TSmoothNode & sNode = smooNoMap[ node ]; + sNode._uv = myHelper->GetNodeUV( geomFace, node ); + + // set sNode._triangles + SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + const int nbN = face->NbCornerNodes(); + const int nInd = face->GetNodeIndex( node ); + const int prevInd = myHelper->WrapIndex( nInd - 1, nbN ); + const int nextInd = myHelper->WrapIndex( nInd + 1, nbN ); + const SMDS_MeshNode* prevNode = face->GetNode( prevInd ); + const SMDS_MeshNode* nextNode = face->GetNode( nextInd ); + sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ], + & smooNoMap[ nextNode ])); + } + } + // set _uv of smooth nodes on FACE boundary + for ( unsigned i = 0; i < quad->side.size(); ++i ) + { + const vector& uvVec = quad->side[i]->GetUVPtStruct(); + for ( unsigned j = 0; j < uvVec.size(); ++j ) + { + TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; + sNode._uv.SetCoord( uvVec[j].u, uvVec[j].v ); + } + } + + // define refernce orientation in 2D + TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); + for ( ; n2sn != smooNoMap.end(); ++n2sn ) + if ( !n2sn->second._triangles.empty() ) + break; + if ( n2sn == smooNoMap.end() ) return; + const TSmoothNode & sampleNode = n2sn->second; + const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv )); + + // Smoothing + + for ( int iLoop = 0; iLoop < 5; ++iLoop ) + { + for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) + { + TSmoothNode& sNode = n2sn->second; + if ( sNode._triangles.empty() ) + continue; // not movable node + + // compute a new UV + gp_XY newUV (0,0); + for ( unsigned i = 0; i < sNode._triangles.size(); ++i ) + newUV += sNode._triangles[i]._n1->_uv; + newUV /= sNode._triangles.size(); + + // check validity of the newUV + bool isValid = true; + for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i ) + isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); + + if ( isValid ) + sNode._uv = newUV; + } + } + + // Set new XYZ to the smoothed nodes + + Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace ); + + for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) + { + TSmoothNode& sNode = n2sn->second; + if ( sNode._triangles.empty() ) + continue; // not movable node + + SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first ); + gp_Pnt xyz = surface->Value( sNode._uv.X(), sNode._uv.Y() ); + meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); + + // store the new UV + node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() ))); + } + + // Move medium nodes in quadratic mesh + if ( _quadraticMesh ) + { + const TLinkNodeMap& links = myHelper->GetTLinkNodeMap(); + TLinkNodeMap::const_iterator linkIt = links.begin(); + for ( ; linkIt != links.end(); ++linkIt ) + { + const SMESH_TLink& link = linkIt->first; + SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( linkIt->second ); + + if ( node->getshapeId() != myHelper->GetSubShapeID() ) + continue; // medium node is on EDGE or VERTEX + + gp_XY uv1 = myHelper->GetNodeUV( geomFace, link.node1(), node ); + gp_XY uv2 = myHelper->GetNodeUV( geomFace, link.node2(), node ); + + gp_XY uv = myHelper->GetMiddleUV( surface, uv1, uv2 ); + node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( uv.X(), uv.Y() ))); + + gp_Pnt xyz = surface->Value( uv.X(), uv.Y() ); + meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); + } } } diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index 18c1daeca..3f9202e86 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -1,39 +1,41 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Quadrangle_2D.hxx // Moved here from SMESH_Quadrangle_2D.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ -// + #ifndef _SMESH_QUADRANGLE_2D_HXX_ #define _SMESH_QUADRANGLE_2D_HXX_ #include "SMESH_StdMeshers.hxx" +#include "StdMeshers_QuadrangleParams.hxx" + #include "SMESH_2D_Algo.hxx" #include "Utils_SALOME_Exception.hxx" +#include + class SMESH_Mesh; class SMESH_MesherHelper; class StdMeshers_FaceSide; @@ -49,6 +51,7 @@ typedef struct faceQuadStruct std::vector< StdMeshers_FaceSide*> side; bool isEdgeOut[4]; // true, if an edge has more nodes, than the opposite UVPtStruct* uv_grid; + TopoDS_Face face; ~faceQuadStruct(); } FaceQuadStruct; @@ -63,20 +66,29 @@ public: SMESH_Hypothesis::Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, + const TopoDS_Shape& aShape, const bool CreateQuadratic); -protected: - FaceQuadStruct* CheckNbEdges(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); +protected: + + bool CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap, + std::vector& aNbNodes, + bool& IsQuadratic); + bool SetNormalizedGrid(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - FaceQuadStruct*& quad); + const TopoDS_Shape& aShape, + FaceQuadStruct*& quad); void SplitQuad(SMESHDS_Mesh *theMeshDS, const int theFaceID, @@ -85,34 +97,40 @@ protected: const SMDS_MeshNode* theNode3, const SMDS_MeshNode* theNode4); - /** - * Special function for creation only quandrangle faces - */ bool ComputeQuadPref(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, FaceQuadStruct* quad); - UVPtStruct* LoadEdgePoints2(SMESH_Mesh& aMesh, - const TopoDS_Face& F, const TopoDS_Edge& E, - bool IsReverse); + bool EvaluateQuadPref(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + std::vector& aNbNodes, + MapShapeNbElems& aResMap, + bool IsQuadratic); + + bool ComputeReduced (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + FaceQuadStruct* quad); + + void UpdateDegenUV(FaceQuadStruct* quad); - UVPtStruct* LoadEdgePoints(SMESH_Mesh& aMesh, - const TopoDS_Face& F, const TopoDS_Edge& E, - double first, double last); + void Smooth (FaceQuadStruct* quad); - UVPtStruct* MakeEdgePoints(SMESH_Mesh& aMesh, - const TopoDS_Face& F, const TopoDS_Edge& E, - double first, double last, int nb_segm); // true if QuadranglePreference hypothesis is assigned that forces // construction of quadrangles if the number of nodes on opposite edges - // is not the same in the case where the global number of nodes on edges is even + // is not the same in the case where the global number of nodes on edges + // is even bool myQuadranglePreference; bool myTrianglePreference; - SMESH_MesherHelper* myTool; // tool for working with quadratic elements + int myTriaVertexID; + + StdMeshers_QuadType myQuadType; + + SMESH_MesherHelper* myHelper; // tool for working with quadratic elements + + bool myNeedSmooth; }; #endif diff --git a/src/StdMeshers/StdMeshers_QuadraticMesh.cxx b/src/StdMeshers/StdMeshers_QuadraticMesh.cxx index 4764356f2..b58504b1f 100644 --- a/src/StdMeshers/StdMeshers_QuadraticMesh.cxx +++ b/src/StdMeshers/StdMeshers_QuadraticMesh.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers_QuadraticMesh : implementaion of SMESH idl descriptions // File : StdMeshers_QuadraticMesh.cxx // Module : SMESH - +// #include "StdMeshers_QuadraticMesh.hxx" #include "utilities.h" diff --git a/src/StdMeshers/StdMeshers_QuadraticMesh.hxx b/src/StdMeshers/StdMeshers_QuadraticMesh.hxx index 9972469c0..7d870408b 100644 --- a/src/StdMeshers/StdMeshers_QuadraticMesh.hxx +++ b/src/StdMeshers/StdMeshers_QuadraticMesh.hxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of SMESH idl descriptions // File : StdMeshers_QuadraticMesh.hxx // Module : SMESH - +// #ifndef _StdMeshers_QuadraticMesh_HXX_ #define _StdMeshers_QuadraticMesh_HXX_ diff --git a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx index b19f79aee..6ae4ac787 100644 --- a/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx +++ b/src/StdMeshers/StdMeshers_RadialPrism_3D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_RadialPrism_3D.cxx // Module : SMESH @@ -37,7 +38,6 @@ #include "SMESHDS_SubMesh.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" @@ -46,10 +46,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -70,7 +72,7 @@ StdMeshers_RadialPrism_3D::StdMeshers_RadialPrism_3D(int hypId, int studyId, SME :SMESH_3D_Algo(hypId, studyId, gen) { _name = "RadialPrism_3D"; - _shapeType = (1 << TopAbs_SOLID); // 1 bit per shape type + _shapeType = (1 << TopAbs_SOLID); // 1 bit per shape type _compatibleHypothesis.push_back("LayerDistribution"); _compatibleHypothesis.push_back("NumberOfLayers"); @@ -170,12 +172,12 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not ")<ShapeToIndex( outFace )); } else { - inFace = TopoDS::Face( shape2ShapeMap( outFace )); + inFace = TopoDS::Face( shape2ShapeMap( outFace, /*isOut=*/true )); } // Find matching nodes of in and out faces @@ -387,3 +389,171 @@ bool StdMeshers_RadialPrism_3D::computeLayerPositions(const gp_Pnt& pIn, } RETURN_BAD_RESULT("Bad hypothesis"); } + + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + // get 2 shells + TopoDS_Solid solid = TopoDS::Solid( aShape ); + TopoDS_Shell outerShell = BRepTools::OuterShell( solid ); + TopoDS_Shape innerShell; + int nbShells = 0; + for ( TopoDS_Iterator It (solid); It.More(); It.Next(), ++nbShells ) + if ( !outerShell.IsSame( It.Value() )) + innerShell = It.Value(); + if ( nbShells != 2 ) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + + // Associate sub-shapes of the shells + TAssocTool::TShapeShapeMap shape2ShapeMap; + if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh, + innerShell, &aMesh, + shape2ShapeMap) ) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + + // get info for outer shell + int nb0d_Out=0, nb2d_3_Out=0, nb2d_4_Out=0; + //TopTools_SequenceOfShape FacesOut; + for (TopExp_Explorer exp(outerShell, TopAbs_FACE); exp.More(); exp.Next()) { + //FacesOut.Append(exp.Current()); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); + MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); + std::vector aVec = (*anIt).second; + nb0d_Out += aVec[SMDSEntity_Node]; + nb2d_3_Out += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + nb2d_4_Out += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + } + int nb1d_Out = 0; + TopTools_MapOfShape tmpMap; + for (TopExp_Explorer exp(outerShell, TopAbs_EDGE); exp.More(); exp.Next()) { + if( tmpMap.Contains( exp.Current() ) ) + continue; + tmpMap.Add( exp.Current() ); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); + MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); + std::vector aVec = (*anIt).second; + nb0d_Out += aVec[SMDSEntity_Node]; + nb1d_Out += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + } + tmpMap.Clear(); + for (TopExp_Explorer exp(outerShell, TopAbs_VERTEX); exp.More(); exp.Next()) { + if( tmpMap.Contains( exp.Current() ) ) + continue; + tmpMap.Add( exp.Current() ); + nb0d_Out++; + } + + // get info for inner shell + int nb0d_In=0, nb2d_3_In=0, nb2d_4_In=0; + //TopTools_SequenceOfShape FacesIn; + for (TopExp_Explorer exp(innerShell, TopAbs_FACE); exp.More(); exp.Next()) { + //FacesIn.Append(exp.Current()); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); + MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); + std::vector aVec = (*anIt).second; + nb0d_In += aVec[SMDSEntity_Node]; + nb2d_3_In += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + nb2d_4_In += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + } + int nb1d_In = 0; + tmpMap.Clear(); + bool IsQuadratic = false; + bool IsFirst = true; + for (TopExp_Explorer exp(innerShell, TopAbs_EDGE); exp.More(); exp.Next()) { + if( tmpMap.Contains( exp.Current() ) ) + continue; + tmpMap.Add( exp.Current() ); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); + MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); + std::vector aVec = (*anIt).second; + nb0d_In += aVec[SMDSEntity_Node]; + nb1d_In += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + if(IsFirst) { + IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); + IsFirst = false; + } + } + tmpMap.Clear(); + for (TopExp_Explorer exp(innerShell, TopAbs_VERTEX); exp.More(); exp.Next()) { + if( tmpMap.Contains( exp.Current() ) ) + continue; + tmpMap.Add( exp.Current() ); + nb0d_In++; + } + + bool IsOK = (nb0d_Out==nb0d_In) && (nb1d_Out==nb1d_In) && + (nb2d_3_Out==nb2d_3_In) && (nb2d_4_Out==nb2d_4_In); + if(!IsOK) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + + int nbLayers = 0; + if( myNbLayerHypo ) { + nbLayers = myNbLayerHypo->GetNumberOfLayers(); + } + if ( myDistributionHypo ) { + if ( !myDistributionHypo->GetLayerDistribution() ) { + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; iGetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + TopExp_Explorer exp(outerShell, TopAbs_VERTEX); + TopoDS_Vertex Vout = TopoDS::Vertex(exp.Current()); + TopoDS_Vertex Vin = TopoDS::Vertex( shape2ShapeMap(Vout) ); + if ( myLayerPositions.empty() ) { + gp_Pnt pIn = BRep_Tool::Pnt(Vin); + gp_Pnt pOut = BRep_Tool::Pnt(Vout); + computeLayerPositions( pIn, pOut ); + } + nbLayers = myLayerPositions.size() + 1; + } + + std::vector aResVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i TNodeColumn; diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx new file mode 100644 index 000000000..d93c64eb6 --- /dev/null +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -0,0 +1,1285 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_RadialQuadrangle_1D2D.cxx +// Module : SMESH +// Created : Fri Oct 20 11:37:07 2006 +// Author : Edward AGAPOV (eap) + +#include "StdMeshers_RadialQuadrangle_1D2D.hxx" + +#include "StdMeshers_NumberOfLayers.hxx" +#include "StdMeshers_LayerDistribution.hxx" +#include "StdMeshers_Regular_1D.hxx" +#include "StdMeshers_NumberOfSegments.hxx" + +#include "SMDS_MeshNode.hxx" +#include "SMESHDS_SubMesh.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_subMeshEventListener.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace std; + +#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; } +#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z()) + + +//======================================================================= +//function : StdMeshers_RadialQuadrangle_1D2D +//purpose : +//======================================================================= + +StdMeshers_RadialQuadrangle_1D2D::StdMeshers_RadialQuadrangle_1D2D(int hypId, + int studyId, + SMESH_Gen* gen) + :SMESH_2D_Algo(hypId, studyId, gen) +{ + _name = "RadialQuadrangle_1D2D"; + _shapeType = (1 << TopAbs_FACE); // 1 bit per shape type + + _compatibleHypothesis.push_back("LayerDistribution2D"); + _compatibleHypothesis.push_back("NumberOfLayers2D"); + myNbLayerHypo = 0; + myDistributionHypo = 0; + _requireDiscreteBoundary = false; + _supportSubmeshes = true; +} + + +//================================================================================ +/*! + * \brief Destructor + */ +//================================================================================ + +StdMeshers_RadialQuadrangle_1D2D::~StdMeshers_RadialQuadrangle_1D2D() +{} + + +//======================================================================= +//function : CheckHypothesis +//purpose : +//======================================================================= + +bool StdMeshers_RadialQuadrangle_1D2D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + // check aShape + myNbLayerHypo = 0; + myDistributionHypo = 0; + + list ::const_iterator itl; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + if ( hyps.size() == 0 ) { + aStatus = SMESH_Hypothesis::HYP_OK; + return true; // can work with no hypothesis + } + + if ( hyps.size() > 1 ) { + aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST; + return false; + } + + const SMESHDS_Hypothesis *theHyp = hyps.front(); + + string hypName = theHyp->GetName(); + + if (hypName == "NumberOfLayers2D") { + myNbLayerHypo = static_cast(theHyp); + aStatus = SMESH_Hypothesis::HYP_OK; + return true; + } + if (hypName == "LayerDistribution2D") { + myDistributionHypo = static_cast(theHyp); + aStatus = SMESH_Hypothesis::HYP_OK; + return true; + } + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + return true; +} + +namespace +{ + // ------------------------------------------------------------------------------ + /*! + * \brief Listener used to mark edges meshed by StdMeshers_RadialQuadrangle_1D2D + */ + class TEdgeMarker : public SMESH_subMeshEventListener + { + TEdgeMarker(): SMESH_subMeshEventListener(/*isDeletable=*/false, + "StdMeshers_RadialQuadrangle_1D2D::TEdgeMarker") {} + public: + //!< Return static listener + static SMESH_subMeshEventListener* getListener() + { + static TEdgeMarker theEdgeMarker; + return &theEdgeMarker; + } + //! Clear face sumbesh if something happens on edges + void ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* edgeSubMesh, + EventListenerData* data, + const SMESH_Hypothesis* /*hyp*/) + { + if ( data && !data->mySubMeshes.empty() && eventType == SMESH_subMesh::ALGO_EVENT) + { + ASSERT( data->mySubMeshes.front() != edgeSubMesh ); + SMESH_subMesh* faceSubMesh = data->mySubMeshes.front(); + faceSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN ); + } + } + }; + + // ------------------------------------------------------------------------------ + /*! + * \brief Mark an edge as computed by StdMeshers_RadialQuadrangle_1D2D + */ + void markEdgeAsComputedByMe(const TopoDS_Edge& edge, SMESH_subMesh* faceSubMesh) + { + if ( SMESH_subMesh* edgeSM = faceSubMesh->GetFather()->GetSubMeshContaining( edge )) + { + if ( !edgeSM->GetEventListenerData( TEdgeMarker::getListener() )) + faceSubMesh->SetEventListener( TEdgeMarker::getListener(), + SMESH_subMeshEventListenerData::MakeData(faceSubMesh), + edgeSM); + } + } + // ------------------------------------------------------------------------------ + /*! + * \brief Return true if a radial edge was meshed with StdMeshers_RadialQuadrangle_1D2D with + * the same radial distribution + */ +// bool isEdgeCompatiballyMeshed(const TopoDS_Edge& edge, SMESH_subMesh* faceSubMesh) +// { +// if ( SMESH_subMesh* edgeSM = faceSubMesh->GetFather()->GetSubMeshContaining( edge )) +// { +// if ( SMESH_subMeshEventListenerData* otherFaceData = +// edgeSM->GetEventListenerData( TEdgeMarker::getListener() )) +// { +// // compare hypothesis aplied to two disk faces sharing radial edges +// SMESH_Mesh& mesh = *faceSubMesh->GetFather(); +// SMESH_Algo* radialQuadAlgo = mesh.GetGen()->GetAlgo(mesh, faceSubMesh->GetSubShape() ); +// SMESH_subMesh* otherFaceSubMesh = otherFaceData->mySubMeshes.front(); +// list hyps1 = +// radialQuadAlgo->GetUsedHypothesis( mesh, faceSubMesh->GetSubShape()); +// list hyps2 = +// radialQuadAlgo->GetUsedHypothesis( mesh, otherFaceSubMesh->GetSubShape()); +// if( hyps1.empty() && hyps2.empty() ) +// return true; // defaul hyps +// if ( hyps1.size() != hyps2.size() ) +// return false; +// return *hyps1.front() == *hyps2.front(); +// } +// } +// return false; +// } + + //================================================================================ + /*! + * \brief Return base curve of the edge and extremum parameters + */ + //================================================================================ + + Handle(Geom_Curve) getCurve(const TopoDS_Edge& edge, double* f=0, double* l=0) + { + Handle(Geom_Curve) C; + if ( !edge.IsNull() ) + { + double first = 0., last = 0.; + C = BRep_Tool::Curve(edge, first, last); + if ( !C.IsNull() ) + { + Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C); + while( !tc.IsNull() ) { + C = tc->BasisCurve(); + tc = Handle(Geom_TrimmedCurve)::DownCast(C); + } + if ( f ) *f = first; + if ( l ) *l = last; + } + } + return C; + } + + //================================================================================ + /*! + * \brief Return edges of the face + * \retval int - nb of edges + */ + //================================================================================ + + int analyseFace(const TopoDS_Shape& face, + TopoDS_Edge& CircEdge, + TopoDS_Edge& LinEdge1, + TopoDS_Edge& LinEdge2) + { + CircEdge.Nullify(); LinEdge1.Nullify(); LinEdge2.Nullify(); + int nbe = 0; + + for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next(), ++nbe ) + { + const TopoDS_Edge& E = TopoDS::Edge( exp.Current() ); + double f,l; + Handle(Geom_Curve) C = getCurve(E,&f,&l); + if ( !C.IsNull() ) + { + if ( C->IsKind( STANDARD_TYPE(Geom_Circle))) + { + if ( CircEdge.IsNull() ) + CircEdge = E; + else + return 0; + } + else if ( LinEdge1.IsNull() ) + LinEdge1 = E; + else + LinEdge2 = E; + } + } + return nbe; + } + +//================================================================================ +//================================================================================ +/*! + * \brief Class computing layers distribution using data of + * StdMeshers_LayerDistribution hypothesis + */ +//================================================================================ +//================================================================================ + +class TNodeDistributor: public StdMeshers_Regular_1D +{ + list myUsedHyps; +public: + // ----------------------------------------------------------------------------- + static TNodeDistributor* GetDistributor(SMESH_Mesh& aMesh) + { + const int myID = -1000; + map < int, SMESH_1D_Algo * > & algoMap = aMesh.GetGen()->_map1D_Algo; + map < int, SMESH_1D_Algo * >::iterator id_algo = algoMap.find( myID ); + if ( id_algo == algoMap.end() ) + return new TNodeDistributor( myID, 0, aMesh.GetGen() ); + return static_cast< TNodeDistributor* >( id_algo->second ); + } + // ----------------------------------------------------------------------------- + //! Computes distribution of nodes on a straight line ending at pIn and pOut + bool Compute( vector< double > & positions, + gp_Pnt pIn, + gp_Pnt pOut, + SMESH_Mesh& aMesh, + const SMESH_Hypothesis* hyp1d) + { + if ( !hyp1d ) return error( "Invalid LayerDistribution hypothesis"); + + double len = pIn.Distance( pOut ); + if ( len <= DBL_MIN ) return error("Too close points of inner and outer shells"); + + myUsedHyps.clear(); + myUsedHyps.push_back( hyp1d ); + + TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( pIn, pOut ); + SMESH_Hypothesis::Hypothesis_Status aStatus; + if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, edge, aStatus )) + return error( "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( aMesh, C3D, len, f, l, params, false )) + return error("StdMeshers_Regular_1D failed to compute layers distribution"); + + positions.clear(); + positions.reserve( params.size() ); + for (list::iterator itU = params.begin(); itU != params.end(); itU++) + positions.push_back( *itU / len ); + return true; + } + // ----------------------------------------------------------------------------- + //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments + bool ComputeCircularEdge(SMESH_Mesh& aMesh, + const TopoDS_Edge& anEdge) + { + _gen->Compute( aMesh, anEdge); + SMESH_subMesh *sm = aMesh.GetSubMesh(anEdge); + if ( sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK) + { + // find any 1d hyp assigned (there can be a hyp w/o algo) + myUsedHyps = SMESH_Algo::GetUsedHypothesis(aMesh, anEdge, /*ignoreAux=*/true); + Hypothesis_Status aStatus; + if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, anEdge, aStatus )) + { + // no valid 1d hyp assigned, use default nb of segments + _hypType = NB_SEGMENTS; + _ivalue[ DISTR_TYPE_IND ] = StdMeshers_NumberOfSegments::DT_Regular; + _ivalue[ NB_SEGMENTS_IND ] = _gen->GetDefaultNbSegments(); + } + return StdMeshers_Regular_1D::Compute( aMesh, anEdge ); + } + return true; + } + // ----------------------------------------------------------------------------- + //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments + bool EvaluateCircularEdge(SMESH_Mesh& aMesh, + const TopoDS_Edge& anEdge, + MapShapeNbElems& aResMap) + { + _gen->Evaluate( aMesh, anEdge, aResMap ); + if ( aResMap.count( aMesh.GetSubMesh( anEdge ))) + return true; + + // find any 1d hyp assigned + myUsedHyps = SMESH_Algo::GetUsedHypothesis(aMesh, anEdge, /*ignoreAux=*/true); + Hypothesis_Status aStatus; + if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, anEdge, aStatus )) + { + // no valid 1d hyp assigned, use default nb of segments + _hypType = NB_SEGMENTS; + _ivalue[ DISTR_TYPE_IND ] = StdMeshers_NumberOfSegments::DT_Regular; + _ivalue[ NB_SEGMENTS_IND ] = _gen->GetDefaultNbSegments(); + } + return StdMeshers_Regular_1D::Evaluate( aMesh, anEdge, aResMap ); + } +protected: + // ----------------------------------------------------------------------------- + TNodeDistributor( int hypId, int studyId, SMESH_Gen* gen) + : StdMeshers_Regular_1D( hypId, studyId, gen) + { + } + // ----------------------------------------------------------------------------- + virtual const list & + GetUsedHypothesis(SMESH_Mesh &, const TopoDS_Shape &, const bool) + { + return myUsedHyps; + } + // ----------------------------------------------------------------------------- +}; +} + +//======================================================================= +/*! + * \brief Allow algo to do something after persistent restoration + * \param subMesh - restored submesh + * + * call markEdgeAsComputedByMe() + */ +//======================================================================= + +void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMesh) +{ + if ( !faceSubMesh->IsEmpty() ) + { + TopoDS_Edge CircEdge, LinEdge1, LinEdge2; + analyseFace( faceSubMesh->GetSubShape(), CircEdge, LinEdge1, LinEdge2 ); + if ( !CircEdge.IsNull() ) markEdgeAsComputedByMe( CircEdge, faceSubMesh ); + if ( !LinEdge1.IsNull() ) markEdgeAsComputedByMe( LinEdge1, faceSubMesh ); + if ( !LinEdge2.IsNull() ) markEdgeAsComputedByMe( LinEdge2, faceSubMesh ); + } +} + +//======================================================================= +//function : Compute +//purpose : +//======================================================================= + +bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + + myHelper = new SMESH_MesherHelper( aMesh ); + myHelper->IsQuadraticSubMesh( aShape ); + // to delete helper at exit from Compute() + auto_ptr helperDeleter( myHelper ); + + TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh); + + TopoDS_Edge CircEdge, LinEdge1, LinEdge2; + int nbe = analyseFace( aShape, CircEdge, LinEdge1, LinEdge2 ); + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); + if( nbe>3 || nbe < 1 || aCirc.IsNull() ) + return error("The face must be a full circle or a part of circle (i.e. the number of edges is less or equal to 3 and one of them is a circle curve)"); + + gp_Pnt P0, P1; + // points for rotation + TColgp_SequenceOfPnt Points; + // angles for rotation + TColStd_SequenceOfReal Angles; + // Nodes1 and Nodes2 - nodes along radiuses + // CNodes - nodes on circle edge + vector< const SMDS_MeshNode* > Nodes1, Nodes2, CNodes; + SMDS_MeshNode * NC; + // parameters edge nodes on face + TColgp_SequenceOfPnt2d Pnts2d1; + gp_Pnt2d PC; + + int faceID = meshDS->ShapeToIndex(aShape); + TopoDS_Face F = TopoDS::Face(aShape); + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + + + if(nbe==1) + { + if (!algo1d->ComputeCircularEdge( aMesh, CircEdge )) + return error( algo1d->GetComputeError() ); + map< double, const SMDS_MeshNode* > theNodes; + if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes)) + return error("Circular edge is incorrectly meshed"); + + CNodes.clear(); + map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin(); + const SMDS_MeshNode* NF = (*itn).second; + CNodes.push_back( (*itn).second ); + double fang = (*itn).first; + if ( itn != theNodes.end() ) { + itn++; + for(; itn != theNodes.end(); itn++ ) { + CNodes.push_back( (*itn).second ); + double ang = (*itn).first - fang; + if( ang>M_PI ) ang = ang - 2.*M_PI; + if( ang<-M_PI ) ang = ang + 2.*M_PI; + Angles.Append( ang ); + } + } + P1 = gp_Pnt( NF->X(), NF->Y(), NF->Z() ); + P0 = aCirc->Location(); + + if ( !computeLayerPositions(P0,P1)) + return false; + + TopoDS_Vertex V1 = myHelper->IthVertex(0, CircEdge ); + gp_Pnt2d p2dV = BRep_Tool::Parameters( V1, TopoDS::Face(aShape) ); + + NC = meshDS->AddNode(P0.X(), P0.Y(), P0.Z()); + GeomAPI_ProjectPointOnSurf PPS(P0,S); + double U0,V0; + PPS.Parameters(1,U0,V0); + meshDS->SetNodeOnFace(NC, faceID, U0, V0); + PC = gp_Pnt2d(U0,V0); + + gp_Vec aVec(P0,P1); + gp_Vec2d aVec2d(PC,p2dV); + Nodes1.resize( myLayerPositions.size()+1 ); + Nodes2.resize( myLayerPositions.size()+1 ); + int i = 0; + for(; iAddNode(P.X(), P.Y(), P.Z()); + Nodes1[i] = node; + Nodes2[i] = node; + double U = PC.X() + aVec2d.X()*myLayerPositions[i]; + double V = PC.Y() + aVec2d.Y()*myLayerPositions[i]; + meshDS->SetNodeOnFace( node, faceID, U, V ); + Pnts2d1.Append(gp_Pnt2d(U,V)); + } + Nodes1[Nodes1.size()-1] = NF; + Nodes2[Nodes1.size()-1] = NF; + } + else if(nbe==2 && LinEdge1.Orientation() != TopAbs_INTERNAL ) + { + // one curve must be a half of circle and other curve must be + // a segment of line + double fp, lp; + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge, &fp, &lp )); + if( fabs(fabs(lp-fp)-M_PI) > Precision::Confusion() ) { + // not half of circle + return error(COMPERR_BAD_SHAPE); + } + Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 )); + if( aLine.IsNull() ) { + // other curve not line + return error(COMPERR_BAD_SHAPE); + } + + if ( !algo1d->ComputeCircularEdge( aMesh, CircEdge )) + return error( algo1d->GetComputeError() ); + map< double, const SMDS_MeshNode* > theNodes; + if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes) ) + return error("Circular edge is incorrectly meshed"); + + map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin(); + CNodes.clear(); + CNodes.push_back( itn->second ); + double fang = (*itn).first; + itn++; + for(; itn != theNodes.end(); itn++ ) { + CNodes.push_back( (*itn).second ); + double ang = (*itn).first - fang; + if( ang>M_PI ) ang = ang - 2.*M_PI; + if( ang<-M_PI ) ang = ang + 2.*M_PI; + Angles.Append( ang ); + } + const SMDS_MeshNode* NF = theNodes.begin()->second; + const SMDS_MeshNode* NL = theNodes.rbegin()->second; + P1 = gp_Pnt( NF->X(), NF->Y(), NF->Z() ); + gp_Pnt P2( NL->X(), NL->Y(), NL->Z() ); + P0 = aCirc->Location(); + + bool linEdgeComputed; + if ( !computeLayerPositions(P0,P1,LinEdge1,&linEdgeComputed)) + return false; + + if ( linEdgeComputed ) + { + if (!GetSortedNodesOnEdge(aMesh.GetMeshDS(),LinEdge1,true,theNodes)) + return error("Invalid mesh on a straight edge"); + + Nodes1.resize( myLayerPositions.size()+1 ); + Nodes2.resize( myLayerPositions.size()+1 ); + vector< const SMDS_MeshNode* > *pNodes1 = &Nodes1, *pNodes2 = &Nodes2; + bool nodesFromP0ToP1 = ( theNodes.rbegin()->second == NF ); + if ( !nodesFromP0ToP1 ) std::swap( pNodes1, pNodes2 ); + + map< double, const SMDS_MeshNode* >::reverse_iterator ritn = theNodes.rbegin(); + itn = theNodes.begin(); + for ( int i = Nodes1.size()-1; i > -1; ++itn, ++ritn, --i ) + { + (*pNodes1)[i] = ritn->second; + (*pNodes2)[i] = itn->second; + Points.Prepend( gpXYZ( Nodes1[i])); + Pnts2d1.Prepend( myHelper->GetNodeUV( F, Nodes1[i])); + } + NC = const_cast( itn->second ); + Points.Remove( Nodes1.size() ); + } + else + { + gp_Vec aVec(P0,P1); + int edgeID = meshDS->ShapeToIndex(LinEdge1); + // check orientation + Handle(Geom_Curve) Crv = BRep_Tool::Curve(LinEdge1,fp,lp); + gp_Pnt Ptmp; + Crv->D0(fp,Ptmp); + bool ori = true; + if( P1.Distance(Ptmp) > Precision::Confusion() ) + ori = false; + // get UV points for edge + gp_Pnt2d PF,PL; + BRep_Tool::UVPoints( LinEdge1, TopoDS::Face(aShape), PF, PL ); + PC = gp_Pnt2d( (PF.X()+PL.X())/2, (PF.Y()+PL.Y())/2 ); + gp_Vec2d V2d; + if(ori) V2d = gp_Vec2d(PC,PF); + else V2d = gp_Vec2d(PC,PL); + // add nodes on edge + double cp = (fp+lp)/2; + double dp2 = (lp-fp)/2; + NC = meshDS->AddNode(P0.X(), P0.Y(), P0.Z()); + meshDS->SetNodeOnEdge(NC, edgeID, cp); + Nodes1.resize( myLayerPositions.size()+1 ); + Nodes2.resize( myLayerPositions.size()+1 ); + int i = 0; + for(; iAddNode(P.X(), P.Y(), P.Z()); + Nodes1[i] = node; + double param; + if(ori) + param = fp + dp2*(1-myLayerPositions[i]); + else + param = cp + dp2*myLayerPositions[i]; + meshDS->SetNodeOnEdge(node, edgeID, param); + P = gp_Pnt( P0.X() - aVec.X()*myLayerPositions[i], + P0.Y() - aVec.Y()*myLayerPositions[i], + P0.Z() - aVec.Z()*myLayerPositions[i] ); + node = meshDS->AddNode(P.X(), P.Y(), P.Z()); + Nodes2[i] = node; + if(!ori) + param = fp + dp2*(1-myLayerPositions[i]); + else + param = cp + dp2*myLayerPositions[i]; + meshDS->SetNodeOnEdge(node, edgeID, param); + // parameters on face + gp_Pnt2d P2d( PC.X() + V2d.X()*myLayerPositions[i], + PC.Y() + V2d.Y()*myLayerPositions[i] ); + Pnts2d1.Append(P2d); + } + Nodes1[ myLayerPositions.size() ] = NF; + Nodes2[ myLayerPositions.size() ] = NL; + // create 1D elements on edge + vector< const SMDS_MeshNode* > tmpNodes; + tmpNodes.resize(2*Nodes1.size()+1); + for(i=0; iAddEdge( tmpNodes[i-1], tmpNodes[i] ); + if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); + } + markEdgeAsComputedByMe( LinEdge1, aMesh.GetSubMesh( F )); + } + } + else // nbe==3 or ( nbe==2 && linEdge is INTERNAL ) + { + if (nbe==2 && LinEdge1.Orientation() == TopAbs_INTERNAL ) + LinEdge2 = LinEdge1; + + // one curve must be a part of circle and other curves must be + // segments of line + double fp, lp; + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); + Handle(Geom_Line) aLine1 = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 )); + Handle(Geom_Line) aLine2 = Handle(Geom_Line)::DownCast( getCurve( LinEdge2 )); + if( aCirc.IsNull() || aLine1.IsNull() || aLine2.IsNull() ) + return error(COMPERR_BAD_SHAPE); + + if ( !algo1d->ComputeCircularEdge( aMesh, CircEdge )) + return error( algo1d->GetComputeError() ); + map< double, const SMDS_MeshNode* > theNodes; + if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes)) + return error("Circular edge is incorrectly meshed"); + + const SMDS_MeshNode* NF = theNodes.begin()->second; + const SMDS_MeshNode* NL = theNodes.rbegin()->second; + CNodes.clear(); + CNodes.push_back( NF ); + map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin(); + double fang = (*itn).first; + itn++; + for(; itn != theNodes.end(); itn++ ) { + CNodes.push_back( (*itn).second ); + double ang = (*itn).first - fang; + if( ang>M_PI ) ang = ang - 2.*M_PI; + if( ang<-M_PI ) ang = ang + 2.*M_PI; + Angles.Append( ang ); + } + P1 = gp_Pnt( NF->X(), NF->Y(), NF->Z() ); + gp_Pnt P2( NL->X(), NL->Y(), NL->Z() ); + P0 = aCirc->Location(); + + // make P1 belong to LinEdge1 + TopoDS_Vertex V1 = myHelper->IthVertex( 0, LinEdge1 ); + TopoDS_Vertex V2 = myHelper->IthVertex( 1, LinEdge1 ); + gp_Pnt PE1 = BRep_Tool::Pnt(V1); + gp_Pnt PE2 = BRep_Tool::Pnt(V2); + if( ( P1.Distance(PE1) > Precision::Confusion() ) && + ( P1.Distance(PE2) > Precision::Confusion() ) ) + std::swap( LinEdge1, LinEdge2 ); + + bool linEdge1Computed, linEdge2Computed; + if ( !computeLayerPositions(P0,P1,LinEdge1,&linEdge1Computed)) + return false; + + Nodes1.resize( myLayerPositions.size()+1 ); + Nodes2.resize( myLayerPositions.size()+1 ); + + // check that both linear edges have same hypotheses + if ( !computeLayerPositions(P0,P2,LinEdge2, &linEdge2Computed)) + return false; + if ( Nodes1.size() != myLayerPositions.size()+1 ) + return error("Different hypotheses apply to radial edges"); + + // find the central vertex + TopoDS_Vertex VC = V2; + if( ( P1.Distance(PE1) > Precision::Confusion() ) && + ( P2.Distance(PE1) > Precision::Confusion() ) ) + VC = V1; + int vertID = meshDS->ShapeToIndex(VC); + + // LinEdge1 + if ( linEdge1Computed ) + { + if (!GetSortedNodesOnEdge(aMesh.GetMeshDS(),LinEdge1,true,theNodes)) + return error("Invalid mesh on a straight edge"); + + bool nodesFromP0ToP1 = ( theNodes.rbegin()->second == NF ); + NC = const_cast + ( nodesFromP0ToP1 ? theNodes.begin()->second : theNodes.rbegin()->second ); + int i = 0, ir = Nodes1.size()-1; + int * pi = nodesFromP0ToP1 ? &i : &ir; + itn = theNodes.begin(); + if ( nodesFromP0ToP1 ) ++itn; + for ( ; i < Nodes1.size(); ++i, --ir, ++itn ) + { + Nodes1[*pi] = itn->second; + } + for ( i = 0; i < Nodes1.size()-1; ++i ) + { + Points.Append( gpXYZ( Nodes1[i])); + Pnts2d1.Append( myHelper->GetNodeUV( F, Nodes1[i])); + } + } + else + { + int edgeID = meshDS->ShapeToIndex(LinEdge1); + gp_Vec aVec(P0,P1); + // check orientation + Handle(Geom_Curve) Crv = BRep_Tool::Curve(LinEdge1,fp,lp); + gp_Pnt Ptmp = Crv->Value(fp); + bool ori = false; + if( P1.Distance(Ptmp) > Precision::Confusion() ) + ori = true; + // get UV points for edge + gp_Pnt2d PF,PL; + BRep_Tool::UVPoints( LinEdge1, TopoDS::Face(aShape), PF, PL ); + gp_Vec2d V2d; + if(ori) { + V2d = gp_Vec2d(PF,PL); + PC = PF; + } + else { + V2d = gp_Vec2d(PL,PF); + PC = PL; + } + NC = const_cast( VertexNode( VC, meshDS )); + if ( !NC ) + { + NC = meshDS->AddNode(P0.X(), P0.Y(), P0.Z()); + meshDS->SetNodeOnVertex(NC, vertID); + } + double dp = lp-fp; + int i = 0; + for(; iAddNode(P.X(), P.Y(), P.Z()); + Nodes1[i] = node; + double param; + if(!ori) + param = fp + dp*(1-myLayerPositions[i]); + else + param = fp + dp*myLayerPositions[i]; + meshDS->SetNodeOnEdge(node, edgeID, param); + // parameters on face + gp_Pnt2d P2d( PC.X() + V2d.X()*myLayerPositions[i], + PC.Y() + V2d.Y()*myLayerPositions[i] ); + Pnts2d1.Append(P2d); + } + Nodes1[ myLayerPositions.size() ] = NF; + // create 1D elements on edge + SMDS_MeshEdge* ME = myHelper->AddEdge( NC, Nodes1[0] ); + if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); + for(i=1; iAddEdge( Nodes1[i-1], Nodes1[i] ); + if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); + } + if (nbe==2 && LinEdge1.Orientation() == TopAbs_INTERNAL ) + Nodes2 = Nodes1; + } + markEdgeAsComputedByMe( LinEdge1, aMesh.GetSubMesh( F )); + + // LinEdge2 + if ( linEdge2Computed ) + { + if (!GetSortedNodesOnEdge(aMesh.GetMeshDS(),LinEdge2,true,theNodes)) + return error("Invalid mesh on a straight edge"); + + bool nodesFromP0ToP2 = ( theNodes.rbegin()->second == NL ); + int i = 0, ir = Nodes1.size()-1; + int * pi = nodesFromP0ToP2 ? &i : &ir; + itn = theNodes.begin(); + if ( nodesFromP0ToP2 ) ++itn; + for ( ; i < Nodes2.size(); ++i, --ir, ++itn ) + Nodes2[*pi] = itn->second; + } + else + { + int edgeID = meshDS->ShapeToIndex(LinEdge2); + gp_Vec aVec = gp_Vec(P0,P2); + // check orientation + Handle(Geom_Curve) Crv = BRep_Tool::Curve(LinEdge2,fp,lp); + gp_Pnt Ptmp = Crv->Value(fp); + bool ori = false; + if( P2.Distance(Ptmp) > Precision::Confusion() ) + ori = true; + // get UV points for edge + gp_Pnt2d PF,PL; + BRep_Tool::UVPoints( LinEdge2, TopoDS::Face(aShape), PF, PL ); + gp_Vec2d V2d; + if(ori) { + V2d = gp_Vec2d(PF,PL); + PC = PF; + } + else { + V2d = gp_Vec2d(PL,PF); + PC = PL; + } + double dp = lp-fp; + for(int i=0; iAddNode(P.X(), P.Y(), P.Z()); + Nodes2[i] = node; + double param; + if(!ori) + param = fp + dp*(1-myLayerPositions[i]); + else + param = fp + dp*myLayerPositions[i]; + meshDS->SetNodeOnEdge(node, edgeID, param); + // parameters on face + gp_Pnt2d P2d( PC.X() + V2d.X()*myLayerPositions[i], + PC.Y() + V2d.Y()*myLayerPositions[i] ); + } + Nodes2[ myLayerPositions.size() ] = NL; + // create 1D elements on edge + SMDS_MeshEdge* ME = myHelper->AddEdge( NC, Nodes2[0] ); + if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); + for(int i=1; iAddEdge( Nodes2[i-1], Nodes2[i] ); + if(ME) meshDS->SetMeshElementOnShape(ME, edgeID); + } + } + markEdgeAsComputedByMe( LinEdge2, aMesh.GetSubMesh( F )); + } + markEdgeAsComputedByMe( CircEdge, aMesh.GetSubMesh( F )); + + // orientation + bool IsForward = ( CircEdge.Orientation()==TopAbs_FORWARD ); + + // create nodes and mesh elements on face + // find axis of rotation + gp_Pnt P2 = gp_Pnt( CNodes[1]->X(), CNodes[1]->Y(), CNodes[1]->Z() ); + gp_Vec Vec1(P0,P1); + gp_Vec Vec2(P0,P2); + gp_Vec Axis = Vec1.Crossed(Vec2); + // create elements + int i = 1; + //cout<<"Angles.Length() = "<& aResVec = + aResMap.insert( make_pair(sm, vector(SMDSEntity_Last,0))).first->second; + + myHelper = new SMESH_MesherHelper( aMesh ); + myHelper->SetSubShape( aShape ); + auto_ptr helperDeleter( myHelper ); + + TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh); + + TopoDS_Edge CircEdge, LinEdge1, LinEdge2; + int nbe = analyseFace( aShape, CircEdge, LinEdge1, LinEdge2 ); + if( nbe>3 || nbe < 1 || CircEdge.IsNull() ) + return false; + + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge )); + if( aCirc.IsNull() ) + return error(COMPERR_BAD_SHAPE); + + gp_Pnt P0 = aCirc->Location(); + gp_Pnt P1 = aCirc->Value(0.); + computeLayerPositions( P0, P1, LinEdge1 ); + + int nb0d=0, nb2d_tria=0, nb2d_quad=0; + bool isQuadratic = false, ok = true; + if(nbe==1) + { + // C1 must be a circle + ok = algo1d->EvaluateCircularEdge( aMesh, CircEdge, aResMap ); + if(ok) { + const vector& aVec = aResMap[aMesh.GetSubMesh(CircEdge)]; + isQuadratic = aVec[SMDSEntity_Quad_Edge]>aVec[SMDSEntity_Edge]; + if(isQuadratic) { + // main nodes + nb0d = (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); + // radial medium nodes + nb0d += (aVec[SMDSEntity_Node]+1) * (myLayerPositions.size()+1); + // other medium nodes + nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); + } + else { + nb0d = (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); + } + nb2d_tria = aVec[SMDSEntity_Node] + 1; + nb2d_quad = nb0d; + } + } + else if(nbe==2 && LinEdge1.Orientation() != TopAbs_INTERNAL) + { + // one curve must be a half of circle and other curve must be + // a segment of line + double fp, lp; + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge, &fp, &lp )); + if( fabs(fabs(lp-fp)-M_PI) > Precision::Confusion() ) { + // not half of circle + return error(COMPERR_BAD_SHAPE); + } + Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 )); + if( aLine.IsNull() ) { + // other curve not line + return error(COMPERR_BAD_SHAPE); + } + ok = !aResMap.count( aMesh.GetSubMesh(LinEdge1) ); + if ( !ok ) { + const vector& aVec = aResMap[ aMesh.GetSubMesh(LinEdge1) ]; + ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() ); + } + if(ok) { + ok = algo1d->EvaluateCircularEdge( aMesh, CircEdge, aResMap ); + } + if(ok) { + const vector& aVec = aResMap[ aMesh.GetSubMesh(CircEdge) ]; + isQuadratic = aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]; + if(isQuadratic) { + // main nodes + nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); + // radial medium nodes + nb0d += aVec[SMDSEntity_Node] * (myLayerPositions.size()+1); + // other medium nodes + nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); + } + else { + nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); + } + nb2d_tria = aVec[SMDSEntity_Node] + 1; + nb2d_quad = nb2d_tria * myLayerPositions.size(); + // add evaluation for edges + vector aResVec(SMDSEntity_Last,0); + if(isQuadratic) { + aResVec[SMDSEntity_Node] = 4*myLayerPositions.size() + 3; + aResVec[SMDSEntity_Quad_Edge] = 2*myLayerPositions.size() + 2; + } + else { + aResVec[SMDSEntity_Node] = 2*myLayerPositions.size() + 1; + aResVec[SMDSEntity_Edge] = 2*myLayerPositions.size() + 2; + } + aResMap[ aMesh.GetSubMesh(LinEdge1) ] = aResVec; + } + } + else // nbe==3 or ( nbe==2 && linEdge is INTERNAL ) + { + if (nbe==2 && LinEdge1.Orientation() == TopAbs_INTERNAL ) + LinEdge2 = LinEdge1; + + // one curve must be a part of circle and other curves must be + // segments of line + Handle(Geom_Line) aLine1 = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 )); + Handle(Geom_Line) aLine2 = Handle(Geom_Line)::DownCast( getCurve( LinEdge2 )); + if( aLine1.IsNull() || aLine2.IsNull() ) { + // other curve not line + return error(COMPERR_BAD_SHAPE); + } + int nbLayers = myLayerPositions.size(); + computeLayerPositions( P0, P1, LinEdge2 ); + if ( nbLayers != myLayerPositions.size() ) + return error("Different hypotheses apply to radial edges"); + + bool ok = !aResMap.count( aMesh.GetSubMesh(LinEdge1)); + if ( !ok ) { + if ( myDistributionHypo || myNbLayerHypo ) + ok = true; // override other 1d hyps + else { + const vector& aVec = aResMap[ aMesh.GetSubMesh(LinEdge1) ]; + ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() ); + } + } + if( ok && aResMap.count( aMesh.GetSubMesh(LinEdge2) )) { + if ( myDistributionHypo || myNbLayerHypo ) + ok = true; // override other 1d hyps + else { + const vector& aVec = aResMap[ aMesh.GetSubMesh(LinEdge2) ]; + ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() ); + } + } + if(ok) { + ok = algo1d->EvaluateCircularEdge( aMesh, CircEdge, aResMap ); + } + if(ok) { + const vector& aVec = aResMap[ aMesh.GetSubMesh(CircEdge) ]; + isQuadratic = aVec[SMDSEntity_Quad_Edge]>aVec[SMDSEntity_Edge]; + if(isQuadratic) { + // main nodes + nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); + // radial medium nodes + nb0d += aVec[SMDSEntity_Node] * (myLayerPositions.size()+1); + // other medium nodes + nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); + } + else { + nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); + } + nb2d_tria = aVec[SMDSEntity_Node] + 1; + nb2d_quad = nb2d_tria * myLayerPositions.size(); + // add evaluation for edges + vector aResVec(SMDSEntity_Last, 0); + if(isQuadratic) { + aResVec[SMDSEntity_Node] = 2*myLayerPositions.size() + 1; + aResVec[SMDSEntity_Quad_Edge] = myLayerPositions.size() + 1; + } + else { + aResVec[SMDSEntity_Node] = myLayerPositions.size(); + aResVec[SMDSEntity_Edge] = myLayerPositions.size() + 1; + } + sm = aMesh.GetSubMesh(LinEdge1); + aResMap[sm] = aResVec; + sm = aMesh.GetSubMesh(LinEdge2); + aResMap[sm] = aResVec; + } + } + + if(nb0d>0) { + aResVec[0] = nb0d; + if(isQuadratic) { + aResVec[SMDSEntity_Quad_Triangle] = nb2d_tria; + aResVec[SMDSEntity_Quad_Quadrangle] = nb2d_quad; + } + else { + aResVec[SMDSEntity_Triangle] = nb2d_tria; + aResVec[SMDSEntity_Quadrangle] = nb2d_quad; + } + return true; + } + + // invalid case + sm = aMesh.GetSubMesh(aShape); + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED, + "Submesh can not be evaluated",this)); + return false; + +} diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx new file mode 100644 index 000000000..b68ebe930 --- /dev/null +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx @@ -0,0 +1,76 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_RadialQuadrangle_1D2D.hxx +// Module : SMESH +// +#ifndef _SMESH_RadialQuadrangle_1D2D_HXX_ +#define _SMESH_RadialQuadrangle_1D2D_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_2D_Algo.hxx" + +#include + +#include + +class StdMeshers_NumberOfLayers; +class StdMeshers_LayerDistribution; +class SMESH_MesherHelper; +class gp_Pnt; + +class STDMESHERS_EXPORT StdMeshers_RadialQuadrangle_1D2D: public SMESH_2D_Algo +{ +public: + StdMeshers_RadialQuadrangle_1D2D(int hypId, int studyId, SMESH_Gen* gen); + virtual ~StdMeshers_RadialQuadrangle_1D2D(); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + /*! + * \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); + +protected: + + bool computeLayerPositions(const gp_Pnt& p1, + const gp_Pnt& p2, + const TopoDS_Edge& linEdge=TopoDS_Edge(), + bool* linEdgeComputed = 0); + + + const StdMeshers_NumberOfLayers* myNbLayerHypo; + const StdMeshers_LayerDistribution* myDistributionHypo; + SMESH_MesherHelper* myHelper; + std::vector< double > myLayerPositions; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index ee4aa86e7..8d900955d 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions + // File : StdMeshers_Regular_1D.cxx // Moved here from SMESH_Regular_1D.cxx // Author : Paul RASCLE, EDF // Module : SMESH - +// #include "StdMeshers_Regular_1D.hxx" #include "StdMeshers_Distribution.hxx" @@ -61,8 +61,10 @@ #include #include #include +#include #include +#include using namespace std; @@ -73,22 +75,24 @@ using namespace std; //============================================================================= StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, - SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen) + SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen) { - MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D"); - _name = "Regular_1D"; - _shapeType = (1 << TopAbs_EDGE); - - _compatibleHypothesis.push_back("LocalLength"); - _compatibleHypothesis.push_back("MaxLength"); - _compatibleHypothesis.push_back("NumberOfSegments"); - _compatibleHypothesis.push_back("StartEndLength"); - _compatibleHypothesis.push_back("Deflection1D"); - _compatibleHypothesis.push_back("Arithmetic1D"); - _compatibleHypothesis.push_back("AutomaticLength"); - - _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!! - _compatibleHypothesis.push_back("Propagation"); // auxiliary !!! + MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D"); + _name = "Regular_1D"; + _shapeType = (1 << TopAbs_EDGE); + _fpHyp = 0; + + _compatibleHypothesis.push_back("LocalLength"); + _compatibleHypothesis.push_back("MaxLength"); + _compatibleHypothesis.push_back("NumberOfSegments"); + _compatibleHypothesis.push_back("StartEndLength"); + _compatibleHypothesis.push_back("Deflection1D"); + _compatibleHypothesis.push_back("Arithmetic1D"); + _compatibleHypothesis.push_back("FixedPoints1D"); + _compatibleHypothesis.push_back("AutomaticLength"); + + _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!! + _compatibleHypothesis.push_back("Propagation"); // auxiliary !!! } //============================================================================= @@ -115,9 +119,8 @@ bool StdMeshers_Regular_1D::CheckHypothesis _hypType = NONE; _quadraticMesh = false; - const bool ignoreAuxiliaryHyps = false; const list & hyps = - GetUsedHypothesis(aMesh, aShape, ignoreAuxiliaryHyps); + GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false); // find non-auxiliary hypothesis const SMESHDS_Hypothesis *theHyp = 0; @@ -180,12 +183,15 @@ bool StdMeshers_Regular_1D::CheckHypothesis { case StdMeshers_NumberOfSegments::DT_Scale: _value[ SCALE_FACTOR_IND ] = hyp->GetScaleFactor(); + _revEdgesIDs = hyp->GetReversedEdges(); break; case StdMeshers_NumberOfSegments::DT_TabFunc: _vvalue[ TAB_FUNC_IND ] = hyp->GetTableFunction(); + _revEdgesIDs = hyp->GetReversedEdges(); break; case StdMeshers_NumberOfSegments::DT_ExprFunc: _svalue[ EXPR_FUNC_IND ] = hyp->GetExpressionFunction(); + _revEdgesIDs = hyp->GetReversedEdges(); break; case StdMeshers_NumberOfSegments::DT_Regular: break; @@ -209,6 +215,19 @@ bool StdMeshers_Regular_1D::CheckHypothesis _value[ END_LENGTH_IND ] = hyp->GetLength( false ); ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 ); _hypType = ARITHMETIC_1D; + + _revEdgesIDs = hyp->GetReversedEdges(); + + aStatus = SMESH_Hypothesis::HYP_OK; + } + + else if (hypName == "FixedPoints1D") { + _fpHyp = dynamic_cast (theHyp); + ASSERT(_fpHyp); + _hypType = FIXED_POINTS_1D; + + _revEdgesIDs = _fpHyp->GetReversedEdges(); + aStatus = SMESH_Hypothesis::HYP_OK; } @@ -221,6 +240,9 @@ bool StdMeshers_Regular_1D::CheckHypothesis _value[ END_LENGTH_IND ] = hyp->GetLength( false ); ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 ); _hypType = BEG_END_LENGTH; + + _revEdgesIDs = hyp->GetReversedEdges(); + aStatus = SMESH_Hypothesis::HYP_OK; } @@ -303,6 +325,8 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last, return false; prevU = U; } + if ( theReverse ) + theParams.reverse(); return true; } @@ -352,10 +376,14 @@ static void compensateError(double a1, double an, } double q = dUn / ( nPar - 1 ); - if ( !adjustNeighbors2an ) { - for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) { + if ( !adjustNeighbors2an ) + { + q = dUn / ( Utgt - Un ); // (signed) factor of segment length change + for ( itU = theParams.rbegin(), i = 1; i < nPar; i++ ) { + double prevU = *itU; (*itU) += dUn; - dUn -= q; + ++itU; + dUn = q * (*itU - prevU) * (prevU-U1)/(Un-U1); } } else { @@ -602,7 +630,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, bool computed = sm->IsMeshComputed(); if (!computed) { if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { - sm->ComputeStateEngine(SMESH_subMesh::COMPUTE); + _gen->Compute( theMesh, _mainEdge, /*anUpward=*/true); computed = sm->IsMeshComputed(); } } @@ -659,6 +687,14 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, theParams.push_back( param ); } } + const double lenFactor = theLength/(l-f); + list::iterator u = theParams.begin(), uEnd = theParams.end(); + for ( ; u != uEnd; ++u ) + { + GCPnts_AbscissaPoint Discret( theC3d, ((*u)-f) * lenFactor, f ); + if ( Discret.IsDone() ) + *u = Discret.Parameter(); + } return true; } break; @@ -706,6 +742,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, double a1 = _value[ BEG_LENGTH_IND ]; double an = _value[ END_LENGTH_IND ]; double q = ( theLength - a1 ) / ( theLength - an ); + if ( q < theLength/1e6 || 1.01*theLength < a1 + an) + return error ( SMESH_Comment("Invalid segment lengths (")< numeric_limits::min() ? ( 1+( an-a1 )/q ) : ( 1+theLength/a1 )); double U1 = theReverse ? l : f; double Un = theReverse ? f : l; @@ -764,6 +806,107 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, return true; } + case FIXED_POINTS_1D: { + const std::vector& aPnts = _fpHyp->GetPoints(); + const std::vector& nbsegs = _fpHyp->GetNbSegments(); + int i = 0; + TColStd_SequenceOfReal Params; + for(; i0.9999 ) continue; + int j=1; + bool IsExist = false; + for(; j<=Params.Length(); j++) { + if( fabs(aPnts[i]-Params.Value(j)) < 1e-4 ) { + IsExist = true; + break; + } + if( aPnts[i] nbsegs.size()-1 ) ? nbsegs[0] : nbsegs[i]; + segmentSize = Params.Value(i+1)*theLength - currAbscissa; + currAbscissa += segmentSize; + GCPnts_AbscissaPoint APnt(theC3d, sign*segmentSize, par1); + if( !APnt.IsDone() ) + return error( "GCPnts_AbscissaPoint failed"); + par2 = APnt.Parameter(); + eltSize = segmentSize/nbseg; + GCPnts_UniformAbscissa Discret(theC3d, eltSize, par1, par2); + if(theReverse) + Discret.Initialize(theC3d, eltSize, par2, par1); + else + Discret.Initialize(theC3d, eltSize, par1, par2); + if ( !Discret.IsDone() ) + return error( "GCPnts_UniformAbscissa failed"); + int NbPoints = Discret.NbPoints(); + list tmpParams; + for(int i=2; i::iterator itP = tmpParams.begin(); + for(; itP != tmpParams.end(); itP++) { + theParams.push_back( *(itP) ); + } + theParams.push_back( par2 ); + + par1 = par2; + } + // add for last + int nbseg = ( nbsegs.size() > Params.Length() ) ? nbsegs[Params.Length()] : nbsegs[0]; + segmentSize = theLength - currAbscissa; + eltSize = segmentSize/nbseg; + GCPnts_UniformAbscissa Discret; + if(theReverse) + Discret.Initialize(theC3d, eltSize, par1, lp); + else + Discret.Initialize(theC3d, eltSize, lp, par1); + if ( !Discret.IsDone() ) + return error( "GCPnts_UniformAbscissa failed"); + int NbPoints = Discret.NbPoints(); + list tmpParams; + for(int i=2; i::iterator itP = tmpParams.begin(); + for(; itP != tmpParams.end(); itP++) { + theParams.push_back( *(itP) ); + } + + if (theReverse) { + theParams.reverse(); // NPAL18025 + } + return true; + } + case DEFLECTION: { GCPnts_UniformDeflection Discret(theC3d, _value[ DEFLECTION_IND ], f, l, true); @@ -815,12 +958,43 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t if (!idFirst || !idLast) return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); + // remove elements created by e.g. patern mapping (PAL21999) + // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp + // so TEMPORARY solution is to clean the submesh manually + //theMesh.GetSubMesh(theShape)->ComputeStateEngine( SMESH_subMesh::CLEAN ); + if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape)) + { + SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); + while (ite->more()) + meshDS->RemoveFreeElement(ite->next(), subMeshDS); + SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); + while (itn->more()) { + const SMDS_MeshNode * node = itn->next(); + if ( node->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode(node, subMeshDS); + else + meshDS->RemoveNode(node); + } + } + if (!Curve.IsNull()) { list< double > params; bool reversed = false; - if ( !_mainEdge.IsNull() ) + if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE ) { + // if the shape to mesh is WIRE or EDGE + reversed = ( EE.Orientation() == TopAbs_REVERSED ); + } + if ( !_mainEdge.IsNull() ) { + // take into account reversing the edge the hypothesis is propagated from reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED ); + int mainID = meshDS->ShapeToIndex(_mainEdge); + if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end()) + reversed = !reversed; + } + // take into account this edge reversing + if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), shapeID) != _revEdgesIDs.end()) + reversed = !reversed; BRepAdaptor_Curve C3d( E ); double length = EdgeLength( E ); @@ -845,7 +1019,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t parLast = f; } */ - for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; gp_Pnt P = Curve->Value(param); @@ -930,6 +1103,81 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t return true; } + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, + const TopoDS_Shape & theShape, + MapShapeNbElems& aResMap) +{ + if ( _hypType == NONE ) + return false; + + //SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); + + const TopoDS_Edge & EE = TopoDS::Edge(theShape); + TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD)); + // int shapeID = meshDS->ShapeToIndex( E ); + + double f, l; + Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l); + + TopoDS_Vertex VFirst, VLast; + TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l + + ASSERT(!VFirst.IsNull()); + ASSERT(!VLast.IsNull()); + + std::vector aVec(SMDSEntity_Last,0); + + if (!Curve.IsNull()) { + list< double > params; + + BRepAdaptor_Curve C3d( E ); + double length = EdgeLength( E ); + if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, false, true )) { + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(std::make_pair(sm,aVec)); + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast ); + + if(_quadraticMesh) { + aVec[SMDSEntity_Node] = 2*params.size() + 1; + aVec[SMDSEntity_Quad_Edge] = params.size() + 1; + } + else { + aVec[SMDSEntity_Node] = params.size(); + aVec[SMDSEntity_Edge] = params.size() + 1; + } + + } + else { + //MESSAGE("************* Degenerated edge! *****************"); + // Edge is a degenerated Edge : We put n = 5 points on the edge. + if(_quadraticMesh) { + aVec[SMDSEntity_Node] = 11; + aVec[SMDSEntity_Quad_Edge] = 6; + } + else { + aVec[SMDSEntity_Node] = 5; + aVec[SMDSEntity_Edge] = 6; + } + } + + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(std::make_pair(sm,aVec)); + + return true; +} + + //============================================================================= /*! * See comments in SMESH_Algo.cxx @@ -946,10 +1194,9 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, SMESH_HypoFilter auxiliaryFilter, compatibleFilter; auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() ); - const bool ignoreAux = true; - InitCompatibleHypoFilter( compatibleFilter, ignoreAux ); + InitCompatibleHypoFilter( compatibleFilter, /*ignoreAux=*/true ); - // get non-auxiliary assigned to aShape + // get non-auxiliary assigned directly to aShape int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false ); if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE) diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx index 7df8e4533..aed1064ab 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.hxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -1,30 +1,31 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Regular_1D.hxx // Moved here from SMESH_Regular_1D.hxx // Author : Paul RASCLE, EDF // Module : SMESH - +// #ifndef _SMESH_REGULAR_1D_HXX_ #define _SMESH_REGULAR_1D_HXX_ @@ -32,6 +33,8 @@ #include "SMESH_1D_Algo.hxx" +#include "StdMeshers_FixedPoints1D.hxx" + class Adaptor3d_Curve; class TopoDS_Vertex; class StdMeshers_SegmentLengthAroundVertex; @@ -47,7 +50,10 @@ public: SMESH_Hypothesis::Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); + + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); virtual const std::list & GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true); @@ -94,7 +100,7 @@ protected: StdMeshers_SegmentLengthAroundVertex* getVertexHyp(SMESH_Mesh & theMesh, const TopoDS_Vertex & theV); - enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, NONE }; + enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, FIXED_POINTS_1D, NONE }; enum ValueIndex { SCALE_FACTOR_IND = 0, @@ -120,10 +126,13 @@ protected: HypothesisType _hypType; + const StdMeshers_FixedPoints1D* _fpHyp; + double _value[2]; int _ivalue[3]; std::vector _vvalue[1]; std::string _svalue[1]; + std::vector _revEdgesIDs; // a source of propagated hypothesis, is set by CheckHypothesis() // always called before Compute() diff --git a/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx b/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx index 60ba2518d..1a6f14e18 100644 --- a/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx +++ b/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_SegmentAroundVertex_0D.cxx // Module : SMESH @@ -38,7 +39,7 @@ StdMeshers_SegmentAroundVertex_0D::StdMeshers_SegmentAroundVertex_0D { _name = "SegmentAroundVertex_0D"; // it is assigned to vertices but influence a state of EDGE submeshes - _shapeType = (1 << TopAbs_VERTEX); // 1 bit per shape type + _shapeType = (1 << TopAbs_VERTEX); // 1 bit per shape type _compatibleHypothesis.push_back("SegmentLengthAroundVertex"); } @@ -92,3 +93,18 @@ bool StdMeshers_SegmentAroundVertex_0D::Compute(SMESH_Mesh&, const TopoDS_Shape& // StdMeshers_SegmentLengthAroundVertex hypothesis return true; } + + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_SegmentAroundVertex_0D::Evaluate(SMESH_Mesh&, + const TopoDS_Shape&, + MapShapeNbElems&) +{ + // This algorithm exists in order just to enable assignation of + // StdMeshers_SegmentLengthAroundVertex hypothesis + return false; +} diff --git a/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx b/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx index 4054a715d..abb8ce2c6 100644 --- a/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx +++ b/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_SegmentAroundVertex_0D.hxx // Module : SMESH @@ -46,6 +47,8 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); }; #endif diff --git a/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx b/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx index f5540a88c..27f280f43 100644 --- a/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx +++ b/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_SegmentLengthAroundVertex.cxx // Module : SMESH - +// #include "StdMeshers_SegmentLengthAroundVertex.hxx" #include "SMESH_Mesh.hxx" @@ -30,7 +31,6 @@ #include "SMDS_MeshNode.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESHDS_SubMesh.hxx" -#include "SMESH_MeshEditor.hxx" #include "SMESH_MesherHelper.hxx" #include "utilities.h" diff --git a/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx b/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx index c7c54bbf6..ed196455a 100644 --- a/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx +++ b/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_SegmentLengthAroundVertex.hxx // Author : Paul RASCLE, EDF // Module : SMESH - +// #ifndef _SMESH_SegmentLengthAroundVertex_HXX_ #define _SMESH_SegmentLengthAroundVertex_HXX_ diff --git a/src/StdMeshers/StdMeshers_StartEndLength.cxx b/src/StdMeshers/StdMeshers_StartEndLength.cxx index 0beb6349a..46cee3f22 100644 --- a/src/StdMeshers/StdMeshers_StartEndLength.cxx +++ b/src/StdMeshers/StdMeshers_StartEndLength.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers_StartEndLength : implementaion of SMESH idl descriptions // File : StdMeshers_StartEndLength.cxx // Module : SMESH - +// #include "StdMeshers_StartEndLength.hxx" #include "SMESH_Algo.hxx" @@ -105,9 +106,33 @@ double StdMeshers_StartEndLength::GetLength(bool isStartLength) const */ //============================================================================= +void StdMeshers_StartEndLength::SetReversedEdges( std::vector& ids ) +{ + if ( ids != _edgeIDs ) { + _edgeIDs = ids; + + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= + ostream & StdMeshers_StartEndLength::SaveTo(ostream & save) { - save << _begLength << " " <<_endLength; + int listSize = _edgeIDs.size(); + save << _begLength << " " << _endLength << " " << listSize; + + if ( listSize > 0 ) { + for ( int i = 0; i < listSize; i++) { + save << " " << _edgeIDs[i]; + } + save << " " << _objEntry; + } + return save; } @@ -120,12 +145,25 @@ ostream & StdMeshers_StartEndLength::SaveTo(ostream & save) istream & StdMeshers_StartEndLength::LoadFrom(istream & load) { bool isOK = true; + int intVal; isOK = (load >> _begLength); if (!isOK) load.clear(ios::badbit | load.rdstate()); isOK = (load >> _endLength); + if (!isOK) load.clear(ios::badbit | load.rdstate()); + + isOK = (load >> intVal); + if (isOK && intVal > 0) { + _edgeIDs.reserve( intVal ); + for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) { + isOK = (load >> intVal); + if ( isOK ) _edgeIDs.push_back( intVal ); + } + isOK = (load >> _objEntry); + } + return load; } @@ -178,7 +216,7 @@ bool StdMeshers_StartEndLength::SetParametersByMesh(const SMESH_Mesh* theMesh, { const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( i )); Handle(Geom_Curve) C = BRep_Tool::Curve(edge, L, UMin, UMax); - GeomAdaptor_Curve AdaptCurve(C); + GeomAdaptor_Curve AdaptCurve(C, UMin, UMax); vector< double > params; SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS(); @@ -207,6 +245,6 @@ bool StdMeshers_StartEndLength::SetParametersByMesh(const SMESH_Mesh* theMesh, bool StdMeshers_StartEndLength::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*theMesh*/) { - return bool(_begLength = _endLength = dflts._elemLength ); + return (_begLength = _endLength = dflts._elemLength ); } diff --git a/src/StdMeshers/StdMeshers_StartEndLength.hxx b/src/StdMeshers/StdMeshers_StartEndLength.hxx index 00f228771..dc8781a7f 100644 --- a/src/StdMeshers/StdMeshers_StartEndLength.hxx +++ b/src/StdMeshers/StdMeshers_StartEndLength.hxx @@ -1,28 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of SMESH idl descriptions // File : StdMeshers_StartEndLength.hxx // Module : SMESH - +// #ifndef _STDMESHERS_STARTENDLENGTH_HXX_ #define _STDMESHERS_STARTENDLENGTH_HXX_ @@ -31,6 +32,8 @@ #include "SMESH_Hypothesis.hxx" #include "Utils_SALOME_Exception.hxx" +#include + class STDMESHERS_EXPORT StdMeshers_StartEndLength:public SMESH_Hypothesis { public: @@ -40,6 +43,14 @@ class STDMESHERS_EXPORT StdMeshers_StartEndLength:public SMESH_Hypothesis void SetLength(double length, bool isStartLength) throw(SALOME_Exception); double GetLength(bool isStartLength) const; + + void SetReversedEdges( std::vector& ids); + + const std::vector& GetReversedEdges() const { return _edgeIDs; } + + void SetObjectEntry( const char* entry ) { _objEntry = entry; } + + const char* GetObjectEntry() { return _objEntry.c_str(); } virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); @@ -63,6 +74,8 @@ class STDMESHERS_EXPORT StdMeshers_StartEndLength:public SMESH_Hypothesis protected: double _begLength, _endLength; + std::vector _edgeIDs; + std::string _objEntry; }; #endif diff --git a/src/StdMeshers/StdMeshers_TrianglePreference.cxx b/src/StdMeshers/StdMeshers_TrianglePreference.cxx deleted file mode 100644 index 331cd0d1c..000000000 --- a/src/StdMeshers/StdMeshers_TrianglePreference.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH StdMeshers_TrianglePreference -// File : StdMeshers_TrianglePreference.cxx -// Module : SMESH - -#include "StdMeshers_TrianglePreference.hxx" -#include "utilities.h" - -using namespace std; - -//============================================================================= -/*! - * - */ -//============================================================================= - -StdMeshers_TrianglePreference::StdMeshers_TrianglePreference(int hypId, - int studyId, - SMESH_Gen * gen) - :SMESH_Hypothesis(hypId, studyId, gen) -{ - _name = "TrianglePreference"; - _param_algo_dim = -2; // auxiliary used by StdMeshers_Quadrangle_2D -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -StdMeshers_TrianglePreference::~StdMeshers_TrianglePreference() -{ -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -ostream & StdMeshers_TrianglePreference::SaveTo(ostream & save) -{ - return save; -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -istream & StdMeshers_TrianglePreference::LoadFrom(istream & load) -{ - return load; -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -ostream & operator <<(ostream & save, StdMeshers_TrianglePreference & hyp) -{ - return hyp.SaveTo( save ); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -istream & operator >>(istream & load, StdMeshers_TrianglePreference & hyp) -{ - return hyp.LoadFrom( load ); -} -//================================================================================ -/*! - * \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 - */ -//================================================================================ - -bool StdMeshers_TrianglePreference::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/, - const TopoDS_Shape& /*theShape*/) -{ - return false; -} - -//================================================================================ -/*! - * \brief Initialize my parameter values by default parameters. - * \retval bool - true if parameter values have been successfully defined - */ -//================================================================================ - -bool StdMeshers_TrianglePreference::SetParametersByDefaults(const TDefaults& /*dflts*/, - const SMESH_Mesh* /*theMesh*/) -{ - return false; -} - diff --git a/src/StdMeshers/StdMeshers_TrianglePreference.hxx b/src/StdMeshers/StdMeshers_TrianglePreference.hxx deleted file mode 100644 index 34ec364a1..000000000 --- a/src/StdMeshers/StdMeshers_TrianglePreference.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SMESH StdMeshers : implementaion of SMESH idl descriptions -// File : StdMeshers_TrianglePreference.hxx -// Module : SMESH - -#ifndef _StdMeshers_TrianglePreference_HXX_ -#define _StdMeshers_TrianglePreference_HXX_ - -#include "SMESH_StdMeshers.hxx" - -#include "SMESH_Hypothesis.hxx" -#include "Utils_SALOME_Exception.hxx" - -/*! - * \brief Hypothesis for StdMeshers_Quadrangle_2D, forcing construction - * of triangles in the in a refinement area if the number of nodes - * on opposite edges is not the same. See Issue 16186. - */ -class STDMESHERS_EXPORT StdMeshers_TrianglePreference:public SMESH_Hypothesis -{ - public: - StdMeshers_TrianglePreference(int hypId, int studyId, SMESH_Gen * gen); - virtual ~ StdMeshers_TrianglePreference(); - - virtual std::ostream & SaveTo(std::ostream & save); - virtual std::istream & LoadFrom(std::istream & load); - friend std::ostream & operator <<(std::ostream & save, StdMeshers_TrianglePreference & hyp); - friend std::istream & operator >>(std::istream & load, StdMeshers_TrianglePreference & hyp); - - /*! - * \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 - */ - virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); - - /*! - * \brief Initialize my parameter values by default parameters. - * \retval bool - true if parameter values have been successfully defined - */ - virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); - -}; - -#endif diff --git a/src/StdMeshers/StdMeshers_UseExisting_1D2D.cxx b/src/StdMeshers/StdMeshers_UseExisting_1D2D.cxx index e44345af4..e93dfffaf 100644 --- a/src/StdMeshers/StdMeshers_UseExisting_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_UseExisting_1D2D.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_UseExisting_1D2D.cxx // Module : SMESH @@ -60,10 +58,27 @@ bool StdMeshers_UseExisting_1D::CheckHypothesis(SMESH_Mesh& , bool StdMeshers_UseExisting_1D::Compute(SMESH_Mesh&, const TopoDS_Shape&) { - // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode + // This algorithm exists to allow mesh generation by mesh + // edition functions in TUI mode return true; } + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_UseExisting_1D::Evaluate(SMESH_Mesh&, + const TopoDS_Shape&, + MapShapeNbElems&) +{ + // This algorithm exists to allow mesh generation by mesh + // edition functions in TUI mode + return false; +} + + //======================================================================= //function : StdMeshers_UseExisting_2D //purpose : @@ -97,6 +112,22 @@ bool StdMeshers_UseExisting_2D::CheckHypothesis(SMESH_Mesh& , bool StdMeshers_UseExisting_2D::Compute(SMESH_Mesh&, const TopoDS_Shape&) { - // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode + // This algorithm exists to allow mesh generation by mesh edition + // functions in TUI mode return true; } + + +//======================================================================= +//function : Evaluate +//purpose : +//======================================================================= + +bool StdMeshers_UseExisting_2D::Evaluate(SMESH_Mesh&, + const TopoDS_Shape&, + MapShapeNbElems&) +{ + // This algorithm exists to allow mesh generation by mesh edition + // functions in TUI mode + return false; +} diff --git a/src/StdMeshers/StdMeshers_UseExisting_1D2D.hxx b/src/StdMeshers/StdMeshers_UseExisting_1D2D.hxx index 6d5a5e495..23c64b5b9 100644 --- a/src/StdMeshers/StdMeshers_UseExisting_1D2D.hxx +++ b/src/StdMeshers/StdMeshers_UseExisting_1D2D.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_UseExisting_1D2D.hxx // Module : SMESH @@ -46,6 +44,8 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); }; class STDMESHERS_EXPORT StdMeshers_UseExisting_1D: public SMESH_1D_Algo @@ -59,6 +59,8 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); }; #endif diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx new file mode 100644 index 000000000..ddae235f7 --- /dev/null +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -0,0 +1,4483 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_ViscousLayers.cxx +// Created : Wed Dec 1 15:15:34 2010 +// Author : Edward AGAPOV (eap) + +#include "StdMeshers_ViscousLayers.hxx" + +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FaceOfNodes.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESHDS_Hypothesis.hxx" +#include "SMESH_Algo.hxx" +#include "SMESH_ComputeError.hxx" +#include "SMESH_ControlsDef.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_ProxyMesh.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_subMeshEventListener.hxx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +//#define __myDEBUG + +using namespace std; + +//================================================================================ +namespace VISCOUS +{ + typedef int TGeomID; + + enum UIndex { U_TGT = 1, U_SRC, LEN_TGT }; + + /*! + * \brief SMESH_ProxyMesh computed by _ViscousBuilder for a SOLID. + * It is stored in a SMESH_subMesh of the SOLID as SMESH_subMeshEventListenerData + */ + struct _MeshOfSolid : public SMESH_ProxyMesh, + public SMESH_subMeshEventListenerData + { + bool _n2nMapComputed; + + _MeshOfSolid( SMESH_Mesh* mesh) + :SMESH_subMeshEventListenerData( /*isDeletable=*/true),_n2nMapComputed(false) + { + SMESH_ProxyMesh::setMesh( *mesh ); + } + + // returns submesh for a geom face + SMESH_ProxyMesh::SubMesh* getFaceSubM(const TopoDS_Face& F, bool create=false) + { + TGeomID i = SMESH_ProxyMesh::shapeIndex(F); + return create ? SMESH_ProxyMesh::getProxySubMesh(i) : findProxySubMesh(i); + } + void setNode2Node(const SMDS_MeshNode* srcNode, + const SMDS_MeshNode* proxyNode, + const SMESH_ProxyMesh::SubMesh* subMesh) + { + SMESH_ProxyMesh::setNode2Node( srcNode,proxyNode,subMesh); + } + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Listener of events of 3D sub-meshes computed with viscous layers. + * It is used to clear an inferior dim sub-meshes modified by viscous layers + */ + class _SrinkShapeListener : SMESH_subMeshEventListener + { + _SrinkShapeListener() + : SMESH_subMeshEventListener(/*isDeletable=*/false, + "StdMeshers_ViscousLayers::_SrinkShapeListener") {} + static SMESH_subMeshEventListener* Get() { static _SrinkShapeListener l; return &l; } + public: + virtual void ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* solidSM, + SMESH_subMeshEventListenerData* data, + const SMESH_Hypothesis* hyp) + { + if ( SMESH_subMesh::COMPUTE_EVENT == eventType && solidSM->IsEmpty() && data ) + { + SMESH_subMeshEventListener::ProcessEvent(event,eventType,solidSM,data,hyp); + } + } + static void ToClearSubMeshWithSolid( SMESH_subMesh* sm, + const TopoDS_Shape& solid) + { + SMESH_subMesh* solidSM = sm->GetFather()->GetSubMesh( solid ); + SMESH_subMeshEventListenerData* data = solidSM->GetEventListenerData( Get()); + if ( data ) + { + if ( find( data->mySubMeshes.begin(), data->mySubMeshes.end(), sm ) == + data->mySubMeshes.end()) + data->mySubMeshes.push_back( sm ); + } + else + { + data = SMESH_subMeshEventListenerData::MakeData( /*dependent=*/sm ); + sm->SetEventListener( Get(), data, /*whereToListenTo=*/solidSM ); + } + } + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Listener of events of 3D sub-meshes computed with viscous layers. + * It is used to store data computed by _ViscousBuilder for a sub-mesh and to + * delete the data as soon as it has been used + */ + class _ViscousListener : SMESH_subMeshEventListener + { + _ViscousListener(): + SMESH_subMeshEventListener(/*isDeletable=*/false, + "StdMeshers_ViscousLayers::_ViscousListener") {} + static SMESH_subMeshEventListener* Get() { static _ViscousListener l; return &l; } + public: + virtual void ProcessEvent(const int event, + const int eventType, + SMESH_subMesh* subMesh, + SMESH_subMeshEventListenerData* data, + const SMESH_Hypothesis* hyp) + { + if ( SMESH_subMesh::COMPUTE_EVENT == eventType ) + { + // delete SMESH_ProxyMesh containing temporary faces + subMesh->DeleteEventListener( this ); + } + } + // Finds or creates proxy mesh of the solid + static _MeshOfSolid* GetSolidMesh(SMESH_Mesh* mesh, + const TopoDS_Shape& solid, + bool toCreate=false) + { + if ( !mesh ) return 0; + SMESH_subMesh* sm = mesh->GetSubMesh(solid); + _MeshOfSolid* data = (_MeshOfSolid*) sm->GetEventListenerData( Get() ); + if ( !data && toCreate ) + { + data = new _MeshOfSolid(mesh); + data->mySubMeshes.push_back( sm ); // to find SOLID by _MeshOfSolid + sm->SetEventListener( Get(), data, sm ); + } + return data; + } + // Removes proxy mesh of the solid + static void RemoveSolidMesh(SMESH_Mesh* mesh, const TopoDS_Shape& solid) + { + mesh->GetSubMesh(solid)->DeleteEventListener( _ViscousListener::Get() ); + } + }; + + //-------------------------------------------------------------------------------- + /*! + * \brief Simplex (triangle or tetrahedron) based on 1 (tria) or 2 (tet) nodes of + * _LayerEdge and 2 nodes of the mesh surface beening smoothed. + * The class is used to check validity of face or volumes around a smoothed node; + * it stores only 2 nodes as the other nodes are stored by _LayerEdge. + */ + struct _Simplex + { + const SMDS_MeshNode *_nPrev, *_nNext; // nodes on a smoothed mesh surface + _Simplex(const SMDS_MeshNode* nPrev=0, const SMDS_MeshNode* nNext=0) + : _nPrev(nPrev), _nNext(nNext) {} + bool IsForward(const SMDS_MeshNode* nSrc, const gp_XYZ* pntTgt) const + { + const double M[3][3] = + {{ _nNext->X() - nSrc->X(), _nNext->Y() - nSrc->Y(), _nNext->Z() - nSrc->Z() }, + { pntTgt->X() - nSrc->X(), pntTgt->Y() - nSrc->Y(), pntTgt->Z() - nSrc->Z() }, + { _nPrev->X() - nSrc->X(), _nPrev->Y() - nSrc->Y(), _nPrev->Z() - nSrc->Z() }}; + double determinant = ( + M[0][0]*M[1][1]*M[2][2] + + M[0][1]*M[1][2]*M[2][0] + + M[0][2]*M[1][0]*M[2][1] + - M[0][0]*M[1][2]*M[2][1] + - M[0][1]*M[1][0]*M[2][2] + - M[0][2]*M[1][1]*M[2][0]); + return determinant > 1e-100; + } + bool IsForward(const gp_XY& tgtUV, + const SMDS_MeshNode* smoothedNode, + const TopoDS_Face& face, + SMESH_MesherHelper& helper, + const double refSign) const + { + gp_XY prevUV = helper.GetNodeUV( face, _nPrev, smoothedNode ); + gp_XY nextUV = helper.GetNodeUV( face, _nNext, smoothedNode ); + gp_Vec2d v1( tgtUV, prevUV ), v2( tgtUV, nextUV ); + double d = v1 ^ v2; + return d*refSign > 1e-100; + } + bool IsNeighbour(const _Simplex& other) const + { + return _nPrev == other._nNext || _nNext == other._nPrev; + } + }; + //-------------------------------------------------------------------------------- + /*! + * Structure used to take into account surface curvature while smoothing + */ + struct _Curvature + { + double _r; // radius + double _k; // factor to correct node smoothed position + public: + static _Curvature* New( double avgNormProj, double avgDist ) + { + _Curvature* c = 0; + if ( fabs( avgNormProj / avgDist ) > 1./200 ) + { + c = new _Curvature; + c->_r = avgDist * avgDist / avgNormProj; + c->_k = avgDist * avgDist / c->_r / c->_r; + c->_k *= ( c->_r < 0 ? 1/1.1 : 1.1 ); // not to be too restrictive + } + return c; + } + double lenDelta(double len) const { return _k * ( _r + len ); } + }; + struct _LayerEdge; + //-------------------------------------------------------------------------------- + /*! + * Structure used to smooth a _LayerEdge (master) based on an EDGE. + */ + struct _2NearEdges + { + // target nodes of 2 neighbour _LayerEdge's based on the same EDGE + const SMDS_MeshNode* _nodes[2]; + // vectors from source nodes of 2 _LayerEdge's to the source node of master _LayerEdge + //gp_XYZ _vec[2]; + double _wgt[2]; // weights of _nodes + _LayerEdge* _edges[2]; + + // normal to plane passing through _LayerEdge._normal and tangent of EDGE + gp_XYZ* _plnNorm; + + _2NearEdges() { _nodes[0]=_nodes[1]=0; _plnNorm = 0; } + void reverse() { + std::swap( _nodes[0], _nodes[1] ); + std::swap( _wgt[0], _wgt[1] ); + } + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Edge normal to surface, connecting a node on solid surface (_nodes[0]) + * and a node of the most internal layer (_nodes.back()) + */ + struct _LayerEdge + { + vector< const SMDS_MeshNode*> _nodes; + + gp_XYZ _normal; // to solid surface + vector _pos; // points computed during inflation + double _len; // length achived with the last step + double _cosin; // of angle (_normal ^ surface) + double _lenFactor; // to compute _len taking _cosin into account + + // face or edge w/o layer along or near which _LayerEdge is inflated + TopoDS_Shape _sWOL; + // simplices connected to the source node (_nodes[0]); + // used for smoothing and quality check of _LayerEdge's based on the FACE + vector<_Simplex> _simplices; + // data for smoothing of _LayerEdge's based on the EDGE + _2NearEdges* _2neibors; + + _Curvature* _curvature; + // TODO:: detele _Curvature, _plnNorm + + void SetNewLength( double len, SMESH_MesherHelper& helper ); + bool SetNewLength2d( Handle(Geom_Surface)& surface, + const TopoDS_Face& F, + SMESH_MesherHelper& helper ); + void SetDataByNeighbors( const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + SMESH_MesherHelper& helper); + void InvalidateStep( int curStep ); + bool Smooth(int& badNb); + bool SmoothOnEdge(Handle(Geom_Surface)& surface, + const TopoDS_Face& F, + SMESH_MesherHelper& helper); + bool FindIntersection( SMESH_ElementSearcher& searcher, + double & distance, + const double& epsilon, + const SMDS_MeshElement** face = 0); + bool SegTriaInter( const gp_Ax1& lastSegment, + const SMDS_MeshNode* n0, + const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + double& dist, + const double& epsilon) const; + gp_Ax1 LastSegment(double& segLen) const; + bool IsOnEdge() const { return _2neibors; } + void Copy( _LayerEdge& other, SMESH_MesherHelper& helper ); + void SetCosin( double cosin ); + }; + struct _LayerEdgeCmp + { + bool operator () (const _LayerEdge* e1, const _LayerEdge* e2) const + { + const bool cmpNodes = ( e1 && e2 && e1->_nodes.size() && e2->_nodes.size() ); + return cmpNodes ? ( e1->_nodes[0]->GetID() < e2->_nodes[0]->GetID()) : ( e1 < e2 ); + } + }; + //-------------------------------------------------------------------------------- + + typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge; + + //-------------------------------------------------------------------------------- + /*! + * \brief Data of a SOLID + */ + struct _SolidData + { + TopoDS_Shape _solid; + const StdMeshers_ViscousLayers* _hyp; + _MeshOfSolid* _proxyMesh; + set _reversedFaceIds; + + double _stepSize, _stepSizeCoeff; + const SMDS_MeshNode* _stepSizeNodes[2]; + + TNode2Edge _n2eMap; + // edges of _n2eMap. We keep same data in two containers because + // iteration over the map is 5 time longer than over the vector + vector< _LayerEdge* > _edges; + + // key: an id of shape (EDGE or VERTEX) shared by a FACE with + // layers and a FACE w/o layers + // value: the shape (FACE or EDGE) to shrink mesh on. + // _LayerEdge's basing on nodes on key shape are inflated along the value shape + map< TGeomID, TopoDS_Shape > _shrinkShape2Shape; + + // FACE's WOL, srink on which is forbiden due to algo on the adjacent SOLID + set< TGeomID > _noShrinkFaces; + + // to + map< TGeomID,Handle(Geom_Curve)> _edge2curve; + + // end indices in _edges of _LayerEdge on one shape to smooth + vector< int > _endEdgeToSmooth; + + double _epsilon; // precision for SegTriaInter() + + int _index; // for debug + + _SolidData(const TopoDS_Shape& s=TopoDS_Shape(), + const StdMeshers_ViscousLayers* h=0, + _MeshOfSolid* m=0) :_solid(s), _hyp(h), _proxyMesh(m) {} + ~_SolidData(); + + Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge& E, + const int iFrom, + const int iTo, + Handle(Geom_Surface)& surface, + const TopoDS_Face& F, + SMESH_MesherHelper& helper); + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Data of node on a shrinked FACE + */ + struct _SmoothNode + { + const SMDS_MeshNode* _node; + //vector _nodesAround; + vector<_Simplex> _simplices; // for quality check + + bool Smooth(int& badNb, + Handle(Geom_Surface)& surface, + SMESH_MesherHelper& helper, + const double refSign, + bool isCentroidal, + bool set3D); + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Builder of viscous layers + */ + class _ViscousBuilder + { + public: + _ViscousBuilder(); + // does it's job + SMESH_ComputeErrorPtr Compute(SMESH_Mesh& mesh, + const TopoDS_Shape& shape); + + // restore event listeners used to clear an inferior dim sub-mesh modified by viscous layers + void RestoreListeners(); + + // computes SMESH_ProxyMesh::SubMesh::_n2n; + bool MakeN2NMap( _MeshOfSolid* pm ); + + private: + + bool findSolidsWithLayers(); + bool findFacesWithLayers(); + bool makeLayer(_SolidData& data); + bool setEdgeData(_LayerEdge& edge, const set& subIds, + SMESH_MesherHelper& helper, _SolidData& data); + bool findNeiborsOnEdge(const _LayerEdge* edge, + const SMDS_MeshNode*& n1, + const SMDS_MeshNode*& n2, + _SolidData& data); + void getSimplices( const SMDS_MeshNode* node, vector<_Simplex>& simplices, + const set& ingnoreShapes, + const _SolidData* dataToCheckOri = 0, + const bool toSort = false); + bool sortEdges( _SolidData& data, + vector< vector<_LayerEdge*> >& edgesByGeom); + void limitStepSize( _SolidData& data, + const SMDS_MeshElement* face, + const double cosin); + void limitStepSize( _SolidData& data, const double minSize); + bool inflate(_SolidData& data); + bool smoothAndCheck(_SolidData& data, const int nbSteps, double & distToIntersection); + bool smoothAnalyticEdge( _SolidData& data, + const int iFrom, + const int iTo, + Handle(Geom_Surface)& surface, + const TopoDS_Face& F, + SMESH_MesherHelper& helper); + bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper ); + bool refine(_SolidData& data); + bool shrink(); + bool prepareEdgeToShrink( _LayerEdge& edge, const TopoDS_Face& F, + SMESH_MesherHelper& helper, + const SMESHDS_SubMesh* faceSubMesh ); + void fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper); + bool addBoundaryElements(); + + bool error( const string& text, int solidID=-1 ); + SMESHDS_Mesh* getMeshDS() { return _mesh->GetMeshDS(); } + + // debug + void makeGroupOfLE(); + + SMESH_Mesh* _mesh; + SMESH_ComputeErrorPtr _error; + + vector< _SolidData > _sdVec; + set _ignoreShapeIds; + int _tmpFaceID; + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Shrinker of nodes on the EDGE + */ + class _Shrinker1D + { + vector _initU; + vector _normPar; + vector _nodes; + const _LayerEdge* _edges[2]; + bool _done; + public: + void AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper ); + void Compute(bool set3D, SMESH_MesherHelper& helper); + void RestoreParams(); + void SwapSrcTgtNodes(SMESHDS_Mesh* mesh); + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Class of temporary mesh face. + * We can't use SMDS_FaceOfNodes since it's impossible to set it's ID which is + * needed because SMESH_ElementSearcher internaly uses set of elements sorted by ID + */ + struct TmpMeshFace : public SMDS_MeshElement + { + vector _nn; + TmpMeshFace( const vector& nodes, int id): + SMDS_MeshElement(id), _nn(nodes) {} + virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nn[ind]; } + virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } + virtual vtkIdType GetVtkType() const { return -1; } + virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; } + virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_TRIANGLE; } +virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const + { return SMDS_ElemIteratorPtr( new SMDS_NodeVectorElemIterator( _nn.begin(), _nn.end()));} + }; + //-------------------------------------------------------------------------------- + /*! + * \brief Class of temporary mesh face storing _LayerEdge it's based on + */ + struct TmpMeshFaceOnEdge : public TmpMeshFace + { + _LayerEdge *_le1, *_le2; + TmpMeshFaceOnEdge( _LayerEdge* le1, _LayerEdge* le2, int ID ): + TmpMeshFace( vector(4), ID ), _le1(le1), _le2(le2) + { + _nn[0]=_le1->_nodes[0]; + _nn[1]=_le1->_nodes.back(); + _nn[2]=_le2->_nodes.back(); + _nn[3]=_le2->_nodes[0]; + } + }; +} // namespace VISCOUS + +//================================================================================ +// StdMeshers_ViscousLayers hypothesis +// +StdMeshers_ViscousLayers::StdMeshers_ViscousLayers(int hypId, int studyId, SMESH_Gen* gen) + :SMESH_Hypothesis(hypId, studyId, gen), + _nbLayers(1), _thickness(1), _stretchFactor(1) +{ + _name = StdMeshers_ViscousLayers::GetHypType(); + _param_algo_dim = -3; // auxiliary hyp used by 3D algos +} // -------------------------------------------------------------------------------- +void StdMeshers_ViscousLayers::SetIgnoreFaces(const std::vector& faceIds) +{ + if ( faceIds != _ignoreFaceIds ) + _ignoreFaceIds = faceIds, NotifySubMeshesHypothesisModification(); +} // -------------------------------------------------------------------------------- +void StdMeshers_ViscousLayers::SetTotalThickness(double thickness) +{ + if ( thickness != _thickness ) + _thickness = thickness, NotifySubMeshesHypothesisModification(); +} // -------------------------------------------------------------------------------- +void StdMeshers_ViscousLayers::SetNumberLayers(int nb) +{ + if ( _nbLayers != nb ) + _nbLayers = nb, NotifySubMeshesHypothesisModification(); +} // -------------------------------------------------------------------------------- +void StdMeshers_ViscousLayers::SetStretchFactor(double factor) +{ + if ( _stretchFactor != factor ) + _stretchFactor = factor, NotifySubMeshesHypothesisModification(); +} // -------------------------------------------------------------------------------- +SMESH_ProxyMesh::Ptr +StdMeshers_ViscousLayers::Compute(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + const bool toMakeN2NMap) const +{ + using namespace VISCOUS; + _ViscousBuilder bulder; + SMESH_ComputeErrorPtr err = bulder.Compute( theMesh, theShape ); + if ( err && !err->IsOK() ) + return SMESH_ProxyMesh::Ptr(); + + vector components; + TopExp_Explorer exp( theShape, TopAbs_SOLID ); + for ( ; exp.More(); exp.Next() ) + { + if ( _MeshOfSolid* pm = + _ViscousListener::GetSolidMesh( &theMesh, exp.Current(), /*toCreate=*/false)) + { + if ( toMakeN2NMap && !pm->_n2nMapComputed ) + if ( !bulder.MakeN2NMap( pm )) + return SMESH_ProxyMesh::Ptr(); + components.push_back( SMESH_ProxyMesh::Ptr( pm )); + pm->myIsDeletable = false; // it will de deleted by boost::shared_ptr + } + _ViscousListener::RemoveSolidMesh ( &theMesh, exp.Current() ); + } + switch ( components.size() ) + { + case 0: break; + + case 1: return components[0]; + + default: return SMESH_ProxyMesh::Ptr( new SMESH_ProxyMesh( components )); + } + return SMESH_ProxyMesh::Ptr(); +} // -------------------------------------------------------------------------------- +std::ostream & StdMeshers_ViscousLayers::SaveTo(std::ostream & save) +{ + save << " " << _nbLayers + << " " << _thickness + << " " << _stretchFactor + << " " << _ignoreFaceIds.size(); + for ( unsigned i = 0; i < _ignoreFaceIds.size(); ++i ) + save << " " << _ignoreFaceIds[i]; + return save; +} // -------------------------------------------------------------------------------- +std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load) +{ + int nbFaces, faceID; + load >> _nbLayers >> _thickness >> _stretchFactor >> nbFaces; + while ( _ignoreFaceIds.size() < nbFaces && load >> faceID ) + _ignoreFaceIds.push_back( faceID ); + return load; +} // -------------------------------------------------------------------------------- +bool StdMeshers_ViscousLayers::SetParametersByMesh(const SMESH_Mesh* theMesh, + const TopoDS_Shape& theShape) +{ + // TODO + return false; +} +// END StdMeshers_ViscousLayers hypothesis +//================================================================================ + +namespace +{ + gp_XYZ getEdgeDir( const TopoDS_Edge& E, const TopoDS_Vertex& fromV ) + { + gp_Vec dir; + double f,l; + Handle(Geom_Curve) c = BRep_Tool::Curve( E, f, l ); + gp_Pnt p = BRep_Tool::Pnt( fromV ); + double distF = p.SquareDistance( c->Value( f )); + double distL = p.SquareDistance( c->Value( l )); + c->D1(( distF < distL ? f : l), p, dir ); + if ( distL < distF ) dir.Reverse(); + return dir.XYZ(); + } + //-------------------------------------------------------------------------------- + gp_XYZ getEdgeDir( const TopoDS_Edge& E, const SMDS_MeshNode* atNode, + SMESH_MesherHelper& helper) + { + gp_Vec dir; + double f,l; gp_Pnt p; + Handle(Geom_Curve) c = BRep_Tool::Curve( E, f, l ); + double u = helper.GetNodeU( E, atNode ); + c->D1( u, p, dir ); + return dir.XYZ(); + } + //-------------------------------------------------------------------------------- + gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Edge& fromE, + const SMDS_MeshNode* node, SMESH_MesherHelper& helper, bool& ok) + { + gp_XY uv = helper.GetNodeUV( F, node, 0, &ok ); + Handle(Geom_Surface) surface = BRep_Tool::Surface( F ); + gp_Pnt p; gp_Vec du, dv, norm; + surface->D1( uv.X(),uv.Y(), p, du,dv ); + norm = du ^ dv; + + double f,l; + Handle(Geom_Curve) c = BRep_Tool::Curve( fromE, f, l ); + double u = helper.GetNodeU( fromE, node, 0, &ok ); + c->D1( u, p, du ); + TopAbs_Orientation o = helper.GetSubShapeOri( F.Oriented(TopAbs_FORWARD), fromE); + if ( o == TopAbs_REVERSED ) + du.Reverse(); + + gp_Vec dir = norm ^ du; + + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX && + helper.IsClosedEdge( fromE )) + { + if ( fabs(u-f) < fabs(u-l )) c->D1( l, p, dv ); + else c->D1( f, p, dv ); + if ( o == TopAbs_REVERSED ) + dv.Reverse(); + gp_Vec dir2 = norm ^ dv; + dir = dir.Normalized() + dir2.Normalized(); + } + return dir.XYZ(); + } + //-------------------------------------------------------------------------------- + gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Vertex& fromV, + const SMDS_MeshNode* node, SMESH_MesherHelper& helper, + bool& ok, double* cosin=0) + { + double f,l; TopLoc_Location loc; + vector< TopoDS_Edge > edges; // sharing a vertex + PShapeIteratorPtr eIt = helper.GetAncestors( fromV, *helper.GetMesh(), TopAbs_EDGE); + while ( eIt->more()) + { + const TopoDS_Edge* e = static_cast( eIt->next() ); + if ( helper.IsSubShape( *e, F ) && !BRep_Tool::Curve( *e, loc,f,l).IsNull() ) + edges.push_back( *e ); + } + gp_XYZ dir(0,0,0); + if ( !( ok = ( edges.size() > 0 ))) return dir; + // get average dir of edges going fromV + gp_Vec edgeDir; + for ( unsigned i = 0; i < edges.size(); ++i ) + { + edgeDir = getEdgeDir( edges[i], fromV ); + double size2 = edgeDir.SquareMagnitude(); + if ( size2 > numeric_limits::min() ) + edgeDir /= sqrt( size2 ); + else + ok = false; + dir += edgeDir.XYZ(); + } + gp_XYZ fromEdgeDir = getFaceDir( F, edges[0], node, helper, ok ); + if ( edges.size() == 1 || dir.SquareModulus() < 1e-10) + dir = fromEdgeDir; + else if ( dir * fromEdgeDir < 0 ) + dir *= -1; + if ( ok ) + { + //dir /= edges.size(); + if ( cosin ) { + double angle = edgeDir.Angle( dir ); + *cosin = cos( angle ); + } + } + return dir; + } + //================================================================================ + /*! + * \brief Returns true if a FACE is bound by a concave EDGE + */ + //================================================================================ + + bool isConcave( const TopoDS_Face& F, SMESH_MesherHelper& helper ) + { + gp_Vec2d drv1, drv2; + gp_Pnt2d p; + TopExp_Explorer eExp( F.Oriented( TopAbs_FORWARD ), TopAbs_EDGE ); + for ( ; eExp.More(); eExp.Next() ) + { + const TopoDS_Edge& E = TopoDS::Edge( eExp.Current() ); + if ( BRep_Tool::Degenerated( E )) continue; + // check if 2D curve is concave + BRepAdaptor_Curve2d curve( E, F ); + const int nbIntervals = curve.NbIntervals( GeomAbs_C2 ); + TColStd_Array1OfReal intervals(1, nbIntervals + 1 ); + curve.Intervals( intervals, GeomAbs_C2 ); + bool isConvex = true; + for ( int i = 1; i <= nbIntervals && isConvex; ++i ) + { + double u1 = intervals( i ); + double u2 = intervals( i+1 ); + curve.D2( 0.5*( u1+u2 ), p, drv1, drv2 ); + double cross = drv2 ^ drv1; + if ( E.Orientation() == TopAbs_REVERSED ) + cross = -cross; + isConvex = ( cross < 1e-9 ); + } + // check if concavity is strong enough to care about it + //const double maxAngle = 5 * Standard_PI180; + if ( !isConvex ) + { + //cout << "Concave FACE " << helper.GetMeshDS()->ShapeToIndex( F ) << endl; + return true; + // map< double, const SMDS_MeshNode* > u2nodes; + // if ( !SMESH_Algo::GetSortedNodesOnEdge( helper.GetMeshDS(), E, + // /*ignoreMedium=*/true, u2nodes)) + // continue; + // map< double, const SMDS_MeshNode* >::iterator u2n = u2nodes.begin(); + // gp_Pnt2d uvPrev = helper.GetNodeUV( F, u2n->second ); + // double uPrev = u2n->first; + // for ( ++u2n; u2n != u2nodes.end(); ++u2n ) + // { + // gp_Pnt2d uv = helper.GetNodeUV( F, u2n->second ); + // gp_Vec2d segmentDir( uvPrev, uv ); + // curve.D1( uPrev, p, drv1 ); + // try { + // if ( fabs( segmentDir.Angle( drv1 )) > maxAngle ) + // return true; + // } + // catch ( ... ) {} + // uvPrev = uv; + // uPrev = u2n->first; + // } + } + } + return false; + } + //-------------------------------------------------------------------------------- + // DEBUG. Dump intermediate node positions into a python script +#ifdef __myDEBUG + ofstream* py; + struct PyDump { + PyDump() { + const char* fname = "/tmp/viscous.py"; + cout << "execfile('"<GetShapeToMesh(), TopAbs_SOLID, allSolids ); + _sdVec.reserve( allSolids.Extent()); + + SMESH_Gen* gen = _mesh->GetGen(); + for ( int i = 1; i <= allSolids.Extent(); ++i ) + { + // find StdMeshers_ViscousLayers hyp assigned to the i-th solid + SMESH_Algo* algo = gen->GetAlgo( *_mesh, allSolids(i) ); + if ( !algo ) continue; + // TODO: check if algo is hidden + const list & allHyps = + algo->GetUsedHypothesis(*_mesh, allSolids(i), /*ignoreAuxiliary=*/false); + list< const SMESHDS_Hypothesis *>::const_iterator hyp = allHyps.begin(); + const StdMeshers_ViscousLayers* viscHyp = 0; + for ( ; hyp != allHyps.end() && !viscHyp; ++hyp ) + viscHyp = dynamic_cast( *hyp ); + if ( viscHyp ) + { + _MeshOfSolid* proxyMesh = _ViscousListener::GetSolidMesh( _mesh, + allSolids(i), + /*toCreate=*/true); + _sdVec.push_back( _SolidData( allSolids(i), viscHyp, proxyMesh )); + _sdVec.back()._index = getMeshDS()->ShapeToIndex( allSolids(i)); + } + } + if ( _sdVec.empty() ) + return error + ( SMESH_Comment(StdMeshers_ViscousLayers::GetHypType()) << " hypothesis not found",0); + + return true; +} + +//================================================================================ +/*! + * \brief + */ +//================================================================================ + +bool _ViscousBuilder::findFacesWithLayers() +{ + // collect all faces to ignore defined by hyp + vector ignoreFaces; + for ( unsigned i = 0; i < _sdVec.size(); ++i ) + { + vector ids = _sdVec[i]._hyp->GetIgnoreFaces(); + for ( unsigned i = 0; i < ids.size(); ++i ) + { + const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[i] ); + if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE ) + { + _ignoreShapeIds.insert( ids[i] ); + ignoreFaces.push_back( s ); + } + } + } + + // ignore internal faces + SMESH_MesherHelper helper( *_mesh ); + TopExp_Explorer exp; + for ( unsigned i = 0; i < _sdVec.size(); ++i ) + { + exp.Init( _sdVec[i]._solid.Oriented( TopAbs_FORWARD ), TopAbs_FACE ); + for ( ; exp.More(); exp.Next() ) + { + TGeomID faceInd = getMeshDS()->ShapeToIndex( exp.Current() ); + if ( helper.NbAncestors( exp.Current(), *_mesh, TopAbs_SOLID ) > 1 ) + { + _ignoreShapeIds.insert( faceInd ); + ignoreFaces.push_back( exp.Current() ); + if ( SMESH_Algo::IsReversedSubMesh( TopoDS::Face( exp.Current() ), getMeshDS())) + _sdVec[i]._reversedFaceIds.insert( faceInd ); + } + } + } + + // Find faces to shrink mesh on (solution 2 in issue 0020832); + TopTools_IndexedMapOfShape shapes; + for ( unsigned i = 0; i < _sdVec.size(); ++i ) + { + shapes.Clear(); + TopExp::MapShapes(_sdVec[i]._solid, TopAbs_EDGE, shapes); + for ( int iE = 1; iE <= shapes.Extent(); ++iE ) + { + const TopoDS_Shape& edge = shapes(iE); + // find 2 faces sharing an edge + TopoDS_Shape FF[2]; + PShapeIteratorPtr fIt = helper.GetAncestors(edge, *_mesh, TopAbs_FACE); + while ( fIt->more()) + { + const TopoDS_Shape* f = fIt->next(); + if ( helper.IsSubShape( *f, _sdVec[i]._solid)) + FF[ int( !FF[0].IsNull()) ] = *f; + } + if( FF[1].IsNull() ) continue; // seam edge can be shared by 1 FACE only + // check presence of layers on them + int ignore[2]; + for ( int j = 0; j < 2; ++j ) + ignore[j] = _ignoreShapeIds.count ( getMeshDS()->ShapeToIndex( FF[j] )); + if ( ignore[0] == ignore[1] ) continue; // nothing interesting + TopoDS_Shape fWOL = FF[ ignore[0] ? 0 : 1 ]; + // add edge to maps + TGeomID edgeInd = getMeshDS()->ShapeToIndex( edge ); + _sdVec[i]._shrinkShape2Shape.insert( make_pair( edgeInd, fWOL )); + } + } + // Exclude from _shrinkShape2Shape FACE's that can't be shrinked since + // the algo of the SOLID sharing the FACE does not support it + set< string > notSupportAlgos; notSupportAlgos.insert("Hexa_3D"); + for ( unsigned i = 0; i < _sdVec.size(); ++i ) + { + TopTools_MapOfShape noShrinkVertices; + map< TGeomID, TopoDS_Shape >::iterator e2f = _sdVec[i]._shrinkShape2Shape.begin(); + for ( ; e2f != _sdVec[i]._shrinkShape2Shape.end(); ++e2f ) + { + const TopoDS_Shape& fWOL = e2f->second; + TGeomID edgeID = e2f->first; + bool notShrinkFace = false; + PShapeIteratorPtr soIt = helper.GetAncestors(fWOL, *_mesh, TopAbs_SOLID); + while ( soIt->more()) + { + const TopoDS_Shape* solid = soIt->next(); + if ( _sdVec[i]._solid.IsSame( *solid )) continue; + SMESH_Algo* algo = _mesh->GetGen()->GetAlgo( *_mesh, *solid ); + if ( !algo || !notSupportAlgos.count( algo->GetName() )) continue; + notShrinkFace = true; + for ( unsigned j = 0; j < _sdVec.size(); ++j ) + { + if ( _sdVec[j]._solid.IsSame( *solid ) ) + if ( _sdVec[j]._shrinkShape2Shape.count( edgeID )) + notShrinkFace = false; + } + } + if ( notShrinkFace ) + { + _sdVec[i]._noShrinkFaces.insert( getMeshDS()->ShapeToIndex( fWOL )); + for ( TopExp_Explorer vExp( fWOL, TopAbs_VERTEX ); vExp.More(); vExp.Next() ) + noShrinkVertices.Add( vExp.Current() ); + } + } + // erase from _shrinkShape2Shape all srink EDGE's of a SOLID connected + // to the found not shrinked fWOL's + e2f = _sdVec[i]._shrinkShape2Shape.begin(); + for ( ; e2f != _sdVec[i]._shrinkShape2Shape.end(); ) + { + TGeomID edgeID = e2f->first; + TopoDS_Vertex VV[2]; + TopExp::Vertices( TopoDS::Edge( getMeshDS()->IndexToShape( edgeID )),VV[0],VV[1]); + if ( noShrinkVertices.Contains( VV[0] ) || noShrinkVertices.Contains( VV[1] )) + { + _sdVec[i]._noShrinkFaces.insert( getMeshDS()->ShapeToIndex( e2f->second )); + _sdVec[i]._shrinkShape2Shape.erase( e2f++ ); + } + else + { + e2f++; + } + } + } + + // Find the SHAPE along which to inflate _LayerEdge based on VERTEX + + for ( unsigned i = 0; i < _sdVec.size(); ++i ) + { + shapes.Clear(); + TopExp::MapShapes(_sdVec[i]._solid, TopAbs_VERTEX, shapes); + for ( int iV = 1; iV <= shapes.Extent(); ++iV ) + { + const TopoDS_Shape& vertex = shapes(iV); + // find faces WOL sharing the vertex + vector< TopoDS_Shape > facesWOL; + int totalNbFaces = 0; + PShapeIteratorPtr fIt = helper.GetAncestors(vertex, *_mesh, TopAbs_FACE); + while ( fIt->more()) + { + const TopoDS_Shape* f = fIt->next(); + const int fID = getMeshDS()->ShapeToIndex( *f ); + if ( helper.IsSubShape( *f, _sdVec[i]._solid ) ) + { + totalNbFaces++; + if ( _ignoreShapeIds.count ( fID ) && ! _sdVec[i]._noShrinkFaces.count( fID )) + facesWOL.push_back( *f ); + } + } + if ( facesWOL.size() == totalNbFaces || facesWOL.empty() ) + continue; // no layers at this vertex or no WOL + TGeomID vInd = getMeshDS()->ShapeToIndex( vertex ); + switch ( facesWOL.size() ) + { + case 1: + { + helper.SetSubShape( facesWOL[0] ); + if ( helper.IsRealSeam( vInd )) // inflate along a seam edge? + { + TopoDS_Shape seamEdge; + PShapeIteratorPtr eIt = helper.GetAncestors(vertex, *_mesh, TopAbs_EDGE); + while ( eIt->more() && seamEdge.IsNull() ) + { + const TopoDS_Shape* e = eIt->next(); + if ( helper.IsRealSeam( *e ) ) + seamEdge = *e; + } + if ( !seamEdge.IsNull() ) + { + _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, seamEdge )); + break; + } + } + _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, facesWOL[0] )); + break; + } + case 2: + { + // find an edge shared by 2 faces + PShapeIteratorPtr eIt = helper.GetAncestors(vertex, *_mesh, TopAbs_EDGE); + while ( eIt->more()) + { + const TopoDS_Shape* e = eIt->next(); + if ( helper.IsSubShape( *e, facesWOL[0]) && + helper.IsSubShape( *e, facesWOL[1])) + { + _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, *e )); break; + } + } + break; + } + default: + return error("Not yet supported case", _sdVec[i]._index); + } + } + } + + return true; +} + +//================================================================================ +/*! + * \brief Create the inner surface of the viscous layer and prepare data for infation + */ +//================================================================================ + +bool _ViscousBuilder::makeLayer(_SolidData& data) +{ + // get all sub-shapes to make layers on + set subIds, faceIds; + subIds = data._noShrinkFaces; + TopExp_Explorer exp( data._solid, TopAbs_FACE ); + for ( ; exp.More(); exp.Next() ) + if ( ! _ignoreShapeIds.count( getMeshDS()->ShapeToIndex( exp.Current() ))) + { + SMESH_subMesh* fSubM = _mesh->GetSubMesh( exp.Current() ); + faceIds.insert( fSubM->GetId() ); + SMESH_subMeshIteratorPtr subIt = + fSubM->getDependsOnIterator(/*includeSelf=*/true, /*complexShapeFirst=*/false); + while ( subIt->more() ) + subIds.insert( subIt->next()->GetId() ); + } + + // make a map to find new nodes on sub-shapes shared with other SOLID + map< TGeomID, TNode2Edge* > s2neMap; + map< TGeomID, TNode2Edge* >::iterator s2ne; + map< TGeomID, TopoDS_Shape >::iterator s2s = data._shrinkShape2Shape.begin(); + for (; s2s != data._shrinkShape2Shape.end(); ++s2s ) + { + TGeomID shapeInd = s2s->first; + for ( unsigned i = 0; i < _sdVec.size(); ++i ) + { + if ( _sdVec[i]._index == data._index ) continue; + map< TGeomID, TopoDS_Shape >::iterator s2s2 = _sdVec[i]._shrinkShape2Shape.find( shapeInd ); + if ( s2s2 != _sdVec[i]._shrinkShape2Shape.end() && + *s2s == *s2s2 && !_sdVec[i]._n2eMap.empty() ) + { + s2neMap.insert( make_pair( shapeInd, &_sdVec[i]._n2eMap )); + break; + } + } + } + + // Create temporary faces and _LayerEdge's + + dumpFunction(SMESH_Comment("makeLayers_")< newNodes; // of a mesh face + TNode2Edge::iterator n2e2; + + // collect _LayerEdge's of shapes they are based on + const int nbShapes = getMeshDS()->MaxShapeIndex(); + vector< vector<_LayerEdge*> > edgesByGeom( nbShapes+1 ); + + for ( set::iterator id = faceIds.begin(); id != faceIds.end(); ++id ) + { + SMESHDS_SubMesh* smDS = getMeshDS()->MeshElements( *id ); + if ( !smDS ) return error(SMESH_Comment("Not meshed face ") << *id, data._index ); + + const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( *id )); + SMESH_ProxyMesh::SubMesh* proxySub = + data._proxyMesh->getFaceSubM( F, /*create=*/true); + + SMDS_ElemIteratorPtr eIt = smDS->GetElements(); + while ( eIt->more() ) + { + const SMDS_MeshElement* face = eIt->next(); + newNodes.resize( face->NbCornerNodes() ); + double faceMaxCosin = -1; + for ( int i = 0 ; i < face->NbCornerNodes(); ++i ) + { + const SMDS_MeshNode* n = face->GetNode(i); + TNode2Edge::iterator n2e = data._n2eMap.insert( make_pair( n, (_LayerEdge*)0 )).first; + if ( !(*n2e).second ) + { + // add a _LayerEdge + _LayerEdge* edge = new _LayerEdge(); + n2e->second = edge; + edge->_nodes.push_back( n ); + const int shapeID = n->getshapeId(); + edgesByGeom[ shapeID ].push_back( edge ); + + // set edge data or find already refined _LayerEdge and get data from it + if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE && + ( s2ne = s2neMap.find( shapeID )) != s2neMap.end() && + ( n2e2 = (*s2ne).second->find( n )) != s2ne->second->end()) + { + _LayerEdge* foundEdge = (*n2e2).second; + edge->Copy( *foundEdge, helper ); + // location of the last node is modified but we can restore + // it by node position on _sWOL stored by the node + const_cast< SMDS_MeshNode* > + ( edge->_nodes.back() )->setXYZ( n->X(), n->Y(), n->Z() ); + } + else + { + edge->_nodes.push_back( helper.AddNode( n->X(), n->Y(), n->Z() )); + if ( !setEdgeData( *edge, subIds, helper, data )) + return false; + } + dumpMove(edge->_nodes.back()); + if ( edge->_cosin > 0.01 ) + { + if ( edge->_cosin > faceMaxCosin ) + faceMaxCosin = edge->_cosin; + } + } + newNodes[ i ] = n2e->second->_nodes.back(); + } + // create a temporary face + const SMDS_MeshElement* newFace = new TmpMeshFace( newNodes, --_tmpFaceID ); + proxySub->AddElement( newFace ); + + // compute inflation step size by min size of element on a convex surface + if ( faceMaxCosin > 0.1 ) + limitStepSize( data, face, faceMaxCosin ); + } // loop on 2D elements on a FACE + } // loop on FACEs of a SOLID + + data._epsilon = 1e-7; + if ( data._stepSize < 1. ) + data._epsilon *= data._stepSize; + + // Put _LayerEdge's into a vector + + if ( !sortEdges( data, edgesByGeom )) + return false; + + // Set target nodes into _Simplex and _2NearEdges + TNode2Edge::iterator n2e; + for ( unsigned i = 0; i < data._edges.size(); ++i ) + { + if ( data._edges[i]->IsOnEdge()) + for ( int j = 0; j < 2; ++j ) + { + if ( data._edges[i]->_nodes.back()->NbInverseElements(SMDSAbs_Volume) > 0 ) + break; // _LayerEdge is shared by two _SolidData's + const SMDS_MeshNode* & n = data._edges[i]->_2neibors->_nodes[j]; + if (( n2e = data._n2eMap.find( n )) == data._n2eMap.end() ) + return error("_LayerEdge not found by src node", data._index); + n = (*n2e).second->_nodes.back(); + data._edges[i]->_2neibors->_edges[j] = n2e->second; + } + else + for ( unsigned j = 0; j < data._edges[i]->_simplices.size(); ++j ) + { + _Simplex& s = data._edges[i]->_simplices[j]; + s._nNext = data._n2eMap[ s._nNext ]->_nodes.back(); + s._nPrev = data._n2eMap[ s._nPrev ]->_nodes.back(); + } + } + + dumpFunctionEnd(); + return true; +} + +//================================================================================ +/*! + * \brief Compute inflation step size by min size of element on a convex surface + */ +//================================================================================ + +void _ViscousBuilder::limitStepSize( _SolidData& data, + const SMDS_MeshElement* face, + const double cosin) +{ + int iN = 0; + double minSize = 10 * data._stepSize; + const int nbNodes = face->NbCornerNodes(); + for ( int i = 0; i < nbNodes; ++i ) + { + const SMDS_MeshNode* nextN = face->GetNode( SMESH_MesherHelper::WrapIndex( i+1, nbNodes )); + const SMDS_MeshNode* curN = face->GetNode( i ); + if ( nextN->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE || + curN->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) + { + double dist = SMESH_TNodeXYZ( face->GetNode(i)).Distance( nextN ); + if ( dist < minSize ) + minSize = dist, iN = i; + } + } + double newStep = 0.8 * minSize / cosin; + if ( newStep < data._stepSize ) + { + data._stepSize = newStep; + data._stepSizeCoeff = 0.8 / cosin; + data._stepSizeNodes[0] = face->GetNode( iN ); + data._stepSizeNodes[1] = face->GetNode( SMESH_MesherHelper::WrapIndex( iN+1, nbNodes )); + } +} + +//================================================================================ +/*! + * \brief Compute inflation step size by min size of element on a convex surface + */ +//================================================================================ + +void _ViscousBuilder::limitStepSize( _SolidData& data, const double minSize) +{ + if ( minSize < data._stepSize ) + { + data._stepSize = minSize; + if ( data._stepSizeNodes[0] ) + { + double dist = + SMESH_TNodeXYZ(data._stepSizeNodes[0]).Distance(data._stepSizeNodes[1]); + data._stepSizeCoeff = data._stepSize / dist; + } + } +} + +//================================================================================ +/*! + * \brief Separate shapes (and _LayerEdge's on them) to smooth from the rest ones + */ +//================================================================================ + +bool _ViscousBuilder::sortEdges( _SolidData& data, + vector< vector<_LayerEdge*> >& edgesByGeom) +{ + // Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's + // boundry inclined at a sharp angle to the shape + + list< TGeomID > shapesToSmooth; + + SMESH_MesherHelper helper( *_mesh ); + bool ok = true; + + for ( unsigned iS = 0; iS < edgesByGeom.size(); ++iS ) + { + vector<_LayerEdge*>& eS = edgesByGeom[iS]; + if ( eS.empty() ) continue; + TopoDS_Shape S = getMeshDS()->IndexToShape( iS ); + bool needSmooth = false; + switch ( S.ShapeType() ) + { + case TopAbs_EDGE: { + + bool isShrinkEdge = !eS[0]->_sWOL.IsNull(); + for ( TopoDS_Iterator vIt( S ); vIt.More() && !needSmooth; vIt.Next() ) + { + TGeomID iV = getMeshDS()->ShapeToIndex( vIt.Value() ); + vector<_LayerEdge*>& eV = edgesByGeom[ iV ]; + if ( eV.empty() ) continue; + double cosin = eV[0]->_cosin; + bool badCosin = + ( !eV[0]->_sWOL.IsNull() && ( eV[0]->_sWOL.ShapeType() == TopAbs_EDGE || !isShrinkEdge)); + if ( badCosin ) + { + gp_Vec dir1, dir2; + if ( eV[0]->_sWOL.ShapeType() == TopAbs_EDGE ) + dir1 = getEdgeDir( TopoDS::Edge( eV[0]->_sWOL ), TopoDS::Vertex( vIt.Value() )); + else + dir1 = getFaceDir( TopoDS::Face( eV[0]->_sWOL ), TopoDS::Vertex( vIt.Value() ), + eV[0]->_nodes[0], helper, ok); + dir2 = getEdgeDir( TopoDS::Edge( S ), TopoDS::Vertex( vIt.Value() )); + double angle = dir1.Angle( dir2 ); + cosin = cos( angle ); + } + needSmooth = ( cosin > 0.1 ); + } + break; + } + case TopAbs_FACE: { + + for ( TopExp_Explorer eExp( S, TopAbs_EDGE ); eExp.More() && !needSmooth; eExp.Next() ) + { + TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() ); + vector<_LayerEdge*>& eE = edgesByGeom[ iE ]; + if ( eE.empty() ) continue; + if ( eE[0]->_sWOL.IsNull() ) + { + for ( unsigned i = 0; i < eE.size() && !needSmooth; ++i ) + needSmooth = ( eE[i]->_cosin > 0.1 ); + } + else + { + const TopoDS_Face& F1 = TopoDS::Face( S ); + const TopoDS_Face& F2 = TopoDS::Face( eE[0]->_sWOL ); + const TopoDS_Edge& E = TopoDS::Edge( eExp.Current() ); + for ( unsigned i = 0; i < eE.size() && !needSmooth; ++i ) + { + gp_Vec dir1 = getFaceDir( F1, E, eE[i]->_nodes[0], helper, ok ); + gp_Vec dir2 = getFaceDir( F2, E, eE[i]->_nodes[0], helper, ok ); + double angle = dir1.Angle( dir2 ); + double cosin = cos( angle ); + needSmooth = ( cosin > 0.1 ); + } + } + } + break; + } + case TopAbs_VERTEX: + continue; + default:; + } + if ( needSmooth ) + { + if ( S.ShapeType() == TopAbs_EDGE ) shapesToSmooth.push_front( iS ); + else shapesToSmooth.push_back ( iS ); + } + + } // loop on edgesByGeom + + data._edges.reserve( data._n2eMap.size() ); + data._endEdgeToSmooth.clear(); + + // first we put _LayerEdge's on shapes to smooth + list< TGeomID >::iterator gIt = shapesToSmooth.begin(); + for ( ; gIt != shapesToSmooth.end(); ++gIt ) + { + vector<_LayerEdge*>& eVec = edgesByGeom[ *gIt ]; + if ( eVec.empty() ) continue; + data._edges.insert( data._edges.end(), eVec.begin(), eVec.end() ); + data._endEdgeToSmooth.push_back( data._edges.size() ); + eVec.clear(); + } + + // then the rest _LayerEdge's + for ( unsigned iS = 0; iS < edgesByGeom.size(); ++iS ) + { + vector<_LayerEdge*>& eVec = edgesByGeom[iS]; + data._edges.insert( data._edges.end(), eVec.begin(), eVec.end() ); + eVec.clear(); + } + + return ok; +} + +//================================================================================ +/*! + * \brief Set data of _LayerEdge needed for smoothing + * \param subIds - ids of sub-shapes of a SOLID to take into account faces from + */ +//================================================================================ + +bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, + const set& subIds, + SMESH_MesherHelper& helper, + _SolidData& data) +{ + SMESH_MeshEditor editor(_mesh); + + const SMDS_MeshNode* node = edge._nodes[0]; // source node + SMDS_TypeOfPosition posType = node->GetPosition()->GetTypeOfPosition(); + + edge._len = 0; + edge._2neibors = 0; + edge._curvature = 0; + + // -------------------------- + // Compute _normal and _cosin + // -------------------------- + + edge._cosin = 0; + edge._normal.SetCoord(0,0,0); + + int totalNbFaces = 0; + gp_Pnt p; + gp_Vec du, dv, geomNorm; + bool normOK = true; + + TGeomID shapeInd = node->getshapeId(); + map< TGeomID, TopoDS_Shape >::const_iterator s2s = data._shrinkShape2Shape.find( shapeInd ); + bool onShrinkShape ( s2s != data._shrinkShape2Shape.end() ); + TopoDS_Shape vertEdge; + + if ( onShrinkShape ) // one of faces the node is on has no layers + { + vertEdge = getMeshDS()->IndexToShape( s2s->first ); // vertex or edge + if ( s2s->second.ShapeType() == TopAbs_EDGE ) + { + // inflate from VERTEX along EDGE + edge._normal = getEdgeDir( TopoDS::Edge( s2s->second ), TopoDS::Vertex( vertEdge )); + } + else if ( vertEdge.ShapeType() == TopAbs_VERTEX ) + { + // inflate from VERTEX along FACE + edge._normal = getFaceDir( TopoDS::Face( s2s->second ), TopoDS::Vertex( vertEdge ), + node, helper, normOK, &edge._cosin); + } + else + { + // inflate from EDGE along FACE + edge._normal = getFaceDir( TopoDS::Face( s2s->second ), TopoDS::Edge( vertEdge ), + node, helper, normOK); + } + } + else // layers are on all faces of SOLID the node is on + { + // find indices of geom faces the node lies on + set faceIds; + if ( posType == SMDS_TOP_FACE ) + { + faceIds.insert( node->getshapeId() ); + } + else + { + SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + faceIds.insert( editor.FindShape(fIt->next())); + } + + set::iterator id = faceIds.begin(); + TopoDS_Face F; + for ( ; id != faceIds.end(); ++id ) + { + const TopoDS_Shape& s = getMeshDS()->IndexToShape( *id ); + if ( s.IsNull() || s.ShapeType() != TopAbs_FACE || !subIds.count( *id )) + continue; + totalNbFaces++; + //nbLayerFaces += subIds.count( *id ); + F = TopoDS::Face( s ); + + gp_XY uv = helper.GetNodeUV( F, node, 0, &normOK ); + Handle(Geom_Surface) surface = BRep_Tool::Surface( F ); + surface->D1( uv.X(),uv.Y(), p, du,dv ); + geomNorm = du ^ dv; + double size2 = geomNorm.SquareMagnitude(); + if ( size2 > numeric_limits::min() ) + geomNorm /= sqrt( size2 ); + else + normOK = false; + if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED ) + geomNorm.Reverse(); + edge._normal += geomNorm.XYZ(); + } + if ( totalNbFaces == 0 ) + return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), data._index); + + edge._normal /= totalNbFaces; + + switch ( posType ) + { + case SMDS_TOP_FACE: + edge._cosin = 0; break; + + case SMDS_TOP_EDGE: { + TopoDS_Edge E = TopoDS::Edge( helper.GetSubShapeByNode( node, getMeshDS())); + gp_Vec inFaceDir = getFaceDir( F, E, node, helper, normOK); + double angle = inFaceDir.Angle( edge._normal ); // [0,PI] + edge._cosin = cos( angle ); + //cout << "Cosin on EDGE " << edge._cosin << " node " << node->GetID() << endl; + break; + } + case SMDS_TOP_VERTEX: { + TopoDS_Vertex V = TopoDS::Vertex( helper.GetSubShapeByNode( node, getMeshDS())); + gp_Vec inFaceDir = getFaceDir( F, V, node, helper, normOK); + double angle = inFaceDir.Angle( edge._normal ); // [0,PI] + edge._cosin = cos( angle ); + //cout << "Cosin on VERTEX " << edge._cosin << " node " << node->GetID() << endl; + break; + } + default: + return error(SMESH_Comment("Invalid shape position of node ")<::min() ) + return error(SMESH_Comment("Bad normal at node ")<< node->GetID(), data._index ); + + edge._normal /= sqrt( normSize ); + + // TODO: if ( !normOK ) then get normal by mesh faces + + // Set the rest data + // -------------------- + if ( onShrinkShape ) + { + edge._sWOL = (*s2s).second; + + SMDS_MeshNode* tgtNode = const_cast( edge._nodes.back() ); + if ( SMESHDS_SubMesh* sm = getMeshDS()->MeshElements( data._solid )) + sm->RemoveNode( tgtNode , /*isNodeDeleted=*/false ); + + // set initial position which is parameters on _sWOL in this case + if ( edge._sWOL.ShapeType() == TopAbs_EDGE ) + { + double u = helper.GetNodeU( TopoDS::Edge( edge._sWOL ), node, 0, &normOK ); + edge._pos.push_back( gp_XYZ( u, 0, 0)); + getMeshDS()->SetNodeOnEdge( tgtNode, TopoDS::Edge( edge._sWOL ), u ); + } + else // TopAbs_FACE + { + gp_XY uv = helper.GetNodeUV( TopoDS::Face( edge._sWOL ), node, 0, &normOK ); + edge._pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0)); + getMeshDS()->SetNodeOnFace( tgtNode, TopoDS::Face( edge._sWOL ), uv.X(), uv.Y() ); + } + } + else + { + edge._pos.push_back( SMESH_TNodeXYZ( node )); + + if ( posType == SMDS_TOP_FACE ) + { + getSimplices( node, edge._simplices, _ignoreShapeIds, &data ); + double avgNormProj = 0, avgLen = 0; + for ( unsigned i = 0; i < edge._simplices.size(); ++i ) + { + gp_XYZ vec = edge._pos.back() - SMESH_TNodeXYZ( edge._simplices[i]._nPrev ); + avgNormProj += edge._normal * vec; + avgLen += vec.Modulus(); + } + avgNormProj /= edge._simplices.size(); + avgLen /= edge._simplices.size(); + edge._curvature = _Curvature::New( avgNormProj, avgLen ); + } + } + + // Set neighbour nodes for a _LayerEdge based on EDGE + + if ( posType == SMDS_TOP_EDGE /*|| + ( onShrinkShape && posType == SMDS_TOP_VERTEX && fabs( edge._cosin ) < 1e-10 )*/) + { + edge._2neibors = new _2NearEdges; + // target node instead of source ones will be set later + if ( ! findNeiborsOnEdge( &edge, + edge._2neibors->_nodes[0], + edge._2neibors->_nodes[1], + data)) + return false; + edge.SetDataByNeighbors( edge._2neibors->_nodes[0], + edge._2neibors->_nodes[1], + helper); + } + + edge.SetCosin( edge._cosin ); // to update edge._lenFactor + + return true; +} + +//================================================================================ +/*! + * \brief Find 2 neigbor nodes of a node on EDGE + */ +//================================================================================ + +bool _ViscousBuilder::findNeiborsOnEdge(const _LayerEdge* edge, + const SMDS_MeshNode*& n1, + const SMDS_MeshNode*& n2, + _SolidData& data) +{ + const SMDS_MeshNode* node = edge->_nodes[0]; + const int shapeInd = node->getshapeId(); + SMESHDS_SubMesh* edgeSM = 0; + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE ) + { + + edgeSM = getMeshDS()->MeshElements( shapeInd ); + if ( !edgeSM || edgeSM->NbElements() == 0 ) + return error(SMESH_Comment("Not meshed EDGE ") << shapeInd, data._index); + } + int iN = 0; + n2 = 0; + SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Edge); + while ( eIt->more() && !n2 ) + { + const SMDS_MeshElement* e = eIt->next(); + const SMDS_MeshNode* nNeibor = e->GetNode( 0 ); + if ( nNeibor == node ) nNeibor = e->GetNode( 1 ); + if ( edgeSM ) + { + if (!edgeSM->Contains(e)) continue; + } + else + { + TopoDS_Shape s = SMESH_MesherHelper::GetSubShapeByNode(nNeibor, getMeshDS() ); + if ( !SMESH_MesherHelper::IsSubShape( s, edge->_sWOL )) continue; + } + ( iN++ ? n2 : n1 ) = nNeibor; + } + if ( !n2 ) + return error(SMESH_Comment("Wrongly meshed EDGE ") << shapeInd, data._index); + return true; +} + +//================================================================================ +/*! + * \brief Set _curvature and _2neibors->_plnNorm by 2 neigbor nodes residing the same EDGE + */ +//================================================================================ + +void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + SMESH_MesherHelper& helper) +{ + if ( _nodes[0]->GetPosition()->GetTypeOfPosition() != SMDS_TOP_EDGE ) + return; + + gp_XYZ pos = SMESH_TNodeXYZ( _nodes[0] ); + gp_XYZ vec1 = pos - SMESH_TNodeXYZ( n1 ); + gp_XYZ vec2 = pos - SMESH_TNodeXYZ( n2 ); + + // Set _curvature + + double sumLen = vec1.Modulus() + vec2.Modulus(); + _2neibors->_wgt[0] = 1 - vec1.Modulus() / sumLen; + _2neibors->_wgt[1] = 1 - vec2.Modulus() / sumLen; + double avgNormProj = 0.5 * ( _normal * vec1 + _normal * vec2 ); + double avgLen = 0.5 * ( vec1.Modulus() + vec2.Modulus() ); + if ( _curvature ) delete _curvature; + _curvature = _Curvature::New( avgNormProj, avgLen ); +#ifdef __myDEBUG +// if ( _curvature ) +// cout << _nodes[0]->GetID() +// << " CURV r,k: " << _curvature->_r<<","<<_curvature->_k +// << " proj = "<AddGroup(SMDSAbs_Edge, name.c_str(), id ); +// SMESHDS_Group* gDS = (SMESHDS_Group*)g->GetGroupDS(); +// SMESHDS_Mesh* mDS = _mesh->GetMeshDS(); + + dumpFunction( SMESH_Comment("make_LayerEdge_") << i ); + for ( unsigned j = 0 ; j < _sdVec[i]._edges.size(); ++j ) + { + _LayerEdge* le = _sdVec[i]._edges[j]; + for ( unsigned iN = 1; iN < le->_nodes.size(); ++iN ) + dumpCmd(SMESH_Comment("mesh.AddEdge([ ") <_nodes[iN-1]->GetID() + << ", " << le->_nodes[iN]->GetID() <<"])"); + //gDS->SMDSGroup().Add( mDS->AddEdge( le->_nodes[iN-1], le->_nodes[iN])); + } + dumpFunctionEnd(); + + dumpFunction( SMESH_Comment("makeNormals") << i ); + for ( unsigned j = 0 ; j < _sdVec[i]._edges.size(); ++j ) + { + _LayerEdge& edge = *_sdVec[i]._edges[j]; + SMESH_TNodeXYZ nXYZ( edge._nodes[0] ); + nXYZ += edge._normal * _sdVec[i]._stepSize; + dumpCmd(SMESH_Comment("mesh.AddEdge([ ") <GetID() + << ", mesh.AddNode( " << nXYZ.X()<<","<< nXYZ.Y()<<","<< nXYZ.Z()<<")])"); + } + dumpFunctionEnd(); + +// name = SMESH_Comment("tmp_faces ") << i; +// g = _mesh->AddGroup(SMDSAbs_Face, name.c_str(), id ); +// gDS = (SMESHDS_Group*)g->GetGroupDS(); +// SMESH_MeshEditor editor( _mesh ); + dumpFunction( SMESH_Comment("makeTmpFaces_") << i ); + TopExp_Explorer fExp( _sdVec[i]._solid, TopAbs_FACE ); + for ( ; fExp.More(); fExp.Next() ) + { + if (const SMESHDS_SubMesh* sm = _sdVec[i]._proxyMesh->GetProxySubMesh( fExp.Current())) + { + SMDS_ElemIteratorPtr fIt = sm->GetElements(); + while ( fIt->more()) + { + const SMDS_MeshElement* e = fIt->next(); + SMESH_Comment cmd("mesh.AddFace(["); + for ( int j=0; j < e->NbCornerNodes(); ++j ) + cmd << e->GetNode(j)->GetID() << (j+1NbCornerNodes() ? ",": "])"); + dumpCmd( cmd ); + //vector nodes( e->begin_nodes(), e->end_nodes() ); + //gDS->SMDSGroup().Add( editor.AddElement( nodes, e->GetType(), e->IsPoly())); + } + } + } + dumpFunctionEnd(); + } +#endif +} + +//================================================================================ +/*! + * \brief Increase length of _LayerEdge's to reach the required thickness of layers + */ +//================================================================================ + +bool _ViscousBuilder::inflate(_SolidData& data) +{ + SMESH_MesherHelper helper( *_mesh ); + + // Limit inflation step size by geometry size found by itersecting + // normals of _LayerEdge's with mesh faces + double geomSize = Precision::Infinite(), intersecDist; + SMESH_MeshEditor editor( _mesh ); + auto_ptr searcher + ( editor.GetElementSearcher( data._proxyMesh->GetFaces( data._solid )) ); + for ( unsigned i = 0; i < data._edges.size(); ++i ) + { + if ( data._edges[i]->IsOnEdge() ) continue; + data._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon ); + if ( geomSize > intersecDist ) + geomSize = intersecDist; + } + if ( data._stepSize > 0.3 * geomSize ) + limitStepSize( data, 0.3 * geomSize ); + + const double tgtThick = data._hyp->GetTotalThickness(); + if ( data._stepSize > tgtThick ) + limitStepSize( data, tgtThick ); + + if ( data._stepSize < 1. ) + data._epsilon = data._stepSize * 1e-7; + +#ifdef __myDEBUG + cout << "-- geomSize = " << geomSize << ", stepSize = " << data._stepSize << endl; +#endif + + double avgThick = 0, curThick = 0, distToIntersection = Precision::Infinite(); + int nbSteps = 0, nbRepeats = 0; + while ( 1.01 * avgThick < tgtThick ) + { + // new target length + curThick += data._stepSize; + if ( curThick > tgtThick ) + { + curThick = tgtThick + ( tgtThick-avgThick ) * nbRepeats; + nbRepeats++; + } + + // Elongate _LayerEdge's + dumpFunction(SMESH_Comment("inflate")<SetNewLength( curThick, helper ); + } + dumpFunctionEnd(); + + if ( !nbSteps ) + if ( !updateNormals( data, helper ) ) + return false; + + // Improve and check quality + if ( !smoothAndCheck( data, nbSteps, distToIntersection )) + { + if ( nbSteps > 0 ) + { + dumpFunction(SMESH_Comment("invalidate")<InvalidateStep( nbSteps+1 ); + } + dumpFunctionEnd(); + } + break; // no more inflating possible + } + nbSteps++; + + // Evaluate achieved thickness + avgThick = 0; + for ( unsigned i = 0; i < data._edges.size(); ++i ) + avgThick += data._edges[i]->_len; + avgThick /= data._edges.size(); +#ifdef __myDEBUG + cout << "-- Thickness " << avgThick << " reached" << endl; +#endif + + if ( distToIntersection < avgThick*1.5 ) + { +#ifdef __myDEBUG + cout << "-- Stop inflation since distToIntersection( "<_sWOL.IsNull() && + data._edges[ iBeg ]->_sWOL.ShapeType() == TopAbs_FACE ) + { + if ( !F.IsSame( data._edges[ iBeg ]->_sWOL )) { + F = TopoDS::Face( data._edges[ iBeg ]->_sWOL ); + helper.SetSubShape( F ); + surface = BRep_Tool::Surface( F ); + } + } + else + { + F.Nullify(); surface.Nullify(); + } + TGeomID sInd = data._edges[ iBeg ]->_nodes[0]->getshapeId(); + + if ( data._edges[ iBeg ]->IsOnEdge() ) + { + dumpFunction(SMESH_Comment("smooth")<SmoothOnEdge(surface, F, helper); + } + dumpCmd( SMESH_Comment("# end step ")<Smooth(badNb); + improved = ( badNb < oldBadNb ); + + dumpFunctionEnd(); + } + if ( badNb > 0 ) + { +#ifdef __myDEBUG + for ( int i = iBeg; i < iEnd; ++i ) + { + _LayerEdge* edge = data._edges[i]; + SMESH_TNodeXYZ tgtXYZ( edge->_nodes.back() ); + for ( unsigned j = 0; j < edge->_simplices.size(); ++j ) + if ( !edge->_simplices[j].IsForward( edge->_nodes[0], &tgtXYZ )) + { + cout << "Bad simplex ( " << edge->_nodes[0]->GetID()<< " "<< tgtXYZ._node->GetID() + << " "<< edge->_simplices[j]._nPrev->GetID() + << " "<< edge->_simplices[j]._nNext->GetID() << " )" << endl; + return false; + } + } +#endif + return false; + } + } + } // loop on shapes to smooth + + // Check if the last segments of _LayerEdge intersects 2D elements; + // checked elements are either temporary faces or faces on surfaces w/o the layers + + SMESH_MeshEditor editor( _mesh ); + auto_ptr searcher + ( editor.GetElementSearcher( data._proxyMesh->GetFaces( data._solid )) ); + + distToIntersection = Precision::Infinite(); + double dist; + const SMDS_MeshElement* intFace = 0; +#ifdef __myDEBUG + const SMDS_MeshElement* closestFace = 0; + int iLE = 0; +#endif + for ( unsigned i = 0; i < data._edges.size(); ++i ) + { + if ( data._edges[i]->FindIntersection( *searcher, dist, data._epsilon, &intFace )) + return false; + if ( distToIntersection > dist ) + { + distToIntersection = dist; +#ifdef __myDEBUG + iLE = i; + closestFace = intFace; +#endif + } + } +#ifdef __myDEBUG + if ( closestFace ) + { + SMDS_MeshElement::iterator nIt = closestFace->begin_nodes(); + cout << "Shortest distance: _LayerEdge nodes: tgt " << data._edges[iLE]->_nodes.back()->GetID() + << " src " << data._edges[iLE]->_nodes[0]->GetID()<< ", intersection with face (" + << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID() + << ") distance = " << distToIntersection<< endl; + } +#endif + + return true; +} + +//================================================================================ +/*! + * \brief Return a curve of the EDGE to be used for smoothing and arrange + * _LayerEdge's to be in a consequent order + */ +//================================================================================ + +Handle(Geom_Curve) _SolidData::CurveForSmooth( const TopoDS_Edge& E, + const int iFrom, + const int iTo, + Handle(Geom_Surface)& surface, + const TopoDS_Face& F, + SMESH_MesherHelper& helper) +{ + TGeomID eIndex = helper.GetMeshDS()->ShapeToIndex( E ); + + map< TGeomID, Handle(Geom_Curve)>::iterator i2curve = _edge2curve.find( eIndex ); + + if ( i2curve == _edge2curve.end() ) + { + // sort _LayerEdge's by position on the EDGE + { + map< double, _LayerEdge* > u2edge; + for ( int i = iFrom; i < iTo; ++i ) + u2edge.insert( make_pair( helper.GetNodeU( E, _edges[i]->_nodes[0] ), _edges[i] )); + + ASSERT( u2edge.size() == iTo - iFrom ); + map< double, _LayerEdge* >::iterator u2e = u2edge.begin(); + for ( int i = iFrom; i < iTo; ++i, ++u2e ) + _edges[i] = u2e->second; + + // set _2neibors according to the new order + for ( int i = iFrom; i < iTo-1; ++i ) + if ( _edges[i]->_2neibors->_nodes[1] != _edges[i+1]->_nodes.back() ) + _edges[i]->_2neibors->reverse(); + if ( u2edge.size() > 1 && + _edges[iTo-1]->_2neibors->_nodes[0] != _edges[iTo-2]->_nodes.back() ) + _edges[iTo-1]->_2neibors->reverse(); + } + + SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( eIndex ); + + TopLoc_Location loc; double f,l; + + Handle(Geom_Line) line; + Handle(Geom_Circle) circle; + bool isLine, isCirc; + if ( F.IsNull() ) // 3D case + { + // check if the EDGE is a line + Handle(Geom_Curve) curve = BRep_Tool::Curve( E, loc, f, l); + if ( curve->IsKind( STANDARD_TYPE( Geom_TrimmedCurve ))) + curve = Handle(Geom_TrimmedCurve)::DownCast( curve )->BasisCurve(); + + line = Handle(Geom_Line)::DownCast( curve ); + circle = Handle(Geom_Circle)::DownCast( curve ); + isLine = (!line.IsNull()); + isCirc = (!circle.IsNull()); + + if ( !isLine && !isCirc ) // Check if the EDGE is close to a line + { + Bnd_B3d bndBox; + SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); + while ( nIt->more() ) + bndBox.Add( SMESH_TNodeXYZ( nIt->next() )); + gp_XYZ size = bndBox.CornerMax() - bndBox.CornerMin(); + + SMESH_TNodeXYZ p0( _edges[iFrom]->_2neibors->_nodes[0] ); + SMESH_TNodeXYZ p1( _edges[iFrom]->_2neibors->_nodes[1] ); + const double lineTol = 1e-2 * ( p0 - p1 ).Modulus(); + for ( int i = 0; i < 3 && !isLine; ++i ) + isLine = ( size.Coord( i+1 ) <= lineTol ); + } + if ( !isLine && !isCirc && iTo-iFrom > 2) // Check if the EDGE is close to a circle + { + // TODO + } + } + else // 2D case + { + // check if the EDGE is a line + Handle(Geom2d_Curve) curve = BRep_Tool::CurveOnSurface( E, F, f, l); + if ( curve->IsKind( STANDARD_TYPE( Geom2d_TrimmedCurve ))) + curve = Handle(Geom2d_TrimmedCurve)::DownCast( curve )->BasisCurve(); + + Handle(Geom2d_Line) line2d = Handle(Geom2d_Line)::DownCast( curve ); + Handle(Geom2d_Circle) circle2d = Handle(Geom2d_Circle)::DownCast( curve ); + isLine = (!line2d.IsNull()); + isCirc = (!circle2d.IsNull()); + + if ( !isLine && !isCirc) // Check if the EDGE is close to a line + { + Bnd_B2d bndBox; + SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); + while ( nIt->more() ) + bndBox.Add( helper.GetNodeUV( F, nIt->next() )); + gp_XY size = bndBox.CornerMax() - bndBox.CornerMin(); + + const double lineTol = 1e-2 * sqrt( bndBox.SquareExtent() ); + for ( int i = 0; i < 2 && !isLine; ++i ) + isLine = ( size.Coord( i+1 ) <= lineTol ); + } + if ( !isLine && !isCirc && iTo-iFrom > 2) // Check if the EDGE is close to a circle + { + // TODO + } + if ( isLine ) + { + line = new Geom_Line( gp::OX() ); // only type does matter + } + else if ( isCirc ) + { + gp_Pnt2d p = circle2d->Location(); + gp_Ax2 ax( gp_Pnt( p.X(), p.Y(), 0), gp::DX()); + circle = new Geom_Circle( ax, 1.); // only center position does matter + } + } + + Handle(Geom_Curve)& res = _edge2curve[ eIndex ]; + if ( isLine ) + res = line; + else if ( isCirc ) + res = circle; + + return res; + } + return i2curve->second; +} + +//================================================================================ +/*! + * \brief smooth _LayerEdge's on a staight EDGE or circular EDGE + */ +//================================================================================ + +bool _ViscousBuilder::smoothAnalyticEdge( _SolidData& data, + const int iFrom, + const int iTo, + Handle(Geom_Surface)& surface, + const TopoDS_Face& F, + SMESH_MesherHelper& helper) +{ + TopoDS_Shape S = helper.GetSubShapeByNode( data._edges[ iFrom ]->_nodes[0], + helper.GetMeshDS()); + TopoDS_Edge E = TopoDS::Edge( S ); + + Handle(Geom_Curve) curve = data.CurveForSmooth( E, iFrom, iTo, surface, F, helper ); + if ( curve.IsNull() ) return false; + + // compute a relative length of segments + vector< double > len( iTo-iFrom+1 ); + { + double curLen, prevLen = len[0] = 1.0; + for ( int i = iFrom; i < iTo; ++i ) + { + curLen = prevLen * data._edges[i]->_2neibors->_wgt[0] / data._edges[i]->_2neibors->_wgt[1]; + len[i-iFrom+1] = len[i-iFrom] + curLen; + prevLen = curLen; + } + } + + if ( curve->IsKind( STANDARD_TYPE( Geom_Line ))) + { + if ( F.IsNull() ) // 3D + { + SMESH_TNodeXYZ p0( data._edges[iFrom]->_2neibors->_nodes[0]); + SMESH_TNodeXYZ p1( data._edges[iTo-1]->_2neibors->_nodes[1]); + for ( int i = iFrom; i < iTo; ++i ) + { + double r = len[i-iFrom] / len.back(); + gp_XYZ newPos = p0 * ( 1. - r ) + p1 * r; + data._edges[i]->_pos.back() = newPos; + SMDS_MeshNode* tgtNode = const_cast( data._edges[i]->_nodes.back() ); + tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); + dumpMove( tgtNode ); + } + } + else + { + gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->_nodes[0]); + gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->_nodes[1]); + if ( data._edges[iFrom]->_2neibors->_nodes[0] == + data._edges[iTo-1]->_2neibors->_nodes[1] ) // closed edge + { + int iPeriodic = helper.GetPeriodicIndex(); + if ( iPeriodic == 1 || iPeriodic == 2 ) + { + uv1.SetCoord( iPeriodic, helper.GetOtherParam( uv1.Coord( iPeriodic ))); + if ( uv0.Coord( iPeriodic ) > uv1.Coord( iPeriodic )) + std::swap( uv0, uv1 ); + } + } + const gp_XY rangeUV = uv1 - uv0; + for ( int i = iFrom; i < iTo; ++i ) + { + double r = len[i-iFrom] / len.back(); + gp_XY newUV = uv0 + r * rangeUV; + data._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 ); + + gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() ); + SMDS_MeshNode* tgtNode = const_cast( data._edges[i]->_nodes.back() ); + tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); + dumpMove( tgtNode ); + + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + pos->SetUParameter( newUV.X() ); + pos->SetVParameter( newUV.Y() ); + } + } + return true; + } + + if ( curve->IsKind( STANDARD_TYPE( Geom_Circle ))) + { + Handle(Geom_Circle) circle = Handle(Geom_Circle)::DownCast( curve ); + gp_Pnt center3D = circle->Location(); + + if ( F.IsNull() ) // 3D + { + return false; // TODO ??? + } + else // 2D + { + const gp_XY center( center3D.X(), center3D.Y() ); + + gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->_nodes[0]); + gp_XY uvM = helper.GetNodeUV( F, data._edges[iFrom]->_nodes.back()); + gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->_nodes[1]); + gp_Vec2d vec0( center, uv0 ); + gp_Vec2d vecM( center, uvM); + gp_Vec2d vec1( center, uv1 ); + double uLast = vec0.Angle( vec1 ); // -PI - +PI + double uMidl = vec0.Angle( vecM ); + if ( uLast < 0 ) uLast += 2.*M_PI; // 0.0 - 2*PI + if ( uMidl < 0 ) uMidl += 2.*M_PI; + const bool sense = ( uMidl < uLast ); + const double radius = 0.5 * ( vec0.Magnitude() + vec1.Magnitude() ); + + gp_Ax2d axis( center, vec0 ); + gp_Circ2d circ ( axis, radius, sense ); + for ( int i = iFrom; i < iTo; ++i ) + { + double newU = uLast * len[i-iFrom] / len.back(); + gp_Pnt2d newUV = ElCLib::Value( newU, circ ); + data._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 ); + + gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() ); + SMDS_MeshNode* tgtNode = const_cast( data._edges[i]->_nodes.back() ); + tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); + dumpMove( tgtNode ); + + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + pos->SetUParameter( newUV.X() ); + pos->SetVParameter( newUV.Y() ); + } + } + return true; + } + + return false; +} + +//================================================================================ +/*! + * \brief Modify normals of _LayerEdge's on EDGE's to avoid intersection with + * _LayerEdge's on neighbor EDGE's + */ +//================================================================================ + +bool _ViscousBuilder::updateNormals( _SolidData& data, + SMESH_MesherHelper& helper ) +{ + // make temporary quadrangles got by extrusion of + // mesh edges along _LayerEdge._normal's + + vector< const SMDS_MeshElement* > tmpFaces; + { + set< SMESH_TLink > extrudedLinks; // contains target nodes + vector< const SMDS_MeshNode*> nodes(4); // of a tmp mesh face + + dumpFunction(SMESH_Comment("makeTmpFacesOnEdges")<IsOnEdge() || !edge->_sWOL.IsNull() ) continue; + const SMDS_MeshNode* tgt1 = edge->_nodes.back(); + for ( int j = 0; j < 2; ++j ) // loop on _2NearEdges + { + const SMDS_MeshNode* tgt2 = edge->_2neibors->_nodes[j]; + pair< set< SMESH_TLink >::iterator, bool > link_isnew = + extrudedLinks.insert( SMESH_TLink( tgt1, tgt2 )); + if ( !link_isnew.second ) + { + extrudedLinks.erase( link_isnew.first ); + continue; // already extruded and will no more encounter + } + // look for a _LayerEdge containg tgt2 +// _LayerEdge* neiborEdge = 0; +// unsigned di = 0; // check _edges[i+di] and _edges[i-di] +// while ( !neiborEdge && ++di <= data._edges.size() ) +// { +// if ( i+di < data._edges.size() && data._edges[i+di]->_nodes.back() == tgt2 ) +// neiborEdge = data._edges[i+di]; +// else if ( di <= i && data._edges[i-di]->_nodes.back() == tgt2 ) +// neiborEdge = data._edges[i-di]; +// } +// if ( !neiborEdge ) +// return error("updateNormals(): neighbor _LayerEdge not found", data._index); + _LayerEdge* neiborEdge = edge->_2neibors->_edges[j]; + + TmpMeshFaceOnEdge* f = new TmpMeshFaceOnEdge( edge, neiborEdge, --_tmpFaceID ); + tmpFaces.push_back( f ); + + dumpCmd(SMESH_Comment("mesh.AddFace([ ") + <_nn[0]->GetID()<<", "<_nn[1]->GetID()<<", " + <_nn[2]->GetID()<<", "<_nn[3]->GetID()<<" ])"); + } + } + dumpFunctionEnd(); + } + // Check if _LayerEdge's based on EDGE's intersects tmpFaces. + // Perform two loops on _LayerEdge on EDGE's: + // 1) to find and fix intersection + // 2) to check that no new intersection appears as result of 1) + + SMESH_MeshEditor editor( _mesh ); + SMDS_ElemIteratorPtr fIt( new SMDS_ElementVectorIterator( tmpFaces.begin(), + tmpFaces.end())); + auto_ptr searcher ( editor.GetElementSearcher( fIt )); + + // 1) Find intersections + double dist; + const SMDS_MeshElement* face; + typedef map< _LayerEdge*, set< _LayerEdge*, _LayerEdgeCmp >, _LayerEdgeCmp > TLEdge2LEdgeSet; + TLEdge2LEdgeSet edge2CloseEdge; + + const double eps = data._epsilon * data._epsilon; + for ( unsigned i = 0; i < data._edges.size(); ++i ) + { + _LayerEdge* edge = data._edges[i]; + if ( !edge->IsOnEdge() || !edge->_sWOL.IsNull() ) continue; + if ( edge->FindIntersection( *searcher, dist, eps, &face )) + { + const TmpMeshFaceOnEdge* f = (const TmpMeshFaceOnEdge*) face; + set< _LayerEdge*, _LayerEdgeCmp > & ee = edge2CloseEdge[ edge ]; + ee.insert( f->_le1 ); + ee.insert( f->_le2 ); + if ( f->_le1->IsOnEdge() && f->_le1->_sWOL.IsNull() ) + edge2CloseEdge[ f->_le1 ].insert( edge ); + if ( f->_le2->IsOnEdge() && f->_le2->_sWOL.IsNull() ) + edge2CloseEdge[ f->_le2 ].insert( edge ); + } + } + + // Set _LayerEdge._normal + + if ( !edge2CloseEdge.empty() ) + { + dumpFunction(SMESH_Comment("updateNormals")<first; + _LayerEdge* edge2 = 0; + set< _LayerEdge*, _LayerEdgeCmp >& ee = e2ee->second; + + // find EDGEs the edges reside + TopoDS_Edge E1, E2; + TopoDS_Shape S = helper.GetSubShapeByNode( edge1->_nodes[0], getMeshDS() ); + if ( S.ShapeType() != TopAbs_EDGE ) + continue; // TODO: find EDGE by VERTEX + E1 = TopoDS::Edge( S ); + set< _LayerEdge*, _LayerEdgeCmp >::iterator eIt = ee.begin(); + while ( E2.IsNull() && eIt != ee.end()) + { + _LayerEdge* e2 = *eIt++; + TopoDS_Shape S = helper.GetSubShapeByNode( e2->_nodes[0], getMeshDS() ); + if ( S.ShapeType() == TopAbs_EDGE ) + E2 = TopoDS::Edge( S ), edge2 = e2; + } + if ( E2.IsNull() ) continue; // TODO: find EDGE by VERTEX + + // find 3 FACEs sharing 2 EDGEs + + TopoDS_Face FF1[2], FF2[2]; + PShapeIteratorPtr fIt = helper.GetAncestors(E1, *_mesh, TopAbs_FACE); + while ( fIt->more() && FF1[1].IsNull()) + { + const TopoDS_Face *F = (const TopoDS_Face*) fIt->next(); + if ( helper.IsSubShape( *F, data._solid)) + FF1[ FF1[0].IsNull() ? 0 : 1 ] = *F; + } + fIt = helper.GetAncestors(E2, *_mesh, TopAbs_FACE); + while ( fIt->more() && FF2[1].IsNull()) + { + const TopoDS_Face *F = (const TopoDS_Face*) fIt->next(); + if ( helper.IsSubShape( *F, data._solid)) + FF2[ FF2[0].IsNull() ? 0 : 1 ] = *F; + } + // exclude a FACE common to E1 and E2 (put it at [1] in FF* ) + if ( FF1[0].IsSame( FF2[0]) || FF1[0].IsSame( FF2[1])) + std::swap( FF1[0], FF1[1] ); + if ( FF2[0].IsSame( FF1[0]) ) + std::swap( FF2[0], FF2[1] ); + if ( FF1[0].IsNull() || FF2[0].IsNull() ) + continue; + +// // get a new normal for edge1 + bool ok; + gp_Vec dir1 = edge1->_normal, dir2 = edge2->_normal; + if ( edge1->_cosin < 0 ) + dir1 = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok ).Normalized(); + if ( edge2->_cosin < 0 ) + dir2 = getFaceDir( FF2[0], E2, edge2->_nodes[0], helper, ok ).Normalized(); + // gp_Vec dir1 = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok ); +// gp_Vec dir2 = getFaceDir( FF2[0], E2, edge2->_nodes[0], helper, ok2 ); +// double wgt1 = ( edge1->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 ); +// double wgt2 = ( edge2->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 ); +// gp_Vec newNorm = wgt1 * dir1 + wgt2 * dir2; +// newNorm.Normalize(); + + double wgt1 = ( edge1->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 ); + double wgt2 = ( edge2->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 ); + gp_Vec newNorm = wgt1 * dir1 + wgt2 * dir2; + newNorm.Normalize(); + + edge1->_normal = newNorm.XYZ(); + + // update data of edge1 depending on _normal + const SMDS_MeshNode *n1, *n2; + n1 = edge1->_2neibors->_edges[0]->_nodes[0]; + n2 = edge1->_2neibors->_edges[1]->_nodes[0]; + //if ( !findNeiborsOnEdge( edge1, n1, n2, data )) + //continue; + edge1->SetDataByNeighbors( n1, n2, helper ); + gp_Vec dirInFace; + if ( edge1->_cosin < 0 ) + dirInFace = dir1; + else + getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok ); + double angle = dir1.Angle( edge1->_normal ); // [0,PI] + edge1->SetCosin( cos( angle )); + + // limit data._stepSize + if ( edge1->_cosin > 0.1 ) + { + SMDS_ElemIteratorPtr fIt = edge1->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + limitStepSize( data, fIt->next(), edge1->_cosin ); + } + // set new XYZ of target node + edge1->InvalidateStep( 1 ); + edge1->_len = 0; + edge1->SetNewLength( data._stepSize, helper ); + } + + // Update normals and other dependent data of not intersecting _LayerEdge's + // neighboring the intersecting ones + + for ( e2ee = edge2CloseEdge.begin(); e2ee != edge2CloseEdge.end(); ++e2ee ) + { + _LayerEdge* edge1 = e2ee->first; + if ( !edge1->_2neibors ) + continue; + for ( int j = 0; j < 2; ++j ) // loop on 2 neighbors + { + _LayerEdge* neighbor = edge1->_2neibors->_edges[j]; + if ( edge2CloseEdge.count ( neighbor )) + continue; // j-th neighbor is also intersected + _LayerEdge* prevEdge = edge1; + const int nbSteps = 6; + for ( int step = nbSteps; step; --step ) // step from edge1 in j-th direction + { + if ( !neighbor->_2neibors ) + break; // neighbor is on VERTEX + int iNext = 0; + _LayerEdge* nextEdge = neighbor->_2neibors->_edges[iNext]; + if ( nextEdge == prevEdge ) + nextEdge = neighbor->_2neibors->_edges[ ++iNext ]; +// const double& wgtPrev = neighbor->_2neibors->_wgt[1-iNext]; +// const double& wgtNext = neighbor->_2neibors->_wgt[iNext]; + double r = double(step-1)/nbSteps; + if ( !nextEdge->_2neibors ) + r = 0.5; + + gp_XYZ newNorm = prevEdge->_normal * r + nextEdge->_normal * (1-r); + newNorm.Normalize(); + + neighbor->_normal = newNorm; + neighbor->SetCosin( prevEdge->_cosin * r + nextEdge->_cosin * (1-r) ); + neighbor->SetDataByNeighbors( prevEdge->_nodes[0], nextEdge->_nodes[0], helper ); + + neighbor->InvalidateStep( 1 ); + neighbor->_len = 0; + neighbor->SetNewLength( data._stepSize, helper ); + + // goto the next neighbor + prevEdge = neighbor; + neighbor = nextEdge; + } + } + } + dumpFunctionEnd(); + } + // 2) Check absence of intersections + // TODO? + + for ( unsigned i = 0 ; i < tmpFaces.size(); ++i ) + delete tmpFaces[i]; + + return true; +} + +//================================================================================ +/*! + * \brief Looks for intersection of it's last segment with faces + * \param distance - returns shortest distance from the last node to intersection + */ +//================================================================================ + +bool _LayerEdge::FindIntersection( SMESH_ElementSearcher& searcher, + double & distance, + const double& epsilon, + const SMDS_MeshElement** face) +{ + vector< const SMDS_MeshElement* > suspectFaces; + double segLen; + gp_Ax1 lastSegment = LastSegment(segLen); + searcher.GetElementsNearLine( lastSegment, SMDSAbs_Face, suspectFaces ); + + bool segmentIntersected = false; + distance = Precision::Infinite(); + int iFace = -1; // intersected face + for ( unsigned j = 0 ; j < suspectFaces.size() && !segmentIntersected; ++j ) + { + const SMDS_MeshElement* face = suspectFaces[j]; + if ( face->GetNodeIndex( _nodes.back() ) >= 0 || + face->GetNodeIndex( _nodes[0] ) >= 0 ) + continue; // face sharing _LayerEdge node + const int nbNodes = face->NbCornerNodes(); + bool intFound = false; + double dist; + SMDS_MeshElement::iterator nIt = face->begin_nodes(); + if ( nbNodes == 3 ) + { + intFound = SegTriaInter( lastSegment, *nIt++, *nIt++, *nIt++, dist, epsilon ); + } + else + { + const SMDS_MeshNode* tria[3]; + tria[0] = *nIt++; + tria[1] = *nIt++;; + for ( int n2 = 2; n2 < nbNodes && !intFound; ++n2 ) + { + tria[2] = *nIt++; + intFound = SegTriaInter(lastSegment, tria[0], tria[1], tria[2], dist, epsilon ); + tria[1] = tria[2]; + } + } + if ( intFound ) + { + if ( dist < segLen*(1.01)) + segmentIntersected = true; + if ( distance > dist ) + distance = dist, iFace = j; + } + } + if ( iFace != -1 && face ) *face = suspectFaces[iFace]; +// if ( distance && iFace > -1 ) +// { +// // distance is used to limit size of inflation step which depends on +// // whether the intersected face bears viscous layers or not +// bool faceHasVL = suspectFaces[iFace]->GetID() < 1; +// if ( faceHasVL ) +// *distance /= 2; +// } + if ( segmentIntersected ) + { +#ifdef __myDEBUG + SMDS_MeshElement::iterator nIt = suspectFaces[iFace]->begin_nodes(); + gp_XYZ intP( lastSegment.Location().XYZ() + lastSegment.Direction().XYZ() * distance ); + cout << "nodes: tgt " << _nodes.back()->GetID() << " src " << _nodes[0]->GetID() + << ", intersection with face (" + << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID() + << ") at point (" << intP.X() << ", " << intP.Y() << ", " << intP.Z() + << ") distance = " << distance - segLen<< endl; +#endif + } + + distance -= segLen; + + return segmentIntersected; +} + +//================================================================================ +/*! + * \brief Returns size and direction of the last segment + */ +//================================================================================ + +gp_Ax1 _LayerEdge::LastSegment(double& segLen) const +{ + // find two non-coincident positions + gp_XYZ orig = _pos.back(); + gp_XYZ dir; + int iPrev = _pos.size() - 2; + while ( iPrev >= 0 ) + { + dir = orig - _pos[iPrev]; + if ( dir.SquareModulus() > 1e-100 ) + break; + else + iPrev--; + } + + // make gp_Ax1 + gp_Ax1 segDir; + if ( iPrev < 0 ) + { + segDir.SetLocation( SMESH_TNodeXYZ( _nodes[0] )); + segDir.SetDirection( _normal ); + segLen = 0; + } + else + { + gp_Pnt pPrev = _pos[ iPrev ]; + if ( !_sWOL.IsNull() ) + { + TopLoc_Location loc; + if ( _sWOL.ShapeType() == TopAbs_EDGE ) + { + double f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( _sWOL ), loc, f,l); + pPrev = curve->Value( pPrev.X() ).Transformed( loc ); + } + else + { + Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(_sWOL), loc ); + pPrev = surface->Value( pPrev.X(), pPrev.Y() ).Transformed( loc ); + } + dir = SMESH_TNodeXYZ( _nodes.back() ) - pPrev.XYZ(); + } + segDir.SetLocation( pPrev ); + segDir.SetDirection( dir ); + segLen = dir.Modulus(); + } + + return segDir; +} + +//================================================================================ +/*! + * \brief Test intersection of the last segment with a given triangle + * using Moller-Trumbore algorithm + * Intersection is detected if distance to intersection is less than _LayerEdge._len + */ +//================================================================================ + +bool _LayerEdge::SegTriaInter( const gp_Ax1& lastSegment, + const SMDS_MeshNode* n0, + const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + double& t, + const double& EPSILON) const +{ + //const double EPSILON = 1e-6; + + gp_XYZ orig = lastSegment.Location().XYZ(); + gp_XYZ dir = lastSegment.Direction().XYZ(); + + SMESH_TNodeXYZ vert0( n0 ); + SMESH_TNodeXYZ vert1( n1 ); + SMESH_TNodeXYZ vert2( n2 ); + + /* calculate distance from vert0 to ray origin */ + gp_XYZ tvec = orig - vert0; + + if ( tvec * dir > EPSILON ) + // intersected face is at back side of the temporary face this _LayerEdge belongs to + return false; + + gp_XYZ edge1 = vert1 - vert0; + gp_XYZ edge2 = vert2 - vert0; + + /* begin calculating determinant - also used to calculate U parameter */ + gp_XYZ pvec = dir ^ edge2; + + /* if determinant is near zero, ray lies in plane of triangle */ + double det = edge1 * pvec; + + if (det > -EPSILON && det < EPSILON) + return 0; + double inv_det = 1.0 / det; + + /* calculate U parameter and test bounds */ + double u = ( tvec * pvec ) * inv_det; + if (u < 0.0 || u > 1.0) + return 0; + + /* prepare to test V parameter */ + gp_XYZ qvec = tvec ^ edge1; + + /* calculate V parameter and test bounds */ + double v = (dir * qvec) * inv_det; + if ( v < 0.0 || u + v > 1.0 ) + return 0; + + /* calculate t, ray intersects triangle */ + t = (edge2 * qvec) * inv_det; + + // if (det < EPSILON) + // return false; + + // /* calculate distance from vert0 to ray origin */ + // gp_XYZ tvec = orig - vert0; + + // /* calculate U parameter and test bounds */ + // double u = tvec * pvec; + // if (u < 0.0 || u > det) +// return 0; + +// /* prepare to test V parameter */ +// gp_XYZ qvec = tvec ^ edge1; + +// /* calculate V parameter and test bounds */ +// double v = dir * qvec; +// if (v < 0.0 || u + v > det) +// return 0; + +// /* calculate t, scale parameters, ray intersects triangle */ +// double t = edge2 * qvec; +// double inv_det = 1.0 / det; +// t *= inv_det; +// //u *= inv_det; +// //v *= inv_det; + + return true; +} + +//================================================================================ +/*! + * \brief Perform smooth of _LayerEdge's based on EDGE's + * \retval bool - true if node has been moved + */ +//================================================================================ + +bool _LayerEdge::SmoothOnEdge(Handle(Geom_Surface)& surface, + const TopoDS_Face& F, + SMESH_MesherHelper& helper) +{ + ASSERT( IsOnEdge() ); + + SMDS_MeshNode* tgtNode = const_cast( _nodes.back() ); + SMESH_TNodeXYZ oldPos( tgtNode ); + double dist01, distNewOld; + + SMESH_TNodeXYZ p0( _2neibors->_nodes[0]); + SMESH_TNodeXYZ p1( _2neibors->_nodes[1]); + dist01 = p0.Distance( _2neibors->_nodes[1] ); + + gp_Pnt newPos = p0 * _2neibors->_wgt[0] + p1 * _2neibors->_wgt[1]; + double lenDelta = 0; + if ( _curvature ) + { + lenDelta = _curvature->lenDelta( _len ); + newPos.ChangeCoord() += _normal * lenDelta; + } + + distNewOld = newPos.Distance( oldPos ); + + if ( F.IsNull() ) + { + if ( _2neibors->_plnNorm ) + { + // put newPos on the plane defined by source node and _plnNorm + gp_XYZ new2src = SMESH_TNodeXYZ( _nodes[0] ) - newPos.XYZ(); + double new2srcProj = (*_2neibors->_plnNorm) * new2src; + newPos.ChangeCoord() += (*_2neibors->_plnNorm) * new2srcProj; + } + tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); + _pos.back() = newPos.XYZ(); + } + else + { + tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); + gp_XY uv( Precision::Infinite(), 0 ); + helper.CheckNodeUV( F, tgtNode, uv, 1e-10, /*force=*/true ); + _pos.back().SetCoord( uv.X(), uv.Y(), 0 ); + + newPos = surface->Value( uv.X(), uv.Y() ); + tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() ); + } + + if ( _curvature && lenDelta < 0 ) + { + gp_Pnt prevPos( _pos[ _pos.size()-2 ]); + _len -= prevPos.Distance( oldPos ); + _len += prevPos.Distance( newPos ); + } + bool moved = distNewOld > dist01/50; + //if ( moved ) + dumpMove( tgtNode ); // debug + + return moved; +} + +//================================================================================ +/*! + * \brief Perform laplacian smooth in 3D of nodes inflated from FACE + * \retval bool - true if _tgtNode has been moved + */ +//================================================================================ + +bool _LayerEdge::Smooth(int& badNb) +{ + if ( _simplices.size() < 2 ) + return false; // _LayerEdge inflated along EDGE or FACE + + // compute new position for the last _pos + gp_XYZ newPos (0,0,0); + for ( unsigned i = 0; i < _simplices.size(); ++i ) + newPos += SMESH_TNodeXYZ( _simplices[i]._nPrev ); + newPos /= _simplices.size(); + + if ( _curvature ) + newPos += _normal * _curvature->lenDelta( _len ); + + gp_Pnt prevPos( _pos[ _pos.size()-2 ]); +// if ( _cosin < -0.1) +// { +// // Avoid decreasing length of edge on concave surface +// //gp_Vec oldMove( _pos[ _pos.size()-2 ], _pos.back() ); +// gp_Vec newMove( prevPos, newPos ); +// newPos = _pos.back() + newMove.XYZ(); +// } +// else if ( _cosin > 0.3 ) +// { +// // Avoid increasing length of edge too much + +// } + // count quality metrics (orientation) of tetras around _tgtNode + int nbOkBefore = 0; + SMESH_TNodeXYZ tgtXYZ( _nodes.back() ); + for ( unsigned i = 0; i < _simplices.size(); ++i ) + nbOkBefore += _simplices[i].IsForward( _nodes[0], &tgtXYZ ); + + int nbOkAfter = 0; + for ( unsigned i = 0; i < _simplices.size(); ++i ) + nbOkAfter += _simplices[i].IsForward( _nodes[0], &newPos ); + + if ( nbOkAfter < nbOkBefore ) + return false; + + SMDS_MeshNode* n = const_cast< SMDS_MeshNode* >( _nodes.back() ); + + _len -= prevPos.Distance(SMESH_TNodeXYZ( n )); + _len += prevPos.Distance(newPos); + + n->setXYZ( newPos.X(), newPos.Y(), newPos.Z()); + _pos.back() = newPos; + + badNb += _simplices.size() - nbOkAfter; + + dumpMove( n ); + + return true; +} + +//================================================================================ +/*! + * \brief Add a new segment to _LayerEdge during inflation + */ +//================================================================================ + +void _LayerEdge::SetNewLength( double len, SMESH_MesherHelper& helper ) +{ + if ( _len - len > -1e-6 ) + { + _pos.push_back( _pos.back() ); + return; + } + + SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( _nodes.back() ); + SMESH_TNodeXYZ oldXYZ( n ); + gp_XYZ nXYZ = oldXYZ + _normal * ( len - _len ) * _lenFactor; + n->setXYZ( nXYZ.X(), nXYZ.Y(), nXYZ.Z() ); + + _pos.push_back( nXYZ ); + _len = len; + if ( !_sWOL.IsNull() ) + { + double distXYZ[4]; + if ( _sWOL.ShapeType() == TopAbs_EDGE ) + { + double u = Precision::Infinite(); // to force projection w/o distance check + helper.CheckNodeU( TopoDS::Edge( _sWOL ), n, u, 1e-10, /*force=*/true, distXYZ ); + _pos.back().SetCoord( u, 0, 0 ); + SMDS_EdgePosition* pos = static_cast( n->GetPosition() ); + pos->SetUParameter( u ); + } + else // TopAbs_FACE + { + gp_XY uv( Precision::Infinite(), 0 ); + helper.CheckNodeUV( TopoDS::Face( _sWOL ), n, uv, 1e-10, /*force=*/true, distXYZ ); + _pos.back().SetCoord( uv.X(), uv.Y(), 0 ); + SMDS_FacePosition* pos = static_cast( n->GetPosition() ); + pos->SetUParameter( uv.X() ); + pos->SetVParameter( uv.Y() ); + } + n->setXYZ( distXYZ[1], distXYZ[2], distXYZ[3]); + } + dumpMove( n ); //debug +} + +//================================================================================ +/*! + * \brief Remove last inflation step + */ +//================================================================================ + +void _LayerEdge::InvalidateStep( int curStep ) +{ + if ( _pos.size() > curStep ) + { + _pos.resize( curStep ); + gp_Pnt nXYZ = _pos.back(); + SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( _nodes.back() ); + if ( !_sWOL.IsNull() ) + { + TopLoc_Location loc; + if ( _sWOL.ShapeType() == TopAbs_EDGE ) + { + SMDS_EdgePosition* pos = static_cast( n->GetPosition() ); + pos->SetUParameter( nXYZ.X() ); + double f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( _sWOL ), loc, f,l); + nXYZ = curve->Value( nXYZ.X() ).Transformed( loc ); + } + else + { + SMDS_FacePosition* pos = static_cast( n->GetPosition() ); + pos->SetUParameter( nXYZ.X() ); + pos->SetVParameter( nXYZ.Y() ); + Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(_sWOL), loc ); + nXYZ = surface->Value( nXYZ.X(), nXYZ.Y() ).Transformed( loc ); + } + } + n->setXYZ( nXYZ.X(), nXYZ.Y(), nXYZ.Z() ); + dumpMove( n ); + } +} + +//================================================================================ +/*! + * \brief Create layers of prisms + */ +//================================================================================ + +bool _ViscousBuilder::refine(_SolidData& data) +{ + SMESH_MesherHelper helper( *_mesh ); + helper.SetSubShape( data._solid ); + helper.SetElementsOnShape(false); + + Handle(Geom_Curve) curve; + Handle(Geom_Surface) surface; + TopoDS_Edge geomEdge; + TopoDS_Face geomFace; + TopLoc_Location loc; + double f,l, u/*, distXYZ[4]*/; + gp_XY uv; + bool isOnEdge; + + for ( unsigned i = 0; i < data._edges.size(); ++i ) + { + _LayerEdge& edge = *data._edges[i]; + + // get accumulated length of segments + vector< double > segLen( edge._pos.size() ); + segLen[0] = 0.0; + for ( unsigned j = 1; j < edge._pos.size(); ++j ) + segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus(); + + // allocate memory for new nodes if it is not yet refined + const SMDS_MeshNode* tgtNode = edge._nodes.back(); + if ( edge._nodes.size() == 2 ) + { + edge._nodes.resize( data._hyp->GetNumberLayers() + 1, 0 ); + edge._nodes[1] = 0; + edge._nodes.back() = tgtNode; + } + if ( !edge._sWOL.IsNull() ) + { + isOnEdge = ( edge._sWOL.ShapeType() == TopAbs_EDGE ); + // restore position of the last node +// gp_Pnt p; + if ( isOnEdge ) + { + geomEdge = TopoDS::Edge( edge._sWOL ); + curve = BRep_Tool::Curve( geomEdge, loc, f,l); +// double u = helper.GetNodeU( tgtNode ); +// p = curve->Value( u ); + } + else + { + geomFace = TopoDS::Face( edge._sWOL ); + surface = BRep_Tool::Surface( geomFace, loc ); +// gp_XY uv = helper.GetNodeUV( tgtNode ); +// p = surface->Value( uv.X(), uv.Y() ); + } +// p.Transform( loc ); +// const_cast< SMDS_MeshNode* >( tgtNode )->setXYZ( p.X(), p.Y(), p.Z() ); + } + // calculate height of the first layer + double h0; + const double T = segLen.back(); //data._hyp.GetTotalThickness(); + const double f = data._hyp->GetStretchFactor(); + const int N = data._hyp->GetNumberLayers(); + const double fPowN = pow( f, N ); + if ( fPowN - 1 <= numeric_limits::min() ) + h0 = T / N; + else + h0 = T * ( f - 1 )/( fPowN - 1 ); + + const double zeroLen = std::numeric_limits::min(); + + // create intermediate nodes + double hSum = 0, hi = h0/f; + unsigned iSeg = 1; + for ( unsigned iStep = 1; iStep < edge._nodes.size(); ++iStep ) + { + // compute an intermediate position + hi *= f; + hSum += hi; + while ( hSum > segLen[iSeg] && iSeg < segLen.size()-1) + ++iSeg; + int iPrevSeg = iSeg-1; + while ( fabs( segLen[iPrevSeg] - segLen[iSeg]) <= zeroLen && iPrevSeg > 0 ) + --iPrevSeg; + double r = ( segLen[iSeg] - hSum ) / ( segLen[iSeg] - segLen[iPrevSeg] ); + gp_Pnt pos = r * edge._pos[iPrevSeg] + (1-r) * edge._pos[iSeg]; + + SMDS_MeshNode*& node = const_cast< SMDS_MeshNode*& >(edge._nodes[ iStep ]); + if ( !edge._sWOL.IsNull() ) + { + // compute XYZ by parameters + if ( isOnEdge ) + { + u = pos.X(); + pos = curve->Value( u ).Transformed(loc); + } + else + { + uv.SetCoord( pos.X(), pos.Y() ); + pos = surface->Value( pos.X(), pos.Y() ).Transformed(loc); + } + } + // create or update the node + if ( !node ) + { + node = helper.AddNode( pos.X(), pos.Y(), pos.Z()); + if ( !edge._sWOL.IsNull() ) + { + if ( isOnEdge ) + getMeshDS()->SetNodeOnEdge( node, geomEdge, u ); + else + getMeshDS()->SetNodeOnFace( node, geomFace, uv.X(), uv.Y() ); + } + else + { + getMeshDS()->SetNodeInVolume( node, helper.GetSubShapeID() ); + } + } + else + { + if ( !edge._sWOL.IsNull() ) + { + // make average pos from new and current parameters + if ( isOnEdge ) + { + u = 0.5 * ( u + helper.GetNodeU( geomEdge, node )); + pos = curve->Value( u ).Transformed(loc); + } + else + { + uv = 0.5 * ( uv + helper.GetNodeUV( geomFace, node )); + pos = surface->Value( uv.X(), uv.Y()).Transformed(loc); + } + } + node->setXYZ( pos.X(), pos.Y(), pos.Z() ); + } + } + } + + // TODO: make quadratic prisms and polyhedrons(?) + + helper.SetElementsOnShape(true); + + TopExp_Explorer exp( data._solid, TopAbs_FACE ); + for ( ; exp.More(); exp.Next() ) + { + if ( _ignoreShapeIds.count( getMeshDS()->ShapeToIndex( exp.Current() ))) + continue; + SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() ); + SMDS_ElemIteratorPtr fIt = fSubM->GetElements(); + vector< vector* > nnVec; + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + int nbNodes = face->NbCornerNodes(); + nnVec.resize( nbNodes ); + SMDS_ElemIteratorPtr nIt = face->nodesIterator(); + for ( int iN = 0; iN < nbNodes; ++iN ) + { + const SMDS_MeshNode* n = static_cast( nIt->next() ); + nnVec[ iN ] = & data._n2eMap[ n ]->_nodes; + } + + int nbZ = nnVec[0]->size(); + switch ( nbNodes ) + { + case 3: + for ( int iZ = 1; iZ < nbZ; ++iZ ) + helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1], + (*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ]); + break; + case 4: + for ( int iZ = 1; iZ < nbZ; ++iZ ) + helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], + (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1], + (*nnVec[0])[iZ], (*nnVec[1])[iZ], + (*nnVec[2])[iZ], (*nnVec[3])[iZ]); + break; + default: + return error("Not supported type of element", data._index); + } + } + } + return true; +} + +//================================================================================ +/*! + * \brief Shrink 2D mesh on faces to let space for inflated layers + */ +//================================================================================ + +bool _ViscousBuilder::shrink() +{ + // make map of (ids of FACEs to shrink mesh on) to (_SolidData containing _LayerEdge's + // inflated along FACE or EDGE) + map< TGeomID, _SolidData* > f2sdMap; + for ( unsigned i = 0 ; i < _sdVec.size(); ++i ) + { + _SolidData& data = _sdVec[i]; + TopTools_MapOfShape FFMap; + map< TGeomID, TopoDS_Shape >::iterator s2s = data._shrinkShape2Shape.begin(); + for (; s2s != data._shrinkShape2Shape.end(); ++s2s ) + if ( s2s->second.ShapeType() == TopAbs_FACE ) + { + f2sdMap.insert( make_pair( getMeshDS()->ShapeToIndex( s2s->second ), &data )); + + if ( FFMap.Add( (*s2s).second )) + // Put mesh faces on the shrinked FACE to the proxy sub-mesh to avoid + // usage of mesh faces made in addBoundaryElements() by the 3D algo or + // by StdMeshers_QuadToTriaAdaptor + if ( SMESHDS_SubMesh* smDS = getMeshDS()->MeshElements( s2s->second )) + { + SMESH_ProxyMesh::SubMesh* proxySub = + data._proxyMesh->getFaceSubM( TopoDS::Face( s2s->second ), /*create=*/true); + SMDS_ElemIteratorPtr fIt = smDS->GetElements(); + while ( fIt->more() ) + proxySub->AddElement( fIt->next() ); + // as a result 3D algo will use elements from proxySub and not from smDS + } + } + } + + SMESH_MesherHelper helper( *_mesh ); + helper.ToFixNodeParameters( true ); + + // EDGE's to shrink + map< int, _Shrinker1D > e2shrMap; + + // loop on FACES to srink mesh on + map< TGeomID, _SolidData* >::iterator f2sd = f2sdMap.begin(); + for ( ; f2sd != f2sdMap.end(); ++f2sd ) + { + _SolidData& data = *f2sd->second; + TNode2Edge& n2eMap = data._n2eMap; + const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( f2sd->first )); + + Handle(Geom_Surface) surface = BRep_Tool::Surface(F); + + SMESH_subMesh* sm = _mesh->GetSubMesh( F ); + SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + + helper.SetSubShape(F); + + // =========================== + // Prepare data for shrinking + // =========================== + + // Collect nodes to smooth, as src nodes are not yet replaced by tgt ones + // and thus all nodes on a FACE connected to 2d elements are to be smoothed + vector < const SMDS_MeshNode* > smoothNodes; + { + SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); + while ( nIt->more() ) + { + const SMDS_MeshNode* n = nIt->next(); + if ( n->NbInverseElements( SMDSAbs_Face ) > 0 ) + smoothNodes.push_back( n ); + } + } + // Find out face orientation + double refSign = 1; + const set ignoreShapes; + bool isOkUV; + if ( !smoothNodes.empty() ) + { + vector<_Simplex> simplices; + getSimplices( smoothNodes[0], simplices, ignoreShapes ); + helper.GetNodeUV( F, simplices[0]._nPrev, 0, &isOkUV ); // fix UV of silpmex nodes + helper.GetNodeUV( F, simplices[0]._nNext, 0, &isOkUV ); + gp_XY uv = helper.GetNodeUV( F, smoothNodes[0], 0, &isOkUV ); + if ( !simplices[0].IsForward(uv, smoothNodes[0], F, helper,refSign) ) + refSign = -1; + } + + // Find _LayerEdge's inflated along F + vector< _LayerEdge* > lEdges; + { + SMESH_subMeshIteratorPtr subIt = + sm->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/false); + while ( subIt->more() ) + { + SMESH_subMesh* sub = subIt->next(); + SMESHDS_SubMesh* subDS = sub->GetSubMeshDS(); + if ( subDS->NbNodes() == 0 || !n2eMap.count( subDS->GetNodes()->next() )) + continue; + SMDS_NodeIteratorPtr nIt = subDS->GetNodes(); + while ( nIt->more() ) + { + _LayerEdge* edge = n2eMap[ nIt->next() ]; + lEdges.push_back( edge ); + prepareEdgeToShrink( *edge, F, helper, smDS ); + } + } + } + + // Replace source nodes by target nodes in mesh faces to shrink + const SMDS_MeshNode* nodes[20]; + for ( unsigned i = 0; i < lEdges.size(); ++i ) + { + _LayerEdge& edge = *lEdges[i]; + const SMDS_MeshNode* srcNode = edge._nodes[0]; + const SMDS_MeshNode* tgtNode = edge._nodes.back(); + SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + { + const SMDS_MeshElement* f = fIt->next(); + if ( !smDS->Contains( f )) + continue; + SMDS_ElemIteratorPtr nIt = f->nodesIterator(); + for ( int iN = 0; iN < f->NbNodes(); ++iN ) + { + const SMDS_MeshNode* n = static_cast( nIt->next() ); + nodes[iN] = ( n == srcNode ? tgtNode : n ); + } + helper.GetMeshDS()->ChangeElementNodes( f, nodes, f->NbNodes() ); + } + } + + // find out if a FACE is concave + const bool isConcaveFace = isConcave( F, helper ); + + // Create _SmoothNode's on face F + vector< _SmoothNode > nodesToSmooth( smoothNodes.size() ); + { + dumpFunction(SMESH_Comment("beforeShrinkFace")<first); // debug + for ( unsigned i = 0; i < smoothNodes.size(); ++i ) + { + const SMDS_MeshNode* n = smoothNodes[i]; + nodesToSmooth[ i ]._node = n; + // src nodes must be replaced by tgt nodes to have tgt nodes in _simplices + getSimplices( n, nodesToSmooth[ i ]._simplices, ignoreShapes, NULL, isConcaveFace ); + // fix up incorrect uv of nodes on the FACE + helper.GetNodeUV( F, n, 0, &isOkUV); + dumpMove( n ); + } + dumpFunctionEnd(); + } + //if ( nodesToSmooth.empty() ) continue; + + // Find EDGE's to shrink + set< _Shrinker1D* > eShri1D; + { + for ( unsigned i = 0; i < lEdges.size(); ++i ) + { + _LayerEdge* edge = lEdges[i]; + if ( edge->_sWOL.ShapeType() == TopAbs_EDGE ) + { + TGeomID edgeIndex = getMeshDS()->ShapeToIndex( edge->_sWOL ); + _Shrinker1D& srinker = e2shrMap[ edgeIndex ]; + eShri1D.insert( & srinker ); + srinker.AddEdge( edge, helper ); + // restore params of nodes on EGDE if the EDGE has been already + // srinked while srinking another FACE + srinker.RestoreParams(); + } + } + } + + // ================== + // Perform shrinking + // ================== + + bool shrinked = true; + int badNb, shriStep=0, smooStep=0; + while ( shrinked ) + { + // Move boundary nodes (actually just set new UV) + // ----------------------------------------------- + dumpFunction(SMESH_Comment("moveBoundaryOnF")<first<<"_st"<SetNewLength2d( surface,F,helper ); + } + dumpFunctionEnd(); + + // Move nodes on EDGE's + set< _Shrinker1D* >::iterator shr = eShri1D.begin(); + for ( ; shr != eShri1D.end(); ++shr ) + (*shr)->Compute( /*set3D=*/false, helper ); + + // Smoothing in 2D + // ----------------- + int nbNoImpSteps = 0; + bool moved = true; + badNb = 1; + while (( nbNoImpSteps < 5 && badNb > 0) && moved) + { + dumpFunction(SMESH_Comment("shrinkFace")<first<<"_st"<<++smooStep); // debug + + int oldBadNb = badNb; + badNb = 0; + moved = false; + for ( unsigned i = 0; i < nodesToSmooth.size(); ++i ) + { + moved |= nodesToSmooth[i].Smooth( badNb,surface,helper,refSign, + /*isCentroidal=*/isConcaveFace,/*set3D=*/false ); + } + if ( badNb < oldBadNb ) + nbNoImpSteps = 0; + else + nbNoImpSteps++; + + dumpFunctionEnd(); + } + if ( badNb > 0 ) + return error(SMESH_Comment("Can't shrink 2D mesh on face ") << f2sd->first ); + } + // No wrongly shaped faces remain; final smooth. Set node XYZ. + // First, find out a needed quality of smoothing (high for quadrangles only) + bool highQuality; + { + const bool hasTria = _mesh->NbTriangles(), hasQuad = _mesh->NbQuadrangles(); + if ( hasTria != hasQuad ) + { + highQuality = hasQuad; + } + else + { + set nbNodesSet; + SMDS_ElemIteratorPtr fIt = smDS->GetElements(); + while ( fIt->more() && nbNodesSet.size() < 2 ) + nbNodesSet.insert( fIt->next()->NbCornerNodes() ); + highQuality = ( *nbNodesSet.begin() == 4 ); + } + } + if ( !highQuality && isConcaveFace ) + fixBadFaces( F, helper ); // fix narrow faces by swaping diagonals + for ( int st = highQuality ? 10 : 3; st; --st ) + { + dumpFunction(SMESH_Comment("shrinkFace")<first<<"_st"<<++smooStep); // debug + for ( unsigned i = 0; i < nodesToSmooth.size(); ++i ) + nodesToSmooth[i].Smooth( badNb,surface,helper,refSign, + /*isCentroidal=*/isConcaveFace,/*set3D=*/st==1 ); + dumpFunctionEnd(); + } + // Set an event listener to clear FACE sub-mesh together with SOLID sub-mesh + _SrinkShapeListener::ToClearSubMeshWithSolid( sm, data._solid ); + + } // loop on FACES to srink mesh on + + + // Replace source nodes by target nodes in shrinked mesh edges + + map< int, _Shrinker1D >::iterator e2shr = e2shrMap.begin(); + for ( ; e2shr != e2shrMap.end(); ++e2shr ) + e2shr->second.SwapSrcTgtNodes( getMeshDS() ); + + return true; +} + +//================================================================================ +/*! + * \brief Computes 2d shrink direction and finds nodes limiting shrinking + */ +//================================================================================ + +bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge& edge, + const TopoDS_Face& F, + SMESH_MesherHelper& helper, + const SMESHDS_SubMesh* faceSubMesh) +{ + const SMDS_MeshNode* srcNode = edge._nodes[0]; + const SMDS_MeshNode* tgtNode = edge._nodes.back(); + + edge._pos.clear(); + + if ( edge._sWOL.ShapeType() == TopAbs_FACE ) + { + gp_XY srcUV = helper.GetNodeUV( F, srcNode ); + gp_XY tgtUV = helper.GetNodeUV( F, tgtNode ); + gp_Vec2d uvDir( srcUV, tgtUV ); + double uvLen = uvDir.Magnitude(); + uvDir /= uvLen; + edge._normal.SetCoord( uvDir.X(),uvDir.Y(), 0); + + // IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces + vector faces; + multimap< double, const SMDS_MeshNode* > proj2node; + SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + { + const SMDS_MeshElement* f = fIt->next(); + if ( faceSubMesh->Contains( f )) + faces.push_back( f ); + } + for ( unsigned i = 0; i < faces.size(); ++i ) + { + const int nbNodes = faces[i]->NbCornerNodes(); + for ( int j = 0; j < nbNodes; ++j ) + { + const SMDS_MeshNode* n = faces[i]->GetNode(j); + if ( n == srcNode ) continue; + if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE && + ( faces.size() > 1 || nbNodes > 3 )) + continue; + gp_Pnt2d uv = helper.GetNodeUV( F, n ); + gp_Vec2d uvDirN( srcUV, uv ); + double proj = uvDirN * uvDir; + proj2node.insert( make_pair( proj, n )); + } + } + + multimap< double, const SMDS_MeshNode* >::iterator p2n = proj2node.begin(), p2nEnd; + const double minProj = p2n->first; + const double projThreshold = 1.1 * uvLen; + if ( minProj > projThreshold ) + { + // tgtNode is located so that it does not make faces with wrong orientation + return true; + } + edge._pos.resize(1); + edge._pos[0].SetCoord( tgtUV.X(), tgtUV.Y(), 0 ); + + // store most risky nodes in _simplices + p2nEnd = proj2node.lower_bound( projThreshold ); + int nbSimpl = ( std::distance( p2n, p2nEnd ) + 1) / 2; + edge._simplices.resize( nbSimpl ); + for ( int i = 0; i < nbSimpl; ++i ) + { + edge._simplices[i]._nPrev = p2n->second; + if ( ++p2n != p2nEnd ) + edge._simplices[i]._nNext = p2n->second; + } + // set UV of source node to target node + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + pos->SetUParameter( srcUV.X() ); + pos->SetVParameter( srcUV.Y() ); + } + else // _sWOL is TopAbs_EDGE + { + TopoDS_Edge E = TopoDS::Edge( edge._sWOL); + SMESHDS_SubMesh* edgeSM = getMeshDS()->MeshElements( E ); + if ( !edgeSM || edgeSM->NbElements() == 0 ) + return error(SMESH_Comment("Not meshed EDGE ") << getMeshDS()->ShapeToIndex( E )); + + const SMDS_MeshNode* n2 = 0; + SMDS_ElemIteratorPtr eIt = srcNode->GetInverseElementIterator(SMDSAbs_Edge); + while ( eIt->more() && !n2 ) + { + const SMDS_MeshElement* e = eIt->next(); + if ( !edgeSM->Contains(e)) continue; + n2 = e->GetNode( 0 ); + if ( n2 == srcNode ) n2 = e->GetNode( 1 ); + } + if ( !n2 ) + return error(SMESH_Comment("Wrongly meshed EDGE ") << getMeshDS()->ShapeToIndex( E )); + + double uSrc = helper.GetNodeU( E, srcNode, n2 ); + double uTgt = helper.GetNodeU( E, tgtNode, srcNode ); + double u2 = helper.GetNodeU( E, n2, srcNode ); + + if ( fabs( uSrc-uTgt ) < 0.99 * fabs( uSrc-u2 )) + { + // tgtNode is located so that it does not make faces with wrong orientation + return true; + } + edge._pos.resize(1); + edge._pos[0].SetCoord( U_TGT, uTgt ); + edge._pos[0].SetCoord( U_SRC, uSrc ); + edge._pos[0].SetCoord( LEN_TGT, fabs( uSrc-uTgt )); + + edge._simplices.resize( 1 ); + edge._simplices[0]._nPrev = n2; + + // set UV of source node to target node + SMDS_EdgePosition* pos = static_cast( tgtNode->GetPosition() ); + pos->SetUParameter( uSrc ); + } + return true; + + //================================================================================ + /*! + * \brief Compute positions (UV) to set to a node on edge moved during shrinking + */ + //================================================================================ + + // Compute UV to follow during shrinking + +// const SMDS_MeshNode* srcNode = edge._nodes[0]; +// const SMDS_MeshNode* tgtNode = edge._nodes.back(); + +// gp_XY srcUV = helper.GetNodeUV( F, srcNode ); +// gp_XY tgtUV = helper.GetNodeUV( F, tgtNode ); +// gp_Vec2d uvDir( srcUV, tgtUV ); +// double uvLen = uvDir.Magnitude(); +// uvDir /= uvLen; + +// // Select shrinking step such that not to make faces with wrong orientation. +// // IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces +// const double minStepSize = uvLen / 20; +// double stepSize = uvLen; +// SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face); +// while ( fIt->more() ) +// { +// const SMDS_MeshElement* f = fIt->next(); +// if ( !faceSubMesh->Contains( f )) continue; +// const int nbNodes = f->NbCornerNodes(); +// for ( int i = 0; i < nbNodes; ++i ) +// { +// const SMDS_MeshNode* n = f->GetNode(i); +// if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE || n == srcNode) +// continue; +// gp_XY uv = helper.GetNodeUV( F, n ); +// gp_Vec2d uvDirN( srcUV, uv ); +// double proj = uvDirN * uvDir; +// if ( proj < stepSize && proj > minStepSize ) +// stepSize = proj; +// } +// } +// stepSize *= 0.8; + +// const int nbSteps = ceil( uvLen / stepSize ); +// gp_XYZ srcUV0( srcUV.X(), srcUV.Y(), 0 ); +// gp_XYZ tgtUV0( tgtUV.X(), tgtUV.Y(), 0 ); +// edge._pos.resize( nbSteps ); +// edge._pos[0] = tgtUV0; +// for ( int i = 1; i < nbSteps; ++i ) +// { +// double r = i / double( nbSteps ); +// edge._pos[i] = (1-r) * tgtUV0 + r * srcUV0; +// } +// return true; +} + +//================================================================================ +/*! + * \brief Try to fix triangles with high aspect ratio by swaping diagonals + */ +//================================================================================ + +void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper) +{ + SMESH::Controls::AspectRatio qualifier; + SMESH::Controls::TSequenceOfXYZ points(3), points1(3), points2(3); + const double maxAspectRatio = 4.; + + // find bad triangles + + vector< const SMDS_MeshElement* > badTrias; + vector< double > badAspects; + SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( F ); + SMDS_ElemIteratorPtr fIt = sm->GetElements(); + while ( fIt->more() ) + { + const SMDS_MeshElement * f = fIt->next(); + if ( f->NbCornerNodes() != 3 ) continue; + for ( int iP = 0; iP < 3; ++iP ) points(iP+1) = SMESH_TNodeXYZ( f->GetNode(iP)); + double aspect = qualifier.GetValue( points ); + if ( aspect > maxAspectRatio ) + { + badTrias.push_back( f ); + badAspects.push_back( aspect ); + } + } + if ( badTrias.empty() ) + return; + + // find couples of faces to swap diagonal + + typedef pair < const SMDS_MeshElement* , const SMDS_MeshElement* > T2Trias; + vector< T2Trias > triaCouples; + + TIDSortedElemSet involvedFaces, emptySet; + for ( size_t iTia = 0; iTia < badTrias.size(); ++iTia ) + { + T2Trias trias [3]; + double aspRatio [3]; + int i1, i2, i3; + + involvedFaces.insert( badTrias[iTia] ); + for ( int iP = 0; iP < 3; ++iP ) + points(iP+1) = SMESH_TNodeXYZ( badTrias[iTia]->GetNode(iP)); + + // find triangles adjacent to badTrias[iTia] with better aspect ratio after diag-swaping + int bestCouple = -1; + for ( int iSide = 0; iSide < 3; ++iSide ) + { + const SMDS_MeshNode* n1 = badTrias[iTia]->GetNode( iSide ); + const SMDS_MeshNode* n2 = badTrias[iTia]->GetNode(( iSide+1 ) % 3 ); + trias [iSide].first = badTrias[iTia]; + trias [iSide].second = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, involvedFaces, + & i1, & i2 ); + if ( ! trias[iSide].second || trias[iSide].second->NbCornerNodes() != 3 ) + continue; + + // aspect ratio of an adjacent tria + for ( int iP = 0; iP < 3; ++iP ) + points2(iP+1) = SMESH_TNodeXYZ( trias[iSide].second->GetNode(iP)); + double aspectInit = qualifier.GetValue( points2 ); + + // arrange nodes as after diag-swaping + if ( helper.WrapIndex( i1+1, 3 ) == i2 ) + i3 = helper.WrapIndex( i1-1, 3 ); + else + i3 = helper.WrapIndex( i1+1, 3 ); + points1 = points; + points1( 1+ iSide ) = points2( 1+ i3 ); + points2( 1+ i2 ) = points1( 1+ ( iSide+2 ) % 3 ); + + // aspect ratio after diag-swaping + aspRatio[ iSide ] = qualifier.GetValue( points1 ) + qualifier.GetValue( points2 ); + if ( aspRatio[ iSide ] > aspectInit + badAspects[ iTia ] ) + continue; + + if ( bestCouple < 0 || aspRatio[ bestCouple ] > aspRatio[ iSide ] ) + bestCouple = iSide; + } + + if ( bestCouple >= 0 ) + { + triaCouples.push_back( trias[bestCouple] ); + involvedFaces.insert ( trias[bestCouple].second ); + } + else + { + involvedFaces.erase( badTrias[iTia] ); + } + } + if ( triaCouples.empty() ) + return; + + // swap diagonals + + SMESH_MeshEditor editor( helper.GetMesh() ); + dumpFunction(SMESH_Comment("beforeSwapDiagonals_F")<( _nodes.back() ); + + if ( _sWOL.ShapeType() == TopAbs_FACE ) + { + gp_XY curUV = helper.GetNodeUV( F, tgtNode ); + gp_Pnt2d tgtUV( _pos[0].X(), _pos[0].Y()); + gp_Vec2d uvDir( _normal.X(), _normal.Y() ); + const double uvLen = tgtUV.Distance( curUV ); + + // Select shrinking step such that not to make faces with wrong orientation. + const double kSafe = 0.8; + const double minStepSize = uvLen / 10; + double stepSize = uvLen; + for ( unsigned i = 0; i < _simplices.size(); ++i ) + { + const SMDS_MeshNode* nn[2] = { _simplices[i]._nPrev, _simplices[i]._nNext }; + for ( int j = 0; j < 2; ++j ) + if ( const SMDS_MeshNode* n = nn[j] ) + { + gp_XY uv = helper.GetNodeUV( F, n ); + gp_Vec2d uvDirN( curUV, uv ); + double proj = uvDirN * uvDir * kSafe; + if ( proj < stepSize && proj > minStepSize ) + stepSize = proj; + } + } + + gp_Pnt2d newUV; + if ( stepSize == uvLen ) + { + newUV = tgtUV; + _pos.clear(); + } + else + { + newUV = curUV + uvDir.XY() * stepSize; + } + + SMDS_FacePosition* pos = static_cast( tgtNode->GetPosition() ); + pos->SetUParameter( newUV.X() ); + pos->SetVParameter( newUV.Y() ); + +#ifdef __myDEBUG + gp_Pnt p = surface->Value( newUV.X(), newUV.Y() ); + tgtNode->setXYZ( p.X(), p.Y(), p.Z() ); + dumpMove( tgtNode ); +#endif + } + else // _sWOL is TopAbs_EDGE + { + TopoDS_Edge E = TopoDS::Edge( _sWOL ); + const SMDS_MeshNode* n2 = _simplices[0]._nPrev; + + const double u2 = helper.GetNodeU( E, n2, tgtNode ); + const double uSrc = _pos[0].Coord( U_SRC ); + const double lenTgt = _pos[0].Coord( LEN_TGT ); + + double newU = _pos[0].Coord( U_TGT ); + if ( lenTgt < 0.99 * fabs( uSrc-u2 )) + { + _pos.clear(); + } + else + { + newU = 0.1 * uSrc + 0.9 * u2; + } + SMDS_EdgePosition* pos = static_cast( tgtNode->GetPosition() ); + pos->SetUParameter( newU ); +#ifdef __myDEBUG + gp_XY newUV = helper.GetNodeUV( F, tgtNode, _nodes[0]); + gp_Pnt p = surface->Value( newUV.X(), newUV.Y() ); + tgtNode->setXYZ( p.X(), p.Y(), p.Z() ); + dumpMove( tgtNode ); +#endif + } + return true; +} + +//================================================================================ +/*! + * \brief Perform smooth on the FACE + * \retval bool - true if the node has been moved + */ +//================================================================================ + +bool _SmoothNode::Smooth(int& badNb, + Handle(Geom_Surface)& surface, + SMESH_MesherHelper& helper, + const double refSign, + bool isCentroidal, + bool set3D) +{ + const TopoDS_Face& face = TopoDS::Face( helper.GetSubShape() ); + + // get uv of surrounding nodes + vector uv( _simplices.size() ); + for ( size_t i = 0; i < _simplices.size(); ++i ) + uv[i] = helper.GetNodeUV( face, _simplices[i]._nPrev, _node ); + + // compute new UV for the node + gp_XY newPos (0,0); + if ( isCentroidal && _simplices.size() > 3 ) + { + // average centers of diagonals wieghted with their reciprocal lengths + if ( _simplices.size() == 4 ) + { + double w1 = 1. / ( uv[2]-uv[0] ).SquareModulus(); + double w2 = 1. / ( uv[3]-uv[1] ).SquareModulus(); + newPos = ( w1 * ( uv[2]+uv[0] ) + w2 * ( uv[3]+uv[1] )) / ( w1+w2 ) / 2; + } + else + { + double sumWeight = 0; + int nb = _simplices.size() == 4 ? 2 : _simplices.size(); + for ( int i = 0; i < nb; ++i ) + { + int iFrom = i + 2; + int iTo = i + _simplices.size() - 1; + for ( int j = iFrom; j < iTo; ++j ) + { + int i2 = SMESH_MesherHelper::WrapIndex( j, _simplices.size() ); + double w = 1. / ( uv[i]-uv[i2] ).SquareModulus(); + sumWeight += w; + newPos += w * ( uv[i]+uv[i2] ); + } + } + newPos /= 2 * sumWeight; + } + } + else + { + // Laplacian smooth + isCentroidal = false; + for ( size_t i = 0; i < _simplices.size(); ++i ) + newPos += uv[i]; + newPos /= _simplices.size(); + } + + // count quality metrics (orientation) of triangles around the node + int nbOkBefore = 0; + gp_XY tgtUV = helper.GetNodeUV( face, _node ); + for ( unsigned i = 0; i < _simplices.size(); ++i ) + nbOkBefore += _simplices[i].IsForward( tgtUV, _node, face, helper, refSign ); + + int nbOkAfter = 0; + for ( unsigned i = 0; i < _simplices.size(); ++i ) + nbOkAfter += _simplices[i].IsForward( newPos, _node, face, helper, refSign ); + + if ( nbOkAfter < nbOkBefore ) + { + // if ( isCentroidal ) + // return Smooth( badNb, surface, helper, refSign, !isCentroidal, set3D ); + badNb += _simplices.size() - nbOkBefore; + return false; + } + + SMDS_FacePosition* pos = static_cast( _node->GetPosition() ); + pos->SetUParameter( newPos.X() ); + pos->SetVParameter( newPos.Y() ); + +#ifdef __myDEBUG + set3D = true; +#endif + if ( set3D ) + { + gp_Pnt p = surface->Value( newPos.X(), newPos.Y() ); + const_cast< SMDS_MeshNode* >( _node )->setXYZ( p.X(), p.Y(), p.Z() ); + dumpMove( _node ); + } + + badNb += _simplices.size() - nbOkAfter; + return ( (tgtUV-newPos).SquareModulus() > 1e-10 ); +} + +//================================================================================ +/*! + * \brief Delete _SolidData + */ +//================================================================================ + +_SolidData::~_SolidData() +{ + for ( unsigned i = 0; i < _edges.size(); ++i ) + { + if ( _edges[i] && _edges[i]->_2neibors ) + delete _edges[i]->_2neibors; + delete _edges[i]; + } + _edges.clear(); +} +//================================================================================ +/*! + * \brief Add a _LayerEdge inflated along the EDGE + */ +//================================================================================ + +void _Shrinker1D::AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper ) +{ + // init + if ( _nodes.empty() ) + { + _edges[0] = _edges[1] = 0; + _done = false; + } + // check _LayerEdge + if ( e == _edges[0] || e == _edges[1] ) + return; + if ( e->_sWOL.IsNull() || e->_sWOL.ShapeType() != TopAbs_EDGE ) + throw SALOME_Exception(LOCALIZED("Wrong _LayerEdge is added")); + if ( _edges[0] && _edges[0]->_sWOL != e->_sWOL ) + throw SALOME_Exception(LOCALIZED("Wrong _LayerEdge is added")); + + // store _LayerEdge + const TopoDS_Edge& E = TopoDS::Edge( e->_sWOL ); + double f,l; + BRep_Tool::Range( E, f,l ); + double u = helper.GetNodeU( E, e->_nodes[0], e->_nodes.back()); + _edges[ u < 0.5*(f+l) ? 0 : 1 ] = e; + + // Update _nodes + + const SMDS_MeshNode* tgtNode0 = _edges[0] ? _edges[0]->_nodes.back() : 0; + const SMDS_MeshNode* tgtNode1 = _edges[1] ? _edges[1]->_nodes.back() : 0; + + if ( _nodes.empty() ) + { + SMESHDS_SubMesh * eSubMesh = helper.GetMeshDS()->MeshElements( E ); + if ( !eSubMesh || eSubMesh->NbNodes() < 1 ) + return; + TopLoc_Location loc; + Handle(Geom_Curve) C = BRep_Tool::Curve(E, loc, f,l); + GeomAdaptor_Curve aCurve(C, f,l); + const double totLen = GCPnts_AbscissaPoint::Length(aCurve, f, l); + + int nbExpectNodes = eSubMesh->NbNodes() - e->_nodes.size(); + _initU .reserve( nbExpectNodes ); + _normPar.reserve( nbExpectNodes ); + _nodes .reserve( nbExpectNodes ); + SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes(); + while ( nIt->more() ) + { + const SMDS_MeshNode* node = nIt->next(); + if ( node->NbInverseElements(SMDSAbs_Edge) == 0 || + node == tgtNode0 || node == tgtNode1 ) + continue; // refinement nodes + _nodes.push_back( node ); + _initU.push_back( helper.GetNodeU( E, node )); + double len = GCPnts_AbscissaPoint::Length(aCurve, f, _initU.back()); + _normPar.push_back( len / totLen ); + } + } + else + { + // remove target node of the _LayerEdge from _nodes + int nbFound = 0; + for ( unsigned i = 0; i < _nodes.size(); ++i ) + if ( !_nodes[i] || _nodes[i] == tgtNode0 || _nodes[i] == tgtNode1 ) + _nodes[i] = 0, nbFound++; + if ( nbFound == _nodes.size() ) + _nodes.clear(); + } +} + +//================================================================================ +/*! + * \brief Move nodes on EDGE from ends where _LayerEdge's are inflated + */ +//================================================================================ + +void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper) +{ + if ( _done || _nodes.empty()) + return; + const _LayerEdge* e = _edges[0]; + if ( !e ) e = _edges[1]; + if ( !e ) return; + + _done = (( !_edges[0] || _edges[0]->_pos.empty() ) && + ( !_edges[1] || _edges[1]->_pos.empty() )); + + const TopoDS_Edge& E = TopoDS::Edge( e->_sWOL ); + double f,l; + if ( set3D || _done ) + { + Handle(Geom_Curve) C = BRep_Tool::Curve(E, f,l); + GeomAdaptor_Curve aCurve(C, f,l); + + if ( _edges[0] ) + f = helper.GetNodeU( E, _edges[0]->_nodes.back(), _nodes[0] ); + if ( _edges[1] ) + l = helper.GetNodeU( E, _edges[1]->_nodes.back(), _nodes.back() ); + double totLen = GCPnts_AbscissaPoint::Length( aCurve, f, l ); + + for ( unsigned i = 0; i < _nodes.size(); ++i ) + { + if ( !_nodes[i] ) continue; + double len = totLen * _normPar[i]; + GCPnts_AbscissaPoint discret( aCurve, len, f ); + if ( !discret.IsDone() ) + return throw SALOME_Exception(LOCALIZED("GCPnts_AbscissaPoint failed")); + double u = discret.Parameter(); + SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); + pos->SetUParameter( u ); + gp_Pnt p = C->Value( u ); + const_cast< SMDS_MeshNode*>( _nodes[i] )->setXYZ( p.X(), p.Y(), p.Z() ); + } + } + else + { + BRep_Tool::Range( E, f,l ); + if ( _edges[0] ) + f = helper.GetNodeU( E, _edges[0]->_nodes.back(), _nodes[0] ); + if ( _edges[1] ) + l = helper.GetNodeU( E, _edges[1]->_nodes.back(), _nodes.back() ); + + for ( unsigned i = 0; i < _nodes.size(); ++i ) + { + if ( !_nodes[i] ) continue; + double u = f * ( 1-_normPar[i] ) + l * _normPar[i]; + SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); + pos->SetUParameter( u ); + } + } +} + +//================================================================================ +/*! + * \brief Restore initial parameters of nodes on EDGE + */ +//================================================================================ + +void _Shrinker1D::RestoreParams() +{ + if ( _done ) + for ( unsigned i = 0; i < _nodes.size(); ++i ) + { + if ( !_nodes[i] ) continue; + SMDS_EdgePosition* pos = static_cast( _nodes[i]->GetPosition() ); + pos->SetUParameter( _initU[i] ); + } + _done = false; +} + +//================================================================================ +/*! + * \brief Replace source nodes by target nodes in shrinked mesh edges + */ +//================================================================================ + +void _Shrinker1D::SwapSrcTgtNodes( SMESHDS_Mesh* mesh ) +{ + const SMDS_MeshNode* nodes[3]; + for ( int i = 0; i < 2; ++i ) + { + if ( !_edges[i] ) continue; + + SMESHDS_SubMesh * eSubMesh = mesh->MeshElements( _edges[i]->_sWOL ); + if ( !eSubMesh ) return; + const SMDS_MeshNode* srcNode = _edges[i]->_nodes[0]; + const SMDS_MeshNode* tgtNode = _edges[i]->_nodes.back(); + SMDS_ElemIteratorPtr eIt = srcNode->GetInverseElementIterator(SMDSAbs_Edge); + while ( eIt->more() ) + { + const SMDS_MeshElement* e = eIt->next(); + if ( !eSubMesh->Contains( e )) + continue; + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + for ( int iN = 0; iN < e->NbNodes(); ++iN ) + { + const SMDS_MeshNode* n = static_cast( nIt->next() ); + nodes[iN] = ( n == srcNode ? tgtNode : n ); + } + mesh->ChangeElementNodes( e, nodes, e->NbNodes() ); + } + } +} + +//================================================================================ +/*! + * \brief Creates 2D and 1D elements on boundaries of new prisms + */ +//================================================================================ + +bool _ViscousBuilder::addBoundaryElements() +{ + SMESH_MesherHelper helper( *_mesh ); + + for ( unsigned i = 0; i < _sdVec.size(); ++i ) + { + _SolidData& data = _sdVec[i]; + TopTools_IndexedMapOfShape geomEdges; + TopExp::MapShapes( data._solid, TopAbs_EDGE, geomEdges ); + for ( int iE = 1; iE <= geomEdges.Extent(); ++iE ) + { + const TopoDS_Edge& E = TopoDS::Edge( geomEdges(iE)); + + // Get _LayerEdge's based on E + + map< double, const SMDS_MeshNode* > u2nodes; + if ( !SMESH_Algo::GetSortedNodesOnEdge( getMeshDS(), E, /*ignoreMedium=*/false, u2nodes)) + continue; + + vector< _LayerEdge* > ledges; ledges.reserve( u2nodes.size() ); + TNode2Edge & n2eMap = data._n2eMap; + map< double, const SMDS_MeshNode* >::iterator u2n = u2nodes.begin(); + { + //check if 2D elements are needed on E + TNode2Edge::iterator n2e = n2eMap.find( u2n->second ); + if ( n2e == n2eMap.end() ) continue; // no layers on vertex + ledges.push_back( n2e->second ); + u2n++; + if (( n2e = n2eMap.find( u2n->second )) == n2eMap.end() ) + continue; // no layers on E + ledges.push_back( n2eMap[ u2n->second ]); + + const SMDS_MeshNode* tgtN0 = ledges[0]->_nodes.back(); + const SMDS_MeshNode* tgtN1 = ledges[1]->_nodes.back(); + int nbSharedPyram = 0; + SMDS_ElemIteratorPtr vIt = tgtN0->GetInverseElementIterator(SMDSAbs_Volume); + while ( vIt->more() ) + { + const SMDS_MeshElement* v = vIt->next(); + nbSharedPyram += int( v->GetNodeIndex( tgtN1 ) >= 0 ); + } + if ( nbSharedPyram > 1 ) + continue; // not free border of the pyramid + + if ( getMeshDS()->FindFace( ledges[0]->_nodes[0], ledges[0]->_nodes[1], + ledges[1]->_nodes[0], ledges[1]->_nodes[1])) + continue; // faces already created + } + for ( ++u2n; u2n != u2nodes.end(); ++u2n ) + ledges.push_back( n2eMap[ u2n->second ]); + + // Find out orientation and type of face to create + + bool reverse = false, isOnFace; + + map< TGeomID, TopoDS_Shape >::iterator e2f = + data._shrinkShape2Shape.find( getMeshDS()->ShapeToIndex( E )); + TopoDS_Shape F; + if (( isOnFace = ( e2f != data._shrinkShape2Shape.end() ))) + { + F = e2f->second.Oriented( TopAbs_FORWARD ); + reverse = ( helper.GetSubShapeOri( F, E ) == TopAbs_REVERSED ); + if ( helper.GetSubShapeOri( data._solid, F ) == TopAbs_REVERSED ) + reverse = !reverse; + } + else + { + // find FACE with layers sharing E + PShapeIteratorPtr fIt = helper.GetAncestors( E, *_mesh, TopAbs_FACE ); + while ( fIt->more() && F.IsNull() ) + { + const TopoDS_Shape* pF = fIt->next(); + if ( helper.IsSubShape( *pF, data._solid) && + !_ignoreShapeIds.count( e2f->first )) + F = *pF; + } + } + // Find the sub-mesh to add new faces + SMESHDS_SubMesh* sm = 0; + if ( isOnFace ) + sm = getMeshDS()->MeshElements( F ); + else + sm = data._proxyMesh->getFaceSubM( TopoDS::Face(F), /*create=*/true ); + if ( !sm ) + return error("error in addBoundaryElements()", data._index); + + // Make faces + const int dj1 = reverse ? 0 : 1; + const int dj2 = reverse ? 1 : 0; + for ( unsigned j = 1; j < ledges.size(); ++j ) + { + vector< const SMDS_MeshNode*>& nn1 = ledges[j-dj1]->_nodes; + vector< const SMDS_MeshNode*>& nn2 = ledges[j-dj2]->_nodes; + if ( isOnFace ) + for ( unsigned z = 1; z < nn1.size(); ++z ) + sm->AddElement( getMeshDS()->AddFace( nn1[z-1], nn2[z-1], nn2[z], nn1[z] )); + else + for ( unsigned z = 1; z < nn1.size(); ++z ) + sm->AddElement( new SMDS_FaceOfNodes( nn1[z-1], nn2[z-1], nn2[z], nn1[z])); + } + } + } + + return true; +} diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.hxx b/src/StdMeshers/StdMeshers_ViscousLayers.hxx new file mode 100644 index 000000000..42c187130 --- /dev/null +++ b/src/StdMeshers/StdMeshers_ViscousLayers.hxx @@ -0,0 +1,94 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshers_ViscousLayers.hxx +// Created : Wed Dec 1 15:15:34 2010 +// Author : Edward AGAPOV (eap) + +#ifndef __StdMeshers_ViscousLayers_HXX__ +#define __StdMeshers_ViscousLayers_HXX__ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "SMESH_ProxyMesh.hxx" + +#include + +/*! + * \brief Hypothesis defining parameters of viscous layers + */ +class STDMESHERS_EXPORT StdMeshers_ViscousLayers : public SMESH_Hypothesis +{ +public: + StdMeshers_ViscousLayers(int hypId, int studyId, SMESH_Gen* gen); + + // Set faces to exclude from treatment + void SetIgnoreFaces(const std::vector& faceIds); + std::vector GetIgnoreFaces() const { return _ignoreFaceIds; } + + // Set total thickness of layers of prisms + void SetTotalThickness(double thickness); + double GetTotalThickness() const { return _thickness; } + + // Set number of layers of prisms + void SetNumberLayers(int nb); + int GetNumberLayers() const { return _nbLayers; } + + // Set factor (>1.0) of growth of layer thickness towards inside of mesh + void SetStretchFactor(double factor); + double GetStretchFactor() const { return _stretchFactor; } + + // Computes temporary 2D mesh to be used by 3D algorithm. + // Return SMESH_ProxyMesh for each SOLID in theShape + SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh, + const TopoDS_Shape& theShape, + const bool toMakeN2NMap=false) const; + + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + + /*! + * \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 + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + + /*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ + virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0) + { return false; } + + static const char* GetHypType() { return "ViscousLayers"; } + + private: + + std::vector _ignoreFaceIds; + int _nbLayers; + double _thickness; + double _stretchFactor; +}; + +#endif diff --git a/src/StdMeshersGUI/Makefile.am b/src/StdMeshersGUI/Makefile.am index 38425ec0c..3f7a1d8ff 100644 --- a/src/StdMeshersGUI/Makefile.am +++ b/src/StdMeshersGUI/Makefile.am @@ -1,30 +1,26 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 # -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# SMESH StdMeshersGUI : GUI for StdMeshers plugin # File : Makefile.in # Author : Julia DOROVSKIKH # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : SMESH -# + include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files @@ -35,10 +31,15 @@ salomeinclude_HEADERS = \ StdMeshersGUI_DistrTable.h \ StdMeshersGUI_NbSegmentsCreator.h \ StdMeshersGUI_ObjectReferenceParamWdg.h \ - StdMeshersGUI_LayerDistributionParamWdg.h + StdMeshersGUI_QuadrangleParamWdg.h \ + StdMeshersGUI_LayerDistributionParamWdg.h \ + StdMeshersGUI_FixedPointsParamWdg.h \ + StdMeshersGUI_SubShapeSelectorWdg.h \ + StdMeshersGUI_CartesianParamCreator.h # Libraries targets lib_LTLIBRARIES = libStdMeshersGUI.la + dist_libStdMeshersGUI_la_SOURCES = \ StdMeshersGUI.cxx \ StdMeshersGUI_StdHypothesisCreator.cxx \ @@ -46,7 +47,11 @@ dist_libStdMeshersGUI_la_SOURCES = \ StdMeshersGUI_DistrTable.cxx \ StdMeshersGUI_NbSegmentsCreator.cxx \ StdMeshersGUI_ObjectReferenceParamWdg.cxx \ - StdMeshersGUI_LayerDistributionParamWdg.cxx + StdMeshersGUI_QuadrangleParamWdg.cxx \ + StdMeshersGUI_LayerDistributionParamWdg.cxx \ + StdMeshersGUI_FixedPointsParamWdg.cxx \ + StdMeshersGUI_SubShapeSelectorWdg.cxx \ + StdMeshersGUI_CartesianParamCreator.cxx MOC_FILES = \ StdMeshersGUI_StdHypothesisCreator_moc.cxx \ @@ -54,7 +59,11 @@ MOC_FILES = \ StdMeshersGUI_DistrTable_moc.cxx \ StdMeshersGUI_NbSegmentsCreator_moc.cxx \ StdMeshersGUI_ObjectReferenceParamWdg_moc.cxx \ - StdMeshersGUI_LayerDistributionParamWdg_moc.cxx + StdMeshersGUI_QuadrangleParamWdg_moc.cxx \ + StdMeshersGUI_LayerDistributionParamWdg_moc.cxx \ + StdMeshersGUI_FixedPointsParamWdg_moc.cxx \ + StdMeshersGUI_SubShapeSelectorWdg_moc.cxx \ + StdMeshersGUI_CartesianParamCreator_moc.cxx nodist_libStdMeshersGUI_la_SOURCES= \ $(MOC_FILES) @@ -74,6 +83,7 @@ libStdMeshersGUI_la_CPPFLAGS = \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ -I$(srcdir)/../SMESH \ + -I$(srcdir)/../SMESHUtils \ -I$(srcdir)/../SMESH_I \ -I$(srcdir)/../SMESHDS \ -I$(srcdir)/../SMDS \ @@ -82,9 +92,7 @@ libStdMeshersGUI_la_CPPFLAGS = \ -I$(srcdir)/../StdMeshers \ -I$(srcdir)/../OBJECT \ -I$(srcdir)/../SMESHFiltersSelection \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix - + -I$(top_builddir)/idl libStdMeshersGUI_la_LDFLAGS = \ ../../idl/libSalomeIDLSMESH.la \ @@ -98,4 +106,5 @@ libStdMeshersGUI_la_LDFLAGS = \ # resources files nodist_salomeres_DATA= \ StdMeshers_images.qm \ - StdMeshers_msg_en.qm + StdMeshers_msg_en.qm \ + StdMeshers_msg_fr.qm diff --git a/src/StdMeshersGUI/SMESH_StdMeshersGUI.hxx b/src/StdMeshersGUI/SMESH_StdMeshersGUI.hxx index 76ce2a2a2..946bd61a6 100755 --- a/src/StdMeshersGUI/SMESH_StdMeshersGUI.hxx +++ b/src/StdMeshersGUI/SMESH_StdMeshersGUI.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_StdMeshersGUI.hxx // Author : Alexander BORODIN, Open CASCADE S.A.S. // @@ -26,7 +27,7 @@ #define SMESH_STDMESHERSGUI_HXX #ifdef WNT - #if defined STDMESHERSGUI_EXPORTS + #if defined STDMESHERSGUI_EXPORTS || defined StdMeshersGUI_EXPORTS #define STDMESHERSGUI_EXPORT __declspec( dllexport ) #else #define STDMESHERSGUI_EXPORT __declspec( dllimport ) diff --git a/src/StdMeshersGUI/StdMeshersGUI.cxx b/src/StdMeshersGUI/StdMeshersGUI.cxx index f3e400e82..8b86c5d27 100644 --- a/src/StdMeshersGUI/StdMeshersGUI.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI.cxx @@ -1,30 +1,32 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI.cxx // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. // SMESH includes // #include "StdMeshersGUI_StdHypothesisCreator.h" #include "StdMeshersGUI_NbSegmentsCreator.h" +#include "StdMeshersGUI_CartesianParamCreator.h" //============================================================================= /*! GetHypothesisCreator @@ -38,6 +40,8 @@ extern "C" { if( aHypType=="NumberOfSegments" ) return new StdMeshersGUI_NbSegmentsCreator(); + else if ( aHypType=="CartesianParameters3D" ) + return new StdMeshersGUI_CartesianParamCreator( aHypType ); else return new StdMeshersGUI_StdHypothesisCreator( aHypType ); } diff --git a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx new file mode 100644 index 000000000..48eec0eb4 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx @@ -0,0 +1,698 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshersGUI_CartesianParamCreator.cxx +// Author : Open CASCADE S.A.S. + +// SMESH includes +#include "StdMeshersGUI_CartesianParamCreator.h" + +#include +#include +#include +#include + +// IDL includes +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +// SALOME GUI includes +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 + +namespace StdMeshersGUI +{ + enum { COORD_BUT = 0, SPACING_BUT }; + + //================================================================================ + /*! + * \brief get spacing definition from a tree item + */ + //================================================================================ + + void getFromItem(QTreeWidgetItem * item, double& t0, double& t1, QString& fun ) + { + if ( item ) + { + t0 = item->text( 0 ).split(' ')[0].toDouble(); + t1 = item->data( 0, Qt::UserRole ).toDouble(); + fun = item->text( 1 ); + } + } + + //================================================================================ + /*! + * \brief set spacing definition to a tree item + */ + //================================================================================ + + QTreeWidgetItem* setToItem(double t0, double t1, const QString& fun, QTreeWidgetItem * item) + { + if ( !item ) item = new QTreeWidgetItem; + item->setText( 0, QString( "%1 - %2" ).arg( t0 ).arg( t1 )); + item->setData( 0, Qt::UserRole, t1 ); + item->setText( 1, fun ); + item->setFlags( item->flags() | Qt::ItemIsEditable ); + return item; + } + + //================================================================================ + /*! + * \brief Retrieves coordinate value from a list item + */ + //================================================================================ + + double coordFromItem( QListWidgetItem * item ) + { + return item ? item->data( Qt::UserRole ).toDouble() : 0; + } + + //================================================================================ + /*! + * \brief Sets coordinate value to a list item + */ + //================================================================================ + + QListWidgetItem* coordToItem( double coord, QListWidgetItem * item ) + { + if ( !item ) item = new QListWidgetItem; + item->setText( QString::number( coord )); + item->setData( Qt::UserRole, coord ); + item->setFlags( item->flags() | Qt::ItemIsEditable ); + return item; + } + + //================================================================================ + /*! + * \brief Constructor + * \param theParent - Parent widget for this tab + * + * Makes tab's look and feel + */ + //================================================================================ + + GridAxisTab::GridAxisTab( QWidget* theParent,const int axisIndex ): + QFrame( theParent ), myAxisIndex( axisIndex ) + { + // 1) Grid definition mode + myModeGroup = new QButtonGroup( this ); + QGroupBox* modeBox = new QGroupBox( tr( "GRID_DEF_MODE" ), this ); + QHBoxLayout* modeLay = new QHBoxLayout( modeBox ); + modeLay->setMargin( MARGIN ); + modeLay->setSpacing( SPACING ); + + QRadioButton* coordModeBtn = new QRadioButton( tr( "SMESH_COORDINATES" ), modeBox ); + QRadioButton* spacModeBtn = new QRadioButton( tr( "SPACING" ), modeBox ); + + modeLay->addWidget( coordModeBtn ); + modeLay->addWidget( spacModeBtn ); + myModeGroup->addButton( coordModeBtn, COORD_BUT ); + myModeGroup->addButton( spacModeBtn, SPACING_BUT ); + + // 2) Buttons + Step + myInsertBtn = new QPushButton( tr("INSERT"), this); + myDeleteBtn = new QPushButton( tr("SMESH_BUT_DELETE"), this); + + myStepLabel = new QLabel( tr("COORD_STEP")); + myStepSpin = new SMESHGUI_SpinBox( this ); + myStepSpin->setAcceptNames( false ); // No Notebook variables allowed + myStepSpin->RangeStepAndValidator(); + myStepSpin->SetStep( 1. ); + myStepSpin->SetValue( myStep = 1. ); + + // 3) Coodrinates/Spacing group + QFrame* csFrame = new QFrame( this ); + QVBoxLayout* scLay = new QVBoxLayout( csFrame ); + scLay->setMargin( 0 ); + scLay->setSpacing( SPACING ); + + // 3.1) Spacing + mySpacingTreeWdg = new QTreeWidget( csFrame ); + mySpacingTreeWdg->setColumnCount(2); + mySpacingTreeWdg->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << QString( "f(t)" )); + mySpacingTreeWdg->setColumnWidth( 1, 40 ); + mySpacingTreeWdg->setColumnWidth( 2, 30 ); + mySpacingTreeWdg->setItemDelegate( new LineDelegate( mySpacingTreeWdg )); + scLay->addWidget( mySpacingTreeWdg ); + + // 3.2) Coordinates + myCoordList = new QListWidget( csFrame ); + myCoordList->setItemDelegate( new LineDelegate( myCoordList )); + scLay->addWidget( myCoordList ); + + // layouting + + QGridLayout* axisTabLayout = new QGridLayout( this ); + axisTabLayout->setMargin( MARGIN ); + axisTabLayout->setSpacing( SPACING ); + + axisTabLayout->addWidget( modeBox , 0, 0, 1, 3 ); + axisTabLayout->addWidget( myInsertBtn , 1, 0, 1, 2 ); + axisTabLayout->addWidget( myDeleteBtn , 2, 0, 1, 2 ); + axisTabLayout->addWidget( myStepLabel, 3, 0 ); + axisTabLayout->addWidget( myStepSpin , 3, 1 ); + axisTabLayout->addWidget( csFrame , 1, 2, 4, 1 ); + + axisTabLayout->setRowStretch( 4, 1 ); + + // signals + connect( myInsertBtn, SIGNAL( clicked() ), SLOT( onInsert() )); + connect( myDeleteBtn, SIGNAL( clicked() ), SLOT( onDelete() )); + connect( myModeGroup, SIGNAL( buttonClicked ( int )), SLOT( onMode(int))); + connect( mySpacingTreeWdg, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() )); + connect( myCoordList, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() )); + connect( myStepSpin, SIGNAL( valueChanged(double)), SLOT( onStepChange() )); + } + + void GridAxisTab::onInsert() + { + if ( isGridBySpacing() ) + { + QTreeWidgetItem * item = mySpacingTreeWdg->currentItem(); + if ( !item ) item = mySpacingTreeWdg->topLevelItem( 0 ); + int i = mySpacingTreeWdg->indexOfTopLevelItem( item ); + + double t0, t1; QString fun; + getFromItem( item, t0, t1, fun ); + double t = 0.5 * ( t0 + t1 ); + setToItem( t0, t, fun, item ); + + item = setToItem( t, t1, fun ); + if ( i == mySpacingTreeWdg->topLevelItemCount()-1 ) + mySpacingTreeWdg->addTopLevelItem( item ); + else + mySpacingTreeWdg->insertTopLevelItem( i+1, item ); + mySpacingTreeWdg->setCurrentItem( item ); + } + else + { + if ( myCoordList->count() == 0 ) + { + myCoordList->addItem( coordToItem( 0 )); + } + else + { + double coord = coordFromItem( myCoordList->currentItem() ) + myStep; + int i = myCoordList->currentRow(); + while ( i > 0 && coordFromItem( myCoordList->item( i-1 )) > coord ) + --i; + while ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) < coord ) + ++i; + const double tol = 1e-6; + const bool isSame = + ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) - coord < tol ) || + ( i > 0 && coord - coordFromItem( myCoordList->item( i-1 )) < tol ); + if ( !isSame ) + myCoordList->insertItem( i, coordToItem( coord )); + else if ( myStep < 0 ) + --i; + myCoordList->setCurrentRow( i ); + } + } + updateButtons(); + } + + void GridAxisTab::onDelete() + { + if ( isGridBySpacing() ) + { + QList selItems = mySpacingTreeWdg->selectedItems(); + QTreeWidgetItem * item; + foreach ( item, selItems ) + { + int i = mySpacingTreeWdg->indexOfTopLevelItem( item ); + if ( i == 0 ) continue; + QTreeWidgetItem* prevItem = mySpacingTreeWdg->topLevelItem( i-1 ); + + double t0, t1, t2; QString fun; + getFromItem( item, t1, t2, fun ); + getFromItem( prevItem, t0, t1, fun ); + delete item; + + setToItem( t0, t2, fun, prevItem ); + } + } + else + { + if ( myCoordList->count() > 2 ) + if ( QListWidgetItem * item = myCoordList->currentItem() ) + delete item; + } + updateButtons(); + } + + void GridAxisTab::onMode(int isSpacing) + { + mySpacingTreeWdg->setShown( isSpacing ); + myCoordList->setShown( !isSpacing ); + myStepSpin->setShown( !isSpacing ); + myStepLabel->setShown( !isSpacing ); + if ( isSpacing ) + { + if ( mySpacingTreeWdg->topLevelItemCount() == 0 ) + { + QString spacing( "1" ); + if ( myCoordList->count() > 1 ) + { + double c1 = coordFromItem( myCoordList->item( 1 )); + double c0 = coordFromItem( myCoordList->item( 0 )); + spacing = QString::number( c1 - c0 ); + } + mySpacingTreeWdg->addTopLevelItem( setToItem( 0., 1., spacing ) ); + } + //myCoordList->clear(); + } + else + { + //mySpacingTreeWdg->clear(); + if ( myCoordList->count() == 0 ) + myCoordList->addItem( coordToItem( 0 )); + } + updateButtons(); + } + + void GridAxisTab::onStepChange() + { + if ( fabs( myStepSpin->GetValue() ) < 1e-100 ) + { + double delta = myStepSpin->singleStep() * ( myStep > myStepSpin->GetValue() ? -1 : +1 ); + myStepSpin->SetValue( myStepSpin->GetValue() + delta ); + } + myStep = myStepSpin->GetValue(); + } + + void GridAxisTab::updateButtons() + { + bool insertEnable = false, deleteEnable = false; + if ( isGridBySpacing() ) + { + insertEnable = true; + const int nbSelected = mySpacingTreeWdg->selectedItems().count(); + if ( nbSelected > 0 ) + { + // we delete a current range by uniting it with the previous + int i = mySpacingTreeWdg->indexOfTopLevelItem( mySpacingTreeWdg->currentItem() ); + deleteEnable = ( i > 0 ); + } + } + else + { + const int nbSelected = myCoordList->selectedItems().count(); + insertEnable = ( nbSelected || myCoordList->count() < 2 ); + deleteEnable = ( nbSelected && myCoordList->count() > 2 ); + } + myInsertBtn->setEnabled( insertEnable ); + myDeleteBtn->setEnabled( deleteEnable ); + } + + void GridAxisTab::setCoordinates( SMESH::double_array_var coords ) + { + myCoordList->clear(); + for ( size_t i = 0; i < coords->length(); ++i ) + myCoordList->addItem( coordToItem( coords[i] )); + + myModeGroup->button( COORD_BUT )->setChecked( true ); + onMode( COORD_BUT ); + } + + void GridAxisTab::setSpacing( SMESH::string_array_var funs, SMESH::double_array_var points ) + { + mySpacingTreeWdg->clear(); + if ( funs->length() == points->length() - 1 ) + { + for ( size_t i = 1; i < points->length(); ++i ) + mySpacingTreeWdg->addTopLevelItem + ( setToItem( points[i-1], points[i], (const char*) funs[i-1] )); + } + myModeGroup->button( SPACING_BUT )->setChecked( true ); + onMode( SPACING_BUT ); + } + + bool GridAxisTab::isGridBySpacing() const + { + return ( myModeGroup->checkedId() == SPACING_BUT ); + } + + SMESH::double_array* GridAxisTab::getCoordinates() + { + SMESH::double_array_var coords = new SMESH::double_array; + coords->length( myCoordList->count() ); + for ( size_t i = 0; i < coords->length(); ++i ) + coords[i] = coordFromItem( myCoordList->item( i ) ); + + return coords._retn(); + } + + void GridAxisTab::getSpacing(SMESH::string_array_out funs, + SMESH::double_array_out points) const + { + funs = new SMESH::string_array(); + points = new SMESH::double_array(); + funs->length( mySpacingTreeWdg->topLevelItemCount() ); + points->length( mySpacingTreeWdg->topLevelItemCount() + 1 ); + double t0, t1; QString fun; + for ( size_t i = 0; i < funs->length(); ++i ) + { + QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( i ); + getFromItem( item, t0, t1, fun ); + points[i] = t0; + funs[i] = fun.toLatin1().constData(); + } + points[ points->length()-1 ] = 1.0; + } + + + bool GridAxisTab::checkParams(QString& msg, SMESH::SMESH_Hypothesis_var& hyp) const + { + if ( isGridBySpacing() ) + { + if ( mySpacingTreeWdg->topLevelItemCount() == 0 ) + return false; // how could it be? + StdMeshers::StdMeshers_CartesianParameters3D_var h = + StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hyp ); + SMESH::string_array_var funs; + SMESH::double_array_var points; + getSpacing( funs.out(), points.out() ); + try { + const char* axisName[3] = { "X", "Y", "Z" }; + SMESH::double_array_var coords = + h->ComputeCoordinates(0.,1., funs, points, axisName[ myAxisIndex ]); + } + catch ( const SALOME::SALOME_Exception& ex ) { + msg = (const char*) ex.details.text; + return false; + } + } + else + { + return myCoordList->count() > 1; + } + return true; + } + + LineDelegate::LineDelegate( QWidget* parent ): + QItemDelegate( parent ), + mySpacingTreeWdg( qobject_cast( parent )), + myCoordList( qobject_cast( parent )) + { + } + + QWidget* LineDelegate::createEditor( QWidget* parent, + const QStyleOptionViewItem& opt, + const QModelIndex& index) const + { + QWidget* w = 0; + if ( mySpacingTreeWdg ) + { + if ( index.column() == 0 && + index.row() != mySpacingTreeWdg->topLevelItemCount()-1 ) + { + SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent ); + sb->setAcceptNames( false ); // No Notebook variables allowed + sb->setFrame( false ); + w = sb; + } + if ( index.column() == 1 ) { + w = new QLineEdit( parent ); + } + } + else + { + SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent ); + sb->setAcceptNames( false ); // No Notebook variables allowed + sb->setFrame( false ); + const double tol = 1e-5; + double from = index.row() ? coordFromItem( myCoordList->item( index.row()-1 ))+tol : -1e+6; + double to = index.row() == myCoordList->count()-1 ? 1e+6 : coordFromItem( myCoordList->item( index.row()+1 ))-tol; + sb->RangeStepAndValidator( from, to, 0.01 ); + w = sb; + } + return w; + } + + void LineDelegate::setEditorData ( QWidget * editor, const QModelIndex & index ) const + { + if ( mySpacingTreeWdg && index.column() == 0 ) + { + double t0, t1, t2=1.0; QString fun; + QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() ); + getFromItem( item, t0, t1, fun ); + if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 ) + { + item = mySpacingTreeWdg->topLevelItem( index.row()+1 ); + getFromItem( item, t1, t2, fun ); + } + const double tol = 1e-3; + SMESHGUI_SpinBox* sb = qobject_cast( editor ); + sb->RangeStepAndValidator( t0 + tol, t2 - tol, 0.01 ); + sb->SetValue( t1 ); + } + else + { + QItemDelegate::setEditorData( editor, index ); + } + } + void LineDelegate::setModelData( QWidget* editor, + QAbstractItemModel* model, + const QModelIndex& index ) const + { + if ( mySpacingTreeWdg ) + { + if ( index.column() == 0 ) + { + if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 ) + { + SMESHGUI_SpinBox* sb = qobject_cast( editor ); + double t0, t1, t = sb->GetValue(); QString fun; + + QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() ); + getFromItem( item, t0, t1, fun ); + setToItem( t0, t, fun, item ); + + item = mySpacingTreeWdg->topLevelItem( index.row() + 1 ); + getFromItem( item, t0, t1, fun ); + setToItem( t, t1, fun, item ); + } + } + else if ( !qobject_cast(editor)->text().trimmed().isEmpty() ) + { + QItemDelegate::setModelData( editor, model, index ); + } + } + else + { + SMESHGUI_SpinBox* sb = qobject_cast( editor ); + coordToItem( sb->GetValue(), myCoordList->item( index.row() )); + } + } + +} // namespace StdMeshersGUI + + +StdMeshersGUI_CartesianParamCreator::StdMeshersGUI_CartesianParamCreator(const QString& aHypType) + : StdMeshersGUI_StdHypothesisCreator( aHypType ), + myThreshold( 0 ) +{ + myAxisTabs[0] = 0; + myAxisTabs[1] = 0; + myAxisTabs[2] = 0; +} + +StdMeshersGUI_CartesianParamCreator::~StdMeshersGUI_CartesianParamCreator() +{ + if ( myAxisTabs[0] ) delete myAxisTabs[0]; + if ( myAxisTabs[1] ) delete myAxisTabs[1]; + if ( myAxisTabs[2] ) delete myAxisTabs[2]; + myAxisTabs[0] = 0; + myAxisTabs[1] = 0; + myAxisTabs[2] = 0; +} + +bool StdMeshersGUI_CartesianParamCreator::checkParams( QString& msg ) const +{ + if( !SMESHGUI_GenericHypothesisCreator::checkParams( msg ) ) + return false; + + if ( myName && myName->text().trimmed().isEmpty() ) + { + msg = tr("SMESH_WRN_EMPTY_NAME"); + return false; + } + if ( ! myThreshold->isValid( msg, true )) + return false; + + SMESH::SMESH_Hypothesis_var hyp = hypothesis(); + if ( !myAxisTabs[0]->checkParams( msg, hyp )) return false; + if ( !myAxisTabs[1]->checkParams( msg, hyp )) return false; + if ( !myAxisTabs[2]->checkParams( msg, hyp )) return false; + + return true; +} + +QFrame* StdMeshersGUI_CartesianParamCreator::buildFrame() +{ + QFrame* fr = new QFrame(); + //fr->setMinimumWidth(460); + + QVBoxLayout* lay = new QVBoxLayout( fr ); + lay->setMargin( 0 ); + lay->setSpacing( SPACING ); + + QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr ); + lay->addWidget( GroupC1 ); + + StdMeshers::StdMeshers_NumberOfSegments_var h = + StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() ); + + QGridLayout* argGroupLayout = new QGridLayout( GroupC1 ); + argGroupLayout->setSpacing( SPACING ); + argGroupLayout->setMargin( MARGIN ); + argGroupLayout->setColumnStretch( 0, 0 ); + argGroupLayout->setColumnStretch( 1, 1 ); + + int row = 0; + // 0) name + myName = 0; + if( isCreation() ) + { + myName = new QLineEdit( GroupC1 ); + argGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 ); + argGroupLayout->addWidget( myName, row, 1 ); + row++; + } + + // 1) threshold + argGroupLayout->addWidget( new QLabel( tr( "THRESHOLD" ), GroupC1 ), row, 0 ); + myThreshold = new SMESHGUI_SpinBox( GroupC1 ); + myThreshold->setAcceptNames( false ); // No Notebook variables allowed + myThreshold->RangeStepAndValidator( 1.1, 1e+10, 1., "length_precision" ); + argGroupLayout->addWidget( myThreshold, row, 1 ); + row++; + + // 2) Grid definition + QTabWidget* tabWdg = new QTabWidget( fr ); + myAxisTabs[ 0 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 0 ); + myAxisTabs[ 1 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 1 ); + myAxisTabs[ 2 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 2 ); + tabWdg->addTab( myAxisTabs[ 0 ], tr( "AXIS_X" ) ); + tabWdg->addTab( myAxisTabs[ 1 ], tr( "AXIS_Y" ) ); + tabWdg->addTab( myAxisTabs[ 2 ], tr( "AXIS_Z" ) ); + argGroupLayout->addWidget( tabWdg, row, 0, 1, 2 ); + + return fr; +} + +void StdMeshersGUI_CartesianParamCreator::retrieveParams() const +{ + StdMeshers::StdMeshers_CartesianParameters3D_var h = + StdMeshers::StdMeshers_CartesianParameters3D::_narrow( initParamsHypothesis() ); + + if( myName ) + myName->setText( hypName() ); + + QString varName = getVariableName( "SetSizeThreshold" ); + if ( varName.isEmpty() ) + myThreshold->setValue( h->GetSizeThreshold() ); + else + myThreshold->setText( varName ); + + for ( int ax = 0; ax < 3; ++ax ) + { + if ( h->IsGridBySpacing( ax )) + { + SMESH::string_array_var funs; + SMESH::double_array_var intPoints; + h->GetGridSpacing( funs.out(), intPoints.out(), ax ); + myAxisTabs[ax]->setSpacing( funs, intPoints ); + } + else + { + SMESH::double_array_var coords = h->GetGrid( ax ); + myAxisTabs[ax]->setCoordinates( coords ); + } + } + if ( dlg() ) + dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() ); +} + +QString StdMeshersGUI_CartesianParamCreator::storeParams() const +{ + StdMeshers::StdMeshers_CartesianParameters3D_var h = + StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() ); + + try + { + if( isCreation() ) + SMESH::SetName( SMESH::FindSObject( h ), myName->text().toLatin1().constData() ); + + h->SetVarParameter( myThreshold->text().toLatin1().constData(), "SetSizeThreshold" ); + h->SetSizeThreshold( myThreshold->text().toDouble() ); + + for ( int ax = 0; ax < 3; ++ax ) + { + if ( myAxisTabs[ax]->isGridBySpacing()) + { + SMESH::double_array_var intPoints; + SMESH::string_array_var funs; + myAxisTabs[ax]->getSpacing( funs.out(), intPoints.out() ); + h->SetGridSpacing( funs, intPoints, ax ); + } + else + { + SMESH::double_array_var coords = myAxisTabs[ax]->getCoordinates(); + h->SetGrid( coords, ax ); + } + } + } + catch(const SALOME::SALOME_Exception& ex) + { + SalomeApp_Tools::QtCatchCorbaException(ex); + } + return ""; +} + +QString StdMeshersGUI_CartesianParamCreator::helpPage() const +{ + return "cartesian_algo_page.html#cartesian_hyp_anchor"; +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h new file mode 100644 index 000000000..d8cddb6a8 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h @@ -0,0 +1,142 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshersGUI_CartesianParamCreator.h +// Author : Open CASCADE S.A.S. +// +#ifndef STDMESHERSGUI_CartesianParamCreator_H +#define STDMESHERSGUI_CartesianParamCreator_H + +// SMESH includes +#include "SMESH_StdMeshersGUI.hxx" + +#include "StdMeshersGUI_StdHypothesisCreator.h" + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Hypothesis) + +#include +#include + +class SMESHGUI_SpinBox; +class QLineEdit; +class QButtonGroup; +class QTreeWidgetItem; +class QString; +class QWidget; +class QTreeWidget; +class QListWidget; +class QStyleOptionViewItem; +class QModelIndex; +class QAbstractItemModel; +class QListWidgetItem; + +namespace StdMeshersGUI +{ + void getFromItem(QTreeWidgetItem * item, double& t0, double& t1, QString& fun ); + QTreeWidgetItem* setToItem (double t0, double t1, const QString& fun, QTreeWidgetItem* item=0); + + double coordFromItem( QListWidgetItem * ); + QListWidgetItem* coordToItem( double coord, QListWidgetItem * item=0); + + /*! + * \brief Widget defining the grid in one direction + */ + class GridAxisTab : public QFrame + { + Q_OBJECT + public: + GridAxisTab( QWidget* parent, const int axisIndex ); + ~GridAxisTab() {} + + void setCoordinates( SMESH::double_array_var coords ); + void setSpacing( SMESH::string_array_var funs, SMESH::double_array_var points ); + + bool checkParams(QString& msg, SMESH::SMESH_Hypothesis_var& hyp) const; + bool isGridBySpacing() const; + SMESH::double_array* getCoordinates(); + void getSpacing(SMESH::string_array_out funs, SMESH::double_array_out points) const; + + private slots: + void onInsert(); + void onDelete(); + void onMode(int); + void onStepChange(); + void updateButtons(); + + private: + + int myAxisIndex; + QButtonGroup* myModeGroup; + QTreeWidget* mySpacingTreeWdg; + QListWidget* myCoordList; + QPushButton* myInsertBtn; + QPushButton* myDeleteBtn; + SMESHGUI_SpinBox* myStepSpin; + QLabel* myStepLabel; + double myStep; + }; + /* + * \brief : Custom item delegate + */ + class LineDelegate : public QItemDelegate + { + Q_OBJECT + public: + LineDelegate( QWidget* parent ); + ~LineDelegate() {} + + QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const; + void setEditorData ( QWidget * editor, const QModelIndex & index ) const; + void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const; + + private: + QTreeWidget* mySpacingTreeWdg; + QListWidget* myCoordList; + }; +} + +class STDMESHERSGUI_EXPORT StdMeshersGUI_CartesianParamCreator : public StdMeshersGUI_StdHypothesisCreator +{ + Q_OBJECT + +public: + StdMeshersGUI_CartesianParamCreator( const QString& aHypType ); + virtual ~StdMeshersGUI_CartesianParamCreator(); + + virtual bool checkParams( QString& ) const; + virtual QString helpPage() const; + +protected: + virtual QFrame* buildFrame(); + virtual void retrieveParams() const; + virtual QString storeParams() const; + +private: + QLineEdit* myName; + SMESHGUI_SpinBox* myThreshold; + StdMeshersGUI::GridAxisTab* myAxisTabs[3]; +}; + +#endif // STDMESHERSGUI_CartesianParamCreator_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx index ead8d1c3d..4d9bd5111 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_DistrPreview.cxx // Author : Open CASCADE S.A.S. // SMESH includes @@ -49,6 +50,10 @@ #ifdef WIN32 # include #endif +#include +#include + +#include StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::StdMeshers_NumberOfSegments_ptr h ) : QwtPlot( p ), @@ -60,6 +65,7 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers:: myIsDone( true ), myNbSeg( 1 ) { + Kernel_Utils::Localizer loc; myHypo = StdMeshers::StdMeshers_NumberOfSegments::_duplicate( h ); myVars.ChangeValue( 1 ) = new Expr_NamedUnknown( "t" ); myDensity = new QwtPlotCurve( QString() ); @@ -72,7 +78,7 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers:: QwtText mt = myMsg->label(); mt.setBackgroundPen( QPen( Qt::red, 1 ) ); QFont f = mt.font(); - f.setPointSize( 14 ); f.setBold( true ); + f.setPointSize( 14 ); //f.setBold( true ); mt.setFont( f ); myMsg->setLabel( mt ); myDensity->setPen( QPen( Qt::red, 1 ) ); @@ -88,6 +94,17 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers:: } insertLegend( l, QwtPlot::BottomLegend ); + enableAxis(QwtPlot::yLeft, false); + enableAxis(QwtPlot::yRight, true); + + QFont axisFont; + axisFont.setPointSize( 8 ); + setAxisFont(QwtPlot::yRight, axisFont); + setAxisFont(QwtPlot::xBottom, axisFont); + + myDensity->setYAxis(QwtPlot::yRight); + myDistr->setYAxis(QwtPlot::yRight); + myMsg->setYAxis(QwtPlot::yRight); myDensity->setTitle( tr( "SMESH_DENSITY_FUNC" ) ); myDistr->setTitle( tr( "SMESH_DISTR" ) ); @@ -200,6 +217,7 @@ bool StdMeshersGUI_DistrPreview::createTable( SMESH::double_array& func ) void StdMeshersGUI_DistrPreview::update() { + Kernel_Utils::Localizer loc; SMESH::double_array graph, distr; if( isTableFunc() ) { @@ -218,13 +236,13 @@ void StdMeshersGUI_DistrPreview::update() { SMESH::double_array* arr = 0; if( isTableFunc() ) - arr = h->BuildDistributionTab( myTableFunc, myNbSeg, ( int )myConv ); + arr = h->BuildDistributionTab( myTableFunc, myNbSeg, ( int )myConv ); else - arr = h->BuildDistributionExpr( myFunction.toLatin1().data(), myNbSeg, ( int )myConv ); + arr = h->BuildDistributionExpr( myFunction.toLatin1().data(), myNbSeg, ( int )myConv ); if( arr ) { - distr = *arr; - delete arr; + distr = *arr; + delete arr; } } } @@ -257,6 +275,15 @@ void StdMeshersGUI_DistrPreview::update() showError(); return; } +#ifdef WIN32 + if ( std::fabs(y[i]) >= HUGE_VAL) + y[i] = HUGE_VAL/100.; +#else + if ( isinf(y[i])) + y[i] = std::numeric_limits::max()/100.; +#endif +// if ( y[i] > 1e3 ) +// y[i] = 1e3; if( i==0 || y[i]max_y ) @@ -333,7 +360,7 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr ) if( !name.IsNull() ) { if( name->GetName()!="t" ) - res = false; + res = false; } else res = isCorrectArg( sub ); @@ -343,6 +370,7 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr ) bool StdMeshersGUI_DistrPreview::init( const QString& str ) { + Kernel_Utils::Localizer loc; bool parsed_ok = true; try { #ifdef NO_CAS_CATCH @@ -416,15 +444,15 @@ bool StdMeshersGUI_DistrPreview::convert( double& v ) const #ifdef NO_CAS_CATCH OCC_CATCH_SIGNALS; #endif - // in StdMeshers_NumberOfSegments.cc - // const double PRECISION = 1e-7; - // - if(v < -7) v = -7.0; - v = pow( 10.0, v ); + // in StdMeshers_NumberOfSegments.cc + // const double PRECISION = 1e-7; + // + if(v < -7) v = -7.0; + v = pow( 10.0, v ); } catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - v = 0.0; - ok = false; + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + v = 0.0; + ok = false; } } break; diff --git a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.h b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.h index 87a9eb86e..8abcc3e26 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.h +++ b/src/StdMeshersGUI/StdMeshersGUI_DistrPreview.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_DistrPreview.h // Author : Open CASCADE S.A.S. // diff --git a/src/StdMeshersGUI/StdMeshersGUI_DistrTable.cxx b/src/StdMeshersGUI/StdMeshersGUI_DistrTable.cxx index cc718ed66..dbd9a4d8b 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_DistrTable.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_DistrTable.cxx @@ -1,34 +1,37 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_DistrTable.cxx // Author : Open CASCADE S.A.S. // SMESH includes // #include "StdMeshersGUI_DistrTable.h" +#include + // Qt incldues #include #include -#include +#include #include #include #include @@ -84,14 +87,14 @@ public: ~SpinBoxDelegate(); QWidget* createEditor( QWidget*, - const QStyleOptionViewItem&, - const QModelIndex& ) const; + const QStyleOptionViewItem&, + const QModelIndex& ) const; void setEditorData( QWidget*, const QModelIndex&) const; void setModelData( QWidget*, QAbstractItemModel*, - const QModelIndex& ) const; + const QModelIndex& ) const; void updateEditorGeometry( QWidget*, - const QStyleOptionViewItem&, - const QModelIndex& ) const; + const QStyleOptionViewItem&, + const QModelIndex& ) const; private: StdMeshersGUI_DistrTableFrame::Table* myTable; @@ -109,7 +112,7 @@ private: struct EditorData { int r, c; - QDoubleSpinBox* sb; + SMESHGUI_SpinBox* sb; EditorData() { reset(); } void reset() { r = -1; c = -1; sb = 0; } }; @@ -138,7 +141,7 @@ public: void addRow(); void deleteRow(); - void setEditor( int, int, QDoubleSpinBox* ); + void setEditor( int, int, SMESHGUI_SpinBox* ); protected: void closeEditor( QWidget*, QAbstractItemDelegate::EndEditHint ); @@ -173,21 +176,25 @@ StdMeshersGUI_DistrTableFrame::SpinBoxDelegate:: QWidget* StdMeshersGUI_DistrTableFrame::SpinBoxDelegate:: createEditor( QWidget* parent, - const QStyleOptionViewItem& /*option*/, - const QModelIndex& index ) const + const QStyleOptionViewItem& /*option*/, + const QModelIndex& index ) const { - QDoubleSpinBox* sb = new QDoubleSpinBox( parent ); + SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent ); + + sb->setAcceptNames(false); // No Notebook variables allowed + double aMin = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? + myTable->argMinimum( index.row() ) : + myTable->funcMinimum( index.row() ); + double aMax = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? + myTable->argMaximum( index.row() ) : + myTable->funcMaximum( index.row() ); + double aStep = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? + myTable->argStep( index.row() ) : + myTable->funcStep( index.row() ); + sb->RangeStepAndValidator( aMin, aMax, aStep, "parametric_precision" ); sb->setFrame(false); - sb->setMinimum( index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? - myTable->argMinimum( index.row() ) : - myTable->funcMinimum( index.row() ) ); - sb->setMaximum( index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? - myTable->argMaximum( index.row() ) : - myTable->funcMaximum( index.row() ) ); - sb->setSingleStep( index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? - myTable->argStep( index.row() ) : - myTable->funcStep( index.row() ) ); - myTable->setEditor( index.row(), index.column(), sb ); + + myTable->setEditor( index.row(), index.column(), sb ); return sb; } @@ -196,7 +203,7 @@ StdMeshersGUI_DistrTableFrame::SpinBoxDelegate:: setEditorData( QWidget* editor, const QModelIndex& index ) const { QString value = index.model()->data(index, Qt::DisplayRole).toString(); - QDoubleSpinBox* sb = static_cast(editor); + SMESHGUI_SpinBox* sb = static_cast(editor); bool bOk = false; double v = value.toDouble( &bOk ); @@ -208,17 +215,17 @@ setEditorData( QWidget* editor, const QModelIndex& index ) const void StdMeshersGUI_DistrTableFrame::SpinBoxDelegate:: setModelData( QWidget* editor, QAbstractItemModel* model, - const QModelIndex& index ) const + const QModelIndex& index ) const { - QDoubleSpinBox* sb = static_cast(editor); + SMESHGUI_SpinBox* sb = static_cast(editor); model->setData( index, QString::number( sb->value() ), Qt::DisplayRole ); } void StdMeshersGUI_DistrTableFrame::SpinBoxDelegate:: updateEditorGeometry( QWidget* editor, - const QStyleOptionViewItem& option, - const QModelIndex& /*index*/ ) const + const QStyleOptionViewItem& option, + const QModelIndex& /*index*/ ) const { editor->setGeometry( option.rect ); } @@ -238,6 +245,8 @@ Table( QWidget* parent, int rows ) QStringList labs; labs << "t" << "f(t)"; setHorizontalHeaderLabels( labs ); + this->horizontalHeader()->setStretchLastSection(true); + this->horizontalHeader()->setDefaultSectionSize(60); while( rows-- ) addRow(); @@ -247,7 +256,7 @@ Table( QWidget* parent, int rows ) void StdMeshersGUI_DistrTableFrame::Table:: -setEditor( int r, int c, QDoubleSpinBox* sb ) +setEditor( int r, int c, SMESHGUI_SpinBox* sb ) { myEditorData.r = r; myEditorData.c = c; @@ -405,15 +414,15 @@ sizeHint() const { if( cachedSizeHint().isValid() ) return cachedSizeHint(); - - QSize sh = QTableWidget::sizeHint(); - if( sh.width() < 400 ) - sh.setWidth( 400 ); - if( sh.height() < 200 ) - sh.setHeight( 200 ); - - setCachedSizeHint( sh ); - return sh; + return QTableWidget::sizeHint(); +// QSize sh = QTableWidget::sizeHint(); +// if( sh.width() < 400 ) +// sh.setWidth( 400 ); +// if( sh.height() < 200 ) +// sh.setHeight( 200 ); +// +// setCachedSizeHint( sh ); +// return sh; } void @@ -501,38 +510,32 @@ StdMeshersGUI_DistrTableFrame:: StdMeshersGUI_DistrTableFrame( QWidget* parent ) : QWidget( parent ) { - QVBoxLayout* main = new QVBoxLayout( this ); + QGridLayout* main = new QGridLayout( this ); main->setMargin( 0 ); main->setSpacing( 0 ); // --- myTable = new Table( this ); connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) ); - - // --- - QWidget* aButFrame = new QWidget( this ); - QHBoxLayout* butLay = new QHBoxLayout( aButFrame ); - butLay->setContentsMargins( 0, SPACING, 0, SPACING ); - butLay->setSpacing( SPACING ); - myButtons[ InsertRowBtn ] = new QPushButton( tr( "SMESH_INSERT_ROW" ), aButFrame ); - myButtons[ RemoveRowBtn ] = new QPushButton( tr( "SMESH_REMOVE_ROW" ), aButFrame ); + myButtons[ InsertRowBtn ] = new QPushButton( tr( "SMESH_INSERT_ROW" ), this ); + myButtons[ RemoveRowBtn ] = new QPushButton( tr( "SMESH_REMOVE_ROW" ), this ); - butLay->addWidget( myButtons[ InsertRowBtn ] ); - butLay->addWidget( myButtons[ RemoveRowBtn ] ); - butLay->addStretch(); // --- - main->addWidget( myTable ); - main->addWidget( aButFrame ); + main->addWidget( myTable , 0, 0, 1, 3); + main->addWidget( myButtons[ InsertRowBtn ] , 1, 0); + main->addWidget( myButtons[ RemoveRowBtn ] , 1, 1); + main->setColumnStretch(2, 1); + main->setSpacing( SPACING ); // --- connect( myButtons[ InsertRowBtn ], SIGNAL( clicked() ), this, SLOT( onInsert() ) ); connect( myButtons[ RemoveRowBtn ], SIGNAL( clicked() ), this, SLOT( onRemove() ) ); connect( myTable, SIGNAL( currentCellChanged( int, int, int, int ) ), - this, SIGNAL( currentChanged( int, int ) ) ); + this, SIGNAL( currentChanged( int, int ) ) ); connect( myTable, SIGNAL( cellChanged( int, int ) ), - this, SIGNAL( valueChanged( int, int ) ) ); + this, SIGNAL( valueChanged( int, int ) ) ); } StdMeshersGUI_DistrTableFrame:: diff --git a/src/StdMeshersGUI/StdMeshersGUI_DistrTable.h b/src/StdMeshersGUI/StdMeshersGUI_DistrTable.h index 11a4ab333..9ba227c3a 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_DistrTable.h +++ b/src/StdMeshersGUI/StdMeshersGUI_DistrTable.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_DistrTable.h // Author : Open CASCADE S.A.S. // diff --git a/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.cxx new file mode 100644 index 000000000..13b575e85 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.cxx @@ -0,0 +1,394 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshersGUI_FixedPointsParamWdg.cxx +// Author : Open CASCADE S.A.S. +// SMESH includes +// +#include "StdMeshersGUI_FixedPointsParamWdg.h" + +#include + +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 6 +#define MARGIN 0 +#define SAME_TEXT "-/-" + +#define TOLERANCE 1e-7 +#define EQUAL_DBL(a,b) (fabs(a-b)b)&&!EQUAL_DBL(a,b)) + +/* + * class : Tree Widget Item Delegate + * purpose : Custom item delegate + */ + +class StdMeshersGUI_FixedPointsParamWdg::LineDelegate : public QItemDelegate +{ +public: + LineDelegate( QTreeWidget* ); + ~LineDelegate() {} + + QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const; + void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const; + +private: + QTreeWidget* myTreeWidget; +}; + +StdMeshersGUI_FixedPointsParamWdg::LineDelegate::LineDelegate( QTreeWidget* parent ) + : QItemDelegate( parent ), + myTreeWidget( parent ) +{ +} + +QWidget* StdMeshersGUI_FixedPointsParamWdg::LineDelegate::createEditor( QWidget* parent, + const QStyleOptionViewItem& option, + const QModelIndex& index ) const +{ + QWidget* w = 0; + if ( (index.column() == 1 ) ) { + SalomeApp_IntSpinBox* sb = new SalomeApp_IntSpinBox( parent ); + sb->setAcceptNames( false ); // No Notebook variables allowed + sb->setFrame( false ); + sb->setRange( 1, 999); + w = sb; + } + + return w; +} + +void StdMeshersGUI_FixedPointsParamWdg::LineDelegate::setModelData( QWidget* editor, + QAbstractItemModel* model, + const QModelIndex& index ) const +{ + model->setData( index, qobject_cast( editor )->value(), Qt::EditRole ); + model->setData( index, qobject_cast( editor )->value(), Qt::UserRole ); +} + +//================================================================================ +/*! + * Constructor + */ +//================================================================================ + +StdMeshersGUI_FixedPointsParamWdg +::StdMeshersGUI_FixedPointsParamWdg( QWidget * parent ): + QWidget( parent ) +{ + QGridLayout* edgesLayout = new QGridLayout( this ); + edgesLayout->setMargin( MARGIN ); + edgesLayout->setSpacing( SPACING ); + + myListWidget = new QListWidget( this ); + myTreeWidget = new QTreeWidget( this ); + mySpinBox = new SMESHGUI_SpinBox( this ); + myAddButton = new QPushButton( tr( "SMESH_BUT_ADD" ), this ); + myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this ); + mySameValues = new QCheckBox( tr("SMESH_SAME_NB_SEGMENTS"), this); + + myListWidget->setSelectionMode( QListWidget::ExtendedSelection ); + + myTreeWidget->setColumnCount(2); + myTreeWidget->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << tr( "SMESH_NB_SEGMENTS" ) ); + myTreeWidget->setColumnWidth( 1, 40 ); + myTreeWidget->setColumnWidth( 2, 30 ); + myTreeWidget->setItemDelegate( new LineDelegate( myTreeWidget ) ); + + edgesLayout->addWidget(myListWidget, 0, 0, 4, 1); + edgesLayout->addWidget(mySpinBox, 0, 1); + edgesLayout->addWidget(myAddButton, 1, 1); + edgesLayout->addWidget(myRemoveButton, 2, 1); + edgesLayout->addWidget(myTreeWidget, 0, 2, 4, 1); + edgesLayout->addWidget(mySameValues, 4, 0, 1, 3); + edgesLayout->setRowStretch( 3, 5 ); + edgesLayout->setColumnStretch(0, 1); + edgesLayout->setColumnStretch(1, 0); + edgesLayout->setColumnStretch(2, 2); + + myListWidget->setMinimumWidth( 80 ); + myTreeWidget->setMinimumWidth( 200 ); + + mySpinBox->setAcceptNames( false ); // No Notebook variables allowed + mySpinBox->RangeStepAndValidator( 0., 1., .1, "parametric_precision" ); + myListWidget->setMinimumWidth( 70 ); + + connect( myAddButton, SIGNAL( clicked() ), SLOT( onAdd() ) ); + connect( myRemoveButton, SIGNAL( clicked() ), SLOT( onRemove() ) ); + connect( mySameValues, SIGNAL( stateChanged( int ) ), SLOT( onCheckBoxChanged() ) ); + connect( mySpinBox, SIGNAL( valueChanged( double ) ), SLOT( updateState() ) ); + connect( myListWidget, SIGNAL( itemSelectionChanged() ), SLOT( updateState() ) ); + myListWidget->installEventFilter( this ); + + clear(); +} + +//================================================================================ +/*! + * Destructor + */ +//================================================================================ + +StdMeshersGUI_FixedPointsParamWdg::~StdMeshersGUI_FixedPointsParamWdg() +{ +} + +//================================================================================ +/*! + * Event filter + */ +//================================================================================ +bool StdMeshersGUI_FixedPointsParamWdg::eventFilter( QObject* o, QEvent* e ) +{ + if ( o == myListWidget && e->type() == QEvent::KeyPress ) { + QKeyEvent* ke = (QKeyEvent*)e; + if ( ke->key() == Qt::Key_Delete ) + removePoints(); + } + return QWidget::eventFilter( o, e ); +} + +//================================================================================ +/*! + * Clear widget + */ +//================================================================================ +void StdMeshersGUI_FixedPointsParamWdg::clear() +{ + myTreeWidget->clear(); + myListWidget->clear(); + myTreeWidget->addTopLevelItem( newTreeItem( 0, 1 ) ); + mySpinBox->setValue( 0. ); + onCheckBoxChanged(); + updateState(); +} + +//================================================================================= +// function : onAdd() +// purpose : Called when Add Button Clicked +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::onAdd() +{ + addPoint( mySpinBox->value() ); +} + +//================================================================================= +// function : onRemove() +// purpose : Called when Remove Button Clicked +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::onRemove() +{ + removePoints(); +} + +//================================================================================= +// function : newTreeItem() +// purpose : Called to create TreeItem +//================================================================================= + +QTreeWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newTreeItem( double v1, double v2 ) +{ + QTreeWidgetItem* anItem = new QTreeWidgetItem(); + anItem->setText( 0, treeItemText( v1, v2 ) ); + anItem->setText( 1, QString::number( 1 ) ); + anItem->setData( 1, Qt::UserRole, 1 ); + return anItem; +} + +//================================================================================= +// function : newListItem() +// purpose : Called to create ListItem +//================================================================================= + +QListWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newListItem( double v ) +{ + QListWidgetItem* anItem = new QListWidgetItem( QString::number( v ) ); + anItem->setData( Qt::UserRole, v ); + return anItem; +} + +//================================================================================= +// function : itemText() +// purpose : Called to convert Values to Text +//================================================================================= + +QString StdMeshersGUI_FixedPointsParamWdg::treeItemText( double v1, double v2 ) +{ + return QString( "%1 - %2" ).arg( v1 ).arg( v2 ); +} + +//================================================================================= +// function : addPoint() +// purpose : Called to Add new Point +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::addPoint( double v) +{ + if ( GT_DBL(v, 0.0) && LT_DBL(v, 1.0)) { + bool toInsert = true; + int idx = myTreeWidget->topLevelItemCount()-1; + for ( int i = 0 ; i < myListWidget->count(); i++ ) { + double lv = point( i ); + if ( EQUAL_DBL(lv, v) ) { toInsert = false; break; } + else if ( GT_DBL(lv, v) ) { + idx = i; break; + } + } + if ( toInsert ) { + double v1 = idx == 0 ? 0 : point( idx-1 ); + double v2 = idx == myTreeWidget->topLevelItemCount()-1 ? 1 : point( idx ); + myTreeWidget->insertTopLevelItem( idx, newTreeItem( v1, v ) ); + myTreeWidget->topLevelItem( idx+1 )->setText( 0, treeItemText( v, v2 ) ); + myListWidget->insertItem( idx, newListItem( v ) ); + onCheckBoxChanged(); + } + } + updateState(); +} + +//================================================================================= +// function : removePoints() +// purpose : Called to remove selected points +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::removePoints() +{ + QList selItems = myListWidget->selectedItems(); + QListWidgetItem* item; + foreach ( item, selItems ) { + int idx = myListWidget->row( item ); + delete myTreeWidget->topLevelItem( idx ); + delete item; + myTreeWidget->topLevelItem( idx )->setText( 0, treeItemText( idx == 0 ? 0 : point( idx-1 ), + idx > myListWidget->count()-1 ? 1 : point( idx ) ) ); + } + onCheckBoxChanged(); + updateState(); +} + +double StdMeshersGUI_FixedPointsParamWdg::point( int idx ) const +{ + return idx >= 0 && idx < myListWidget->count() ? myListWidget->item( idx )->data( Qt::UserRole ).toDouble() : 0.; +} + +void StdMeshersGUI_FixedPointsParamWdg::setNbSegments( int idx, int val ) +{ + if ( idx >= 0 && idx < myTreeWidget->topLevelItemCount() ) { + myTreeWidget->topLevelItem( idx )->setData( 1, Qt::UserRole, val ); + myTreeWidget->topLevelItem( idx )->setText( 1, idx > 0 && mySameValues->isChecked() ? QString( SAME_TEXT ) : QString::number( val ) ); + } +} + +int StdMeshersGUI_FixedPointsParamWdg::nbSegments( int idx ) const +{ + return idx >= 0 && idx < myTreeWidget->topLevelItemCount() ? myTreeWidget->topLevelItem( idx )->data( 1, Qt::UserRole ).toInt() : 1; +} + +//================================================================================= +// function : onCheckBoxChanged() +// purpose : Called when Check Box Clicked +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::onCheckBoxChanged() +{ + for ( int i = 0; i < myTreeWidget->topLevelItemCount(); i++ ) { + QTreeWidgetItem* anItem = myTreeWidget->topLevelItem(i); + setNbSegments( i, nbSegments( i ) ); + anItem->setFlags( mySameValues->isChecked() && i > 0 ? anItem->flags() & ~Qt::ItemIsEditable : anItem->flags() | Qt::ItemIsEditable ); + } +} + +//================================================================================= +// function : updateState() +// purpose : Update widgets state +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::updateState() +{ + double v = mySpinBox->value(); + myAddButton->setEnabled( GT_DBL(v, 0.0) && LT_DBL(v, 1.0) ); + myRemoveButton->setEnabled( myListWidget->selectedItems().count() > 0 ); +} + +//================================================================================= +// function : GetListOfPoints +// purpose : Called to get the list of Edges IDs +//================================================================================= +SMESH::double_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfPoints() +{ + SMESH::double_array_var anArray = new SMESH::double_array; + int size = myListWidget->count(); + anArray->length( size ); + for (int i = 0; i < size; i++) { + anArray[i] = point(i); + } + return anArray; +} + +//================================================================================= +// function : SetListOfPoints +// purpose : Called to set the list of Points +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::SetListOfPoints( SMESH::double_array_var thePoints) +{ + clear(); + for ( int i = 0; i < thePoints->length(); i++ ) { + addPoint( thePoints[ i ] ); + } +} + +//================================================================================= +// function : GetListOfSegments +// purpose : Called to get the list Number of Segments +//================================================================================= +SMESH::long_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfSegments() +{ + SMESH::long_array_var anArray = new SMESH::long_array; + int size = mySameValues->isChecked() ? 1 : myTreeWidget->topLevelItemCount(); + anArray->length( size ); + for (int i = 0; i < size; i++) { + anArray[i] = nbSegments( i ); + } + return anArray; +} + +//================================================================================= +// function : SetListOfPoints +// purpose : Called to set the list of Points +//================================================================================= +void StdMeshersGUI_FixedPointsParamWdg::SetListOfSegments( SMESH::long_array_var theSegments) +{ + if ( myListWidget->count() > 0 && theSegments->length() == 1) + mySameValues->setChecked(true); + for ( int i = 0; i < theSegments->length(); i++ ) { + setNbSegments( i, theSegments[i] ); + } +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.h new file mode 100644 index 000000000..312b00a34 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.h @@ -0,0 +1,92 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshersGUI_FixedPointsParamWdg.h +// Author : Open CASCADE S.A.S. (dmv) +// +#ifndef STDMESHERSGUI_FIXEDPOINTSPARAMWGD_H +#define STDMESHERSGUI_FIXEDPOINTSPARAMWGD_H + +// SMESH includes +#include +#include "SMESH_StdMeshersGUI.hxx" + +// Qt includes +#include +#include + +class SMESHGUI; +class SMESHGUI_SpinBox; +class QPushButton; +class QLineEdit; +class QCheckBox; +class QListWidget; +class QListWidgetItem; +class QTreeWidget; +class QTreeWidgetItem; + +class STDMESHERSGUI_EXPORT StdMeshersGUI_FixedPointsParamWdg : public QWidget +{ + Q_OBJECT + + class LineDelegate; + +public: + StdMeshersGUI_FixedPointsParamWdg( QWidget* parent = 0 ); + ~StdMeshersGUI_FixedPointsParamWdg(); + + bool eventFilter( QObject*, QEvent* ); + + SMESH::double_array_var GetListOfPoints(); + void SetListOfPoints( SMESH::double_array_var ); + + SMESH::long_array_var GetListOfSegments(); + void SetListOfSegments( SMESH::long_array_var ); + + QString GetValue() const { return myParamValue; } + +private slots: + void onAdd(); + void onRemove(); + void onCheckBoxChanged(); + void updateState(); + +private: + void clear(); + void addPoint( double ); + void removePoints(); + double point( int ) const; + void setNbSegments( int, int ); + int nbSegments( int ) const; + + static QTreeWidgetItem* newTreeItem( double v1, double v2 ); + static QListWidgetItem* newListItem( double v1 ); + static QString treeItemText( double v1, double v2 ); + +private: + QListWidget* myListWidget; + QTreeWidget* myTreeWidget; + SMESHGUI_SpinBox* mySpinBox; + QPushButton* myAddButton; + QPushButton* myRemoveButton; + QCheckBox* mySameValues; + QString myParamValue; +}; + +#endif // STDMESHERSGUI_FIXEDPOINTSPARAMWGD_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx index ffdc4a7f1..ee46af5b1 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_LayerDistributionParamWdg.cxx // Author : Open CASCADE S.A.S. // SMESH includes @@ -50,7 +51,7 @@ StdMeshersGUI_LayerDistributionParamWdg ::StdMeshersGUI_LayerDistributionParamWdg(SMESH::SMESH_Hypothesis_ptr hyp, - const QString& theName, + const QString& theName, QDialog* dlg): QWidget(), myName(theName), myDlg( dlg ) { @@ -198,19 +199,26 @@ void StdMeshersGUI_LayerDistributionParamWdg::onEdit() return; CORBA::String_var hypType = myHyp->GetName(); - SMESHGUI_GenericHypothesisCreator* - editor = SMESH::GetHypothesisCreator( hypType.in() ); + // BUG 0020378 + SMESHGUI_GenericHypothesisCreator* editor = SMESH::GetHypothesisCreator(hypType.in()); if ( !editor ) return; - if ( myDlg ) myDlg->hide(); + if ( myDlg ) + myDlg->hide(); try { QWidget* parent = this; - if ( myDlg ) parent = myDlg->parentWidget(); - editor->edit( myHyp, myName, parent ); + if ( myDlg ) + parent = myDlg->parentWidget(); + editor->edit( myHyp, myName, parent, this, SLOT( onEdited( int ) ) ); } - catch(...) { + catch(...) + { } +} - if ( myDlg ) myDlg->show(); +void StdMeshersGUI_LayerDistributionParamWdg::onEdited( int result ) +{ + if ( myDlg ) + myDlg->show(); } diff --git a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h index b04f2a605..41224a412 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_LayerDistributionParamWdg.h // Author : Open CASCADE S.A.S. // @@ -51,7 +52,7 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_LayerDistributionParamWdg : public QWid public: StdMeshersGUI_LayerDistributionParamWdg(SMESH::SMESH_Hypothesis_ptr, - const QString&, + const QString&, QDialog*); ~StdMeshersGUI_LayerDistributionParamWdg(); @@ -65,6 +66,7 @@ private slots: void onCreate(); void onEdit(); void onHypTypePopup( QAction* ); + void onEdited(int); private: void init(); diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx index 9e8e0bda8..f4e65c3f6 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_NbSegmentsCreator.cxx // Author : Open CASCADE S.A.S. // SMESH includes @@ -26,6 +27,7 @@ #include "StdMeshersGUI_NbSegmentsCreator.h" #include "StdMeshersGUI_DistrTable.h" #include "StdMeshersGUI_DistrPreview.h" +#include "StdMeshersGUI_SubShapeSelectorWdg.h" #include #include @@ -96,17 +98,17 @@ bool StdMeshersGUI_NbSegmentsCreator::checkParams( QString& msg ) const QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame() { QFrame* fr = new QFrame(); + fr->setMinimumWidth(460); QVBoxLayout* lay = new QVBoxLayout( fr ); lay->setMargin( 0 ); - lay->setSpacing( 0 ); + lay->setSpacing( SPACING ); QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr ); lay->addWidget( GroupC1 ); StdMeshers::StdMeshers_NumberOfSegments_var h = StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() ); - myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() ); myGroupLayout = new QGridLayout( GroupC1 ); myGroupLayout->setSpacing( SPACING ); @@ -125,6 +127,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame() row++; } + // 1) number of segments myGroupLayout->addWidget( new QLabel( tr( "SMESH_NB_SEGMENTS_PARAM" ), GroupC1 ), row, 0 ); myNbSeg = new SalomeApp_IntSpinBox( GroupC1 ); @@ -133,6 +136,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame() myGroupLayout->addWidget( myNbSeg, row, 1 ); row++; + // 2) type of distribution myGroupLayout->addWidget( new QLabel( tr( "SMESH_DISTR_TYPE" ), GroupC1 ), row, 0 ); myDistr = new QtxComboBox( GroupC1 ); @@ -145,32 +149,43 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame() myGroupLayout->addWidget( myDistr, row, 1 ); row++; + // 3) scale myGroupLayout->addWidget( myLScale = new QLabel( tr( "SMESH_NB_SEGMENTS_SCALE_PARAM" ), GroupC1 ), row, 0 ); myScale = new SMESHGUI_SpinBox( GroupC1 ); - myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, 6 ); + myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, "parametric_precision" ); myGroupLayout->addWidget( myScale, row, 1 ); row++; - myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 ); - myGroupLayout->addWidget( myInfo, row, 0, 1, 2 ); - row++; - // 4) table - myGroupLayout->addWidget( myLTable = new QLabel( tr( "SMESH_TAB_FUNC" ), GroupC1 ), row, 0 ); - myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 ); - myGroupLayout->addWidget( myTable, row, 1 ); + // 4) Distribution definition + QGridLayout* myDistLayout = new QGridLayout(GroupC1); + myGroupLayout->addLayout( myDistLayout, row, 0, 1, 2 ); myGroupLayout->setRowStretch( row, 1 ); - myTableRow = row; - row++; + row ++; - // 5) expression - myGroupLayout->addWidget( myLExpr = new QLabel( tr( "SMESH_EXPR_FUNC" ), GroupC1 ), row, 0 ); + // a) expression + QHBoxLayout* myExprLayout = new QHBoxLayout(GroupC1); + myExprLayout->addWidget( myLExpr = new QLabel( "f(t)=", GroupC1 ), 0); myExpr = new QLineEdit( GroupC1 ); - myGroupLayout->addWidget( myExpr, row, 1 ); - row++; + myExprLayout->addWidget( myExpr,1); + myDistLayout->addLayout(myExprLayout,1 ,0); + myDistLayout->setRowStretch(2, 1); - // 6) conversion (radiogroup) + // b) warning + myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 ); + myDistLayout->addWidget( myInfo, 0, 0, 1, 2); + + // c) table + myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 ); + myDistLayout->addWidget( myTable, 1, 0, 2, 1 ); + + // d) preview + myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() ); + myPreview->setMinimumHeight(220); + myDistLayout->addWidget( myPreview, 1, 1, 2, 1 ); + + // 5) conversion (radiogroup) myConvBox = new QGroupBox( tr( "SMESH_CONV_MODE" ), GroupC1 ); myConv = new QButtonGroup( GroupC1 ); @@ -189,17 +204,30 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame() myGroupLayout->addWidget( myConvBox, row, 0, 1, 2 ); row++; - // 7) distribution preview - myGroupLayout->addWidget( myPreview, row, 0, 1, 2 ); - myGroupLayout->setRowStretch( row, 1 ); - myPreviewRow = row; - row++; + // 6) reverse edge parameters + myReversedEdgesBox = new QGroupBox(tr( "SMESH_REVERSED_EDGES" ), fr); + QHBoxLayout* edgeLay = new QHBoxLayout( myReversedEdgesBox ); + + myDirectionWidget = new StdMeshersGUI_SubShapeSelectorWdg( myReversedEdgesBox ); + QString aGeomEntry = getShapeEntry(); + QString aMainEntry = getMainShapeEntry(); + if ( aGeomEntry == "" ) + aGeomEntry = h->GetObjectEntry(); + myDirectionWidget->SetGeomShapeEntry( aGeomEntry ); + myDirectionWidget->SetMainShapeEntry( aMainEntry ); + myDirectionWidget->SetListOfIDs( h->GetReversedEdges() ); + edgeLay->addWidget( myDirectionWidget ); + + lay->addWidget( myReversedEdgesBox ); + lay->setStretchFactor( GroupC1, 2); + lay->setStretchFactor( myReversedEdgesBox, 1); + connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) ); connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) ); connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) ); connect( myExpr, SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) ); - connect( myConv, SIGNAL( cuttonClicked( int ) ), this, SLOT( onValueChanged() ) ); + connect( myConv, SIGNAL( buttonClicked( int ) ), this, SLOT( onValueChanged() ) ); return fr; } @@ -271,10 +299,12 @@ QString StdMeshersGUI_NbSegmentsCreator::storeParams() const break; } if ( hasConv ) + { if ( data.myConv ) valStr += "; " + tr("SMESH_CUT_NEG_MODE"); else valStr += "; " + tr("SMESH_EXP_MODE"); + } return valStr; } @@ -287,17 +317,17 @@ bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisDa h_data.myName = hypName(); h_data.myNbSeg = (int) h->GetNumberOfSegments(); - - SMESH::ListOfParameters_var aParameters = h->GetLastParameters(); - h_data.myNbSegVarName = (aParameters->length() > 0) ? QString(aParameters[0].in()) : QString(""); + CORBA::String_var aVaribaleName = h->GetVarParameter( "SetNumberOfSegments" ); + h_data.myNbSegVarName = aVaribaleName.in(); int distr = (int) h->GetDistrType(); h_data.myDistrType = distr; h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0; - if(distr==1){ - h_data.myScaleVarName = (aParameters->length() > 1) ? QString(aParameters[1].in()) : QString(""); + if(distr==1) { + aVaribaleName = h->GetVarParameter( "SetScaleFactor" ); + h_data.myScaleVarName = aVaribaleName.in(); } else h_data.myScaleVarName = QString(""); @@ -334,20 +364,23 @@ bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothe if( isCreation() ) SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().data() ); - QStringList aVariablesList; - aVariablesList.append(h_data.myNbSegVarName); - + h->SetVarParameter( h_data.myNbSegVarName.toLatin1().constData(), "SetNumberOfSegments" ); h->SetNumberOfSegments( h_data.myNbSeg ); int distr = h_data.myDistrType; h->SetDistrType( distr ); if( distr==1 ) { + h->SetVarParameter( h_data.myScaleVarName.toLatin1().constData(), "SetScaleFactor" ); h->SetScaleFactor( h_data.myScale ); - aVariablesList.append(h_data.myScaleVarName); } if( distr==2 || distr==3 ) h->SetConversionMode( h_data.myConv ); + if( distr==1 || distr==2 || distr==3 ) { + h->SetReversedEdges( myDirectionWidget->GetListOfIDs() ); + h->SetObjectEntry( myDirectionWidget->GetMainShapeEntry() ); + } + if( distr==2 ) h->SetTableFunction( h_data.myTable ); @@ -356,8 +389,6 @@ bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothe //setting of function must follow after setConversionMode, because otherwise //the function will be checked with old conversion mode, so that it may occurs //unexpected errors for user - - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); } catch(const SALOME::SALOME_Exception& ex) { @@ -400,23 +431,17 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged() myScale->setShown( distr==1 ); myLScale->setShown( distr==1 ); + myReversedEdgesBox->setShown( !distr==0 ); + myDirectionWidget->showPreview( !distr==0 ); bool isFunc = distr==2 || distr==3; myPreview->setShown( isFunc ); - myGroupLayout->setRowStretch( myPreviewRow, isFunc ? 1 : 0 ); - myConvBox->setShown( isFunc ); - - if( distr==2 ) - myTable->show(); - else - myTable->hide(); - myLTable->setShown( distr==2 ); - myGroupLayout->setRowStretch( myTableRow, distr==2 ? 1 : 0 ); - + + myTable->setShown( distr==2 ); myExpr->setShown( distr==3 ); myLExpr->setShown( distr==3 ); - myInfo->setShown( isFunc ); + myInfo->setShown( distr==3); //change of preview int nbSeg = myNbSeg->value(); @@ -434,8 +459,11 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged() if ( (QtxComboBox*)sender() == myDistr && dlg() ) { QApplication::instance()->processEvents(); + myGroupLayout->invalidate(); + dlg()->layout()->invalidate(); dlg()->updateGeometry(); - dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() ); + dlg()->setMinimumSize( dlg()->minimumSizeHint() ); dlg()->resize( dlg()->minimumSize() ); + QApplication::instance()->processEvents(); } } diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h index ba7c7bff8..66456e0ca 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_NbSegmentsCreator.h // Author : Open CASCADE S.A.S. // @@ -44,6 +45,7 @@ class QButtonGroup; class QGroupBox; class QGridLayout; class QRadioButton; +class StdMeshersGUI_SubShapeSelectorWdg; typedef struct { @@ -90,7 +92,10 @@ private: QLabel *myLScale, *myLTable, *myLExpr, *myInfo; QGridLayout* myGroupLayout; int myTableRow, myPreviewRow; - QRadioButton* myCutNeg; + //QRadioButton* myCutNeg; + QGroupBox* myReversedEdgesBox; + + StdMeshersGUI_SubShapeSelectorWdg* myDirectionWidget; }; #endif // STDMESHERSGUI_NBSEGMENTSCREATOR_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx index 37a3ce7ee..1efeb0162 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_ObjectReferenceParamWdg.cxx // Author : Open CASCADE S.A.S. // SMESH includes @@ -34,9 +35,11 @@ #include #include #include +#include // SALOME KERNEL incldues #include +#include // Qt includes #include @@ -53,10 +56,11 @@ //================================================================================ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg -( SUIT_SelectionFilter* f, QWidget* parent) - : QWidget( parent ) +( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection, bool stretch ) + : QWidget( parent ), myMultiSelection( multiSelection ) { myFilter = f; + myStretchActivated = stretch; init(); } @@ -68,8 +72,8 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg //================================================================================ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg -( MeshObjectType objType, QWidget* parent ) - : QWidget( parent ) +( MeshObjectType objType, QWidget* parent, bool multiSelection ) + : QWidget( parent ), myMultiSelection( multiSelection ) { myFilter = new SMESH_TypeFilter( objType ); init(); @@ -83,7 +87,10 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg StdMeshersGUI_ObjectReferenceParamWdg::~StdMeshersGUI_ObjectReferenceParamWdg() { if ( myFilter ) + { + mySelectionMgr->removeFilter( myFilter ); delete myFilter; + } } @@ -104,6 +111,8 @@ void StdMeshersGUI_ObjectReferenceParamWdg::init() mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI ); mySelectionActivated = false; myParamValue = ""; + myEmptyText = ""; + myEmptyStyleSheet =""; SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI ); QPixmap iconSlct ( mgr->loadPixmap("SMESH", tr("ICON_SELECT"))); @@ -114,10 +123,13 @@ void StdMeshersGUI_ObjectReferenceParamWdg::init() myObjNameLineEdit = new QLineEdit(this); myObjNameLineEdit->setReadOnly(true); + myObjNameLineEdit->setStyleSheet(myEmptyStyleSheet); aHBox->addWidget( mySelButton ); aHBox->addWidget( myObjNameLineEdit ); - aHBox->addStretch(); + if (myStretchActivated){ + aHBox->addStretch(); + } connect( mySelButton, SIGNAL(clicked()), SLOT(activateSelection())); } @@ -141,6 +153,7 @@ void StdMeshersGUI_ObjectReferenceParamWdg::activateSelection() connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone())); } emit selectionActivated(); + onSelectionDone(); mySelButton->setChecked( mySelectionActivated ); } @@ -183,8 +196,9 @@ void StdMeshersGUI_ObjectReferenceParamWdg::AvoidSimultaneousSelection void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj) { - myObject = CORBA::Object::_nil(); - myObjNameLineEdit->setText( "" ); + myObjects.clear(); + myObjNameLineEdit->setText( myEmptyText ); + myObjNameLineEdit->setStyleSheet(myEmptyStyleSheet); myParamValue = ""; _PTR(SObject) sobj; @@ -192,10 +206,52 @@ void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj) sobj = SMESH::FindSObject (obj); if ( sobj ) { std::string name = sobj->GetName(); - myObjNameLineEdit->setText( name.c_str() ); - myObject = CORBA::Object::_duplicate( obj ); + myObjNameLineEdit->setText( QString( name.c_str() ).trimmed() ); + myObjNameLineEdit->setStyleSheet(""); + myObjects.push_back( CORBA::Object::_duplicate( obj )); myParamValue = sobj->GetID().c_str(); + emit contentModified(); + } +} + +//================================================================================ +/*! + * \brief Initialize selected objects + * \param objects - entries of objects + */ +//================================================================================ + +void StdMeshersGUI_ObjectReferenceParamWdg::SetObjects(SMESH::string_array_var& objects) +{ + myObjects.clear(); + myObjNameLineEdit->setText( myEmptyText ); + myObjNameLineEdit->setStyleSheet(myEmptyStyleSheet); + myParamValue = ""; + bool selChanged = false; + + for ( unsigned i = 0; i < objects->length(); ++i ) + { + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + _PTR(SObject) aSObj = aStudy->FindObjectID(objects[i].in()); + CORBA::Object_var anObj = SMESH::SObjectToObject(aSObj,aStudy); + if ( !CORBA::is_nil( anObj )) { + std::string name = aSObj->GetName(); + QString text = myObjNameLineEdit->text(); + if ( text != myEmptyText ) + text += " "; + else + text = ""; + text += QString( name.c_str() ).trimmed(); + myObjNameLineEdit->setText( text ); + myObjNameLineEdit->setStyleSheet(""); + myObjects.push_back( anObj ); + myParamValue += " "; + myParamValue += objects[i]; + selChanged = true; + } } + if (selChanged) + emit contentModified(); } //================================================================================ @@ -211,7 +267,34 @@ void StdMeshersGUI_ObjectReferenceParamWdg::onSelectionDone() SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList); if (aList.Extent() == 1) + { obj = SMESH::IObjectToObject( aList.First() ); - SetObject( obj.in() ); + SetObject( obj.in() ); + } + else if (myMultiSelection) + { + SMESH::string_array_var objIds = new SMESH::string_array; + objIds->length( aList.Extent()); + SALOME_ListIteratorOfListIO io( aList ); + int i = 0; + for ( ; io.More(); io.Next(), ++i ) + { + Handle(SALOME_InteractiveObject) anIO = io.Value(); + if ( anIO->hasEntry() ) + objIds[i] = anIO->getEntry(); + else + i--; + } + objIds->length(i); + SetObjects( objIds ); + } } } + +void StdMeshersGUI_ObjectReferenceParamWdg::SetDefaultText(QString defaultText, QString styleSheet) +{ + myEmptyText = defaultText; + myEmptyStyleSheet = styleSheet; + myObjNameLineEdit->setText( myEmptyText ); + myObjNameLineEdit->setStyleSheet( myEmptyStyleSheet); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h index 62e5096af..26448cf22 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_ObjectReferenceParamWdg.h // Author : Open CASCADE S.A.S. // @@ -36,6 +37,9 @@ // CORBA includes #include +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + class SUIT_SelectionFilter; class SMESHGUI; class LightApp_SelectionMgr; @@ -51,24 +55,34 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_ObjectReferenceParamWdg : public QWidge public: StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, - QWidget* parent); + QWidget* parent, + bool multiSelection=false, + bool stretch=true); StdMeshersGUI_ObjectReferenceParamWdg( MeshObjectType objType, - QWidget* parent); + QWidget* parent, + bool multiSelection=false); ~StdMeshersGUI_ObjectReferenceParamWdg(); void SetObject(CORBA::Object_ptr obj); + void SetObjects(SMESH::string_array_var& objEntries); + template - typename TInterface::_var_type GetObject() const { - if ( IsObjectSelected() ) return TInterface::_narrow(myObject); + typename TInterface::_var_type GetObject(unsigned i=0) const { + if ( IsObjectSelected(i) ) return TInterface::_narrow(myObjects[i]); return TInterface::_nil(); } + int NbObjects() const { return myObjects.size(); } + QString GetValue() const { return myParamValue; } - bool IsObjectSelected() const { return !CORBA::is_nil(myObject); } + bool IsObjectSelected(unsigned i=0) const + { return i < myObjects.size() && !CORBA::is_nil(myObjects[i]); } void AvoidSimultaneousSelection( StdMeshersGUI_ObjectReferenceParamWdg* other); + + void SetDefaultText(QString defaultText="", QString styleSheet=""); public slots: /*! @@ -88,6 +102,7 @@ signals: * one is activated */ void selectionActivated(); + void contentModified(); private slots: void onSelectionDone(); @@ -96,9 +111,13 @@ private: void init(); private: - CORBA::Object_var myObject; + + bool myMultiSelection; + std::vector myObjects; + SUIT_SelectionFilter* myFilter; bool mySelectionActivated; + bool myStretchActivated; SMESHGUI* mySMESHGUI; LightApp_SelectionMgr* mySelectionMgr; @@ -106,6 +125,8 @@ private: QLineEdit* myObjNameLineEdit; QPushButton* mySelButton; QString myParamValue; + QString myEmptyText; + QString myEmptyStyleSheet; }; #endif // STDMESHERSGUI_OBJECTREFERENCEPARAMWDG_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx new file mode 100644 index 000000000..cb951878a --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx @@ -0,0 +1,100 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshersGUI_QuadrangleParamWdg.cxx +// Author : Open CASCADE S.A.S. (jfa) +// SMESH includes + +#include "StdMeshersGUI_QuadrangleParamWdg.h" + +#include "SMESHGUI.h" + +#include "SUIT_ResourceMgr.h" + +// Qt includes +#include +#include +#include +#include + +// IDL includes +#include +#include CORBA_CLIENT_HEADER(SMESH_BasicHypothesis) + +#define SPACING 6 +#define MARGIN 0 + +//================================================================================ +// function : Constructor +// purpose : +//================================================================================ +StdMeshersGUI_QuadrangleParamWdg::StdMeshersGUI_QuadrangleParamWdg (QWidget * parent) + : QWidget(parent), + myType(0) +{ + myType = new QButtonGroup (this); + + QGridLayout* typeLay = new QGridLayout( this ); + + typeLay->setMargin(MARGIN); + typeLay->setSpacing(SPACING); + + QString aTypeKey ("SMESH_QUAD_TYPE_%1"); + QString aPictKey ("ICON_StdMeshers_Quadrangle_Params_%1"); + + int itype = 0; + for (; itype < int(StdMeshers::QUAD_NB_TYPES); itype++) { + QRadioButton* rbi = new QRadioButton (tr(aTypeKey.arg(itype).toLatin1()), this); + QPixmap pmi (SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr(aPictKey.arg(itype).toLatin1()))); + QLabel* pli = new QLabel (this); + pli->setPixmap(pmi); + typeLay->addWidget(rbi, itype, 0, 1, 1); + typeLay->addWidget(pli, itype, 1, 1, 1); + myType->addButton(rbi, itype); + } + myType->button(0)->setChecked(true); + + setLayout(typeLay); + setMinimumWidth(300); +} + +//================================================================================ +// function : Destructor +// purpose : +//================================================================================ +StdMeshersGUI_QuadrangleParamWdg::~StdMeshersGUI_QuadrangleParamWdg() +{ +} + +//================================================================================= +// function : SetType +// purpose : +//================================================================================= +void StdMeshersGUI_QuadrangleParamWdg::SetType (int theType) +{ + myType->button(theType)->setChecked(true); +} + +//================================================================================= +// function : GetType +// purpose : +//================================================================================= +int StdMeshersGUI_QuadrangleParamWdg::GetType() +{ + return myType->checkedId(); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h new file mode 100644 index 000000000..b58445b6d --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshersGUI_QuadrangleParamWdg.h +// Author : Open CASCADE S.A.S. (jfa) + +#ifndef STDMESHERSGUI_QUADRANGLEPARAMWDG_H +#define STDMESHERSGUI_QUADRANGLEPARAMWDG_H + +// SMESH includes +#include "SMESH_StdMeshersGUI.hxx" + +// Qt includes +#include + +class QButtonGroup; + +class STDMESHERSGUI_EXPORT StdMeshersGUI_QuadrangleParamWdg : public QWidget +{ + Q_OBJECT + +public: + StdMeshersGUI_QuadrangleParamWdg (QWidget* parent = 0); + ~StdMeshersGUI_QuadrangleParamWdg(); + + void SetType (int theType); + int GetType (); + +private: + // Quadranle preference, Triangle preference, Reduced + QButtonGroup* myType; +}; + +#endif // STDMESHERSGUI_QUADRANGLEPARAMWDG_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx index 56e31b5a6..6e902a7f1 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx @@ -1,38 +1,45 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : StdMeshersGUI_StdHypothesisCreator.cxx -// Author : Alexander SOLOVYOV, Open CASCADE S.A.S. -// SMESH includes +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : StdMeshersGUI_StdHypothesisCreator.cxx +// Author : Alexander SOLOVYOV, Open CASCADE S.A.S. +// SMESH includes + #include "StdMeshersGUI_StdHypothesisCreator.h" #include #include #include #include +#include + #include #include -#include -#include + +#include "StdMeshersGUI_FixedPointsParamWdg.h" +#include "StdMeshersGUI_LayerDistributionParamWdg.h" +#include "StdMeshersGUI_ObjectReferenceParamWdg.h" +#include "StdMeshersGUI_QuadrangleParamWdg.h" +#include "StdMeshersGUI_SubShapeSelectorWdg.h" + #include // SALOME GUI includes @@ -42,6 +49,7 @@ #include #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) // Qt includes #include @@ -184,10 +192,10 @@ namespace { */ //================================================================================ - class TDoubleSliderWith2Lables: public QWidget + class TDoubleSliderWith2Labels: public QWidget { public: - TDoubleSliderWith2Lables( const QString& leftLabel, const QString& rightLabel, + TDoubleSliderWith2Labels( const QString& leftLabel, const QString& rightLabel, const double initValue, const double bottom, const double top , const double precision, QWidget * parent=0 , const char * name=0 ) @@ -196,11 +204,11 @@ namespace { setObjectName(name); QHBoxLayout* aHBoxL = new QHBoxLayout(this); - + if ( !leftLabel.isEmpty() ) { - QLabel* aLeftLabel = new QLabel( this ); - aLeftLabel->setText( leftLabel ); - aHBoxL->addWidget( aLeftLabel ); + QLabel* aLeftLabel = new QLabel( this ); + aLeftLabel->setText( leftLabel ); + aHBoxL->addWidget( aLeftLabel ); } _slider = new QSlider( Qt::Horizontal, this ); @@ -209,9 +217,9 @@ namespace { aHBoxL->addWidget( _slider ); if ( !rightLabel.isEmpty() ) { - QLabel* aRightLabel = new QLabel( this ); - aRightLabel->setText( rightLabel ); - aHBoxL->addWidget( aRightLabel ); + QLabel* aRightLabel = new QLabel( this ); + aRightLabel->setText( rightLabel ); + aHBoxL->addWidget( aRightLabel ); } setLayout( aHBoxL ); @@ -255,11 +263,30 @@ namespace { return SMESH::SMESH_Mesh::_nil(); } //================================================================================ + /*! + * \brief Retrieve SMESH_Mesh held by widget + */ + //================================================================================ + + inline SMESH::ListOfGroups_var groupsFromWdg(const QWidget* wdg) + { + SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups; + const StdMeshersGUI_ObjectReferenceParamWdg * objRefWdg = + dynamic_cast( wdg ); + if ( objRefWdg ) + { + groups->length( objRefWdg->NbObjects() ); + for ( unsigned i = 0; i < groups->length(); ++i ) + groups[i] = objRefWdg->GetObject< SMESH::SMESH_GroupBase >(i); + } + return groups; + } + //================================================================================ /*! * \brief creates a filter for selection of shapes of given dimension * \param dim - dimension - * \param subShapeType - required type of subshapes, number of which must be \a nbSubShapes - * \param nbSubShapes - number of subshapes of given type + * \param subShapeType - required type of sub-shapes, number of which must be \a nbSubShapes + * \param nbSubShapes - number of sub-shapes of given type * \param closed - required closeness flag of a shape * \retval SUIT_SelectionFilter* - created filter */ @@ -311,6 +338,16 @@ namespace { w->SetObject( object.in() ); return w; } + QWidget* newObjRefParamWdg( SUIT_SelectionFilter* filter, + SMESH::string_array_var& objEntries) + { + StdMeshersGUI_ObjectReferenceParamWdg* w = + new StdMeshersGUI_ObjectReferenceParamWdg( filter, 0, /*multiSel=*/true); + //RNV: Firstly, activate selection, then set objects + w->activateSelection(); + w->SetObjects( objEntries ); + return w; + } //================================================================================ /*! @@ -355,7 +392,8 @@ bool StdMeshersGUI_StdHypothesisCreator::checkParams( QString& msg ) const ok = ( w->IsObjectSelected() ); if ( !ok ) w->SetObject( CORBA::Object::_nil() ); int nbAssocVert = ( hypType() == "ProjectionSource1D" ? 1 : 2 ); - for ( int i = 0; ok && i < nbAssocVert; i += 2) + int nbNonEmptyAssoc = 0; + for ( int i = 0; ok && i < nbAssocVert*2; i += 2) { QString srcV, tgtV; StdMeshersGUI_ObjectReferenceParamWdg* w1 = @@ -370,18 +408,43 @@ bool StdMeshersGUI_StdHypothesisCreator::checkParams( QString& msg ) const w1->SetObject( CORBA::Object::_nil() ); w2->SetObject( CORBA::Object::_nil() ); } + nbNonEmptyAssoc += !srcV.isEmpty(); + } + if ( ok && nbNonEmptyAssoc == 1 && nbAssocVert == 2 ) + { + // only one pair of VERTEXes is given for a FACE, + // then the FACE must have only one VERTEX + GEOM::GEOM_Object_var face = w->GetObject< GEOM::GEOM_Object >(); + + GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen(); + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + GEOM::GEOM_IShapesOperations_var shapeOp; + if ( !geomGen->_is_nil() && aStudy ) + shapeOp = geomGen->GetIShapesOperations( aStudy->StudyId() ); + if ( !shapeOp->_is_nil() ) + { + GEOM::ListOfLong_var vertices = + shapeOp->GetAllSubShapesIDs (face, GEOM::VERTEX, /*isSorted=*/false); + ok = ( vertices->length() == 1 ); + } } - // Uninstall filters of StdMeshersGUI_ObjectReferenceParamWdg if ( ok ) deactivateObjRefParamWdg( customWidgets() ); } - else if ( hypType() == "LayerDistribution" ) + else if ( hypType().startsWith("ImportSource" )) + { + StdMeshersGUI_ObjectReferenceParamWdg* w = + widget< StdMeshersGUI_ObjectReferenceParamWdg >( 0 ); + ok = ( w->IsObjectSelected() ); + } + else if ( hypType() == "LayerDistribution" || hypType() == "LayerDistribution2D" ) { StdMeshersGUI_LayerDistributionParamWdg* w = widget< StdMeshersGUI_LayerDistributionParamWdg >( 0 ); ok = ( w && w->IsOk() ); } + return ok; } @@ -403,25 +466,26 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const } QString valueStr = stdParamValues( params ); - QStringList aVariablesList = getVariablesFromDlg(); + //QStringList aVariablesList = getVariablesFromDlg(); if( res && !params.isEmpty() ) { if( hypType()=="LocalLength" ) { StdMeshers::StdMeshers_LocalLength_var h = - StdMeshers::StdMeshers_LocalLength::_narrow( hypothesis() ); + StdMeshers::StdMeshers_LocalLength::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetLength" ); h->SetLength( params[0].myValue.toDouble() ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); + h->SetVarParameter( params[1].text(), "SetPrecision" ); h->SetPrecision( params[1].myValue.toDouble() ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); } else if( hypType()=="MaxLength" ) { StdMeshers::StdMeshers_MaxLength_var h = - StdMeshers::StdMeshers_MaxLength::_narrow( hypothesis() ); + StdMeshers::StdMeshers_MaxLength::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetLength" ); h->SetLength( params[0].myValue.toDouble() ); h->SetUsePreestimatedLength( widget< QCheckBox >( 1 )->isChecked() ); if ( !h->HavePreestimatedLength() && !h->_is_equivalent( initParamsHypothesis() )) { @@ -433,83 +497,133 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const else if( hypType()=="SegmentLengthAroundVertex" ) { StdMeshers::StdMeshers_SegmentLengthAroundVertex_var h = - StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hypothesis() ); + StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetLength" ); h->SetLength( params[0].myValue.toDouble() ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); } else if( hypType()=="Arithmetic1D" ) { StdMeshers::StdMeshers_Arithmetic1D_var h = - StdMeshers::StdMeshers_Arithmetic1D::_narrow( hypothesis() ); + StdMeshers::StdMeshers_Arithmetic1D::_narrow( hypothesis() ); + + StdMeshersGUI_SubShapeSelectorWdg* w = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 2 ); + + h->SetVarParameter( params[0].text(), "SetStartLength" ); + h->SetStartLength( params[0].myValue.toDouble() ); + h->SetVarParameter( params[1].text(), "SetEndLength" ); + h->SetEndLength( params[1].myValue.toDouble() ); + if (w) { + h->SetReversedEdges( w->GetListOfIDs() ); + h->SetObjectEntry( w->GetMainShapeEntry() ); + } + } + else if( hypType()=="FixedPoints1D" ) + { + StdMeshers::StdMeshers_FixedPoints1D_var h = + StdMeshers::StdMeshers_FixedPoints1D::_narrow( hypothesis() ); + + StdMeshersGUI_FixedPointsParamWdg* w1 = + widget< StdMeshersGUI_FixedPointsParamWdg >( 0 ); - h->SetLength( params[0].myValue.toDouble(), true ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); - h->SetLength( params[1].myValue.toDouble(), false ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); + StdMeshersGUI_SubShapeSelectorWdg* w2 = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 1 ); + + if (w1) { + h->SetPoints( w1->GetListOfPoints() ); + h->SetNbSegments( w1->GetListOfSegments() ); + } + if (w2) { + h->SetReversedEdges( w2->GetListOfIDs() ); + h->SetObjectEntry( w2->GetMainShapeEntry() ); + } } else if( hypType()=="MaxElementArea" ) { StdMeshers::StdMeshers_MaxElementArea_var h = - StdMeshers::StdMeshers_MaxElementArea::_narrow( hypothesis() ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); + StdMeshers::StdMeshers_MaxElementArea::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetMaxElementArea" ); h->SetMaxElementArea( params[0].myValue.toDouble() ); } else if( hypType()=="MaxElementVolume" ) { StdMeshers::StdMeshers_MaxElementVolume_var h = - StdMeshers::StdMeshers_MaxElementVolume::_narrow( hypothesis() ); + StdMeshers::StdMeshers_MaxElementVolume::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetMaxElementVolume" ); h->SetMaxElementVolume( params[0].myValue.toDouble() ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); } else if( hypType()=="StartEndLength" ) { StdMeshers::StdMeshers_StartEndLength_var h = - StdMeshers::StdMeshers_StartEndLength::_narrow( hypothesis() ); - - h->SetLength( params[0].myValue.toDouble(), true ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); - h->SetLength( params[1].myValue.toDouble(), false ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); + StdMeshers::StdMeshers_StartEndLength::_narrow( hypothesis() ); + + StdMeshersGUI_SubShapeSelectorWdg* w = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 2 ); + + h->SetVarParameter( params[0].text(), "SetStartLength" ); + h->SetStartLength( params[0].myValue.toDouble() ); + h->SetVarParameter( params[1].text(), "SetEndLength" ); + h->SetEndLength( params[1].myValue.toDouble() ); + if (w) { + h->SetReversedEdges( w->GetListOfIDs() ); + h->SetObjectEntry( w->GetMainShapeEntry() ); + } } else if( hypType()=="Deflection1D" ) { StdMeshers::StdMeshers_Deflection1D_var h = - StdMeshers::StdMeshers_Deflection1D::_narrow( hypothesis() ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); + StdMeshers::StdMeshers_Deflection1D::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetDeflection" ); h->SetDeflection( params[0].myValue.toDouble() ); } else if( hypType()=="AutomaticLength" ) { StdMeshers::StdMeshers_AutomaticLength_var h = - StdMeshers::StdMeshers_AutomaticLength::_narrow( hypothesis() ); + StdMeshers::StdMeshers_AutomaticLength::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetFineness" ); h->SetFineness( params[0].myValue.toDouble() ); } else if( hypType()=="NumberOfLayers" ) { StdMeshers::StdMeshers_NumberOfLayers_var h = - StdMeshers::StdMeshers_NumberOfLayers::_narrow( hypothesis() ); + StdMeshers::StdMeshers_NumberOfLayers::_narrow( hypothesis() ); + h->SetVarParameter( params[0].text(), "SetNumberOfLayers" ); h->SetNumberOfLayers( params[0].myValue.toInt() ); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); } else if( hypType()=="LayerDistribution" ) { StdMeshers::StdMeshers_LayerDistribution_var h = - StdMeshers::StdMeshers_LayerDistribution::_narrow( hypothesis() ); + StdMeshers::StdMeshers_LayerDistribution::_narrow( hypothesis() ); + StdMeshersGUI_LayerDistributionParamWdg* w = + widget< StdMeshersGUI_LayerDistributionParamWdg >( 0 ); + + h->SetLayerDistribution( w->GetHypothesis() ); + } + else if( hypType()=="NumberOfLayers2D" ) + { + StdMeshers::StdMeshers_NumberOfLayers2D_var h = + StdMeshers::StdMeshers_NumberOfLayers2D::_narrow( hypothesis() ); + + h->SetVarParameter( params[0].text(), "SetNumberOfLayers" ); + h->SetNumberOfLayers( params[0].myValue.toInt() ); + } + else if( hypType()=="LayerDistribution2D" ) + { + StdMeshers::StdMeshers_LayerDistribution2D_var h = + StdMeshers::StdMeshers_LayerDistribution2D::_narrow( hypothesis() ); StdMeshersGUI_LayerDistributionParamWdg* w = widget< StdMeshersGUI_LayerDistributionParamWdg >( 0 ); h->SetLayerDistribution( w->GetHypothesis() ); - h->SetParameters(w->GetHypothesis()->GetParameters()); - w->GetHypothesis()->ClearParameters(); } else if( hypType()=="ProjectionSource1D" ) { StdMeshers::StdMeshers_ProjectionSource1D_var h = - StdMeshers::StdMeshers_ProjectionSource1D::_narrow( hypothesis() ); + StdMeshers::StdMeshers_ProjectionSource1D::_narrow( hypothesis() ); h->SetSourceEdge ( geomFromWdg ( getWidgetForParam( 0 ))); h->SetSourceMesh ( meshFromWdg ( getWidgetForParam( 1 ))); @@ -519,7 +633,7 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const else if( hypType()=="ProjectionSource2D" ) { StdMeshers::StdMeshers_ProjectionSource2D_var h = - StdMeshers::StdMeshers_ProjectionSource2D::_narrow( hypothesis() ); + StdMeshers::StdMeshers_ProjectionSource2D::_narrow( hypothesis() ); h->SetSourceFace ( geomFromWdg ( getWidgetForParam( 0 ))); h->SetSourceMesh ( meshFromWdg ( getWidgetForParam( 1 ))); @@ -531,7 +645,7 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const else if( hypType()=="ProjectionSource3D" ) { StdMeshers::StdMeshers_ProjectionSource3D_var h = - StdMeshers::StdMeshers_ProjectionSource3D::_narrow( hypothesis() ); + StdMeshers::StdMeshers_ProjectionSource3D::_narrow( hypothesis() ); h->SetSource3DShape ( geomFromWdg ( getWidgetForParam( 0 ))); h->SetSourceMesh ( meshFromWdg ( getWidgetForParam( 1 ))); @@ -540,6 +654,63 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const geomFromWdg ( getWidgetForParam( 3 )), // tgt1 geomFromWdg ( getWidgetForParam( 5 ))); // tgt2 } + else if( hypType()=="ImportSource1D" ) + { + StdMeshers::StdMeshers_ImportSource1D_var h = + StdMeshers::StdMeshers_ImportSource1D::_narrow( hypothesis() ); + + SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 )); + h->SetSourceEdges( groups.in() ); + QCheckBox* toCopyMesh = widget< QCheckBox >( 1 ); + QCheckBox* toCopyGroups = widget< QCheckBox >( 2 ); + h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked()); + } + else if( hypType()=="ImportSource2D" ) + { + StdMeshers::StdMeshers_ImportSource2D_var h = + StdMeshers::StdMeshers_ImportSource2D::_narrow( hypothesis() ); + + SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 )); + h->SetSourceFaces( groups.in() ); + QCheckBox* toCopyMesh = widget< QCheckBox >( 1 ); + QCheckBox* toCopyGroups = widget< QCheckBox >( 2 ); + h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked()); + } + else if( hypType()=="ViscousLayers" ) + { + StdMeshers::StdMeshers_ViscousLayers_var h = + StdMeshers::StdMeshers_ViscousLayers::_narrow( hypothesis() ); + + h->SetVarParameter( params[0].text(), "SetTotalThickness" ); + h->SetTotalThickness( params[0].myValue.toDouble() ); + h->SetVarParameter( params[1].text(), "SetNumberLayers" ); + h->SetNumberLayers ( params[1].myValue.toInt() ); + h->SetVarParameter( params[2].text(), "SetStretchFactor" ); + h->SetStretchFactor ( params[2].myValue.toDouble() ); + + if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 3 )) + { + h->SetIgnoreFaces( idsWg->GetListOfIDs() ); + } + } + else if( hypType()=="QuadrangleParams" ) + { + StdMeshers::StdMeshers_QuadrangleParams_var h = + StdMeshers::StdMeshers_QuadrangleParams::_narrow( hypothesis() ); + StdMeshersGUI_SubShapeSelectorWdg* w1 = + widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 ); + StdMeshersGUI_QuadrangleParamWdg* w2 = + widget< StdMeshersGUI_QuadrangleParamWdg >( 1 ); + if (w1 && w2) { + if (w1->GetListSize() > 0) { + h->SetTriaVertex(w1->GetListOfIDs()[0]); // getlist must be called once + const char * entry = w1->GetMainShapeEntry(); + h->SetObjectEntry(entry); + } + h->SetQuadType(StdMeshers::QuadType(w2->GetType())); + } + } } return valueStr; } @@ -547,15 +718,15 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const //================================================================================ /*! * \brief Return parameter values as SMESHGUI_GenericHypothesisCreator::StdParam - * \param p - list of parameters - * \retval bool - success flag - * - * Is called from SMESHGUI_GenericHypothesisCreator::buildStdFrame(). - * Parameters will be shown using "standard" controls: - * Int by QtxIntSpinBox - * Double by SMESHGUI_SpinBox - * String by QLineEdit - * getCustomWidget() allows to redefine control for a parameter + * \param p - list of parameters + * \retval bool - success flag + * + * Is called from SMESHGUI_GenericHypothesisCreator::buildStdFrame(). + * Parameters will be shown using "standard" controls: + * Int by QtxIntSpinBox + * Double by SMESHGUI_SpinBox + * String by QLineEdit + * getCustomWidget() allows to redefine control for a parameter */ //================================================================================ @@ -574,7 +745,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const p.append( item ); customWidgets()->append(0); } - + SMESH::SMESH_Hypothesis_var hyp = initParamsHypothesis(); SMESH::ListOfParameters_var aParameters = hyp->GetLastParameters(); @@ -582,17 +753,16 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const { StdMeshers::StdMeshers_LocalLength_var h = StdMeshers::StdMeshers_LocalLength::_narrow( hyp ); - + item.myName = tr("SMESH_LOCAL_LENGTH_PARAM"); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetLength")) item.myValue = h->GetLength(); p.append( item ); - + item.myName = tr("SMESH_LOCAL_LENGTH_PRECISION"); - if(!initVariableName(aParameters,item,1)) + if(!initVariableName( hyp, item, "SetPrecision")) item.myValue = h->GetPrecision(); p.append( item ); - } else if( hypType()=="MaxLength" ) { @@ -610,7 +780,8 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const } item.myName = tr("SMESH_LOCAL_LENGTH_PARAM"); - item.myValue = h->GetLength(); + if(!initVariableName( hyp, item, "SetLength")) + item.myValue = h->GetLength(); p.append( item ); customWidgets()->append(0); @@ -633,7 +804,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hyp ); item.myName = tr("SMESH_LOCAL_LENGTH_PARAM"); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetLength")) item.myValue = h->GetLength(); p.append( item ); @@ -644,22 +815,78 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const StdMeshers::StdMeshers_Arithmetic1D::_narrow( hyp ); item.myName = tr( "SMESH_START_LENGTH_PARAM" ); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetStartLength" )) item.myValue = h->GetLength( true ); p.append( item ); + customWidgets()->append (0); + item.myName = tr( "SMESH_END_LENGTH_PARAM" ); - if(!initVariableName(aParameters,item,1)) + if(!initVariableName( hyp, item, "SetEndLength" )) item.myValue = h->GetLength( false ); p.append( item ); + + customWidgets()->append (0); + + item.myName = tr( "SMESH_REVERSED_EDGES" ); + p.append( item ); + + StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = + new StdMeshersGUI_SubShapeSelectorWdg(); + QString aGeomEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); + QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry(); + if ( aGeomEntry == "" ) + aGeomEntry = h->GetObjectEntry(); + + aDirectionWidget->SetGeomShapeEntry( aGeomEntry ); + aDirectionWidget->SetMainShapeEntry( aMainEntry ); + aDirectionWidget->SetListOfIDs( h->GetReversedEdges() ); + aDirectionWidget->showPreview( true ); + customWidgets()->append ( aDirectionWidget ); } + + + else if( hypType()=="FixedPoints1D" ) + { + StdMeshers::StdMeshers_FixedPoints1D_var h = + StdMeshers::StdMeshers_FixedPoints1D::_narrow( hyp ); + + item.myName = tr( "SMESH_FIXED_POINTS" ); + p.append( item ); + + StdMeshersGUI_FixedPointsParamWdg* aFixedPointsWidget = + new StdMeshersGUI_FixedPointsParamWdg(); + + if ( !isCreation() ) { + aFixedPointsWidget->SetListOfPoints( h->GetPoints() ); + aFixedPointsWidget->SetListOfSegments( h->GetNbSegments() ); + } + customWidgets()->append( aFixedPointsWidget ); + + item.myName = tr( "SMESH_REVERSED_EDGES" ); + p.append( item ); + + StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = + new StdMeshersGUI_SubShapeSelectorWdg(); + QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); + QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry(); + if ( anEntry == "" ) + anEntry = h->GetObjectEntry(); + aDirectionWidget->SetGeomShapeEntry( anEntry ); + aDirectionWidget->SetMainShapeEntry( aMainEntry ); + aDirectionWidget->SetListOfIDs( h->GetReversedEdges() ); + aDirectionWidget->showPreview( true ); + customWidgets()->append ( aDirectionWidget ); + } + + else if( hypType()=="MaxElementArea" ) { StdMeshers::StdMeshers_MaxElementArea_var h = StdMeshers::StdMeshers_MaxElementArea::_narrow( hyp ); item.myName = tr( "SMESH_MAX_ELEMENT_AREA_PARAM" ); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetMaxElementArea" )) item.myValue = h->GetMaxElementArea(); p.append( item ); @@ -670,7 +897,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const StdMeshers::StdMeshers_MaxElementVolume::_narrow( hyp ); item.myName = tr( "SMESH_MAX_ELEMENT_VOLUME_PARAM" ); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetMaxElementVolume" )) item.myValue = h->GetMaxElementVolume(); p.append( item ); } @@ -681,15 +908,31 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const item.myName = tr( "SMESH_START_LENGTH_PARAM" ); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetStartLength" )) item.myValue = h->GetLength( true ); p.append( item ); + customWidgets()->append(0); item.myName = tr( "SMESH_END_LENGTH_PARAM" ); - if(!initVariableName(aParameters,item,1)) + if(!initVariableName( hyp, item, "SetEndLength" )) item.myValue = h->GetLength( false ); p.append( item ); - + customWidgets()->append(0); + + item.myName = tr( "SMESH_REVERSED_EDGES" ); + p.append( item ); + + StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = + new StdMeshersGUI_SubShapeSelectorWdg(); + QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); + QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry(); + if ( anEntry == "" ) + anEntry = h->GetObjectEntry(); + aDirectionWidget->SetGeomShapeEntry( anEntry ); + aDirectionWidget->SetMainShapeEntry( aMainEntry ); + aDirectionWidget->SetListOfIDs( h->GetReversedEdges() ); + aDirectionWidget->showPreview( true ); + customWidgets()->append ( aDirectionWidget ); } else if( hypType()=="Deflection1D" ) { @@ -697,7 +940,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const StdMeshers::StdMeshers_Deflection1D::_narrow( hyp ); item.myName = tr( "SMESH_DEFLECTION1D_PARAM" ); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetDeflection" )) item.myValue = h->GetDeflection(); p.append( item ); } @@ -709,8 +952,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const item.myName = tr( "SMESH_FINENESS_PARAM" ); //item.myValue = h->GetFineness(); p.append( item ); - customWidgets()->append - ( new TDoubleSliderWith2Lables( "0 ", " 1", h->GetFineness(), 0, 1, 0.01, 0 )); + SMESHGUI_SpinBox* _autoLengthSpinBox = new SMESHGUI_SpinBox(dlg()); + _autoLengthSpinBox->RangeStepAndValidator(0, 1, 0.01, "length_precision"); + _autoLengthSpinBox->SetValue(h->GetFineness()); + customWidgets()->append( _autoLengthSpinBox); } else if( hypType()=="NumberOfLayers" ) { @@ -718,25 +963,37 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const StdMeshers::StdMeshers_NumberOfLayers::_narrow( hyp ); item.myName = tr( "SMESH_NUMBER_OF_LAYERS" ); - if(!initVariableName(aParameters,item,0)) + if(!initVariableName( hyp, item, "SetNumberOfLayers" )) item.myValue = (int) h->GetNumberOfLayers(); p.append( item ); } else if( hypType()=="LayerDistribution" ) - { - StdMeshers::StdMeshers_LayerDistribution_var h = + { + StdMeshers::StdMeshers_LayerDistribution_var h = StdMeshers::StdMeshers_LayerDistribution::_narrow( hyp ); - + item.myName = tr( "SMESH_LAYERS_DISTRIBUTION" ); p.append( item ); + initVariableName( hyp, item, "SetLayerDistribution" ); + customWidgets()->append + ( new StdMeshersGUI_LayerDistributionParamWdg( h->GetLayerDistribution(), hypName(), dlg())); + } + else if( hypType()=="NumberOfLayers2D" ) + { + StdMeshers::StdMeshers_NumberOfLayers2D_var h = + StdMeshers::StdMeshers_NumberOfLayers2D::_narrow( hyp ); - //Set into not published hypo last variables - QStringList aLastVarsList; - for(int i = 0;ilength();i++) - aLastVarsList.append(QString(aParameters[i].in())); + item.myName = tr( "SMESH_NUMBER_OF_LAYERS" ); + if(!initVariableName( hyp, item, "SetNumberOfLayers" )) + item.myValue = (int) h->GetNumberOfLayers(); + p.append( item ); + } + else if( hypType()=="LayerDistribution2D" ) + { + StdMeshers::StdMeshers_LayerDistribution2D_var h = + StdMeshers::StdMeshers_LayerDistribution2D::_narrow( hyp ); - if(!aLastVarsList.isEmpty()) - h->GetLayerDistribution()->SetLastParameters(SMESHGUI::JoinObjectParameters(aLastVarsList)); - + item.myName = tr( "SMESH_LAYERS_DISTRIBUTION" ); p.append( item ); + initVariableName( hyp, item, "SetLayerDistribution" ); customWidgets()->append ( new StdMeshersGUI_LayerDistributionParamWdg( h->GetLayerDistribution(), hypName(), dlg())); } @@ -806,6 +1063,135 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const customWidgets()->append( newObjRefParamWdg( filterForShapeOfDim( 0 ), h->GetTargetVertex( 2 ))); } + else if( hypType()=="ImportSource1D" ) + { + StdMeshers::StdMeshers_ImportSource1D_var h = + StdMeshers::StdMeshers_ImportSource1D::_narrow( hyp ); + + SMESH::string_array_var groupEntries = h->GetSourceEdges(); + CORBA::Boolean toCopyMesh, toCopyGroups; + h->GetCopySourceMesh(toCopyMesh, toCopyGroups); + + item.myName = tr( "SMESH_SOURCE_EDGES" ); p.append( item ); + customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_EDGE ), + groupEntries)); + + item.myName = tr( "SMESH_COPY_MESH" ); p.append( item ); + QCheckBox* aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyMesh ); + connect( aQCheckBox, SIGNAL( stateChanged(int) ), this, SLOT( onValueChanged() )); + customWidgets()->append( aQCheckBox ); + + item.myName = tr( "SMESH_TO_COPY_GROUPS" ); p.append( item ); + aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyGroups ); + aQCheckBox->setEnabled( toCopyMesh ); + customWidgets()->append( aQCheckBox ); + } + else if( hypType()=="ImportSource2D" ) + { + StdMeshers::StdMeshers_ImportSource2D_var h = + StdMeshers::StdMeshers_ImportSource2D::_narrow( hyp ); + + SMESH::string_array_var groupEntries = h->GetSourceFaces(); + CORBA::Boolean toCopyMesh, toCopyGroups; + h->GetCopySourceMesh(toCopyMesh, toCopyGroups); + + item.myName = tr( "SMESH_SOURCE_FACES" ); p.append( item ); + customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_FACE ), + groupEntries)); + + item.myName = tr( "SMESH_COPY_MESH" ); p.append( item ); + QCheckBox* aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyMesh ); + connect( aQCheckBox, SIGNAL( stateChanged(int) ), this, SLOT( onValueChanged() )); + customWidgets()->append( aQCheckBox ); + + item.myName = tr( "SMESH_COPY_GROUPS" ); p.append( item ); + aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyGroups ); + aQCheckBox->setEnabled( toCopyMesh ); + customWidgets()->append( aQCheckBox ); + } + else if( hypType()=="ViscousLayers" ) + { + StdMeshers::StdMeshers_ViscousLayers_var h = + StdMeshers::StdMeshers_ViscousLayers::_narrow( hyp ); + + item.myName = tr( "SMESH_TOTAL_THICKNESS" ); + if(!initVariableName( hyp, item, "SetTotalThickness" )) + item.myValue = h->GetTotalThickness(); + p.append( item ); + customWidgets()->append (0); + + item.myName = tr( "SMESH_NUMBER_OF_LAYERS" ); + if(!initVariableName( hyp, item, "SetNumberLayers" )) + item.myValue = h->GetNumberLayers(); + p.append( item ); + customWidgets()->append (0); + + item.myName = tr( "SMESH_STRETCH_FACTOR" ); + if(!initVariableName( hyp, item, "SetStretchFactor" )) + item.myValue = h->GetStretchFactor(); + p.append( item ); + customWidgets()->append (0); + + QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry(); + if ( !aMainEntry.isEmpty() ) + { + item.myName = tr( "SMESH_FACES_WO_LAYERS" ); + p.append( item ); + + StdMeshersGUI_SubShapeSelectorWdg* idsWg = + new StdMeshersGUI_SubShapeSelectorWdg(0,TopAbs_FACE); + + idsWg->SetGeomShapeEntry( aMainEntry ); + idsWg->SetMainShapeEntry( aMainEntry ); + idsWg->SetListOfIDs( h->GetIgnoreFaces() ); + idsWg->showPreview( true ); + customWidgets()->append ( idsWg ); + } + } + else if (hypType() == "QuadrangleParams") + { + StdMeshers::StdMeshers_QuadrangleParams_var h = + StdMeshers::StdMeshers_QuadrangleParams::_narrow(hyp); + + item.myName = tr("SMESH_BASE_VERTEX"); + p.append(item); + + StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = + new StdMeshersGUI_SubShapeSelectorWdg(0, TopAbs_VERTEX); + aDirectionWidget->SetMaxSize(1); + QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); + QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry(); + if (anEntry == "") + anEntry = h->GetObjectEntry(); + aDirectionWidget->SetGeomShapeEntry(anEntry); + aDirectionWidget->SetMainShapeEntry(aMainEntry); + if (!isCreation()) { + SMESH::long_array_var aVec = new SMESH::long_array; + int vertID = h->GetTriaVertex(); + if (vertID > 0) { + aVec->length(1); + aVec[0] = vertID; + aDirectionWidget->SetListOfIDs(aVec); + } + } + aDirectionWidget->showPreview(true); + + item.myName = tr("SMESH_QUAD_TYPE"); + p.append(item); + + StdMeshersGUI_QuadrangleParamWdg* aTypeWidget = + new StdMeshersGUI_QuadrangleParamWdg(); + if (!isCreation()) { + aTypeWidget->SetType(int(h->GetQuadType())); + } + + customWidgets()->append(aDirectionWidget); + customWidgets()->append(aTypeWidget); + } else res = false; return res; @@ -814,50 +1200,66 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const //================================================================================ /*! * \brief tune "standard" control - * \param w - control widget - * \param int - parameter index + * \param w - control widget + * \param int - parameter index */ //================================================================================ void StdMeshersGUI_StdHypothesisCreator::attuneStdWidget (QWidget* w, const int) const { SMESHGUI_SpinBox* sb = w->inherits( "SMESHGUI_SpinBox" ) ? ( SMESHGUI_SpinBox* )w : 0; - if( hypType()=="LocalLength" && sb ) - { - if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PARAM")) - sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 ); - else if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PRECISION")) - sb->RangeStepAndValidator( 0.0, 1.0, 0.05, 7 ); - } - else if( hypType()=="Arithmetic1D" && sb ) - { - sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 ); - } - else if( hypType()=="MaxLength" && sb ) - { - sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 ); - sb->setEnabled( !widget< QCheckBox >( 1 )->isChecked() ); - } - else if( hypType()=="MaxElementArea" && sb ) - { - sb->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 1.0, 6 ); - } - else if( hypType()=="MaxElementVolume" && sb ) + if ( sb ) { - sb->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 1.0, 6 ); - } - else if( hypType()=="StartEndLength" && sb ) - { - sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 ); - } - else if( hypType()=="Deflection1D" && sb ) - { - sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 ); - } - else if ( sb ) // default validator for possible ancestors - { - sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 ); + if( hypType()=="LocalLength" ) + { + if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PARAM")) + sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" ); + else if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PRECISION")) + sb->RangeStepAndValidator( 0.0, 1.0, 0.05, "len_tol_precision" ); + } + else if( hypType()=="Arithmetic1D" ) + { + sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "parametric_precision" ); + } + else if( hypType()=="MaxLength" ) + { + sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" ); + sb->setEnabled( !widget< QCheckBox >( 1 )->isChecked() ); + } + else if( hypType()=="MaxElementArea" ) + { + sb->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 1.0, "area_precision" ); + } + else if( hypType()=="MaxElementVolume" ) + { + sb->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 1.0, "vol_precision" ); + } + else if( hypType()=="StartEndLength" ) + { + sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" ); + } + else if( hypType()=="Deflection1D" ) + { + sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "parametric_precision" ); + } + else if( hypType()=="ViscousLayers" ) + { + if (sb->objectName() == tr("SMESH_STRETCH_FACTOR")) + sb->RangeStepAndValidator( 1.0, VALUE_MAX, 0.1, "parametric_precision" ); + else + sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" ); + } + else // default validator for possible ancestors + { + sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" ); + } } +// else if ( QtxIntSpinBox* ib = w->inherits( "QtxIntSpinBox" ) ? ( QtxIntSpinBox* )w : 0) +// { +// if( hypType()=="ViscousLayers" ) +// { +// } +// } } //================================================================================ @@ -918,14 +1320,22 @@ QString StdMeshersGUI_StdHypothesisCreator::hypTypeName( const QString& t ) cons types.insert( "StartEndLength", "START_END_LENGTH" ); types.insert( "Deflection1D", "DEFLECTION1D" ); types.insert( "Arithmetic1D", "ARITHMETIC_1D" ); + types.insert( "FixedPoints1D", "FIXED_POINTS_1D" ); types.insert( "AutomaticLength", "AUTOMATIC_LENGTH" ); types.insert( "ProjectionSource1D", "PROJECTION_SOURCE_1D" ); types.insert( "ProjectionSource2D", "PROJECTION_SOURCE_2D" ); types.insert( "ProjectionSource3D", "PROJECTION_SOURCE_3D" ); + types.insert( "ImportSource1D", "IMPORT_SOURCE_1D" ); + types.insert( "ImportSource2D", "IMPORT_SOURCE_2D" ); types.insert( "NumberOfLayers", "NUMBER_OF_LAYERS" ); types.insert( "LayerDistribution", "LAYER_DISTRIBUTION" ); + types.insert( "NumberOfLayers2D", "NUMBER_OF_LAYERS_2D" ); + types.insert( "LayerDistribution2D", "LAYER_DISTRIBUTION" ); types.insert( "SegmentLengthAroundVertex", "SEGMENT_LENGTH_AROUND_VERTEX" ); types.insert( "MaxLength", "MAX_LENGTH" ); + types.insert( "ViscousLayers", "VISCOUS_LAYERS" ); + types.insert( "QuadrangleParams", "QUADRANGLE_PARAMS" ); + types.insert( "CartesianParameters3D", "CARTESIAN_PARAMS" ); } QString res; @@ -971,9 +1381,9 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa QWidget* widget) const { if ( hypType()=="AutomaticLength" ) { - TDoubleSliderWith2Lables* w = dynamic_cast( widget ); + SMESHGUI_SpinBox* w = dynamic_cast( widget ); if ( w ) { - param.myValue = w->value(); + param.myValue = w->GetValue(); return true; } } @@ -998,6 +1408,33 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa param.myValue = w->GetValue(); return true; } + if ( widget->inherits( "StdMeshersGUI_SubShapeSelectorWdg" )) + { + const StdMeshersGUI_SubShapeSelectorWdg * w = + static_cast( widget ); + param.myValue = w->GetValue(); + return true; + } + if ( widget->inherits( "StdMeshersGUI_QuadrangleParamWdg" )) + { + //const StdMeshersGUI_QuadrangleParamWdg * w = + // static_cast( widget ); + param.myValue = "QuadType"; + return true; + } + if ( widget->inherits( "StdMeshersGUI_FixedPointsParamWdg" )) + { + const StdMeshersGUI_FixedPointsParamWdg * w = + static_cast( widget ); + param.myValue = w->GetValue(); + return true; + } + if ( widget->inherits( "QCheckBox" )) + { + //const QCheckBox * w = static_cast( widget ); + //param.myValue = w->isChecked(); + return true; + } return false; } @@ -1009,7 +1446,8 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa void StdMeshersGUI_StdHypothesisCreator::onReject() { - if ( hypType().startsWith("ProjectionSource" )) + if ( hypType().startsWith("ProjectionSource" ) || + hypType().startsWith("ImportSource" )) { // Uninstall filters of StdMeshersGUI_ObjectReferenceParamWdg deactivateObjRefParamWdg( customWidgets() ); @@ -1018,13 +1456,14 @@ void StdMeshersGUI_StdHypothesisCreator::onReject() //================================================================================ /*! - * \brief + * \brief Update widgets dependent on paramWidget */ //================================================================================ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget) { - if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) ) { + if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) ) + { getWidgetForParam(0)->setEnabled( !widget< QCheckBox >( 1 )->isChecked() ); if ( !getWidgetForParam(0)->isEnabled() ) { StdMeshers::StdMeshers_MaxLength_var h = @@ -1032,6 +1471,20 @@ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget) widget< QtxDoubleSpinBox >( 0 )->setValue( h->GetPreestimatedLength() ); } } + else if ( hypType().startsWith("ImportSource") && paramWidget == getWidgetForParam(1) ) + { + QCheckBox* toCopyMesh = (QCheckBox*) paramWidget; + QCheckBox* toCopyGroups = widget< QCheckBox >( 2 ); + if ( !toCopyMesh->isChecked() ) + { + toCopyGroups->setChecked( false ); + toCopyGroups->setEnabled( false ); + } + else + { + toCopyGroups->setEnabled( true ); + } + } } //================================================================================ @@ -1040,13 +1493,13 @@ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget) */ //================================================================================ -bool StdMeshersGUI_StdHypothesisCreator::initVariableName(SMESH::ListOfParameters_var theParameters, - StdParam &theParams, - int order) const +bool StdMeshersGUI_StdHypothesisCreator::initVariableName(SMESH::SMESH_Hypothesis_var theHyp, + StdParam & theParams, + const char* theMethod) const { - QString aVaribaleName = (theParameters->length() > order) ? QString(theParameters[order].in()) : QString(""); + QString aVaribaleName = getVariableName( theMethod ); theParams.isVariable = !aVaribaleName.isEmpty(); - if(theParams.isVariable) + if (theParams.isVariable) theParams.myValue = aVaribaleName; return theParams.isVariable; diff --git a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.h b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.h index 0973c5c03..c08e255e7 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.h +++ b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : StdMeshersGUI_StdHypothesisCreator.h // Author : Alexander SOLOVYOV, Open CASCADE S.A.S. // @@ -59,7 +60,7 @@ protected: virtual QWidget* getWidgetForParam( int paramIndex ) const; virtual ListOfWidgets* customWidgets() const; virtual void onReject(); - virtual bool initVariableName(SMESH::ListOfParameters_var theParameters, StdParam& theParams, int order) const; + bool initVariableName(SMESH::SMESH_Hypothesis_var theHyp, StdParam& theParams, const char* theMethod) const; virtual void valueChanged( QWidget* ); diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx new file mode 100644 index 000000000..8c2240803 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx @@ -0,0 +1,610 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshersGUI_SubShapeSelectorWdg.cxx +// Author : Open CASCADE S.A.S. (dmv) +// SMESH includes +// +#include "StdMeshersGUI_SubShapeSelectorWdg.h" + +// SMESH Includes +#include "SMESH_Type.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESH_Actor.h" +#include "SMESH_PreviewActorsCollection.h" +#include "SMESH_ActorUtils.h" +#include "SMESHGUI_GroupUtils.h" +#include "SMESH_Gen_i.hxx" +#include "SMESHGUI_GEOMGenUtils.h" +#include "SMESH_LogicalFilter.hxx" + +// SVTK Includes +#include +#include +#include +#include + +// SALOME GUI includes +#include +#include +#include + +// SUIT Includes +#include + +// GEOM Includes +#include +#include +#include + +// Qt includes +#include +#include +#include +#include +#include + +// OCCT includes +#include +#include +#include +#include +#include +#include + +// SALOME KERNEL includes +#include + + +#define SPACING 6 +#define MARGIN 0 + +//================================================================================ +/*! + * Constructor + */ +//================================================================================ + +StdMeshersGUI_SubShapeSelectorWdg +::StdMeshersGUI_SubShapeSelectorWdg( QWidget * parent, TopAbs_ShapeEnum aSubShType ): + QWidget( parent ), + myPreviewActor( 0 ), + myMaxSize( -1 ) +{ + QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) ); + + QGridLayout* edgesLayout = new QGridLayout( this ); + edgesLayout->setMargin( MARGIN ); + edgesLayout->setSpacing( SPACING ); + + myListWidget = new QListWidget( this ); + myAddButton = new QPushButton( tr( "SMESH_BUT_ADD" ), this ); + myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this ); + myInfoLabel = new QLabel( this ); + myPrevButton = new QPushButton( "<<", this ); + myNextButton = new QPushButton( ">>", this ); + myListWidget->setSelectionMode( QListWidget::ExtendedSelection ); + + edgesLayout->addWidget(myListWidget, 0, 0, 3, 3); + edgesLayout->addWidget(myAddButton, 0, 3); + edgesLayout->addWidget(myRemoveButton, 1, 3); + edgesLayout->addWidget(myInfoLabel, 3, 0, 1, 3); + edgesLayout->addWidget(myPrevButton, 4, 0); + edgesLayout->addWidget(myNextButton, 4, 2); + + edgesLayout->setRowStretch(2, 5); + edgesLayout->setColumnStretch(1, 5); + + myListWidget->setMinimumWidth(300); + myInfoLabel->setMinimumWidth(300); + myInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + myInfoLabel->setAlignment(Qt::AlignCenter); + + mySubShType = aSubShType; + + init(); +} + +//================================================================================ +/*! + * Destructor + */ +//================================================================================ + +StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg() +{ + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) { + if ( myPreviewActor ) { + myPreviewActor->RemoveFromRender( myRenderer ); + aViewWindow->Repaint(); + + delete myPreviewActor; + myPreviewActor = 0; + } + } + myEntry = ""; + myParamValue = ""; + myMainShape.Nullify(); + + if ( mySelectionMgr && myFilter ) + mySelectionMgr->removeFilter( myFilter ); + delete myFilter; myFilter=0; + + SUIT_SelectionFilter* filter; + foreach( filter, myGeomFilters ) + delete filter; +} + +//================================================================================ +/*! + * Create a layout, initialize fields + */ +//================================================================================ + +void StdMeshersGUI_SubShapeSelectorWdg::init() +{ + myParamValue = ""; + myIsNotCorrected = true; // to dont call the GetCorrectedValue method twice + myListOfIDs.clear(); + mySelectedIDs.clear(); + + myAddButton->setEnabled( false ); + myRemoveButton->setEnabled( false ); + + mySMESHGUI = SMESHGUI::GetSMESHGUI(); + mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI ); + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode( ActorSelection ); + + myFilter=0; + //setFilter(); + + connect( myAddButton, SIGNAL(clicked()), SLOT(onAdd())); + connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove())); + connect( myPrevButton, SIGNAL(clicked()), SLOT(onPrevious())); + connect( myNextButton, SIGNAL(clicked()), SLOT(onNext())); + + connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + connect( myListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); + + updateState(); +} + +//================================================================================ +/*! + * \brief Install filters to select sub-shapes of mySubShType or their groups + */ +//================================================================================ + +void StdMeshersGUI_SubShapeSelectorWdg::setFilter() +{ + SalomeApp_Study* study = mySMESHGUI->activeStudy(); + GEOM_TypeFilter* typeFilter = new GEOM_TypeFilter(study, mySubShType, /*isShapeType=*/true ); + GEOM_CompoundFilter* gpoupFilter = new GEOM_CompoundFilter(study); + gpoupFilter->addSubType( mySubShType ); + myGeomFilters.append( typeFilter ); + myGeomFilters.append( gpoupFilter ); + myFilter = new SMESH_LogicalFilter( myGeomFilters, SMESH_LogicalFilter::LO_OR ); + mySelectionMgr->installFilter( myFilter ); +} + +//================================================================================ +/*! + * Create a layout, initialize fields + */ +//================================================================================ + +void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible) +{ + if ( !myPreviewActor ) + return; + + if ( myIsShown != visible ) { + myPreviewActor->SetShown( visible ); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->Repaint(); + + myIsShown = visible; + } +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument() +{ + if ( !myPreviewActor ) + return; + + mySelectedIDs.clear(); + + // get selected mesh + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + int nbSel = aList.Extent(); + + if (nbSel > 0) { + SALOME_ListIteratorOfListIO anIt (aList); + + for ( ; anIt.More(); anIt.Next()) { // Loop on selected objects + Handle(SALOME_InteractiveObject) IO = anIt.Value(); + + GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( IO->getEntry() ); + if ( !CORBA::is_nil( aGeomObj ) ) { // Selected Object From Study + GEOM::GEOM_Object_ptr aGeomFatherObj = aGeomObj->GetMainShape(); + QString aFatherEntry = ""; + QString aMainFatherEntry = ""; + TopoDS_Shape shape; + if ( !CORBA::is_nil( aGeomFatherObj ) ) { + // Get Main Shape + GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry ); + if ( !CORBA::is_nil( aGeomMain ) && aGeomMain->GetType() == 37 ) { // Main Shape is a Group + GEOM::GEOM_Object_ptr aMainFatherObj = aGeomMain->GetMainShape(); + if ( !CORBA::is_nil( aMainFatherObj ) ) + aMainFatherEntry = aMainFatherObj->GetStudyEntry(); + } + aFatherEntry = aGeomFatherObj->GetStudyEntry(); + } + + if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) ) + { + if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object + GEOMBase::GetShape(aGeomObj, shape); + if ( !shape.IsNull() ) { + TopExp_Explorer exp( shape, mySubShType ); + for ( ; exp.More(); exp.Next() ) { + int index = myPreviewActor->GetIndexByShape( exp.Current() ); + if ( index ) { + mySelectedIDs.append( index ); + myPreviewActor->HighlightID( index ); + } + } + } + } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/ ) { + GEOMBase::GetShape(aGeomObj, shape); + if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) { + int index = myPreviewActor->GetIndexByShape( shape ); + if ( index ) { + mySelectedIDs.append( index ); + myPreviewActor->HighlightID( index ); + } + } + } + } + } else { // Selected Actor from Actor Collection + QString anEntry = IO->getEntry(); + QString str = "_"; + int index = anEntry.lastIndexOf( str ); + anEntry.remove(0, index+1); + int ind = anEntry.toInt(); + if ( ind ) + mySelectedIDs.append( ind ); + } + } + } + // update add button + myAddButton->setEnabled( ( myListWidget->count() < myMaxSize || myMaxSize == -1 ) && mySelectedIDs.size() > 0 && ( mySelectedIDs.size() <= myMaxSize || myMaxSize == -1 ) ); + + //Connect Selected Ids in viewer and dialog's Ids list + bool signalsBlocked = myListWidget->blockSignals( true ); + myListWidget->clearSelection(); + if ( mySelectedIDs.size() > 0 ) { + for (int i = 0; i < mySelectedIDs.size(); i++) { + QString anID = QString(" %1").arg( mySelectedIDs.at(i) ); + QList anItems = myListWidget->findItems ( anID, Qt::MatchExactly ); + QListWidgetItem* item; + foreach(item, anItems) + item->setSelected(true); + } + } + myListWidget->blockSignals( signalsBlocked ); +} + +//================================================================================= +// function : onAdd() +// purpose : Called when Add Button Clicked +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::onAdd() +{ + if ( mySelectedIDs.size() < 1 ) + return; + + myListWidget->blockSignals( true ); + for (int i = 0; i < mySelectedIDs.size() && (myMaxSize == -1 || myListOfIDs.size() < myMaxSize); i++) { + if ( myListOfIDs.indexOf( mySelectedIDs.at(i) ) == -1 ) { + QString anID = QString(" %1").arg( mySelectedIDs.at(i) ); + + QListWidgetItem* anItem = new QListWidgetItem( anID, myListWidget ); + anItem->setSelected(true); + + myListOfIDs.append( mySelectedIDs.at(i) ); + } + } + onListSelectionChanged(); + myListWidget->blockSignals( false ); + myAddButton->setEnabled( myMaxSize == -1 || myListOfIDs.size() < myMaxSize ); +} + +//================================================================================= +// function : onRemove() +// purpose : Called when Remove Button Clicked +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::onRemove() +{ + if ( myListWidget->count() < 1 ) + return; + + myListWidget->blockSignals( true ); + QList selItems = myListWidget->selectedItems(); + QListWidgetItem* item; + foreach(item, selItems) { + QString idStr = item->text(); + int id = idStr.toInt(); + + int index = myListOfIDs.indexOf( id ); + myListOfIDs.removeAt( index ); + delete item; + } + + onListSelectionChanged(); + myListWidget->blockSignals( false ); + + myAddButton->setEnabled( true ); +} + +void StdMeshersGUI_SubShapeSelectorWdg::onPrevious() +{ + if ( myPreviewActor ) { + myPreviewActor->previous(); + myListWidget->clearSelection(); + updateButtons(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->Repaint(); + } +} + +void StdMeshersGUI_SubShapeSelectorWdg::onNext() +{ + if ( myPreviewActor ) { + myPreviewActor->next(); + myListWidget->clearSelection(); + updateButtons(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->Repaint(); + } +} + +//================================================================================= +// function : onListSelectionChanged() +// purpose : Called when selection in element list is changed +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged() +{ + if ( !myPreviewActor ) + return; + + mySelectionMgr->clearSelected(); + TColStd_MapOfInteger aIndexes; + QList selItems = myListWidget->selectedItems(); + QListWidgetItem* anItem; + foreach(anItem, selItems) + myPreviewActor->HighlightID( anItem->text().toInt() ); + + // update remove button + myRemoveButton->setEnabled( selItems.size() > 0 ); +} + +//================================================================================= +// function : setGeomShape +// purpose : Called to set geometry whose sub-shapes are selected +//================================================================================ +void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEntry ) +{ + if ( theEntry != "") { + myParamValue = theEntry; + myEntry = theEntry; + myGeomShape = GetTopoDSByEntry( theEntry ); + updateState(); + myIsNotCorrected = true; + } +} + +//================================================================================= +// function : updateState +// purpose : update Widget state +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::updateState() +{ + bool state = false; + if ( !myGeomShape.IsNull() ) + state = true; + myInfoLabel->setVisible( false ); + myPrevButton->setVisible( false ); + myNextButton->setVisible( false ); + + myListWidget->setEnabled( state ); + myAddButton->setEnabled( mySelectedIDs.size() > 0 ); + + if (state) { + myPreviewActor = new SMESH_PreviewActorsCollection(); + myPreviewActor->SetSelector( mySelector ); + myPreviewActor->Init( myGeomShape, mySubShType, myEntry ); + myPreviewActor->SetShown( false ); + myIsShown = false; + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) { + myRenderer = aViewWindow->getRenderer(); + myPreviewActor->AddToRender( myRenderer ); + aViewWindow->Repaint(); + } + updateButtons(); + } +} + +//================================================================================= +// function : GetGeomObjectByEntry +// purpose : Called to get GeomObject +//================================================================================= +GEOM::GEOM_Object_var StdMeshersGUI_SubShapeSelectorWdg::GetGeomObjectByEntry( const QString& theEntry ) +{ + GEOM::GEOM_Object_var aGeomObj; + SALOMEDS::Study_var aStudy = SMESHGUI::GetSMESHGen()->GetCurrentStudy(); + if (aStudy != 0) { + SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( theEntry.toLatin1().data() ); + SALOMEDS::GenericAttribute_var anAttr; + + if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) { + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var aVal = anIOR->Value(); + CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal); + aGeomObj = GEOM::GEOM_Object::_narrow(obj); + } + } + return aGeomObj; +} + +//================================================================================= +// function : setObjectByEntry +// purpose : Called to get GeomObject +//================================================================================= +TopoDS_Shape StdMeshersGUI_SubShapeSelectorWdg::GetTopoDSByEntry( const QString& theEntry ) +{ + TopoDS_Shape shape; + GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( theEntry ); + GEOMBase::GetShape(aGeomObj, shape); + return shape; +} + +//================================================================================= +// function : GetListOfIds +// purpose : Called to get the list of SubShapes IDs +//================================================================================= +SMESH::long_array_var StdMeshersGUI_SubShapeSelectorWdg::GetListOfIDs() +{ + SMESH::long_array_var anArray = new SMESH::long_array; + + if ( myMainEntry != "" && myIsNotCorrected ) + myListOfIDs = GetCorrectedListOfIDs( true ); + + int size = myListOfIDs.size(); + anArray->length( size ); + if ( size ) { + for (int i = 0; i < size; i++) { + anArray[i] = myListOfIDs.at(i); + } + } + return anArray; +} + +//================================================================================= +// function : SetListOfIds +// purpose : Called to set the list of SubShapes IDs +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theIds) +{ + mySelectedIDs.clear(); + myListOfIDs.clear(); + int size = theIds->length(); + for ( int i = 0; i < size; i++ ) + mySelectedIDs.append( theIds[ i ] ); + + mySelectedIDs = GetCorrectedListOfIDs( false ); + onAdd(); +} + +//================================================================================= +// function : SetMainShapeEntry +// purpose : Called to set the Entry of main shape of the mesh +//================================================================================= +void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEntry ) +{ + myMainEntry = theEntry; + myMainShape = GetTopoDSByEntry( theEntry ); + myIsNotCorrected = true; +} + +//================================================================================= +// function : GetMainShapeEntry +// purpose : Called to get the Main Object Entry +//================================================================================= +const char* StdMeshersGUI_SubShapeSelectorWdg::GetMainShapeEntry() +{ + if ( myMainEntry == "") + return myEntry.toLatin1().data(); + + return myMainEntry.toLatin1().data(); +} + +//================================================================================= +// function : GetCorrectedListOfIds +// purpose : Called to convert the list of IDs from sub-shape IDs to main shape IDs +//================================================================================= +QList StdMeshersGUI_SubShapeSelectorWdg::GetCorrectedListOfIDs( bool fromSubshapeToMainshape ) +{ + if ( ( myMainShape.IsNull() || myGeomShape.IsNull() ) && fromSubshapeToMainshape ) + return myListOfIDs; + else if ( ( myMainShape.IsNull() || myGeomShape.IsNull() ) && !fromSubshapeToMainshape ) + return mySelectedIDs; + + QList aList; + TopTools_IndexedMapOfShape aGeomMap; + TopTools_IndexedMapOfShape aMainMap; + TopExp::MapShapes(myGeomShape, aGeomMap); + TopExp::MapShapes(myMainShape, aMainMap); + + if ( fromSubshapeToMainshape ) { // convert indexes from sub-shape to mainshape + int size = myListOfIDs.size(); + for (int i = 0; i < size; i++) { + TopoDS_Shape aSubShape = aGeomMap.FindKey( myListOfIDs.at(i) ); + int index = aMainMap.FindIndex( aSubShape ); + aList.append( index ); + } + myIsNotCorrected = false; + } else { // convert indexes from main shape to sub-shape + int size = mySelectedIDs.size(); + for (int i = 0; i < size; i++) { + TopoDS_Shape aSubShape = aMainMap.FindKey( mySelectedIDs.at(i) ); + int index = aGeomMap.FindIndex( aSubShape ); + aList.append( index ); + } + } + + return aList; +} + +void StdMeshersGUI_SubShapeSelectorWdg::updateButtons() +{ + if ( myPreviewActor ) { + int total = myPreviewActor->count(); + int chunk = myPreviewActor->currentChunk(); + int chunkSize = myPreviewActor->chunkSize(); + int imin = chunk*chunkSize+1; + int imax = std::min((chunk+1)*chunkSize, total); + bool vis = imax > 0 && total > chunkSize; + myInfoLabel->setVisible( vis ); + myPrevButton->setVisible( vis ); + myNextButton->setVisible( vis ); + myInfoLabel->setText( tr( "X_FROM_Y_ITEMS_SHOWN" ).arg(imin).arg(imax).arg(total) ); + myPrevButton->setEnabled( myPreviewActor->hasPrevious() ); + myNextButton->setEnabled( myPreviewActor->hasNext() ); + } +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h new file mode 100644 index 000000000..6d3cbbe7d --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h @@ -0,0 +1,136 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : StdMeshersGUI_SubShapeSelectorWdg.h +// Author : Open CASCADE S.A.S. (dmv) +// +#ifndef STDMESHERSGUI_SUBSHAPESELECTORWDG_H +#define STDMESHERSGUI_SUBSHAPESELECTORWDG_H + +// SMESH includes +#include +#include "SMESH_StdMeshersGUI.hxx" +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include +#include +#include + +#include + +class SMESHGUI; +class LightApp_SelectionMgr; +class SVTK_Selector; +class QPushButton; +class QLabel; +class QLineEdit; +class QCheckBox; +class QListWidget; +class SMESH_Actor; +class SMESH_PreviewActorsCollection; +class vtkRenderer; +class SUIT_SelectionFilter; + +class STDMESHERSGUI_EXPORT StdMeshersGUI_SubShapeSelectorWdg : public QWidget +{ + Q_OBJECT + +public: + StdMeshersGUI_SubShapeSelectorWdg( QWidget* parent = 0, + TopAbs_ShapeEnum aSubShType = TopAbs_EDGE ); + ~StdMeshersGUI_SubShapeSelectorWdg(); + + SMESH::long_array_var GetListOfIDs(); + void SetListOfIDs( SMESH::long_array_var ); + + void SetGeomShapeEntry( const QString& theEntry ); + const char* GetGeomShapeEntry() { return myEntry.toLatin1().data();} + + void SetMainShapeEntry( const QString& theEntry ); + const char* GetMainShapeEntry(); + + TopoDS_Shape GetGeomShape() { return myGeomShape; } + TopoDS_Shape GetMainShape() { return myMainShape; } + + QList GetCorrectedListOfIDs( bool fromSubshapeToMainshape = true ); + + static GEOM::GEOM_Object_var GetGeomObjectByEntry( const QString& ); + static TopoDS_Shape GetTopoDSByEntry( const QString& ); + + QString GetValue() const { return myParamValue; } + + void showPreview ( bool ); + + int GetListSize() { return myListOfIDs.size(); } + + void SetMaxSize(int aMaxSize) { myMaxSize = aMaxSize; } + //void SetSubShType(TopAbs_ShapeEnum aSubShType) { mySubShType = aSubShType; } + +private: + void updateState(); + void setFilter(); + void updateButtons(); + +private slots: + void onAdd(); + void onRemove(); + void onPrevious(); + void onNext(); + void SelectionIntoArgument(); + void onListSelectionChanged(); + +private: + void init(); + +private: + SMESHGUI* mySMESHGUI; + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + SVTK_Selector* mySelector; + SMESH::SMESH_Mesh_var myMesh; + TopoDS_Shape myGeomShape; // shape whose sub-shapes are selected + TopoDS_Shape myMainShape; // main shape of the mesh + QString myEntry; + QString myMainEntry; + vtkRenderer* myRenderer; + + QListWidget* myListWidget; + QPushButton* myAddButton; + QPushButton* myRemoveButton; + QLabel* myInfoLabel; + QPushButton* myPrevButton; + QPushButton* myNextButton; + QList mySelectedIDs; + QList myListOfIDs; + + QString myParamValue; + bool myIsShown; + bool myIsNotCorrected; + + // for manage possible size of myListOfIDs + int myMaxSize; + // for manage type of selected subshape + TopAbs_ShapeEnum mySubShType; + + SMESH_PreviewActorsCollection* myPreviewActor; + QList myGeomFilters; + SUIT_SelectionFilter* myFilter; +}; + +#endif // STDMESHERSGUI_SUBSHAPESELECTORWDG_H diff --git a/src/StdMeshersGUI/StdMeshers_images.ts b/src/StdMeshersGUI/StdMeshers_images.ts index 132661aa0..aaf16607c 100644 --- a/src/StdMeshersGUI/StdMeshers_images.ts +++ b/src/StdMeshersGUI/StdMeshers_images.ts @@ -1,34 +1,16 @@ + - - + @default ICON_DLG_ARITHMETIC_1D mesh_hypo_length.png + + ICON_DLG_FIXED_POINTS_1D + mesh_hypo_length.png + ICON_DLG_AUTOMATIC_LENGTH mesh_hypo_length.png @@ -53,6 +35,14 @@ ICON_DLG_MAX_LENGTH mesh_hypo_length.png + + ICON_DLG_CARTESIAN_PARAMS + mesh_hypo_length.png + + + ICON_DLG_VISCOUS_LAYERS + mesh_hypo_viscous_layers.png + ICON_DLG_MAX_ELEMENT_AREA mesh_hypo_area.png @@ -69,6 +59,10 @@ ICON_DLG_NUMBER_OF_LAYERS mesh_hypo_layer_distribution.png + + ICON_DLG_NUMBER_OF_LAYERS_2D + mesh_hypo_layer_distribution.png + ICON_DLG_PROJECTION_SOURCE_1D mesh_hypo_source_edge.png @@ -81,6 +75,18 @@ ICON_DLG_PROJECTION_SOURCE_3D mesh_hypo_source_3d.png + + ICON_DLG_QUADRANGLE_PARAMS + mesh_hypo_length.png + + + ICON_DLG_IMPORT_SOURCE_1D + mesh_hypo_source_edge.png + + + ICON_DLG_IMPORT_SOURCE_2D + mesh_hypo_source_face.png + ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX mesh_hypo_length.png @@ -97,6 +103,14 @@ ICON_SMESH_TREE_ALGO_CompositeSegment_1D mesh_tree_algo_regular.png + + ICON_SMESH_TREE_ALGO_UseExisting_2D + mesh_tree_algo_existing_2D.png + + + ICON_SMESH_TREE_ALGO_UseExisting_1D + mesh_tree_algo_regular.png + ICON_SMESH_TREE_ALGO_Hexa_3D mesh_tree_algo_hexa.png @@ -121,6 +135,14 @@ ICON_SMESH_TREE_ALGO_Quadrangle_2D mesh_tree_algo_quad.png + + ICON_SMESH_TREE_ALGO_RadialQuadrangle_1D2D + mesh_tree_algo_radial_quadrangle_1D2D.png + + + ICON_SMESH_TREE_ALGO_Prism_3D + mesh_tree_algo_prism.png + ICON_SMESH_TREE_ALGO_RadialPrism_3D mesh_tree_algo_radial_prism.png @@ -131,7 +153,7 @@ ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D - mesh_tree_algo_regular.png + mesh_tree_algo_0D.png ICON_SMESH_TREE_HYPO_Arithmetic1D @@ -181,6 +203,10 @@ ICON_SMESH_TREE_HYPO_NumberOfSegments mesh_tree_hypo_segment.png + + ICON_SMESH_TREE_HYPO_ViscousLayers + mesh_tree_hypo_viscous_layers.png + ICON_SMESH_TREE_HYPO_ProjectionSource1D mesh_tree_hypo_source_edge.png @@ -218,4 +244,27 @@ mesh_tree_hypo_length.png + + StdMeshersGUI_QuadrangleParamWdg + + ICON_StdMeshers_Quadrangle_Params_0 + mesh_quadrangle_standard.png + + + ICON_StdMeshers_Quadrangle_Params_1 + mesh_quadrangle_triapref.png + + + ICON_StdMeshers_Quadrangle_Params_2 + mesh_quadrangle_quadpref.png + + + ICON_StdMeshers_Quadrangle_Params_3 + mesh_quadrangle_quadpref_reversed.png + + + ICON_StdMeshers_Quadrangle_Params_4 + mesh_quadrangle_reduced.png + + diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.ts b/src/StdMeshersGUI/StdMeshers_msg_en.ts index f11a5d675..df97c12a1 100644 --- a/src/StdMeshersGUI/StdMeshers_msg_en.ts +++ b/src/StdMeshersGUI/StdMeshers_msg_en.ts @@ -1,332 +1,484 @@ + - - - - @default - - SMESH_ARITHMETIC_1D_HYPOTHESIS - Arithmetic 1D - - - SMESH_ARITHMETIC_1D_PARAM - Arithmetic Reason - - - SMESH_ARITHMETIC_1D_TITLE - Hypothesis Construction - - - SMESH_AUTOMATIC_LENGTH_HYPOTHESIS - Automatic Length - - - SMESH_AUTOMATIC_LENGTH_TITLE - Hypothesis Construction - - - SMESH_CONV_MODE - Conversion mode - - - SMESH_CUT_NEG_MODE - Cut negative - - - SMESH_DEFLECTION1D_HYPOTHESIS - Deflection 1D - - - SMESH_DEFLECTION1D_PARAM - Deflection - - - SMESH_DEFLECTION1D_TITLE - Hypothesis Construction - - - SMESH_DENSITY_FUNC - Density function - - - SMESH_DISTR - Distribution - - - SMESH_DISTR_EXPR - Distribution with analitic density - - - SMESH_DISTR_REGULAR - Equidistant distribution - - - SMESH_DISTR_SCALE - Scale distribution - - - SMESH_DISTR_TAB - Distribution with table density - - - SMESH_DISTR_TYPE - Type of distribution - - - SMESH_END_LENGTH_PARAM - End Length - - - SMESH_EXPR_FUNC - Density function f(t) = - - - SMESH_EXP_MODE - Exponent - - - SMESH_FINENESS_PARAM - Fineness - - - SMESH_FUNC_DOMAIN - Warning: function must be defined on segment [0..1] - - - SMESH_INSERT_ROW - Insert row - - - SMESH_INVALID_FUNCTION - Function is invalid - - - SMESH_LAYERS_DISTRIBUTION - 1D Hypothesis - - - SMESH_LAYER_DISTRIBUTION_HYPOTHESIS - Distribution of Layers - - - SMESH_LAYER_DISTRIBUTION_TITLE - Hypothesis Construction - - - SMESH_LOCAL_LENGTH_HYPOTHESIS - Average Length - - - SMESH_LOCAL_LENGTH_PARAM - Length - - - SMESH_LOCAL_LENGTH_PRECISION - Precision - - - SMESH_LOCAL_LENGTH_TITLE - Hypothesis Construction - - - SMESH_MAX_LENGTH_HYPOTHESIS - Max Length - - - SMESH_USE_PREESTIMATED_LENGTH - Use preestimated length - - - SMESH_MAX_LENGTH_TITLE - Hypothesis Construction - - - SMESH_MAX_ELEMENT_AREA_HYPOTHESIS - Max. Element Area - - - SMESH_MAX_ELEMENT_AREA_PARAM - Max. Area - - - SMESH_MAX_ELEMENT_AREA_TITLE - Hypothesis Construction - - - SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS - Max. Element Volume - - - SMESH_MAX_ELEMENT_VOLUME_PARAM - Max. Volume - - - SMESH_MAX_ELEMENT_VOLUME_TITLE - Hypothesis Construction - - - SMESH_NB_SEGMENTS_HYPOTHESIS - Number of Segments - - - SMESH_NB_SEGMENTS_PARAM - Number of Segments - - - SMESH_NB_SEGMENTS_SCALE_PARAM - Scale Factor - - - SMESH_NB_SEGMENTS_TITLE - Hypothesis Construction - - - SMESH_NO_CONV - No conversion - - - SMESH_NUMBER_OF_LAYERS - Number of Layers - - - SMESH_NUMBER_OF_LAYERS_HYPOTHESIS - Radial Prism Parameter - - - SMESH_NUMBER_OF_LAYERS_TITLE - Hypothesis Construction - - - SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS - Projection Source 1D - - - SMESH_PROJECTION_SOURCE_1D_TITLE - Hypothesis Construction - - - SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS - Projection Source 2D - - - SMESH_PROJECTION_SOURCE_2D_TITLE - Hypothesis Construction - - - SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS - Projection Source 3D - - - SMESH_PROJECTION_SOURCE_3D_TITLE - Hypothesis Construction - - - SMESH_REMOVE_ROW - Remove row - - - SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS - Segment Length Around Vertex - - - SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM - Length - - - SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE - Hypothesis Construction - - - SMESH_SOURCE_3DSHAPE - 3D shape - - - SMESH_SOURCE_EDGE - Edge - - - SMESH_SOURCE_FACE - Face - - - SMESH_SOURCE_MESH - Mesh - - - SMESH_SOURCE_VERTEX - Source Vertex - - - SMESH_SOURCE_VERTEX1 - Source Vertex 1 - - - SMESH_SOURCE_VERTEX2 - Source Vertex 2 - - - SMESH_START_END_LENGTH_HYPOTHESIS - Start and End local Length - - - SMESH_START_END_LENGTH_TITLE - Hypothesis Construction - - - SMESH_START_LENGTH_PARAM - Start Length - - - SMESH_TAB_FUNC - Table function - - - SMESH_TARGET_VERTEX - Target Vertex - - - SMESH_TARGET_VERTEX1 - Target Vertex 1 - - - SMESH_TARGET_VERTEX2 - Target Vertex 2 - - - - StdMeshersGUI_LayerDistributionParamWdg - - CHANGE_TYPE - Change Type - - - CREATE - Create - - - EDIT - Edit - - + + + @default + + SMESH_ARITHMETIC_1D_HYPOTHESIS + Arithmetic 1D + + + SMESH_ARITHMETIC_1D_PARAM + Arithmetic Reason + + + SMESH_ARITHMETIC_1D_TITLE + Hypothesis Construction + + + SMESH_AUTOMATIC_LENGTH_HYPOTHESIS + Automatic Length + + + SMESH_AUTOMATIC_LENGTH_TITLE + Hypothesis Construction + + + SMESH_CONV_MODE + Conversion mode + + + SMESH_CUT_NEG_MODE + Cut negative + + + SMESH_DEFLECTION1D_HYPOTHESIS + Deflection 1D + + + SMESH_DEFLECTION1D_PARAM + Deflection + + + SMESH_DEFLECTION1D_TITLE + Hypothesis Construction + + + SMESH_DENSITY_FUNC + Density function + + + SMESH_DISTR + Distribution + + + SMESH_DISTR_EXPR + Distribution with analitic density + + + SMESH_DISTR_REGULAR + Equidistant distribution + + + SMESH_DISTR_SCALE + Scale distribution + + + SMESH_DISTR_TAB + Distribution with table density + + + SMESH_DISTR_TYPE + Type of distribution + + + SMESH_END_LENGTH_PARAM + End Length + + + SMESH_EXPR_FUNC + Density function + + + SMESH_EXP_MODE + Exponent + + + SMESH_FINENESS_PARAM + Fineness + + + SMESH_FUNC_DOMAIN + Warning: function must be defined on segment [0..1] + + + SMESH_INSERT_ROW + Insert row + + + SMESH_INVALID_FUNCTION + Function is invalid + + + SMESH_LAYERS_DISTRIBUTION + 1D Hypothesis + + + SMESH_LAYER_DISTRIBUTION_HYPOTHESIS + Distribution of Layers + + + SMESH_LAYER_DISTRIBUTION_TITLE + Hypothesis Construction + + + SMESH_LOCAL_LENGTH_HYPOTHESIS + Local Length + + + SMESH_LOCAL_LENGTH_PARAM + Length + + + SMESH_LOCAL_LENGTH_PRECISION + Precision + + + SMESH_LOCAL_LENGTH_TITLE + Hypothesis Construction + + + SMESH_FIXED_POINTS_1D_HYPOTHESIS + Fixed points 1D + + + SMESH_FIXED_POINTS_1D_TITLE + Hypothesis Construction + + + SMESH_MAX_LENGTH_HYPOTHESIS + Max Length + + + SMESH_CARTESIAN_PARAMS_HYPOTHESIS + Body Fitting Parameters + + + SMESH_USE_PREESTIMATED_LENGTH + Use preestimated length + + + SMESH_VISCOUS_LAYERS_HYPOTHESIS + Viscous Layers + + + SMESH_VISCOUS_LAYERS_TITLE + Hypothesis Construction + + + SMESH_TOTAL_THICKNESS + Total thickness + + + SMESH_STRETCH_FACTOR + Stretch factor + + + SMESH_FACES_WO_LAYERS + Faces without layers +(inlets and oulets) + + + SMESH_MAX_LENGTH_TITLE + Hypothesis Construction + + + SMESH_CARTESIAN_PARAMS_TITLE + Hypothesis Construction + + + SMESH_MAX_ELEMENT_AREA_HYPOTHESIS + Max. Element Area + + + SMESH_MAX_ELEMENT_AREA_PARAM + Max. Area + + + SMESH_MAX_ELEMENT_AREA_TITLE + Hypothesis Construction + + + SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS + Max. Element Volume + + + SMESH_MAX_ELEMENT_VOLUME_PARAM + Max. Volume + + + SMESH_MAX_ELEMENT_VOLUME_TITLE + Hypothesis Construction + + + SMESH_NB_SEGMENTS_HYPOTHESIS + Number of Segments + + + SMESH_NB_SEGMENTS_PARAM + Number of Segments + + + SMESH_NB_SEGMENTS_SCALE_PARAM + Scale Factor + + + SMESH_NB_SEGMENTS_TITLE + Hypothesis Construction + + + SMESH_NO_CONV + No conversion + + + SMESH_NUMBER_OF_LAYERS + Number of layers + + + SMESH_NUMBER_OF_LAYERS_HYPOTHESIS + Radial Prism Parameter + + + SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS + Radial Quadrangle Parameter + + + SMESH_NUMBER_OF_LAYERS_TITLE + Hypothesis Construction + + + SMESH_NUMBER_OF_LAYERS_2D_TITLE + Hypothesis Construction + + + SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS + Projection Source 1D + + + SMESH_PROJECTION_SOURCE_1D_TITLE + Hypothesis Construction + + + SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS + Projection Source 2D + + + SMESH_PROJECTION_SOURCE_2D_TITLE + Hypothesis Construction + + + SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS + Projection Source 3D + + + SMESH_PROJECTION_SOURCE_3D_TITLE + Hypothesis Construction + + + SMESH_IMPORT_SOURCE_1D_HYPOTHESIS + Source edges + + + SMESH_IMPORT_SOURCE_1D_TITLE + Hypothesis Construction + + + SMESH_IMPORT_SOURCE_2D_HYPOTHESIS + Source faces + + + SMESH_IMPORT_SOURCE_2D_TITLE + Hypothesis Construction + + + SMESH_REMOVE_ROW + Remove row + + + SMESH_REVERSED_EDGES + Reversed Edges + + + SMESH_FIXED_POINTS + Fixed Points + + + SMESH_RANGE + Range + + + SMESH_NB_SEGMENTS + Nb. Segments + + + SMESH_SAME_NB_SEGMENTS + Same Nb. Segments for All Intervals + + + SMESH_BASE_VERTEX + Base vertex + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS + Segment Length Around Vertex + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM + Length + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE + Hypothesis Construction + + + SMESH_SOURCE_3DSHAPE + Source 3D shape + + + SMESH_SOURCE_EDGE + Source Edge + + + SMESH_SOURCE_EDGES + Groups of Edges + + + SMESH_SOURCE_FACE + Source Face + + + SMESH_SOURCE_FACES + Groups of Faces + + + SMESH_SOURCE_MESH + Source Mesh + + + SMESH_COPY_MESH + To copy mesh + + + SMESH_TO_COPY_GROUPS + To copy groups + + + SMESH_SOURCE_VERTEX + Source Vertex + + + SMESH_SOURCE_VERTEX1 + Source Vertex 1 + + + SMESH_SOURCE_VERTEX2 + Source Vertex 2 + + + SMESH_START_END_LENGTH_HYPOTHESIS + Start and End local Length + + + SMESH_START_END_LENGTH_TITLE + Hypothesis Construction + + + SMESH_START_LENGTH_PARAM + Start Length + + + SMESH_TAB_FUNC + Table function + + + SMESH_TARGET_VERTEX + Target Vertex + + + SMESH_TARGET_VERTEX1 + Target Vertex 1 + + + SMESH_TARGET_VERTEX2 + Target Vertex 2 + + + SMESH_QUADRANGLE_PARAMS_HYPOTHESIS + Quadrangle parameters + + + SMESH_QUADRANGLE_PARAMS_TITLE + Hypothesis Construction + + + SMESH_QUAD_TYPE + Type + + + + StdMeshersGUI_QuadrangleParamWdg + + SMESH_QUAD_TYPE_0 + Standard + + + SMESH_QUAD_TYPE_1 + Triangle preference + + + SMESH_QUAD_TYPE_2 + Quadrangle preference + + + SMESH_QUAD_TYPE_3 + Quadrangle preference (reversed) + + + SMESH_QUAD_TYPE_4 + Reduced + + + + StdMeshersGUI_LayerDistributionParamWdg + + CHANGE_TYPE + Change Type + + + CREATE + Create + + + EDIT + Edit + + + + StdMeshersGUI_CartesianParamCreator + + THRESHOLD + Threshold + + + AXIS_X + Axis X + + + AXIS_Y + Axis Y + + + AXIS_Z + Axis Z + + + + StdMeshersGUI::GridAxisTab + + GRID_DEF_MODE + Definition mode + + + SPACING + Spacing + + + INSERT + Insert + + + COORD_STEP + Step + + diff --git a/src/StdMeshersGUI/StdMeshers_msg_fr.ts b/src/StdMeshersGUI/StdMeshers_msg_fr.ts new file mode 100755 index 000000000..836a9fb20 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshers_msg_fr.ts @@ -0,0 +1,484 @@ + + + + + @default + + SMESH_ARITHMETIC_1D_HYPOTHESIS + Arithmétique 1D + + + SMESH_ARITHMETIC_1D_PARAM + Raison arithmétique + + + SMESH_ARITHMETIC_1D_TITLE + Construction de l'hypothèse + + + SMESH_AUTOMATIC_LENGTH_HYPOTHESIS + Longueur automatique + + + SMESH_AUTOMATIC_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_CONV_MODE + Mode de conversion + + + SMESH_CUT_NEG_MODE + Section négative + + + SMESH_DEFLECTION1D_HYPOTHESIS + Déflection 1D + + + SMESH_DEFLECTION1D_PARAM + Déflection + + + SMESH_DEFLECTION1D_TITLE + Construction de l'hypothèse + + + SMESH_DENSITY_FUNC + Fonction de densité + + + SMESH_DISTR + Distribution + + + SMESH_DISTR_EXPR + Distribution de densité analytique + + + SMESH_DISTR_REGULAR + Distribution équidistante + + + SMESH_DISTR_SCALE + Progression géométrique + + + SMESH_DISTR_TAB + Table de densités + + + SMESH_DISTR_TYPE + Type de distribution + + + SMESH_END_LENGTH_PARAM + Longueur finale + + + SMESH_EXPR_FUNC + Expression de la densité + + + SMESH_EXP_MODE + Exposant + + + SMESH_FINENESS_PARAM + Finesse + + + SMESH_FUNC_DOMAIN + Avertissement: La fonction doit être définie sur le segment [0..1] + + + SMESH_INSERT_ROW + Insérer une ligne + + + SMESH_INVALID_FUNCTION + La fonction n'est pas valide + + + SMESH_LAYERS_DISTRIBUTION + Hypothèse 1D + + + SMESH_LAYER_DISTRIBUTION_HYPOTHESIS + Distribution des couches + + + SMESH_LAYER_DISTRIBUTION_TITLE + Construction de l'hypothèse + + + SMESH_LOCAL_LENGTH_HYPOTHESIS + Longueur moyenne + + + SMESH_LOCAL_LENGTH_PARAM + Longueur + + + SMESH_LOCAL_LENGTH_PRECISION + Précision + + + SMESH_LOCAL_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_FIXED_POINTS_1D_HYPOTHESIS + Points fixes 1D + + + SMESH_FIXED_POINTS_1D_TITLE + Construction de l'hypothèse + + + SMESH_MAX_LENGTH_HYPOTHESIS + Longueur maximale + + + SMESH_CARTESIAN_PARAMS_HYPOTHESIS + Paramètres de Body Fitting + + + SMESH_USE_PREESTIMATED_LENGTH + Utiliser la longueur pré-estimée + + + SMESH_VISCOUS_LAYERS_HYPOTHESIS + Couches limites + + + SMESH_VISCOUS_LAYERS_TITLE + Construction de l'hypothèse + + + SMESH_TOTAL_THICKNESS + Epaisseur totale + + + SMESH_STRETCH_FACTOR + Facteur d'échelle + + + SMESH_FACES_WO_LAYERS + Faces sans couche limite +(entrées et sorties) + + + SMESH_MAX_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_CARTESIAN_PARAMS_TITLE + Construction de l'hypothèse + + + SMESH_MAX_ELEMENT_AREA_HYPOTHESIS + Aire maximale d'une maille + + + SMESH_MAX_ELEMENT_AREA_PARAM + Aire maximale + + + SMESH_MAX_ELEMENT_AREA_TITLE + Construction de l'hypothèse + + + SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS + Volume maximal d'une maille + + + SMESH_MAX_ELEMENT_VOLUME_PARAM + Volume maximal + + + SMESH_MAX_ELEMENT_VOLUME_TITLE + Construction de l'hypothèse + + + SMESH_NB_SEGMENTS_HYPOTHESIS + Nombre de segments + + + SMESH_NB_SEGMENTS_PARAM + Nombre de segments + + + SMESH_NB_SEGMENTS_SCALE_PARAM + Facteur d'échelle + + + SMESH_NB_SEGMENTS_TITLE + Construction de l'hypothèse + + + SMESH_NO_CONV + Sans conversion + + + SMESH_NUMBER_OF_LAYERS + Nombre de couches + + + SMESH_NUMBER_OF_LAYERS_HYPOTHESIS + Paramètre des prismes radiaux + + + SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS + Paramètre des quadrangles radiaux + + + SMESH_NUMBER_OF_LAYERS_TITLE + Construction de l'hypothèse + + + SMESH_NUMBER_OF_LAYERS_2D_TITLE + Construction de l'hypothèse + + + SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS + Source pour le projection 1D + + + SMESH_PROJECTION_SOURCE_1D_TITLE + Construction de l'hypothèse + + + SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS + Source pour la projection 2D + + + SMESH_PROJECTION_SOURCE_2D_TITLE + Construction de l'hypothèse + + + SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS + Source pour la projection 3D + + + SMESH_PROJECTION_SOURCE_3D_TITLE + Construction de l'hypothèse + + + SMESH_IMPORT_SOURCE_1D_HYPOTHESIS + Arêtes source + + + SMESH_IMPORT_SOURCE_1D_TITLE + Construction de l'hypothèse + + + SMESH_IMPORT_SOURCE_2D_HYPOTHESIS + Faces sources + + + SMESH_IMPORT_SOURCE_2D_TITLE + Construction de l'hypothèse + + + SMESH_REMOVE_ROW + Supprimer une ligne + + + SMESH_REVERSED_EDGES + Arêtes inversées + + + SMESH_FIXED_POINTS + Points fixés + + + SMESH_RANGE + Intervalle + + + SMESH_NB_SEGMENTS + Nb. segments + + + SMESH_SAME_NB_SEGMENTS + Le même Nb. segments dans chaque intervalle + + + SMESH_BASE_VERTEX + Point de base + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS + Longueur des segments autour d'un point + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM + Longueur + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE + Construction de l'hypothèse + + + SMESH_SOURCE_3DSHAPE + Objet 3D + + + SMESH_SOURCE_EDGE + Arête + + + SMESH_SOURCE_EDGES + Groupes d'arêtes + + + SMESH_SOURCE_FACE + Face + + + SMESH_SOURCE_FACES + Groupes de faces + + + SMESH_SOURCE_MESH + Maillage + + + SMESH_COPY_MESH + Copier le maillage + + + SMESH_TO_COPY_GROUPS + Copier les groupes + + + SMESH_SOURCE_VERTEX + Point source + + + SMESH_SOURCE_VERTEX1 + Point source 1 + + + SMESH_SOURCE_VERTEX2 + Point source 2 + + + SMESH_START_END_LENGTH_HYPOTHESIS + Start and end local Length + + + SMESH_START_END_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_START_LENGTH_PARAM + Longueur initiale + + + SMESH_TAB_FUNC + Table de valeurs de la fonction + + + SMESH_TARGET_VERTEX + Point cible + + + SMESH_TARGET_VERTEX1 + Point cible 1 + + + SMESH_TARGET_VERTEX2 + Point cible 2 + + + SMESH_QUADRANGLE_PARAMS_HYPOTHESIS + Paramètres pour le maillage quadrangulaire + + + SMESH_QUADRANGLE_PARAMS_TITLE + Construction de l'hypothèse + + + SMESH_QUAD_TYPE + Type + + + + StdMeshersGUI_QuadrangleParamWdg + + SMESH_QUAD_TYPE_0 + Standard + + + SMESH_QUAD_TYPE_1 + Triangles privilégiés + + + SMESH_QUAD_TYPE_2 + Quadrangles privilégiés + + + SMESH_QUAD_TYPE_3 + Quadrangles privilégiés (inversé) + + + SMESH_QUAD_TYPE_4 + Réduction + + + + StdMeshersGUI_LayerDistributionParamWdg + + CHANGE_TYPE + Changer le type + + + CREATE + Créer + + + EDIT + Editer + + + + StdMeshersGUI_CartesianParamCreator + + THRESHOLD + Seuil + + + AXIS_X + Axe X + + + AXIS_Y + Axe Y + + + AXIS_Z + Axe Z + + + + StdMeshersGUI::GridAxisTab + + GRID_DEF_MODE + Mode de définition + + + SPACING + Espacement + + + INSERT + Insérer + + + COORD_STEP + Pas + + + diff --git a/src/StdMeshers_I/Makefile.am b/src/StdMeshers_I/Makefile.am index 526d71fc5..4bc901d2d 100644 --- a/src/StdMeshers_I/Makefile.am +++ b/src/StdMeshers_I/Makefile.am @@ -1,30 +1,28 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is 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. # -# 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 # -# 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # SMESH StdMeshers_I : idl implementation based on 'StdMeshersPlugin' unit's classes # File : Makefile.in # Author : Julia DOROVSKIKH # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : SMESH - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files @@ -32,6 +30,7 @@ salomeinclude_HEADERS = \ StdMeshers_LocalLength_i.hxx \ StdMeshers_StartEndLength_i.hxx \ StdMeshers_Arithmetic1D_i.hxx \ + StdMeshers_FixedPoints1D_i.hxx \ StdMeshers_NumberOfSegments_i.hxx \ StdMeshers_Deflection1D_i.hxx \ StdMeshers_Propagation_i.hxx \ @@ -47,6 +46,7 @@ salomeinclude_HEADERS = \ StdMeshers_QuadranglePreference_i.hxx \ StdMeshers_QuadraticMesh_i.hxx \ StdMeshers_NumberOfLayers_i.hxx \ + StdMeshers_NumberOfLayers2D_i.hxx \ StdMeshers_Prism_3D_i.hxx \ StdMeshers_ProjectionSource1D_i.hxx \ StdMeshers_ProjectionSource2D_i.hxx \ @@ -54,13 +54,22 @@ salomeinclude_HEADERS = \ StdMeshers_Projection_1D_2D_3D_i.hxx \ StdMeshers_ObjRefUlils.hxx \ StdMeshers_LayerDistribution_i.hxx \ + StdMeshers_LayerDistribution2D_i.hxx \ StdMeshers_CompositeSegment_1D_i.hxx \ StdMeshers_SegmentAroundVertex_0D_i.hxx \ StdMeshers_SegmentLengthAroundVertex_i.hxx \ StdMeshers_UseExisting_1D2D_i.hxx \ - StdMeshers_TrianglePreference_i.hxx \ StdMeshers_MaxLength_i.hxx \ - SMESH_StdMeshers_I.hxx + StdMeshers_QuadrangleParams_i.hxx \ + StdMeshers_RadialQuadrangle_1D2D_i.hxx \ + SMESH_StdMeshers_I.hxx \ + StdMeshers_ImportSource1D_i.hxx \ + StdMeshers_ImportSource2D_i.hxx \ + StdMeshers_Import_1D_i.hxx \ + StdMeshers_Import_1D2D_i.hxx \ + StdMeshers_ViscousLayers_i.hxx \ + StdMeshers_CartesianParameters3D_i.hxx \ + StdMeshers_Cartesian_3D_i.hxx # Libraries targets lib_LTLIBRARIES = libStdMeshersEngine.la @@ -70,6 +79,7 @@ dist_libStdMeshersEngine_la_SOURCES = \ StdMeshers_LocalLength_i.cxx \ StdMeshers_StartEndLength_i.cxx \ StdMeshers_Arithmetic1D_i.cxx \ + StdMeshers_FixedPoints1D_i.cxx \ StdMeshers_NumberOfSegments_i.cxx \ StdMeshers_Deflection1D_i.cxx \ StdMeshers_Propagation_i.cxx \ @@ -85,6 +95,7 @@ dist_libStdMeshersEngine_la_SOURCES = \ StdMeshers_QuadranglePreference_i.cxx \ StdMeshers_QuadraticMesh_i.cxx \ StdMeshers_NumberOfLayers_i.cxx \ + StdMeshers_NumberOfLayers2D_i.cxx \ StdMeshers_Prism_3D_i.cxx \ StdMeshers_ProjectionSource1D_i.cxx \ StdMeshers_ProjectionSource2D_i.cxx \ @@ -92,12 +103,21 @@ dist_libStdMeshersEngine_la_SOURCES = \ StdMeshers_Projection_1D_2D_3D_i.cxx \ StdMeshers_ObjRefUlils.cxx \ StdMeshers_LayerDistribution_i.cxx \ + StdMeshers_LayerDistribution2D_i.cxx \ StdMeshers_CompositeSegment_1D_i.cxx \ StdMeshers_SegmentAroundVertex_0D_i.cxx \ StdMeshers_SegmentLengthAroundVertex_i.cxx \ StdMeshers_UseExisting_1D2D_i.cxx \ - StdMeshers_TrianglePreference_i.cxx \ - StdMeshers_MaxLength_i.cxx + StdMeshers_MaxLength_i.cxx \ + StdMeshers_QuadrangleParams_i.cxx \ + StdMeshers_RadialQuadrangle_1D2D_i.cxx \ + StdMeshers_ImportSource1D_i.cxx \ + StdMeshers_ImportSource2D_i.cxx \ + StdMeshers_Import_1D_i.cxx \ + StdMeshers_Import_1D2D_i.cxx \ + StdMeshers_ViscousLayers_i.cxx \ + StdMeshers_CartesianParameters3D_i.cxx \ + StdMeshers_Cartesian_3D_i.cxx # additionnal information to compil and link file libStdMeshersEngine_la_CPPFLAGS = \ @@ -107,19 +127,19 @@ libStdMeshersEngine_la_CPPFLAGS = \ $(GEOM_CXXFLAGS) \ $(MED_CXXFLAGS) \ $(BOOST_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ -I$(srcdir)/../SMESHImpl \ -I$(srcdir)/../MEFISTO2 \ -I$(srcdir)/../SMESH \ + -I$(srcdir)/../SMESHUtils \ -I$(srcdir)/../SMESH_I \ -I$(srcdir)/../SMESHDS \ -I$(srcdir)/../SMDS \ -I$(srcdir)/../Controls \ -I$(srcdir)/../StdMeshers \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix - + -I$(top_builddir)/idl libStdMeshersEngine_la_LDFLAGS = \ ../../idl/libSalomeIDLSMESH.la \ diff --git a/src/StdMeshers_I/SMESH_StdMeshers_I.hxx b/src/StdMeshers_I/SMESH_StdMeshers_I.hxx index 70a1bda44..6352b0734 100755 --- a/src/StdMeshers_I/SMESH_StdMeshers_I.hxx +++ b/src/StdMeshers_I/SMESH_StdMeshers_I.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : SMESH_StdMeshers_I.hxx // Author : Alexander BORODIN // Module : SMESH @@ -28,7 +29,7 @@ #define _SMESH_StdMeshers_I_HXX_ #ifdef WNT - #if defined STDMESHERS_I_EXPORTS + #if defined STDMESHERS_I_EXPORTS || defined StdMeshersEngine_EXPORTS #define STDMESHERS_I_EXPORT __declspec( dllexport ) #else #define STDMESHERS_I_EXPORT __declspec( dllimport ) diff --git a/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.cxx b/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.cxx index 20a0b2909..8d57e1e9a 100644 --- a/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Arithmetic1D_i.cxx // Author : Damien COQUERET, OCC // Module : SMESH -// $Header$ // #include "StdMeshers_Arithmetic1D_i.hxx" #include "SMESH_Gen_i.hxx" @@ -46,15 +46,15 @@ using namespace std; //============================================================================= StdMeshers_Arithmetic1D_i::StdMeshers_Arithmetic1D_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) + int theStudyId, + ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { MESSAGE( "StdMeshers_Arithmetic1D_i::StdMeshers_Arithmetic1D_i" ); myBaseImpl = new ::StdMeshers_Arithmetic1D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= @@ -79,7 +79,7 @@ StdMeshers_Arithmetic1D_i::~StdMeshers_Arithmetic1D_i() //============================================================================= void StdMeshers_Arithmetic1D_i::SetLength(CORBA::Double theLength, - CORBA::Boolean theIsStart ) + CORBA::Boolean theIsStart ) throw ( SALOME::SALOME_Exception ) { MESSAGE( "StdMeshers_StartEndLength_i::SetLength" ); @@ -89,12 +89,37 @@ void StdMeshers_Arithmetic1D_i::SetLength(CORBA::Double theLength, } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetLength( " - << theLength << ", " << theIsStart << " )"; + SMESH::TPythonDump() + << _this() << ( theIsStart ? ".SetStartLength( " : ".SetEndLength( " ) + << SMESH::TVar(theLength) << " )"; +} + +//============================================================================= +/*! + * Sets parameter value + */ +//============================================================================= + +void StdMeshers_Arithmetic1D_i::SetStartLength( CORBA::Double length) + throw (SALOME::SALOME_Exception) +{ + SetLength( length, true ); +} + +//============================================================================= +/*! + * Sets parameter value + */ +//============================================================================= + +void StdMeshers_Arithmetic1D_i::SetEndLength( CORBA::Double length) + throw (SALOME::SALOME_Exception) +{ + SetLength( length, false ); } //============================================================================= @@ -107,11 +132,105 @@ void StdMeshers_Arithmetic1D_i::SetLength(CORBA::Double theLength, CORBA::Double StdMeshers_Arithmetic1D_i::GetLength( CORBA::Boolean theIsStart) { - MESSAGE( "StdMeshers_StartEndLength_i::GetLength" ); + MESSAGE( "StdMeshers_Arithmetic1D_i::GetLength" ); ASSERT( myBaseImpl ); return this->GetImpl()->GetLength( theIsStart ); } +//============================================================================= +/*! + * StdMeshers_Arithmetic1D_i::SetReversedEdges + * + * Set edges to reverse + */ +//============================================================================= + +void StdMeshers_Arithmetic1D_i::SetReversedEdges( const SMESH::long_array& theIds ) +{ + ASSERT( myBaseImpl ); + try { + std::vector ids( theIds.length() ); + CORBA::Long iEnd = theIds.length(); + for ( CORBA::Long i = 0; i < iEnd; i++ ) + ids[ i ] = theIds[ i ]; + + this->GetImpl()->SetReversedEdges( ids ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )"; +} + +//============================================================================= +/*! + * StdMeshers_Arithmetic1D_i::SetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +void StdMeshers_Arithmetic1D_i::SetObjectEntry( const char* theEntry ) +{ + ASSERT( myBaseImpl ); + string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping + try { + this->GetImpl()->SetObjectEntry( entry.c_str() ); + // Update Python script + SMESH::TPythonDump() << _this() << ".SetObjectEntry( \"" << entry.c_str() << "\" )"; + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_Arithmetic1D_i::GetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +char* StdMeshers_Arithmetic1D_i::GetObjectEntry() +{ + MESSAGE( "StdMeshers_Arithmetic1D_i::SetObjectEntry" ); + ASSERT( myBaseImpl ); + const char* entry; + try { + entry = this->GetImpl()->GetObjectEntry(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return CORBA::string_dup( entry ); +} + +//============================================================================= +/*! + * StdMeshers_Arithmetic1D_i::GetReversedEdges + * + * Get reversed edges + */ +//============================================================================= + +SMESH::long_array* StdMeshers_Arithmetic1D_i::GetReversedEdges() +{ + MESSAGE( "StdMeshers_StartEndLength_i::GetReversedEdges" ); + ASSERT( myBaseImpl ); + SMESH::long_array_var anArray = new SMESH::long_array; + std::vector ids = this->GetImpl()->GetReversedEdges(); + anArray->length( ids.size() ); + for ( CORBA::Long i = 0; i < ids.size(); i++) + anArray [ i ] = ids [ i ]; + + return anArray._retn(); +} + //============================================================================= /*! * StdMeshers_Arithmetic1D_i::GetImpl @@ -140,3 +259,14 @@ CORBA::Boolean StdMeshers_Arithmetic1D_i::IsDimSupported( SMESH::Dimension type return type == SMESH::DIM_1D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_Arithmetic1D_i::getMethodOfParameter(const int paramIndex, + int nbVars) const +{ + return paramIndex == 0 ? "SetStartLength" : "SetEndLength"; +} diff --git a/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx b/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx index 3d8ec8642..6dfeb10fd 100644 --- a/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Arithmetic1D_i.hxx // Author : Damien COQUERET, OCC // Module : SMESH -// $Header$ // #ifndef _SMESH_ARITHMETIC1D_I_HXX_ #define _SMESH_ARITHMETIC1D_I_HXX_ @@ -47,21 +47,44 @@ public: // Constructor StdMeshers_Arithmetic1D_i( PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~StdMeshers_Arithmetic1D_i(); // Set length + // * OBSOLETE *. Avoid such a way of interface design void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart ) throw ( SALOME::SALOME_Exception ); + + // Sets parameter value + void SetStartLength( CORBA::Double length) throw (SALOME::SALOME_Exception); + + // Sets parameter value + void SetEndLength( CORBA::Double length) throw (SALOME::SALOME_Exception); + // Get length CORBA::Double GetLength(CORBA::Boolean theIsStart); + //Set Reversed Edges + void SetReversedEdges( const SMESH::long_array& theIDs); + + //Get Reversed Edges + SMESH::long_array* GetReversedEdges(); + + //Set the Entry of the Object + void SetObjectEntry( const char* theEntry); + + //Get Object Entry + char* GetObjectEntry(); + // Get implementation ::StdMeshers_Arithmetic1D* GetImpl(); - + // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx b/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx index 2085f1f52..9d8f15e65 100644 --- a/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx +++ b/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_AutomaticLength_i.cxx // Author : Edward AGAPOV @@ -87,7 +88,7 @@ void StdMeshers_AutomaticLength_i::SetFineness( CORBA::Double theFineness ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script SMESH::TPythonDump() << _this() << ".SetFineness( " << theFineness << " )"; diff --git a/src/StdMeshers_I/StdMeshers_AutomaticLength_i.hxx b/src/StdMeshers_I/StdMeshers_AutomaticLength_i.hxx index 7bb85cf45..c3492bf38 100644 --- a/src/StdMeshers_I/StdMeshers_AutomaticLength_i.hxx +++ b/src/StdMeshers_I/StdMeshers_AutomaticLength_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_AutomaticLength_i.hxx // Author : Edward AGAPOV diff --git a/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.cxx b/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.cxx new file mode 100644 index 000000000..d8b072476 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.cxx @@ -0,0 +1,293 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_CartesianParameters3D_i.cxx +// Module : SMESH +// +#include "StdMeshers_CartesianParameters3D_i.hxx" + +#include "StdMeshers_CartesianParameters3D.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_PythonDump.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#define _vec2array( v, a,conversion ) \ + { \ + a->length( v.size() ); \ + for ( size_t i = 0; i < v.size(); ++i ) \ + a[i] = conversion( v[i] ); \ + } +#define _array2vec(a,v,conversion) \ + { \ + v.resize( a.length() ); \ + for ( size_t i = 0; i < v.size(); ++i ) \ + v[i] = conversion ( a[i] ); \ + } +namespace +{ + const char* _string2chars(const std::string& s ) { return s.c_str(); } +} + +//============================================================================= +/*! + * StdMeshers_CartesianParameters3D_i::StdMeshers_CartesianParameters3D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_CartesianParameters3D_i:: +StdMeshers_CartesianParameters3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_CartesianParameters3D_i::StdMeshers_CartesianParameters3D_i" ); + myBaseImpl = new ::StdMeshers_CartesianParameters3D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_CartesianParameters3D_i::~StdMeshers_CartesianParameters3D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_CartesianParameters3D_i::~StdMeshers_CartesianParameters3D_i() +{ + MESSAGE( "StdMeshers_CartesianParameters3D_i::~StdMeshers_CartesianParameters3D_i" ); +} + +//============================================================================= +/*! + * SetGrid + */ +//============================================================================= + +void StdMeshers_CartesianParameters3D_i::SetGrid(const SMESH::double_array& coords, + CORBA::Short axis) + throw (SALOME::SALOME_Exception) +{ + std::vector coordVec;//, yCoords, zCoords; + _array2vec( coords, coordVec, ); + + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetGrid( coordVec, axis ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetGrid( " << coords << ", " << axis << " )"; +} + +//============================================================================= +/*! + * GetGrid + */ +//============================================================================= + +SMESH::double_array* StdMeshers_CartesianParameters3D_i::GetGrid(CORBA::Short axis) + throw (SALOME::SALOME_Exception) +{ + std::vector coordVec; + ASSERT( myBaseImpl ); + try { + this->GetImpl()->GetGrid(coordVec, axis); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + SMESH::double_array_var coords = new SMESH::double_array(); + _vec2array( coordVec, coords, ); + + return coords._retn(); +} + +//============================================================================= +/*! + * SetSizeThreshold + */ +//============================================================================= + +void StdMeshers_CartesianParameters3D_i::SetSizeThreshold(CORBA::Double threshold) + throw (SALOME::SALOME_Exception) +{ + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetSizeThreshold(threshold); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetSizeThreshold( " << SMESH::TVar(threshold) << " )"; +} + +//============================================================================= +/*! + * GetSizeThreshold + */ +//============================================================================= + +CORBA::Double StdMeshers_CartesianParameters3D_i::GetSizeThreshold() +{ + return this->GetImpl()->GetSizeThreshold(); +} + +//======================================================================= +//function : SetGridSpacing +//\brief Set grid spacing along the three axes +// \param spaceFunctions - functions defining spacing values at given point on axis +// \param internalPoints - points dividing a grid into parts along each direction +// Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of +// the shape to mesh or withing an interval defined by internal points +//======================================================================= + +void StdMeshers_CartesianParameters3D_i::SetGridSpacing(const SMESH::string_array& spaceFunctions, + const SMESH::double_array& internalPoints, + CORBA::Short axis) + throw (SALOME::SALOME_Exception) +{ + vector funVec; + vector pointVec; + _array2vec( spaceFunctions, funVec, (const char*) ); + _array2vec( internalPoints, pointVec, ); + + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetGridSpacing( funVec, pointVec, axis ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetGridSpacing( " + << spaceFunctions << ", " + << internalPoints << ", " + << axis << " )"; +} + +//======================================================================= +//function : GetGridSpacing +//======================================================================= + +void StdMeshers_CartesianParameters3D_i::GetGridSpacing(SMESH::string_array_out xSpaceFunctions, + SMESH::double_array_out xInternalPoints, + CORBA::Short axis) + throw (SALOME::SALOME_Exception) +{ + ASSERT( myBaseImpl ); + try { + vector funVec; + vector pointVec; + this->GetImpl()->GetGridSpacing( funVec, pointVec, axis ); + + xSpaceFunctions = new SMESH::string_array(); + xInternalPoints = new SMESH::double_array(); + + _vec2array( funVec, xSpaceFunctions, _string2chars ); + _vec2array( pointVec, xInternalPoints, ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } +} + +//======================================================================= +//function : IsGridBySpacing +//purpose : Return true if the grid is defined by spacing functions and +// not by node coordinates +//======================================================================= + +CORBA::Boolean StdMeshers_CartesianParameters3D_i::IsGridBySpacing(CORBA::Short axis) +{ + return this->GetImpl()->IsGridBySpacing(axis); +} + +//======================================================================= +//function : ComputeCoordinates +//purpose : Computes node coordinates by spacing functions +//======================================================================= + +SMESH::double_array* +StdMeshers_CartesianParameters3D_i::ComputeCoordinates(CORBA::Double x0, + CORBA::Double x1, + const SMESH::string_array& spaceFuns, + const SMESH::double_array& points, + const char* axisName ) + throw (SALOME::SALOME_Exception) +{ + vector xFuns; + vector xPoints, coords; + _array2vec( spaceFuns, xFuns, (const char*) ); + _array2vec( points, xPoints, ); + + try { + this->GetImpl()->ComputeCoordinates( x0, x1, xFuns, xPoints, coords, axisName ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + SMESH::double_array_var res = new SMESH::double_array; + _vec2array( coords, res, ); + + return res._retn(); +} + +//============================================================================= +/*! + * Get implementation + */ +//============================================================================= + +::StdMeshers_CartesianParameters3D* StdMeshers_CartesianParameters3D_i::GetImpl() +{ + MESSAGE( "StdMeshers_CartesianParameters3D_i::GetImpl" ); + return ( ::StdMeshers_CartesianParameters3D* )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_CartesianParameters3D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_3D; +} diff --git a/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.hxx b/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.hxx new file mode 100644 index 000000000..e09422d0f --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.hxx @@ -0,0 +1,116 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_CartesianParameters3D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_CartesianParameters3D_I_HXX_ +#define _SMESH_CartesianParameters3D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" + +class SMESH_Gen; +class StdMeshers_CartesianParameters3D; + +// ====================================================== +// "CartesianParameters3D" hypothesis +// ====================================================== + +class STDMESHERS_I_EXPORT StdMeshers_CartesianParameters3D_i: + public virtual POA_StdMeshers::StdMeshers_CartesianParameters3D, + public virtual SMESH_Hypothesis_i +{ + public: + // Constructor + StdMeshers_CartesianParameters3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_CartesianParameters3D_i(); + + /*! + * Set size threshold. A polyhedral cell got by cutting an initial + * hexahedron by geometry boundary is considered small and is removed if + * it's size is \athreshold times less than the size of the initial hexahedron. + * threshold must be > 1.0 + */ + void SetSizeThreshold(CORBA::Double threshold) throw (SALOME::SALOME_Exception); + CORBA::Double GetSizeThreshold(); + + /*! + * \brief Set node coordinates along an axis (counterd from zero) + */ + void SetGrid(const SMESH::double_array& coords, + CORBA::Short axis) throw (SALOME::SALOME_Exception); + SMESH::double_array* GetGrid(CORBA::Short axis) throw (SALOME::SALOME_Exception); + + /*! + * \brief Set grid spacing along an axis + * \param spaceFunctions - functions defining spacing value at given point on axis + * \param internalPoints - points dividing a grid into parts along each direction + * \param axis - index of an axis counterd from zero, i.e. 0==X, 1==Y, 2==Z + * + * Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of + * the shape to mesh or withing an interval defined by internal points + */ + void SetGridSpacing(const SMESH::string_array& spaceFunctions, + const SMESH::double_array& internalPoints, + CORBA::Short axis) throw (SALOME::SALOME_Exception); + + void GetGridSpacing(SMESH::string_array_out xSpaceFunctions, + SMESH::double_array_out xInternalPoints, + CORBA::Short axis) throw (SALOME::SALOME_Exception); + + /*! + * \brief Return true if the grid is defined by spacing functions and + * not by node coordinates + */ + CORBA::Boolean IsGridBySpacing(CORBA::Short axis); + + /*! + * \brief Computes node coordinates by spacing functions + * \param x0 - lower coordinate + * \param x1 - upper coordinate + * \param spaceFuns - space functions + * \param points - internal points + * \param coords - the computed coordinates + */ + SMESH::double_array* ComputeCoordinates(CORBA::Double x0, + CORBA::Double x1, + const SMESH::string_array& spaceFuns, + const SMESH::double_array& points, + const char* axisName ) + throw (SALOME::SALOME_Exception); + + // Get implementation + ::StdMeshers_CartesianParameters3D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.cxx new file mode 100644 index 000000000..445495f7a --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.cxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_Cartesian_3D_i.cxx +// Module : SMESH +// +#include "StdMeshers_Cartesian_3D_i.hxx" +#include "StdMeshers_Cartesian_3D.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_Cartesian_3D_i::StdMeshers_Cartesian_3D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_Cartesian_3D_i::StdMeshers_Cartesian_3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_3D_Algo_i( thePOA ) +{ + MESSAGE( "StdMeshers_Cartesian_3D_i::StdMeshers_Cartesian_3D_i" ); + myBaseImpl = new ::StdMeshers_Cartesian_3D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_Cartesian_3D_i::~StdMeshers_Cartesian_3D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_Cartesian_3D_i::~StdMeshers_Cartesian_3D_i() +{ + MESSAGE( "StdMeshers_Cartesian_3D_i::~StdMeshers_Cartesian_3D_i" ); +} + +//============================================================================= +/*! + * StdMeshers_Cartesian_3D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_Cartesian_3D* StdMeshers_Cartesian_3D_i::GetImpl() +{ + MESSAGE( "StdMeshers_Cartesian_3D_i::GetImpl" ); + return ( ::StdMeshers_Cartesian_3D* )myBaseImpl; +} diff --git a/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.hxx new file mode 100644 index 000000000..7b2d72a28 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.hxx @@ -0,0 +1,58 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_Cartesian_3D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_Cartesian_3D_I_HXX_ +#define _SMESH_Cartesian_3D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_3D_Algo_i.hxx" + +class SMESH_Gen; +class StdMeshers_Cartesian_3D; + +// ====================================================== +// Cartesianedron 3d algorithm +// ====================================================== +class STDMESHERS_I_EXPORT StdMeshers_Cartesian_3D_i: + public virtual POA_StdMeshers::StdMeshers_Cartesian_3D, + public virtual SMESH_3D_Algo_i +{ +public: + // Constructor + StdMeshers_Cartesian_3D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + + // Destructor + virtual ~StdMeshers_Cartesian_3D_i(); + + // Get implementation + ::StdMeshers_Cartesian_3D* GetImpl(); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx b/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx index c9d1d7693..5dc09cbc5 100644 --- a/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_CompositeSegment_1D_i.cxx // Module : SMESH diff --git a/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx b/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx index d8ffd9b9f..4f40a2d7a 100644 --- a/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_CompositeSegment_1D_i.hxx // Module : SMESH diff --git a/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx b/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx index 2386c6aa7..93b208b7a 100644 --- a/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Deflection1D_i.cxx // Moved here from SMESH_LocalLength_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_Deflection1D_i.hxx" #include "SMESH_Gen_i.hxx" @@ -47,15 +47,15 @@ using namespace std; //============================================================================= StdMeshers_Deflection1D_i::StdMeshers_Deflection1D_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) + int theStudyId, + ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { MESSAGE( "StdMeshers_Deflection1D_i::StdMeshers_Deflection1D_i" ); myBaseImpl = new ::StdMeshers_Deflection1D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= @@ -89,11 +89,11 @@ void StdMeshers_Deflection1D_i::SetDeflection( CORBA::Double theValue ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetDeflection( " << theValue << " )"; + SMESH::TPythonDump() << _this() << ".SetDeflection( " << SMESH::TVar(theValue) << " )"; } //============================================================================= @@ -139,3 +139,14 @@ CORBA::Boolean StdMeshers_Deflection1D_i::IsDimSupported( SMESH::Dimension type return type == SMESH::DIM_1D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_Deflection1D_i::getMethodOfParameter(const int paramIndex, + int /*nbVars*/) const +{ + return "SetDeflection"; +} diff --git a/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx b/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx index 8fd89d4cd..f4e9a9b26 100644 --- a/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Deflection1D_i.hxx // Moved here from SMESH_LocalLength_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_Deflection1D_I_HXX_ #define _SMESH_Deflection1D_I_HXX_ @@ -65,7 +65,9 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif - diff --git a/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.cxx b/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.cxx new file mode 100644 index 000000000..1d39c8edd --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.cxx @@ -0,0 +1,288 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_FixedPoints1D_i.cxx +// Author : Damien COQUERET, OCC +// Module : SMESH +// $Header$ +// +#include "StdMeshers_FixedPoints1D_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_PythonDump.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::StdMeshers_FixedPoints1D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_FixedPoints1D_i::StdMeshers_FixedPoints1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::StdMeshers_FixedPoints1D_i" ); + myBaseImpl = new ::StdMeshers_FixedPoints1D(theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::~StdMeshers_FixedPoints1D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_FixedPoints1D_i::~StdMeshers_FixedPoints1D_i() +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::~StdMeshers_FixedPoints1D_i" ); +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::SetNbSegments + */ +//============================================================================= + +void StdMeshers_FixedPoints1D_i::SetNbSegments(const SMESH::long_array& listNbSeg) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::SetNbSegments" ); + ASSERT( myBaseImpl ); + try { + std::vector nbsegs( listNbSeg.length() ); + CORBA::Long iEnd = listNbSeg.length(); + for ( CORBA::Long i = 0; i < iEnd; i++ ) + nbsegs[ i ] = listNbSeg[ i ]; + this->GetImpl()->SetNbSegments( nbsegs ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetNbSegments( " << listNbSeg << " )"; +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::SetPoints + */ +//============================================================================= + +void StdMeshers_FixedPoints1D_i::SetPoints(const SMESH::double_array& listParams) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::SetPoints" ); + ASSERT( myBaseImpl ); + try { + std::vector params( listParams.length() ); + CORBA::Long iEnd = listParams.length(); + for ( CORBA::Long i = 0; i < iEnd; i++ ) + params[ i ] = listParams[ i ]; + this->GetImpl()->SetPoints( params ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetPoints( " << listParams << " )"; +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::GetPoints + * + * Get list of point's parameters + */ +//============================================================================= + +SMESH::double_array* StdMeshers_FixedPoints1D_i::GetPoints() +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::GetPoints" ); + ASSERT( myBaseImpl ); + SMESH::double_array_var anArray = new SMESH::double_array; + std::vector params = this->GetImpl()->GetPoints(); + anArray->length( params.size() ); + for ( CORBA::Long i = 0; i < params.size(); i++) + anArray [ i ] = params [ i ]; + + return anArray._retn(); +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::GetNbSegments + * + * Get list of point's parameters + */ +//============================================================================= + +SMESH::long_array* StdMeshers_FixedPoints1D_i::GetNbSegments() +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::GetNbSegments" ); + ASSERT( myBaseImpl ); + SMESH::long_array_var anArray = new SMESH::long_array; + std::vector nbsegs = this->GetImpl()->GetNbSegments(); + anArray->length( nbsegs.size() ); + for ( CORBA::Long i = 0; i < nbsegs.size(); i++) + anArray [ i ] = nbsegs [ i ]; + + return anArray._retn(); +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::SetReversedEdges + * + * Set edges to reverse + */ +//============================================================================= + +void StdMeshers_FixedPoints1D_i::SetReversedEdges( const SMESH::long_array& theIds ) +{ + ASSERT( myBaseImpl ); + try { + std::vector ids( theIds.length() ); + CORBA::Long iEnd = theIds.length(); + for ( CORBA::Long i = 0; i < iEnd; i++ ) + ids[ i ] = theIds[ i ]; + + this->GetImpl()->SetReversedEdges( ids ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )"; +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::SetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +void StdMeshers_FixedPoints1D_i::SetObjectEntry( const char* theEntry ) +{ + ASSERT( myBaseImpl ); + string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping + try { + this->GetImpl()->SetObjectEntry( entry.c_str() ); + // Update Python script + SMESH::TPythonDump() << _this() << ".SetObjectEntry( \"" << entry.c_str() << "\" )"; + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::GetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +char* StdMeshers_FixedPoints1D_i::GetObjectEntry() +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::SetObjectEntry" ); + ASSERT( myBaseImpl ); + const char* entry; + try { + entry = this->GetImpl()->GetObjectEntry(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return CORBA::string_dup( entry ); +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::GetReversedEdges + * + * Get reversed edges + */ +//============================================================================= + +SMESH::long_array* StdMeshers_FixedPoints1D_i::GetReversedEdges() +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::GetReversedEdges" ); + ASSERT( myBaseImpl ); + SMESH::long_array_var anArray = new SMESH::long_array; + std::vector ids = this->GetImpl()->GetReversedEdges(); + anArray->length( ids.size() ); + for ( CORBA::Long i = 0; i < ids.size(); i++) + anArray [ i ] = ids [ i ]; + + return anArray._retn(); +} + +//============================================================================= +/*! + * StdMeshers_FixedPoints1D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_FixedPoints1D* StdMeshers_FixedPoints1D_i::GetImpl() +{ + MESSAGE( "StdMeshers_FixedPoints1D_i::GetImpl" ); + return ( ::StdMeshers_FixedPoints1D* )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_FixedPoints1D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_1D; +} + diff --git a/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.hxx b/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.hxx new file mode 100644 index 000000000..ee43e5ca9 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.hxx @@ -0,0 +1,85 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_FixedPoints1D_i.hxx +// Author : Damien COQUERET, OCC +// Module : SMESH +// +#ifndef _SMESH_FIXEDPOINTS1D_I_HXX_ +#define _SMESH_FIXEDPOINTS1D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_FixedPoints1D.hxx" + +// ====================================================== +// Fixed points 1D hypothesis +// ====================================================== +class STDMESHERS_I_EXPORT StdMeshers_FixedPoints1D_i: + public virtual POA_StdMeshers::StdMeshers_FixedPoints1D, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_FixedPoints1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_FixedPoints1D_i(); + + // Sets some points on edge using parameter on curve from 0 to 1 + // (additionally it is neecessary to check orientation of edges and + // create list of reversed edges if it is needed) and sets numbers + // of segments between given points (default values are equals 1) + void SetPoints(const SMESH::double_array& listParams) + throw ( SALOME::SALOME_Exception ); + void SetNbSegments(const SMESH::long_array& listNbSeg) + throw ( SALOME::SALOME_Exception ); + + // Returns list of point's parameters + SMESH::double_array* GetPoints(); + + // Returns list of numbers of segments + SMESH::long_array* GetNbSegments(); + + //Set Reversed Edges + void SetReversedEdges( const SMESH::long_array& theIDs); + + //Get Reversed Edges + SMESH::long_array* GetReversedEdges(); + + //Set the Entry of the Object + void SetObjectEntry( const char* theEntry); + + //Get Object Entry + char* GetObjectEntry(); + + // Get implementation + ::StdMeshers_FixedPoints1D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx index cac9b45e2..d75efe8e8 100644 --- a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Hexa_3D_i.cxx // Moved here from SMESH_Hexa_3D_i.cxx @@ -43,8 +44,8 @@ using namespace std; //============================================================================= StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_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 ), @@ -52,8 +53,8 @@ StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA, { MESSAGE( "StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i" ); myBaseImpl = new ::StdMeshers_Hexa_3D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= diff --git a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx index 9c07aed6f..6316fea71 100644 --- a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Hexa_3D_i.hxx // Moved here from SMESH_Hexa_3D_i.hxx @@ -50,7 +51,7 @@ public: // Constructor StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~StdMeshers_Hexa_3D_i(); diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx new file mode 100644 index 000000000..e2ad32141 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx @@ -0,0 +1,280 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource1D_i.cxx +// Module : SMESH +// +#include "StdMeshers_ImportSource1D_i.hxx" + +#include "SMESH_Gen.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_PythonDump.hxx" +#include "StdMeshers_ObjRefUlils.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +#include CORBA_SERVER_HEADER(SMESH_Group) + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i" ); + myBaseImpl = new ::StdMeshers_ImportSource1D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); + _groupEntries = new SMESH::string_array(); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i() +{ + MESSAGE( "StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i" ); +} + +//============================================================================= +/*! + * SetSourceEdges + */ +//============================================================================= + +void StdMeshers_ImportSource1D_i::SetSourceEdges(const SMESH::ListOfGroups& groups) +{ + MESSAGE( "StdMeshers_ImportSource1D_i::SetSourceEdges" ); + ASSERT( myBaseImpl ); + try + { + std::vector smesh_groups; + std::vector entries; + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < groups.length(); ++i ) + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( groups[i] )) + { + if ( gp_i->GetType() != SMESH::EDGE ) + THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM); + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + + SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]); + if ( !so->_is_nil()) + { + CORBA::String_var entry = so->GetID(); + entries.push_back( entry.in() ); + } + } + this->GetImpl()->SetGroups( smesh_groups ); + + _groupEntries = new SMESH::string_array; + _groupEntries->length( entries.size ()); + for ( int i = 0; i < entries.size(); ++i ) + _groupEntries[i] = entries[i].c_str(); + } + catch ( SALOME_Exception& S_ex ) + { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetSourceEdges( " << groups << " )"; +} + +//============================================================================= +/*! + * Return entries of groups + */ +//============================================================================= + +SMESH::string_array* StdMeshers_ImportSource1D_i::GetSourceEdges() +{ + MESSAGE( "StdMeshers_ImportSource1D_i::GetImportSource" ); + SMESH::string_array_var res = new SMESH::string_array( _groupEntries ); + return res._retn(); +} + +//================================================================================ +/*! + * \brief Set to copy mesh and groups + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh, + CORBA::Boolean toCopyGroups) +{ + GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups); + SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( " + << toCopyMesh << ", " << toCopyGroups << " )"; +} + +//================================================================================ +/*! + * \brief Return "to copy mesh and groups" + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh, + CORBA::Boolean& toCopyGroups) +{ + GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups); +} + +//================================================================================ +/*! + * \brief Write parameters in a string + * \retval char* - resulting string + */ +//================================================================================ + +char* StdMeshers_ImportSource1D_i::SaveTo() +{ + std::ostringstream os; + os << " " << _groupEntries->length(); + + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + // entry + os << " " << _groupEntries[i]; + + // id + SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] ); + CORBA::Object_var groupObj; + if ( !groupSO->_is_nil() ) + groupObj = groupSO->GetObject(); + StdMeshers_ObjRefUlils::SaveToStream( groupObj, os ); + } + + myBaseImpl->SaveTo( os ); + + return CORBA::string_dup( os.str().c_str() ); +} + +//================================================================================ +/*! + * \brief Retrieve parameters from the string + * \param theStream - the input string + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::LoadFrom( const char* theStream ) +{ + std::istringstream is( theStream ); + + int nbGroups; + is >> nbGroups; + + _groupEntries = new SMESH::string_array; + _groupEntries->length( nbGroups ); + std::string id, entry; + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + if ( is >> entry ) + _groupEntries[i] = entry.c_str(); + else + { + _groupEntries->length( i ); + is.clear(ios::badbit | is.rdstate()); + break; + } + if ( is >> id ) + _groupIDs.push_back( id ); + else + { + is.clear(ios::badbit | is.rdstate()); + break; + } + } + + myBaseImpl->LoadFrom( is ); +} + +//================================================================================ +/*! + * \brief Retrieve groups by their ids loaded by LoadFrom() + * This is possible only when all meshes are fully loaded + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::UpdateAsMeshesRestored() +{ + std::vector smesh_groups; + for ( unsigned i = 0; i < _groupIDs.size(); ++i ) + { + std::istringstream is( _groupIDs[i].c_str() ); + SMESH::SMESH_GroupBase_var group = + StdMeshers_ObjRefUlils::LoadObjectFromStream( is ); + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( group )) + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + } + GetImpl()->RestoreGroups(smesh_groups); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource1D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_ImportSource1D* StdMeshers_ImportSource1D_i::GetImpl() +{ + MESSAGE( "StdMeshers_ImportSource1D_i::GetImpl" ); + return ( ::StdMeshers_ImportSource1D* )myBaseImpl; +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean StdMeshers_ImportSource1D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_1D; +} + diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx new file mode 100644 index 000000000..1c3fafaa7 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx @@ -0,0 +1,74 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource1D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_ImportSource1D_I_HXX_ +#define _SMESH_ImportSource1D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_ImportSource.hxx" + +class SMESH_Gen; + +class STDMESHERS_I_EXPORT StdMeshers_ImportSource1D_i: + public virtual POA_StdMeshers::StdMeshers_ImportSource1D, + public virtual SMESH_Hypothesis_i +{ + public: + // Constructor + StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_ImportSource1D_i(); + + void SetSourceEdges(const ::SMESH::ListOfGroups& groups); + SMESH::string_array* GetSourceEdges(); + void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups); + void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups); + + // Get implementation + ::StdMeshers_ImportSource1D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + // Redefined Persistence + virtual char* SaveTo(); + virtual void LoadFrom( const char* theStream ); + virtual void UpdateAsMeshesRestored(); + + private: + SMESH::string_array_var _groupEntries; + std::vector< std::string > _groupIDs; +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx new file mode 100644 index 000000000..35f9d3fb0 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx @@ -0,0 +1,280 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource2D_i.cxx +// Module : SMESH +// +#include "StdMeshers_ImportSource2D_i.hxx" + +#include "SMESH_Gen.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_PythonDump.hxx" +#include "StdMeshers_ObjRefUlils.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +#include CORBA_SERVER_HEADER(SMESH_Group) + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i" ); + myBaseImpl = new ::StdMeshers_ImportSource2D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); + _groupEntries = new SMESH::string_array(); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i() +{ + MESSAGE( "StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i" ); +} + +//============================================================================= +/*! + * SetSourceFaces + */ +//============================================================================= + +void StdMeshers_ImportSource2D_i::SetSourceFaces(const SMESH::ListOfGroups& groups) +{ + MESSAGE( "StdMeshers_ImportSource2D_i::SetSourceFaces" ); + ASSERT( myBaseImpl ); + try + { + std::vector smesh_groups; + std::vector entries; + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < groups.length(); ++i ) + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( groups[i] )) + { + if ( gp_i->GetType() != SMESH::FACE ) + THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM); + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + + SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]); + if ( !so->_is_nil()) + { + CORBA::String_var entry = so->GetID(); + entries.push_back( entry.in() ); + } + } + this->GetImpl()->SetGroups( smesh_groups ); + + _groupEntries = new SMESH::string_array; + _groupEntries->length( entries.size ()); + for ( int i = 0; i < entries.size(); ++i ) + _groupEntries[i] = entries[i].c_str(); + } + catch ( SALOME_Exception& S_ex ) + { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetSourceFaces( " << groups << " )"; +} + +//============================================================================= +/*! + * Return entries of groups + */ +//============================================================================= + +SMESH::string_array* StdMeshers_ImportSource2D_i::GetSourceFaces() +{ + MESSAGE( "StdMeshers_ImportSource2D_i::GetImportSource" ); + SMESH::string_array_var res = new SMESH::string_array( _groupEntries ); + return res._retn(); +} + +//================================================================================ +/*! + * \brief Set to copy mesh and groups + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh, + CORBA::Boolean toCopyGroups) +{ + GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups); + SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( " + << toCopyMesh << ", " << toCopyGroups << " )"; +} + +//================================================================================ +/*! + * \brief Return "to copy mesh and groups" + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh, + CORBA::Boolean& toCopyGroups) +{ + GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups); +} + +//================================================================================ +/*! + * \brief Write parameters in a string + * \retval char* - resulting string + */ +//================================================================================ + +char* StdMeshers_ImportSource2D_i::SaveTo() +{ + std::ostringstream os; + os << " " << _groupEntries->length(); + + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + // entry + os << " " << _groupEntries[i]; + + // id + SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] ); + CORBA::Object_var groupObj; + if ( !groupSO->_is_nil() ) + groupObj = groupSO->GetObject(); + StdMeshers_ObjRefUlils::SaveToStream( groupObj, os ); + } + + myBaseImpl->SaveTo( os ); + + return CORBA::string_dup( os.str().c_str() ); +} + +//================================================================================ +/*! + * \brief Retrieve parameters from the string + * \param theStream - the input string + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::LoadFrom( const char* theStream ) +{ + std::istringstream is( theStream ); + + int nbGroups; + is >> nbGroups; + + _groupEntries = new SMESH::string_array; + _groupEntries->length( nbGroups ); + std::string id, entry; + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + if ( is >> entry ) + _groupEntries[i] = entry.c_str(); + else + { + _groupEntries->length( i ); + is.clear(ios::badbit | is.rdstate()); + break; + } + if ( is >> id ) + _groupIDs.push_back( id ); + else + { + is.clear(ios::badbit | is.rdstate()); + break; + } + } + + myBaseImpl->LoadFrom( is ); +} + +//================================================================================ +/*! + * \brief Retrieve groups by their ids loaded by LoadFrom() + * This is possible only when all meshes are fully loaded + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::UpdateAsMeshesRestored() +{ + std::vector smesh_groups; + for ( unsigned i = 0; i < _groupIDs.size(); ++i ) + { + std::istringstream is( _groupIDs[i].c_str() ); + SMESH::SMESH_GroupBase_var group = + StdMeshers_ObjRefUlils::LoadObjectFromStream( is ); + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( group )) + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + } + GetImpl()->RestoreGroups(smesh_groups); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource2D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_ImportSource2D* StdMeshers_ImportSource2D_i::GetImpl() +{ + MESSAGE( "StdMeshers_ImportSource2D_i::GetImpl" ); + return ( ::StdMeshers_ImportSource2D* )myBaseImpl; +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean StdMeshers_ImportSource2D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} + diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx new file mode 100644 index 000000000..eea15bacd --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx @@ -0,0 +1,74 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource2D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_ImportSource2D_I_HXX_ +#define _SMESH_ImportSource2D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_ImportSource.hxx" + +class SMESH_Gen; + +class STDMESHERS_I_EXPORT StdMeshers_ImportSource2D_i: + public virtual POA_StdMeshers::StdMeshers_ImportSource2D, + public virtual SMESH_Hypothesis_i +{ + public: + // Constructor + StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_ImportSource2D_i(); + + void SetSourceFaces(const ::SMESH::ListOfGroups& groups); + SMESH::string_array* GetSourceFaces(); + void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups); + void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups); + + // Get implementation + ::StdMeshers_ImportSource2D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + // Redefined Persistence + virtual char* SaveTo(); + virtual void LoadFrom( const char* theStream ); + virtual void UpdateAsMeshesRestored(); + + private: + SMESH::string_array_var _groupEntries; + std::vector< std::string > _groupIDs; +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx new file mode 100644 index 000000000..104b7773b --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D2D_i.cxx +// Module : SMESH +// +#include "StdMeshers_Import_1D2D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + + +//============================================================================= +/*! + * StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i + */ +//============================================================================= + +StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_2D_Algo_i( thePOA ) +{ + MESSAGE( "StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i" ); + myBaseImpl = new ::StdMeshers_Import_1D2D(theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//----------------------------------------------------------------------------- + +StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i() +{ + MESSAGE( "StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i" ); +} + +//----------------------------------------------------------------------------- + +::StdMeshers_Import_1D2D* StdMeshers_Import_1D2D_i::GetImpl() +{ + MESSAGE( "StdMeshers_Import_1D2D_i::GetImpl" ); + return ( ::StdMeshers_Import_1D2D* )myBaseImpl; +} + diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx new file mode 100644 index 000000000..150f5aa3a --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D2D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_Import_1D2D_I_HXX_ +#define _SMESH_Import_1D2D_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_2D_Algo_i.hxx" +#include "StdMeshers_Import_1D2D.hxx" + +class SMESH_Gen; + +class StdMeshers_Import_1D2D_i: + public virtual POA_StdMeshers::StdMeshers_Import_1D2D, + public virtual SMESH_2D_Algo_i +{ +public: + // Constructor + StdMeshers_Import_1D2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + + // Destructor + virtual ~StdMeshers_Import_1D2D_i(); + + // Get implementation + ::StdMeshers_Import_1D2D* GetImpl(); +}; + + +#endif diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx new file mode 100644 index 000000000..2a73e4e2e --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx @@ -0,0 +1,85 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D_i.cxx +// Moved here from SMESH_Import_1D_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// +#include "StdMeshers_Import_1D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_Import_1D_i::StdMeshers_Import_1D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_Import_1D_i::StdMeshers_Import_1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_1D_Algo_i( thePOA ) +{ + MESSAGE( "StdMeshers_Import_1D_i::StdMeshers_Import_1D_i" ); + myBaseImpl = new ::StdMeshers_Import_1D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i() +{ + MESSAGE( "StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i" ); +} + +//============================================================================= +/*! + * StdMeshers_Import_1D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_Import_1D* StdMeshers_Import_1D_i::GetImpl() +{ + MESSAGE( "StdMeshers_Import_1D_i::GetImpl" ); + return ( ::StdMeshers_Import_1D* )myBaseImpl; +} + diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx new file mode 100644 index 000000000..eec55f242 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_Import_1D_I_HXX_ +#define _SMESH_Import_1D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_1D_Algo_i.hxx" +#include "StdMeshers_Import_1D.hxx" + +class STDMESHERS_I_EXPORT StdMeshers_Import_1D_i: + public virtual POA_StdMeshers::StdMeshers_Import_1D, + public virtual SMESH_1D_Algo_i +{ + public: + // Constructor + StdMeshers_Import_1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_Import_1D_i(); + + // Get implementation + ::StdMeshers_Import_1D* GetImpl(); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.cxx b/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.cxx new file mode 100644 index 000000000..5fd33f413 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.cxx @@ -0,0 +1,90 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes +// File : StdMeshers_LayerDistribution2D_i.cxx +// Author : Edward AGAPOV +// Module : SMESH +// +#include "StdMeshers_LayerDistribution2D_i.hxx" + +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_LayerDistribution2D_i::StdMeshers_LayerDistribution2D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_LayerDistribution2D_i::StdMeshers_LayerDistribution2D_i + (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) +: StdMeshers_LayerDistribution_i(thePOA,theStudyId,theGenImpl), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_LayerDistribution2D_i::StdMeshers_LayerDistribution2D_i" ); + myBaseImpl = new ::StdMeshers_LayerDistribution2D(theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//============================================================================= +/*! + * StdMeshers_LayerDistribution2D_i::~StdMeshers_LayerDistribution2D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_LayerDistribution2D_i::~StdMeshers_LayerDistribution2D_i() +{ + MESSAGE("StdMeshers_LayerDistribution2D_i::~StdMeshers_LayerDistribution2D_i"); +} + +//============================================================================= +/*! + * StdMeshers_LayerDistribution2D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_LayerDistribution2D* StdMeshers_LayerDistribution2D_i::GetImpl() +{ + return ( ::StdMeshers_LayerDistribution2D* )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_LayerDistribution2D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} + + diff --git a/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.hxx b/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.hxx new file mode 100644 index 000000000..25acd65ce --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.hxx @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_LayerDistribution2D_i.hxx +// Author : Edward AGAPOV +// Module : SMESH +// +#ifndef _SMESH_LayerDistribution2D_I_HXX_ +#define _SMESH_LayerDistribution2D_I_HXX_ + +#include "StdMeshers_LayerDistribution_i.hxx" +#include "StdMeshers_LayerDistribution2D.hxx" + + +// ========================================================= +/*! + * This hypothesis is used by "Radial quadrangle" algorithm. + * It specifies 1D hypothesis defining distribution of segments + * between the internal and the external surfaces. + */ +// ========================================================= + +class StdMeshers_LayerDistribution2D_i: + public virtual POA_StdMeshers::StdMeshers_LayerDistribution2D, + public virtual StdMeshers_LayerDistribution_i +{ +public: + // Constructor + StdMeshers_LayerDistribution2D_i(PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_LayerDistribution2D_i(); + + // Get implementation + ::StdMeshers_LayerDistribution2D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_LayerDistribution_i.cxx b/src/StdMeshers_I/StdMeshers_LayerDistribution_i.cxx index 53707613c..e162f22aa 100644 --- a/src/StdMeshers_I/StdMeshers_LayerDistribution_i.cxx +++ b/src/StdMeshers_I/StdMeshers_LayerDistribution_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_LayerDistribution_i.cxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #include "StdMeshers_LayerDistribution_i.hxx" #include "SMESH_Gen_i.hxx" @@ -168,9 +168,9 @@ char* StdMeshers_LayerDistribution_i::SaveTo() else { os << hyp1D->GetName() << " " << hyp1D->GetLibName() << " " - << hyp1D_i->SaveTo(); + << hyp1D_i->SaveTo() << " "; } - //myBaseImpl->SaveTo( os ); + os << SMESH_Hypothesis_i::SaveTo(); // to have a mark of storage version ("VARS...") return CORBA::string_dup( os.str().c_str() ); } @@ -200,11 +200,14 @@ void StdMeshers_LayerDistribution_i::LoadFrom( const char* theStream ) gen->CreateHypothesis( typeName.c_str(), libName.c_str() ); SMESH_Hypothesis_i* hyp1D_i = SMESH::DownCast< SMESH_Hypothesis_i*>( hyp1D ); if ( hyp1D_i ) { - hyp1D_i->LoadFrom( & theStream[ is.tellg() ]); + hyp1D_i->LoadFrom( & theStream[ (streamoff) is.tellg()+1 ]); this->GetImpl()->SetLayerDistribution( hyp1D_i->GetImpl() ); myHyp = hyp1D; // as hyp1D is not published, its ID changes //SMESH::TPythonDump() << _this() << ".SetLayerDistribution( " << hyp1D << " )"; + + // restore a mark of storage version ("VARS...") + SMESH_Hypothesis_i::LoadFrom( & theStream[ (streamoff)is.tellg()+1 ]); } } catch (...) { @@ -213,3 +216,14 @@ void StdMeshers_LayerDistribution_i::LoadFrom( const char* theStream ) } } +//================================================================================ +/*! + * \brief Restore myMethod2VarParams by parameters stored in an old study + */ +//================================================================================ + +void StdMeshers_LayerDistribution_i::setOldParameters (const char* theParameters) +{ + if ( SMESH_Hypothesis_i* hyp1D_i = SMESH::DownCast< SMESH_Hypothesis_i*>( myHyp )) + hyp1D_i->setOldParameters( theParameters ); +} diff --git a/src/StdMeshers_I/StdMeshers_LayerDistribution_i.hxx b/src/StdMeshers_I/StdMeshers_LayerDistribution_i.hxx index f08a9d7ef..78bf71d5a 100644 --- a/src/StdMeshers_I/StdMeshers_LayerDistribution_i.hxx +++ b/src/StdMeshers_I/StdMeshers_LayerDistribution_i.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_LayerDistribution_i.hxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #ifndef _SMESH_LayerDistribution_I_HXX_ #define _SMESH_LayerDistribution_I_HXX_ @@ -79,9 +79,12 @@ public: virtual char* SaveTo(); virtual void LoadFrom( const char* theStream ); +protected: + // restore myMethod2VarParams by parameters stored in an old study + virtual void setOldParameters (const char* theParameters); + private: SMESH::SMESH_Hypothesis_var myHyp; }; #endif - diff --git a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx index 0d78830d6..324a9b064 100644 --- a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx +++ b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_LengthFromEdges_i.cxx // Moved here from SMESH_LengthFromEdges_i.cxx @@ -43,15 +44,15 @@ using namespace std; //============================================================================= StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) + int theStudyId, + ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { MESSAGE( "StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i" ); myBaseImpl = new ::StdMeshers_LengthFromEdges( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= @@ -85,7 +86,7 @@ void StdMeshers_LengthFromEdges_i::SetMode( CORBA::Long theMode ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } } diff --git a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx index 77ebc48ad..38f50d3df 100644 --- a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx +++ b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_LengthFromEdges_i.hxx // Moved here from SMESH_LengthFromEdges_i.hxx diff --git a/src/StdMeshers_I/StdMeshers_LocalLength_i.cxx b/src/StdMeshers_I/StdMeshers_LocalLength_i.cxx index fdc8c1c27..5d6ec1b51 100644 --- a/src/StdMeshers_I/StdMeshers_LocalLength_i.cxx +++ b/src/StdMeshers_I/StdMeshers_LocalLength_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_LocalLength_i.cxx // Moved here from SMESH_LocalLength_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_LocalLength_i.hxx" #include "SMESH_Gen_i.hxx" @@ -88,11 +88,11 @@ void StdMeshers_LocalLength_i::SetLength( CORBA::Double theLength ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )"; + SMESH::TPythonDump() << _this() << ".SetLength( " << SMESH::TVar(theLength) << " )"; } //============================================================================= @@ -112,11 +112,11 @@ void StdMeshers_LocalLength_i::SetPrecision( CORBA::Double thePrecision ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetPrecision( " << thePrecision << " )"; + SMESH::TPythonDump() << _this() << ".SetPrecision( " << SMESH::TVar(thePrecision) << " )"; } //============================================================================= @@ -173,3 +173,9 @@ CORBA::Boolean StdMeshers_LocalLength_i::IsDimSupported( SMESH::Dimension type ) { return type == SMESH::DIM_1D; } + +std::string StdMeshers_LocalLength_i::getMethodOfParameter(const int paramIndex, + int /*nbVars*/) const +{ + return paramIndex == 0 ? "SetLength" : "SetPrecision"; +} diff --git a/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx b/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx index e31b08ece..dd2b239e1 100644 --- a/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx +++ b/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_LocalLength_i.hxx // Moved here from SMESH_LocalLength_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_LOCALLENGTH_I_HXX_ #define _SMESH_LOCALLENGTH_I_HXX_ @@ -71,6 +71,9 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx index 4731e8888..5eb244e89 100644 --- a/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MEFISTO_2D_i.cxx // Moved here from SMESH_MEFISTO_2D_i.cxx @@ -43,8 +44,8 @@ using namespace std; //============================================================================= StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_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 ), @@ -52,8 +53,8 @@ StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA { MESSAGE( "StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i" ); myBaseImpl = new ::StdMeshers_MEFISTO_2D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= diff --git a/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx index f368c76c5..3700c7cea 100644 --- a/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MEFISTO_2D_i.hxx // Moved here from SMESH_MEFISTO_2D_i.hxx @@ -50,7 +51,7 @@ public: // Constructor StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~StdMeshers_MEFISTO_2D_i(); diff --git a/src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx index 8a8169135..7af8090bc 100644 --- a/src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx +++ b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MaxElementArea_i.cxx // Moved here from SMESH_MaxElementArea_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_MaxElementArea_i.hxx" #include "SMESH_Gen_i.hxx" @@ -47,15 +47,15 @@ using namespace std; //============================================================================= StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) + int theStudyId, + ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { MESSAGE( "StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i" ); myBaseImpl = new ::StdMeshers_MaxElementArea( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= @@ -89,11 +89,11 @@ void StdMeshers_MaxElementArea_i::SetMaxElementArea( CORBA::Double theArea ) } catch (SALOME_Exception& S_ex) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetMaxElementArea( " << theArea << " )"; + SMESH::TPythonDump() << _this() << ".SetMaxElementArea( " << SMESH::TVar(theArea) << " )"; } //============================================================================= @@ -139,3 +139,14 @@ CORBA::Boolean StdMeshers_MaxElementArea_i::IsDimSupported( SMESH::Dimension typ return type == SMESH::DIM_2D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_MaxElementArea_i::getMethodOfParameter(const int paramIndex, + int /*nbVars*/) const +{ + return "SetMaxElementArea"; +} diff --git a/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx index 199c4bb4b..51e6033b9 100644 --- a/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx +++ b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MaxElementArea_i.hxx // Moved here from SMESH_MaxElementArea_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_MAXELEMENTAREA_I_HXX_ #define _SMESH_MAXELEMENTAREA_I_HXX_ @@ -48,7 +48,7 @@ public: // Constructor StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~StdMeshers_MaxElementArea_i(); @@ -63,6 +63,9 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx index 7ee1eefdc..a9e8b657d 100644 --- a/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx +++ b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MaxElementVolume_i.cxx // Moved here from SMESH_MaxElementVolume_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_MaxElementVolume_i.hxx" #include "SMESH_Gen_i.hxx" @@ -47,15 +47,15 @@ using namespace std; //============================================================================= StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) + int theStudyId, + ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { MESSAGE( "StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i" ); myBaseImpl = new ::StdMeshers_MaxElementVolume( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= @@ -89,11 +89,11 @@ void StdMeshers_MaxElementVolume_i::SetMaxElementVolume( CORBA::Double theVolume } catch (SALOME_Exception& S_ex) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetMaxElementVolume( " << theVolume << " )"; + SMESH::TPythonDump() << _this() << ".SetMaxElementVolume( " << SMESH::TVar(theVolume) << " )"; } //============================================================================= @@ -139,3 +139,13 @@ CORBA::Boolean StdMeshers_MaxElementVolume_i::IsDimSupported( SMESH::Dimension t return type == SMESH::DIM_3D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_MaxElementVolume_i::getMethodOfParameter(const int, int) const +{ + return "SetMaxElementVolume"; +} diff --git a/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx index a01df5444..829097c4d 100644 --- a/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx +++ b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MaxElementVolume_i.hxx // Moved here from SMESH_MaxElementVolume_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_MAXELEMENTVOLUME_I_HXX_ #define _SMESH_MAXELEMENTVOLUME_I_HXX_ @@ -63,6 +63,9 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_MaxLength_i.cxx b/src/StdMeshers_I/StdMeshers_MaxLength_i.cxx index bbed6c448..5ce5b34f9 100644 --- a/src/StdMeshers_I/StdMeshers_MaxLength_i.cxx +++ b/src/StdMeshers_I/StdMeshers_MaxLength_i.cxx @@ -1,27 +1,26 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 // + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MaxLength_i.cxx // Module : SMESH - +// #include "StdMeshers_MaxLength_i.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Gen.hxx" @@ -81,11 +80,11 @@ void StdMeshers_MaxLength_i::SetLength( CORBA::Double theLength ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )"; + SMESH::TPythonDump() << _this() << ".SetLength( " << SMESH::TVar(theLength) << " )"; } //============================================================================= @@ -102,7 +101,7 @@ void StdMeshers_MaxLength_i::SetUsePreestimatedLength( CORBA::Boolean toUse ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // this is an internal kitchen call - no Python dump @@ -123,7 +122,7 @@ void StdMeshers_MaxLength_i::SetPreestimatedLength( CORBA::Double theLength ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // this is an internal kitchen call - no Python dump // Update Python script @@ -202,3 +201,14 @@ CORBA::Boolean StdMeshers_MaxLength_i::IsDimSupported( SMESH::Dimension type ) { return type == SMESH::DIM_1D; } + +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_MaxLength_i::getMethodOfParameter(const int, int) const +{ + return "SetLength"; +} diff --git a/src/StdMeshers_I/StdMeshers_MaxLength_i.hxx b/src/StdMeshers_I/StdMeshers_MaxLength_i.hxx index 715da7a23..f088f7895 100644 --- a/src/StdMeshers_I/StdMeshers_MaxLength_i.hxx +++ b/src/StdMeshers_I/StdMeshers_MaxLength_i.hxx @@ -1,27 +1,26 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 // + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_MaxLength_i.hxx // Module : SMESH - +// #ifndef _SMESH_MaxLength_I_HXX_ #define _SMESH_MaxLength_I_HXX_ @@ -78,6 +77,9 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx index 59f13b891..78831a397 100644 --- a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx +++ b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_NotConformAllowed_i.cxx // Author : Paul RASCLE, EDF diff --git a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx index be9f764c2..862baae57 100644 --- a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx +++ b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_NotConformAllowed_i.hxx // Author : Paul RASCLE, EDF diff --git a/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.cxx new file mode 100644 index 000000000..e4e5a1ecf --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.cxx @@ -0,0 +1,88 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes +// File : StdMeshers_NumberOfLayers2D_i.cxx +// Author : Edward AGAPOV +// Module : SMESH +// +#include "StdMeshers_NumberOfLayers2D_i.hxx" + +#include "utilities.h" + +//============================================================================= +/*! + * StdMeshers_NumberOfLayers2D_i::StdMeshers_NumberOfLayers2D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_NumberOfLayers2D_i::StdMeshers_NumberOfLayers2D_i + (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) +: StdMeshers_NumberOfLayers_i(thePOA,theStudyId,theGenImpl), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE("StdMeshers_NumberOfLayers2D_i::StdMeshers_NumberOfLayers2D_i"); + myBaseImpl = new ::StdMeshers_NumberOfLayers2D(theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//============================================================================= +/*! + * StdMeshers_NumberOfLayers2D_i::~StdMeshers_NumberOfLayers2D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_NumberOfLayers2D_i::~StdMeshers_NumberOfLayers2D_i() +{ + MESSAGE( "StdMeshers_NumberOfLayers2D_i::~StdMeshers_NumberOfLayers2D_i" ); +} + +//============================================================================= +/*! + * StdMeshers_NumberOfLayers2D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_NumberOfLayers2D* StdMeshers_NumberOfLayers2D_i::GetImpl() +{ + return ( ::StdMeshers_NumberOfLayers2D* )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_NumberOfLayers2D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} diff --git a/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.hxx b/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.hxx new file mode 100644 index 000000000..ae684594d --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.hxx @@ -0,0 +1,58 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_NumberOfLayers2D_i.hxx +// Author : Edward AGAPOV +// Module : SMESH +// +#ifndef _SMESH_NumberOfLayers2D_I_HXX_ +#define _SMESH_NumberOfLayers2D_I_HXX_ + +#include "StdMeshers_NumberOfLayers2D.hxx" +#include "StdMeshers_NumberOfLayers_i.hxx" + +// ========================================================= +/*! + * This hypothesis is used by "Radial quadrangle" algorithm. + * It specifies number of segments between the internal + * and the external surfaces. + */ +// ========================================================= + +class StdMeshers_NumberOfLayers2D_i: + public virtual POA_StdMeshers::StdMeshers_NumberOfLayers2D, + public virtual StdMeshers_NumberOfLayers_i +{ +public: + // Constructor + StdMeshers_NumberOfLayers2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_NumberOfLayers2D_i(); + + // Get implementation + ::StdMeshers_NumberOfLayers2D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.cxx index 9779cfbdb..8c12ab727 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_NumberOfLayers_i.cxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #include "StdMeshers_NumberOfLayers_i.hxx" #include "SMESH_Gen_i.hxx" @@ -89,7 +89,7 @@ void StdMeshers_NumberOfLayers_i::SetNumberOfLayers(CORBA::Long numberOfLayers) THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetNumberOfLayers( " << numberOfLayers << " )"; + SMESH::TPythonDump() << _this() << ".SetNumberOfLayers( " << SMESH::TVar(numberOfLayers) << " )"; } //============================================================================= @@ -133,3 +133,13 @@ CORBA::Boolean StdMeshers_NumberOfLayers_i::IsDimSupported( SMESH::Dimension typ return type == SMESH::DIM_3D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_NumberOfLayers_i::getMethodOfParameter(const int, int) const +{ + return "SetNumberOfLayers"; +} diff --git a/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.hxx b/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.hxx index 3d926b03b..cf8b1bcb2 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.hxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfLayers_i.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_NumberOfLayers_i.hxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #ifndef _SMESH_NumberOfLayers_I_HXX_ #define _SMESH_NumberOfLayers_I_HXX_ @@ -68,7 +68,9 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif - diff --git a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx index 7b2d215a5..d0195c9a7 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_NumberOfSegments_i.cxx // Moved here from SMESH_NumberOfSegments_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_NumberOfSegments_i.hxx" #include "SMESH_Gen_i.hxx" @@ -46,15 +46,15 @@ using namespace std; //============================================================================= StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) + int theStudyId, + ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { MESSAGE( "StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i" ); myBaseImpl = new ::StdMeshers_NumberOfSegments( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= @@ -78,8 +78,8 @@ StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i() */ //============================================================================= SMESH::double_array* StdMeshers_NumberOfSegments_i::BuildDistributionExpr( const char* func, - CORBA::Long nbSeg, - CORBA::Long conv ) + CORBA::Long nbSeg, + CORBA::Long conv ) throw ( SALOME::SALOME_Exception ) { ASSERT( myBaseImpl ); @@ -99,8 +99,8 @@ SMESH::double_array* StdMeshers_NumberOfSegments_i::BuildDistributionExpr( const } SMESH::double_array* StdMeshers_NumberOfSegments_i::BuildDistributionTab( const SMESH::double_array& func, - CORBA::Long nbSeg, - CORBA::Long conv ) + CORBA::Long nbSeg, + CORBA::Long conv ) throw ( SALOME::SALOME_Exception ) { ASSERT( myBaseImpl ); @@ -141,11 +141,11 @@ void StdMeshers_NumberOfSegments_i::SetNumberOfSegments( CORBA::Long theSegments } catch (SALOME_Exception& S_ex) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetNumberOfSegments( " << theSegmentsNumber << " )"; + SMESH::TPythonDump() << _this() << ".SetNumberOfSegments( " << SMESH::TVar(theSegmentsNumber) << " )"; } //============================================================================= @@ -162,6 +162,101 @@ CORBA::Long StdMeshers_NumberOfSegments_i::GetNumberOfSegments() return this->GetImpl()->GetNumberOfSegments(); } +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::SetReversedEdges + * + * Set edges to reverse + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetReversedEdges( const SMESH::long_array& theIds ) +{ + ASSERT( myBaseImpl ); + try { + std::vector ids( theIds.length() ); + CORBA::Long iEnd = theIds.length(); + for ( CORBA::Long i = 0; i < iEnd; i++ ) + ids[ i ] = theIds[ i ]; + + this->GetImpl()->SetReversedEdges( ids ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )"; +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::SetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetObjectEntry( const char* theEntry ) +{ + ASSERT( myBaseImpl ); + string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping + try { + this->GetImpl()->SetObjectEntry( entry.c_str() ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + // Update Python script + SMESH::TPythonDump() << _this() << ".SetObjectEntry( \"" << entry.c_str() << "\" )"; +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::GetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +char* StdMeshers_NumberOfSegments_i::GetObjectEntry() +{ + ASSERT( myBaseImpl ); + + const char* entry; + try { + entry = this->GetImpl()->GetObjectEntry(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return CORBA::string_dup( entry ); +} + +//============================================================================= +/*! + * StdMeshers_NumberOfSegments_i::GetReversedEdges + * + * Get reversed edges + */ +//============================================================================= + +SMESH::long_array* StdMeshers_NumberOfSegments_i::GetReversedEdges() +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::GetReversedEdges" ); + ASSERT( myBaseImpl ); + SMESH::long_array_var anArray = new SMESH::long_array; + std::vector ids = this->GetImpl()->GetReversedEdges(); + anArray->length( ids.size() ); + for ( CORBA::Long i = 0; i < ids.size(); i++) + anArray [ i ] = ids [ i ]; + + return anArray._retn(); +} + //============================================================================= /*! */ @@ -179,7 +274,7 @@ void StdMeshers_NumberOfSegments_i::SetDistrType(CORBA::Long typ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } } @@ -209,11 +304,11 @@ void StdMeshers_NumberOfSegments_i::SetScaleFactor( CORBA::Double theScaleFactor try { this->GetImpl()->SetScaleFactor( theScaleFactor ); // Update Python script - SMESH::TPythonDump() << _this() << ".SetScaleFactor( " << theScaleFactor << " )"; + SMESH::TPythonDump() << _this() << ".SetScaleFactor( " << SMESH::TVar(theScaleFactor) << " )"; } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } } @@ -235,7 +330,7 @@ CORBA::Double StdMeshers_NumberOfSegments_i::GetScaleFactor() } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } return scale; } @@ -259,7 +354,7 @@ void StdMeshers_NumberOfSegments_i::SetTableFunction(const SMESH::double_array& } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } } @@ -278,7 +373,7 @@ SMESH::double_array* StdMeshers_NumberOfSegments_i::GetTableFunction() } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } SMESH::double_array_var aRes = new SMESH::double_array(); aRes->length(tbl->size()); @@ -303,7 +398,7 @@ void StdMeshers_NumberOfSegments_i::SetExpressionFunction(const char* expr) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } } @@ -322,7 +417,7 @@ char* StdMeshers_NumberOfSegments_i::GetExpressionFunction() } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } return CORBA::string_dup(expr); } @@ -343,7 +438,7 @@ void StdMeshers_NumberOfSegments_i::SetConversionMode(CORBA::Long conv ) } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } } @@ -362,7 +457,7 @@ CORBA::Long StdMeshers_NumberOfSegments_i::ConversionMode() } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } return conv; } @@ -394,3 +489,13 @@ CORBA::Boolean StdMeshers_NumberOfSegments_i::IsDimSupported( SMESH::Dimension t return type == SMESH::DIM_1D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_NumberOfSegments_i::getMethodOfParameter(const int paramIndex, int ) const +{ + return paramIndex == 0 ? "SetNumberOfSegments" : "SetScaleFactor"; +} diff --git a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx index 208a59b0b..3745a736c 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_NumberOfSegments_i.hxx // Moved here from SMESH_NumberOfSegments_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_NUMBEROFSEGMENTS_I_HXX_ #define _SMESH_NUMBEROFSEGMENTS_I_HXX_ @@ -49,7 +49,7 @@ public: // Constructor StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~StdMeshers_NumberOfSegments_i(); @@ -104,6 +104,21 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + //Set Reversed Edges + void SetReversedEdges( const SMESH::long_array& theIDs); + + //Get Reversed Edges + SMESH::long_array* GetReversedEdges(); + + //Set Object Entry + void SetObjectEntry( const char* entry); + + //Get Object Entry + char* GetObjectEntry(); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_ObjRefUlils.cxx b/src/StdMeshers_I/StdMeshers_ObjRefUlils.cxx index 53330557b..910d0aaa8 100644 --- a/src/StdMeshers_I/StdMeshers_ObjRefUlils.cxx +++ b/src/StdMeshers_I/StdMeshers_ObjRefUlils.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_ObjRefUlils.cxx // Created : Wed Oct 18 15:38:22 2006 @@ -30,6 +31,47 @@ using namespace std; +//======================================================================= +//function : GeomObjectToEntry +//purpose : Return study entry of GEOM Object +//======================================================================= + +std::string StdMeshers_ObjRefUlils::GeomObjectToEntry(GEOM::GEOM_Object_ptr& theGeomObject) +{ + if ( CORBA::is_nil( theGeomObject )) + return "NULL_OBJECT"; + + CORBA::String_var entry = theGeomObject->GetStudyEntry(); + return entry.in(); +} + +//======================================================================= +//function : EntryOrShapeToGeomObject +//purpose : Return GEOM Object by its sytudy entry or TopoDS_Shape +//======================================================================= + +GEOM::GEOM_Object_ptr +StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject (const std::string& theEntry, + const TopoDS_Shape& theShape) +{ + GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_nil(); + + // try by entry + if (SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen()) { + SALOMEDS::Study_var study = gen->GetCurrentStudy(); + if ( ! theEntry.empty() && ! study->_is_nil() ) { + SALOMEDS::SObject_var sobj= study->FindObjectID( theEntry.c_str() ); + CORBA::Object_var obj = gen->SObjectToObject( sobj ); + geom = GEOM::GEOM_Object::_narrow( obj ); + } + } + // try by TopoDS_Shape + if ( geom->_is_nil() ) + geom = ShapeToGeomObject( theShape ); + + return geom._retn(); +} + //================================================================================ /*! * \brief Store the shape in the stream @@ -103,3 +145,17 @@ void StdMeshers_ObjRefUlils::SaveToStream( CORBA::Object_ptr obj, if ( ! ok ) stream << " NULL_OBJECT "; } + +//======================================================================= +//function : SaveToStream +//purpose : Store the study entry of object in the stream +//======================================================================= + +void StdMeshers_ObjRefUlils::SaveToStream( const std::string& studyEntry, + std::ostream & stream) +{ + if ( studyEntry.find_first_not_of( ' ' ) == std::string::npos ) + stream << " NULL_OBJECT "; + else + stream << " " << studyEntry; +} diff --git a/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx b/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx index 4556810cf..2f13689c1 100644 --- a/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx +++ b/src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_ObjRefUlils.hxx // Created : Wed Oct 18 15:15:27 2006 @@ -64,6 +65,18 @@ public: return TopoDS_Shape(); } + /*! + * \brief Return study entry of GEOM Object + */ + static std::string GeomObjectToEntry(GEOM::GEOM_Object_ptr& theGeomObject); + + /*! + * \brief Return GEOM Object by its study entry or TopoDS_Shape + */ + static GEOM::GEOM_Object_ptr EntryOrShapeToGeomObject (const std::string& theEntry, + const TopoDS_Shape& theShape); + + /*! * \brief Store the shape in the stream * \param theShape - shape to store @@ -76,14 +89,14 @@ public: * \param stream - the stream * \retval TopoDS_Shape - resulting shape */ - static TopoDS_Shape LoadFromStream( std::istream & stream); + static TopoDS_Shape LoadFromStream( std::istream & stream ); /*! * \brief Store the CORBA object in the stream * \param obj - object to store * \param stream - the stream */ - static void SaveToStream( CORBA::Object_ptr obj, std::ostream & stream); + static void SaveToStream( CORBA::Object_ptr obj, std::ostream & stream ); /*! * \brief Retrieve a CORBA object from the stream @@ -106,6 +119,14 @@ public: } return TInterface::_nil(); } + + /*! + * \brief Store the study entry of object in the stream + * \param studyEntry - the study entry + * \param stream - the stream + */ + static void SaveToStream( const std::string& studyEntry, std::ostream & stream); + }; #endif diff --git a/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx index f6e2a3f70..4daffc4a4 100644 --- a/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Prism_3D_i.cxx // Moved here from SMESH_Prism_3D_i.cxx @@ -41,8 +42,8 @@ using namespace std; //============================================================================= StdMeshers_Prism_3D_i::StdMeshers_Prism_3D_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 ), @@ -75,8 +76,8 @@ StdMeshers_Prism_3D_i::~StdMeshers_Prism_3D_i() //============================================================================= StdMeshers_RadialPrism_3D_i::StdMeshers_RadialPrism_3D_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 ), @@ -84,8 +85,8 @@ StdMeshers_RadialPrism_3D_i::StdMeshers_RadialPrism_3D_i( PortableServer::POA_pt { MESSAGE( "StdMeshers_RadialPrism_3D_i::StdMeshers_RadialPrism_3D_i" ); myBaseImpl = new ::StdMeshers_RadialPrism_3D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //----------------------------------------------------------------------------- diff --git a/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx index fc09a08db..c7d179c09 100644 --- a/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Prism_3D_i.hxx // Moved here from SMESH_Prism_3D_i.hxx diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx index 62d7d7af7..092e9b451 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_ProjectionSource1D_i.cxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #include "StdMeshers_ProjectionSource1D_i.hxx" @@ -83,6 +83,8 @@ void StdMeshers_ProjectionSource1D_i::SetSourceEdge(GEOM::GEOM_Object_ptr edge) ASSERT( myBaseImpl ); try { this->GetImpl()->SetSourceEdge( StdMeshers_ObjRefUlils::GeomObjectToShape( edge )); + CORBA::String_var entry = edge->GetStudyEntry(); + myShapeEntries[ SRC_EDGE ] = entry.in(); } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); @@ -107,6 +109,9 @@ void StdMeshers_ProjectionSource1D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr TopoDS_Shape v1 = StdMeshers_ObjRefUlils::GeomObjectToShape( sourceVertex ); TopoDS_Shape v2 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex ); this->GetImpl()->SetVertexAssociation( v1, v2 ); + + myShapeEntries[ SRC_VERTEX ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex ); + myShapeEntries[ TGT_VERTEX ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex ); } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); @@ -171,7 +176,9 @@ SMESH::SMESH_Mesh_ptr StdMeshers_ProjectionSource1D_i::GetSourceMesh() GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceEdge() { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceEdge() ); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ SRC_EDGE ], + this->GetImpl()->GetSourceEdge() ); } //============================================================================= @@ -184,7 +191,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceEdge() GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceVertex() { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceVertex() ); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ SRC_VERTEX ], + this->GetImpl()->GetSourceVertex() ); } //============================================================================= @@ -197,7 +206,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceVertex() GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetTargetVertex() { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetTargetVertex() ); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ TGT_VERTEX ], + this->GetImpl()->GetTargetVertex() ); } //============================================================================= @@ -239,12 +250,8 @@ char* StdMeshers_ProjectionSource1D_i::SaveTo() ASSERT( myBaseImpl ); std::ostringstream os; - TopoDS_Shape s1, s2, s3; - GetImpl()->GetStoreParams( s1, s2, s3 ); - - StdMeshers_ObjRefUlils::SaveToStream( s1, os ); - StdMeshers_ObjRefUlils::SaveToStream( s2, os ); - StdMeshers_ObjRefUlils::SaveToStream( s3, os ); + for ( int i = 0; i < NB_SHAPES; ++i ) + StdMeshers_ObjRefUlils::SaveToStream( myShapeEntries[ i ], os ); StdMeshers_ObjRefUlils::SaveToStream( GetSourceMesh(), os ); myBaseImpl->SaveTo( os ); @@ -264,9 +271,9 @@ void StdMeshers_ProjectionSource1D_i::LoadFrom( const char* theStream ) ASSERT( myBaseImpl ); std::istringstream is( theStream ); - TopoDS_Shape s1 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s2 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s3 = StdMeshers_ObjRefUlils::LoadFromStream( is ); + TopoDS_Shape shapes[ NB_SHAPES ]; + for ( int i = 0; i < NB_SHAPES; ++i ) + shapes[ i ] = StdMeshers_ObjRefUlils::LoadFromStream( is ); SMESH::SMESH_Mesh_var mesh = StdMeshers_ObjRefUlils::LoadObjectFromStream< SMESH::SMESH_Mesh >( is ); @@ -280,8 +287,15 @@ void StdMeshers_ProjectionSource1D_i::LoadFrom( const char* theStream ) } myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh ); - GetImpl()->RestoreParams( s1, s2, s3, meshImpl ); + GetImpl()->SetSourceMesh ( meshImpl ); + GetImpl()->SetSourceEdge ( shapes[ SRC_EDGE ] ); + GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX ], + shapes[ TGT_VERTEX ]); myBaseImpl->LoadFrom( is ); + + std::istringstream str( theStream ); + for ( int i = 0; i < NB_SHAPES; ++i ) + str >> myShapeEntries[ i ]; } diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx index f73d75762..7326d3730 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionSource1D_i.hxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #ifndef _SMESH_ProjectionSource1D_I_HXX_ #define _SMESH_ProjectionSource1D_I_HXX_ @@ -111,6 +111,11 @@ public: virtual void LoadFrom( const char* theStream ); private: + // keep entries because the same shape can be published several times with + // different names and in this case a correct name can't be restored by a TopoDS_Shape + // kept by ::StdMeshers_ProjectionSource1D + enum { SRC_EDGE=0, SRC_VERTEX, TGT_VERTEX, NB_SHAPES }; + std::string myShapeEntries[NB_SHAPES]; SMESH::SMESH_Mesh_var myCorbaMesh; }; diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx b/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx index 6186a7b04..2c14db459 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_ProjectionSource2D_i.cxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #include "StdMeshers_ProjectionSource2D_i.hxx" @@ -83,6 +83,8 @@ void StdMeshers_ProjectionSource2D_i::SetSourceFace(GEOM::GEOM_Object_ptr face) ASSERT( myBaseImpl ); try { this->GetImpl()->SetSourceFace( StdMeshers_ObjRefUlils::GeomObjectToShape( face )); + CORBA::String_var entry = face->GetStudyEntry(); + myShapeEntries[ SRC_FACE ] = entry.in(); } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); @@ -158,6 +160,11 @@ void StdMeshers_ProjectionSource2D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr TopoDS_Shape v3 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex1 ); TopoDS_Shape v4 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex2 ); this->GetImpl()->SetVertexAssociation( v1, v2, v3, v4 ); + + myShapeEntries[ SRC_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex1 ); + myShapeEntries[ SRC_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex2 ); + myShapeEntries[ TGT_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex1 ); + myShapeEntries[ TGT_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex2 ); } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); @@ -179,7 +186,9 @@ void StdMeshers_ProjectionSource2D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceFace() { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceFace() ); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ SRC_FACE ], + this->GetImpl()->GetSourceFace() ); } //============================================================================= @@ -192,7 +201,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceFace() GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceVertex(CORBA::Long i) { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceVertex((int) i )); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ i == 1 ? SRC_VERTEX1 : SRC_VERTEX2 ], + this->GetImpl()->GetSourceVertex((int) i )); } //============================================================================= @@ -205,7 +216,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceVertex(CORBA::Lo GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetTargetVertex(CORBA::Long i) { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetTargetVertex( (int)i )); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ i == 1 ? TGT_VERTEX1 : TGT_VERTEX2 ], + this->GetImpl()->GetTargetVertex( (int)i )); } //============================================================================= @@ -247,14 +260,8 @@ char* StdMeshers_ProjectionSource2D_i::SaveTo() ASSERT( myBaseImpl ); std::ostringstream os; - TopoDS_Shape s1, s2, s3, s4, s5; - GetImpl()->GetStoreParams( s1, s2, s3, s4, s5 ); - - StdMeshers_ObjRefUlils::SaveToStream( s1, os ); - StdMeshers_ObjRefUlils::SaveToStream( s2, os ); - StdMeshers_ObjRefUlils::SaveToStream( s3, os ); - StdMeshers_ObjRefUlils::SaveToStream( s4, os ); - StdMeshers_ObjRefUlils::SaveToStream( s5, os ); + for ( int i = 0; i < NB_SHAPES; ++i ) + StdMeshers_ObjRefUlils::SaveToStream( myShapeEntries[ i ], os ); StdMeshers_ObjRefUlils::SaveToStream( GetSourceMesh(), os ); myBaseImpl->SaveTo( os ); @@ -274,11 +281,9 @@ void StdMeshers_ProjectionSource2D_i::LoadFrom( const char* theStream ) ASSERT( myBaseImpl ); std::istringstream is( theStream ); - TopoDS_Shape s1 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s2 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s3 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s4 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s5 = StdMeshers_ObjRefUlils::LoadFromStream( is ); + TopoDS_Shape shapes[ NB_SHAPES ]; + for ( int i = 0; i < NB_SHAPES; ++i ) + shapes[ i ] = StdMeshers_ObjRefUlils::LoadFromStream( is ); SMESH::SMESH_Mesh_var mesh = StdMeshers_ObjRefUlils::LoadObjectFromStream< SMESH::SMESH_Mesh >( is ); @@ -292,8 +297,17 @@ void StdMeshers_ProjectionSource2D_i::LoadFrom( const char* theStream ) } myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh ); - GetImpl()->RestoreParams( s1, s2, s3, s4, s5, meshImpl ); + GetImpl()->SetSourceMesh ( meshImpl ); + GetImpl()->SetSourceFace ( shapes[ SRC_FACE ] ); + GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ], + shapes[ SRC_VERTEX2 ], + shapes[ TGT_VERTEX1 ], + shapes[ TGT_VERTEX2 ]); myBaseImpl->LoadFrom( is ); + + std::istringstream str( theStream ); + for ( int i = 0; i < NB_SHAPES; ++i ) + str >> myShapeEntries[ i ]; } diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.hxx b/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.hxx index 4aa63c7a5..454744439 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.hxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionSource2D_i.hxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #ifndef _SMESH_ProjectionSource2D_I_HXX_ #define _SMESH_ProjectionSource2D_I_HXX_ @@ -93,6 +93,7 @@ public: /*! * Returns the -th source vertex associated with the -th target vertex. * Result may be nil if association not set. + * Valid indices are 1 and 2 */ GEOM::GEOM_Object_ptr GetSourceVertex(CORBA::Long i); @@ -114,8 +115,12 @@ public: virtual void LoadFrom( const char* theStream ); private: + // keep entries because the same shape can be published several times with + // different names and in this case a correct name can't be restored by a TopoDS_Shape + // kept by ::StdMeshers_ProjectionSource2D + enum { SRC_FACE=0, SRC_VERTEX1, SRC_VERTEX2, TGT_VERTEX1, TGT_VERTEX2, NB_SHAPES }; + std::string myShapeEntries[NB_SHAPES]; SMESH::SMESH_Mesh_var myCorbaMesh; }; #endif - diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx b/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx index 5ee44b3fc..ea2a2b31f 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx @@ -1,29 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_ProjectionSource3D_i.cxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #include "StdMeshers_ProjectionSource3D_i.hxx" @@ -83,6 +83,9 @@ void StdMeshers_ProjectionSource3D_i::SetSource3DShape(GEOM::GEOM_Object_ptr sha ASSERT( myBaseImpl ); try { this->GetImpl()->SetSource3DShape( StdMeshers_ObjRefUlils::GeomObjectToShape( shape )); + + CORBA::String_var entry = shape->GetStudyEntry(); + myShapeEntries[ SRC_SHAPE3D ] = entry.in(); } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); @@ -158,6 +161,11 @@ void StdMeshers_ProjectionSource3D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr TopoDS_Shape v3 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex1 ); TopoDS_Shape v4 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex2 ); this->GetImpl()->SetVertexAssociation( v1, v2, v3, v4 ); + + myShapeEntries[ SRC_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex1 ); + myShapeEntries[ SRC_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex2 ); + myShapeEntries[ TGT_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex1 ); + myShapeEntries[ TGT_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex2 ); } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); @@ -179,7 +187,9 @@ void StdMeshers_ProjectionSource3D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSource3DShape() { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSource3DShape() ); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ SRC_SHAPE3D ], + this->GetImpl()->GetSource3DShape() ); } //============================================================================= @@ -192,7 +202,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSource3DShape() GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSourceVertex(CORBA::Long i) { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceVertex((int) i )); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ i == 1 ? SRC_VERTEX1 : SRC_VERTEX2 ], + this->GetImpl()->GetSourceVertex((int) i )); } //============================================================================= @@ -205,7 +217,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSourceVertex(CORBA::Lo GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetTargetVertex(CORBA::Long i) { ASSERT( myBaseImpl ); - return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetTargetVertex( (int)i )); + return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject + ( myShapeEntries[ i == 1 ? TGT_VERTEX1 : TGT_VERTEX2 ], + this->GetImpl()->GetTargetVertex( (int)i )); } //============================================================================= @@ -247,14 +261,8 @@ char* StdMeshers_ProjectionSource3D_i::SaveTo() ASSERT( myBaseImpl ); std::ostringstream os; - TopoDS_Shape s1, s2, s3, s4, s5; - GetImpl()->GetStoreParams( s1, s2, s3, s4, s5 ); - - StdMeshers_ObjRefUlils::SaveToStream( s1, os ); - StdMeshers_ObjRefUlils::SaveToStream( s2, os ); - StdMeshers_ObjRefUlils::SaveToStream( s3, os ); - StdMeshers_ObjRefUlils::SaveToStream( s4, os ); - StdMeshers_ObjRefUlils::SaveToStream( s5, os ); + for ( int i = 0; i < NB_SHAPES; ++i ) + StdMeshers_ObjRefUlils::SaveToStream( myShapeEntries[ i ], os ); StdMeshers_ObjRefUlils::SaveToStream( GetSourceMesh(), os ); myBaseImpl->SaveTo( os ); @@ -274,11 +282,9 @@ void StdMeshers_ProjectionSource3D_i::LoadFrom( const char* theStream ) ASSERT( myBaseImpl ); std::istringstream is( theStream ); - TopoDS_Shape s1 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s2 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s3 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s4 = StdMeshers_ObjRefUlils::LoadFromStream( is ); - TopoDS_Shape s5 = StdMeshers_ObjRefUlils::LoadFromStream( is ); + TopoDS_Shape shapes[ NB_SHAPES ]; + for ( int i = 0; i < NB_SHAPES; ++i ) + shapes[ i ] = StdMeshers_ObjRefUlils::LoadFromStream( is ); SMESH::SMESH_Mesh_var mesh = StdMeshers_ObjRefUlils::LoadObjectFromStream< SMESH::SMESH_Mesh >( is ); @@ -292,7 +298,18 @@ void StdMeshers_ProjectionSource3D_i::LoadFrom( const char* theStream ) } myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh ); - GetImpl()->RestoreParams( s1, s2, s3, s4, s5, meshImpl ); + + GetImpl()->SetSourceMesh ( meshImpl ); + GetImpl()->SetSource3DShape ( shapes[ SRC_SHAPE3D ] ); + GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ], + shapes[ SRC_VERTEX2 ], + shapes[ TGT_VERTEX1 ], + shapes[ TGT_VERTEX2 ]); + myBaseImpl->LoadFrom( is ); + + std::istringstream str( theStream ); + for ( int i = 0; i < NB_SHAPES; ++i ) + str >> myShapeEntries[ i ]; } diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.hxx b/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.hxx index d8eff8b7f..f09340130 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_ProjectionSource3D_i.hxx // Author : Edward AGAPOV @@ -93,6 +94,7 @@ public: /*! * Returns the -th source vertex associated with the -th target vertex. * Result may be nil if association not set. + * Valid indices are 1 and 2 */ GEOM::GEOM_Object_ptr GetSourceVertex(CORBA::Long i); @@ -114,6 +116,11 @@ public: virtual void LoadFrom( const char* theStream ); private: + // keep entries because the same shape can be published several times with + // different names and in this case a correct name can't be restored by a TopoDS_Shape + // kept by ::StdMeshers_ProjectionSource3D + enum { SRC_SHAPE3D=0, SRC_VERTEX1, SRC_VERTEX2, TGT_VERTEX1, TGT_VERTEX2, NB_SHAPES }; + std::string myShapeEntries[NB_SHAPES]; SMESH::SMESH_Mesh_var myCorbaMesh; }; diff --git a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx index 185bdd6ad..ed4063315 100644 --- a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx @@ -1,30 +1,26 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses -// File : StdMeshers_Projection_3D_i.cxx -// Moved here from SMESH_Projection_3D_i.cxx -// Author : Paul RASCLE, EDF +// File : StdMeshers_Projection_1D_2D_3D_i.cxx // Module : SMESH -// $Header$ // #include "StdMeshers_Projection_1D_2D_3D_i.hxx" @@ -53,8 +49,8 @@ StdMeshers_Projection_3D_i::StdMeshers_Projection_3D_i( PortableServer::POA_ptr { MESSAGE( "StdMeshers_Projection_3D_i::StdMeshers_Projection_3D_i" ); myBaseImpl = new ::StdMeshers_Projection_3D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //----------------------------------------------------------------------------- @@ -87,8 +83,8 @@ StdMeshers_Projection_2D_i::StdMeshers_Projection_2D_i( PortableServer::POA_ptr { MESSAGE( "StdMeshers_Projection_2D_i::StdMeshers_Projection_2D_i" ); myBaseImpl = new ::StdMeshers_Projection_2D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //----------------------------------------------------------------------------- @@ -105,6 +101,40 @@ StdMeshers_Projection_2D_i::~StdMeshers_Projection_2D_i() } +//============================================================================= +/*! + * StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i + */ +//============================================================================= + +StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_2D_Algo_i( thePOA ) +{ + MESSAGE( "StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i" ); + myBaseImpl = new ::StdMeshers_Projection_1D2D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} +//----------------------------------------------------------------------------- + +StdMeshers_Projection_1D2D_i::~StdMeshers_Projection_1D2D_i() +{ + MESSAGE( "StdMeshers_Projection_1D2D_i::~StdMeshers_Projection_1D2D_i" ); +} +//----------------------------------------------------------------------------- + +::StdMeshers_Projection_1D2D* StdMeshers_Projection_1D2D_i::GetImpl() +{ + MESSAGE( "StdMeshers_Projection_1D2D_i::GetImpl" ); + return ( ::StdMeshers_Projection_1D2D* )myBaseImpl; +} + + //============================================================================= /*! * StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i @@ -121,8 +151,8 @@ StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i( PortableServer::POA_ptr { MESSAGE( "StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i" ); myBaseImpl = new ::StdMeshers_Projection_1D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //----------------------------------------------------------------------------- diff --git a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx index 7fdba6588..fb17dd609 100644 --- a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx @@ -1,33 +1,29 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses -// File : StdMeshers_Hexa_3D_i.hxx -// Moved here from SMESH_Hexa_3D_i.hxx -// Author : Paul RASCLE, EDF +// File : StdMeshers_Projection_1D_2D_3D_i.hxx // Module : SMESH -// $Header$ // -#ifndef _SMESH_Projection_3D_I_HXX_ -#define _SMESH_Projection_3D_I_HXX_ +#ifndef _SMESH_Projection_1D2D3D_I_HXX_ +#define _SMESH_Projection_1D2D3D_I_HXX_ #include #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) @@ -36,6 +32,7 @@ #include "SMESH_2D_Algo_i.hxx" #include "SMESH_3D_Algo_i.hxx" #include "StdMeshers_Projection_1D.hxx" +#include "StdMeshers_Projection_1D2D.hxx" #include "StdMeshers_Projection_2D.hxx" #include "StdMeshers_Projection_3D.hxx" @@ -63,7 +60,7 @@ public: }; // ====================================================== -// Projection 3D algorithm +// Projection 2D algorithm // ====================================================== class StdMeshers_Projection_2D_i: @@ -84,7 +81,28 @@ public: }; // ====================================================== -// Projection 3D algorithm +// Projection 1D-2D algorithm +// ====================================================== + +class StdMeshers_Projection_1D2D_i: + public virtual POA_StdMeshers::StdMeshers_Projection_1D2D, + public virtual SMESH_2D_Algo_i +{ +public: + // Constructor + StdMeshers_Projection_1D2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + + // Destructor + virtual ~StdMeshers_Projection_1D2D_i(); + + // Get implementation + ::StdMeshers_Projection_1D2D* GetImpl(); +}; + +// ====================================================== +// Projection 1D algorithm // ====================================================== class StdMeshers_Projection_1D_i: diff --git a/src/StdMeshers_I/StdMeshers_Propagation_i.cxx b/src/StdMeshers_I/StdMeshers_Propagation_i.cxx index 707e41600..a288d1c3b 100644 --- a/src/StdMeshers_I/StdMeshers_Propagation_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Propagation_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Propagation_i.cxx // Module : SMESH diff --git a/src/StdMeshers_I/StdMeshers_Propagation_i.hxx b/src/StdMeshers_I/StdMeshers_Propagation_i.hxx index 77f863175..a79465a3e 100644 --- a/src/StdMeshers_I/StdMeshers_Propagation_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Propagation_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Propagation_i.hxx // Module : SMESH diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx new file mode 100644 index 000000000..4d72e8de1 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx @@ -0,0 +1,245 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_QuadrangleParams_i.cxx +// Author : Sergey KUUL, OCC +// Module : SMESH + +#include "StdMeshers_QuadrangleParams_i.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_PythonDump.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i + (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i" ); + myBaseImpl = new ::StdMeshers_QuadrangleParams(theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i" ); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::SetTriaVertex + * + * Set base vertex for triangles + */ +//============================================================================= + +void StdMeshers_QuadrangleParams_i::SetTriaVertex(CORBA::Long vertID) +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::SetTriaVertex" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetTriaVertex( vertID ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetTriaVertex( " + << vertID << " )"; +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetTriaVertex + * + * Get base vertex for triangles + */ +//============================================================================= + +CORBA::Long StdMeshers_QuadrangleParams_i::GetTriaVertex() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::GetTriaVertex" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetTriaVertex(); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::SetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +void StdMeshers_QuadrangleParams_i::SetObjectEntry( const char* entry ) +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::SetObjectEntry" ); + ASSERT( myBaseImpl ); + + try { + this->GetImpl()->SetObjectEntry( entry ); + // Update Python script + // SMESH::TPythonDump() << _this() << ".SetObjectEntry( '" << entry << "' )"; + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +char* StdMeshers_QuadrangleParams_i::GetObjectEntry() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::SetObjectEntry" ); + ASSERT( myBaseImpl ); + const char* entry; + try { + entry = this->GetImpl()->GetObjectEntry(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return CORBA::string_dup( entry ); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::SetQuadType + * + * Set the type of quadrangulation + */ +//============================================================================= +void StdMeshers_QuadrangleParams_i::SetQuadType(StdMeshers::QuadType type) +{ + //static char* quadTypes[5] = {"StdMeshers.QUAD_STANDARD", + // "StdMeshers.QUAD_TRIANGLE_PREF", + // "StdMeshers.QUAD_QUADRANGLE_PREF", + // "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED", + // "StdMeshers.QUAD_REDUCED"}; + + MESSAGE("StdMeshers_QuadrangleParams_i::SetQuadType"); + ASSERT(myBaseImpl); + + if (int(type) >= int(StdMeshers::QUAD_NB_TYPES)) { + THROW_SALOME_CORBA_EXCEPTION("Bad type of quadrangulation", SALOME::BAD_PARAM); + } + + try { + this->GetImpl()->SetQuadType(StdMeshers_QuadType(int(type))); + } + catch (SALOME_Exception& S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + // Update Python script + const char* quadType; + switch (type) { + case StdMeshers::QUAD_STANDARD: + quadType = "StdMeshers.QUAD_STANDARD"; break; + case StdMeshers::QUAD_TRIANGLE_PREF: + quadType = "StdMeshers.QUAD_TRIANGLE_PREF"; break; + case StdMeshers::QUAD_QUADRANGLE_PREF: + quadType = "StdMeshers.QUAD_QUADRANGLE_PREF"; break; + case StdMeshers::QUAD_QUADRANGLE_PREF_REVERSED: + quadType = "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED"; break; + case StdMeshers::QUAD_REDUCED: + quadType = "StdMeshers.QUAD_REDUCED"; break; + default: + quadType = "UNKNOWN"; + } + SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadType << " )"; + //SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadTypes[int(type)] << " )"; +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetQuadType + * + * Get the type of quadrangulation + */ +//============================================================================= +StdMeshers::QuadType StdMeshers_QuadrangleParams_i::GetQuadType() +{ + MESSAGE("StdMeshers_QuadrangleParams_i::GetQuadType"); + ASSERT(myBaseImpl); + return StdMeshers::QuadType(int(this->GetImpl()->GetQuadType())); +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_QuadrangleParams* StdMeshers_QuadrangleParams_i::GetImpl() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::GetImpl" ); + return ( ::StdMeshers_QuadrangleParams* )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_QuadrangleParams_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx new file mode 100644 index 000000000..7558ea36c --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx @@ -0,0 +1,82 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshers_QuadrangleParams_i.hxx +// Author : Sergey KUUL, OCC +// Module : SMESH +// $Header$ + +#ifndef _SMESH_QUADRANGLEPARAMS_I_HXX_ +#define _SMESH_QUADRANGLEPARAMS_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_QuadrangleParams.hxx" + +// ====================================================== +// QuadrangleParams hypothesis +// ====================================================== +class STDMESHERS_I_EXPORT StdMeshers_QuadrangleParams_i: + public virtual POA_StdMeshers::StdMeshers_QuadrangleParams, + public virtual SMESH_Hypothesis_i +{ +public: + // Constructor + StdMeshers_QuadrangleParams_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl); + // Destructor + virtual ~StdMeshers_QuadrangleParams_i(); + + // Set length + //void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart ) + // throw ( SALOME::SALOME_Exception ); + + // Get length + //CORBA::Double GetLength(CORBA::Boolean theIsStart); + + // Set base vertex for triangles + void SetTriaVertex (CORBA::Long vertID); + + // Get base vertex for triangles + CORBA::Long GetTriaVertex(); + + // Set the Entry of the Object + void SetObjectEntry (const char* theEntry); + + // Get Object Entry + char* GetObjectEntry(); + + // Set the type of quadrangulation + void SetQuadType (StdMeshers::QuadType type); + + // Get the type of quadrangulation + StdMeshers::QuadType GetQuadType(); + + // Get implementation + ::StdMeshers_QuadrangleParams* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.cxx b/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.cxx index c199fcebd..57a053d98 100644 --- a/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.cxx +++ b/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_QuadranglePreference_i.cxx // Moved here from SMESH_LocalLength_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_QuadranglePreference_i.hxx" #include "SMESH_Gen_i.hxx" diff --git a/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.hxx b/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.hxx index fc63462a9..b0d2bc712 100644 --- a/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.hxx +++ b/src/StdMeshers_I/StdMeshers_QuadranglePreference_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_QuadranglePreference_i.hxx // Moved here from SMESH_LocalLength_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_QuadranglePreference_I_HXX_ #define _SMESH_QuadranglePreference_I_HXX_ diff --git a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx index 7b0ce1e63..24d44ac6a 100644 --- a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Quadrangle_2D_i.cxx // Moved here from SMESH_Quadrangle_2D_i.cxx @@ -43,8 +44,8 @@ using namespace std; //============================================================================= StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_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 ), @@ -52,8 +53,8 @@ StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr { MESSAGE( "StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i" ); myBaseImpl = new ::StdMeshers_Quadrangle_2D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= diff --git a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx index abe6ce46a..2dfcce71d 100644 --- a/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Quadrangle_2D_i.hxx // Moved here from SMESH_Quadrangle_2D_i.hxx @@ -50,7 +51,7 @@ public: // Constructor StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~StdMeshers_Quadrangle_2D_i(); diff --git a/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx index 46052eb94..71553993f 100644 --- a/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx +++ b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_QuadraticMesh_i.cxx // Moved here from SMESH_LocalLength_i.cxx diff --git a/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx index ecd7baaa3..522f69644 100644 --- a/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx +++ b/src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_QuadraticMesh_i.hxx // Moved here from SMESH_LocalLength_i.hxx diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx new file mode 100644 index 000000000..202faa256 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_RadialQuadrangle_1D2D_i.cxx +// Module : SMESH +// +#include "StdMeshers_RadialQuadrangle_1D2D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + + +//============================================================================= +/*! + * StdMeshers_RadialQuadrangle_1D2D_i::StdMeshers_RadialQuadrangle_1D2D_i + */ +//============================================================================= + +StdMeshers_RadialQuadrangle_1D2D_i::StdMeshers_RadialQuadrangle_1D2D_i + (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_2D_Algo_i( thePOA ) +{ + MESSAGE( "StdMeshers_RadialQuadrangle_1D2D_i::StdMeshers_RadialQuadrangle_1D2D_i" ); + myBaseImpl = new ::StdMeshers_RadialQuadrangle_1D2D(theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//----------------------------------------------------------------------------- + +StdMeshers_RadialQuadrangle_1D2D_i::~StdMeshers_RadialQuadrangle_1D2D_i() +{ + MESSAGE( "StdMeshers_RadialQuadrangle_1D2D_i::~StdMeshers_RadialQuadrangle_1D2D_i" ); +} + +//----------------------------------------------------------------------------- + +::StdMeshers_RadialQuadrangle_1D2D* StdMeshers_RadialQuadrangle_1D2D_i::GetImpl() +{ + MESSAGE( "StdMeshers_RadialQuadrangle_1D2D_i::GetImpl" ); + return ( ::StdMeshers_RadialQuadrangle_1D2D* )myBaseImpl; +} + diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx new file mode 100644 index 000000000..ae5b731cb --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_RadialQuadrangle_1D2D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_RadialQuadrangle_1D2D_I_HXX_ +#define _SMESH_RadialQuadrangle_1D2D_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_2D_Algo_i.hxx" +#include "StdMeshers_RadialQuadrangle_1D2D.hxx" + +class SMESH_Gen; + +class StdMeshers_RadialQuadrangle_1D2D_i: + public virtual POA_StdMeshers::StdMeshers_RadialQuadrangle_1D2D, + public virtual SMESH_2D_Algo_i +{ +public: + // Constructor + StdMeshers_RadialQuadrangle_1D2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + + // Destructor + virtual ~StdMeshers_RadialQuadrangle_1D2D_i(); + + // Get implementation + ::StdMeshers_RadialQuadrangle_1D2D* GetImpl(); +}; + + +#endif diff --git a/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx b/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx index 1ac655bda..a9b8cd8ac 100644 --- a/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Regular_1D_i.cxx // Moved here from SMESH_Regular_1D_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_Regular_1D_i.hxx" #include "SMESH_Gen.hxx" diff --git a/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx b/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx index 2c3e89ba1..ea299fc98 100644 --- a/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Regular_1D_i.hxx // Moved here from SMESH_Regular_1D_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_REGULAR_1D_I_HXX_ #define _SMESH_REGULAR_1D_I_HXX_ @@ -48,7 +48,7 @@ public: // Constructor StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~StdMeshers_Regular_1D_i(); diff --git a/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx b/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx index fb81f9e9f..0836c36e4 100644 --- a/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Projection_3D_i.cxx // Moved here from SMESH_Projection_3D_i.cxx diff --git a/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx b/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx index 526bfca8f..64d559097 100644 --- a/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_SegmentAroundVertex_0D.hxx // Module : SMESH diff --git a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx index 9ee69e626..7eba3661c 100644 --- a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx +++ b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_SegmentLengthAroundVertex_i.cxx // Module : SMESH -// $Header$ // #include "StdMeshers_SegmentLengthAroundVertex_i.hxx" #include "SMESH_Gen.hxx" @@ -90,7 +90,7 @@ void StdMeshers_SegmentLengthAroundVertex_i::SetLength( CORBA::Double theLength } // Update Python script - SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )"; + SMESH::TPythonDump() << _this() << ".SetLength( " << SMESH::TVar(theLength) << " )"; } //============================================================================= @@ -137,3 +137,13 @@ CORBA::Boolean StdMeshers_SegmentLengthAroundVertex_i::IsDimSupported( SMESH::Di return type == SMESH::DIM_1D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_SegmentLengthAroundVertex_i::getMethodOfParameter(const int, int ) const +{ + return "SetLength"; +} diff --git a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx index 2add0396a..220a7e733 100644 --- a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx +++ b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_SegmentLengthAroundVertex_i.hxx // Module : SMESH -// $Header$ // #ifndef _SMESH_SegmentLengthAroundVertex_I_HXX_ #define _SMESH_SegmentLengthAroundVertex_I_HXX_ @@ -63,6 +63,9 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/StdMeshers_I/StdMeshers_StartEndLength_i.cxx b/src/StdMeshers_I/StdMeshers_StartEndLength_i.cxx index 1154b63f2..61b855a1d 100644 --- a/src/StdMeshers_I/StdMeshers_StartEndLength_i.cxx +++ b/src/StdMeshers_I/StdMeshers_StartEndLength_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_StartEndLength_i.cxx // Moved here from SMESH_LocalLength_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_StartEndLength_i.hxx" #include "SMESH_Gen_i.hxx" @@ -90,12 +90,37 @@ void StdMeshers_StartEndLength_i::SetLength(CORBA::Double theLength, } catch ( SALOME_Exception& S_ex ) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), - SALOME::BAD_PARAM ); + SALOME::BAD_PARAM ); } // Update Python script - SMESH::TPythonDump() << _this() << ".SetLength( " - << theLength << ", " << theIsStart << " )"; + SMESH::TPythonDump() << + _this() << ( theIsStart ? ".SetStartLength( " : ".SetEndLength( " ) << + SMESH::TVar(theLength) << " )"; +} + +//============================================================================= +/*! + * Sets parameter value + */ +//============================================================================= + +void StdMeshers_StartEndLength_i::SetStartLength( CORBA::Double length) + throw (SALOME::SALOME_Exception) +{ + SetLength( length, true ); +} + +//============================================================================= +/*! + * Sets parameter value + */ +//============================================================================= + +void StdMeshers_StartEndLength_i::SetEndLength( CORBA::Double length) + throw (SALOME::SALOME_Exception) +{ + SetLength( length, false ); } //============================================================================= @@ -113,6 +138,97 @@ CORBA::Double StdMeshers_StartEndLength_i::GetLength( CORBA::Boolean theIsStart) return this->GetImpl()->GetLength( theIsStart ); } +//============================================================================= +/*! + * StdMeshers_StartEndLength_i::SetReversedEdges + * + * Set edges to reverse + */ +//============================================================================= + +void StdMeshers_StartEndLength_i::SetReversedEdges( const SMESH::long_array& theIds ) +{ + ASSERT( myBaseImpl ); + try { + std::vector ids( theIds.length() ); + CORBA::Long iEnd = theIds.length(); + for ( CORBA::Long i = 0; i < iEnd; i++ ) + ids[ i ] = theIds[ i ]; + + this->GetImpl()->SetReversedEdges( ids ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )"; +} + +//============================================================================= +/*! + * StdMeshers_StartEndLength_i::SetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +void StdMeshers_StartEndLength_i::SetObjectEntry( const char* theEntry ) +{ + ASSERT( myBaseImpl ); + string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping + try { + this->GetImpl()->SetObjectEntry( entry.c_str() ); + // Update Python script + SMESH::TPythonDump() << _this() << ".SetObjectEntry( '" << entry.c_str() << "' )"; + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + * StdMeshers_StartEndLength_i::GetObjectEntry + * + * Set the Entry for the Main Object + */ +//============================================================================= + +char* StdMeshers_StartEndLength_i::GetObjectEntry() +{ + ASSERT( myBaseImpl ); + const char* entry; + try { + entry = this->GetImpl()->GetObjectEntry(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + return CORBA::string_dup( entry ); +} + +//============================================================================= +/*! + * StdMeshers_StartEndLength_i::GetReversedEdges + * + * Get reversed edges + */ +//============================================================================= + +SMESH::long_array* StdMeshers_StartEndLength_i::GetReversedEdges() +{ + ASSERT( myBaseImpl ); + SMESH::long_array_var anArray = new SMESH::long_array; + std::vector ids = this->GetImpl()->GetReversedEdges(); + anArray->length( ids.size() ); + for ( CORBA::Long i = 0; i < ids.size(); i++) + anArray [ i ] = ids [ i ]; + + return anArray._retn(); +} + //============================================================================= /*! * StdMeshers_StartEndLength_i::GetImpl @@ -141,3 +257,14 @@ CORBA::Boolean StdMeshers_StartEndLength_i::IsDimSupported( SMESH::Dimension typ return type == SMESH::DIM_1D; } +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_StartEndLength_i::getMethodOfParameter(const int paramIndex, + int /*nbVars*/) const +{ + return paramIndex == 0 ? "SetStartLength" : "SetEndLength"; +} diff --git a/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx b/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx index d7a4c4bcd..7eeb70e17 100644 --- a/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx +++ b/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_StartEndLength_i.hxx // Moved here from SMESH_LocalLength_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_StartEndLength_I_HXX_ #define _SMESH_StartEndLength_I_HXX_ @@ -55,8 +55,16 @@ public: virtual ~StdMeshers_StartEndLength_i(); // Set length + // * OBSOLETE *. Avoid such a way of interface design void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart ) throw ( SALOME::SALOME_Exception ); + + // Sets parameter value + void SetStartLength( CORBA::Double length) throw (SALOME::SALOME_Exception); + + // Sets parameter value + void SetEndLength( CORBA::Double length) throw (SALOME::SALOME_Exception); + // Get length CORBA::Double GetLength(CORBA::Boolean theIsStart); @@ -65,7 +73,21 @@ public: // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + //Set Reversed Edges + void SetReversedEdges( const SMESH::long_array& theIDs); + + //Get Reversed Edges + SMESH::long_array* GetReversedEdges(); + + //Set Object Entry + void SetObjectEntry( const char* entry); + + //Get Object Entry + char* GetObjectEntry(); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif - diff --git a/src/StdMeshers_I/StdMeshers_TrianglePreference_i.cxx b/src/StdMeshers_I/StdMeshers_TrianglePreference_i.cxx deleted file mode 100644 index 330216d89..000000000 --- a/src/StdMeshers_I/StdMeshers_TrianglePreference_i.cxx +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : StdMeshers_TrianglePreference_i.cxx -// Author : -// Module : SMESH -// -#include "StdMeshers_TrianglePreference_i.hxx" -#include "SMESH_Gen_i.hxx" -#include "SMESH_Gen.hxx" - -#include "Utils_CorbaException.hxx" -#include "utilities.h" - -#include - -using namespace std; - -//============================================================================= -/*! - * StdMeshers_TrianglePreference_i::StdMeshers_TrianglePreference_i - * - * Constructor - */ -//============================================================================= - -StdMeshers_TrianglePreference_i::StdMeshers_TrianglePreference_i -( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ): SALOME::GenericObj_i( thePOA ), - SMESH_Hypothesis_i( thePOA ) -{ - myBaseImpl = new ::StdMeshers_TrianglePreference( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); -} - -//============================================================================= -/*! - * StdMeshers_TrianglePreference_i::~StdMeshers_TrianglePreference_i - * - * Destructor - */ -//============================================================================= - -StdMeshers_TrianglePreference_i::~StdMeshers_TrianglePreference_i() -{ -} - -//============================================================================= -/*! - * StdMeshers_TrianglePreference_i::GetImpl - * - * Get implementation - */ -//============================================================================= - -::StdMeshers_TrianglePreference* StdMeshers_TrianglePreference_i::GetImpl() -{ - return ( ::StdMeshers_TrianglePreference* )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_TrianglePreference_i::IsDimSupported( SMESH::Dimension type ) -{ - return type == SMESH::DIM_2D; -} - diff --git a/src/StdMeshers_I/StdMeshers_TrianglePreference_i.hxx b/src/StdMeshers_I/StdMeshers_TrianglePreference_i.hxx deleted file mode 100644 index ce4826305..000000000 --- a/src/StdMeshers_I/StdMeshers_TrianglePreference_i.hxx +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : StdMeshers_TrianglePreference_i.hxx -// Author : -// Module : SMESH -// -#ifndef _SMESH_TrianglePreference_I_HXX_ -#define _SMESH_TrianglePreference_I_HXX_ - -#include "SMESH_StdMeshers_I.hxx" - -#include -#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) - -#include "SMESH_Hypothesis_i.hxx" -#include "StdMeshers_TrianglePreference.hxx" - -class SMESH_Gen; - -class STDMESHERS_I_EXPORT StdMeshers_TrianglePreference_i: - public virtual POA_StdMeshers::StdMeshers_TrianglePreference, - public virtual SMESH_Hypothesis_i -{ -public: - // Constructor - StdMeshers_TrianglePreference_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ); - // Destructor - virtual ~StdMeshers_TrianglePreference_i(); - - // Get implementation - ::StdMeshers_TrianglePreference* GetImpl(); - - // Verify whether hypothesis supports given entity type - CORBA::Boolean IsDimSupported( SMESH::Dimension type ); -}; - -#endif //_SMESH_TrianglePreference_I_HXX_ diff --git a/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.cxx index 63814d218..1ca4f2038 100644 --- a/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_Projection_3D_i.cxx // Moved here from SMESH_Projection_3D_i.cxx diff --git a/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.hxx index 32035e3c1..77f019fbf 100644 --- a/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is 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. // -// 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 // -// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_UseExisting_1D2D.hxx // Module : SMESH diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx new file mode 100644 index 000000000..55ca30d75 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx @@ -0,0 +1,231 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ViscousLayers_i.cxx +// Module : SMESH +// +#include "StdMeshers_ViscousLayers_i.hxx" + +#include "SMESH_Gen.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_PythonDump.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +#include CORBA_SERVER_HEADER(SMESH_Group) + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_ViscousLayers_i::StdMeshers_ViscousLayers_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_ViscousLayers_i::StdMeshers_ViscousLayers_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_ViscousLayers_i::StdMeshers_ViscousLayers_i" ); + myBaseImpl = new ::StdMeshers_ViscousLayers( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_ViscousLayers_i::~StdMeshers_ViscousLayers_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_ViscousLayers_i::~StdMeshers_ViscousLayers_i() +{ + MESSAGE( "StdMeshers_ViscousLayers_i::~StdMeshers_ViscousLayers_i" ); +} + +//================================================================================ +/*! + * \brief + */ +//================================================================================ + +void StdMeshers_ViscousLayers_i::SetIgnoreFaces(const ::SMESH::long_array& faceIDs) +throw ( SALOME::SALOME_Exception ) +{ + vector ids( faceIDs.length() ); + for ( unsigned i = 0; i < ids.size(); ++i ) + if (( ids[i] = faceIDs[i] ) < 1 ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid face id", SALOME::BAD_PARAM ); + GetImpl()->SetIgnoreFaces( ids ); + SMESH::TPythonDump() << _this() << ".SetIgnoreFaces( " << faceIDs << " )"; +} + +//================================================================================ +/*! + * \brief + */ +//================================================================================ + +SMESH::long_array* StdMeshers_ViscousLayers_i::GetIgnoreFaces() +{ + vector idsVec = GetImpl()->GetIgnoreFaces(); + SMESH::long_array_var ids = new SMESH::long_array; + ids->length( idsVec.size() ); + for ( unsigned i = 0; i < idsVec.size(); ++i ) + ids[i] = idsVec[i]; + return ids._retn(); +} + +//================================================================================ +/*! + * \brief + */ +//================================================================================ + +void StdMeshers_ViscousLayers_i::SetTotalThickness(::CORBA::Double thickness) +throw ( SALOME::SALOME_Exception ) +{ + if ( thickness < 1e-100 ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid thickness", SALOME::BAD_PARAM ); + GetImpl()->SetTotalThickness(thickness); + SMESH::TPythonDump() << _this() << ".SetTotalThickness( " << SMESH::TVar(thickness) << " )"; +} + +//================================================================================ +/*! + * \brief + */ +//================================================================================ + +::CORBA::Double StdMeshers_ViscousLayers_i::GetTotalThickness() +{ + return GetImpl()->GetTotalThickness(); +} + +//================================================================================ +/*! + * \brief + * \param nb - + */ +//================================================================================ + +void StdMeshers_ViscousLayers_i::SetNumberLayers(::CORBA::Short nb) +throw ( SALOME::SALOME_Exception ) +{ + if ( nb < 1 ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid number of layers", SALOME::BAD_PARAM ); + GetImpl()->SetNumberLayers( nb ); + SMESH::TPythonDump() << _this() << ".SetNumberLayers( " << SMESH::TVar(nb) << " )"; +} + +//================================================================================ +/*! + * \brief + */ +//================================================================================ + +::CORBA::Short StdMeshers_ViscousLayers_i::GetNumberLayers() +{ + return CORBA::Short( GetImpl()->GetNumberLayers() ); +} + +//================================================================================ +/*! + * \brief + * \param factor - + */ +//================================================================================ + +void StdMeshers_ViscousLayers_i::SetStretchFactor(::CORBA::Double factor) +throw ( SALOME::SALOME_Exception ) +{ + if ( factor < 1 ) + THROW_SALOME_CORBA_EXCEPTION( "Invalid stretch factor, it must be >= 1.0", SALOME::BAD_PARAM ); + GetImpl()->SetStretchFactor(factor); + SMESH::TPythonDump() << _this() << ".SetStretchFactor( " << SMESH::TVar(factor) << " )"; +} + +//================================================================================ +/*! + * \brief + * + */ +//================================================================================ + +::CORBA::Double StdMeshers_ViscousLayers_i::GetStretchFactor() +{ + return GetImpl()->GetStretchFactor(); +} + +//============================================================================= +/*! + * Get implementation + */ +//============================================================================= + +::StdMeshers_ViscousLayers* StdMeshers_ViscousLayers_i::GetImpl() +{ + MESSAGE( "StdMeshers_ViscousLayers_i::GetImpl" ); + return ( ::StdMeshers_ViscousLayers* )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_ViscousLayers_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_3D; +} + +//================================================================================ +/*! + * \brief Return method name corresponding to index of variable parameter + */ +//================================================================================ + +std::string StdMeshers_ViscousLayers_i::getMethodOfParameter(const int paramIndex, int ) const +{ + // order of methods was defined by StdMeshersGUI_StdHypothesisCreator::storeParams() + switch ( paramIndex ) + { + case 0: return "SetTotalThickness"; + case 1: return "SetNumberLayers"; + case 2: return "SetStretchFactor"; + } + return ""; +} diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx new file mode 100644 index 000000000..e4d5d6e2e --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx @@ -0,0 +1,74 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ViscousLayers_i.hxx +// Module : SMESH +// +#ifndef _SMESH_ViscousLayers_I_HXX_ +#define _SMESH_ViscousLayers_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_ViscousLayers.hxx" + +class SMESH_Gen; + +class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers_i: + public virtual POA_StdMeshers::StdMeshers_ViscousLayers, + public virtual SMESH_Hypothesis_i +{ + public: + // Constructor + StdMeshers_ViscousLayers_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_ViscousLayers_i(); + + void SetIgnoreFaces(const ::SMESH::long_array& faceIDs) throw ( SALOME::SALOME_Exception ); + SMESH::long_array* GetIgnoreFaces(); + + void SetTotalThickness(::CORBA::Double thickness) throw ( SALOME::SALOME_Exception ); + ::CORBA::Double GetTotalThickness(); + + void SetNumberLayers(::CORBA::Short nb) throw ( SALOME::SALOME_Exception ); + ::CORBA::Short GetNumberLayers(); + + void SetStretchFactor(::CORBA::Double factor) throw ( SALOME::SALOME_Exception ); + ::CORBA::Double GetStretchFactor(); + + // Get implementation + ::StdMeshers_ViscousLayers* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx index 8d73b56d8..20104d9c8 100644 --- a/src/StdMeshers_I/StdMeshers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -1,29 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH StdMeshers : implementaion of SMESH idl descriptions // File : StdMeshers_i.cxx // Author : Julia DOROVSKIKH // Module : SMESH - +// #include "SMESH_StdMeshers_I.hxx" #include "SMESH_Gen_i.hxx" @@ -34,12 +35,13 @@ #include "StdMeshers_AutomaticLength_i.hxx" #include "StdMeshers_StartEndLength_i.hxx" #include "StdMeshers_Arithmetic1D_i.hxx" +#include "StdMeshers_FixedPoints1D_i.hxx" #include "StdMeshers_NumberOfSegments_i.hxx" #include "StdMeshers_Deflection1D_i.hxx" #include "StdMeshers_Propagation_i.hxx" #include "StdMeshers_LengthFromEdges_i.hxx" #include "StdMeshers_QuadranglePreference_i.hxx" -#include "StdMeshers_TrianglePreference_i.hxx" +//#include "StdMeshers_TrianglePreference_i.hxx" #include "StdMeshers_QuadraticMesh_i.hxx" #include "StdMeshers_MaxElementArea_i.hxx" #include "StdMeshers_MaxElementVolume_i.hxx" @@ -49,8 +51,14 @@ #include "StdMeshers_ProjectionSource1D_i.hxx" #include "StdMeshers_NumberOfLayers_i.hxx" #include "StdMeshers_LayerDistribution_i.hxx" +#include "StdMeshers_NumberOfLayers2D_i.hxx" +#include "StdMeshers_LayerDistribution2D_i.hxx" #include "StdMeshers_SegmentLengthAroundVertex_i.hxx" #include "StdMeshers_MaxLength_i.hxx" +#include "StdMeshers_QuadrangleParams_i.hxx" +#include "StdMeshers_ImportSource1D_i.hxx" +#include "StdMeshers_ImportSource2D_i.hxx" +#include "StdMeshers_Cartesian_3D_i.hxx" #include "StdMeshers_Regular_1D_i.hxx" #include "StdMeshers_MEFISTO_2D_i.hxx" @@ -61,14 +69,41 @@ #include "StdMeshers_SegmentAroundVertex_0D_i.hxx" #include "StdMeshers_CompositeSegment_1D_i.hxx" #include "StdMeshers_UseExisting_1D2D_i.hxx" - +#include "StdMeshers_RadialQuadrangle_1D2D_i.hxx" +#include "StdMeshers_Import_1D_i.hxx" +#include "StdMeshers_Import_1D2D_i.hxx" +#include "StdMeshers_ViscousLayers_i.hxx" +#include "StdMeshers_CartesianParameters3D_i.hxx" template class StdHypothesisCreator_i:public HypothesisCreator_i { +public: // as we have 'module StdMeshers' in SMESH_BasicHypothesis.idl virtual std::string GetModuleName() { return "StdMeshers"; } }; +//============================================================================= +/*! + * \brief Creates StdMeshers_QuadrangleParams_i instead of + * StdMeshers_TrianglePreference_i and StdMeshers_QuadranglePreference_i + */ +//============================================================================= + +template +class QuadrangleParamsCreator : public StdHypothesisCreator_i +{ +public: + virtual SMESH_Hypothesis_i* Create (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + { + StdMeshers_QuadrangleParams_i* h = + new StdMeshers_QuadrangleParams_i( thePOA, theStudyId, theGenImpl); + h->SetQuadType( TYPE ); + return h; + } +}; + //============================================================================= /*! * @@ -105,14 +140,19 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Deflection1D") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "FixedPoints1D") == 0) + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Arithmetic1D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "AutomaticLength") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "QuadranglePreference") == 0) + // do not convert to StdMeshers_QuadrangleParams_i as it is used by NETGEN 2D aCreator = new StdHypothesisCreator_i; + //aCreator = new QuadrangleParamsCreator< StdMeshers::QUAD_QUADRANGLE_PREF >(); else if (strcmp(aHypName, "TrianglePreference") == 0) - aCreator = new StdHypothesisCreator_i; + //aCreator = new StdHypothesisCreator_i; + aCreator = new QuadrangleParamsCreator< StdMeshers::QUAD_TRIANGLE_PREF >(); else if (strcmp(aHypName, "QuadraticMesh") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "ProjectionSource3D") == 0) @@ -125,8 +165,22 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "LayerDistribution") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "NumberOfLayers2D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "LayerDistribution2D") == 0) + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "SegmentLengthAroundVertex") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "QuadrangleParams") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "ImportSource1D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "ImportSource2D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "ViscousLayers") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "CartesianParameters3D") == 0) + aCreator = new StdHypothesisCreator_i; // Algorithms else if (strcmp(aHypName, "Regular_1D") == 0) @@ -139,6 +193,8 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Projection_1D") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "Projection_1D2D") == 0) + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Projection_2D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Projection_3D") == 0) @@ -155,6 +211,14 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "UseExisting_2D") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "RadialQuadrangle_1D2D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "Import_1D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "Import_1D2D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "Cartesian_3D") == 0) + aCreator = new StdHypothesisCreator_i; else ; return aCreator; diff --git a/src/Tools/Makefile.am b/src/Tools/Makefile.am new file mode 100644 index 000000000..cae255b85 --- /dev/null +++ b/src/Tools/Makefile.am @@ -0,0 +1,31 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# File : Makefile.in +# Author : Patrick GOLDBRONN (CEA) +# Modified by : Alexander BORODIN (OCN) - autotools usage +# Module : SMESH +# $Header$ +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +SUBDIRS = MeshCut padder + +salomeplugins_PYTHON = \ + smesh_plugins.py diff --git a/src/Tools/MeshCut/AUTHORS b/src/Tools/MeshCut/AUTHORS new file mode 100644 index 000000000..28f414d71 --- /dev/null +++ b/src/Tools/MeshCut/AUTHORS @@ -0,0 +1,19 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors: Jean Claude LALEUF, Jean Francois HERY, XMESHLAB project, EDF R&D diff --git a/src/Tools/MeshCut/Makefile.am b/src/Tools/MeshCut/Makefile.am new file mode 100644 index 000000000..d09c3bb2a --- /dev/null +++ b/src/Tools/MeshCut/Makefile.am @@ -0,0 +1,59 @@ +# Copyright (C) 2007-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + + +bin_PROGRAMS = MeshCut + +MeshCut_SOURCES = \ + MeshCut_Globals.hxx \ + MeshCut_Carre.hxx \ + MeshCut_Carre.cxx \ + MeshCut_Cube.hxx \ + MeshCut_Cube.cxx \ + MeshCut_Maillage.hxx \ + MeshCut_Maillage.cxx \ + MeshCut_Fonctions.hxx \ + MeshCut_Fonctions.cxx \ + MeshCut_Utils.hxx \ + MeshCut_Utils.cxx \ + MeshCut_Cas.hxx \ + MeshCut_Cas.cxx \ + MeshCut_DC.cxx + +MeshCut_CPPFLAGS = $(MED3_INCLUDES) + +MeshCut_LDFLAGS = $(MED3_LIBS) $(HDF5_LIBS) + +salomeplugins_PYTHON = \ + meshcut_plugin.py + +UIPY_FILES = MeshCutDialog.py + +if SMESH_ENABLE_GUI + nodist_salomescript_SCRIPTS = $(UIPY_FILES) +endif + +CLEANFILES = $(UIPY_FILES) + +EXTRA_DIST += $(UIPY_FILES:%.py=%.ui) + +%.py : %.ui + $(PYUIC) $< -o $@ diff --git a/src/Tools/MeshCut/MeshCutDialog.ui b/src/Tools/MeshCut/MeshCutDialog.ui new file mode 100644 index 000000000..a7f29b453 --- /dev/null +++ b/src/Tools/MeshCut/MeshCutDialog.ui @@ -0,0 +1,273 @@ + + + Dialog + + + + 0 + 0 + 416 + 431 + + + + cut a mesh by a plane + + + false + + + + + + + + original mesh file + + + + + + + + + + + + output mesh name + + + + + + + meshCut + + + + + + + name of group above cut + + + + + + + above + + + + + + + name of group below cut + + + + + + + below + + + + + + + + + cut plane + + + + + + + + normal vector + + + + + + + vertex in plane + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + 1.000000000000000 + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + + + + + + Qt::Horizontal + + + + Tolerance 0 < T <= 1 + + + + + 1.000000000000000 + + + 0.010000000000000 + + + 0.010000000000000 + + + + + + + + Qt::Vertical + + + + 396 + 90 + + + + + + + + Qt::Horizontal + + + + Help + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + cut mesh file + + + + + + + + + + + pb_okCancel + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + pb_okCancel + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Tools/MeshCut/MeshCut_Carre.cxx b/src/Tools/MeshCut/MeshCut_Carre.cxx new file mode 100644 index 000000000..181a6e5f9 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Carre.cxx @@ -0,0 +1,54 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MeshCut_Carre.hxx" + +#include + +using namespace MESHCUT; +using namespace std; + +Carre::Carre(float _x0, float _x1, float _y0, float _y1) +{ + x0 = _x0; + x1 = _x1; + y0 = _y0; + y1 = _y1; +} + +bool Carre::disjoint(Carre* c2) +{ + return (x0 > c2->x1 || x1 < c2->x0 || y0 > c2->y1 || y1 < c2->y0); +} + +bool Carre::contientNoeud(int ngnoeud, Maillage *MAILLAGE) +{ + float x = *(MAILLAGE->XX + ngnoeud - 1); + float y = *(MAILLAGE->YY + ngnoeud - 1); + return (x >= x0 && x <= x1 && y >= y0 && y <= y1); +} + +void Carre::affichage() +{ + cout << "x0=" << x0 << " "; + cout << "x1=" << x1 << " "; + cout << "y0=" << y0 << " "; + cout << "y1=" << y1 << " "; +} + diff --git a/src/Tools/MeshCut/MeshCut_Carre.hxx b/src/Tools/MeshCut/MeshCut_Carre.hxx new file mode 100644 index 000000000..9f6f303b8 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Carre.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MESHCUT_CARRE_HXX__ +#define __MESHCUT_CARRE_HXX__ + +#include "MeshCut_Maillage.hxx" + +namespace MESHCUT + { + class Carre + { + public: + float x0, x1, y0, y1; + public: + Carre(float _x0, float _x1, float _y0, float _y1); + bool disjoint(Carre* c2); + bool contientNoeud(int ngnoeud, Maillage *MAILLAGE); + void affichage(); + }; + } + +#endif diff --git a/src/Tools/MeshCut/MeshCut_Cas.cxx b/src/Tools/MeshCut/MeshCut_Cas.cxx new file mode 100644 index 000000000..16c8455a4 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Cas.cxx @@ -0,0 +1,945 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MeshCut_Cas.hxx" + +#include "MeshCut_Globals.hxx" + +using namespace MESHCUT; +using namespace std; + +/*! + * Le cas 1 traduit le fait que deux des sommets du T4 initial sont dans le plan de coupe. + * Le point d'intersection franc trouvé est sur l'arête opposée à ces deux points du T4. + + * Le T4 initial produit deux nouveaux T4. + */ +void MESHCUT::cas1(int VN[6], int it4) +{ + cutTetras.push_back(it4); + // cout << "Cas 1 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " << VN[4] + // << " " << VN[5] << " " << endl; + + // Numéros des noeuds du TETRA4 + int ng0 = MAILLAGE1->CNX[TETRA4][4 * it4 + 0]; + int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1]; + int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2]; + int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3]; + + int i1, i2; + + if (VN[0] != -1) + { + // Le sommet de T4new1 servant à la détermination du groupe est le noeud 1 du T4 d'origine + + // cout << "cas 1/0" << endl; + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i1 = cptNouvellesMailles[TETRA4] - 1; + + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i2 = cptNouvellesMailles[TETRA4] - 1; + + if (POSN[ng1 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + } + else + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + } + } + + else if (VN[1] != -1) + { + // Le sommet de T4new1 servant à la détermination du groupe est le noeud 0 du T4 d'origine + + // cout << "cas 1/1" << endl; + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i1 = cptNouvellesMailles[TETRA4] - 1; + + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i2 = cptNouvellesMailles[TETRA4] - 1; + + if (POSN[ng0 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + } + else + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + } + } + + else if (VN[2] != -1) + { + // Le sommet de T4new1 servant à la détermination du groupe est le noeud 0 du T4 d'origine + + // cout << "cas 1/2" << endl; + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[2]); + cptNouvellesMailles[TETRA4]++; + i1 = cptNouvellesMailles[TETRA4] - 1; + + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[2]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i2 = cptNouvellesMailles[TETRA4] - 1; + + if (POSN[ng0 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + } + else + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + } + } + + else if (VN[3] != -1) + { + // Le sommet de T4new1 servant à la détermination du groupe est le noeud 1 du T4 d'origine + + // cout << "cas 1/3" << endl; + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i1 = cptNouvellesMailles[TETRA4] - 1; + + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i2 = cptNouvellesMailles[TETRA4] - 1; + + if (POSN[ng1 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + } + else + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + } + } + + else if (VN[4] != -1) + { + // Le sommet de T4new1 servant à la détermination du groupe est le noeud 1 du T4 d'origine + + // cout << "cas 1/4" << endl; + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[4]); + cptNouvellesMailles[TETRA4]++; + i1 = cptNouvellesMailles[TETRA4] - 1; + + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(VN[4]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i2 = cptNouvellesMailles[TETRA4] - 1; + + if (POSN[ng1 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + } + else + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + } + } + + else if (VN[5] != -1) + { + // Le sommet de T4new1 servant à la détermination du groupe est le noeud 3 du T4 d'origine + + // cout << "cas 1/5" << endl; + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(VN[5]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + i1 = cptNouvellesMailles[TETRA4] - 1; + + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[5]); + cptNouvellesMailles[TETRA4]++; + i2 = cptNouvellesMailles[TETRA4] - 1; + + if (POSN[ng3 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + } + else + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2); + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1); + } + } + + else + ERREUR(" Intersections configuration not taken into account (case cptPI=1) "); + + //int nl1 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1; + //int nl2 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2; + // cout << "La maille TETRA4 " << it4 << " produit les mailles TETRA4-" << nl1 << " et TETRA4-" << nl2 << endl; + +} + +/*! Deux points d'intersection + * Le cas 2 traduit le fait qu'un des sommets du T4 est dans le plan de coupe. + * Ce sommet est celui des quatre qui n'appartient à aucune des deux arêtes sur lesquelles + * un point d'intersection non -1 a été calculé. + * + * Le T4 initial produit un nouveau T4 et un élément PYRAM5. + * + */ +void MESHCUT::cas2(int VN[6], int it4) +{ + cutTetras.push_back(it4); + // cout << "Cas 2 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " << VN[4] + // << " " << VN[5] << " " << endl; + + // Numéros des noeuds du TETRA4 + int ng0 = MAILLAGE1->CNX[TETRA4][4 * it4 + 0]; + int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1]; + int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2]; + int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3]; + + if (VN[0] != -1 && VN[1] != -1) + { + // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine + + // cout << "cas 2.01" << endl; + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(ng3); + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(ng0); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(VN[0]); + newCNX[PYRAM5].push_back(ng1); + newCNX[PYRAM5].push_back(ng2); + newCNX[PYRAM5].push_back(VN[1]); + newCNX[PYRAM5].push_back(ng3); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng0 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + else if (VN[0] != -1 && VN[2] != -1) + { + // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine + + // cout << "cas 2.02" << endl; + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(VN[2]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(ng0); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(VN[0]); + newCNX[PYRAM5].push_back(VN[2]); + newCNX[PYRAM5].push_back(ng3); + newCNX[PYRAM5].push_back(ng1); + newCNX[PYRAM5].push_back(ng2); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng0 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + else if (VN[0] != -1 && VN[3] != -1) + { + // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine + + // cout << "cas 2.03" << endl; + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(ng3); + newCNX[TETRA4].push_back(ng1); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(VN[0]); + newCNX[PYRAM5].push_back(VN[3]); + newCNX[PYRAM5].push_back(ng2); + newCNX[PYRAM5].push_back(ng0); + newCNX[PYRAM5].push_back(ng3); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng1 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + else if (VN[0] != -1 && VN[4] != -1) + { + // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine + + // cout << "cas 2.04" << endl; + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[4]); + newCNX[TETRA4].push_back(ng1); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(ng0); + newCNX[PYRAM5].push_back(ng3); + newCNX[PYRAM5].push_back(VN[4]); + newCNX[PYRAM5].push_back(VN[0]); + newCNX[PYRAM5].push_back(ng2); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng1 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else if (VN[0] != -1 && VN[5] != -1) + ERREUR("Case 2/05 forbidden"); + + else if (VN[1] != -1 && VN[2] != -1) + { + // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine + + // cout << "cas 2.12" << endl; + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(VN[2]); + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(ng0); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(ng2); + newCNX[PYRAM5].push_back(ng3); + newCNX[PYRAM5].push_back(VN[2]); + newCNX[PYRAM5].push_back(VN[1]); + newCNX[PYRAM5].push_back(ng1); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng0 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + else if (VN[1] != -1 && VN[3] != -1) + { + // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine + + // cout << "cas 2.13" << endl; + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(ng3); + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(ng2); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(ng0); + newCNX[PYRAM5].push_back(ng1); + newCNX[PYRAM5].push_back(VN[3]); + newCNX[PYRAM5].push_back(VN[1]); + newCNX[PYRAM5].push_back(ng3); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng2 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else if (VN[1] != -1 && VN[4] != -1) + ERREUR("Case 2/14 excluded"); + + else if (VN[1] != -1 && VN[5] != -1) + { + // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine + + // cout << "cas 2.15" << endl; + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(VN[5]); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(VN[1]); + newCNX[PYRAM5].push_back(VN[5]); + newCNX[PYRAM5].push_back(ng3); + newCNX[PYRAM5].push_back(ng0); + newCNX[PYRAM5].push_back(ng1); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng2 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else if (VN[2] != -1 && VN[3] != -1) + ERREUR("Case 2/23 excluded"); + + else if (VN[2] != -1 && VN[4] != -1) + { + // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine + + // cout << "cas 2.24" << endl; + newCNX[TETRA4].push_back(VN[2]); + newCNX[TETRA4].push_back(VN[4]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(ng0); + newCNX[PYRAM5].push_back(VN[2]); + newCNX[PYRAM5].push_back(VN[4]); + newCNX[PYRAM5].push_back(ng1); + newCNX[PYRAM5].push_back(ng2); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng3 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else if (VN[2] != -1 && VN[5] != -1) + { + // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine + + // cout << "cas 2.25" << endl; + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(VN[5]); + newCNX[TETRA4].push_back(VN[2]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(ng0); + newCNX[PYRAM5].push_back(ng2); + newCNX[PYRAM5].push_back(VN[5]); + newCNX[PYRAM5].push_back(VN[2]); + newCNX[PYRAM5].push_back(ng1); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng3 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else if (VN[3] != -1 && VN[4] != -1) + { + // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine + + // cout << "cas 2.34" << endl; + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(VN[4]); + newCNX[TETRA4].push_back(ng1); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(VN[3]); + newCNX[PYRAM5].push_back(VN[4]); + newCNX[PYRAM5].push_back(ng3); + newCNX[PYRAM5].push_back(ng2); + newCNX[PYRAM5].push_back(ng0); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng1 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else if (VN[3] != -1 && VN[5] != -1) + { + // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine + + // cout << "cas 2.35" << endl; + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(VN[5]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(ng0); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(VN[3]); + newCNX[PYRAM5].push_back(ng1); + newCNX[PYRAM5].push_back(ng3); + newCNX[PYRAM5].push_back(VN[5]); + newCNX[PYRAM5].push_back(ng0); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng2 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else if (VN[4] != -1 && VN[5] != -1) + { + // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine + + // cout << "cas 2.35" << endl; + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(VN[4]); + newCNX[TETRA4].push_back(VN[5]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + + newCNX[PYRAM5].push_back(ng1); + newCNX[PYRAM5].push_back(VN[4]); + newCNX[PYRAM5].push_back(VN[5]); + newCNX[PYRAM5].push_back(ng2); + newCNX[PYRAM5].push_back(ng0); + cptNouvellesMailles[PYRAM5]++; + + if (POSN[ng3 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1); + } + } + + else + ERREUR(" Intersections configuration not taken into account (case cptPI=2) "); + + // int ngT4 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1; + // int ngP5 = MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1; + // cout << "La maille TETRA4 " << it4 << " produit les mailles TETRA4-" << ngT4 << " et PYRAM5-" << ngP5 << endl; + +} + +/*! Trois points d'intersection + * ATTENTION: pour les PENTA6 on adopte la convention d'orientation SALOME : + * + * N1 N2 N3 N4 N5 N6 + * + * où N1 N2 N3 sont les sommets du haut et N4 N5 N6 les sommets du bas + * (selon l'orientation donnée par le sens des triangles) + */ +void MESHCUT::cas3(int VN[6], int it4) +{ + cutTetras.push_back(it4); + // cout << "Cas 3 - it4="<CNX[TETRA4][4 * it4 + 0]; + int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1]; + int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2]; + int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3]; + + if (VN[0] != -1 && VN[1] != -1 && VN[2] != -1) + { + + // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine + + newCNX[TETRA4].push_back(ng0); + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(VN[2]); + cptNouvellesMailles[TETRA4]++; + + newCNX[PENTA6].push_back(ng1); + newCNX[PENTA6].push_back(ng3); + newCNX[PENTA6].push_back(ng2); + newCNX[PENTA6].push_back(VN[0]); + newCNX[PENTA6].push_back(VN[2]); + newCNX[PENTA6].push_back(VN[1]); + cptNouvellesMailles[PENTA6]++; + + if (POSN[ng0 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + } + + else if (VN[0] != -1 && VN[3] != -1 && VN[4] != -1) + { + // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine + + //cout << "cas 3.2 (noeud sommet 1)" << endl; + newCNX[TETRA4].push_back(VN[0]); + newCNX[TETRA4].push_back(ng1); + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(VN[4]); + cptNouvellesMailles[TETRA4]++; + + newCNX[PENTA6].push_back(ng0); + newCNX[PENTA6].push_back(ng2); + newCNX[PENTA6].push_back(ng3); + newCNX[PENTA6].push_back(VN[0]); + newCNX[PENTA6].push_back(VN[3]); + newCNX[PENTA6].push_back(VN[4]); + cptNouvellesMailles[PENTA6]++; + + if (POSN[ng1 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + } + else if (VN[1] != -1 && VN[3] != -1 && VN[5] != -1) + { + // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine + + //cout << "cas 3.3 (noeud sommet 2)" << endl; + + newCNX[TETRA4].push_back(VN[1]); + newCNX[TETRA4].push_back(VN[3]); + newCNX[TETRA4].push_back(ng2); + newCNX[TETRA4].push_back(VN[5]); + cptNouvellesMailles[TETRA4]++; + + newCNX[PENTA6].push_back(ng0); + newCNX[PENTA6].push_back(ng3); + newCNX[PENTA6].push_back(ng1); + newCNX[PENTA6].push_back(VN[1]); + newCNX[PENTA6].push_back(VN[5]); + newCNX[PENTA6].push_back(VN[3]); + cptNouvellesMailles[PENTA6]++; + + if (POSN[ng2 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + } + else if (VN[2] != -1 && VN[4] != -1 && VN[5] != -1) + { + // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine + + newCNX[TETRA4].push_back(VN[2]); + newCNX[TETRA4].push_back(VN[4]); + newCNX[TETRA4].push_back(VN[5]); + newCNX[TETRA4].push_back(ng3); + cptNouvellesMailles[TETRA4]++; + + newCNX[PENTA6].push_back(ng0); + newCNX[PENTA6].push_back(ng1); + newCNX[PENTA6].push_back(ng2); + newCNX[PENTA6].push_back(VN[2]); + newCNX[PENTA6].push_back(VN[4]); + newCNX[PENTA6].push_back(VN[5]); + cptNouvellesMailles[PENTA6]++; + + if (POSN[ng3 - 1] == 1) + { + GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + else + { + GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1); + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1); + } + } + else + { + // cout << "Cas 3 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " + // << VN[4] << " " << VN[5] << " " << endl; + // + // int n0 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 0); + // float x0 = MAILLAGE1->XX[n0 - 1]; + // float y0 = MAILLAGE1->YY[n0 - 1]; + // float z0 = MAILLAGE1->ZZ[n0 - 1]; + // + // int n1 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 1); + // float x1 = MAILLAGE1->XX[n1 - 1]; + // float y1 = MAILLAGE1->YY[n1 - 1]; + // float z1 = MAILLAGE1->ZZ[n1 - 1]; + // + // int n2 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 2); + // float x2 = MAILLAGE1->XX[n2 - 1]; + // float y2 = MAILLAGE1->YY[n2 - 1]; + // float z2 = MAILLAGE1->ZZ[n2 - 1]; + // + // int n3 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 3); + // float x3 = MAILLAGE1->XX[n3 - 1]; + // float y3 = MAILLAGE1->YY[n3 - 1]; + // float z3 = MAILLAGE1->ZZ[n3 - 1]; + // + // cout << x0 << " " << y0 << " " << z0 << " " << endl; + // cout << x1 << " " << y1 << " " << z1 << " " << endl; + // cout << x2 << " " << y2 << " " << z2 << " " << endl; + // cout << x3 << " " << y3 << " " << z3 << " " << endl; + + ERREUR(" Intersections configuration not taken into account (case cptPI=3) "); + } + + // int ngT4 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1; + // int ngP6 = MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1; + // cout << "La maille TETRA4 " << it4 << " produit les mailles TETRA4-" << ngT4 << " et PENTA6-" << ngP6 << endl; +} + +/*! Quatre points d'intersection + * + * ATTENTION: pour les PENTA6 on adopte la convention d'orientation SALOME + * + * N1 N2 N3 N4 N5 N6 + * + * où N1 N2 N3 sont les sommets du haut et N4 N5 N6 les sommets du bas + * (selon l'orientation donnée par le sens des triangles) + */ +void MESHCUT::cas4(int VN[6], int it4) +{ + cutTetras.push_back(it4); + // cout << "Cas 4 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " << VN[4] + // << " " << VN[5] << " " << endl; + + // Numéros des noeuds du TETRA4 + int ng0 = MAILLAGE1->CNX[TETRA4][4 * it4 + 0]; + int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1]; + int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2]; + int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3]; + + int i1, i2; // Numéros locaux dans le type des mailles créées + + if (VN[0] == -1 && VN[5] == -1) + { + // Les deux arêtes opposées sont [0,1] et [2,3] + + newCNX[PENTA6].push_back(ng0); + newCNX[PENTA6].push_back(VN[1]); + newCNX[PENTA6].push_back(VN[2]); + newCNX[PENTA6].push_back(ng1); + newCNX[PENTA6].push_back(VN[3]); + newCNX[PENTA6].push_back(VN[4]); + cptNouvellesMailles[PENTA6]++; + i1 = cptNouvellesMailles[PENTA6] - 1; + + newCNX[PENTA6].push_back(ng3); + newCNX[PENTA6].push_back(VN[4]); + newCNX[PENTA6].push_back(VN[2]); + newCNX[PENTA6].push_back(ng2); + newCNX[PENTA6].push_back(VN[3]); + newCNX[PENTA6].push_back(VN[1]); + cptNouvellesMailles[PENTA6]++; + i2 = cptNouvellesMailles[PENTA6] - 1; + + if (POSN[ng0 - 1] == 1) + { + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2); + } + else + { + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1); + } + + } // if ( VN[0]==-1 && VN[5]==-1 ) + + else if (VN[1] == -1 && VN[4] == -1) + { + // Les deux arêtes opposées sont [0,2] et [1,3] + + newCNX[PENTA6].push_back(ng2); + newCNX[PENTA6].push_back(VN[3]); + newCNX[PENTA6].push_back(VN[5]); + newCNX[PENTA6].push_back(ng0); + newCNX[PENTA6].push_back(VN[0]); + newCNX[PENTA6].push_back(VN[2]); + cptNouvellesMailles[PENTA6]++; + i1 = cptNouvellesMailles[PENTA6] - 1; + + newCNX[PENTA6].push_back(ng1); + newCNX[PENTA6].push_back(VN[3]); + newCNX[PENTA6].push_back(VN[0]); + newCNX[PENTA6].push_back(ng3); + newCNX[PENTA6].push_back(VN[5]); + newCNX[PENTA6].push_back(VN[2]); + cptNouvellesMailles[PENTA6]++; + i2 = cptNouvellesMailles[PENTA6] - 1; + + if (POSN[ng0 - 1] == 1) + { + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2); + } + else + { + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1); + } + } + + else if (VN[2] == -1 && VN[3] == -1) + { + // Les deux arêtes opposées sont [0,3] et [1,2] + + newCNX[PENTA6].push_back(ng0); + newCNX[PENTA6].push_back(VN[0]); + newCNX[PENTA6].push_back(VN[1]); + newCNX[PENTA6].push_back(ng3); + newCNX[PENTA6].push_back(VN[4]); + newCNX[PENTA6].push_back(VN[5]); + cptNouvellesMailles[PENTA6]++; + i1 = cptNouvellesMailles[PENTA6] - 1; + + newCNX[PENTA6].push_back(ng2); + newCNX[PENTA6].push_back(VN[5]); + newCNX[PENTA6].push_back(VN[1]); + newCNX[PENTA6].push_back(ng1); + newCNX[PENTA6].push_back(VN[4]); + newCNX[PENTA6].push_back(VN[0]); + cptNouvellesMailles[PENTA6]++; + i2 = cptNouvellesMailles[PENTA6] - 1; + + if (POSN[ng0 - 1] == 1) + { + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2); + } + else + { + GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2); + GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1); + } + } + else + ERREUR(" Intersection configuration not taken into account (case cptPI=4) "); + + // int nl1 = MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1; + // int nl2 = MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2; + // cout << "La maille TETRA4 " << it4 << " produit les mailles PENTA6-" << nl1 << " et PENTA6-" << nl2 << endl; +} diff --git a/src/Tools/MeshCut/MeshCut_Cas.hxx b/src/Tools/MeshCut/MeshCut_Cas.hxx new file mode 100644 index 000000000..0840280f8 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Cas.hxx @@ -0,0 +1,31 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MESHCUT_CAS_HXX__ +#define __MESHCUT_CAS_HXX__ + +namespace MESHCUT + { + void cas1(int VN[6], int it4); + void cas2(int VN[6], int it4); + void cas3(int VN[6], int it4); + void cas4(int VN[6], int it4); + } + +#endif diff --git a/src/Tools/MeshCut/MeshCut_Cube.cxx b/src/Tools/MeshCut/MeshCut_Cube.cxx new file mode 100644 index 000000000..62ef84613 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Cube.cxx @@ -0,0 +1,58 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MeshCut_Cube.hxx" + +#include + +using namespace MESHCUT; +using namespace std; + +Cube::Cube(float _x0, float _x1, float _y0, float _y1, float _z0, float _z1) +{ + x0 = _x0; + x1 = _x1; + y0 = _y0; + y1 = _y1; + z0 = _z0; + z1 = _z1; +} + +bool Cube::disjoint(Cube* c2) +{ + return (x0 > c2->x1 || x1 < c2->x0 || y0 > c2->y1 || y1 < c2->y0 || z0 > c2->z1 || z1 < c2->z0); +} + +bool Cube::contientNoeud(int ngnoeud, Maillage *MAILLAGE) +{ + float x = *(MAILLAGE->XX + ngnoeud - 1); + float y = *(MAILLAGE->YY + ngnoeud - 1); + float z = *(MAILLAGE->ZZ + ngnoeud - 1); + return (x >= x0 && x <= x1 && y >= y0 && y <= y1 && z >= z0 && z <= z1); +} + +void Cube::affichage() +{ + cout << "x0=" << x0 << " "; + cout << "x1=" << x1 << " "; + cout << "y0=" << y0 << " "; + cout << "y1=" << y1 << " "; + cout << "z0=" << z0 << " "; + cout << "z1=" << z1 << " "; +} diff --git a/src/Tools/MeshCut/MeshCut_Cube.hxx b/src/Tools/MeshCut/MeshCut_Cube.hxx new file mode 100644 index 000000000..03068d933 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Cube.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MESHCUT_CUBE_HXX__ +#define __MESHCUT_CUBE_HXX__ + +#include "MeshCut_Maillage.hxx" + +namespace MESHCUT + { + class Cube + { + public: + float x0, x1, y0, y1, z0, z1; + public: + Cube(float _x0, float _x1, float _y0, float _y1, float _z0, float _z1); + bool disjoint(Cube* c2); + bool contientNoeud(int ngnoeud, Maillage *MAILLAGE); + void affichage(); + }; + } + +#endif diff --git a/src/Tools/MeshCut/MeshCut_DC.cxx b/src/Tools/MeshCut/MeshCut_DC.cxx new file mode 100644 index 000000000..36bcae4b0 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_DC.cxx @@ -0,0 +1,1124 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// Classes et fonctions XMeshLab + +#include "MeshCut_Utils.hxx" +#include "MeshCut_Maillage.hxx" + +#include "MeshCut_Carre.hxx" +#include "MeshCut_Cube.hxx" + +#include "MeshCut_Fonctions.hxx" +#include "MeshCut_Cas.hxx" + +#include "MeshCut_Globals.hxx" + +#include +#include +#include +#include + +using namespace MESHCUT; +using namespace std; + +// ================================== DECLARATION DES VARIABLES GLOBALES ================================================== + +std::map MESHCUT::intersections; + +int MESHCUT::indexNouvellesMailles, MESHCUT::indexNouveauxNoeuds, MESHCUT::offsetMailles; +std::string MESHCUT::str_id_GMplus, MESHCUT::str_id_GMmoins; +Maillage *MESHCUT::MAILLAGE1, *MESHCUT::MAILLAGE2; + +std::vector MESHCUT::newXX, MESHCUT::newYY, MESHCUT::newZZ; +std::map > MESHCUT::newCNX; +std::map MESHCUT::cptNouvellesMailles; +std::map > MESHCUT::GMplus, MESHCUT::GMmoins; +std::vector MESHCUT::cutTetras; + +float *MESHCUT::DNP; +int *MESHCUT::POSN; + +std::string MESHCUT::str_id_maillagenew; + +float MESHCUT::normale[3], MESHCUT::pointPlan[3]; +float MESHCUT::d; +float MESHCUT::epsilon; + +bool MESHCUT::debug; +int MESHCUT::Naretes; + +// ================================== PROGRAMME PRINCIPAL ================================================== + +int main(int argc, char *argv[]) +{ + + debug = false; + string ficMEDin; + string ficMEDout; + float xNormal; + float yNormal; + float zNormal; + float xm; + float ym; + float zm; + float tolerance; + try + { + if (argc != 13) + throw std::exception(); + char *ficMEDin0 = argv[1]; + ficMEDin = (string) ficMEDin0; + char *ficMEDout0 = argv[2]; + ficMEDout = (string) ficMEDout0; + char *id_maillagenew = argv[3]; + str_id_maillagenew = (string) id_maillagenew; + + // Groupes créés + char *id_GMplus = argv[4]; + str_id_GMplus = (string) id_GMplus; + char *id_GMmoins = argv[5]; + str_id_GMmoins = (string) id_GMmoins; + + // Vecteur normal au plan de coupe + char *charxn = argv[6]; + xNormal = char2float(charxn); + char *charyn = argv[7]; + yNormal = char2float(charyn); + char *charzn = argv[8]; + zNormal = char2float(charzn); + + // Point du plan de coupe + char *charxm = argv[9]; + xm = char2float(charxm); + char *charym = argv[10]; + ym = char2float(charym); + char *charzm = argv[11]; + zm = char2float(charzm); + + // Tolérance : epsilon = tolérance * longueur arête moyenne - où epsilon est la tolérance absolue (distance) + char *chtolerance = argv[12]; + tolerance = char2float(chtolerance); + } + catch (...) + { + cout << endl; + cout << " Cut a tetrahedron mesh by a plane" << endl; + cout << " ---------------------------------" << endl; + cout << "Syntax:" << endl << endl; + cout << argv[0] << " input.med output.med resuMeshName aboveGroup belowGroup nx ny nz px py pz T " << endl; + cout << endl << "where:" << endl; + cout << " input.med = name of the original mesh file in med format" << endl; + cout << " output.med = name of the result mesh file in med format" << endl; + cout << " resuMeshName = name of the result mesh" << endl; + cout << " aboveGroup = name of the group of volumes above the cut plane" << endl; + cout << " belowGroups = name of the group of volumes below the cut plane" << endl; + cout << " nx ny nz = vector normal to the cut plane" << endl; + cout << " px py pz = a point of the cut plane" << endl; + cout << " T = 0 < T < 1 : vertices of a tetrahedron are considered as belonging" << endl; + cout << " the cut plane if their distance to the plane is inferior to L*T" << endl; + cout << " where L is the mean edge size of the tetrahedron" << endl; + ERREUR("--> check arguments!"); + } + + cout << "Cut by a plane :" << endl; + cout << " source mesh: " << ficMEDin << endl; + cout << " result mesh: " << ficMEDout << endl; + cout << " mesh name: " << str_id_maillagenew << endl; + cout << " group above plane: " << str_id_GMplus << endl; + cout << " group below plane: " << str_id_GMmoins << endl; + cout << " vector normal to the cut plane: xn=" << xNormal << " yn=" << yNormal << " zn=" << zNormal << endl; + cout << " point in the cut plane: xm=" << xm << " ym=" << ym << " zm=" << zm << endl; + cout << " tolerance: " << tolerance << endl; + cout << endl; + + if (tolerance <= 0.0) + ERREUR("Tolerance must not be negative or null"); + + // Il faut normer la normale + float normeNormal = sqrt(xNormal * xNormal + yNormal * yNormal + zNormal * zNormal); + if (normeNormal == 0.0) + ERREUR("null normal vector"); + normale[0] = xNormal / normeNormal; + normale[1] = yNormal / normeNormal; + normale[2] = zNormal / normeNormal; + + pointPlan[0] = xm; + pointPlan[1] = ym; + pointPlan[2] = zm; + + // Calcul du coefficient d de l'équation du plan xn x + yn y + zn n + d = 0 + d = -normale[0] * xm - normale[1] * ym - normale[2] * zm; + + intersections.clear(); + + // Initialisation des compteurs de nouvelles mailles + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + cptNouvellesMailles[tm] = 0; + } + + int V[6]; + int S[4]; // Signature du T4 courant + //int NG[4]; // Num. globaux des sommets + + // Acquisition maillage initial + //cout << chrono() << " - Acquisition du maillage initial" << endl; + MAILLAGE1 = new Maillage((string) "TEMP"); + MAILLAGE1->inputMED(ficMEDin); + cout << chrono() << " - End of mesh read" << endl; + indexNouveauxNoeuds = MAILLAGE1->nombreNoeudsMaillage; + + // Le maillage ne contient aucun TETRA4 : on rend le maillage initial sans modification + if (!MAILLAGE1->EFFECTIFS_TYPES[TETRA4]) + { + cout << "WARNING: mesh does not contain tetra4 elements, it will not be modified" << endl; + MAILLAGE1->ID = str_id_maillagenew; + MAILLAGE1->outputMED(ficMEDout); + cout << chrono() << " - Finished!" << endl << endl; + exit(0); + } + // A partir de cet instant le maillage contient forcément des TETRA4 + + + // Chargement des distances noeud-plan DNP + DNP = (float*) malloc(sizeof(float) * MAILLAGE1->nombreNoeudsMaillage); + for (int k = 0; k < MAILLAGE1->nombreNoeudsMaillage; k++) + DNP[k] = distanceNoeudPlan(k + 1); + cout << chrono() << " - End of computation of distances between nodes and plane" << endl; + + // Longueur d'arête moyenne des T4 intersectant le plan de coupe + float LONGUEURS = 0.0; + int cptLONGUEURS = 0; + for (int it4 = 0; it4 < MAILLAGE1->EFFECTIFS_TYPES[TETRA4]; it4++) + { + bool plus = false; + bool moins = false; + int *offset = MAILLAGE1->CNX[TETRA4] + 4 * it4; + for (int is = 0; is < 4; is++) + { + int ng = *(offset + is); + if (DNP[ng - 1] > 0.0) + plus = true; + else if (DNP[ng - 1] < 0.0) + moins = true; + } + if (plus && moins) + { + // Ce tetra est à cheval sur le plan de coupe: on calcule ses longueurs d'arêtes + LONGUEURS += longueurSegment(*(offset + 0), *(offset + 1)); + cptLONGUEURS++; + LONGUEURS += longueurSegment(*(offset + 0), *(offset + 2)); + cptLONGUEURS++; + LONGUEURS += longueurSegment(*(offset + 0), *(offset + 3)); + cptLONGUEURS++; + LONGUEURS += longueurSegment(*(offset + 1), *(offset + 2)); + cptLONGUEURS++; + LONGUEURS += longueurSegment(*(offset + 1), *(offset + 3)); + cptLONGUEURS++; + LONGUEURS += longueurSegment(*(offset + 2), *(offset + 3)); + cptLONGUEURS++; + } + } + + // Aucun TETRA4 intercepté par le plan de coupe : on rend MAILLAGE1 + if (cptLONGUEURS == 0) + { + cout + << "WARNING: the cut plane does not cut any tetra4 element, initial mesh will not be modified" + << endl; + MAILLAGE1->ID = str_id_maillagenew; + MAILLAGE1->outputMED(ficMEDout); + cout << chrono() << " - Finished!" << endl << endl; + exit(0); + } + // A partir de cet instant le maillage contient forcément des TETRA4 intersectant le plan de coupe + + + float longueurMoyenne = LONGUEURS / cptLONGUEURS; + epsilon = tolerance * longueurMoyenne; + + int nT4coupe = cptLONGUEURS / 6; + cout << chrono() << " - End of computation of mean length of tetra4 edges near the cut plane" << endl; + + cout << "Number of tetra4 to be cut = " << nT4coupe << endl; + cout << "Mean length = " << longueurMoyenne << endl; + cout << "Tolerance = " << tolerance << endl; + cout << "Epsilon = " << epsilon << endl; + + // Détermination des positions de noeuds par rapport au plan de coupe - POSN + POSN = (int*) malloc(sizeof(int) * MAILLAGE1->nombreNoeudsMaillage); + for (int k = 0; k < MAILLAGE1->nombreNoeudsMaillage; k++) + { + if (DNP[k] > epsilon) + POSN[k] = 1; + else if (DNP[k] < -epsilon) + POSN[k] = -1; + else + POSN[k] = 0; + } + cout << chrono() << " - End of nodes qualification above or below the cut plane" << endl; + cout << "Start of iteration on tetra4" << endl; + + for (int it4 = 0; it4 < MAILLAGE1->EFFECTIFS_TYPES[TETRA4]; it4++) + { + + for (int is = 0; is < 4; is++) + { + int ng = *(MAILLAGE1->CNX[TETRA4] + 4 * it4 + is); + //NG[is] = ng; + S[is] = *(POSN + ng - 1); + } + + // ------------------------------------------------------------------- + + if (S[0] == -1 && S[1] == -1 && S[2] == -1 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == -1 && S[2] == -1 && S[3] == 0) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == -1 && S[2] == -1 && S[3] == 1) + { // Cas 3 - Arêtes 2 4 5 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = intersectionSegmentPlan(it4, 5); + cas3(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == -1 && S[2] == 0 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == -1 && S[2] == 0 && S[3] == 0) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == -1 && S[2] == 0 && S[3] == 1) + { // Cas 2, arêtes 2 4 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == -1 && S[2] == 1 && S[3] == -1) + { // Cas 3, arêtes 1 3 5 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas3(V, it4); + } + + else if (S[0] == -1 && S[1] == -1 && S[2] == 1 && S[3] == 0) + { // Cas 2, arêtes 1 3 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == -1 && S[1] == -1 && S[2] == 1 && S[3] == 1) + { // Cas 4, arêtes 1 2 3 4 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas4(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == 0 && S[2] == -1 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == 0 && S[2] == -1 && S[3] == 0) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == 0 && S[2] == -1 && S[3] == 1) + { // Cas 2, arêtes 2 5 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == 0 && S[2] == 0 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == 0 && S[2] == 0 && S[3] == 0) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == -1 && S[1] == 0 && S[2] == 0 && S[3] == 1) + { // Cas 1, arête 2 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == 0 && S[2] == 1 && S[3] == -1) + { // Cas 2, arêtes 1 5 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + else if (S[0] == -1 && S[1] == 0 && S[2] == 1 && S[3] == 0) + { // Cas 1, arête 1 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == -1 && S[1] == 0 && S[2] == 1 && S[3] == 1) + { // Cas 2, arêtes 1 2 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == 1 && S[2] == -1 && S[3] == -1) + { // Cas 3, arêtes 0 3 4 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas3(V, it4); + } + + else if (S[0] == -1 && S[1] == 1 && S[2] == -1 && S[3] == 0) + { // Cas 2, arêtes 0 3 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == -1 && S[1] == 1 && S[2] == -1 && S[3] == 1) + { // Cas 4, arêtes 0 2 3 5 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas4(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == 1 && S[2] == 0 && S[3] == -1) + { // Cas 2, arêtes 0 4 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == -1 && S[1] == 1 && S[2] == 0 && S[3] == 0) + { // Cas 1, arête 0 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == -1 && S[1] == 1 && S[2] == 0 && S[3] == 1) + { // Cas 2, arêtes 0 2 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == -1 && S[1] == 1 && S[2] == 1 && S[3] == -1) + { // Cas 4, arêtes 0 1 4 5 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = intersectionSegmentPlan(it4, 5); + cas4(V, it4); + } + + else if (S[0] == -1 && S[1] == 1 && S[2] == 1 && S[3] == 0) + { // Cas 2, arêtes 0 1 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == -1 && S[1] == 1 && S[2] == 1 && S[3] == 1) + { // Cas 3, arêtes 0 1 2 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas3(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == -1 && S[2] == -1 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == -1 && S[2] == -1 && S[3] == 0) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == -1 && S[2] == -1 && S[3] == 1) + { // Cas 2, arêtes 4 5 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == -1 && S[2] == 0 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == -1 && S[2] == 0 && S[3] == 0) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == -1 && S[2] == 0 && S[3] == 1) + { // Cas 1, arête 4 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas1(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == -1 && S[2] == 1 && S[3] == -1) + { // Cas 2, arêtes 3 5 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + else if (S[0] == 0 && S[1] == -1 && S[2] == 1 && S[3] == 0) + { // Cas 1, arête 3 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == 0 && S[1] == -1 && S[2] == 1 && S[3] == 1) + { // Cas 2, arêtes 3 4 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == 0 && S[2] == -1 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == 0 && S[2] == -1 && S[3] == 0) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == 0 && S[2] == -1 && S[3] == 1) + { // Cas 1, arête 5 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas1(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == 0 && S[2] == 0 && S[3] == -1) + GMmoins[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == 0 && S[2] == 0 && S[3] == 0) + { + cout << "WARNING: TETRA4 number " << it4 + << " entirely in the tolerance zone near the cut plane" << endl; + cout << " --> affected to group " << str_id_GMmoins << endl; + GMmoins[TETRA4].push_back(it4); + } + + else if (S[0] == 0 && S[1] == 0 && S[2] == 0 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == 0 && S[2] == 1 && S[3] == -1) + { // Cas 1, arête 5 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas1(V, it4); + } + + else if (S[0] == 0 && S[1] == 0 && S[2] == 1 && S[3] == 0) + GMplus[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == 0 && S[2] == 1 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == 1 && S[2] == -1 && S[3] == -1) + { // Cas 2, arêtes 3 4 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == 0 && S[1] == 1 && S[2] == -1 && S[3] == 0) + { // Cas 1, arête 3 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == 0 && S[1] == 1 && S[2] == -1 && S[3] == 1) + { // Cas 2, arêtes 3 5 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == 1 && S[2] == 0 && S[3] == -1) + { // Cas 1, arête 4 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == 0 && S[1] == 1 && S[2] == 0 && S[3] == 0) + GMplus[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == 1 && S[2] == 0 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + // ------------------------------------------------------------------- + + else if (S[0] == 0 && S[1] == 1 && S[2] == 1 && S[3] == -1) + { // Cas 2, arêtes 4 5 + V[0] = -1; + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + else if (S[0] == 0 && S[1] == 1 && S[2] == 1 && S[3] == 0) + GMplus[TETRA4].push_back(it4); + + else if (S[0] == 0 && S[1] == 1 && S[2] == 1 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == -1 && S[2] == -1 && S[3] == -1) + { // Cas 3, arêtes 0 1 2 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas3(V, it4); + } + + else if (S[0] == 1 && S[1] == -1 && S[2] == -1 && S[3] == 0) + { // Cas 2, arêtes 0 1 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == 1 && S[1] == -1 && S[2] == -1 && S[3] == 1) + { // Cas 4, arêtes 0 1 4 5 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = intersectionSegmentPlan(it4, 5); + cas4(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == -1 && S[2] == 0 && S[3] == -1) + { // Cas 2, arêtes 0 2 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == 1 && S[1] == -1 && S[2] == 0 && S[3] == 0) + { // Cas 1, arête 0 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == 1 && S[1] == -1 && S[2] == 0 && S[3] == 1) + { // Cas 2, arêtes 0 4 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == -1 && S[2] == 1 && S[3] == -1) + { // Cas 4, arêtes 0 2 3 5 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas4(V, it4); + } + + else if (S[0] == 1 && S[1] == -1 && S[2] == 1 && S[3] == 0) + { // Cas 2, arêtes 0 3 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == 1 && S[1] == -1 && S[2] == 1 && S[3] == 1) + { // Cas 3, arêtes 0 3 4 + V[0] = intersectionSegmentPlan(it4, 0); + V[1] = -1; + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas3(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == 0 && S[2] == -1 && S[3] == -1) + { // Cas 2, arêtes 1 2 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == 1 && S[1] == 0 && S[2] == -1 && S[3] == 0) + { // Cas 1, arête 1 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == 1 && S[1] == 0 && S[2] == -1 && S[3] == 1) + { // Cas 2, arêtes 1 5 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = -1; + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == 0 && S[2] == 0 && S[3] == -1) + { // Cas 1, arête 2 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = -1; + cas1(V, it4); + } + + else if (S[0] == 1 && S[1] == 0 && S[2] == 0 && S[3] == 0) + GMplus[TETRA4].push_back(it4); + + else if (S[0] == 1 && S[1] == 0 && S[2] == 0 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == 0 && S[2] == 1 && S[3] == -1) + { // Cas 2, arêtes 2 5 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas2(V, it4); + } + + else if (S[0] == 1 && S[1] == 0 && S[2] == 1 && S[3] == 0) + GMplus[TETRA4].push_back(it4); + + else if (S[0] == 1 && S[1] == 0 && S[2] == 1 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == 1 && S[2] == -1 && S[3] == -1) + { // Cas 4, arêtes 1 2 3 4 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas4(V, it4); + } + + else if (S[0] == 1 && S[1] == 1 && S[2] == -1 && S[3] == 0) + { // Cas 2, arêtes 1 3 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == 1 && S[1] == 1 && S[2] == -1 && S[3] == 1) + { // Cas 3, arêtes 1 3 5 + V[0] = -1; + V[1] = intersectionSegmentPlan(it4, 1); + V[2] = -1; + V[3] = intersectionSegmentPlan(it4, 3); + V[4] = -1; + V[5] = intersectionSegmentPlan(it4, 5); + cas3(V, it4); + } + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == 1 && S[2] == 0 && S[3] == -1) + { // Cas 2, arêtes 2 4 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = -1; + cas2(V, it4); + } + + else if (S[0] == 1 && S[1] == 1 && S[2] == 0 && S[3] == 0) + GMplus[TETRA4].push_back(it4); + + else if (S[0] == 1 && S[1] == 1 && S[2] == 0 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + // ------------------------------------------------------------------- + + else if (S[0] == 1 && S[1] == 1 && S[2] == 1 && S[3] == -1) + { // Cas 3, arêtes 2 4 5 + V[0] = -1; + V[1] = -1; + V[2] = intersectionSegmentPlan(it4, 2); + V[3] = -1; + V[4] = intersectionSegmentPlan(it4, 4); + V[5] = intersectionSegmentPlan(it4, 5); + cas3(V, it4); + } + + else if (S[0] == 1 && S[1] == 1 && S[2] == 1 && S[3] == 0) + GMplus[TETRA4].push_back(it4); + + else if (S[0] == 1 && S[1] == 1 && S[2] == 1 && S[3] == 1) + GMplus[TETRA4].push_back(it4); + + else + ERREUR("Case not taken into account"); + + } + cout << chrono() << " - End of iteration on tetra4" << endl; + + // cout << "indexNouveauxNoeuds = " << indexNouveauxNoeuds << endl; + newXX.resize(indexNouveauxNoeuds - MAILLAGE1->nombreNoeudsMaillage); + newYY.resize(indexNouveauxNoeuds - MAILLAGE1->nombreNoeudsMaillage); + newZZ.resize(indexNouveauxNoeuds - MAILLAGE1->nombreNoeudsMaillage); + + if (cptNouvellesMailles[TETRA4]) + newCNX[TETRA4].resize(4 * cptNouvellesMailles[TETRA4]); + if (cptNouvellesMailles[PYRAM5]) + newCNX[PYRAM5].resize(5 * cptNouvellesMailles[PYRAM5]); + if (cptNouvellesMailles[PENTA6]) + newCNX[PENTA6].resize(6 * cptNouvellesMailles[PENTA6]); + + // ========================================================================================= + // 2. Constitution du maillage final + // ========================================================================================= + + cout << chrono() << " - Constitution of final mesh" << endl; + + MAILLAGE2 = new Maillage(str_id_maillagenew); + MAILLAGE2->dimensionMaillage = MAILLAGE1->dimensionMaillage; + MAILLAGE2->dimensionEspace = MAILLAGE1->dimensionEspace; + strcpy(MAILLAGE2->axisname, MAILLAGE1->axisname); + strcpy(MAILLAGE2->unitname, MAILLAGE1->unitname); + MAILLAGE2->nombreNoeudsMaillage = indexNouveauxNoeuds; + MAILLAGE2->nombreMaillesMaillage = MAILLAGE1->nombreMaillesMaillage + cptNouvellesMailles[TETRA4] + + cptNouvellesMailles[PYRAM5] + cptNouvellesMailles[PENTA6]; + + // ---------- Coordonnées + // Optimisation de la mémoire au détriment du temps + + // Héritage des coordonnées MAILLAGE1 + MAILLAGE2->XX = (float*) malloc(sizeof(float) * MAILLAGE2->nombreNoeudsMaillage); + for (int i = 0; i < MAILLAGE1->nombreNoeudsMaillage; i++) + *(MAILLAGE2->XX + i) = *(MAILLAGE1->XX + i); + free(MAILLAGE1->XX); + MAILLAGE2->YY = (float*) malloc(sizeof(float) * MAILLAGE2->nombreNoeudsMaillage); + for (int i = 0; i < MAILLAGE1->nombreNoeudsMaillage; i++) + *(MAILLAGE2->YY + i) = *(MAILLAGE1->YY + i); + free(MAILLAGE1->YY); + MAILLAGE2->ZZ = (float*) malloc(sizeof(float) * MAILLAGE2->nombreNoeudsMaillage); + for (int i = 0; i < MAILLAGE1->nombreNoeudsMaillage; i++) + *(MAILLAGE2->ZZ + i) = *(MAILLAGE1->ZZ + i); + free(MAILLAGE1->ZZ); + + // Coordonnées des noeuds créés + for (int i = 0; i < MAILLAGE2->nombreNoeudsMaillage - MAILLAGE1->nombreNoeudsMaillage; i++) + { + *(MAILLAGE2->XX + MAILLAGE1->nombreNoeudsMaillage + i) = newXX[i]; + *(MAILLAGE2->YY + MAILLAGE1->nombreNoeudsMaillage + i) = newYY[i]; + *(MAILLAGE2->ZZ + MAILLAGE1->nombreNoeudsMaillage + i) = newZZ[i]; + // cout << "Nouveaux noeuds, indice " << i << " : " << newXX[i] << " " << newYY[i] << " " << newZZ[i] << " " << endl; + } + + // Legacy mailles maillage 1 (volumes seulement) + for (int itm = (int) TETRA4; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + if (tm != TETRA4 && tm != PYRAM5 && tm != PENTA6) + { + // Pour les types autres que TETRA4 PYRAM5 PENTA6 on fait seulement pointer CNX2 vers CNX1 + if (MAILLAGE1->EFFECTIFS_TYPES[tm]) + MAILLAGE2->CNX[tm] = MAILLAGE1->CNX[tm]; + MAILLAGE2->EFFECTIFS_TYPES[tm] = MAILLAGE1->EFFECTIFS_TYPES[tm]; + } + else + { + // Pour les types TETRA4 PYRAM5 PENTA6 on recopie CNX1 et on ajoute à la suite les newCNX + // cout << "Legacy " << tm << " effectif " << MAILLAGE1->EFFECTIFS_TYPES[tm] << endl; + int tailleType = Nnoeuds(tm); + + MAILLAGE2->CNX[tm] = (int*) malloc(sizeof(int) * tailleType * (MAILLAGE1->EFFECTIFS_TYPES[tm] + + cptNouvellesMailles[tm])); + for (int i = 0; i < MAILLAGE1->EFFECTIFS_TYPES[tm]; i++) + for (int j = 0; j < tailleType; j++) + *(MAILLAGE2->CNX[tm] + tailleType * i + j) = *(MAILLAGE1->CNX[tm] + tailleType * i + j); + + for (int i = 0; i < cptNouvellesMailles[tm]; i++) + for (int j = 0; j < tailleType; j++) + *(MAILLAGE2->CNX[tm] + tailleType * (MAILLAGE1->EFFECTIFS_TYPES[tm] + i) + j) = newCNX[tm][i * tailleType + + j]; + + MAILLAGE2->EFFECTIFS_TYPES[tm] = MAILLAGE1->EFFECTIFS_TYPES[tm] + cptNouvellesMailles[tm]; + } + } + + // Restit CNX + + // cout << "Maillage 2 - CNX TETRA4 : " << endl; + // ; + // for (int i = 0; i < MAILLAGE2->EFFECTIFS_TYPES[TETRA4]; i++) + // { + // cout << "Maille " << i << " : "; + // for (int j = 0; j < 4; j++) + // cout << MAILLAGE2->CNX[TETRA4][i * 4 + j] << " "; + // cout << endl; + // } + // cout << endl; + // cout << "Maillage 2 - CNX PENTA6 : " << endl; + // ; + // for (int i = 0; i < MAILLAGE2->EFFECTIFS_TYPES[PENTA6]; i++) + // { + // cout << "Maille " << i << " : "; + // for (int j = 0; j < 6; j++) + // cout << MAILLAGE2->CNX[PENTA6][i * 6 + j] << " "; + // cout << endl; + // } + // cout << endl; + + // Groupes de mailles + // MAILLAGE2->GM = MAILLAGE1->GM; + MAILLAGE2->GN.clear(); + MAILLAGE2->GM.clear(); + MAILLAGE2->GM[str_id_GMplus] = GMplus; + MAILLAGE2->GM[str_id_GMmoins] = GMmoins; + + // MAILLAGE2->GN = MAILLAGE1->GN; + + MAILLAGE2->eliminationMailles(TETRA4, cutTetras); + + cout << chrono() << " - MED file writing" << endl; + + MAILLAGE2->outputMED(ficMEDout); + cout << chrono() << " - Finished!" << endl << endl; + + return 0; + +} diff --git a/src/Tools/MeshCut/MeshCut_Fonctions.cxx b/src/Tools/MeshCut/MeshCut_Fonctions.cxx new file mode 100644 index 000000000..28ca3dc56 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Fonctions.cxx @@ -0,0 +1,188 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MeshCut_Fonctions.hxx" +#include "MeshCut_Globals.hxx" + +#include +#include + +using namespace MESHCUT; +using namespace std; + +//================================================================================================= +// intersectionSegmentPlan +//================================================================================================= + +float MESHCUT::longueurSegment(int ngA, int ngB) +{ + float A[3], B[3]; + A[0] = MAILLAGE1->XX[ngA - 1]; + A[1] = MAILLAGE1->YY[ngA - 1]; + A[2] = MAILLAGE1->ZZ[ngA - 1]; + B[0] = MAILLAGE1->XX[ngB - 1]; + B[1] = MAILLAGE1->YY[ngB - 1]; + B[2] = MAILLAGE1->ZZ[ngB - 1]; + float dx = B[0] - A[0]; + float dy = B[1] - A[1]; + float dz = B[2] - A[2]; + return sqrt(dx * dx + dy * dy + dz * dz); +} + +float MESHCUT::distanceNoeudPlan(float point[3]) +{ + return normale[0] * point[0] + normale[1] * point[1] + normale[2] * point[2] + d; +} + +float MESHCUT::distanceNoeudPlan(int ng) +{ + float A[3]; + A[0] = MAILLAGE1->XX[ng - 1]; + A[1] = MAILLAGE1->YY[ng - 1]; + A[2] = MAILLAGE1->ZZ[ng - 1]; + return distanceNoeudPlan(A); +} + +int MESHCUT::positionNoeudPlan(int indiceNoeud) +{ + if (distanceNoeudPlan(indiceNoeud + 1) > epsilon) + return 1; + else if (distanceNoeudPlan(indiceNoeud + 1) < -epsilon) + return -1; + else + return 0; +} + +/*! + * Equation paramétrique de la droite AB: OP = OA + lambda AB + * + * Fonction caractéristique du plan : PI(X,Y,Z) = nx X + ny Y + nz Z + d + * + * Pour un point P de la droite: PI(OP) = PI(OA) + lambda n.AB avec n=(nx,ny,nz), + * L'intersection AB/plan est donnée par le point P tel que PI(OP)=0. + * + * Il lui correspond la coordonnée lambda = - PI(OA) / n.AB. + * + * Cette intersection est dans le segment si lambda est dans [0,1] + */ +int MESHCUT::intersectionSegmentPlan(int it4, int na) +{ + + int ngA, ngB; // Numéros des noeuds extrémités AB + float lambda, ps; //, ab; // ab = longueur AB + float A[3], B[3]; + + // Détermination des ng des extrémités de l'arête passée en argument na + int * offset = MAILLAGE1->CNX[TETRA4] + 4 * it4; + if (na == 0) + { + ngA = *(offset + 0); + ngB = *(offset + 1); + } + else if (na == 1) + { + ngA = *(offset + 0); + ngB = *(offset + 2); + } + else if (na == 2) + { + ngA = *(offset + 0); + ngB = *(offset + 3); + } + else if (na == 3) + { + ngA = *(offset + 1); + ngB = *(offset + 2); + } + else if (na == 4) + { + ngA = *(offset + 1); + ngB = *(offset + 3); + } + else if (na == 5) + { + ngA = *(offset + 2); + ngB = *(offset + 3); + } + else + ERREUR("Edge number superior to 6"); + + string cle1 = int2string(ngA) + (string) "_" + int2string(ngB); + string cle2 = int2string(ngB) + (string) "_" + int2string(ngA); + + if (intersections[cle1]) + return intersections[cle1]; + + else + { + + A[0] = MAILLAGE1->XX[ngA - 1]; + A[1] = MAILLAGE1->YY[ngA - 1]; + A[2] = MAILLAGE1->ZZ[ngA - 1]; + B[0] = MAILLAGE1->XX[ngB - 1]; + B[1] = MAILLAGE1->YY[ngB - 1]; + B[2] = MAILLAGE1->ZZ[ngB - 1]; + + // // Longueur AB + // float lx = B[0] - A[0], ly = B[1] - A[1], lz = B[2] - A[2]; + // ab = sqrt(lx * lx + ly * ly + lz * lz); + // // La longueur maximale théorique est 2 epsilon + // if (ab < 2 * epsilon * 0.9) + // ERREUR("Arête de longueur inférieure au minimum théorique 2 epsilon"); + + // Calcul du produit scalaire AB.n + ps = 0.0; + for (int k = 0; k < 3; k++) + ps += (B[k] - A[k]) * normale[k]; + // ps = ps / ab ; + + if (debug) + { + cout << "Routine ISP : arête " << na << " - ngA=" << ngA << " ngB=" << ngB << endl; + cout << "A : " << A[0] << ' ' << A[1] << ' ' << A[2] << endl; + cout << "B : " << B[0] << ' ' << B[1] << ' ' << B[2] << endl; + cout << "N : " << normale[0] << ' ' << normale[1] << ' ' << normale[2] << endl; + } + + if (fabs(ps) == 0.0) + ERREUR("Error on null scalar product"); + + // PS non nul: l'intersection AB/plan existe + + lambda = -distanceNoeudPlan(A) / ps; + + float inter[3]; + for (int k = 0; k < 3; k++) + inter[k] = A[k] + lambda * (B[k] - A[k]); + newXX.push_back(inter[0]); + newYY.push_back(inter[1]); + newZZ.push_back(inter[2]); + indexNouveauxNoeuds++; + intersections[cle1] = indexNouveauxNoeuds; + intersections[cle2] = indexNouveauxNoeuds; + + // cout << "création noeud " << indexNouveauxNoeuds << " : " << inter[0] << " " << inter[1] << " " << inter[2] + // << endl; + if (debug) + cout << " sortie nouveau noeud, lambda = " << lambda << " , noeud = " << indexNouveauxNoeuds << endl; + return indexNouveauxNoeuds; + + } +} + diff --git a/src/Tools/MeshCut/MeshCut_Fonctions.hxx b/src/Tools/MeshCut/MeshCut_Fonctions.hxx new file mode 100644 index 000000000..cee002f34 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Fonctions.hxx @@ -0,0 +1,36 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MESHCUT_FONCTION_HXX__ +#define __MESHCUT_FONCTION_HXX__ + +namespace MESHCUT + { + float longueurSegment(int ngA, int ngB); + + float distanceNoeudPlan(float point[3]); + + float distanceNoeudPlan(int ng); + + int positionNoeudPlan(int indiceNoeud); + + int intersectionSegmentPlan(int it4, int na); + } + +#endif diff --git a/src/Tools/MeshCut/MeshCut_Globals.hxx b/src/Tools/MeshCut/MeshCut_Globals.hxx new file mode 100644 index 000000000..fc1f83153 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Globals.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MESHCUT_GLOBALS_HXX__ +#define __MESHCUT_GLOBALS_HXX__ + +#include "MeshCut_Maillage.hxx" + +#include +#include +#include + +namespace MESHCUT + { + /*! Table des points d'intersection calculés. + * Si on a calculé une intersection entre le plan et un segment reliant N1 et N2 + * de numéros globaux n1 et n2, on stocke dans ce tableau, sous les libellés "n1_n2" et "n2_n1", + * le numéro global du point d'intersection (noeud créé). + * On évite ainsi de calculer deux fois l'intersection d'une même arête de T4 avec le plan + */ + extern std::map intersections; + + extern int indexNouvellesMailles, indexNouveauxNoeuds, offsetMailles; + extern std::string str_id_GMplus, str_id_GMmoins; + extern Maillage *MAILLAGE1, *MAILLAGE2; + + extern std::vector newXX, newYY, newZZ; + extern std::map > newCNX; + extern std::map cptNouvellesMailles; + extern std::map > GMplus, GMmoins; + extern std::vector cutTetras; + + extern float *DNP; //!< Distance Noeud Plan + extern int *POSN; //!< Version -1/0/+1 du précédent, selon epsilon + + extern std::string str_id_maillagenew; + + extern float normale[3], pointPlan[3]; //!< Définition du plan de coupe + extern float d; //!< coefficient constant de l'équation du plan de coupe + extern float epsilon; //!< distance en dessous de laquelle un point est considéré comme appartenant au plan de coupe + + extern bool debug; + extern int Naretes; + } + +#endif diff --git a/src/Tools/MeshCut/MeshCut_Maillage.cxx b/src/Tools/MeshCut/MeshCut_Maillage.cxx new file mode 100644 index 000000000..0ae4437e0 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Maillage.cxx @@ -0,0 +1,1789 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MeshCut_Maillage.hxx" +#include "MeshCut_Cube.hxx" + +#include +#include +#include +#include +#include +#include + +using namespace MESHCUT; +using namespace std; + +Maillage::Maillage(std::string _ID) +{ + ID = _ID; + nombreNoeudsMaillage = 0; + nombreMaillesMaillage = 0; + //nPOI1=0; nSEG2=0; nSEG3=0; nTRIA3=0; nTRIA6=0; nQUAD4=0; nQUAD8=0; nTETRA4=0; nTETRA10=0; nPYRAM5=0; nPYRAM13=0; nPENTA6=0; nPENTA15=0; nHEXA8=0; nHEXA20=0; + GM.clear(); + GN.clear(); + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + EFFECTIFS_TYPES[(TYPE_MAILLE) itm] = 0; +} + +Maillage::~Maillage() +{ +} + +void Maillage::creationGMtype(TYPE_MAILLE tm, std::string nomGMtype) +{ + //cout << "Creation GM type, groupe " << nomGMtype << endl; + for (int nl = 0; nl < EFFECTIFS_TYPES[tm]; nl++) + GM[nomGMtype][tm].push_back(nl); + GM[nomGMtype][tm].resize(EFFECTIFS_TYPES[tm]); + sort(GM[nomGMtype][tm].begin(), GM[nomGMtype][tm].end()); +} + +void Maillage::afficheMailles(TYPE_MAILLE tm) +{ + cout << "Affichage des mailles du type " << TM2string(tm) << " (effectif " << EFFECTIFS_TYPES[tm] << "): " << endl; + if (EFFECTIFS_TYPES[tm]) + { + // Boucle sur les connectivités d'un type tm + int nnoeuds = Nnoeuds(tm); + for (int i = 0; i < EFFECTIFS_TYPES[tm]; i++) + { + cout << "\tMaille " << i << " :" << endl; + //Boucle sur les noeuds de la maille de numéro local i dans le type tm + int * offset = CNX[tm] + nnoeuds * i; + for (int j = 0; j < nnoeuds; j++) + { + int ngnoeud = *(offset + j); + //cout << "\t\t" << X[ngnoeud-1] << " " << Y[ngnoeud-1] << " " << Z[ngnoeud-1] << endl; + cout << "\t" << ngnoeud << "\t" << *(XX + ngnoeud - 1) << " " << *(YY + ngnoeud - 1) << " " << *(ZZ + ngnoeud - 1) << endl; + } + } + cout << endl; + } +} + +void Maillage::listeMaillesType(TYPE_MAILLE tm) +{ + cout << "La fonction \"Restitution des mailles par type\" est obsolète " << endl; + + // cout << "Restitution des mailles du type " << TM2string(tm) << " (effectif " << EFFECTIFS_TYPES[tm] << "): " << endl; + // if (EFFECTIFS_TYPES[tm]) + // for (int i = 0; i < IDS_MAILLES[tm].size(); i++) + // cout << IDS_MAILLES[tm][i] << " "; + // cout << endl; +} + +void Maillage::listeMaillesTousTypes() +{ + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + listeMaillesType(tm); + } +} + +void Maillage::listeMaillesParGM() +{ + cout << "Liste des mailles par GM : " << endl; + for (map > >::iterator I = GM.begin(); I != GM.end(); I++) + listeMaillesGM(I->first); +} + +void Maillage::listeMaillesGM(std::string nomGM) +{ + cout << "Liste des mailles du groupe " << nomGM << " : " << endl; + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + if (GM[nomGM][tm].size()) + { + cout << "\t" << TM2string(tm) << " : "; + for (unsigned int j = 0; j < GM[nomGM][tm].size(); j++) + cout << GM[nomGM][tm][j] << " "; + cout << endl; + } + } +} + +//void Maillage::listeMaillesGMordonne(std::string nomGM) +//{ +// cout << "Liste ordonnée des mailles du groupe " << nomGM << " (" << GM[nomGM].size() << " mailles) : "; +// sort(GM[nomGM].begin(), GM[nomGM].end()); +// for (int j = 0; j < GM[nomGM].size(); j++) +// cout << GM[nomGM][j] << " "; +// cout << endl; +//} + +void Maillage::listeNoeuds() +{ + cout << "Liste des noeuds du maillage : " << endl; + for (int i = 0; i < nombreNoeudsMaillage; i++) + cout << "\t" << *(XX + i) << " " << *(YY + i) << " " << *(ZZ + i) << endl; + cout << endl; +} + +void Maillage::listeNoeudsGN(std::string nomGN) +{ + cout << "Liste brute des noeuds du groupe " << nomGN << " (" << GN[nomGN].size() << " noeuds) : "; + for (unsigned int j = 0; j < GN[nomGN].size(); j++) + cout << GN[nomGN][j] << " "; + cout << endl; +} + +void Maillage::listeNoeudsGNordonne(std::string nomGN) +{ + cout << "Liste ordonnée des noeuds du groupe " << nomGN << " (" << GN[nomGN].size() << " noeuds) : "; + sort(GN[nomGN].begin(), GN[nomGN].end()); + for (unsigned int j = 0; j < GN[nomGN].size(); j++) + cout << GN[nomGN][j] << " "; + cout << endl; +} + +std::vector Maillage::G(int i, TYPE_MAILLE tm) +{ + vector G; + float x = 0.0; + float y = 0.0; + float z = 0.0; + int nn = NnoeudsGeom(tm); + for (int j = 0; j < nn; j++) + { + int ng = CNX[tm][nn * i + j]; + x += XX[ng - 1]; + y += YY[ng - 1]; + z += ZZ[ng - 1]; + } + G.push_back(x / nn); + G.push_back(y / nn); + G.push_back(z / nn); + G.resize(3); + return G; +} + +float Maillage::distanceNoeudMaille(int ngnoeud, int imaille, TYPE_MAILLE tm) +{ + float x, y, z; + float x0 = XX[ngnoeud - 1]; + float y0 = YY[ngnoeud - 1]; + float z0 = ZZ[ngnoeud - 1]; + int nn = NnoeudsGeom(tm); + float d1 = 1000000000000.0; + float d; + for (int j = 0; j < nn; j++) + { + int ng = CNX[tm][nn * imaille + j]; // Noeud courant dans la maille + x = XX[ng - 1]; + y = YY[ng - 1]; + z = ZZ[ng - 1]; + d = sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0)); + if (d < d1) + d1 = d; + } + return d1; +} + +/*! + * Retourne le ng du noeud le plus proche de ngnoeud dans la maille imaille du type tm + */ +int Maillage::noeudVoisin(int ngnoeud, int imaille, TYPE_MAILLE tm) +{ + float x, y, z; + int ngv; + float x0 = XX[ngnoeud - 1]; + float y0 = YY[ngnoeud - 1]; + float z0 = ZZ[ngnoeud - 1]; + int nn = NnoeudsGeom(tm); + float d1 = 1000000000000.0; + float d; + for (int j = 0; j < nn; j++) + { + int ng = CNX[tm][nn * imaille + j]; // Noeud courant dans la maille + x = XX[ng - 1]; + y = YY[ng - 1]; + z = ZZ[ng - 1]; + d = sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0)); + if (d < d1) + { + d1 = d; + ngv = ng; + } + } + return ngv; +} + +float Maillage::distanceNoeudNoeud(int ng1, int ng2) +{ + float x1, x2, y1, y2, z1, z2; + x1 = XX[ng1 - 1]; + y1 = YY[ng1 - 1]; + z1 = ZZ[ng1 - 1]; + x2 = XX[ng2 - 1]; + y2 = YY[ng2 - 1]; + z2 = ZZ[ng2 - 1]; + return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2)); +} + +//void Maillage::encombrements() +//{ +// float ex = 0.0; +// float ey = 0.0; +// float ez = 0.0; +// +// for (int itm = (int) SEG2; itm <= (int) HEXA20; itm++) +// { +// TYPE_MAILLE tm = (TYPE_MAILLE) itm; +// if (MAILLAGE->EFFECTIFS_TYPES[tm]) +// { +// int nnoeuds = Nnoeuds(tm); +// for (int i = 0; i < CON[tm].size() / nnoeuds; i++) +// { +// //Boucle sur les noeuds de la maille de numéro local i dans le type tm +// for (int j = 0; j < nnoeuds; j++) +// { +// //..... CON[tm][nnoeuds*i+j]; +// } +// } +// } +// } +// // Boucle sur les connectivités d'un type tm +//} + +void Maillage::inputMED(std::string fichierMED) +{ + //cout << endl << "Début procédure inputMED, fichier "<< fichierMED << endl; + + // int i, j, k, ichamp, igauss, ipt, ival; + int j; + // med_err ret = 0; // Code retour + med_idt fid; // Descripteur de fichier MED + char maa[MED_NAME_SIZE + 1]; // nom du maillage de longueur maxi MED_NAME_SIZE + med_int spacedim; + med_int mdim; // Dimension du maillage + med_mesh_type type; + char desc[MED_COMMENT_SIZE + 1]; // Description du maillage + + // Profils + // med_int nprofils; + // int iprofil; + // char nomprofil[MED_NAME_SIZE + 1] = ""; + // med_int nvalprofil, nvalprofil2; + // med_int *pflval; + + // Champs + // med_int nChamps, nCompChamp, nval; + // char *compChamp, *unitChamp, *nomChamp; + //char nomChamp [ MED_NAME_SIZE+1 ] = ""; + // med_field_type typeChamp; + // med_int nGauss, ngpdt, numdt, numo; + med_int nPasTemps; + // char locname[MED_NAME_SIZE + 1] = ""; + // med_geometry_type type_geo; + // med_int ngauss; + char dtunit[MED_SNAME_SIZE + 1] = ""; + // med_float dt = 0.0; + // med_bool local; + // med_int nbrefmaa; + + med_sorting_type sortingtype; + med_axis_type axistype; + + // Initialisations + FAMILLES.clear(); + FAM_TYPES.clear(); + FAMILLES_NOEUDS.clear(); + GROUPES_MAILLES.clear(); + GROUPES_NOEUDS.clear(); + RESIDU.clear(); // Sera initialisé à 1 par la routine acquisitionTYPE_inputMED + tailleFAMILLES.clear(); + tailleGROUPES.clear(); + + // Ouverture du fichier MED en lecture seule + fid = MEDfileOpen(string2char(fichierMED), MED_ACC_RDONLY); + if (fid < 0) + { + ERREUR("Error file open\n"); + } + //cout << chrono() << " --- inputMED: MEDfileOpen: ouverture du maillage en lecture seule, OK" << endl; + + // Lecture des infos concernant le premier maillage + if (MEDmeshInfo(fid, 1, maa, &spacedim, &mdim, &type, desc, dtunit, &sortingtype, &nPasTemps, &axistype, axisname, + unitname) < 0) + ERREUR("Error while reading mesh informations "); + //cout << chrono() << " --- inputMED: MEDmeshInfo: OK" << endl; + +// cerr << "maa=" << maa << endl; +// cerr << "spacedim=" << spacedim << endl; +// cerr << "mdim=" << mdim << endl; +// cerr << "type=" << type << endl; +// cerr << "desc=" << desc << endl; +// cerr << "dtunit=" << dtunit << endl; +// cerr << "sortingtype=" << sortingtype << endl; +// cerr << "nPasTemps=" << nPasTemps << endl; +// cerr << "axistype=" << axistype << endl; +// cerr << "axisname=" << axisname << endl; +// cerr << "unitname=" << unitname << endl; + + dimensionMaillage = mdim; + dimensionEspace = spacedim; + + ID = (string) maa; + + // nGauss = MEDnGauss(fid); + // if (debug > 0) + // cout << "Nombre d'éléments portant des points de Gauss: " << (int) nGauss << endl; + // map REFGAUSS; + // map::iterator iterGAUSS; + // for (igauss = 1; igauss <= nGauss; igauss++) + // { + // if (MEDgaussInfo(fid, igauss, locname, &type_geo, &ngauss) < 0) + // ERREUR("Erreur MEDgaussInfo"); + // if (debug == 2) + // { + // cout << endl << " Retour MEDgaussInfo, localisation gauss n°" << igauss << " : " << endl; + // cout << " locname = " << locname << endl; + // cout << " type_geo = " << type_geo << endl; + // cout << " ngauss = " << ngauss << endl; + // cout << endl; + // } + // REFGAUSS[(string) locname] = (int) ngauss; + // } + // + // if (debug == 2) + // { + // cout << endl << "Restitution de la table REFGAUSS:" << endl; + // for (iterGAUSS = REFGAUSS.begin(); iterGAUSS != REFGAUSS.end(); iterGAUSS++) + // { + // cout << iterGAUSS->first << " : " << iterGAUSS->second << endl; + // } + // } + // + // nprofils = MEDnProfil(fid); + // if (debug) + // cout << endl << endl << "Nombre de profils: " << nprofils << endl; + // for (iprofil = 1; iprofil <= nprofils; iprofil++) + // { + // if (MEDprofilInfo(fid, iprofil, nomprofil, &nvalprofil) < 0) + // ERREUR("ERREUR MEDprofilInfo"); + // nvalprofil2 = MEDnValProfil(fid, nomprofil); + // if (debug == 2) + // { + // cout << "Profil " << iprofil << " : " << endl; + // cout << " Nom profil : " << nomprofil << endl; + // cout << " Nombre de valeurs profil (par MEDprofilInfo) : " << nvalprofil << endl; + // cout << " Nombre de valeurs profil (par MEDnValProfil) : " << nvalprofil2 << endl; + // } + // if (nvalprofil != nvalprofil2) + // ERREUR("Discordance nvalprofil (entre MEDprofilInfo et MEDnValProfil)"); + // pflval = (med_int*) malloc(sizeof(med_int) * nvalprofil); + // if (MEDprofilLire(fid, pflval, nomprofil) < 0) + // ERREUR("ERREUR MEDprofilLire"); + // //cout << " Affichage des 100 premières valeurs:" << endl; + // //for (ival=0;ival 0) + // { + // + // for (ichamp = 1; ichamp <= nChamps; ichamp++) + // { + // //for (ichamp=4; ichamp<=4; ichamp++ ) { + // cout << endl << endl; + // cout << endl << endl << " ====================================================================" << endl; + // cout << endl << endl << " CHAMP " << ichamp << endl; + // cout << endl << endl << " ====================================================================" << endl; + // cout << endl << endl; + // + // nCompChamp = MEDnChamp(fid, ichamp); + // if (nCompChamp < 0) + // ERREUR("Erreur Ncomposantes champ"); + // cout << "Nombre de composantes du champ " << ichamp << " : " << (int) nCompChamp << endl; + // + // nomChamp = (char*) malloc(MED_NAME_SIZE + 1); + // compChamp = (char*) malloc(nCompChamp * MED_SNAME_SIZE + 1); + // unitChamp = (char*) malloc(nCompChamp * MED_SNAME_SIZE + 1); + // + // if (MEDchampInfo(fid, ichamp, nomChamp, &typeChamp, compChamp, unitChamp, nCompChamp) < 0) + // ERREUR("Erreur MEDchampInfo"); + // + // cout << "Infos sur le champ " << ichamp << " : " << endl; + // cout << " Nom: " << (string) nomChamp << endl; + // cout << " Type: " << typeChamp << endl; + // cout << " Noms des composantes: " << (string) compChamp << endl; + // cout << " Unités des composantes: " << (string) unitChamp << endl; + // + // infoChamps((string) "NOEUDS", MED_NODE, MED_NONE, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "POI1", MED_CELL, MED_POINT1, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "SEG2", MED_CELL, MED_SEG2, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "SEG3", MED_CELL, MED_SEG3, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "TRIA3", MED_CELL, MED_TRIA3, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "TRIA6", MED_CELL, MED_TRIA6, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "QUAD4", MED_CELL, MED_QUAD4, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "QUAD8", MED_CELL, MED_QUAD8, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "TETRA4", MED_CELL, MED_TETRA4, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "TETRA10", MED_CELL, MED_TETRA10, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "PYRAM5", MED_CELL, MED_PYRA5, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "PYRAM13", MED_CELL, MED_PYRA13, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "PENTA6", MED_CELL, MED_PENTA6, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "PENTA15", MED_CELL, MED_PENTA15, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "HEXA8", MED_CELL, MED_HEXA8, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // infoChamps((string) "HEXA20", MED_CELL, MED_HEXA20, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS); + // + // } + // + // cout << endl << "Rappel des codes de géométries: " << endl; + // cout << " TETRA4 = " << MED_TETRA4 << endl; + // cout << " PENTA6 = " << MED_PENTA6 << endl; + // cout << " HEXA8 = " << MED_HEXA8 << endl; + // + // } + // else + // cout << "Pas de champs dans ce maillage" << endl; + + // ################################################################################################## + // ################################################################################################## + // + // A C Q U I S I T I O N D E S F A M I L L E S + // + // ################################################################################################## + // ################################################################################################## + + + med_int nFamilles; + char nomGroupeChar[MED_LNAME_SIZE + 1]; + if ((nFamilles = MEDnFamily(fid, maa)) < 0) + ERREUR("ERROR MEDnFamily"); + + // Initialisation des tailles: tailleFAMILLES et tailleGROUPES + + // for (int i = 0; i < nFamilles; i++) + // { + // char nomfam[MED_NAME_SIZE + 1]; + // char *attdes, *gro; + // med_int numfam, *attide, *attval, natt, ngro; + // + // if ((ngro = MEDnFamilyGroup(fid, maa, i + 1)) < 0) + // ERREUR("ERREUR MEDnFamilyGroup"); + // if ((natt = MEDnFamily23Attribute(fid, maa, i + 1)) < 0) + // ERREUR("ERREUR MEDnFamily23Attribute"); + // + // attide = (med_int *) malloc(sizeof(med_int) * natt); + // attval = (med_int *) malloc(sizeof(med_int) * natt); + // attdes = (char *) malloc(MED_COMMENT_SIZE * natt + 1); + // gro = (char *) malloc(MED_LNAME_SIZE * ngro + 1); + // + // if (MEDfamilyInfo(fid, maa, (med_int)(i + 1), nomfam, &numfam, attide, attval, attdes, &natt, gro, &ngro) < 0) + // ERREUR("ERREUR MEDfamilyInfo"); + // + // free(attide); + // free(attval); + // free(attdes); + // free(gro); + // } + + for (int i = 0; i < nFamilles; i++) + { + char nomfam[MED_NAME_SIZE + 1]; + char *attdes, *gro; + med_int numfam, *attide, *attval, natt, ngro; + + if ((ngro = MEDnFamilyGroup(fid, maa, i + 1)) < 0) + ERREUR("ERROR MEDnFamilyGroup"); + if ((natt = MEDnFamily23Attribute(fid, maa, i + 1)) < 0) + ERREUR("ERROR MEDnFamily23Attribute"); + + attide = (med_int *) malloc(sizeof(med_int) * natt); + attval = (med_int *) malloc(sizeof(med_int) * natt); + attdes = (char *) malloc(MED_COMMENT_SIZE * natt + 1); + gro = (char *) malloc(MED_LNAME_SIZE * ngro + 1); + + if (MEDfamilyInfo(fid, maa, (med_int) (i + 1), nomfam, &numfam, gro) < 0) + ERREUR("ERROR MEDfamilyInfo"); + + for (int ig = 1; ig <= ngro; ig++) + { + for (j = 0; j < MED_LNAME_SIZE; j++) + nomGroupeChar[j] = gro[(ig - 1) * MED_LNAME_SIZE + j]; + nomGroupeChar[MED_LNAME_SIZE] = '\0'; + //cout << "Groupe lu : " << (string)nomGroupeChar << endl; + tailleGROUPES[strip((string) nomGroupeChar)]++; + if (numfam > 0) + GROUPES_NOEUDS[strip((string) nomGroupeChar)].push_back((int) numfam); + else if (numfam < 0) + GROUPES_MAILLES[strip((string) nomGroupeChar)].push_back((int) numfam); + } + + free(attide); + free(attval); + free(attdes); + free(gro); + } + + // ################################################################################################## + // ################################################################################################## + // + // A C Q U I S I T I O N D E S N O E U D S + // + // ################################################################################################## + // ################################################################################################## + + // class Noeud *n; + // list listeNoeuds; + // float x, y, z, rx, ry, rz, tx, ty, tz; + string line, IDnoeud; + float x0, x1, y0, y1, z0, z1; + + vector RESIDU_NOEUDS; // Table de vérité du résidu des noeuds + + ostringstream OSCOORD; + + med_int nnoe = 0; // Nbre de noeuds + med_float *coo1; // Table des coordonnées + // char nomcoo[mdim * MED_SNAME_SIZE + 1]; // Table des noms des coordonnées + // char unicoo[mdim * MED_SNAME_SIZE + 1]; // Table des unités des coordonnées + char *nomnoe; + + med_int *numnoe; + med_int *nufano; + // med_grid_type rep; + // med_bool inonoe, inunoe; + // med_int profil[2] = { 2, 3 }; + med_bool coordinatechangement; + med_bool geotransformation; + + // Combien de noeuds a lire ? + nnoe = MEDmeshnEntity(fid, maa, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NO_GEOTYPE, MED_COORDINATE, MED_NO_CMODE, + &coordinatechangement, &geotransformation); + + if (nnoe < 0) + ERREUR("Error while reading number of nodes"); + + nombreNoeudsMaillage = nnoe; + + // Lecture des familles des noeuds + med_int *famNoeuds = (med_int*) malloc(sizeof(med_int) * nnoe); + if (nnoe > 0) + { + if (MEDmeshEntityFamilyNumberRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NONE, famNoeuds) < 0) + ERREUR("Error while reading family node number (MEDmeshEntityFamilyNumberRd)"); + } + + /* Allocations memoires */ + if (nnoe > 0) + { + // table des coordonnees - profil : (dimension * nombre de noeuds ) + coo1 = (med_float*) calloc(nnoe * mdim, sizeof(med_float)); + // table des des numeros, des numeros de familles des noeuds - profil : (nombre de noeuds) + numnoe = (med_int*) malloc(sizeof(med_int) * nnoe); + nufano = (med_int*) malloc(sizeof(med_int) * nnoe); + // table des noms des noeuds - profil : (nnoe*MED_SNAME_SIZE+1) + nomnoe = (char*) malloc(MED_SNAME_SIZE * nnoe + 1); + } + + // Lecture des composantes des coordonnees des noeuds + if (nnoe > 0) + if (MEDmeshNodeCoordinateRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE, coo1) < 0) + ERREUR("Error while reading nodes coordinates"); + + // // Les noeuds ont-ils un nom? un numéro? + // if (nnoe > 0) + // { + // if (MEDnomLire(fid, maa, nomnoe, nnoe, MED_NODE, (med_geometry_type) 0) < 0) + // inonoe = MED_FALSE; + // else + // inonoe = MED_TRUE; + // if (MEDnumLire(fid, maa, numnoe, nnoe, MED_NODE, (med_geometry_type) 0) < 0) + // inunoe = MED_FALSE; + // else + // inunoe = MED_TRUE; + // } + // + // if (inonoe) + // cout << "WARNING input MED : les noms des noeuds sont ignorés" << endl; + // if (inunoe) + // cout << "WARNING input MED : les numéros des noeuds sont ignorés" << endl; + // + // if (inonoe) + // { + // char str[MED_SNAME_SIZE + 1]; + // for (int inoeud = 0; inoeud < nnoe; inoeud++) + // { + // strncpy(str, nomnoe + inoeud * MED_SNAME_SIZE, MED_SNAME_SIZE); + // str[MED_SNAME_SIZE] = '\0'; + // IDS_NOEUDS.push_back((string) str); + // } + // } + // else if (inunoe) + // { + // for (int inoeud = 0; inoeud < nnoe; inoeud++) + // { + // int numnoeud = *(numnoe + inoeud); + // IDS_NOEUDS.push_back((string) "N" + int2string(numnoeud)); + // } + // } + // else + // for (int inoeud = 0; inoeud < nnoe; inoeud++) + // IDS_NOEUDS.push_back((string) "N" + int2string(inoeud + 1)); + // IDS_NOEUDS.resize(nnoe); + + /* ====================================================================== */ + /* BOUCLE SUR LES NOEUDS LUS DANS LE FICHIER MED */ + /* ====================================================================== */ + + // X.resize(nnoe); + // Y.resize(nnoe); + // Z.resize(nnoe); + + // Initialisation de l'enveloppe + x0 = coo1[0]; + x1 = coo1[0]; + y0 = coo1[1]; + y1 = coo1[1]; + if (mdim == 3) + { + z0 = coo1[2]; + z1 = coo1[2]; + } + else + { + z0 = 0.0; + z1 = 0.0; + } + + // Allocation mémoire pour les coordonnées XX YY ZZ + XX = (float*) malloc(sizeof(float) * nombreNoeudsMaillage); + if (mdim > 1) + YY = (float*) malloc(sizeof(float) * nombreNoeudsMaillage); + if (mdim > 2) + ZZ = (float*) malloc(sizeof(float) * nombreNoeudsMaillage); + + for (int i = 0; i < nnoe; i++) + { + + // Chargement des coordonnées X, Y et Z + // Calcul de l'enveloppe du maillage + + FAMILLES_NOEUDS[*(famNoeuds + i)].push_back(i + 1); // ATTENTION! Les num. de noeuds commencent à 1 + tailleFAMILLES[*(famNoeuds + i)]++; + + // IDnoeud = "N"+int2string(i+1); + + float * XXi = XX + i; + float * YYi = YY + i; + float * ZZi = ZZ + i; + + if (mdim == 3) + { + *XXi = (float) coo1[3 * i]; + *YYi = (float) coo1[3 * i + 1]; + *ZZi = (float) coo1[3 * i + 2]; + if (*XXi < x0) + x0 = *XXi; + else if (*XXi > x1) + x1 = *XXi; + if (*YYi < y0) + y0 = *YYi; + else if (*YYi > y1) + y1 = *YYi; + if (*ZZi < z0) + z0 = *ZZi; + else if (*ZZi > z1) + z1 = *ZZi; + } + else if (mdim == 2) + { + *XXi = (float) coo1[2 * i]; + *YYi = (float) coo1[2 * i + 1]; + if (*XXi < x0) + x0 = *XXi; + else if (*XXi > x1) + x1 = *XXi; + if (*YYi < y0) + y0 = *YYi; + else if (*YYi > y1) + y1 = *YYi; + } + else if (mdim == 1) + { + *XXi = (float) coo1[1 * i]; + if (*XXi < x0) + x0 = *XXi; + else if (*XXi > x1) + x1 = *XXi; + } + + // Chargement des numéros de noeuds + // if (inunoe) + // NUM_NOEUDS.push_back(*(numnoe + i)); + // else + // NUM_NOEUDS.push_back(i + 1); + + } // boucle sur les noeuds + + // NUM_NOEUDS.resize(nnoe); + + // Enveloppe du maillage + enveloppeMaillage = new Cube(x0, x1, y0, y1, z0, z1); + + // Libération mémoire + if (nnoe > 0) + { + free(coo1); + free(nomnoe); + free(numnoe); + free(nufano); + } + + // ################################################################################################## + // ################################################################################################## + // + // A C Q U I S I T I O N D E S M A I L L E S + // + // ################################################################################################## + // ################################################################################################## + + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + EFFECTIFS_TYPES[tm] = MEDmeshnEntity(fid, maa, MED_NO_DT, MED_NO_IT, MED_CELL, InstanceMGE(tm), MED_CONNECTIVITY, + MED_NODAL, &coordinatechangement, &geotransformation); + if (EFFECTIFS_TYPES[tm]) + acquisitionTYPE_inputMED(tm, EFFECTIFS_TYPES[tm], fid, maa, mdim); + } + + // Resize des vecteurs des maps FAMILLES et FAM_TYPES + map >::iterator IF; + for (IF = FAMILLES.begin(); IF != FAMILLES.end(); IF++) + { + IF->second.resize(tailleFAMILLES[IF->first]); + FAM_TYPES[IF->first].resize(tailleFAMILLES[IF->first]); + } + + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + nombreMaillesMaillage += EFFECTIFS_TYPES[(TYPE_MAILLE) itm]; + + // ################################################################################################## + // ################################################################################################## + // + // A C Q U I S I T I O N D E S G R O U P E S + // D E M A I L L E S E T D E N O E U D S + // + // ################################################################################################## + // ################################################################################################## + + // ============================================================================================= + // Chargement des groupes dans GM et GN + // ============================================================================================= + + string nomGM; + vector vfam; + map >::iterator iterGRO; + + int cptGM = 0; + for (iterGRO = GROUPES_MAILLES.begin(); iterGRO != GROUPES_MAILLES.end(); iterGRO++) + { + nomGM = iterGRO->first; + vfam = iterGRO->second; + cptGM++; + map effectifGroupeType; + for (unsigned int i = 0; i < vfam.size(); i++) + { + int numf = vfam[i]; + // Parcours simultané des vecteurs FAMILLES[numf] et FAM_TYPES[numfam] pour obtention du num local + // et du type des mailles de la famille numf + for (unsigned int imaille = 0; imaille < FAMILLES[numf].size(); imaille++) + { + TYPE_MAILLE tm = FAM_TYPES[numf][imaille]; + int nl = FAMILLES[numf][imaille]; + GM[nomGM][tm].push_back(nl); + effectifGroupeType[tm]++; + } + } + + // Resize d'un GM + for (map >::iterator I = GM[nomGM].begin(); I != GM[nomGM].end(); I++) + { + TYPE_MAILLE tm = I->first; + GM[nomGM][tm].resize(effectifGroupeType[tm]); + sort(GM[nomGM][tm].begin(), GM[nomGM][tm].end()); + } + } + + int cptGN = 0; + for (iterGRO = GROUPES_NOEUDS.begin(); iterGRO != GROUPES_NOEUDS.end(); iterGRO++) + { + nomGM = iterGRO->first; + vfam = iterGRO->second; + cptGN++; + int cptNoeudsGN = 0; + for (unsigned int i = 0; i < vfam.size(); i++) + { + int numf = vfam[i]; + // Parcours vecteurs FAMILLES_NOEUDS[numf] + for (unsigned int inoeud = 0; inoeud < FAMILLES_NOEUDS[numf].size(); inoeud++) + { + GN[nomGM].push_back(FAMILLES_NOEUDS[numf][inoeud]); + cptNoeudsGN++; + } + } + GN[nomGM].resize(cptNoeudsGN); + sort(GN[nomGM].begin(), GN[nomGM].end()); + } + + MEDfileClose(fid); + // cout << "Fin procédure inputMED" << endl << endl; +} + +void Maillage::acquisitionTYPE_inputMED(TYPE_MAILLE TYPE, int nTYPE, med_idt fid, char maa[MED_NAME_SIZE + 1], + med_int mdim) +{ + + // int taille, numeromaille, numeroFamille; + int numeroFamille; + string line, IDmaille, IDnoeud, typeMaille; + // char str[MED_SNAME_SIZE + 1]; // Conteneur pour un nom de maille + // bool rejetMaille; + med_int tTYPE = (med_int) Nnoeuds(TYPE); + char *nomTYPE = (char*) malloc(MED_SNAME_SIZE * nTYPE + 1); + med_int *numTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE); + med_int *famTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE); + + //med_int *conTYPE = (med_int*) malloc(sizeof(med_int)*tTYPE*nTYPE); + CNX[TYPE] = (int*) malloc(sizeof(int) * tTYPE * nTYPE); + + med_bool inomTYPE, inumTYPE, ifamTYPE; + med_geometry_type typeBanaliseMED = InstanceMGE(TYPE); + + if (MEDmeshElementRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_CELL, typeBanaliseMED, MED_NODAL, MED_FULL_INTERLACE, + CNX[TYPE], &inomTYPE, nomTYPE, &inumTYPE, numTYPE, &ifamTYPE, famTYPE) < 0) + ERREUR("Error while reading elements"); + + // Conversion HL + conversionCNX(CNX[TYPE], TYPE, nTYPE); + + // CON[TYPE].resize(tTYPE * nTYPE); + // for (int i = 0; i < tTYPE * nTYPE; i++) + // CON[TYPE][i] = (int) *(conTYPE + i); + // CNX[TYPE] = (int*) malloc(sizeof(int) * tTYPE * nTYPE); + // for (int i = 0; i < tTYPE * nTYPE; i++) + // *(CNX[TYPE] + i) = (int) *(conTYPE + i); + + for (int i = 0; i < nTYPE; i++) + { + numeroFamille = (int) *(famTYPE + i); + FAMILLES[numeroFamille].push_back(i); + tailleFAMILLES[numeroFamille]++; + FAM_TYPES[numeroFamille].push_back(TYPE); + + // Chargement des numéros de mailles + // if (inumTYPE) + // NUM_MAILLES[TYPE].push_back(*(numTYPE + i)); + // else + // NUM_MAILLES[TYPE].push_back(NGLOBAL(TYPE, i)); + + } + // NUM_MAILLES[TYPE].resize(nTYPE); + + // if (inomTYPE) + // { + // char str[MED_SNAME_SIZE + 1]; + // for (int imaille = 0; imaille < nTYPE; imaille++) + // { + // strncpy(str, nomTYPE + imaille * MED_SNAME_SIZE, MED_SNAME_SIZE); + // str[MED_SNAME_SIZE] = '\0'; + // IDS_MAILLES[TYPE].push_back((string) str); + // } + // } + // else if (inumTYPE) + // { + // for (int imaille = 0; imaille < nTYPE; imaille++) + // { + // int nummaille = *(numTYPE + imaille); + // IDS_MAILLES[TYPE].push_back((string) "M" + int2string(nummaille)); + // } + // } + // else + // { + // for (int imaille = 0; imaille < nTYPE; imaille++) + // { + // IDS_MAILLES[TYPE].push_back((string) "M" + int2string(imaille + 1)); + // } + // } + // IDS_MAILLES[TYPE].resize(nTYPE); +} + +void Maillage::outputMED(std::string fichierMED) +{ + // int i, j, k; + int nTYPE, tTYPE; + string line, s, stype, nomnoeud; + // med_err ret = 0; // Code retour + // int ig, jg; + // cout << endl << endl << "Début procédure outputMED, fichier " << fichierMED << endl; + + // Sortie sur erreur en cas de maillage sans noeuds + if (nombreNoeudsMaillage <= 0) + { + ERREUR("This mesh does not contain any node\n"); /* cout << "Maillage sans noeuds" << endl; */ + } + + // ######################################################################## + // Ouverture du fichier MED et création du maillage + // ######################################################################## + + // Ouverture du fichier MED en création + med_idt fid = MEDfileOpen(string2char(fichierMED), MED_ACC_CREAT); + if (fid < 0) + { + ERREUR("Error MEDfileOpen\n"); + cout << "Error MEDfileOpen" << endl; + } + + // Création du maillage + char maa[MED_NAME_SIZE + 1]; // Nom du maillage de longueur maxi MED_NAME_SIZE + strcpy(maa, string2char(ID)); + + med_int mdim; // Dimension du maillage + if (dimensionMaillage == 0) + { + mdim = 3; + cout << "ATTENTION, dimension 3 attribuée par défaut!" << endl; + } + else + mdim = dimensionMaillage; + med_int spacedim = 3; + if (dimensionEspace) + spacedim = dimensionEspace; + + //med_int profil[2] = { 2, 3 }; + char desc[MED_COMMENT_SIZE + 1]; // Description du maillage + strcpy(desc, string2char(ID)); + med_mesh_type type = MED_UNSTRUCTURED_MESH; +// cerr << "maa=" << maa << endl; +// cerr << "spacedim=" << spacedim << endl; +// cerr << "mdim=" << mdim << endl; +// cerr << "type=" << type << endl; +// cerr << "axisname=" << axisname << endl; +// cerr << "unitname=" << unitname << endl; + if (MEDmeshCr(fid, maa, spacedim, mdim, type, desc, "s", MED_SORT_DTIT, MED_CARTESIAN, axisname, unitname) < 0) + { + ERREUR("Error MEDmeshCr"); + cout << "Error MEDmeshCr" << endl; + } + + // ============================= CREATION FAMILLE ZERO + char nomfam[MED_NAME_SIZE + 1]; + med_int numfam; + // char attdes[MED_COMMENT_SIZE + 1]; + // med_int natt, attide, attval; + int ngro; + // char gro[MED_LNAME_SIZE + 1]; + + strcpy(nomfam, "FAMILLE_0"); + numfam = 0; + if (MEDfamilyCr(fid, maa, nomfam, numfam, 0, MED_NO_GROUP) < 0) + ERREUR("Error MEDfamilyCr (create family 0)"); + + // ######################################################################## + // GROUPES DE NOEUDS + // ######################################################################## + + int nGroupesNoeuds = GN.size(); + + vector > ETIQUETTES_N; + ETIQUETTES_N.resize(nombreNoeudsMaillage); + vector INDEX_N; + INDEX_N.resize(GN.size()); + vector NOMSFAM; + vector > ETIQFAM; + int cptNOMFAM = 0; + map NUMFAMETIQ; // clé = étiquette - valeur = numéros de familles + + + if (nGroupesNoeuds) + { + + // Pérennisation d'un ordre sur les GM dans le vecteur NOMS_GROUPES_MAILLES + vector NOMS_GROUPES_NOEUDS; + for (map >::iterator ITGN = GN.begin(); ITGN != GN.end(); ITGN++) + { + string nomGN = ITGN->first; + NOMS_GROUPES_NOEUDS.push_back(nomGN); + } + NOMS_GROUPES_NOEUDS.resize(GN.size()); + + // Tri des vecteurs de noeuds de GN + for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++) + sort(GN[NOMS_GROUPES_NOEUDS[ig]].begin(), GN[NOMS_GROUPES_NOEUDS[ig]].end()); + + // Construction des étiquettes (familles) + + // Initialisation des index de groupes + for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++) + INDEX_N[ig] = 0; + + for (int k = 1; k <= nombreNoeudsMaillage; k++) + { // k: num. global de noeud + int tailleEtiquette = 0; + string etiq = (string) ""; + // Boucle sur les groupes + for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++) + { + if (INDEX_N[ig] < GN[NOMS_GROUPES_NOEUDS[ig]].size()) + { + string nomgroupe = NOMS_GROUPES_NOEUDS[ig]; + if (k == GN[nomgroupe][INDEX_N[ig]]) + { + // Attention: l'indice 0 dans le vecteur ETIQUETTES correspond + // à l'élément (noeud ou maille) de num. global 1 + // Par ailleurs, le numéro de groupe dans l'étiquette commence à 0 + ETIQUETTES_N[k - 1].push_back(ig); + tailleEtiquette++; + etiq += int2string(ig); + INDEX_N[ig]++; + } + } + } + ETIQUETTES_N[k - 1].resize(tailleEtiquette); + // Stockage de l'étiquette dans NOMSFAM ETIQFAM, si pas déjà stockée + // bool trouve = false; + // for (int i = 0; i < NOMSFAM.size(); i++) + // if (NOMSFAM[i] == ((string) "ETIQUETTE_" + etiq)) + // { + // trouve = true; + // break; + // } + if (!NUMFAMETIQ[etiq] && etiq != (string) "") + { + NOMSFAM.push_back((string) "ETIQN_" + etiq); + ETIQFAM.push_back(ETIQUETTES_N[k - 1]); + NUMFAMETIQ[etiq] = cptNOMFAM + 1; // Famille de noeuds, num>0 + cptNOMFAM++; + } + } + + NOMSFAM.resize(cptNOMFAM); + ETIQFAM.resize(cptNOMFAM); + + // Création des familles de noeuds + for (unsigned int ifam = 0; ifam < NOMSFAM.size(); ifam++) + { + strcpy(nomfam, string2char(NOMSFAM[ifam])); + // Numéro de famille: ifam+1 (positif pour les noeuds + non nul) + numfam = ifam + 1; + ngro = ETIQFAM[ifam].size(); + + // Noms des groupes de la famille: variable nomsGN + char *gro = new char[ngro * MED_LNAME_SIZE + 1]; + int cptGN = 0; + for (unsigned int ign = 0; ign < ETIQFAM[ifam].size(); ign++) + { + string nomGNcourant = NOMS_GROUPES_NOEUDS[ETIQFAM[ifam][ign]]; + // ATTENTION! Il faut mettre à la fin de chaque segment un \0 qui est ensuite écrasé + // par le premier caractère du champ suivant dans le strcat !!!! + if (ign == 0) + { + // Premier groupe + strcpy(gro, string2char(nomGNcourant)); + for (int jg = nomGNcourant.size(); jg < MED_LNAME_SIZE; jg++) + gro[jg] = ' '; + gro[MED_LNAME_SIZE] = '\0'; + } + else + { + strcat(gro, string2char(nomGNcourant)); + for (int jg = nomGNcourant.size(); jg < MED_LNAME_SIZE; jg++) + gro[cptGN * MED_LNAME_SIZE + jg] = ' '; + gro[(cptGN + 1) * MED_LNAME_SIZE] = '\0'; + } + cptGN++; + } + + // Création de la famille + if (MEDfamilyCr(fid, maa, nomfam, numfam, 0, MED_NO_GROUP) < 0) + ERREUR("Error MEDfamilyCr"); + delete gro; + } + + } + + // ######################################################################## + // NOEUDS + // ######################################################################## + + // float x, y, z; + + med_int nnoe = nombreNoeudsMaillage; // Nombre de noeuds + med_float *coo; // Table des coordonnées + + // Noms des coordonnées (variable nomcoo) + char* nomcoo = new char[mdim * MED_SNAME_SIZE + 1]; + string strX = (string) "X"; + while (strX.size() < MED_SNAME_SIZE) + strX += (string) " "; + string strY = (string) "Y"; + while (strY.size() < MED_SNAME_SIZE) + strY += (string) " "; + string strZ = (string) "Z"; + while (strZ.size() < MED_SNAME_SIZE) + strZ += (string) " "; + if (mdim == 3) + strcpy(nomcoo, string2char(strX + strY + strZ)); + else if (mdim == 2) + strcpy(nomcoo, string2char(strX + strY)); + else + strcpy(nomcoo, string2char(strX)); + nomcoo[mdim * MED_SNAME_SIZE] = '\0'; + + // Unités des coordonnées (variable unicoo) + char* unicoo = new char[mdim * MED_SNAME_SIZE + 1]; + string strmesure = (string) "SI"; + while (strmesure.size() < MED_SNAME_SIZE) + strmesure += (string) " "; + if (mdim == 3) + strcpy(unicoo, string2char(strmesure + strmesure + strmesure)); + else if (mdim == 2) + strcpy(unicoo, string2char(strmesure + strmesure)); + else + strcpy(unicoo, string2char(strmesure)); + unicoo[mdim * MED_SNAME_SIZE] = '\0'; + + // Tables des noms, numeros, numeros de familles des noeuds + // autant d'elements que de noeuds - les noms ont pout longueur MED_SNAME_SIZE + char *nomnoe; + med_int *numnoe = NULL; + med_int *nufano; + med_bool inonoe = MED_FALSE; + med_bool inunoe = MED_FALSE; + + // Allocations memoire + if (nnoe > 0) + { + // table des coordonnees - profil : (dimension * nombre de noeuds ) + coo = (med_float*) calloc(nnoe * mdim, sizeof(med_float)); + + // table des des numeros, des numeros de familles des noeuds - profil : (nombre de noeuds) + // numnoe = (med_int*) malloc(sizeof(med_int) * nnoe); + nufano = (med_int*) malloc(sizeof(med_int) * nnoe); + + // table des noms des noeuds - profil : (nnoe*MED_SNAME_SIZE+1) + nomnoe = (char*) ""; // ATTENTION! + + // nomnoe = (char*) malloc(MED_SNAME_SIZE * nnoe + 1); + // for (int inoeud = 0; inoeud < IDS_NOEUDS.size(); inoeud++) + // { + // string nomNoeud = IDS_NOEUDS[inoeud]; + // if (inoeud == 0) + // { + // // Premier groupe + // strcpy(nomnoe, string2char(nomNoeud)); + // for (int jg = nomNoeud.size(); jg < MED_SNAME_SIZE; jg++) + // nomnoe[jg] = ' '; + // nomnoe[MED_SNAME_SIZE] = '\0'; + // } + // else + // { + // strcat(nomnoe, string2char(nomNoeud)); + // for (int jg = nomNoeud.size(); jg < MED_SNAME_SIZE; jg++) + // nomnoe[inoeud * MED_SNAME_SIZE + jg] = ' '; + // nomnoe[(inoeud + 1) * MED_SNAME_SIZE] = '\0'; + // } + // } + } + + // Chargement des coordonnées, numéros de familles et numéros de noeuds + if (dimensionMaillage == 3) + { + int i3 = 0; + for (int i = 0; i < nnoe; i++) + { + // coo[i3] = X[i]; + // coo[i3 + 1] = Y[i]; + // coo[i3 + 2] = Z[i]; + // i3 = i3 + 3; + coo[i3] = *(XX + i); + coo[i3 + 1] = *(YY + i); + coo[i3 + 2] = *(ZZ + i); + i3 = i3 + 3; + + // Numéros de familles - Le num. global de noeud est i+1 + if (nGroupesNoeuds) + { + vector v = ETIQUETTES_N[i]; + string sv = (string) ""; + for (unsigned int j = 0; j < v.size(); j++) + sv += int2string(v[j]); // Etiquette du noeud au format string + // cout << "Noeud " << i + 1 << " : sv=" << sv << endl; + *(nufano + i) = (med_int) NUMFAMETIQ[sv]; + } + else + *(nufano + i) = (med_int) 0; + + // Numéros de noeuds + // *(numnoe + i) = (med_int) NUM_NOEUDS[i]; + } + } + else /* dimension 2 */ + { + int i2 = 0; + for (int i = 0; i < nnoe; i++) + { + coo[i2] = *(XX + i); + coo[i2 + 1] = *(YY + i); + i2 = i2 + 2; + // Numéros de familles - Le num. global de noeud est i+1 + if (nGroupesNoeuds) + { + vector v = ETIQUETTES_N[i]; + string sv = (string) ""; + for (unsigned int j = 0; j < v.size(); j++) + sv += int2string(v[j]); // Etiquette du noeud au format string + // cout << "Noeud " << i + 1 << " : sv=" << sv << endl; + *(nufano + i) = (med_int) NUMFAMETIQ[sv]; + } + else + *(nufano + i) = (med_int) 0; + // Numéros de noeuds + // *(numnoe + i) = (med_int) NUM_NOEUDS[i]; + } + } + + // // Restitution coo + // int i3 = 0; + // for (int i = 0; i < nnoe; i++) + // { + // cout << "Noeud " << i << " : " << coo[i3] << " " << coo[i3 + 1] << " " << coo[i3 + 2] << endl; + // i3 = i3 + 3; + // } + + if (MEDmeshNodeWr(fid, maa, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT, MED_FULL_INTERLACE, nnoe, coo, inonoe, nomnoe, + inunoe, numnoe, MED_TRUE, nufano) < 0) + { + ERREUR("Error MEDmeshNodeWr"); + cout << "Error MEDmeshNodeWr" << endl; + } + + // ######################################################################## + // GROUPES DE MAILLES + // ######################################################################## + + int nGroupesMailles = GM.size(); + + map > > ETIQUETTES_M; // [ tm => [ nl => [ig1, ig2, ... ] ] ] + // INDEX_M : + // Clé : tm + // Valeur : vect. des compteurs par indice de GM dans NOMS_GROUPES_MAILLES + map > INDEX_M; + NOMSFAM.clear(); + ETIQFAM.clear(); + NUMFAMETIQ.clear(); // clé = étiquette - valeur = numéros de familles + cptNOMFAM = 0; + + if (nGroupesMailles) + { + + // Pérennisation d'un ordre sur les GM dans le vecteur NOMS_GROUPES_MAILLES + vector NOMS_GROUPES_MAILLES; + for (map > >::iterator ITGM = GM.begin(); ITGM != GM.end(); ITGM++) + { + string nomGM = ITGM->first; + NOMS_GROUPES_MAILLES.push_back(nomGM); + } + NOMS_GROUPES_MAILLES.resize(GM.size()); + // Tri des vecteurs d'entiers de GM + for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++) + { + string nomGM = NOMS_GROUPES_MAILLES[ig]; + for (map >::iterator I = GM[nomGM].begin(); I != GM[nomGM].end(); I++) + { + TYPE_MAILLE tm = I->first; + sort(GM[nomGM][tm].begin(), GM[nomGM][tm].end()); + } + } + + // Construction des étiquettes (familles) + + // Initialisation 0 des index de groupes, et resize ETIQUETTES_M[tm] + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + if (EFFECTIFS_TYPES[tm]) + { + for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++) + INDEX_M[tm].push_back(0); + ETIQUETTES_M[tm].resize(EFFECTIFS_TYPES[tm]); + } + } + + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + int efftm = EFFECTIFS_TYPES[tm]; + // cout << endl << "*************** coucou ***************" << endl; + // cout << "*************** Type " << TM2string(tm) << " effectif = " << efftm << endl; + if (efftm) + { + // cout << "Traitement du type " << TM2string(tm) << endl; + for (int nl = 0; nl < efftm; nl++) + { + // nl = num. local de la maille dans son type + // cout << "\tMaille " << TM2string(tm) << " n° " << nl << endl; + + int tailleEtiquette = 0; + string etiq = (string) ""; + // Boucle sur les groupes + for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++) + { + string nomGM = NOMS_GROUPES_MAILLES[ig]; + // cout << "\t\t" << "Groupe " << nomGM << endl; + + if (INDEX_M[tm][ig] < GM[nomGM][tm].size()) + { + if (nl == GM[nomGM][tm][INDEX_M[tm][ig]]) + { + // Attention: l'indice 0 dans le vecteur ETIQUETTES correspond + // à l'élément (noeud ou maille) de num. global 1 + // Par ailleurs, le numéro de groupe dans l'étiquette commence à 0 + // cout << "\t\t\t" << "La maille est dans le groupe " << nomGM << endl; + ETIQUETTES_M[tm][nl].push_back(ig); + tailleEtiquette++; + etiq += int2string(ig); + INDEX_M[tm][ig]++; + // cout << "\t\t\t OK" << endl; + } + } + } + + ETIQUETTES_M[tm][nl].resize(tailleEtiquette); + // Stockage de l'étiquette dans NOMSFAM ETIQFAM, si pas déjà stockée + // bool trouve = false; + // for (int i = 0; i < NOMSFAM.size(); i++) + // if (NOMSFAM[i] == ((string) "ETIQUETTE_" + etiq)) + // { + // trouve = true; + // break; + // } + + if (!NUMFAMETIQ[etiq] && etiq != (string) "") + { + NOMSFAM.push_back((string) "ETIQM_" + etiq); + ETIQFAM.push_back(ETIQUETTES_M[tm][nl]); + NUMFAMETIQ[etiq] = -cptNOMFAM - 1; // Famille de mailles, num<0 + cptNOMFAM++; + } + + } + + } // if (efftm) + } + + NOMSFAM.resize(cptNOMFAM); + ETIQFAM.resize(cptNOMFAM); + + // Création des familles de mailles + for (unsigned int ifam = 0; ifam < NOMSFAM.size(); ifam++) + { + strcpy(nomfam, string2char(NOMSFAM[ifam])); + // Numéro de famille: -ifam-1 (négatif pour les mailles, et non nul) + numfam = -ifam - 1; + ngro = ETIQFAM[ifam].size(); + + // Noms des groupes de la famille + char* gro = new char[ngro * MED_LNAME_SIZE + 1]; + int cptGM = 0; + for (unsigned int ign = 0; ign < ETIQFAM[ifam].size(); ign++) + { + string nomGMcourant = NOMS_GROUPES_MAILLES[ETIQFAM[ifam][ign]]; + // ATTENTION! Il faut mettre à la fin de chaque segment un \0 qui est ensuite écrasé + // par le premier caractère du champ suivant dans le strcat !!!! + if (ign == 0) + { + // Premier groupe + strcpy(gro, string2char(nomGMcourant)); + for (int jg = nomGMcourant.size(); jg < MED_LNAME_SIZE; jg++) + gro[jg] = ' '; + gro[MED_LNAME_SIZE] = '\0'; + } + else + { + strcat(gro, string2char(nomGMcourant)); + for (int jg = nomGMcourant.size(); jg < MED_LNAME_SIZE; jg++) + gro[cptGM * MED_LNAME_SIZE + jg] = ' '; + gro[(cptGM + 1) * MED_LNAME_SIZE] = '\0'; + } + cptGM++; + } + + // Création de la famille + if (MEDfamilyCr(fid, maa, nomfam, numfam, 1, gro) < 0) + ERREUR("Error MEDfamilyCr"); + + delete gro; + } + } + + // ######################################################################## + // MAILLES + // ######################################################################## + // Appel de la routine ecritureTypeNew + + med_bool inomTYPE = MED_FALSE; + med_bool inumTYPE = MED_FALSE; + + med_geometry_type MGE; + + for (int itm = (int) POI1; itm <= (int) HEXA20; itm++) + { + TYPE_MAILLE tm = (TYPE_MAILLE) itm; + if (EFFECTIFS_TYPES[tm]) + { + nTYPE = EFFECTIFS_TYPES[tm]; + tTYPE = Nnoeuds(tm); + MGE = InstanceMGE(tm); + stype = TM2string(tm); + + // Noms des mailles + // char *nomTYPE = (char*) malloc(MED_SNAME_SIZE * nTYPE + 1); + // strcpy(nomTYPE, ""); // ATTENTION! + + char *nomTYPE = (char*)""; // Attention! Ne pas faire strcpy ! + + // for (int imaille = 0; imaille < IDS_MAILLES[tm].size(); imaille++) + // { + // string nomMaille = IDS_MAILLES[tm][imaille]; + // if (imaille == 0) + // { + // // Premier groupe + // strcpy(nomTYPE, string2char(nomMaille)); + // for (int jg = nomMaille.size(); jg < MED_SNAME_SIZE; jg++) + // nomTYPE[jg] = ' '; + // nomTYPE[MED_SNAME_SIZE] = '\0'; + // } + // else + // { + // strcat(nomTYPE, string2char(nomMaille)); + // for (int jg = nomMaille.size(); jg < MED_SNAME_SIZE; jg++) + // nomTYPE[imaille * MED_SNAME_SIZE + jg] = ' '; + // nomTYPE[(imaille + 1) * MED_SNAME_SIZE] = '\0'; + // } + // } + + med_int *numTYPE = NULL; // (med_int*) malloc(sizeof(med_int)*nTYPE); + + med_int *famTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE); + + // med_int *conTYPE = (med_int*) malloc(sizeof(med_int) * tTYPE * nTYPE); + // for (int i = 0; i < nTYPE * tTYPE; i++) + // *(conTYPE + i) = (med_int) CON[tm][i]; + + // Chargement famTYPE + if (nGroupesMailles) + { + // Boucle sur les mailles du type (indice = num. local) + for (int nl = 0; nl < nTYPE; nl++) + { + // Construction de l'étiquette de la maille au format string + vector v = ETIQUETTES_M[tm][nl]; + string sv = (string) ""; + for (unsigned int j = 0; j < v.size(); j++) + sv += int2string(v[j]); + // Accès au num. de la famille + *(famTYPE + nl) = (med_int) NUMFAMETIQ[sv]; + } // Boucle sur les mailles du type + } // if (nGroupesMailles) + else + for (int nl = 0; nl < nTYPE; nl++) + *(famTYPE + nl) = (med_int) 0; + + // Formatage MED des CNX + conversionCNX(CNX[tm], tm, nTYPE); + + // Chargement numTYPE + //for (int nl=0; nl listeMaillesSuppr) +{ + map TABLE_NL; // Table des num. locaux dans le type tm + + cout << "Method eliminationMailles, listeMaillesSuppr.size()=" << listeMaillesSuppr.size() << endl; + + // ************* Modification de la connectivité du type concerné + + int* CNX2; + int nNoeudsType = Nnoeuds(tm); + int tailleCNX2 = nNoeudsType * (EFFECTIFS_TYPES[tm] - listeMaillesSuppr.size()); + CNX2 = (int*) malloc(sizeof(int) * tailleCNX2); + // Recopie sélective des connectivités + int isuppr = 0; // indice dans listeMaillesSuppr + int ih2 = 0; // nouveau numéro local ( remarque: ih2 = ih1 - isuppr ) + for (int ih1 = 0; ih1 < EFFECTIFS_TYPES[tm]; ih1++) + { + if (listeMaillesSuppr[isuppr] != ih1) + { + for (int jh1 = 0; jh1 < nNoeudsType; jh1++) + *(CNX2 + nNoeudsType * ih2 + jh1) = *(CNX[tm] + nNoeudsType * ih1 + jh1); + ih2++; + } + else + isuppr++; + } + free(CNX[tm]); + CNX[tm] = CNX2; + + // ************* Construction de la table de correspondance des NL dans le type concerné + unsigned int offset = 0; + for (int i = 0; i < EFFECTIFS_TYPES[tm]; i++) + { + if (offset < listeMaillesSuppr.size()) + { + if (i < listeMaillesSuppr[offset]) + TABLE_NL[i] = i - offset; + else if (i == listeMaillesSuppr[offset]) + { + TABLE_NL[i] = -1; // Element à supprimer + offset++; + } + } + else + TABLE_NL[i] = i - offset; + } + + // Contrôle + if (offset != listeMaillesSuppr.size()) + { + ERREUR("Incoherent offset, method eliminationMailles"); + exit(0); + } + + // ************* Mise à jour du type concerné dans les GM + for (map > >::iterator I = GM.begin(); I != GM.end(); I++) + { + string nomGM = I->first; + + if (GM[nomGM][tm].size()) + { + //cout << "GM[" << nomGM <<"][" << tm << "].size()=" << GM[nomGM][tm].size() << endl; + vector mailles = GM[nomGM][tm]; + vector mailles2; //mailles2.resize(mailles.size()-listeMaillesSuppr.size()); + unsigned int cptMailles = 0; + for (unsigned int i = 0; i < mailles.size(); i++) + { + int nl2 = TABLE_NL[mailles[i]]; + if (nl2 != -1) + { + mailles2.push_back(nl2); + cptMailles++; + } + } + + GM[nomGM][tm].clear(); + mailles2.resize(cptMailles); + GM[nomGM][tm] = mailles2; + + } + } + + // ************* Mise à jour des effectifs + + EFFECTIFS_TYPES[tm] = EFFECTIFS_TYPES[tm] - listeMaillesSuppr.size(); + nombreMaillesMaillage = nombreMaillesMaillage - listeMaillesSuppr.size(); + + TABLE_NL.clear(); +} + diff --git a/src/Tools/MeshCut/MeshCut_Maillage.hxx b/src/Tools/MeshCut/MeshCut_Maillage.hxx new file mode 100644 index 000000000..06dbc5c34 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Maillage.hxx @@ -0,0 +1,165 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MESHCUT_MAILLAGE_HXX__ +#define __MESHCUT_MAILLAGE_HXX__ + +#include "MeshCut_Utils.hxx" + +#include +#include +#include + +namespace MESHCUT + { + class Maillage + { + public: + // Toutes ces variables doivent être placées au niveau du principal pour être connues de toutes les fonctions + + // Vecteurs des familles d'éléments + std::map > FAMILLES; + std::map > FAM_TYPES; + + // Vecteurs des familles de noeuds + std::map > FAMILLES_NOEUDS; + + // Description des groupes (par familles) + std::map > GROUPES_MAILLES; + std::map > GROUPES_NOEUDS; + + // Commun noeuds et mailles + std::map tailleFAMILLES; // la clé est un num. de famille + std::map tailleGROUPES; // Tailles des vecteurs GROUPES_MAILLES et GROUPES_NOEUDS - la clé est un nom de groupe (de noeuds ou de mailles) + + // Résidus mailles + std::map > RESIDU; + + public: + std::string ID; + int nombreNoeudsMaillage; // ****** MED-OBLIGATOIRE ****** + int nombreMaillesMaillage; // ****** MED-OBLIGATOIRE ****** + + class Cube *enveloppeMaillage; + + int dimensionMaillage; // ****** MED-OBLIGATOIRE ****** + int dimensionEspace; // ****** MED-OBLIGATOIRE ****** + + char axisname[3*MED_SNAME_SIZE+1]; // ****** MED-OBLIGATOIRE ****** + char unitname[3*MED_SNAME_SIZE+1]; // ****** MED-OBLIGATOIRE ****** + + float *XX; + float *YY; + float *ZZ; // ****** MED-OBLIGATOIRE ****** + + // Effectifs des éléments par type + std::map EFFECTIFS_TYPES; // ****** MED-OBLIGATOIRE ****** + + // Connectivités des types + // Le numéro global du j-ième noeud de la maille de numéro global i est stocké à l'adresse + // CNX[tm]+t*(i-1)+(j-1) + // (t = taille du type, i.e. nombre de noeuds de l'élément) + std::map CNX; // ****** MED-OBLIGATOIRE ****** + + // Enveloppes cubiques + std::map EC; + + // Description des groupes + std::map > > GM; + std::map > GN; + + // std::vector IDS_NOEUDS; // Indice = num. global - 1 + // std::map > IDS_MAILLES; // Indice = num local de maille dans le type + // + // std::vector NUM_NOEUDS; // Indice = num. global - 1 + // std::map > NUM_MAILLES; // Indice = num local de maille dans le type + + Maillage(std::string _ID); + virtual ~Maillage(); + + void creationGMtype(TYPE_MAILLE tm, std::string nomGMtype); + void afficheMailles(TYPE_MAILLE tm); + void listeMaillesType(TYPE_MAILLE tm); + void listeMaillesTousTypes(); + void listeMaillesParGM(); + void listeMaillesGM(std::string nomGM); + // void listeMaillesGMordonne(std::string nomGM); + void listeNoeuds(); + void listeNoeudsGN(std::string nomGN); + void listeNoeudsGNordonne(std::string nomGN); + std::vector G(int i, TYPE_MAILLE tm); + float distanceNoeudMaille(int ngnoeud, int imaille, TYPE_MAILLE tm); + int noeudVoisin(int ngnoeud, int imaille, TYPE_MAILLE tm); + float distanceNoeudNoeud(int ng1, int ng2); + // void encombrements() + + void inputMED(std::string fichierMED); + void outputMED(std::string fichierMED); + void outputMEDold(std::string fichierMED); + + void inputHL(std::string fichierHL /*, std::string ficDICnoeuds, std::string ficDICmailles, bool DICO */); + void outputHL(std::string fichierHL); + + void outputVRML(std::string ficVRML, float rNoeuds, char *renduAretes, char *renduFaces, float transparence); + // std::string vrmlType(TYPE_MAILLE tm, char *renduAretes, char *renduFaces, float transparence); + // void Maillage::creationGMtype(TYPE_MAILLE tm, std::vector CON_TYPE); + int NGLOBAL(TYPE_MAILLE typeMaille, int nlocal); + int NLOCAL(int nglobal, TYPE_MAILLE tm); + TYPE_MAILLE TYPE(int nglobal); + void eliminationMailles(TYPE_MAILLE typeMaille, std::vector listeMaillesSuppr); + + // acquisitionTYPE_inputMED appelée par inputMED + void + acquisitionTYPE_inputMED(TYPE_MAILLE TYPE, int nTYPE, med_idt fid, char maa[MED_NAME_SIZE + 1], med_int mdim); + + // void infoChamps(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid, char *maa, + // char *nomChamp, med_field_type typeChamp, med_int nCompChamp, std::map REFGAUSS); + + bool NoeudDansHEXA8(int n, int n0, int n1, int n2, int n3, int n4, int n5, int n6, int n7, float epsilon); + bool NoeudDansPENTA6(int n, int n0, int n1, int n2, int n3, int n4, int n5, float epsilon); + bool NoeudDansPYRAM5(int n, int n0, int n1, int n2, int n3, int n4, float epsilon); + bool NoeudDansTETRA4(int n, int n1, int n2, int n3, int n4, float epsilon); + bool NoeudDansQUAD4(int n, int n1, int n2, int n3, int n4, float epsilon); + bool NoeudDansTRIA3(int n, int n1, int n2, int n3, float epsilon); + double volumeTETRA(int n1, int n2, int n3, int n4); + double aireTRIA(int n1, int n2, int n3); + double DET3(int n1, int n2, int n3); + double DET2(int n1, int n2); + void * chargeEnveloppesCubiques(TYPE_MAILLE tm); + void * chargeEnveloppesCarrees(TYPE_MAILLE tm); + bool noeudDeMaille(int ngnoeud, int i, TYPE_MAILLE tm); + bool NoeudDansMaille3D(int n, int i, TYPE_MAILLE tm, float epsilon); + bool NoeudDansMaille2D(int n, int i, TYPE_MAILLE tm, float epsilon); + bool NoeudDansEnveloppeMaille2D(int n, int i, TYPE_MAILLE tm, float epsilon); + bool NoeudDansEnveloppeMaille3D(int n, int i, TYPE_MAILLE tm, float epsilon); + void * afficheEnveloppesCubiques(TYPE_MAILLE tm); + void * afficheEnveloppesCarrees(TYPE_MAILLE tm); + + std::vector noeudsGeomCommuns(int i1, TYPE_MAILLE tm1, int i2, TYPE_MAILLE tm2); + void creationGMresidu(); + + float longueurMoyenne(); + // void Maillage::infoChamps2(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid, + // char *maa, char *nomChamp, med_field_type typeChamp, med_int nCompChamp, map REFGAUSS); + + }; + } + +#endif diff --git a/src/Tools/MeshCut/MeshCut_Utils.cxx b/src/Tools/MeshCut/MeshCut_Utils.cxx new file mode 100644 index 000000000..e7cf9e0b4 --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Utils.cxx @@ -0,0 +1,1104 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MeshCut_Utils.hxx" + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace MESHCUT; + +//string pathUsers = (string) "/var/www/XMeshLab/users/"; + +bool MESHCUT::estUnTypeMaille(std::string S) +{ + if (S == (string) "POI1" || S == (string) "SEG2" || S == (string) "SEG3" || S == (string) "TRIA3" || S + == (string) "TRIA6" || S == (string) "QUAD4" || S == (string) "QUAD8" || S == (string) "QUAD9" || S + == (string) "TETRA4" || S == (string) "TETRA10" || S == (string) "PYRAM5" || S == (string) "PYRAM13" || S + == (string) "PENTA6" || S == (string) "PENTA15" || S == (string) "HEXA8" || S == (string) "HEXA20" || S + == (string) "HEXA27") + return true; + else + return false; +} + +void MESHCUT::ERREUR(const char* msg) +{ + cout << endl << "====== ERROR ====== " << msg << endl << endl; + exit(-1); +} + +char* MESHCUT::string2char(std::string str) +{ + // créer le buffer pour copier la chaîne + size_t size = str.size() + 1; + char* buffer = new char[size]; + // copier la chaîne + strncpy(buffer, str.c_str(), size); + + // libérer la mémoire + //delete [] buffer; + + return buffer; +} + +std::string MESHCUT::int2string(int k) +{ + std::stringstream oss; + oss << k; + return oss.str(); // oss.seekp (ios_base::beg); +} + +float MESHCUT::char2float(const char* ch) +{ + return atof(ch); +} + +std::string MESHCUT::float2string(float f) +{ + stringstream buf; + buf << fixed << f; + string s = buf.str(); + return s; +} + +bool MESHCUT::appartient(std::string e, std::string tableau[], int taille) +{ + for (int i = 0; i < taille; i++) + if (tableau[i] == e) + return true; + return false; +} + +float MESHCUT::arrondi(float x) +{ + if (x > 0 && x < 1.0e-5) + return 0; + else if (x < 0 && x > -1.0e-5) + return 0; + else + return x; +} + +int MESHCUT::numNoeudPointe(std::string b1, std::string b2, std::string b3) +{ + if (b1 == "1" && b2 == "1" && b3 == "2") + return 2; + else if (b1 == "1" && b2 == "2" && b3 == "1") + return 1; + else if (b1 == "1" && b2 == "2" && b3 == "2") + return 2; + else if (b1 == "2" && b2 == "1" && b3 == "1") + return 3; + else if (b1 == "2" && b2 == "1" && b3 == "2") + return 3; + else if (b1 == "2" && b2 == "2" && b3 == "1") + return 1; + else + return -1; +} + +std::string MESHCUT::strip(std::string S) +{ + if (S.empty()) + return S; + int startIndex = S.find_first_not_of(" "); + int endIndex = S.find_last_not_of(" "); + return S.substr(startIndex, (endIndex - startIndex + 1)); +} + +std::string MESHCUT::entierSur10_g(int i) +{ + if (i > 999999999) + ERREUR("trying to write a number superior to 999999999 on more than 10 chars"); + if (i < 10) + return int2string(i) + (string) " "; + else if (i < 100) + return int2string(i) + (string) " "; + else if (i < 1000) + return int2string(i) + (string) " "; + else if (i < 10000) + return int2string(i) + (string) " "; + else if (i < 100000) + return int2string(i) + (string) " "; + else if (i < 1000000) + return int2string(i) + (string) " "; + else if (i < 10000000) + return int2string(i) + (string) " "; + else if (i < 100000000) + return int2string(i) + (string) " "; + else if (i < 1000000000) + return int2string(i) + (string) " "; + else + return int2string(i); +} + +std::string MESHCUT::entierSur10_d(int i) +{ + if (i > 999999999) + ERREUR("trying to write a number superior to 999999999 on more than 10 chars"); + if (i < 10) + return (string) " " + int2string(i); + else if (i < 100) + return (string) " " + int2string(i); + else if (i < 1000) + return (string) " " + int2string(i); + else if (i < 10000) + return (string) " " + int2string(i); + else if (i < 100000) + return (string) " " + int2string(i); + else if (i < 1000000) + return (string) " " + int2string(i); + else if (i < 10000000) + return (string) " " + int2string(i); + else if (i < 100000000) + return (string) " " + int2string(i); + else if (i < 1000000000) + return (string) " " + int2string(i); + else + return int2string(i); +} + +std::string MESHCUT::typeEnsight(std::string type) +{ + if (type == (string) "POI1") + return (string) "point"; + else if (type == (string) "SEG2") + return (string) "bar2"; + else if (type == (string) "SEG3") + return (string) "bar2";// ATTENTION, triche! + else if (type == (string) "TRIA3") + return (string) "tria3"; + else if (type == (string) "TRIA6") + return (string) "tria3";// ATTENTION, triche! + else if (type == (string) "QUAD4") + return (string) "quad4"; + else if (type == (string) "QUAD8") + return (string) "quad4"; // ATTENTION, triche! + else if (type == (string) "QUAD9") + ERREUR("Type QUAD9 not supported by Ensight"); + else if (type == (string) "TETRA4") + return (string) "tetra4"; + else if (type == (string) "TETRA10") + return (string) "tetra4"; // ATTENTION, triche! + else if (type == (string) "PYRAM5") + return (string) "pyramid5"; + else if (type == (string) "PYRAM13") + return (string) "pyramid5"; // ATTENTION, triche! + else if (type == (string) "PENTA6") + return (string) "penta6"; + else if (type == (string) "PENTA15") + return (string) "penta6"; // ATTENTION, triche! + else if (type == (string) "HEXA8") + return (string) "hexa8"; + else if (type == (string) "HEXA20") + return (string) "hexa8"; // ATTENTION, triche! + else if (type == (string) "HEXA27") + ERREUR("Type HEXA27 not supported by Ensight"); + else + ERREUR("Type of element not accepted (method \"typeEnsight\""); + return (string) ""; +} + +int MESHCUT::Nnoeuds(TYPE_MAILLE type) +{ + switch (type) + { + case POI1: + { + return 1; + break; + } + case SEG2: + { + return 2; + break; + } + case SEG3: + { + return 3; + break; + } + case TRIA3: + { + return 3; + break; + } + case TRIA6: + { + return 6; + break; + } + case QUAD4: + { + return 4; + break; + } + case QUAD8: + { + return 8; + break; + } + //case QUAD9: { return 9; break; } + case TETRA4: + { + return 4; + break; + } + case TETRA10: + { + return 10; + break; + } + case PYRAM5: + { + return 5; + break; + } + case PYRAM13: + { + return 13; + break; + } + case PENTA6: + { + return 6; + break; + } + case PENTA15: + { + return 15; + break; + } + case HEXA8: + { + return 8; + break; + } + case HEXA20: + { + return 20; + break; + } + //case HEXA27: { return 27; break; } + default: + ERREUR("Type of elem not accepted (method Nnoeuds)"); + } + return 0; +} + +int MESHCUT::NnoeudsGeom(TYPE_MAILLE type) +{ + switch (type) + { + case POI1: + { + return 1; + break; + } + case SEG2: + { + return 2; + break; + } + case SEG3: + { + return 2; + break; + } + case TRIA3: + { + return 3; + break; + } + case TRIA6: + { + return 3; + break; + } + case QUAD4: + { + return 4; + break; + } + case QUAD8: + { + return 4; + break; + } + //case QUAD9: { return 9; break; } + case TETRA4: + { + return 4; + break; + } + case TETRA10: + { + return 4; + break; + } + case PYRAM5: + { + return 5; + break; + } + case PYRAM13: + { + return 5; + break; + } + case PENTA6: + { + return 6; + break; + } + case PENTA15: + { + return 6; + break; + } + case HEXA8: + { + return 8; + break; + } + case HEXA20: + { + return 8; + break; + } + //case HEXA27: { return 27; break; } + default: + ERREUR("Type of elem not accepted (method NnoeudsGeom)"); + } + return 0; +} + +int MESHCUT::codeGMSH(std::string type) +{ + if (type == (string) "POI1") + ERREUR("POI1 not taken into account by GMSH"); + else if (type == (string) "SEG2") + return 1; + else if (type == (string) "SEG3") + return 8; + else if (type == (string) "TRIA3") + return 2; + else if (type == (string) "TRIA6") + return 9; + else if (type == (string) "QUAD4") + return 3; + else if (type == (string) "QUAD8") + return 16; + else if (type == (string) "QUAD9") + return 10; + else if (type == (string) "TETRA4") + return 4; + else if (type == (string) "TETRA10") + return 11; + else if (type == (string) "PYRAM5") + return 7; + else if (type == (string) "PENTA6") + return 6; + else if (type == (string) "PENTA15") + return 18; + else if (type == (string) "HEXA8") + return 5; + else if (type == (string) "HEXA20") + return 17; + else if (type == (string) "HEXA27") + return 12; + else + ERREUR("Type of elem not accepted (method codeGMSH)"); + return 0; +} + +std::string MESHCUT::floatEnsight(float x) +{ + char buf[12]; + string s; + if (x < 0.0) + sprintf(buf, "%1.5E", x); + else + sprintf(buf, " %1.5E", x); + s = (string) buf; + s.erase(10, 1); + return s; +} + +bool MESHCUT::typeComplexe(std::string type) +{ + if (type == (string) "SEG3") + return true; + else if (type == (string) "TRIA6") + return true; + else if (type == (string) "QUAD8") + return true; + else if (type == (string) "QUAD9") + return true; + else if (type == (string) "TETRA10") + return true; + else if (type == (string) "PYRAM13") + return true; + else if (type == (string) "PENTA15") + return true; + else if (type == (string) "HEXA20") + return true; + else if (type == (string) "HEXA27") + return true; + else + return false; +} + +std::string MESHCUT::ASTER8(std::string s) +{ + if (s.size() == 0) + return (s + (string) " "); + else if (s.size() == 1) + return (s + (string) " "); + else if (s.size() == 2) + return (s + (string) " "); + else if (s.size() == 3) + return (s + (string) " "); + else if (s.size() == 4) + return (s + (string) " "); + else if (s.size() == 5) + return (s + (string) " "); + else if (s.size() == 6) + return (s + (string) " "); + else if (s.size() == 7) + return (s + (string) " "); + else if (s.size() == 8) + return (s); + else + ERREUR("More than 8 char for an ASTER string"); + return (s); +} + +/*! + * Distance à laquelle doit se tenir l'observateur sur un axe + * pour voir sous 90° un objet centré de dimensions a et b selon les deux autres axes. + * Si on ne tient pas compte de la dimension de l'objet selon l'axe choisi, + * la formule d_obs=max(a,b)/2 donne la cote + * qui permet de voir l'objet plat dans un angle de 90°. + * A cela il faut ajouter la dimension de l'objet selon l'axe d'observation = c. + * + * @param a dimensions de l'objet selon un des axes normal à l'axe d'observation + * @param b dimensions de l'objet selon l'autre axe normal à l'axe d'observation + * @param c est la dimension de l'objet selon l'axe d'observation + */ +float MESHCUT::dObservateur(float a, float b, float c) +{ + return (max(a, b) / 2.0 + c); +} + +int MESHCUT::copieFichier(std::string source, std::string cible) +{ + FILE *fsource, *fcible; + char buffer[512]; + int NbLu; + if ((fsource = fopen(string2char(source), "rb")) == NULL) + return -1; + if ((fcible = fopen(string2char(cible), "wb")) == NULL) + { + fclose(fsource); + return -2; + } + while ((NbLu = fread(buffer, 1, 512, fsource)) != 0) + fwrite(buffer, 1, NbLu, fcible); + fclose(fcible); + fclose(fsource); + return 0; +} + +med_geometry_type MESHCUT::InstanceMGE(TYPE_MAILLE TYPE) +{ + med_geometry_type typeBanaliseMED; + + switch (TYPE) + { + case POI1: + typeBanaliseMED = MED_POINT1; + break; // Attention, piège ! + case SEG2: + typeBanaliseMED = MED_SEG2; + break; + case SEG3: + typeBanaliseMED = MED_SEG3; + break; + case TRIA3: + typeBanaliseMED = MED_TRIA3; + break; + case TRIA6: + typeBanaliseMED = MED_TRIA6; + break; + case QUAD4: + typeBanaliseMED = MED_QUAD4; + break; + case QUAD8: + typeBanaliseMED = MED_QUAD8; + break; + case TETRA4: + typeBanaliseMED = MED_TETRA4; + break; + case TETRA10: + typeBanaliseMED = MED_TETRA10; + break; + case PYRAM5: + typeBanaliseMED = MED_PYRA5; + break; // Attention, piège ! + case PYRAM13: + typeBanaliseMED = MED_PYRA13; + break; // Attention, piège ! + case PENTA6: + typeBanaliseMED = MED_PENTA6; + break; + case PENTA15: + typeBanaliseMED = MED_PENTA15; + break; + case HEXA8: + typeBanaliseMED = MED_HEXA8; + break; + case HEXA20: + typeBanaliseMED = MED_HEXA20; + break; + default: + ERREUR("Method InstanceMGE, unknown type "); + } + return typeBanaliseMED; +} + +int MESHCUT::chrono() +{ + return clock() / CLOCKS_PER_SEC; +} + +TYPE_MAILLE MESHCUT::typeMaille(std::string type) +{ + if (type == (string) "POI1") + return POI1; + else if (type == (string) "SEG2") + return SEG2; + else if (type == (string) "SEG3") + return SEG3; + else if (type == (string) "TRIA3") + return TRIA3; + else if (type == (string) "TRIA6") + return TRIA6; + else if (type == (string) "QUAD4") + return QUAD4; + else if (type == (string) "QUAD8") + return QUAD8; + else if (type == (string) "TETRA4") + return TETRA4; + else if (type == (string) "TETRA10") + return TETRA10; + else if (type == (string) "PYRAM5") + return PYRAM5; + else if (type == (string) "PYRAM13") + return PYRAM13; + else if (type == (string) "PENTA6") + return PENTA6; + else if (type == (string) "PENTA15") + return PENTA15; + else if (type == (string) "HEXA8") + return HEXA8; + else if (type == (string) "HEXA20") + return HEXA20; + else + ERREUR("ERROR method typeMaille, unknown type"); + return POI1; +} + +std::string MESHCUT::MGE2string(med_geometry_type MGE) +{ + if (MGE == MED_NONE) + return (string) "NOEUD"; + else if (MGE == MED_POINT1) + return (string) "POI1"; + else if (MGE == MED_SEG2) + return (string) "SEG2"; + else if (MGE == MED_SEG3) + return (string) "SEG3"; + else if (MGE == MED_TRIA3) + return (string) "TRIA3"; + else if (MGE == MED_TRIA6) + return (string) "TRIA6"; + else if (MGE == MED_QUAD4) + return (string) "QUAD4"; + else if (MGE == MED_QUAD8) + return (string) "QUAD8"; + else if (MGE == MED_TETRA4) + return (string) "TETRA4"; + else if (MGE == MED_TETRA10) + return (string) "TETRA10"; + else if (MGE == MED_PYRA5) + return (string) "PYRAM5"; + else if (MGE == MED_PYRA13) + return (string) "PYRAM13"; + else if (MGE == MED_PENTA6) + return (string) "PENTA6"; + else if (MGE == MED_PENTA15) + return (string) "PENTA15"; + else if (MGE == MED_HEXA8) + return (string) "HEXA8"; + else if (MGE == MED_HEXA20) + return (string) "HEXA20"; + else + ERREUR("ERROR method MGE2string, unknown type"); + return (string) "NOEUD"; +} + +std::string MESHCUT::TM2string(TYPE_MAILLE MGE) +{ + if (MGE == POI1) + return (string) "POI1"; + else if (MGE == SEG2) + return (string) "SEG2"; + else if (MGE == SEG3) + return (string) "SEG3"; + else if (MGE == TRIA3) + return (string) "TRIA3"; + else if (MGE == TRIA6) + return (string) "TRIA6"; + else if (MGE == QUAD4) + return (string) "QUAD4"; + else if (MGE == QUAD8) + return (string) "QUAD8"; + else if (MGE == TETRA4) + return (string) "TETRA4"; + else if (MGE == TETRA10) + return (string) "TETRA10"; + else if (MGE == PYRAM5) + return (string) "PYRAM5"; + else if (MGE == PYRAM13) + return (string) "PYRAM13"; + else if (MGE == PENTA6) + return (string) "PENTA6"; + else if (MGE == PENTA15) + return (string) "PENTA15"; + else if (MGE == HEXA8) + return (string) "HEXA8"; + else if (MGE == HEXA20) + return (string) "HEXA20"; + else + ERREUR("ERROR method TM2string, unknown type"); + return (string) "POI1"; +} + +TYPE_MAILLE MESHCUT::string2TM(std::string stm) +{ + if (stm == (string) "POI1") + return POI1; + else if (stm == (string) "SEG2") + return SEG2; + else if (stm == (string) "SEG3") + return SEG3; + else if (stm == (string) "TRIA3") + return TRIA3; + else if (stm == (string) "TRIA6") + return TRIA6; + else if (stm == (string) "QUAD4") + return QUAD4; + else if (stm == (string) "QUAD8") + return QUAD8; + else if (stm == (string) "TETRA4") + return TETRA4; + else if (stm == (string) "TETRA10") + return TETRA10; + else if (stm == (string) "PYRAM5") + return PYRAM5; + else if (stm == (string) "PYRAM13") + return PYRAM13; + else if (stm == (string) "PENTA6") + return PENTA6; + else if (stm == (string) "PENTA15") + return PENTA15; + else if (stm == (string) "HEXA8") + return HEXA8; + else if (stm == (string) "HEXA20") + return HEXA20; + else + ERREUR("ERROR method string2TM, unknown type"); + return POI1; +} + +std::string MESHCUT::coordIndex_ILS(TYPE_MAILLE tm) +{ + if (tm == SEG2) + return (string) " 0,1 "; + else if (tm == SEG3) + return (string) " 0,1 "; // Idem SEG2 + else if (tm == TRIA3) + return (string) " 0,1,2,0 "; + else if (tm == TRIA6) + return (string) " 0,1,2,0 "; + else if (tm == QUAD4) + return (string) " 0,1,2,3,0 "; + else if (tm == QUAD8) + return (string) " 0,1,2,3,0 "; + else if (tm == TETRA4) + return (string) " 0,1,2,0,-1, 0,3,-1, 1,3,-1, 2,3,-1 "; + else if (tm == TETRA10) + return (string) " 0,1,2,0,-1, 0,3,-1, 1,3,-1, 2,3,-1 "; + else if (tm == PYRAM5) + return (string) " 0,1,2,3,0,-1, 0,4,-1, 1,4,-1, 2,4,-1, 3,4,-1 "; + else if (tm == PYRAM13) + return (string) " 0,1,2,3,0,-1, 0,4,-1, 1,4,-1, 2,4,-1, 3,4,-1 "; + else if (tm == PENTA6) + return (string) " 0,1,2,0,-1, 3,4,5,3,-1, 0,3,-1, 1,4,-1, 2,5,-1 "; + else if (tm == PENTA15) + return (string) " 0,1,2,0,-1, 3,4,5,3,-1, 0,3,-1, 1,4,-1, 2,5,-1 "; + else if (tm == HEXA8) + return (string) " 0,1,2,3,0,-1, 4,5,6,7,4,-1, 0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1 "; + else if (tm == HEXA20) + return (string) " 0,1,2,3,0,-1, 4,5,6,7,4,-1, 0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1 "; + else + return (string) ""; +} + +std::string MESHCUT::coordIndex_IFS(TYPE_MAILLE tm) +{ + if (tm == SEG2) + return (string) " "; + else if (tm == SEG3) + return (string) " "; // Idem SEG2 + else if (tm == TRIA3) + return (string) " 0,1,2,0,-1, 0,2,1,0,-1 "; + else if (tm == TRIA6) + return (string) " 0,1,2,0,-1, 0,2,1,0,-1 "; + else if (tm == QUAD4) + return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1 "; + else if (tm == QUAD8) + return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1 "; + else if (tm == TETRA4) + return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 0,3,1,0,-1, 0,1,3,0,-1, 1,3,2,1,-1, 1,2,3,1,-1, 0,2,3,0,-1, 0,3,2,0,-1 "; + else if (tm == TETRA10) + return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 0,3,1,0,-1, 0,1,3,0,-1, 1,3,2,1,-1, 1,2,3,1,-1, 0,2,3,0,-1, 0,3,2,0,-1 "; + else if (tm == PYRAM5) + return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 0,1,4,0,-1, 0,4,1,0,-1, 1,2,4,1,-1, 1,4,2,1,-1, 2,4,3,2,-1, 2,3,4,2,-1, 3,4,0,3,-1, 3,0,4,3,-1 "; + else if (tm == PYRAM13) + return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 0,1,4,0,-1, 0,4,1,0,-1, 1,2,4,1,-1, 1,4,2,1,-1, 2,4,3,2,-1, 2,3,4,2,-1, 3,4,0,3,-1, 3,0,4,3,-1 "; + else if (tm == PENTA6) + return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 3,4,5,3,-1, 3,5,4,3,-1, 0,1,4,3,0,-1, 0,3,4,1,0,-1, 1,4,5,2,1,-1, 1,2,5,4,1,-1, 0,3,5,2,0,-1, 0,2,5,3,0,-1 "; + else if (tm == PENTA15) + return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 3,4,5,3,-1, 3,5,4,3,-1, 0,1,4,3,0,-1, 0,3,4,1,0,-1, 1,4,5,2,1,-1, 1,2,5,4,1,-1, 0,3,5,2,0,-1, 0,2,5,3,0,-1 "; + else if (tm == HEXA8) + return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 1,5,6,2,1,-1, 1,2,6,5,1,-1, 5,4,7,6,5,-1, 5,6,7,4,5,-1, 4,0,3,7,4,-1, 4,7,3,0,4,-1, 0,4,5,1,0,-1, 0,1,5,4,0,-1, 3,7,6,2,3,-1, 3,2,6,7,3,-1 "; + else if (tm == HEXA20) + return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 1,5,6,2,1,-1, 1,2,6,5,1,-1, 5,4,7,6,5,-1, 5,6,7,4,5,-1, 4,0,3,7,4,-1, 4,7,3,0,4,-1, 0,4,5,1,0,-1, 0,1,5,4,0,-1, 3,7,6,2,3,-1, 3,2,6,7,3,-1 "; + else + return (string) ""; +} + +std::string MESHCUT::SIGNE(double x) +{ + if (x < 0) + return "-"; + else if (x > 0) + return "+"; + else + return "0"; +} + +void MESHCUT::champType(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid, med_idt fidout, + char *maa, char *nomChamp, char *nomChampMoy, med_field_type typeChamp, char *compChamp, + char *unitChamp, med_int nCompChamp, std::map REFGAUSS, int ichamp) +{ + + bool debug = true; + int ipt, nmailles, ngauss, imaille, igauss, icomp; + // int ival, ngpdt; + med_int nval, numdt, numo, nPasTemps; + char dtunit[MED_SNAME_SIZE + 1] = ""; + char locname[MED_NAME_SIZE + 1] = ""; + char nomprofil[MED_NAME_SIZE + 1] = ""; + med_float dt = 0.0; + med_float *valr = NULL; + med_float *valr2 = NULL; + med_bool local; + // med_int nbrefmaa; + med_field_type fieldType; + + if (MEDfieldInfo(fid, ichamp, nomChamp, maa, &local, &fieldType, compChamp, unitChamp, dtunit, &nPasTemps) < 0) + ERREUR("Error MEDfieldInfo"); + cout << type << " : " << (int) nPasTemps << " timestep " << endl; + + for (ipt = 1; ipt <= nPasTemps; ipt++) + { + //for (ipt=1; ipt<=min(nPasTemps,1); ipt++) { + if (debug) + cout << endl; + if (debug) + cout << "************************************************************" << endl; + if (debug) + cout << " FIELD " << ichamp << endl; + if (debug) + cout << " " << nomChamp << endl; + if (debug) + cout << " " << type << " --- Timestep " << ipt << endl; + if (debug) + cout << "************************************************************" << endl; + if (debug) + cout << endl; + + if (MEDfieldComputingStepInfo(fid, nomChamp, ipt, &numdt, &numo, &dt) < 0) + { + cout << endl; + cout << endl << "####################################################################" << endl; + cout << " ERROR MEDpasdetempsInfo " << endl; + cout << endl << "####################################################################" << endl; + cout << " Field: " << (string) nomChamp << endl; + cout << " Geometrie: " << MGE2string(MGE) << endl; + cout << " Timestep " << ipt << " ignored" << endl; + + continue; + } + + med_int profilesize, nintegrationpoint; + nval = MEDfieldnValueWithProfile(fid, nomChamp, numdt, numo, MEM, MGE, ipt, MED_COMPACT_PFLMODE, nomprofil, + &profilesize, locname, &nintegrationpoint); + if (debug) + cout << " Number of values in this timestep: " << (int) nval << endl; + + if (typeChamp == MED_FLOAT64) + valr = (med_float*) calloc(nCompChamp * nval, sizeof(med_float)); + else + ERREUR("Type of field not taken into account"); + + if (MEDfieldValueWithProfileRd(fid, maa, numdt, numo, MEM, MGE, MED_COMPACT_PFLMODE, nomprofil, + MED_FULL_INTERLACE, MED_ALL_CONSTITUENT, (unsigned char*) valr) < 0) + { + cout << endl; + cout << endl << "####################################################################" << endl; + cout << " ERROR MEDchampLire " << endl; + cout << endl << "####################################################################" << endl; + cout << endl; + cout << " Field: " << (string) nomChamp << endl; + cout << " Geometry: " << MGE2string(MGE) << endl; + cout << " Timestep " << ipt << " ignored" << endl; + cout << endl << endl; + continue; + } + + if (debug) + cout << " profile = " << (string) nomprofil << endl; + // Localisation du champ aux points de Gauss + if (debug) + cout << " locname = " << (string) locname << endl; + + if (REFGAUSS[(string) locname]) + { + ngauss = REFGAUSS[(string) locname]; + if (debug) + cout << " " << ngauss << " Gauss points by element)" << endl; + } + else + ngauss = 1; + + nmailles = nval / ngauss; + if (debug) + cout << " Nbre de mailles: " << nmailles << endl; + + if (debug) + { + cout << endl << " Liste des valeurs du champ brut aux 3 premiers éléments:" << endl; + for (imaille = 0; imaille < min(nmailles, 3); imaille++) + { + cout << " Maille " << imaille << endl; + for (igauss = 0; igauss < ngauss; igauss++) + { + cout << " PG " << igauss << " : "; + for (icomp = 0; icomp < nCompChamp; icomp++) + cout << " " << *(valr + imaille * ngauss * nCompChamp + igauss * nCompChamp + icomp); + cout << endl; + } + cout << endl; + } + cout << endl; + } + + if (ngauss > 1) + { + + valr2 = (med_float*) calloc(nCompChamp * nmailles, sizeof(med_float)); + + if (debug) + cout << endl << " Moyenne sur les PG des mailles" << endl; + for (imaille = 0; imaille < nmailles; imaille++) + { + for (icomp = 0; icomp < nCompChamp; icomp++) + { + float valCompMaille = 0.0; + for (igauss = 0; igauss < ngauss; igauss++) + valCompMaille += *(valr + imaille * ngauss * nCompChamp + igauss * nCompChamp + icomp); + *(valr2 + imaille * nCompChamp + icomp) = valCompMaille / ngauss; + + } + } + + //cout << endl << "Nom champ moy = " << (string)nomChampMoy << endl; + //cout << endl << "Type champ = " << typeChamp << endl; + //cout << endl << "Comp champ = " << (string)compChamp << endl; + //cout << endl << "Unit champ = " << (string)unitChamp << endl; + //cout << endl << "N comp champ = " << nCompChamp << endl; + + if (MEDfieldValueWithProfileWr(fidout, nomChampMoy, numdt, numo, dt, MEM, MGE, MED_COMPACT_PFLMODE, + nomprofil, MED_NO_LOCALIZATION, MED_FULL_INTERLACE, MED_ALL_CONSTITUENT, + (med_int) nmailles, (unsigned char*) valr2) < 0) + { + cout << endl; + cout << endl << "********************************************************************" << endl; + cout << "******************** ***********************" << endl; + cout << "******************** ERROR MEDchampEcr ***********************" << endl; + cout << "******************** ***********************" << endl; + cout << "********************************************************************" << endl; + cout << endl; + cout << " Champ: " << (string) nomChampMoy << endl; + cout << " Géométrie: " << MGE2string(MGE) << endl; + cout << " Pas de temps " << ipt << " ignoré" << endl; + cout << endl << endl; + continue; + } + + if (debug) + cout << " Writing mean values in new field: OK " << endl; + + // Restitution du champ moyenné + if (debug) + { + cout << endl << " Liste des valeurs du champ moyenné aux 3 premiers éléments:" << endl; + for (imaille = 0; imaille < min(nmailles, 3); imaille++) + { + cout << " Maille " << imaille << endl; + for (icomp = 0; icomp < nCompChamp; icomp++) + cout << " " << *(valr2 + imaille * nCompChamp + icomp); + cout << endl; + } + cout << endl; + } + + } + + free(valr); + free(valr2); + + } // boucle sur les pas de temps + + cout << endl; +} + +std::string MESHCUT::nomMaille(TYPE_MAILLE tm, int nl) +{ + return (TM2string(tm) + (string) "_" + int2string(nl)); +} + +bool MESHCUT::appartientVN(int n, std::vector V) +{ + bool app = false; + for (unsigned int i = 0; i < V.size(); i++) + if (n == V[i]) + { + app = true; + break; + } + return app; +} + +float MESHCUT::distance2(float x1, float y1, float z1, float x2, float y2, float z2) +{ + return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1); +} + +/*! + * Conversion HL-MED d'une table de connectivités + */ +void MESHCUT::conversionCNX(int *CNXtm, TYPE_MAILLE tm, int N) +{ + + int n = Nnoeuds(tm); + + if (tm == TETRA4) + { + for (int i = 0; i < N; i++) + { + int i1 = CNXtm[i * n + 1]; + int i2 = CNXtm[i * n + 2]; + CNXtm[i * n + 1] = i2; + CNXtm[i * n + 2] = i1; + } + } + else if (tm == PYRAM5) + { + for (int i = 0; i < N; i++) + { + int i1 = CNXtm[i * n + 1]; + int i3 = CNXtm[i * n + 3]; + CNXtm[i * n + 1] = i3; + CNXtm[i * n + 3] = i1; + } + } + else if (tm == PENTA6) + { + for (int i = 0; i < N; i++) + { + int i0 = CNXtm[i * n + 0]; + int i1 = CNXtm[i * n + 1]; + int i2 = CNXtm[i * n + 2]; + int i3 = CNXtm[i * n + 3]; + int i4 = CNXtm[i * n + 4]; + int i5 = CNXtm[i * n + 5]; + CNXtm[i * n + 0] = i3; + CNXtm[i * n + 1] = i4; + CNXtm[i * n + 2] = i5; + CNXtm[i * n + 3] = i0; + CNXtm[i * n + 4] = i1; + CNXtm[i * n + 5] = i2; + } + } + + else if (tm == HEXA8) + { + for (int i = 0; i < N; i++) + { + int i0 = CNXtm[i * n + 0]; + int i1 = CNXtm[i * n + 1]; + int i2 = CNXtm[i * n + 2]; + int i3 = CNXtm[i * n + 3]; + int i4 = CNXtm[i * n + 4]; + int i5 = CNXtm[i * n + 5]; + int i6 = CNXtm[i * n + 6]; + int i7 = CNXtm[i * n + 7]; + CNXtm[i * n + 0] = i4; + CNXtm[i * n + 1] = i5; + CNXtm[i * n + 2] = i6; + CNXtm[i * n + 3] = i7; + CNXtm[i * n + 4] = i0; + CNXtm[i * n + 5] = i1; + CNXtm[i * n + 6] = i2; + CNXtm[i * n + 7] = i3; + } + } +} + diff --git a/src/Tools/MeshCut/MeshCut_Utils.hxx b/src/Tools/MeshCut/MeshCut_Utils.hxx new file mode 100644 index 000000000..36eb22d0f --- /dev/null +++ b/src/Tools/MeshCut/MeshCut_Utils.hxx @@ -0,0 +1,81 @@ +// Copyright (C) 2006-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MESHCUT_UTILS_HXX__ +#define __MESHCUT_UTILS_HXX__ + +extern "C" + { +#include + } + +#include +#include +#include + +namespace MESHCUT + { + + enum TYPE_MAILLE + { + POI1, SEG2, SEG3, TRIA3, TRIA6, QUAD4, QUAD8, TETRA4, TETRA10, PYRAM5, PYRAM13, PENTA6, PENTA15, HEXA8, HEXA20 + }; + + bool estUnTypeMaille(std::string S); + void ERREUR(const char* msg); + char* string2char(std::string str); + std::string int2string(int k); + float char2float(const char* ch); + std::string float2string(float f); + bool appartient(std::string e, std::string tableau[], int taille); + float arrondi(float x); + int numNoeudPointe(std::string b1, std::string b2, std::string b3); + std::string strip(std::string S); + std::string entierSur10_g(int i); + std::string entierSur10_d(int i); + std::string typeEnsight(std::string type); + int Nnoeuds(TYPE_MAILLE type); + int NnoeudsGeom(TYPE_MAILLE type); + int codeGMSH(std::string type); + std::string floatEnsight(float x); + bool typeComplexe(std::string type); + std::string ASTER8(std::string s); + float dObservateur(float a, float b, float c); + + int copieFichier(std::string source, std::string cible); + med_geometry_type InstanceMGE(TYPE_MAILLE TYPE); + int chrono(); + TYPE_MAILLE typeMaille(std::string type); + std::string MGE2string(med_geometry_type MGE); + std::string TM2string(TYPE_MAILLE MGE); + TYPE_MAILLE string2TM(std::string stm); + std::string coordIndex_ILS(TYPE_MAILLE tm); + std::string coordIndex_IFS(TYPE_MAILLE tm); + std::string SIGNE(double x); + void champType(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid, med_idt fidout, + char *maa, char *nomChamp, char *nomChampMoy, med_field_type typeChamp, char *compChamp, + char *unitChamp, med_int nCompChamp, std::map REFGAUSS, int ichamp); + std::string nomMaille(TYPE_MAILLE tm, int nl); + bool appartientVN(int n, std::vector V); + float distance2(float x1, float y1, float z1, float x2, float y2, float z2); + void conversionCNX(int *CNXtm, TYPE_MAILLE tm, int N); + + } + +#endif diff --git a/src/Tools/MeshCut/README b/src/Tools/MeshCut/README new file mode 100644 index 000000000..599806b18 --- /dev/null +++ b/src/Tools/MeshCut/README @@ -0,0 +1,26 @@ + + + Cut a tetrahedron mesh by a plane + --------------------------------- + +MeshCut allows to cut a mesh constituted of linear tetrahedrons by a plane. +The tetrahedrons intersected by the plane are cut and replaced by elements of various types, +(tetrahedron, pyramid, pentahedron). + +MeshCut is a standalone program, reading and producing med files. + +Syntax: + +MeshCut input.med output.med resuMeshName aboveGroup belowGroup nx ny nz px py pz T + +where: + input.med = name of the original mesh file in med format + output.med = name of the result mesh file in med format + resuMeshName = name of the result mesh + aboveGroup = name of the group of volumes above the cut plane + belowGroups = name of the group of volumes below the cut plane + nx ny nz = vector normal to the cut plane + px py pz = a point of the cut plane + T = 0 < T < 1 : vertices of a tetrahedron are considered as belonging to + the cut plane if their distance to the plane is inferior to L*T + where L is the mean edge size of the tetrahedron diff --git a/src/Tools/MeshCut/meshcut_plugin.py b/src/Tools/MeshCut/meshcut_plugin.py new file mode 100644 index 000000000..eaab60897 --- /dev/null +++ b/src/Tools/MeshCut/meshcut_plugin.py @@ -0,0 +1,140 @@ +# Copyright (C) 2006-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# if you already have plugins defined in a salome_plugins.py file, add this file at the end. +# if not, copy this file as ${HOME}/Plugins/smesh_plugins.py or ${APPLI}/Plugins/smesh_plugins.py + +def MeshCut(context): + # get context study, studyId, salomeGui + study = context.study + studyId = context.studyId + sg = context.sg + + import os + import subprocess + import tempfile + from PyQt4 import QtCore + from PyQt4 import QtGui + from PyQt4.QtGui import QFileDialog + from PyQt4.QtGui import QMessageBox + from MeshCutDialog import Ui_Dialog + + class CutDialog(QtGui.QDialog): + + def __init__(self): + QtGui.QDialog.__init__(self) + # Set up the user interface from Designer. + self.ui = Ui_Dialog() + self.ui.setupUi(self) + # Connect up the buttons. + self.connect(self.ui.pb_origMeshFile, QtCore.SIGNAL("clicked()"), + self.setInputFile) + self.connect(self.ui.pb_cutMeshFile, QtCore.SIGNAL("clicked()"), + self.setOutputFile) + self.connect(self.ui.pb_help, QtCore.SIGNAL("clicked()"), + self.helpMessage) + pass + + def setInputFile(self): + fd = QFileDialog(self, "select an existing Med file", self.ui.le_origMeshFile.text(), "MED-Files (*.med);;All Files (*)") + if fd.exec_(): + infile = fd.selectedFiles()[0] + self.ui.le_origMeshFile.setText(infile) + insplit = os.path.splitext(infile.toLocal8Bit().data()) + outfile = insplit[0] + '_cut' + insplit[1] + self.ui.le_cutMeshFile.setText(outfile) + pass + + def setOutputFile(self): + fd = QFileDialog(self, "select an output Med file", self.ui.le_cutMeshFile.text(), "MED-Files (*.med);;All Files (*)") + if fd.exec_(): + self.ui.le_cutMeshFile.setText(fd.selectedFiles()[0]) + pass + + def helpMessage(self): + QMessageBox.about(None, "About MeshCut", + """ + Cut a tetrahedron mesh by a plane + --------------------------------- + +MeshCut allows to cut a mesh constituted of linear +tetrahedrons by a plane. The tetrahedrons intersected +by the plane are cut and replaced by elements of +various types (tetrahedron, pyramid, pentahedron). + +MeshCut is a standalone program, reading and +producing med files. The cutting plane is defined +by a vector normal to the plane and a vertex +belonging to the plane. + +Vertices of a tetrahedron are considered as belonging to +the cut plane if their distance to the plane is inferior +to L*T where L is the mean edge size of the tetrahedron +and T the tolerance. + """) + pass + pass + + + + window = CutDialog() + window.ui.dsb_tolerance.setValue(0.01) + retry = True + while(retry): + retry = False + window.exec_() + result = window.result() + if result: + # dialog accepted + args = ['MeshCut'] + args += [window.ui.le_origMeshFile.text().toLocal8Bit().data()] + args += [window.ui.le_cutMeshFile.text().toLocal8Bit().data()] + args += [window.ui.le_outMeshName.text().toLocal8Bit().data()] + args += [window.ui.le_groupAbove.text().toLocal8Bit().data()] + args += [window.ui.le_groupBelow.text().toLocal8Bit().data()] + args += [str(window.ui.dsb_normX.value())] + args += [str(window.ui.dsb_normY.value())] + args += [str(window.ui.dsb_normZ.value())] + args += [str(window.ui.dsb_vertX.value())] + args += [str(window.ui.dsb_vertY.value())] + args += [str(window.ui.dsb_vertZ.value())] + args += [str(window.ui.dsb_tolerance.value())] + f= tempfile.NamedTemporaryFile(delete=False) + fname = f.name + p = subprocess.Popen(args, stdout=f, stderr=f) + err = p.wait() + f.close() + if err==0: + os.remove(fname) + else: + f = open(fname, 'r') + m = f.read() + msgBox = QMessageBox() + msgBox.setText("Parameters are not OK") + msgBox.setInformativeText("Do you want to retry ?") + msgBox.setDetailedText(m) + msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Cancel) + msgBox.setDefaultButton(QMessageBox.Retry) + ret = msgBox.exec_() + if ret == QMessageBox.Retry: + retry = True + pass + pass + pass + pass diff --git a/src/Tools/padder/Makefile.am b/src/Tools/padder/Makefile.am new file mode 100644 index 000000000..e771536bd --- /dev/null +++ b/src/Tools/padder/Makefile.am @@ -0,0 +1,22 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SUBDIRS = meshjob spadderpy unittests resources doc + +EXTRA_DIST = README.txt diff --git a/src/Tools/padder/README.txt b/src/Tools/padder/README.txt new file mode 100644 index 000000000..2ecebb32c --- /dev/null +++ b/src/Tools/padder/README.txt @@ -0,0 +1,38 @@ + + +PADDER overview +--------------- + +PADDER is an algorithm that creates a set of particules called a "discrete mesh". +The particules are characterized by a location in space and a weight that can be considered +as the radius of a sphere whose center is the location of the particule. + +Discrete meshes are typically used to modelize civil components in rapid dynamic +computation problems (seisms, chocs). These components consists in concrete parts +embedding steal bares for reinforcement. These parts are input to the algorithm +as standard finite elements meshes. The cells of theses meshes drive the location +and sizing of particules. + +In the med representation, a discrete mesh is described as MED_BALL elements. +A MED_BALL element is defined by a location and a radius. + +PADDER plugin +------------- + +This directory provides SMESH with a SALOME plugin that can be used to define +and then run a PADDER execution. The inputs are the FE meshes that describe +the concrete parts and steal bares parts. The output is a discrete mesh +containing MED_BALL elements. + +A graphical interface is used to drive the user for data input and computation +supervision (the algorithm may last more than an hour long), and finally the publication +of the resulting mesh (when succeed) in the SALOME study. + +Technically speaking, the PADDER plugin consists in: + +* a SALOME component MESHJOB that do the computation job (wrapper to the padder executable program) +* a graphical interface composed of two dialog windows +* a configuration mechanism (data file and read function), to define + the computation resource (a SALOME resource + the software configuration of the padder executable + program on this resource) +* an integration file (salomeplugin.py) diff --git a/src/Tools/padder/doc/Makefile.am b/src/Tools/padder/doc/Makefile.am new file mode 100755 index 000000000..ec45f7474 --- /dev/null +++ b/src/Tools/padder/doc/Makefile.am @@ -0,0 +1,39 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# Author : Guillaume Boulant (EDF/R&D) + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +EXTRA_DIST += images input + +# +# The simplest way to extend the documentation of SMESH with the +# documentation for PADDER is to add path to the padder documentation +# in the SMESH gui documentation (see the doxyfile). +# + +# For test purpose, we let the user generate a local dosygen +# documentation including only the local pages +# +test_docs: doxyfile + echo "===========================================" ; \ + echo "Generating PADDER documentation" ; \ + echo "===========================================" ; \ + $(DOXYGEN) doxyfile ; diff --git a/src/Tools/padder/doc/doxyfile.in b/src/Tools/padder/doc/doxyfile.in new file mode 100755 index 000000000..7ce741cfa --- /dev/null +++ b/src/Tools/padder/doc/doxyfile.in @@ -0,0 +1,77 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "SALOME Mesh User's Guide" +OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +TAB_SIZE = 5 + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES + +#--------------------------------------------------------------------------- +#Input related options +#--------------------------------------------------------------------------- +INPUT = @srcdir@/input +FILE_PATTERNS = *.doc +EXCLUDE = +IMAGE_PATH = @srcdir@/images +EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG + +#--------------------------------------------------------------------------- +#HTML related options +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_HEADER = @top_builddir@/doc/salome/gui/SMESH/static/header.html +HTML_FOOTER = @top_srcdir@/doc/salome/gui/SMESH/static/footer.html +HTML_STYLESHEET = @top_srcdir@/doc/salome/gui/SMESH/static/doxygen.css +TOC_EXPAND = YES +DISABLE_INDEX = NO +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 300 + +#--------------------------------------------------------------------------- +#SORT related options +#--------------------------------------------------------------------------- +SORT_GROUP_NAMES = NO + + +#--------------------------------------------------------------------------- +#LaTeX related option +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +EXTRA_PACKAGES = amsmath + +#--------------------------------------------------------------------------- +#RTF related options +#--------------------------------------------------------------------------- +GENERATE_RTF = NO + +SEARCHENGINE = YES diff --git a/src/Tools/padder/doc/images/SMESH_spadder_end.png b/src/Tools/padder/doc/images/SMESH_spadder_end.png new file mode 100644 index 000000000..12e2b7cf2 Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_end.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png new file mode 100644 index 000000000..ed0a8a72c Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png new file mode 100644 index 000000000..8725d7165 Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png new file mode 100644 index 000000000..8e692dcff Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_menu.png b/src/Tools/padder/doc/images/SMESH_spadder_menu.png new file mode 100644 index 000000000..e89140690 Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_menu.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png new file mode 100644 index 000000000..e29cf5634 Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png new file mode 100644 index 000000000..f86790b0c Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png new file mode 100644 index 000000000..b3c9ef169 Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png new file mode 100644 index 000000000..19e1ae71f Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png new file mode 100644 index 000000000..45ba1a097 Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png differ diff --git a/src/Tools/padder/doc/images/SMESH_spadder_start.png b/src/Tools/padder/doc/images/SMESH_spadder_start.png new file mode 100644 index 000000000..160da9d26 Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_start.png differ diff --git a/src/Tools/padder/doc/input/padder_userguide.doc b/src/Tools/padder/doc/input/padder_userguide.doc new file mode 100644 index 000000000..d92f85ef6 --- /dev/null +++ b/src/Tools/padder/doc/input/padder_userguide.doc @@ -0,0 +1,139 @@ +/*! + +\page padder_userguide_page Use the padder SMESH Plugin + +-# \ref S1_PADDER +-# \ref S2_PADDER +-# \ref S3_PADDER + +\section S1_PADDER The PADDER Algorithm + +PADDER is an algorithm that creates a set of particules called a "discrete mesh". +The particules are characterized by a location in space and a weight that can be considered +as the radius of a sphere whose center is the location of the particule. + +Discrete meshes are typically used to modelize civil components in rapid dynamic +computation problems (seisms, chocs). These components consists in concrete parts +embedding steal bares for reinforcement. These parts are input to the algorithm +as standard finite elements meshes. The cells of theses meshes drive the location +and sizing of particules. + +In the med representation, a discrete mesh is described as MED_BALL elements. +A MED_BALL element is defined by a location and a radius. + +\section S2_PADDER The PADDER SALOME plugin + +The PADDER algoritm is integrated in the module SMESH as a SALOME +plugin. This section illustrates how to use this plugin to create a +discrete mesh. + +In this example, we suppose that two standard meshes (Finite Elements +Meshes) have been created and publish in the study to modelize the +concrete part (here with the name "concrete") and the steal bars part +(here with the name "ferrail"): + +\image html SMESH_spadder_start.png + +The PADDER plugin can be invoked from the SMESH plugins menu, as +illustrated on the figure below: + +\image html SMESH_spadder_menu.png + +When you clic on the "PADDER mesher" item, the graphical interface of +the PADDER plugin appears: + +\image html SMESH_spadder_plugindialog_start.png + +This interface invites you to specify input data by pressing the button +"Input". This command opens the Input dialog box to specify the list +of meshes and the type of the selected meshes (to be choosen between +"concrete" or "steelbar" using the combobox on the right side of the +input line): + +\image html SMESH_spadder_inputdialog_start.png + +In the figure below, the mesh with name "concrete" has been selected +in the study and added in the list of input file as a "concrete +mesh". You have to input the mesh in the dialog using the rounded +arrow icon, then specify a group name (the name of the group of +MED_BALL created for this mesh in the resulting mesh), and finnaly +clic on the "Add" icon: + +\image html SMESH_spadder_inputdialog_concrete.png + +Then, the mesh with name "ferrail" is selected and added to the list +as a "steelbar mesh": + +\image html SMESH_spadder_inputdialog_steelbar.png + +The input dialog box can be validated toreturn to the main plugin +interface. The "Compute" button is now enable, indicating that the +problem is ready to be computed: + +\image html SMESH_spadder_plugindialog_compute_ready.png + +The command "Compute" start the job. The progression can be requested +using the command "Refresh". In the figure below, the job is still +running: + +\image html SMESH_spadder_plugindialog_compute_running.png + +Finally, the job is finished and the result is ready to be published +in the SALOME study: + +\image html SMESH_spadder_plugindialog_compute_finished.png + +Clic on the command "Publish" to explicitly import the resulting med +file in SMESH and published the resulting mesh in the SALOME study: + +\image html SMESH_spadder_plugindialog_published.png + +Note that this mesh contains one group for each of the input mesh. A +group with the name specified in the input dialog has been defined for +the set of MED_BALL created from the corresponding input mesh: + +\image html SMESH_spadder_end.png + +\section S3_PADDER Configuring the plugin + +The configuration of the plugin consists in specifying the location of +the padder executable program for each of the SALOME resource (at +least for the localhost resource). This specification is done in the +file padder.cfg, located in the plugin installation folder +(i.e. /plugins): + +\code +# This section specify the configurations to be used respectively for +# the local execution and the remote execution. The value for 'local' +# and 'remote' keys must be the name of a configuration section in +# this file. The default key must specify a value between "local" or +# "remote" to indicate the user preference. +[resources] +local = localhost +remote = nepal + +[preferences] +defaultres = local + +# The following sections defines the available configurations. +# The name of the section can be choosen arbitrary. But the value of +# the resname key MUST be the name of a SALOME resource defined in the +# catalog of resources (CatalogResources.xml). + +# For each section: +# - resname : the name of the SALOME resource to be used in this configuration +# - binpath : the path to the padder executable program on this resource +# - envpath : the path to the environment file on this resource +[localhost] +resname = localhost +binpath = /home/.programs/salome/workspace/V6_4_BR/SMESH/install/share/salome/resources/smesh/padderexe/padder.exe +envpath = /home/.programs/salome/workspace/V6_4_BR/SMESH/install/share/salome/resources/smesh/padderexe/envPadder.sh + +[nepal] +resname = nepal@nepal +binpath = /usr/local/bin/padder.exe +envpath = /usr/local/share/envPadder.sh +\endcode + +*/ + diff --git a/src/Tools/padder/meshjob/Makefile.am b/src/Tools/padder/meshjob/Makefile.am new file mode 100644 index 000000000..b1a47b9d9 --- /dev/null +++ b/src/Tools/padder/meshjob/Makefile.am @@ -0,0 +1,20 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SUBDIRS = idl impl diff --git a/src/Tools/padder/meshjob/idl/MESHJOB.idl b/src/Tools/padder/meshjob/idl/MESHJOB.idl new file mode 100644 index 000000000..a5559cd77 --- /dev/null +++ b/src/Tools/padder/meshjob/idl/MESHJOB.idl @@ -0,0 +1,126 @@ +// Copyright (C) 2011-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors : Guillaume Boulant (EDF) - 31/01/2011 + +#ifndef _MESHJOB_IDL_ +#define _MESHJOB_IDL_ + +#include "SALOME_Exception.idl" +#include "SALOME_Component.idl" + +// +// This interface is used for mesh job submission from within the +// SALOME plugin for PADDER. +// +module MESHJOB +{ + + // + // Structure to transmit the parameters requiered for the job to run + // the executable program on the target resource. See configure + // service. + // + struct ConfigParameter { + string resname; // The name of the SALOME resource to be used + string binpath; // The path of the executable program on this resource + string envpath; // The path of the environment file on this resource + }; + + // + // This set of specification defines the data structure used to + // initialize a job on a specific resource, then supervise the job + // and finally retrieve the result data. + // + + // This defines the set of temporary folders used by the jobmanager + // when executing a job (may depends on the job). + struct MeshJobPaths + { + string local_inputdir; + string local_resultdir; + string remote_workdir; + }; + + // This defines the possible types for a job parameter + enum FileType {MED_CONCRETE, MED_STEELBAR}; + + // This defines a single parameter for the job initialization (a med file) + struct MeshJobParameter + { + string file_name; + FileType file_type; + string group_name; + }; + + // This defines a set of parameters for the job initialization + typedef sequence MeshJobParameterList; + + // This defines the result data of a job + struct MeshJobResults + { + string results_dirname; + string outputmesh_filename; + string status; + }; + + // This defines the possible states of a job + enum MeshJobState {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR}; + + // + // This interface defines the computation services of the component + // + + interface MeshJobManager: Engines::EngineComponent + { + + /*! Add a resource configuration, identified by the string + configId and characterized by the parameters in + configParameter */ + boolean configure(in string configId, in MESHJOB::ConfigParameter configParameter) + raises (SALOME::SALOME_Exception); + + /*! Initialize a smesh computation job and return the job identifier */ + long initialize(in MESHJOB::MeshJobParameterList meshJobParameterList, in string configId) + raises (SALOME::SALOME_Exception); + + /*! Submit the job execution and return true if submission is OK */ + boolean start(in long jobId) + raises (SALOME::SALOME_Exception); + + /*! Request the launch manager for the state of the specified job */ + string getState(in long jobId) + raises (SALOME::SALOME_Exception); + + /*! Request the launch manager for downloading the results */ + MeshJobResults finalize(in long jobid) + raises (SALOME::SALOME_Exception); + + /*! Clean all data associated to this job and remove the job from the launch manager */ + boolean clean(in long jobId) + raises (SALOME::SALOME_Exception); + + /*! Returns the set of temporary folders used by the job instance */ + MeshJobPaths getPaths(in long jobId) + raises (SALOME::SALOME_Exception); + + }; + +}; + +#endif // _MESHJOB_IDL_ diff --git a/src/Tools/padder/meshjob/idl/Makefile.am b/src/Tools/padder/meshjob/idl/Makefile.am new file mode 100644 index 000000000..15bb1a87c --- /dev/null +++ b/src/Tools/padder/meshjob/idl/Makefile.am @@ -0,0 +1,95 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# This Makefile is responsible of generating the client and server +# implementation of IDL interfaces for both C++ and python usage. +# The building process of the C++ files is in charge of each source +# package and then is not manage here. +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +BUILT_SOURCES = MESHJOBSK.cc +IDL_FILES = MESHJOB.idl + +# For test purpose, we add a little component: +BUILT_SOURCES += SPADDERPluginTestSK.cc +IDL_FILES += SPADDERPluginTest.idl + +IDL_FILES_PY=$(IDL_FILES:%.idl=%_idl.py) + +salomeidl_DATA = $(IDL_FILES) + +lib_LTLIBRARIES = libSalomeIDLSPADDER.la +libSalomeIDLSPADDER_la_SOURCES = +nodist_libSalomeIDLSPADDER_la_SOURCES = $(BUILT_SOURCES) +nodist_salomeinclude_HEADERS= $(IDL_FILES:%idl=%hh) + +OMNIORB_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@ +OMNIORB_LIBS=@OMNIORB_LIBS@ + +libSalomeIDLSPADDER_la_CXXFLAGS = \ + $(KERNEL_CXXFLAGS) \ + $(OMNIORB_CXXFLAGS) \ + -I. + +libSalomeIDLSPADDER_la_LIBADD = \ + $(KERNEL_LDFLAGS) -lSalomeIDLKernel \ + $(OMNIORB_LIBS) + + +# These variables defines the building process of CORBA files +IDLCXXFLAGS = \ + -bcxx -I. \ + @OMNIORB_IDLCXXFLAGS@ \ + -I$(KERNEL_ROOT_DIR)/idl/salome + +IDLPYFLAGS = \ + -I. \ + @OMNIORB_IDLPYFLAGS@ \ + -I$(KERNEL_ROOT_DIR)/idl/salome + +########################################################## +SUFFIXES = .idl .hh SK.cc + +%SK.cc %.hh : %.idl + $(OMNIORB_IDL) $(IDLCXXFLAGS) $< + +%_idl.py : %.idl + $(OMNIORB_IDL) $(IDLPYFLAGS) $< + +CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx + +EXTRA_DIST += $(IDL_FILES) + +install-data-local: $(IDL_FILES) + $(INSTALL) -d $(DESTDIR)$(salomepythondir) + ls $^ | while read file; do \ + $(OMNIORB_IDL) $(IDLPYFLAGS) -C$(DESTDIR)$(salomepythondir) $$file ; \ + done + +# we want to remove only staff generated for IDL files and nothing more +uninstall-local: + @for modulen in MESHJOB SPADDERPluginTest ; do \ + test -d $(DESTDIR)$(salomepythondir)/$${modulen} && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen} ; \ + test -d $(DESTDIR)$(salomepythondir)/$${modulen}__POA && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}__POA" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen}__POA ; \ + done ; \ + for filen in $(IDL_FILES_PY) ; do \ + echo "Removing $(DESTDIR)$(salomepythondir)/$${filen}" && rm -f $(DESTDIR)$(salomepythondir)/$${filen}* ; \ + done + diff --git a/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl b/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl new file mode 100644 index 000000000..e0beec0e9 --- /dev/null +++ b/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl @@ -0,0 +1,46 @@ +// Copyright (C) 2011-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors : Guillaume Boulant (EDF) - 31/01/2011 + +#ifndef _SPADDERPLUGINTEST_IDL_ +#define _SPADDERPLUGINTEST_IDL_ + +#include "SALOME_Exception.idl" +#include "SALOME_Component.idl" + +module SPADDERPluginTest { + + // + // ======================================================================== + // Thi module defines an interface provided for testing the usage + // of SPADDERPlugin components and underlying classes from within a + // C++ unit test running in a SALOME container (easy to run from a + // python client).. + // ======================================================================== + // + + interface SPADDERPluginTester: Engines::EngineComponent + { + void demo(in double a,in double b,out double c) raises (SALOME::SALOME_Exception); + boolean testkernel() raises (SALOME::SALOME_Exception); + boolean testsmesh(in long studyId) raises (SALOME::SALOME_Exception); + }; +}; + +#endif // _SPADDERPLUGINTEST_IDL_ diff --git a/src/Tools/padder/meshjob/impl/Makefile.am b/src/Tools/padder/meshjob/impl/Makefile.am new file mode 100644 index 000000000..31a6dbbdf --- /dev/null +++ b/src/Tools/padder/meshjob/impl/Makefile.am @@ -0,0 +1,89 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +AM_CFLAGS=$(SALOME_INCLUDES) -fexceptions + +lib_LTLIBRARIES= libMeshJobManagerEngine.la + +salomeinclude_HEADERS= \ + MeshJobManager_i.hxx + + +# ============================================================= +# Definition of MeshJobManagerEngine construction +# ============================================================= +libMeshJobManagerEngine_la_SOURCES = \ + MeshJobManager_i.cxx + +LIBXML_LIBS=@LIBXML_LIBS@ +KERNEL_CXXFLAGS=@KERNEL_CXXFLAGS@ + +libMeshJobManagerEngine_la_CXXFLAGS = \ + -I$(top_builddir)/src/Tools/padder/meshjob/idl $(KERNEL_CXXFLAGS) \ + @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ @LIBXML_INCLUDES@ + +libMeshJobManagerEngine_la_FFLAGS = -fexceptions +libMeshJobManagerEngine_la_LDFLAGS = \ + $(top_builddir)/src/Tools/padder/meshjob/idl/libSalomeIDLSPADDER.la \ + @KERNEL_LDFLAGS@ -lSalomeContainer -lSalomeKernelHelpers -lSalomeLifeCycleCORBA \ + @LIBXML_LIBS@ + +# ============================================================= +# Definition of the SPADDERPluginTester engine construction +# ============================================================= +lib_LTLIBRARIES += libSPADDERPluginTesterEngine.la + +libSPADDERPluginTesterEngine_la_SOURCES = \ + SPADDERPluginTester_i.hxx \ + SPADDERPluginTester_i.cxx + +nodist_libSPADDERPluginTesterEngine_la_SOURCES = + +libSPADDERPluginTesterEngine_la_CXXFLAGS = \ + -I$(top_builddir)/src/Tools/padder/meshjob/idl $(KERNEL_CXXFLAGS) \ + @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ @LIBXML_INCLUDES@ + +libSPADDERPluginTesterEngine_la_FFLAGS = -fexceptions +libSPADDERPluginTesterEngine_la_LIBADD = \ + $(top_builddir)/src/Tools/padder/meshjob/idl/libSalomeIDLSPADDER.la \ + @KERNEL_LDFLAGS@ -lSalomeContainer -lSalomeKernelHelpers \ + @LIBXML_LIBS@ + + +# For testing SMESH +# +libSPADDERPluginTesterEngine_la_CXXFLAGS += \ + @GEOM_CXXFLAGS@ @MED_CXXFLAGS@ \ + -I$(top_builddir)/idl \ + -I$(top_srcdir)/src/SMESH \ + -I$(top_srcdir)/src/SMESH_I \ + -I$(top_srcdir)/src/SMESHDS \ + -I$(top_srcdir)/src/SMDS \ + -I$(top_srcdir)/src/SMESHUtils \ + $(VTK_INCLUDES) $(CAS_CPPFLAGS) $(BOOST_CPPFLAGS) + +libSPADDERPluginTesterEngine_la_LIBADD += \ + $(top_builddir)/src/SMESH/libSMESHimpl.la \ + $(top_builddir)/src/SMESH_I/libSMESHEngine.la \ + $(top_builddir)/src/SMESHDS/libSMESHDS.la \ + $(top_builddir)/src/SMDS/libSMDS.la \ + $(top_builddir)/src/SMESHUtils/libSMESHUtils.la + diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx new file mode 100644 index 000000000..72520fbab --- /dev/null +++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx @@ -0,0 +1,631 @@ +// Copyright (C) 2011-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors : Guillaume Boulant (EDF) - 01/03/2011 + +#ifdef WIN32 +#include +#include +#else +#include +#endif + +#include "MeshJobManager_i.hxx" + +#include +#include CORBA_SERVER_HEADER(SALOME_Exception) + + +#include "Basics_Utils.hxx" // For standard logging +#undef LOG +#include "SALOME_KernelServices.hxx" // For CORBA logging +#undef LOG + +#define LOG STDLOG + +// +// ==================================================================== +// General purpose helper functions (to put elsewhere at least) +// ==================================================================== +// + +/*! + * This function must be used to associate a datetime tag to a job + */ + +#ifndef WIN32 +static long timetag() { + timeval tv; + gettimeofday(&tv,0); + long tag = tv.tv_usec + tv.tv_sec*1000000; + return tag; +} +#endif + +/*! + * This function returns true if the string text starts with the string + * token. + */ +static bool myStartsWith(const std::string& text,const std::string& token){ + if(text.length() < token.length()) + return false; + return (text.compare(0, token.length(), token) == 0); +} + +// +// ==================================================================== +// Constructor/Destructor +// ==================================================================== +// +MeshJobManager_i::MeshJobManager_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + : Engines_Component_i(orb, poa, contId, instanceName, interfaceName) +{ + LOG("Activating MESHJOB::MeshJobManager object"); + _thisObj = this ; + _id = _poa->activate_object(_thisObj); + + _salomeLauncher = KERNEL::getSalomeLauncher(); + if(CORBA::is_nil(_salomeLauncher)){ + LOG("The SALOME launcher can't be reached ==> STOP"); + throw KERNEL::createSalomeException("SALOME launcher can't be reached"); + } + + _resourcesManager = KERNEL::getResourcesManager(); + if(CORBA::is_nil(_resourcesManager)){ + LOG("The SALOME resource manager can't be reached ==> STOP"); + throw KERNEL::createSalomeException("The SALOME resource manager can't be reached"); + } +} + +MeshJobManager_i::~MeshJobManager_i() { + LOG("MeshJobManager_i::~MeshJobManager_i()"); +} + +// +// ==================================================================== +// Helper functions to deals with the local and remote file systems +// ==================================================================== +// +#include // to get the file streams +#ifdef WNT +#include // to get _splitpath +#include // to get _mkdir +#else +#include // to get basename +#include // to get mkdir +#include // to get mkdir options +#endif + +#include // to get system and getenv + +static std::string OUTPUTFILE("output.med"); +static std::string DATAFILE("data.txt"); +static std::string SCRIPTFILE("padder.sh"); +static std::string SEPARATOR(" "); + +static std::string USER(getenv("USER")); +static std::string LOCAL_INPUTDIR("/tmp/spadder.local.inputdir."+USER); +static std::string LOCAL_RESULTDIR("/tmp/spadder.local.resultdir."+USER); +static std::string REMOTE_WORKDIR("/tmp/spadder.remote.workdir."+USER); + +/*! + * This function creates the padder text input file containing the + * input data (list of filenames and groupnames) and returns the path + * of the created file. This function is the one that knows the format + * of the padder input file. If the input file format changes, then + * this function (and only this one) should be updated. + */ +const char * MeshJobManager_i::_writeDataFile(std::vector listConcreteMesh, + std::vector listSteelBarMesh) { +#ifdef WIN32 + _mkdir(LOCAL_INPUTDIR.c_str()); +#else + mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + + // Make it static so that it's allocated once (constant name) + static std::string * dataFilename = new std::string(LOCAL_INPUTDIR+"/"+DATAFILE); + std::ofstream dataFile(dataFilename->c_str()); + + // We first specify the concrete mesh data (filename and groupname) + std::string line; +#ifdef WIN32 + char fname[ _MAX_FNAME ]; + _splitpath( listConcreteMesh[0].file_name, NULL, NULL, fname, NULL ); + char* bname = &fname[0]; +#else + char* bname = basename(listConcreteMesh[0].file_name); +#endif + line = std::string(bname) + " " + std::string(listConcreteMesh[0].group_name); + dataFile << line.c_str() << std::endl; + // Note that we use here the basename because the files are supposed + // to be copied in the REMOTE_WORKDIR for execution. + + // The, we can specify the steelbar mesh data, starting by the + // number of meshes + int nbSteelBarMesh=listSteelBarMesh.size(); + line = std::string("nbSteelbarMesh") + SEPARATOR + ToString(nbSteelBarMesh); + dataFile << line.c_str() << std::endl; + for (int i=0; ic_str(); +} + +/*! + * This function creates a shell script that runs padder whith the + * specified data file, and returns the path of the created script + * file. The config id is used to retrieve the path to the binary file + * and other required files. + */ +const char* MeshJobManager_i::_writeScriptFile(const char * dataFileName, const char * configId) { +#ifdef WIN32 + _mkdir(LOCAL_INPUTDIR.c_str()); +#else + mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + + // Make it static so that it's allocated once (constant name) + static std::string * scriptFilename = new std::string(LOCAL_INPUTDIR+"/"+SCRIPTFILE); + + char * binpath = _configMap[configId].binpath; + char * envpath = _configMap[configId].envpath; + +#ifdef WIN32 + char fname[ _MAX_FNAME ]; + _splitpath( dataFileName, NULL, NULL, fname, NULL ); + const char* bname = &fname[0]; +#else + const char* bname = basename(dataFileName); +#endif + + + std::ofstream script(scriptFilename->c_str()); + script << "#!/bin/sh" << std::endl; + script << "here=$(dirname $0)" << std::endl; + script << ". " << envpath << std::endl; + script << binpath << " $here/" << bname << std::endl; + // Note that we use the basename of the datafile because all data + // files are supposed to have been copied in the REMOTE_WORKDIR. + script.close(); + return scriptFilename->c_str(); +} + +// +// ==================================================================== +// Functions to initialize and supervise the mesh computation job +// ==================================================================== +// +bool MeshJobManager_i::configure(const char *configId, + const MESHJOB::ConfigParameter & configParameter) +{ + beginService("MeshJobManager_i::configure"); + + _configMap[configId] = configParameter; + + LOG("Adding configuration for " << configId); + LOG("- binpath = " << _configMap[configId].binpath); + LOG("- envpath = " << _configMap[configId].envpath); + + endService("MeshJobManager_i::configure"); + return true; +} + +long MeshJobManager_i::JOBID_UNDEFINED = -1; + +/*! Initialize a smesh computation job and return the job identifier */ +CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobParameterList & meshJobParameterList, + const char * configId) +{ + beginService("MeshJobManager_i::initialize"); + std::cerr << "##################################### initialize" << std::endl; + std::cerr << "#####################################" << std::endl; + + // + // We first analyse the CORBA sequence to store data in C++ vectors + // + std::vector listConcreteMesh; + std::vector listSteelBarMesh; + for(CORBA::ULong i=0; iremote_workdir = (REMOTE_WORKDIR + "." + ToString(jobDatetimeTag)).c_str(); + + // + // Then, we have to create the padder input data file. This input + // data is a text file containing the list of file names and group + // names. + // + const char * dataFilename = this->_writeDataFile(listConcreteMesh, listSteelBarMesh); + LOG("dataFilename = " << dataFilename); + const char * scriptFilename = this->_writeScriptFile(dataFilename, configId); + LOG("scriptFilename = " << scriptFilename); + + // + // Then, the following instructions consists in preparing the job + // parameters to request the SALOME launcher for creating a new + // job. + // + Engines::JobParameters_var jobParameters = new Engines::JobParameters; + jobParameters->job_type = CORBA::string_dup("command"); + // CAUTION: the job_file must be a single filename specifying a + // self-consistent script to be executed without any argument on the + // remote host. + jobParameters->job_file = CORBA::string_dup(scriptFilename); + + // + // Specification of the working spaces: + // + // - local_directory: can be used to specify where to find the input + // files on the local resource. It's optionnal if you specify the + // absolute path name of input files. + // + // - result_directory: must be used to specify where to download the + // output files on the local resources + // + // - work_directory: must be used to specify the remote directory + // where to put all the stuff to run the job. Note that the job + // will be executed from within this directory, i.e. a change + // directory toward this working directory is done by the batch + // system before running the specified job script. + // + jobParameters->local_directory = CORBA::string_dup(""); + jobParameters->result_directory = CORBA::string_dup(jobPaths->local_resultdir); + jobParameters->work_directory = CORBA::string_dup(jobPaths->remote_workdir); + + // We specify the input files that are required to execute the + // job_file. If basenames are specified, then the files are supposed + // to be located in local_directory. + int nbFiles = listSteelBarMesh.size()+2; + // The number of input file is: + // (nb. of steelbar meshfile) + // + (1 concrete meshfile) + // + (1 padder input file) + // = nb steelbar meshfile + 2 + jobParameters->in_files.length(nbFiles); + jobParameters->in_files[0] = CORBA::string_dup(listConcreteMesh[0].file_name); + for (int i=0; iin_files[1+i] = CORBA::string_dup(listSteelBarMesh[i].file_name); + } + jobParameters->in_files[1+listSteelBarMesh.size()] = CORBA::string_dup(dataFilename); + // Note that all these input files will be copied in the + // REMOTE_WORKDIR on the remote host + + // Then, we have to specify the existance of an output + // filenames. The path is supposed to be a path on the remote + // resource, i.e. where the job is executed. + jobParameters->out_files.length(1); + std::string outputfile_name = std::string(jobPaths->remote_workdir)+"/"+OUTPUTFILE; + jobParameters->out_files[0] = CORBA::string_dup(outputfile_name.c_str()); + + // CAUTION: the maximum duration has to be set with a format like "hh:mm" + jobParameters->maximum_duration = CORBA::string_dup("01:00"); + jobParameters->queue = CORBA::string_dup(""); + + // Setting resource and additionnal properties (if needed) + // The resource parameters can be initiated from scratch, for + // example by specifying the values in hard coding: + // >>> + //jobParameters->resource_required.name = CORBA::string_dup("localhost"); + //jobParameters->resource_required.hostname = CORBA::string_dup("localhost"); + //jobParameters->resource_required.mem_mb = 1024 * 10; + //jobParameters->resource_required.nb_proc = 1; + // <<< + // But it's better to initiate these parameters from a resource + // definition known by the resource manager. This ensures that the + // resource will be available: + //const char * resourceName = "localhost"; + //const char * resourceName = "boulant@claui2p1"; + //const char * resourceName = "nepal@nepal"; + const char * resourceName = _configMap[configId].resname; + Engines::ResourceDefinition * resourceDefinition = _resourcesManager->GetResourceDefinition(resourceName); + // CAUTION: This resource should have been defined in the + // CatalogResource.xml associated to the SALOME application. + // + // Then, the values can be used to initiate the resource parameters + // of the job: + jobParameters->resource_required.name = CORBA::string_dup(resourceDefinition->name.in()); + // CAUTION: the additionnal two following parameters MUST be + // specified explicitly, because they are not provided by the + // resource definition: + jobParameters->resource_required.mem_mb = resourceDefinition->mem_mb; + jobParameters->resource_required.nb_proc = resourceDefinition->nb_proc_per_node; + // CAUTION: the parameter mem_mb specifies the maximum memory value + // that could be allocated for executing the job. This takes into + // account not only the data that could be loaded by the batch + // process but also the linked dynamic library. + // + // A possible problem, for exemple in the case where you use the ssh + // emulation of a batch system, is to get an error message as below + // when libBatch try to run the ssh command: + // + // ## /usr/bin/ssh: error while loading shared libraries: libcrypto.so.0.9.8: failed + // ## to map segment from shared object: Cannot allocate memory + // + // In this exemple, the mem_mb was set to 1MB, value that is not + // sufficient to load the dynamic libraries linked to the ssh + // executable (libcrypto.so in the error message). + // + // So, even in the case of a simple test shell script, you should + // set this value at least to a standard threshold as 500MB + + int jobId = JOBID_UNDEFINED; + try { + std::cerr << "#####################################" << std::endl; + std::cerr << "#####################################" << std::endl; + std::cerr << "jobUndef = " << JOBID_UNDEFINED << std::endl; + jobId = _salomeLauncher->createJob(jobParameters); + std::cerr << "#####################################" << std::endl; + std::cerr << "#####################################" << std::endl; + std::cerr << "#####################################" << std::endl; + std::cerr << "jobId = " << jobId << std::endl; + // We register the datetime tag of this job + _jobDateTimeMap[jobId]=jobDatetimeTag; + _jobPathsMap[jobId] = jobPaths; + } + catch (const SALOME::SALOME_Exception & ex) { + LOG("SALOME Exception in createJob !" <launchJob(jobId); + } + catch (const SALOME::SALOME_Exception & ex) { + LOG("SALOME Exception in launchjob !" <getJobState(jobId); + } + catch (const SALOME::SALOME_Exception & ex) + { + LOG("SALOME Exception in getJobState !"); + state = ex.details.text; + } + catch (const CORBA::SystemException& ex) + { + LOG("Receive SALOME System Exception: " << ex); + state="SALOME System Exception - see logs"; + } + LOG("jobId="<getPaths(jobId); + std::string local_resultdir(jobPaths->local_resultdir); + result->results_dirname = local_resultdir.c_str(); + try + { + _salomeLauncher->getJobResults(jobId, local_resultdir.c_str()); + + // __BUG__: to prevent from a bug of the MED driver (SALOME + // 5.1.5), we change the basename of the output file to force the + // complete reloading of data by the med driver. + long jobDatetimeTag = _jobDateTimeMap[jobId]; + std::string outputFileName = "output"+ToString(jobDatetimeTag)+".med"; + rename((local_resultdir+"/"+OUTPUTFILE).c_str(), (local_resultdir+"/"+outputFileName).c_str()); + + result->outputmesh_filename = outputFileName.c_str(); + result->status = "OK"; + } + catch (const SALOME::SALOME_Exception & ex) + { + LOG("SALOME Exception in getResults !"); + result->status = "SALOME Exception in getResults !"; + } + catch (const CORBA::SystemException& ex) + { + LOG("Receive CORBA System Exception: " << ex); + result->status = "Receive CORBA System Exception: see log"; + } + endService("MeshJobManager_i::getResults"); + return result; +} + + +/*! Clean all data associated to this job and remove the job from the launch manager */ +bool MeshJobManager_i::clean(CORBA::Long jobId) { + beginService("MeshJobManager_i::clean"); + + // __GBO__ WORK IN PROGRESS: we just clean the temporary local + // directories. The remote working directories are tag with the + // execution datetime and the we prevent the task from conflict + // with files of another task. + MESHJOB::MeshJobPaths * jobPaths = this->getPaths(jobId); + if ( jobPaths == NULL ) return false; + + // WARN: !!!!! + // For safety reason (and prevent from bug that could erase the + // filesystem), we cancel the operation in the case where the + // directories to delete are not in the /tmp folder. + std::string shell_command("rm -rf "); + std::string inputdir(jobPaths->local_inputdir); + std::string resultdir(jobPaths->local_resultdir); + if ( !myStartsWith(inputdir,"/tmp/") ) { + LOG("WRN: The directory "< * MeshJobManager_i::_getResourceNames() { + + // + // These part is just to control the available resources + // + Engines::ResourceParameters params; + KERNEL::getLifeCycleCORBA()->preSet(params); + + Engines::ResourceList * resourceList = _resourcesManager->GetFittingResources(params); + Engines::ResourceDefinition * resourceDefinition = NULL; + LOG("### resource list:"); + std::vector* resourceNames = new std::vector(); + if (resourceList) { + for (int i = 0; i < resourceList->length(); i++) { + const char* aResourceName = (*resourceList)[i]; + resourceNames->push_back(std::string(aResourceName)); + LOG("resource["<GetResourceDefinition(aResourceName); + LOG("protocol["<protocol); + } + } + + // Note: a ResourceDefinition is used to create a batch configuration + // in the Launcher. This operation is done at Launcher startup from + // the configuration file CatalogResources.xml provided by the + // SALOME application. + // In the code instructions, you just have to choose a resource + // configuration by its name and then define the ResourceParameters + // that specify additionnal properties for a specific job submission + // (use the attribute resource_required of the JobParameters). + + return resourceNames; +} + + +// +// ========================================================================== +// Factory services +// ========================================================================== +// +extern "C" +{ + PortableServer::ObjectId * MeshJobManagerEngine_factory( CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + { + LOG("PortableServer::ObjectId * MeshJobManagerEngine_factory()"); + MeshJobManager_i * myEngine = new MeshJobManager_i(orb, poa, contId, instanceName, interfaceName); + return myEngine->getId() ; + } +} diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx new file mode 100644 index 000000000..283a92d7a --- /dev/null +++ b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx @@ -0,0 +1,81 @@ +// Copyright (C) 2011-2012 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors : Guillaume Boulant (EDF) - 01/03/2011 + +#ifndef _MESHJOBMANAGER_HXX_ +#define _MESHJOBMANAGER_HXX_ + +// include the stubs generating from MESHJOB.idl +#include +#include CORBA_SERVER_HEADER(MESHJOB) +#include CORBA_SERVER_HEADER(SALOME_Component) +#include "SALOME_Component_i.hxx" + +#include "SALOME_Launcher.hxx" +#include +#include +#include + +class MeshJobManager_i: public virtual POA_MESHJOB::MeshJobManager, + public Engines_Component_i +{ +public: + MeshJobManager_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, const char *interfaceName); + ~MeshJobManager_i(); + + bool configure (const char *configId, + const MESHJOB::ConfigParameter & configParameter); + CORBA::Long initialize (const MESHJOB::MeshJobParameterList & meshJobParameterList, + const char *configId); + bool start (CORBA::Long jobId); + char* getState (CORBA::Long jobId); + MESHJOB::MeshJobResults * finalize(CORBA::Long jobId); + MESHJOB::MeshJobPaths * getPaths(CORBA::Long jobId); + bool clean (CORBA::Long jobId); + + static long JOBID_UNDEFINED; + +private: + Engines::SalomeLauncher_var _salomeLauncher; + Engines::ResourcesManager_var _resourcesManager; + + // This maps the config identifier to the config parameters. A + // config is a resource with additionnal data specifying the + // location of the binary program to be executed by the task + std::map _configMap; + + // This maps a job identifier to its associated datetime tag. When + // a job is created during the initialize function, a datetime tag + // is associated to this job and can be used to characterized files + // and directories associated to this job. + std::map _jobDateTimeMap; + std::map _jobPathsMap; + + const char* _writeDataFile (std::vector listConcreteMesh, + std::vector listSteelBarMesh); + const char* _writeScriptFile (const char * dataFileName, const char * configId); + + std::vector * _getResourceNames(); + +}; + +#endif + diff --git a/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.cxx b/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.cxx new file mode 100644 index 000000000..805eb4f91 --- /dev/null +++ b/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.cxx @@ -0,0 +1,157 @@ +// Copyright (C) 2011-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors : Guillaume Boulant (EDF) - 01/03/2011 + +#include "SPADDERPluginTester_i.hxx" + +#include +#include + +// For standard logging +#include "Basics_Utils.hxx" + +// +// ========================================================================== +// Implementation of the SPADDER component interface +// ========================================================================== +// +using namespace std; + +/*! + * Constructor for component "SPADDER" instance + */ +SPADDERPluginTester_i::SPADDERPluginTester_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + : Engines_Component_i(orb, poa, contId, instanceName, interfaceName) +{ + LOG("Activating SPADDERPluginTester_i::SPADDERPluginTester object"); + _thisObj = this ; + _id = _poa->activate_object(_thisObj); +} + +//! Destructor for component "SPADDER" instance +SPADDERPluginTester_i::~SPADDERPluginTester_i() +{ + std::cerr << "SPADDERPluginTester destruction" << std::endl; +} + +/*! + * This test is just to check the component SPADDER. + */ +void SPADDERPluginTester_i::demo(CORBA::Double a,CORBA::Double b,CORBA::Double& c) +{ + beginService("SPADDERPluginTester_i::demo"); + try { + //BODY + + std::cerr << "a: " << a << std::endl; + std::cerr << "b: " << b << std::endl; + c=a+b; + std::cerr << "c: " << c << std::endl; + + } + catch ( const SALOME_Exception & ex) { + SALOME::ExceptionStruct es; + es.text=CORBA::string_dup(ex.what()); + es.type=SALOME::INTERNAL_ERROR; + throw SALOME::SALOME_Exception(es); + } + catch ( const SALOME::SALOME_Exception & ex) { + throw; + } + catch (...) { + std::cerr << "unknown exception" << std::endl; + SALOME::ExceptionStruct es; + es.text=CORBA::string_dup(" unknown exception"); + es.type=SALOME::INTERNAL_ERROR; + throw SALOME::SALOME_Exception(es); + } + endService("SPADDERPluginTester_i::demo"); +} + +#ifdef LOG +#undef LOG +#endif + +#include +#include "SALOME_Launcher.hxx" +bool SPADDERPluginTester_i::testkernel() +{ + beginService("SPADDERPluginTester_i::testplugin"); + + Engines::SalomeLauncher_ptr salomeLauncher = KERNEL::getSalomeLauncher(); + + endService("SPADDERPluginTester_i::testplugin"); + return true; +} + + +#include +#include +#include +#include CORBA_CLIENT_HEADER(SALOMEDS) + +#include + +/*! + * This test checks the constructor of the basic classes of the SMESH + * plugin for PADDER. + */ +bool SPADDERPluginTester_i::testsmesh(CORBA::Long studyId) +{ + beginService("SPADDERPluginTester_i::testsmesh"); + + // Resolve the SMESH engine and the SALOME study + // _WARN_ The SMESH engine should have been loaded first + SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); + CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject); + SALOMEDS::Study_var myStudy = aStudyMgr->GetStudyByID(studyId); + + // + // _MEM_ CAUTION: SMESH_Gen define a data structure for local usage + // while SMESH_Gen_i is the implementation of the SMESH_Gen IDL + // interface. + // + + endService("SPADDERPluginTester_i::testsmesh"); + return true; +} + +// +// ========================================================================== +// Factory services +// ========================================================================== +// +extern "C" +{ + PortableServer::ObjectId * SPADDERPluginTesterEngine_factory( CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + { + MESSAGE("PortableServer::ObjectId * SPADDERPluginTesterEngine_factory()"); + SPADDERPluginTester_i * myEngine = new SPADDERPluginTester_i(orb, poa, contId, instanceName, interfaceName); + return myEngine->getId() ; + } +} diff --git a/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.hxx b/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.hxx new file mode 100644 index 000000000..26a7416cd --- /dev/null +++ b/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2011-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors : Guillaume Boulant (EDF) - 01/03/2011 + +#ifndef _SPADDER_PLUGINTESTER_HXX_ +#define _SPADDER_PLUGINTESTER_HXX_ + +// include the stubs generating from SPADDERPluginTest.idl +#include +#include CORBA_SERVER_HEADER(SPADDERPluginTest) +#include +#include "SALOME_Component_i.hxx" + +class SPADDERPluginTester_i: + public virtual POA_SPADDERPluginTest::SPADDERPluginTester, + public Engines_Component_i +{ +public: + SPADDERPluginTester_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, const char *interfaceName); + virtual ~SPADDERPluginTester_i(); + + void demo(CORBA::Double a,CORBA::Double b,CORBA::Double& c); + bool testkernel(); + bool testsmesh(CORBA::Long studyId); + +}; + +#endif + diff --git a/src/Tools/padder/meshjob/impl/testhelper.hxx b/src/Tools/padder/meshjob/impl/testhelper.hxx new file mode 100644 index 000000000..adc7fdf29 --- /dev/null +++ b/src/Tools/padder/meshjob/impl/testhelper.hxx @@ -0,0 +1,66 @@ +// Copyright (C) 2011-2012 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Authors : Guillaume Boulant (EDF) - 01/03/2011 + +#ifndef __TESTHELPER_HXX__ +#define __TESTHELPER_HXX__ + +// >>> +// WARN: this file is DEPRECATED and/or should be used for test +// purpose only. The PADDER configuration is now read in a +// configuration file (padder.cfg). +// <<< + +#include // Standard C include (for getenv) +#include +#include + +/*! + * This function returns the module SMESH installation root directory + * as a string. + */ +static std::string SMESH_ROOT_DIR() { + static std::string * smesh_root_dir; + if ( smesh_root_dir == NULL ) { + char * SMESH_ROOT_DIR = getenv("SMESH_ROOT_DIR"); + if ( SMESH_ROOT_DIR == NULL ) { + smesh_root_dir = new std::string(""); + } + else { + smesh_root_dir = new std::string(SMESH_ROOT_DIR); + } + } + return *smesh_root_dir; +} + +/*! Relative path of the directory containing data and exe for tests */ +static std::string PADDEREXE_RPATH("/share/salome/resources/smesh/padderexe"); +/*! Absolute path of the directory containing data and exe for tests */ +static std::string PADDEREXE_APATH(SMESH_ROOT_DIR()+PADDEREXE_RPATH); +/*! Absolute path of the exe shell script for tests */ +static std::string PADDEREXE_SCRIPT_FILENAME(PADDEREXE_APATH+"/padder.sh"); + + +static int testssh_using_system() { + const char * cmd = "/usr/bin/ssh claui2p1 -l boulant 'cd /tmp && ./runCommand_padder_Mon_Feb_28_14_28_36_2011.sh'"; + int result = system(cmd); + return result; +} + +#endif // __TESTHELPER_HXX__ diff --git a/src/Tools/padder/resources/Makefile.am b/src/Tools/padder/resources/Makefile.am new file mode 100644 index 000000000..207faadad --- /dev/null +++ b/src/Tools/padder/resources/Makefile.am @@ -0,0 +1,25 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SUBDIRS = appligen padderexe + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +mysalomeresdir=$(salomeresdir) +dist_mysalomeres_DATA = SPADDERCatalog.xml diff --git a/src/Tools/padder/resources/SPADDERCatalog.xml b/src/Tools/padder/resources/SPADDERCatalog.xml new file mode 100644 index 000000000..4e4cafe42 --- /dev/null +++ b/src/Tools/padder/resources/SPADDERCatalog.xml @@ -0,0 +1,16 @@ + + + + + + + + + + MeshJobManager + + + SPADDERPluginTester + + + diff --git a/src/Tools/padder/resources/appligen/CatalogResources.xml b/src/Tools/padder/resources/appligen/CatalogResources.xml new file mode 100644 index 000000000..4900b5fd3 --- /dev/null +++ b/src/Tools/padder/resources/appligen/CatalogResources.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/src/Tools/padder/resources/appligen/Makefile.am b/src/Tools/padder/resources/appligen/Makefile.am new file mode 100644 index 000000000..c22ab6534 --- /dev/null +++ b/src/Tools/padder/resources/appligen/Makefile.am @@ -0,0 +1,40 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +appligendir = $(salomeresdir)/appligen + +dist_appligen_DATA= \ + appli-splashscreen.jpg \ + SalomeApp.xml \ + CatalogResources.xml + +nodist_appligen_DATA= \ + envappli.sh \ + config_appli.xml + +nodist_appligen_SCRIPTS= \ + appligen.sh + +envappli.sh: + $(srcdir)/genenv.sh envappli.sh + +EXTRA_DIST += README.txt genenv.sh +CLEANFILES = envappli.sh diff --git a/src/Tools/padder/resources/appligen/README.txt b/src/Tools/padder/resources/appligen/README.txt new file mode 100644 index 000000000..6fb376cba --- /dev/null +++ b/src/Tools/padder/resources/appligen/README.txt @@ -0,0 +1,24 @@ +This package defines a build procedure that creates a +set of files ready to use to generate a SALOME application +embedding this module. + +The files are created in the directory: + + /share/salome/resources//appligen + +Where is the installation directory of the module. + +To generate a SALOME application, just change directory to go +where you want to install the SALOME application and type the +following command in a standard shell (the SALOME environment +is not required, all paths are "hard" coded in the script): + + $ /share/salome/resources//appligen/appligen.sh + +This script generates an application in a directory ./appli. +Then type the following command to run a SALOME application +embedding your module: + + $ ./appli/runAppli -k + + diff --git a/src/Tools/padder/resources/appligen/SalomeApp.xml b/src/Tools/padder/resources/appligen/SalomeApp.xml new file mode 100644 index 000000000..87ca36264 --- /dev/null +++ b/src/Tools/padder/resources/appligen/SalomeApp.xml @@ -0,0 +1,40 @@ + +
                    + + + + + + + + + + + + + + + +
                    +
                    + +
                    +
                    + + + + + + + + + + + + + + + + +
                    +
                    diff --git a/src/Tools/padder/resources/appligen/appli-splashscreen.jpg b/src/Tools/padder/resources/appligen/appli-splashscreen.jpg new file mode 100644 index 000000000..45377b17d Binary files /dev/null and b/src/Tools/padder/resources/appligen/appli-splashscreen.jpg differ diff --git a/src/Tools/padder/resources/appligen/appligen.sh.in b/src/Tools/padder/resources/appligen/appligen.sh.in new file mode 100755 index 000000000..a27a3eb53 --- /dev/null +++ b/src/Tools/padder/resources/appligen/appligen.sh.in @@ -0,0 +1,50 @@ +#!/bin/sh +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# +# This script installs or updates a SALOME application for testing the +# PADDER plugin for SMESH. The application is installed in the +# directory ./appli. The configuration file is supposed to be adapted +# to your own environment (see config_appli.xml). +# +# To run this script, you should have first configure your +# shell with the SALOME environment, i.e. source the files +# prerequis.sh and envSalome.sh (or equivalent) that fit +# your configuration. You can alternatively customize the env.sh file +# to fit your SALOME environment and let the script do the job (see +# source below). +# +# (gboulant - 3/2/2011) +# + +here=$(dirname $0) + +# +# Run the appli_gen.py +# +APPLIDIR="./appli" +@KERNEL_ROOT_DIR@/bin/salome/appli_gen.py --prefix=$APPLIDIR --config=$here/config_appli.xml + +# +# Copy customized configuration files in the application +# +cp $here/SalomeApp.xml $APPLIDIR/. +cp $here/CatalogResources.xml $APPLIDIR/. +cp @prefix@/plugins/envPlugins.sh $APPLIDIR/env.d/. diff --git a/src/Tools/padder/resources/appligen/config_appli.xml.in b/src/Tools/padder/resources/appligen/config_appli.xml.in new file mode 100644 index 000000000..2f77f06a3 --- /dev/null +++ b/src/Tools/padder/resources/appligen/config_appli.xml.in @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/Tools/padder/resources/appligen/genenv.sh b/src/Tools/padder/resources/appligen/genenv.sh new file mode 100755 index 000000000..c4d5dc525 --- /dev/null +++ b/src/Tools/padder/resources/appligen/genenv.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# This script creates a source file that defines a SALOME shell +# environment. We assume here that the SALOME environment has been +# previously set, so that the env command get all environment +# variables required for building and executing SALOME. We talk +# about third party software programs and libraries. The environment +# variables defining SALOME module are exluded (i.e. *_ROOT_DIR) +# because they are automatically set when generating a SALOME application.. +# +# The argument is the filepath to be created. +# + +if [ $# == 1 ]; then + ENVAPPLI_SH=$1 +else + ENVAPPLI_SH=envappli.sh +fi + +function header { + echo "#" + echo "# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + echo "# THIS FILE IS GENERATED from the shell environment used to build the SALOME module." + echo "# IT SHOULD NOT BE EDITED, it is generated for the need of the SALOME application " + echo "# that embeds the module (for test purposes). " + echo "# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + echo "#" +} +header > $ENVAPPLI_SH +env | grep -v -e PWD -e SalomeAppConfig -e _ROOT_DIR | while read f; do + key=$(echo $f | cut -d"=" -f1) + value=$(echo $f | cut -d"=" -f2-) + + # if the key is a path (LD_LIBRARY_PATH, PATH and PYTHONPATH) then + # we must extends the variable. + if [ $key == "LD_LIBRARY_PATH" -o $key == "PATH" -o $key == "PYTHONPATH" ]; then + echo export $key=\"$value:\$$key\" + else + echo export $key=\"$value\" + fi +done >> $ENVAPPLI_SH diff --git a/src/Tools/padder/resources/padderexe/Makefile.am b/src/Tools/padder/resources/padderexe/Makefile.am new file mode 100644 index 000000000..1388ede61 --- /dev/null +++ b/src/Tools/padder/resources/padderexe/Makefile.am @@ -0,0 +1,42 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +mysalomeresdir=$(salomeresdir)/padderexe + +version=med3 +notinstall_version=med2 + +# We install the padder.exe program and the files required for testing +# the execution from within the installation directory +dist_mysalomeres_SCRIPTS = \ + $(version)/padder.exe \ + padder.sh + +nodist_mysalomeres_SCRIPTS = \ + envPadder.sh + +dist_mysalomeres_DATA = \ + $(version)/data.txt \ + $(version)/concrete.med \ + $(version)/ferraill.med + +NOT_USED_FILES = buildparticules.py particules.png +EXTRA_DIST += $(notinstall_version) $(NOT_USED_FILES) diff --git a/src/Tools/padder/resources/padderexe/buildparticules.py b/src/Tools/padder/resources/padderexe/buildparticules.py new file mode 100755 index 000000000..04035f1f1 --- /dev/null +++ b/src/Tools/padder/resources/padderexe/buildparticules.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +import geompy +import salome +salome.salome_init() +theStudy = salome.myStudy +geompy.init_geom(theStudy) + +filename="/home/gboulant/development/projets/salome/SPADDER/spadder/resources/padderexe/REF_spheres.dat.xyz" +file=open(filename,'rb') + +import csv +datalines = csv.reader(file, delimiter=' ') +i=0 +for row in datalines: + x=float(row[0]) + y=float(row[1]) + z=float(row[2]) + rayon=float(row[3])/2. + + centre = geompy.MakeVertex(x, y, z) + particule = geompy.MakeSpherePntR(centre, rayon) + geompy.addToStudy( particule, 'p'+str(i) ) + i+=1 diff --git a/src/Tools/padder/resources/padderexe/envPadder.sh.in b/src/Tools/padder/resources/padderexe/envPadder.sh.in new file mode 100644 index 000000000..90848a915 --- /dev/null +++ b/src/Tools/padder/resources/padderexe/envPadder.sh.in @@ -0,0 +1,27 @@ +#!/bin/sh +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# This script defines the shell extension required for executing the +# padder executable program on the localhost (for test purposes) + +MED_ROOT="@MED3HOME@" +HDF_ROOT="@HDF5HOME@" +CGAL_ROOT="@CGALHOME@" +export LD_LIBRARY_PATH="$MED_ROOT/lib:$HDF_ROOT/lib:$CGAL_ROOT/lib:$LD_LIBRARY_PATH" diff --git a/src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med b/src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med new file mode 100644 index 000000000..0072943fd Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med differ diff --git a/src/Tools/padder/resources/padderexe/med2/REF_spheres.dat.xyz b/src/Tools/padder/resources/padderexe/med2/REF_spheres.dat.xyz new file mode 100644 index 000000000..d511c3821 --- /dev/null +++ b/src/Tools/padder/resources/padderexe/med2/REF_spheres.dat.xyz @@ -0,0 +1,4097 @@ +0.00782971 0.00837862 0.188345 0.00802045 1 0 +0.0154087 0.00912149 0.0068625 0.00705037 1 0 +0.00853443 0.191571 0.191485 0.00877202 1 0 +0.00831246 0.192152 0.00532739 0.00567024 1 0 +0.392373 0.0103119 0.19108 0.00782777 1 0 +0.382012 0.00642122 0.00627707 0.00662885 1 0 +0.393074 0.19203 0.194472 0.00590232 1 0 +0.387096 0.187644 0.0151337 0.0125061 1 0 +0.0107355 0.00843302 0.0669608 0.00880526 1 0 +0.0130229 0.0100937 0.135407 0.0113355 1 0 +0.0066941 0.0661207 0.191646 0.00802792 1 0 +0.0103253 0.133553 0.192494 0.00822172 1 0 +0.0101874 0.193228 0.0665758 0.00716313 1 0 +0.0128864 0.189676 0.134999 0.0115899 1 0 +0.00969349 0.0657247 0.00859538 0.00955034 1 0 +0.00859049 0.132642 0.00899122 0.00969975 1 0 +0.385203 0.00809838 0.0668407 0.00880575 1 0 +0.386131 0.0107039 0.135508 0.0115306 1 0 +0.393588 0.0665381 0.191132 0.00775488 1 0 +0.386598 0.134808 0.191052 0.0102175 1 0 +0.389949 0.190842 0.0653571 0.00998665 1 0 +0.389353 0.192011 0.133631 0.00881068 1 0 +0.392783 0.067271 0.00660849 0.00698802 1 0 +0.388304 0.134196 0.0104575 0.0117876 1 0 +0.078446 0.0111886 0.00562685 0.00698503 1 0 +0.15933 0.010178 0.0071953 0.00782222 1 0 +0.239408 0.0117814 0.00838242 0.00902724 1 0 +0.319266 0.0104094 0.0109799 0.0115214 1 0 +0.0801022 0.00839366 0.191955 0.009342 1 0 +0.158855 0.0101758 0.190771 0.00985613 1 0 +0.240059 0.008372 0.19268 0.00811281 1 0 +0.319477 0.00952385 0.189827 0.0109663 1 0 +0.080239 0.184554 0.0107232 0.0118692 1 0 +0.158896 0.189543 0.0104515 0.0111914 1 0 +0.239206 0.192295 0.0114336 0.00824166 1 0 +0.321165 0.189065 0.0198378 0.011684 1 0 +0.0784293 0.189358 0.189415 0.0114984 1 0 +0.158102 0.183775 0.186583 0.0140474 1 0 +0.240505 0.191585 0.192095 0.00878636 1 0 +0.320737 0.187137 0.173616 0.0136636 1 0 +0.0102439 0.0601788 0.110611 0.011165 1 0 +0.00632993 0.0606389 0.0501703 0.00699327 1 0 +0.00886816 0.118481 0.073089 0.00961398 1 0 +0.0084637 0.130613 0.129338 0.0092135 1 0 +0.390636 0.0614183 0.111012 0.010272 1 0 +0.391413 0.0615332 0.0505572 0.0092585 1 0 +0.392479 0.119396 0.0733079 0.00827305 1 0 +0.389389 0.131268 0.129331 0.0113393 1 0 +0.274388 0.0076649 0.0575634 0.00842627 1 0 +0.134941 0.00959236 0.0653354 0.0105187 1 0 +0.0651853 0.00803465 0.0661969 0.00886309 1 0 +0.110295 0.00934566 0.133492 0.010401 1 0 +0.185332 0.0137269 0.132579 0.0147265 1 0 +0.331786 0.0104332 0.0984378 0.0115849 1 0 +0.207876 0.0106516 0.0633744 0.0116242 1 0 +0.261527 0.00924836 0.126979 0.0103371 1 0 +0.274177 0.19319 0.0574857 0.00758089 1 0 +0.135692 0.189732 0.0648955 0.0112128 1 0 +0.0663 0.187677 0.0661222 0.0131058 1 0 +0.109855 0.18853 0.132715 0.0125194 1 0 +0.185773 0.18914 0.131535 0.0118814 1 0 +0.332133 0.189017 0.0978282 0.0121498 1 0 +0.207852 0.192331 0.0632991 0.00864703 1 0 +0.261572 0.192711 0.126344 0.00840316 1 0 +0.0697814 0.106226 0.00960134 0.0108828 1 0 +0.131623 0.0598217 0.0086532 0.00941678 1 0 +0.266788 0.0652192 0.0102618 0.0112281 1 0 +0.340609 0.0648565 0.00796636 0.00886868 1 0 +0.291252 0.132331 0.011155 0.0121409 1 0 +0.215098 0.131697 0.0133923 0.0143177 1 0 +0.19535 0.0639082 0.0075357 0.00848584 1 0 +0.141228 0.128178 0.0122679 0.0132652 1 0 +0.0684398 0.10719 0.184859 0.0147587 1 0 +0.131467 0.0598993 0.189562 0.0112022 1 0 +0.267697 0.0654378 0.191161 0.00979633 1 0 +0.340927 0.0652784 0.190301 0.0106229 1 0 +0.291838 0.133337 0.1901 0.0109407 1 0 +0.216095 0.132971 0.190766 0.0102258 1 0 +0.194717 0.0641122 0.187867 0.0130967 1 0 +0.141036 0.129092 0.188982 0.0120216 1 0 +0.0669682 0.0665113 0.0941136 0.0147587 1 0 +0.0833322 0.143862 0.12175 0.0147587 1 0 +0.189807 0.104641 0.118969 0.0147587 1 0 +0.344502 0.0601456 0.0998379 0.0141213 1 0 +0.274144 0.081421 0.098988 0.0147587 1 0 +0.329187 0.144678 0.0830052 0.0143816 1 0 +0.243586 0.146288 0.0866495 0.0147193 1 0 +0.132914 0.0731836 0.103217 0.0147587 1 0 +0.0428272 0.119038 0.052029 0.0119519 1 0 +0.261979 0.150932 0.146194 0.0117141 1 0 +0.102115 0.140291 0.0526524 0.0147587 1 0 +0.0340305 0.101951 0.155062 0.0129279 1 0 +0.357144 0.101091 0.153465 0.0134399 1 0 +0.187456 0.162108 0.0494275 0.0113731 1 0 +0.232702 0.0552718 0.0430421 0.0140424 1 0 +0.171625 0.0519527 0.049372 0.0140307 1 0 +0.369195 0.0892426 0.0427442 0.0106064 1 0 +0.282643 0.107185 0.149494 0.0143329 1 0 +0.301665 0.113049 0.0909966 0.0106702 1 0 +0.310165 0.138814 0.141503 0.0130046 1 0 +0.343165 0.122885 0.118235 0.0109302 1 0 +0.315644 0.0912562 0.126227 0.0126514 1 0 +0.324143 0.117021 0.176733 0.0108517 1 0 +0.241903 0.0991953 0.191196 0.00904411 1 0 +0.205529 0.0985492 0.193468 0.00687593 1 0 +0.231275 0.0648555 0.192248 0.00804733 1 0 +0.192501 0.0845542 0.159484 0.0113254 1 0 +0.203006 0.118545 0.159484 0.0112056 1 0 +0.228532 0.0851619 0.159484 0.0128027 1 0 +0.0076378 0.159507 0.0697794 0.00794379 1 0 +0.00797419 0.124577 0.101219 0.00825663 1 0 +0.00724401 0.165552 0.0978756 0.0074128 1 0 +0.0416661 0.137341 0.125342 0.0105815 1 0 +0.0416661 0.131346 0.0975119 0.0124504 1 0 +0.0416661 0.171931 0.0942084 0.0143232 1 0 +0.0327151 0.00826481 0.0665097 0.00864515 1 0 +0.0663095 0.0332556 0.0799531 0.00903774 1 0 +0.0334841 0.0332556 0.0803902 0.0122868 1 0 +0.0573668 0.0559547 0.065866 0.00791185 1 0 +0.0567081 0.0226991 0.0517055 0.00704303 1 0 +0.0238827 0.0226991 0.0521425 0.00900202 1 0 +0.342522 0.0625798 0.149919 0.0125448 1 0 +0.350823 0.0806185 0.126652 0.00858079 1 0 +0.348843 0.0830528 0.176733 0.00764718 1 0 +0.363749 0.071594 0.15777 0.00763325 1 0 +0.357428 0.051121 0.130956 0.008721 1 0 +0.355448 0.0535553 0.181037 0.00667593 1 0 +0.0681372 0.08677 0.147057 0.0141747 1 0 +0.0504993 0.0842312 0.124588 0.00972722 1 0 +0.0516683 0.10449 0.177531 0.00716934 1 0 +0.0399296 0.0726263 0.156605 0.00748802 1 0 +0.0563985 0.0549064 0.12613 0.00891438 1 0 +0.0575674 0.0751651 0.179073 0.00997186 1 0 +0.0329075 0.194096 0.0663952 0.00629114 1 0 +0.054239 0.159519 0.0589108 0.0106545 1 0 +0.0214136 0.159519 0.0593479 0.0115942 1 0 +0.0444173 0.141073 0.0412066 0.00615021 1 0 +0.0558291 0.181554 0.0480883 0.00684724 1 0 +0.0230037 0.181554 0.0485254 0.00865493 1 0 +0.305829 0.166343 0.00930025 0.00968747 1 0 +0.310165 0.138814 0.0415026 0.0115073 1 0 +0.294382 0.156927 0.0589093 0.0106354 1 0 +0.275359 0.151063 0.0174067 0.007417 1 0 +0.289788 0.184588 0.0174067 0.00953043 1 0 +0.00594911 0.0607854 0.0803628 0.0061939 1 0 +0.00479756 0.0897179 0.0617091 0.00502066 1 0 +0.00616272 0.0895967 0.0918222 0.00633686 1 0 +0.0334841 0.0926703 0.0836937 0.0109375 1 0 +0.0334841 0.0638087 0.072279 0.0100164 1 0 +0.0334841 0.0638137 0.10221 0.0086386 1 0 +0.38987 0.00500221 0.0329115 0.0052469 1 0 +0.393944 0.0306307 0.0587043 0.00630491 1 0 +0.381303 0.0482723 0.0447202 0.00584722 1 0 +0.381303 0.0177192 0.0528313 0.0073099 1 0 +0.100494 0.0834848 0.190271 0.00999289 1 0 +0.136589 0.094439 0.188634 0.0116715 1 0 +0.10535 0.11814 0.185976 0.0143114 1 0 +0.137312 0.100876 0.151609 0.013982 1 0 +0.132467 0.0667472 0.151609 0.0122049 1 0 +0.10111 0.0901062 0.151609 0.0133919 1 0 +0.196804 0.00564298 0.0979846 0.00597401 1 0 +0.234676 0.00734643 0.0952439 0.0075486 1 0 +0.223513 0.00751701 0.129666 0.00783969 1 0 +0.267589 0.0407105 0.112875 0.0108776 1 0 +0.241081 0.0407105 0.0814703 0.0138234 1 0 +0.230019 0.0407105 0.115571 0.0123786 1 0 +0.395052 0.090127 0.0918997 0.00512988 1 0 +0.394346 0.124977 0.101082 0.00594888 1 0 +0.394125 0.0960045 0.119809 0.00606523 1 0 +0.372251 0.0954827 0.114386 0.0118067 1 0 +0.372251 0.0894874 0.0865558 0.0106283 1 0 +0.372251 0.0606309 0.105072 0.00706064 1 0 +0.240956 0.194533 0.060616 0.00571904 1 0 +0.225802 0.173144 0.0753011 0.00853777 1 0 +0.258741 0.173144 0.0722814 0.00850498 1 0 +0.251581 0.157732 0.0607315 0.00735967 1 0 +0.233797 0.184588 0.049383 0.00834547 1 0 +0.266736 0.184588 0.0463634 0.00513679 1 0 +0.00936532 0.0328331 0.190733 0.00954134 1 0 +0.03956 0.0329435 0.190241 0.00993531 1 0 +0.0229144 0.0549841 0.179073 0.00828957 1 0 +0.223628 0.194435 0.129147 0.00587496 1 0 +0.25231 0.173144 0.106706 0.00865879 1 0 +0.214741 0.173144 0.109401 0.011377 1 0 +0.230868 0.156087 0.11999 0.00925117 1 0 +0.239592 0.182943 0.140046 0.00761219 1 0 +0.202023 0.182943 0.142742 0.00643796 1 0 +0.360114 0.190042 0.16695 0.0101415 1 0 +0.324593 0.172339 0.141503 0.0102159 1 0 +0.364593 0.172339 0.108169 0.0128744 1 0 +0.344574 0.149581 0.121034 0.010329 1 0 +0.37998 0.177242 0.146199 0.00823187 1 0 +0.0750501 0.153331 0.00691301 0.00725809 1 0 +0.0857105 0.12366 0.0263262 0.00879905 1 0 +0.0740611 0.1517 0.0415182 0.00806666 1 0 +0.0576568 0.135069 0.0151921 0.008488 1 0 +0.0630037 0.181554 0.0151921 0.00733111 1 0 +0.100334 0.00507726 0.0657085 0.00540601 1 0 +0.101348 0.0332556 0.0799218 0.0124732 1 0 +0.0888629 0.0482426 0.0678241 0.00969621 1 0 +0.0882042 0.0149869 0.0536635 0.00741779 1 0 +0.123242 0.0149869 0.0536322 0.00573819 1 0 +0.366088 0.00696468 0.116037 0.00721858 1 0 +0.366109 0.00552948 0.0824399 0.00579393 1 0 +0.338439 0.0300728 0.0991444 0.00767144 1 0 +0.372251 0.0300728 0.116586 0.0110535 1 0 +0.372251 0.0300728 0.0832523 0.0110382 1 0 +0.203006 0.118545 0.0594845 0.0120352 1 0 +0.211255 0.0799562 0.0810055 0.0125263 1 0 +0.224453 0.0938606 0.021521 0.0112369 1 0 +0.202163 0.0536123 0.046207 0.00768668 1 0 +0.180716 0.0782967 0.0841705 0.0111456 1 0 +0.193914 0.0922011 0.024686 0.0130531 1 0 +0.394528 0.0305532 0.122124 0.00575726 1 0 +0.385177 0.0516063 0.13619 0.00782689 1 0 +0.385177 0.0210482 0.147704 0.0073708 1 0 +0.0751502 0.105187 0.107932 0.0104693 1 0 +0.0763192 0.125446 0.160875 0.010952 1 0 +0.108123 0.108523 0.112484 0.0110378 1 0 +0.0999413 0.0698475 0.0986656 0.00836315 1 0 +0.165758 0.116605 0.159484 0.0121527 1 0 +0.160914 0.0824757 0.159484 0.013619 1 0 +0.161361 0.0889121 0.111093 0.00836142 1 0 +0.294009 0.0323892 0.189614 0.01061 1 0 +0.304296 0.0653391 0.191657 0.00865693 1 0 +0.330471 0.0324018 0.19251 0.00785154 1 0 +0.302412 0.0509357 0.177837 0.0115737 1 0 +0.26577 0.0512702 0.177837 0.00661967 1 0 +0.187851 0.15232 0.125561 0.0120432 1 0 +0.216697 0.125464 0.102809 0.00941345 1 0 +0.215521 0.154198 0.0680385 0.00864791 1 0 +0.188632 0.133375 0.0841982 0.0112806 1 0 +0.186676 0.181054 0.0907904 0.0113755 1 0 +0.257158 0.00634884 0.0286278 0.00661142 1 0 +0.24115 0.00797505 0.0605706 0.00822542 1 0 +0.223999 0.00751144 0.0314485 0.00773857 1 0 +0.22036 0.0276359 0.0534973 0.00800536 1 0 +0.253299 0.0276359 0.0504777 0.00881505 1 0 +0.0994942 0.063411 0.0470568 0.014322 1 0 +0.132467 0.0667472 0.0516087 0.0130026 1 0 +0.121836 0.0515788 0.072376 0.00981294 1 0 +0.121389 0.0451423 0.0207672 0.00695694 1 0 +0.199897 0.192878 0.195143 0.00502548 1 0 +0.213141 0.191335 0.165953 0.0089279 1 0 +0.17265 0.189447 0.165926 0.0108864 1 0 +0.2707 0.0735521 0.049494 0.0125585 1 0 +0.28673 0.0582431 0.0706498 0.00967816 1 0 +0.283286 0.0503742 0.0211558 0.00766029 1 0 +0.266009 0.0451685 0.0426768 0.00870186 1 0 +0.253423 0.0683464 0.071015 0.0092965 1 0 +0.249979 0.0604775 0.021521 0.0070212 1 0 +0.227566 0.166162 0.00927722 0.00964504 1 0 +0.23789 0.150813 0.0174067 0.0083311 1 0 +0.249788 0.184588 0.0174067 0.00630637 1 0 +0.20183 0.147279 0.0247137 0.00805173 1 0 +0.21747 0.0316523 0.190068 0.010193 1 0 +0.229739 0.0506625 0.177837 0.0108254 1 0 +0.186798 0.0522662 0.181595 0.00590615 1 0 +0.231976 0.0930308 0.108978 0.011216 1 0 +0.245174 0.106935 0.049494 0.00991656 1 0 +0.258865 0.113855 0.0928188 0.00909479 1 0 +0.229895 0.139369 0.0433248 0.0114901 1 0 +0.309323 0.0707833 0.099413 0.00918863 1 0 +0.30326 0.0407105 0.0987195 0.0125128 1 0 +0.269214 0.0591391 0.127331 0.00909719 1 0 +0.304393 0.0485014 0.127756 0.0125593 1 0 +0.298329 0.0184286 0.127063 0.0120348 1 0 +0.342522 0.0625798 0.049919 0.0125044 1 0 +0.353554 0.047792 0.069417 0.00851466 1 0 +0.351574 0.0502263 0.019498 0.00671085 1 0 +0.365901 0.0623405 0.0408701 0.00679192 1 0 +0.356848 0.0746941 0.0712911 0.0085842 1 0 +0.354868 0.0771284 0.0213721 0.00710973 1 0 +0.393665 0.0612623 0.0805882 0.00656835 1 0 +0.372251 0.0606259 0.0751412 0.00928767 1 0 +0.00800775 0.00481281 0.0330032 0.00501284 1 0 +0.00493794 0.0302994 0.058471 0.0051964 1 0 +0.0238827 0.0532522 0.0440314 0.0064865 1 0 +0.388819 0.00982632 0.167372 0.0110774 1 0 +0.359782 0.0103331 0.167339 0.0105166 1 0 +0.360202 0.00555297 0.194979 0.00521289 1 0 +0.307343 0.0732175 0.149494 0.0100654 1 0 +0.297242 0.00716979 0.112559 0.0074196 1 0 +0.262658 0.0184286 0.141219 0.00586963 1 0 +0.252783 0.14861 0.116422 0.00781161 1 0 +0.261506 0.175466 0.136478 0.00659803 1 0 +0.240065 0.158409 0.149762 0.00585704 1 0 +0.280059 0.00504557 0.194484 0.00529663 1 0 +0.291028 0.0109082 0.163718 0.0111851 1 0 +0.250706 0.00816308 0.163779 0.0085333 1 0 +0.251026 0.191692 0.163287 0.00868018 1 0 +0.0742247 0.0530447 0.190726 0.00951869 1 0 +0.105992 0.0295004 0.189733 0.0105254 1 0 +0.121557 0.0494515 0.179666 0.00632887 1 0 +0.0902001 0.0728104 0.179666 0.0112387 1 0 +0.0400163 0.189738 0.166964 0.0104471 1 0 +0.0416661 0.171931 0.127542 0.0126428 1 0 +0.0611786 0.149062 0.142927 0.00777122 1 0 +0.0195125 0.177131 0.148718 0.00844259 1 0 +0.280463 0.194149 0.194111 0.00609663 1 0 +0.30581 0.166488 0.193747 0.00663919 1 0 +0.265709 0.166873 0.191652 0.00860795 1 0 +0.276561 0.141941 0.173097 0.00797356 1 0 +0.118638 0.186606 0.187079 0.0130349 1 0 +0.149567 0.165601 0.18603 0.0143514 1 0 +0.110778 0.164928 0.189958 0.0102913 1 0 +0.112521 0.136216 0.160875 0.0123521 1 0 +0.168005 0.0965757 0.192944 0.00723432 1 0 +0.178652 0.13081 0.193931 0.00640298 1 0 +0.332251 0.0300728 0.149919 0.0103012 1 0 +0.325711 0.00860382 0.149657 0.00892666 1 0 +0.0548977 0.0927747 0.0730713 0.00893812 1 0 +0.0214136 0.118934 0.0626514 0.00597593 1 0 +0.0214136 0.0900721 0.0512367 0.00900762 1 0 +0.321909 0.0476054 0.0710748 0.0096664 1 0 +0.319929 0.0500397 0.0211558 0.00827911 1 0 +0.267936 0.00808185 0.0922081 0.00836643 1 0 +0.27402 0.0407105 0.0784506 0.0113994 1 0 +0.370562 0.0994924 0.193807 0.00632978 1 0 +0.378572 0.117212 0.176733 0.00887554 1 0 +0.378572 0.0838791 0.176733 0.00900273 1 0 +0.0170152 0.0815337 0.132684 0.00868612 1 0 +0.0229144 0.0522088 0.134226 0.00857542 1 0 +0.00714838 0.192871 0.0328516 0.00736289 1 0 +0.0329743 0.189293 0.0327432 0.0108652 1 0 +0.0230037 0.181554 0.0151921 0.00829238 1 0 +0.280033 0.194371 0.00546809 0.00575251 1 0 +0.265391 0.166364 0.00786568 0.00811157 1 0 +0.336844 0.102412 0.0914216 0.0109427 1 0 +0.364593 0.137749 0.10597 0.0106918 1 0 +0.378572 0.115956 0.1412 0.00720476 1 0 +0.160389 0.00646817 0.0988948 0.0067168 1 0 +0.17157 0.00638728 0.0645314 0.00668162 1 0 +0.189822 0.0259764 0.0566623 0.00813572 1 0 +0.17876 0.0259764 0.0907627 0.0123462 1 0 +0.153676 0.0259764 0.057551 0.00815413 1 0 +0.147479 0.00853593 0.0323513 0.00887264 1 0 +0.183736 0.00755407 0.0314761 0.0077984 1 0 +0.378572 0.0811038 0.131886 0.00909792 1 0 +0.00591154 0.132048 0.1648 0.00629393 1 0 +0.0195125 0.142541 0.146519 0.0071908 1 0 +0.0195125 0.143797 0.182052 0.00712555 1 0 +0.0365277 0.128106 0.159583 0.00666505 1 0 +0.0170152 0.116386 0.141999 0.00646397 1 0 +0.0170152 0.117642 0.177531 0.00806451 1 0 +0.370844 0.0324118 0.191016 0.00912187 1 0 +0.134768 0.188691 0.166564 0.0115827 1 0 +0.148015 0.19024 0.132253 0.0100692 1 0 +0.134614 0.171931 0.126952 0.0146729 1 0 +0.097124 0.171931 0.127505 0.00794981 1 0 +0.392841 0.0977101 0.0250466 0.00727379 1 0 +0.394032 0.126426 0.0363921 0.00628753 1 0 +0.384597 0.104036 0.058009 0.00656267 1 0 +0.384597 0.0751744 0.0465943 0.00530318 1 0 +0.384597 0.111288 0.0213721 0.00858782 1 0 +0.390129 0.167151 0.0101153 0.0100334 1 0 +0.360693 0.166517 0.0106686 0.0108482 1 0 +0.361679 0.190338 0.013115 0.00979974 1 0 +0.364593 0.139006 0.0415026 0.0137119 1 0 +0.325829 0.188443 0.149303 0.0118787 1 0 +0.366315 0.193143 0.115659 0.00709951 1 0 +0.330781 0.172339 0.0907281 0.00719079 1 0 +0.393701 0.16717 0.194106 0.00622614 1 0 +0.389212 0.189767 0.166773 0.0104671 1 0 +0.37998 0.143909 0.179532 0.00763044 1 0 +0.119432 0.00577778 0.0058474 0.00598998 1 0 +0.107374 0.00697596 0.0325843 0.00717186 1 0 +0.0953788 0.0149869 0.0207672 0.00746824 1 0 +0.392788 0.0332226 0.193286 0.00688538 1 0 +0.385177 0.0543815 0.181037 0.00675563 1 0 +0.13657 0.124252 0.12036 0.0141879 1 0 +0.227045 0.070749 0.137322 0.0133981 1 0 +0.165758 0.116605 0.0594845 0.010786 1 0 +0.137312 0.100876 0.0516087 0.0146835 1 0 +0.117515 0.106738 0.0779349 0.0111866 1 0 +0.145961 0.122466 0.0858107 0.0144476 1 0 +0.121912 0.13443 0.0263262 0.00836417 1 0 +0.303644 0.0655245 0.00637762 0.0067013 1 0 +0.307343 0.0732175 0.049494 0.0112366 1 0 +0.0898928 0.0528545 0.0188092 0.0112597 1 0 +0.100339 0.0835407 0.00719202 0.00745889 1 0 +0.0681372 0.08677 0.0470568 0.0128114 1 0 +0.0845416 0.103401 0.073383 0.011455 1 0 +0.117068 0.100301 0.0263262 0.0125396 1 0 +0.227947 0.166669 0.192156 0.00820954 1 0 +0.239091 0.141691 0.173097 0.00912766 1 0 +0.217177 0.149168 0.176665 0.00718058 1 0 +0.359991 0.00561588 0.00622086 0.00588961 1 0 +0.330111 0.0325816 0.00548694 0.00583707 1 0 +0.370436 0.0326136 0.00785919 0.00799892 1 0 +0.187721 0.166242 0.0085089 0.00875112 1 0 +0.17892 0.13031 0.0061861 0.00650468 1 0 +0.150608 0.164404 0.0088986 0.00927567 1 0 +0.164583 0.145339 0.0247137 0.0094048 1 0 +0.163348 0.0622665 0.195283 0.0049871 1 0 +0.184104 0.0723527 0.14108 0.0098866 1 0 +0.155211 0.0501878 0.181595 0.00782231 1 0 +0.0323044 0.00983341 0.0328972 0.00998101 1 0 +0.286387 0.145483 0.0848274 0.0107116 1 0 +0.295583 0.147805 0.114599 0.0115574 1 0 +0.268062 0.116176 0.122591 0.0106126 1 0 +0.286606 0.0175326 0.0501124 0.00575424 1 0 +0.393607 0.159806 0.0697236 0.00670458 1 0 +0.392433 0.165936 0.0977602 0.00773155 1 0 +0.364593 0.131754 0.0781394 0.00950111 1 0 +0.364593 0.172339 0.0748359 0.0114168 1 0 +0.370471 0.0987242 0.00887783 0.00900479 1 0 +0.334864 0.104846 0.0415026 0.0144509 1 0 +0.349191 0.11696 0.0628747 0.00991734 1 0 +0.391274 0.191165 0.0995132 0.00895533 1 0 +0.394266 0.165746 0.131262 0.0061074 1 0 +0.212893 0.00607632 0.166473 0.00634648 1 0 +0.225089 0.0184286 0.143914 0.0112197 1 0 +0.0100767 0.166711 0.0104198 0.0102409 1 0 +0.0401862 0.166512 0.0109898 0.0111838 1 0 +0.0402255 0.193994 0.00591644 0.00621158 1 0 +0.0230037 0.148221 0.0151921 0.00783265 1 0 +0.381303 0.0510526 0.019498 0.00780039 1 0 +0.384597 0.0779546 0.0213721 0.00716514 1 0 +0.00795073 0.100327 0.191944 0.00820322 1 0 +0.00729948 0.0984007 0.164901 0.00747012 1 0 +0.0170152 0.0843089 0.177531 0.00831272 1 0 +0.309658 0.0175326 0.0211558 0.00733963 1 0 +0.144786 0.1512 0.0510399 0.0110181 1 0 +0.0398287 0.0100308 0.167135 0.0102105 1 0 +0.0956244 0.00846175 0.166819 0.00882322 1 0 +0.0553841 0.00785993 0.133774 0.00819954 1 0 +0.0783722 0.0216507 0.145704 0.0102551 1 0 +0.0229144 0.0216507 0.14574 0.00846962 1 0 +0.122004 0.0558879 0.131275 0.00867966 1 0 +0.0125628 0.192161 0.168294 0.00802027 1 0 +0.37998 0.142652 0.143999 0.00692701 1 0 +0.234711 0.192608 0.0948239 0.00758701 1 0 +0.267805 0.192014 0.0920019 0.00827455 1 0 +0.141191 0.0409633 0.0454532 0.00814838 1 0 +0.303395 0.00577704 0.0780608 0.00607367 1 0 +0.315845 0.0175326 0.0703813 0.00924845 1 0 +0.00557333 0.165517 0.131393 0.00595387 1 0 +0.134321 0.0365918 0.0844737 0.0102843 1 0 +0.15227 0.0625682 0.0762948 0.00870398 1 0 +0.00610125 0.1259 0.0362767 0.00640747 1 0 +0.0214136 0.126186 0.0260145 0.00861099 1 0 +0.203979 0.135263 0.13615 0.00946628 1 0 +0.0541656 0.130645 0.182052 0.00832584 1 0 +0.0586813 0.122907 0.138406 0.00909749 1 0 +0.0733752 0.190249 0.0328107 0.0100889 1 0 +0.0838829 0.170146 0.0592225 0.00889822 1 0 +0.253452 0.132342 0.00666335 0.00698182 1 0 +0.267364 0.139619 0.0433248 0.0124672 1 0 +0.122838 0.00676448 0.099532 0.00706562 1 0 +0.088942 0.0332556 0.113687 0.0111015 1 0 +0.121915 0.0365918 0.118239 0.010264 1 0 +0.120406 0.00711212 0.193704 0.00641037 1 0 +0.135269 0.00862405 0.166962 0.00889347 1 0 +0.111005 0.0192961 0.146296 0.00582169 1 0 +0.297338 0.00779496 0.0287033 0.00808652 1 0 +0.325794 0.00845973 0.0487937 0.00864908 1 0 +0.187851 0.0523203 0.125561 0.0131926 1 0 +0.182148 0.0200324 0.147672 0.00640389 1 0 +0.10101 0.193895 0.065773 0.00643011 1 0 +0.0885172 0.194105 0.0997932 0.00613151 1 0 +0.123113 0.194109 0.099166 0.00619423 1 0 +0.0744915 0.171931 0.0937713 0.0101514 1 0 +0.10953 0.171931 0.09374 0.0118815 1 0 +0.13666 0.0941074 0.00611892 0.00642099 1 0 +0.156667 0.0902607 0.024686 0.0119912 1 0 +0.303258 0.19412 0.0778613 0.00617833 1 0 +0.297043 0.193387 0.112406 0.00685793 1 0 +0.29511 0.172339 0.104884 0.0122603 1 0 +0.301542 0.172339 0.0704592 0.00991179 1 0 +0.145949 0.0298672 0.194806 0.00545143 1 0 +0.169201 0.0200324 0.181595 0.00717934 1 0 +0.0346919 0.119789 0.0059911 0.0062676 1 0 +0.0560667 0.113033 0.0260145 0.00745023 1 0 +0.39462 0.0641305 0.0251582 0.00571618 1 0 +0.358552 0.127788 0.156265 0.00671995 1 0 +0.22384 0.19136 0.0315576 0.00886931 1 0 +0.197737 0.181054 0.05669 0.00568653 1 0 +0.31648 0.0993063 0.190149 0.010111 1 0 +0.196881 0.194663 0.0976769 0.00566597 1 0 +0.0927236 0.142077 0.0872012 0.00896175 1 0 +0.325551 0.143717 0.179532 0.0103648 1 0 +0.293068 0.0329148 0.00869786 0.00893395 1 0 +0.145887 0.0300695 0.00590849 0.0061642 1 0 +0.163592 0.0622743 0.00591676 0.00618727 1 0 +0.177744 0.0321437 0.00757873 0.00778291 1 0 +0.18341 0.0582102 0.024686 0.00701536 1 0 +0.151823 0.0561318 0.024686 0.00798044 1 0 +0.148058 0.190384 0.0324284 0.00993649 1 0 +0.171705 0.193063 0.0644836 0.0072308 1 0 +0.183703 0.191741 0.0316221 0.00850022 1 0 +0.161592 0.181054 0.0575787 0.00827033 1 0 +0.0334841 0.0332556 0.113723 0.0127761 1 0 +0.177315 0.0318544 0.193179 0.00702079 1 0 +0.00742114 0.00649798 0.100794 0.00672344 1 0 +0.0327225 0.00713169 0.100056 0.00728828 1 0 +0.00670312 0.0301976 0.122088 0.00698302 1 0 +0.360594 0.166754 0.190849 0.00932946 1 0 +0.360458 0.194671 0.1947 0.00561391 1 0 +0.187984 0.166822 0.189677 0.0105794 1 0 +0.0890311 0.0525517 0.126723 0.0104433 1 0 +0.279526 0.0994358 0.191957 0.00838132 1 0 +0.2707 0.0735521 0.149494 0.0128078 1 0 +0.395059 0.132156 0.164748 0.00532758 1 0 +0.0630797 0.13145 0.0868896 0.010546 1 0 +0.297324 0.192975 0.0285702 0.00731488 1 0 +0.256988 0.193627 0.0285966 0.00663241 1 0 +0.159405 0.0365918 0.117685 0.0118586 1 0 +0.148494 0.0192961 0.145743 0.0110561 1 0 +0.155658 0.0566242 0.133204 0.0102794 1 0 +0.347491 0.0177192 0.0687235 0.00944119 1 0 +0.253944 0.133117 0.19163 0.00868888 1 0 +0.160668 0.192288 0.0983666 0.00794803 1 0 +0.162767 0.15232 0.0923495 0.011823 1 0 +0.118921 0.170146 0.0591912 0.00871951 1 0 +0.393862 0.0306371 0.0888131 0.00630879 1 0 +0.0342825 0.0868882 0.194405 0.00582405 1 0 +0.0724711 0.129665 0.0523407 0.00787313 1 0 +0.0114266 0.193846 0.10058 0.00631329 1 0 +0.00798199 0.0330447 0.00607383 0.00636767 1 0 +0.0238827 0.0560324 0.0188092 0.00805161 1 0 +0.225893 0.127786 0.132581 0.011245 1 0 +0.0878774 0.00698675 0.0995188 0.00723216 1 0 +0.359861 0.0100027 0.0325919 0.0101839 1 0 +0.00634885 0.0635272 0.15549 0.00666141 1 0 +0.198913 0.0523203 0.0914608 0.0110048 1 0 +0.316316 0.0979592 0.0127506 0.0129877 1 0 +0.279109 0.0990261 0.00597457 0.00631869 1 0 +0.282643 0.107185 0.049494 0.0141105 1 0 +0.0948512 0.190047 0.166682 0.0103369 1 0 +0.0557363 0.192315 0.133729 0.0080218 1 0 +0.345858 0.133694 0.191225 0.00911709 1 0 +0.291379 0.188532 0.163401 0.0117574 1 0 +0.147955 0.00690015 0.132871 0.00722402 1 0 +0.392977 0.0637462 0.155599 0.00734253 1 0 +0.205744 0.0981554 0.00574847 0.0060839 1 0 +0.213949 0.0598698 0.021521 0.00722832 1 0 +0.119829 0.194369 0.00555227 0.00581835 1 0 +0.110214 0.164362 0.00948955 0.00975918 1 0 +0.241564 0.0986453 0.00619258 0.0064188 1 0 +0.231155 0.0649184 0.00722361 0.00752111 1 0 +0.072516 0.00571679 0.032973 0.00607668 1 0 +0.0398795 0.0325987 0.0100453 0.0102223 1 0 +0.0749134 0.0529824 0.0074804 0.00770916 1 0 +0.034637 0.0863996 0.00611601 0.00636006 1 0 +0.0585358 0.0762134 0.0188092 0.00941862 1 0 +0.0452963 0.0822181 0.0448237 0.00939987 1 0 +0.0328906 0.192731 0.1 0.0074275 1 0 +0.00681689 0.00655054 0.166864 0.00687372 1 0 +0.00498748 0.0997191 0.00470913 0.00492065 1 0 +0.00722114 0.0969544 0.024775 0.00732295 1 0 +0.0214136 0.0928524 0.0260145 0.0106683 1 0 +0.00611892 0.0301864 0.0885671 0.00629176 1 0 +0.00549623 0.0956741 0.119829 0.00569037 1 0 +0.0334841 0.0986656 0.111524 0.0123951 1 0 +0.0742482 0.153988 0.191585 0.0087894 1 0 +0.346052 0.132703 0.0081435 0.00845818 1 0 +0.172624 0.00676555 0.166485 0.00710748 1 0 +0.105188 0.117628 0.00615975 0.0064399 1 0 +0.10855 0.190097 0.0325934 0.0101185 1 0 +0.168432 0.096057 0.00759595 0.00777318 1 0 +0.10551 0.0300778 0.00791612 0.00819381 1 0 +0.253178 0.0328009 0.00693181 0.00723025 1 0 +0.217325 0.0321298 0.00770683 0.00796454 1 0 +0.199642 0.193449 0.00648802 0.00669564 1 0 +0.19968 0.0060719 0.193867 0.00628404 1 0 +0.245174 0.106935 0.149494 0.0121355 1 0 +0.360308 0.190453 0.0326889 0.00972258 1 0 +0.326158 0.191821 0.0485561 0.00837765 1 0 +0.366278 0.195066 0.0822926 0.0051992 1 0 +0.392933 0.100219 0.00558497 0.00577655 1 0 +0.0342897 0.120289 0.194417 0.00586501 1 0 +0.0109856 0.167283 0.18869 0.0111292 1 0 +0.0394183 0.167057 0.191843 0.00833159 1 0 +0.390892 0.190956 0.0327244 0.0093067 1 0 +0.253763 0.0323933 0.190427 0.00989013 1 0 +0.279981 0.00552827 0.00540814 0.00558839 1 0 +0.390994 0.0986796 0.165026 0.00917001 1 0 +0.199351 0.00925291 0.00631537 0.00641028 1 0 +0.339858 0.0978656 0.116162 0.0143915 1 0 +0.291051 0.0839952 0.134791 0.0143838 1 0 +0.0230061 0.123341 0.115559 0.014715 1 0 +0.0519932 0.0216838 0.0700086 0.0118849 1 0 +0.0659504 0.0385772 0.0588947 0.0126856 1 0 +0.0384246 0.0355656 0.0575836 0.0111628 1 0 +0.0413681 0.0154344 0.0520067 0.00993293 1 0 +0.355919 0.0796688 0.144359 0.00987007 1 0 +0.353269 0.0664527 0.133592 0.00738205 1 0 +0.352004 0.0664607 0.170429 0.0103816 1 0 +0.359379 0.058104 0.157686 0.00654738 1 0 +0.0439492 0.0842267 0.143609 0.0103898 1 0 +0.0555715 0.0700535 0.136294 0.00934517 1 0 +0.0493466 0.0863296 0.163824 0.0106386 1 0 +0.0534492 0.0726907 0.152056 0.00677646 1 0 +0.0386384 0.178144 0.0651692 0.0144339 1 0 +0.0476738 0.170827 0.0475964 0.00663684 1 0 +0.0327376 0.19314 0.0513751 0.00696728 1 0 +0.308907 0.158592 0.0460618 0.0088282 1 0 +0.0166338 0.0802439 0.0709789 0.0135577 1 0 +0.0185188 0.0796215 0.097997 0.0135333 1 0 +0.017346 0.0603505 0.0840744 0.0102698 1 0 +0.385086 0.0340574 0.0498343 0.00972602 1 0 +0.388393 0.106695 0.102392 0.0116154 1 0 +0.38536 0.0845969 0.101285 0.00968738 1 0 +0.387865 0.0846269 0.118425 0.00763409 1 0 +0.387009 0.093955 0.0898924 0.00514799 1 0 +0.241671 0.181504 0.0670229 0.0112165 1 0 +0.226608 0.172233 0.0583028 0.00850386 1 0 +0.255964 0.172978 0.0541895 0.00979963 1 0 +0.249612 0.189723 0.0511142 0.00837173 1 0 +0.022717 0.0142507 0.190427 0.00962286 1 0 +0.0407331 0.0149915 0.192019 0.00699943 1 0 +0.235776 0.18609 0.115207 0.0139961 1 0 +0.248867 0.166126 0.126089 0.0122412 1 0 +0.22212 0.171399 0.131059 0.0115699 1 0 +0.229005 0.186785 0.133425 0.0054521 1 0 +0.0851153 0.146493 0.022762 0.0143185 1 0 +0.0669041 0.130177 0.0330515 0.0122099 1 0 +0.063305 0.151289 0.0168905 0.00877187 1 0 +0.0815405 0.0205122 0.0716063 0.012504 1 0 +0.0780966 0.038364 0.0727091 0.00571037 1 0 +0.0957399 0.0321352 0.0575695 0.010599 1 0 +0.105371 0.0143381 0.0549332 0.0098079 1 0 +0.353367 0.0167339 0.0905831 0.0132159 1 0 +0.385155 0.0166265 0.0999075 0.0139561 1 0 +0.210662 0.0770846 0.015566 0.0112815 1 0 +0.389953 0.0388172 0.108549 0.0102772 1 0 +0.374346 0.0517042 0.120709 0.011067 1 0 +0.370621 0.037495 0.137735 0.0114201 1 0 +0.390558 0.0348163 0.13853 0.00953474 1 0 +0.0614848 0.104058 0.127071 0.013075 1 0 +0.0841309 0.110185 0.141854 0.0146546 1 0 +0.313814 0.0452291 0.190212 0.00980316 1 0 +0.292761 0.0517713 0.19146 0.00875362 1 0 +0.21056 0.154445 0.121274 0.0111641 1 0 +0.206882 0.165797 0.0859801 0.014397 1 0 +0.185081 0.158987 0.101408 0.0131654 1 0 +0.240847 0.0199757 0.0656529 0.0122568 1 0 +0.106587 0.047547 0.0623922 0.00885443 1 0 +0.103367 0.0560932 0.0794102 0.0104592 1 0 +0.116016 0.0593138 0.0591628 0.00656649 1 0 +0.117395 0.0483294 0.048068 0.00910673 1 0 +0.191796 0.19261 0.178099 0.00739796 1 0 +0.190262 0.1898 0.155824 0.010507 1 0 +0.202655 0.189878 0.185887 0.00756968 1 0 +0.284667 0.0527579 0.0492684 0.0124918 1 0 +0.267685 0.0562034 0.0643551 0.0104832 1 0 +0.252363 0.0623362 0.0534503 0.00929825 1 0 +0.217215 0.109656 0.118837 0.0131045 1 0 +0.320736 0.0555155 0.0908827 0.0116948 1 0 +0.292623 0.0664634 0.113613 0.013154 1 0 +0.288493 0.0359165 0.11613 0.0108148 1 0 +0.306189 0.0324051 0.116388 0.00722874 1 0 +0.361999 0.0517455 0.0533655 0.0100488 1 0 +0.35477 0.0616834 0.0642386 0.00636022 1 0 +0.353108 0.0627607 0.0302231 0.00985696 1 0 +0.357697 0.0745456 0.0429063 0.00805419 1 0 +0.388473 0.0786088 0.0762144 0.0115309 1 0 +0.371176 0.0763511 0.0756446 0.00648226 1 0 +0.384953 0.0606811 0.0905716 0.0106986 1 0 +0.0133713 0.0395707 0.0482004 0.0112632 1 0 +0.377054 0.00985857 0.185869 0.00990833 1 0 +0.358234 0.00751157 0.184997 0.00687113 1 0 +0.322977 0.0666139 0.132647 0.0138483 1 0 +0.290648 0.0596014 0.144794 0.0119843 1 0 +0.318269 0.0522183 0.156885 0.0147333 1 0 +0.298642 0.0225801 0.107366 0.00809767 1 0 +0.275372 0.0400522 0.134644 0.0122502 1 0 +0.277295 0.0139269 0.111945 0.0142065 1 0 +0.243332 0.158549 0.107592 0.00849985 1 0 +0.242569 0.143772 0.132518 0.0118557 1 0 +0.250115 0.170904 0.148051 0.0102692 1 0 +0.270953 0.0113225 0.178894 0.0113339 1 0 +0.29312 0.0104373 0.185275 0.010733 1 0 +0.231865 0.191675 0.150453 0.0083346 1 0 +0.0363854 0.187793 0.145368 0.0117962 1 0 +0.037714 0.16799 0.147599 0.00817705 1 0 +0.286593 0.17804 0.189411 0.0105941 1 0 +0.293143 0.15599 0.186423 0.0120585 1 0 +0.264356 0.185135 0.187138 0.0121549 1 0 +0.164858 0.117047 0.185871 0.0144117 1 0 +0.177516 0.0986111 0.17122 0.0123366 1 0 +0.184805 0.120304 0.171268 0.0105479 1 0 +0.311233 0.0306946 0.142974 0.0118427 1 0 +0.304212 0.0102483 0.147532 0.0102694 1 0 +0.318374 0.0131916 0.133019 0.00952195 1 0 +0.0386367 0.0873516 0.0632239 0.0108306 1 0 +0.0346314 0.0785248 0.0759995 0.005206 1 0 +0.0129629 0.103031 0.0634684 0.0107145 1 0 +0.337932 0.040181 0.0586026 0.0119534 1 0 +0.32304 0.0510643 0.0458029 0.0104974 1 0 +0.250929 0.00828934 0.0790767 0.00830518 1 0 +0.279563 0.033216 0.0976184 0.0099148 1 0 +0.259255 0.0237673 0.0795199 0.0110999 1 0 +0.387591 0.0867004 0.191347 0.00868954 1 0 +0.380134 0.100613 0.182544 0.00878057 1 0 +0.363045 0.0756534 0.186215 0.0109639 1 0 +0.391256 0.0917194 0.178525 0.00601633 1 0 +0.0314241 0.0759766 0.119374 0.0117015 1 0 +0.029587 0.0691096 0.140595 0.0106787 1 0 +0.0388408 0.0552642 0.118268 0.0103264 1 0 +0.0157146 0.193858 0.0469593 0.00617142 1 0 +0.277481 0.181533 0.00721478 0.00724873 1 0 +0.271742 0.191377 0.0181054 0.00864813 1 0 +0.357203 0.0992801 0.0980791 0.010705 1 0 +0.346708 0.113725 0.102435 0.00767388 1 0 +0.363235 0.116484 0.111255 0.0112617 1 0 +0.36471 0.092865 0.133798 0.00918174 1 0 +0.179094 0.00946046 0.0850337 0.0094677 1 0 +0.199891 0.0155986 0.0842305 0.0120848 1 0 +0.172 0.021775 0.0668766 0.0128311 1 0 +0.161145 0.0142864 0.0849849 0.00957009 1 0 +0.16531 0.0124429 0.0443094 0.0124479 1 0 +0.0225446 0.0474814 0.0663094 0.0105236 1 0 +0.0363874 0.056185 0.0541821 0.00983428 1 0 +0.365501 0.08116 0.123471 0.00644773 1 0 +0.385763 0.0960578 0.128605 0.00781636 1 0 +0.0139599 0.147592 0.164164 0.0119845 1 0 +0.0193222 0.126877 0.155769 0.0110009 1 0 +0.0212865 0.132071 0.173446 0.00752773 1 0 +0.00730761 0.117082 0.165563 0.00740949 1 0 +0.355834 0.0185177 0.191414 0.00859597 1 0 +0.348607 0.0383027 0.189035 0.0111529 1 0 +0.132639 0.191841 0.11779 0.00827679 1 0 +0.131246 0.18865 0.14727 0.0116651 1 0 +0.116957 0.175433 0.141497 0.00846987 1 0 +0.393127 0.106986 0.048055 0.0069068 1 0 +0.386686 0.0899624 0.0516342 0.00902786 1 0 +0.394727 0.112683 0.030698 0.00538644 1 0 +0.387084 0.104472 0.0346597 0.00655158 1 0 +0.345148 0.184789 0.0466062 0.0120454 1 0 +0.356736 0.19091 0.0990343 0.0093597 1 0 +0.127682 0.00939457 0.0200367 0.00940051 1 0 +0.132097 0.0106245 0.0400132 0.0108593 1 0 +0.114843 0.0126578 0.0419875 0.00632081 1 0 +0.116248 0.014684 0.0122303 0.00542048 1 0 +0.170733 0.133505 0.170743 0.00875461 1 0 +0.218872 0.06169 0.160269 0.0125913 1 0 +0.246232 0.0513181 0.190082 0.0100493 1 0 +0.143967 0.127614 0.0582512 0.0136594 1 0 +0.301316 0.0589064 0.0296002 0.0140002 1 0 +0.305269 0.053935 0.0508793 0.00820659 1 0 +0.306264 0.0475953 0.00980291 0.00981875 1 0 +0.0837573 0.0439635 0.0525451 0.00697184 1 0 +0.0834765 0.0514769 0.0414608 0.00642183 1 0 +0.076722 0.0672725 0.0328524 0.0127936 1 0 +0.0658256 0.110332 0.0584587 0.013466 1 0 +0.0942477 0.102218 0.0133943 0.0136546 1 0 +0.225715 0.148708 0.162646 0.00924061 1 0 +0.221432 0.176832 0.188792 0.00785824 1 0 +0.348751 0.0206444 0.0108774 0.0108922 1 0 +0.354084 0.00754641 0.0149245 0.00773943 1 0 +0.16887 0.150891 0.0104275 0.0104412 1 0 +0.184389 0.138255 0.0194275 0.0122844 1 0 +0.170477 0.0770973 0.185021 0.0141745 1 0 +0.179787 0.0643972 0.161671 0.0126068 1 0 +0.178077 0.0813081 0.167517 0.00536716 1 0 +0.171908 0.0530528 0.187151 0.0100066 1 0 +0.0215599 0.00758453 0.0470124 0.00758974 1 0 +0.295725 0.0372936 0.0668884 0.013429 1 0 +0.257832 0.038671 0.0651608 0.00964449 1 0 +0.375459 0.123248 0.09362 0.0112366 1 0 +0.378156 0.157402 0.0583142 0.0146607 1 0 +0.361717 0.112088 0.0437565 0.0134527 1 0 +0.354214 0.0947525 0.0274061 0.0115302 1 0 +0.343699 0.127706 0.046363 0.0105342 1 0 +0.375771 0.093816 0.0209501 0.0109917 1 0 +0.387431 0.179191 0.116619 0.012603 1 0 +0.38242 0.153218 0.1108 0.0133994 1 0 +0.378499 0.187674 0.094636 0.0118575 1 0 +0.231756 0.00691231 0.151275 0.00691899 1 0 +0.241288 0.00968751 0.13274 0.0100394 1 0 +0.224111 0.0114066 0.159899 0.00626691 1 0 +0.0229603 0.185685 0.00743012 0.00747811 1 0 +0.037411 0.185073 0.00917614 0.00771211 1 0 +0.0152978 0.169501 0.00788204 0.0080064 1 0 +0.365584 0.0584976 0.015229 0.0101092 1 0 +0.377674 0.064919 0.0295789 0.00972316 1 0 +0.371345 0.0763962 0.0124227 0.00890194 1 0 +0.00607016 0.113737 0.183234 0.00610793 1 0 +0.0177482 0.106556 0.166576 0.00753866 1 0 +0.0173924 0.101126 0.188401 0.0116203 1 0 +0.320855 0.0376444 0.0116917 0.00734364 1 0 +0.165208 0.137354 0.0720785 0.0134923 1 0 +0.144079 0.135267 0.0312902 0.014367 1 0 +0.165475 0.13543 0.0466744 0.011986 1 0 +0.0745623 0.00883203 0.149173 0.00893237 1 0 +0.0535073 0.0116626 0.173585 0.00612253 1 0 +0.130865 0.0425638 0.145565 0.0127738 1 0 +0.0174239 0.190396 0.172379 0.00967554 1 0 +0.0419233 0.185353 0.185353 0.0108033 1 0 +0.36587 0.143274 0.129383 0.0133985 1 0 +0.38734 0.15923 0.145213 0.0112514 1 0 +0.250941 0.192171 0.0787188 0.00784625 1 0 +0.240426 0.178773 0.0903638 0.0123165 1 0 +0.26236 0.182441 0.0879309 0.0100541 1 0 +0.115378 0.0852737 0.0465421 0.0127064 1 0 +0.135265 0.0258461 0.0546071 0.0104916 1 0 +0.289878 0.0375387 0.0857934 0.00636108 1 0 +0.294878 0.0501245 0.0832888 0.00741146 1 0 +0.296897 0.0125443 0.0631942 0.0116219 1 0 +0.0319177 0.15258 0.137429 0.0111748 1 0 +0.0461303 0.13768 0.146997 0.011531 1 0 +0.0124959 0.159635 0.144886 0.0107932 1 0 +0.121417 0.0316553 0.0691049 0.0103816 1 0 +0.142505 0.0474971 0.0650048 0.0125079 1 0 +0.136531 0.0567854 0.0846523 0.0100307 1 0 +0.00947917 0.146002 0.0490215 0.00949669 1 0 +0.0189339 0.126393 0.0464796 0.0120048 1 0 +0.0138137 0.140396 0.0740045 0.0136698 1 0 +0.211644 0.133981 0.118885 0.00946723 1 0 +0.203399 0.154344 0.1416 0.0103861 1 0 +0.37496 0.0650114 0.17113 0.0110079 1 0 +0.368208 0.0574165 0.187213 0.00801593 1 0 +0.0599565 0.140497 0.16553 0.0117625 1 0 +0.0649543 0.135088 0.147747 0.00748528 1 0 +0.0507607 0.119256 0.166314 0.0113964 1 0 +0.0611788 0.126711 0.156142 0.00496128 1 0 +0.071849 0.165862 0.0484098 0.00783746 1 0 +0.232227 0.15496 0.0381257 0.0051099 1 0 +0.26539 0.153878 0.0308856 0.00655751 1 0 +0.254226 0.148364 0.010579 0.00954279 1 0 +0.0872335 0.0210381 0.0948407 0.0114235 1 0 +0.105355 0.0511996 0.109046 0.0136553 1 0 +0.116522 0.0454841 0.0897557 0.00935573 1 0 +0.1186 0.0229352 0.0978742 0.0144792 1 0 +0.114751 0.0094733 0.178 0.00947644 1 0 +0.124719 0.0129115 0.190021 0.00698671 1 0 +0.307064 0.0130512 0.042066 0.0118309 1 0 +0.31323 0.00918472 0.0581303 0.00580519 1 0 +0.211591 0.0479259 0.138481 0.0141896 1 0 +0.192181 0.0566818 0.146392 0.00852602 1 0 +0.106678 0.190419 0.0861648 0.00958831 1 0 +0.0908359 0.178847 0.108707 0.0130443 1 0 +0.111001 0.188553 0.106954 0.00940378 1 0 +0.0909946 0.179291 0.086244 0.00942362 1 0 +0.134588 0.0840325 0.0312592 0.0118727 1 0 +0.12406 0.109313 0.00937685 0.00950764 1 0 +0.152886 0.0799858 0.0459999 0.0119702 1 0 +0.162111 0.101123 0.0443798 0.0111489 1 0 +0.367244 0.0678647 0.0600582 0.00817559 1 0 +0.379698 0.0622769 0.0475206 0.00852458 1 0 +0.382411 0.0656188 0.0628647 0.00741194 1 0 +0.00530947 0.148284 0.152208 0.00533782 1 0 +0.288341 0.189851 0.092671 0.0101512 1 0 +0.309853 0.189503 0.10137 0.0106376 1 0 +0.302921 0.179146 0.0872126 0.00822421 1 0 +0.296218 0.186488 0.0765203 0.00637589 1 0 +0.12987 0.0269885 0.191541 0.00851021 1 0 +0.155532 0.0360994 0.188404 0.00782845 1 0 +0.0410591 0.123946 0.0199892 0.0120594 1 0 +0.0498383 0.139312 0.0286472 0.00764205 1 0 +0.031696 0.141924 0.030251 0.01066 1 0 +0.0422405 0.140611 0.0091657 0.00922523 1 0 +0.322469 0.0178805 0.146835 0.00563141 1 0 +0.353699 0.0281999 0.149582 0.011231 1 0 +0.393307 0.0473753 0.0129008 0.0067172 1 0 +0.39101 0.0521887 0.0335625 0.00922384 1 0 +0.387535 0.0310431 0.0114009 0.00871386 1 0 +0.352823 0.136375 0.117279 0.00568851 1 0 +0.371019 0.129497 0.146528 0.00919033 1 0 +0.23975 0.193302 0.0389499 0.00670009 1 0 +0.21322 0.183876 0.0473552 0.012344 1 0 +0.290996 0.0840484 0.162816 0.0136415 1 0 +0.325332 0.0739599 0.153491 0.00837755 1 0 +0.216003 0.193165 0.107949 0.00683835 1 0 +0.208824 0.186868 0.0957084 0.0088923 1 0 +0.0847779 0.120989 0.0918488 0.0140475 1 0 +0.345015 0.130383 0.172191 0.0143434 1 0 +0.312653 0.0320914 0.00504478 0.00513512 1 0 +0.160375 0.0435024 0.012158 0.0121629 1 0 +0.167644 0.0655224 0.0186183 0.0113927 1 0 +0.153084 0.0234026 0.0132979 0.00819621 1 0 +0.165403 0.190889 0.0441825 0.00911561 1 0 +0.180966 0.183623 0.0569599 0.011283 1 0 +0.0703895 0.0374811 0.129595 0.0136996 1 0 +0.0388652 0.0422696 0.134182 0.0102187 1 0 +0.392038 0.0743685 0.0348702 0.00826804 1 0 +0.196846 0.143226 0.0628502 0.0136246 1 0 +0.013777 0.012867 0.0881742 0.0129082 1 0 +0.0326336 0.0202219 0.096746 0.00864434 1 0 +0.0196705 0.0323884 0.0967388 0.00913384 1 0 +0.0212244 0.0499256 0.104219 0.00999515 1 0 +0.0168423 0.0335269 0.131134 0.0113103 1 0 +0.36748 0.185207 0.190326 0.00919273 1 0 +0.352104 0.181131 0.189058 0.00676397 1 0 +0.356398 0.190294 0.182063 0.00553682 1 0 +0.189141 0.142776 0.181993 0.0147268 1 0 +0.209487 0.139272 0.155345 0.0109017 1 0 +0.0562426 0.155027 0.00555774 0.005627 1 0 +0.107317 0.0430345 0.132072 0.0108538 1 0 +0.296461 0.0860378 0.187312 0.0126963 1 0 +0.277728 0.103706 0.177365 0.0141811 1 0 +0.299084 0.0636102 0.162844 0.00833912 1 0 +0.385162 0.120121 0.157934 0.0112558 1 0 +0.37038 0.132965 0.168166 0.0108392 1 0 +0.385632 0.140025 0.158284 0.00865763 1 0 +0.0482981 0.19129 0.0831739 0.00916622 1 0 +0.0612524 0.15544 0.0821634 0.0139729 1 0 +0.0367202 0.15469 0.0757918 0.0113843 1 0 +0.161624 0.0198379 0.103776 0.0100296 1 0 +0.15685 0.0402778 0.0923543 0.0138665 1 0 +0.15098 0.0378477 0.137264 0.00949224 1 0 +0.149986 0.0504614 0.149848 0.0083531 1 0 +0.169736 0.0424577 0.135879 0.00987065 1 0 +0.345062 0.0342228 0.0782216 0.00975469 1 0 +0.33098 0.0194967 0.0588677 0.00986929 1 0 +0.327716 0.0304708 0.0735557 0.00859503 1 0 +0.246079 0.154124 0.191715 0.00829122 1 0 +0.257018 0.141833 0.182154 0.0109571 1 0 +0.0909553 0.0358688 0.131503 0.00701734 1 0 +0.0721281 0.060405 0.134812 0.00987482 1 0 +0.129253 0.179824 0.102862 0.0112379 1 0 +0.164382 0.176216 0.10136 0.0137664 1 0 +0.140089 0.149112 0.0760627 0.0145271 1 0 +0.140634 0.172744 0.0614462 0.013265 1 0 +0.180291 0.151694 0.0809075 0.00911506 1 0 +0.386181 0.0416112 0.0904011 0.00841162 1 0 +0.0516717 0.0525541 0.184848 0.0140982 1 0 +0.0722764 0.0624285 0.179007 0.00948518 1 0 +0.0348474 0.0734227 0.181379 0.0129312 1 0 +0.0506055 0.100507 0.0440875 0.00965794 1 0 +0.0706543 0.0913602 0.0671509 0.00795337 1 0 +0.0816734 0.117759 0.0433435 0.00965938 1 0 +0.0483573 0.188757 0.112117 0.0111442 1 0 +0.00970976 0.0470906 0.0128571 0.00973229 1 0 +0.0123456 0.0550317 0.0325287 0.00990198 1 0 +0.00980577 0.0280851 0.0111555 0.00741917 1 0 +0.2282 0.155122 0.0560451 0.00882879 1 0 +0.213943 0.16944 0.0663647 0.00676659 1 0 +0.232681 0.136413 0.112038 0.0120468 1 0 +0.243686 0.114589 0.120711 0.0138871 1 0 +0.0564921 0.0924674 0.105065 0.0122932 1 0 +0.0498239 0.190957 0.0181107 0.00905355 1 0 +0.238506 0.150955 0.00679354 0.00687541 1 0 +0.106056 0.00804251 0.0861211 0.0080478 1 0 +0.0994817 0.0132035 0.11266 0.0115751 1 0 +0.142361 0.143467 0.102546 0.0126466 1 0 +0.346896 0.0103949 0.0502715 0.0104187 1 0 +0.337578 0.00615697 0.0647539 0.00632648 1 0 +0.365415 0.0149719 0.0720151 0.008988 1 0 +0.0131234 0.045257 0.15088 0.0119557 1 0 +0.0127507 0.0623101 0.141517 0.00750223 1 0 +0.304444 0.185815 0.0513571 0.0136452 1 0 +0.281936 0.176296 0.0604795 0.0124403 1 0 +0.179508 0.0471838 0.102471 0.0118902 1 0 +0.178001 0.0538737 0.0770514 0.0144384 1 0 +0.187521 0.0410831 0.0886018 0.00525026 1 0 +0.174998 0.0847604 0.0147851 0.00955679 1 0 +0.290064 0.084341 0.0344495 0.0142315 1 0 +0.290002 0.0844431 0.0611749 0.0124942 1 0 +0.376134 0.0463674 0.191537 0.00625324 1 0 +0.0513784 0.191572 0.152027 0.00853012 1 0 +0.0678098 0.176773 0.12328 0.0142848 1 0 +0.344998 0.153703 0.184615 0.0120791 1 0 +0.362316 0.140492 0.185516 0.00972086 1 0 +0.18804 0.169771 0.146387 0.0119031 1 0 +0.308172 0.180009 0.1575 0.00797814 1 0 +0.308458 0.182891 0.125762 0.0146732 1 0 +0.323046 0.0647415 0.0612375 0.0101253 1 0 +0.314683 0.0935818 0.0994618 0.0142316 1 0 +0.30898 0.0979252 0.0495522 0.0135253 1 0 +0.347456 0.0862242 0.0563558 0.0124924 1 0 +0.139757 0.0240381 0.124471 0.0124244 1 0 +0.119083 0.0265038 0.135206 0.00967716 1 0 +0.131047 0.00950555 0.13885 0.00995462 1 0 +0.390467 0.0463886 0.154038 0.00872832 1 0 +0.379006 0.0613228 0.150385 0.0104481 1 0 +0.382075 0.0448445 0.00657943 0.00658226 1 0 +0.22257 0.14715 0.140927 0.0101008 1 0 +0.283228 0.192355 0.18211 0.00772919 1 0 +0.251721 0.184881 0.157569 0.00671726 1 0 +0.272656 0.0531788 0.149365 0.0076595 1 0 +0.209222 0.0940953 0.0136833 0.00589358 1 0 +0.199062 0.0655167 0.031442 0.0115316 1 0 +0.193577 0.0745342 0.0173387 0.00608358 1 0 +0.132108 0.179284 0.00894548 0.0089664 1 0 +0.139169 0.152455 0.0124863 0.0115774 1 0 +0.226438 0.0840168 0.00791548 0.00792328 1 0 +0.231146 0.0678308 0.0205716 0.0117466 1 0 +0.242263 0.0852114 0.0147031 0.00970349 1 0 +0.151372 0.0795723 0.192909 0.00712179 1 0 +0.0541621 0.009468 0.0191585 0.00949259 1 0 +0.0663788 0.0137363 0.0309331 0.00688294 1 0 +0.0387704 0.0148417 0.0112337 0.00865432 1 0 +0.353335 0.0998197 0.0757791 0.0119344 1 0 +0.362165 0.119893 0.187596 0.010984 1 0 +0.0728923 0.0772205 0.190884 0.00967805 1 0 +0.288715 0.00701357 0.0926238 0.00701559 1 0 +0.0506495 0.0549668 0.0138225 0.0138284 1 0 +0.0708841 0.0519034 0.0203875 0.00783806 1 0 +0.0365921 0.0763735 0.0199077 0.0125531 1 0 +0.365386 0.0868869 0.0713017 0.00630041 1 0 +0.054346 0.0732162 0.0601268 0.0105279 1 0 +0.05443 0.0886831 0.0309235 0.00844493 1 0 +0.057257 0.0690964 0.0416356 0.00863903 1 0 +0.364393 0.0328048 0.0626499 0.0111804 1 0 +0.262206 0.12561 0.144205 0.0136869 1 0 +0.0690483 0.193069 0.111205 0.00699695 1 0 +0.0517508 0.17195 0.111857 0.00600386 1 0 +0.0317408 0.00808948 0.183343 0.00727501 1 0 +0.0448126 0.132295 0.0726416 0.012636 1 0 +0.0105125 0.0861309 0.00983185 0.0100961 1 0 +0.0124964 0.104975 0.0414812 0.0109114 1 0 +0.00883058 0.0853637 0.0392147 0.00906131 1 0 +0.0142786 0.1082 0.011511 0.0115812 1 0 +0.0377934 0.0960012 0.182614 0.00987213 1 0 +0.0166288 0.068417 0.167964 0.0102407 1 0 +0.306593 0.0605586 0.0743283 0.0106548 1 0 +0.0219073 0.0146401 0.00836378 0.00841415 1 0 +0.00810007 0.0434991 0.0724525 0.00811193 1 0 +0.0221052 0.0452536 0.0887114 0.00622461 1 0 +0.0164182 0.0888751 0.117519 0.0081728 1 0 +0.0358909 0.0913123 0.129594 0.00726122 1 0 +0.0149256 0.101493 0.132387 0.0113841 1 0 +0.0064834 0.0180904 0.106134 0.00649126 1 0 +0.327023 0.0779322 0.11252 0.00959491 1 0 +0.0792518 0.136865 0.0706925 0.0129743 1 0 +0.0720758 0.152592 0.0579455 0.00850425 1 0 +0.0861308 0.159992 0.0801141 0.0114014 1 0 +0.103346 0.171842 0.0714987 0.0112036 1 0 +0.3503 0.125144 0.0244213 0.0125217 1 0 +0.154271 0.00658848 0.154326 0.00659142 1 0 +0.145609 0.0129631 0.162101 0.00672077 1 0 +0.105485 0.124246 0.0203198 0.0118756 1 0 +0.385248 0.0794694 0.158897 0.0105453 1 0 +0.372667 0.0773341 0.146586 0.0071862 1 0 +0.343365 0.0431501 0.146365 0.00722527 1 0 +0.063767 0.142112 0.0487261 0.00773984 1 0 +0.0938688 0.184927 0.0594656 0.00894189 1 0 +0.152705 0.0619648 0.0546286 0.00801086 1 0 +0.39375 0.146995 0.0492081 0.00626239 1 0 +0.383045 0.130686 0.0581556 0.0124989 1 0 +0.167215 0.0563811 0.117252 0.00942078 1 0 +0.171844 0.0640991 0.131713 0.0076115 1 0 +0.152281 0.0794524 0.0082892 0.00831509 1 0 +0.175193 0.0796253 0.0358228 0.0120995 1 0 +0.140635 0.090329 0.0145581 0.00697231 1 0 +0.286716 0.16251 0.0756719 0.00862372 1 0 +0.248275 0.0833534 0.144199 0.0122316 1 0 +0.126338 0.0206836 0.00730592 0.00730955 1 0 +0.0404216 0.100268 0.0163574 0.0119049 1 0 +0.0378094 0.0911662 0.0329799 0.00722532 1 0 +0.235829 0.0443444 0.0110074 0.0110097 1 0 +0.248735 0.0314925 0.0141296 0.00612448 1 0 +0.208742 0.178494 0.0101585 0.0101662 1 0 +0.196251 0.189903 0.0181036 0.0101298 1 0 +0.0887479 0.0103276 0.0365731 0.0103767 1 0 +0.0975155 0.00563253 0.0489598 0.0056578 1 0 +0.0158431 0.106378 0.0939756 0.0136557 1 0 +0.0502105 0.113761 0.109082 0.0102676 1 0 +0.0436462 0.104431 0.0946859 0.00809977 1 0 +0.202061 0.187687 0.0791138 0.00904632 1 0 +0.201503 0.0132524 0.0433349 0.0106019 1 0 +0.191637 0.0115332 0.178539 0.0115424 1 0 +0.204607 0.0138582 0.167907 0.00543025 1 0 +0.194779 0.0189619 0.192232 0.00777998 1 0 +0.168729 0.189848 0.0818483 0.010209 1 0 +0.129854 0.190782 0.0210644 0.00923197 1 0 +0.26258 0.110366 0.161066 0.00904576 1 0 +0.262803 0.106419 0.146864 0.00569588 1 0 +0.36782 0.188057 0.0582292 0.0121309 1 0 +0.363468 0.18552 0.0857521 0.00573485 1 0 +0.355917 0.173687 0.0582736 0.00732894 1 0 +0.14095 0.00809392 0.111729 0.00810161 1 0 +0.139403 0.0520251 0.158761 0.00557152 1 0 +0.391256 0.0859491 0.00909444 0.00878231 1 0 +0.388958 0.10046 0.0129862 0.00578511 1 0 +0.229216 0.108846 0.136684 0.00841708 1 0 +0.252786 0.0911588 0.168619 0.0137994 1 0 +0.0620011 0.109176 0.0885769 0.0118184 1 0 +0.341706 0.111231 0.188779 0.0112243 1 0 +0.035336 0.135001 0.185697 0.0113418 1 0 +0.0334853 0.114705 0.182273 0.00932439 1 0 +0.0245974 0.185509 0.191853 0.00818761 1 0 +0.204741 0.0577915 0.0675464 0.0142103 1 0 +0.206424 0.179996 0.192712 0.00729287 1 0 +0.370418 0.00789946 0.0151283 0.00793645 1 0 +0.297334 0.10541 0.0705256 0.0116052 1 0 +0.289761 0.133647 0.0548894 0.0134367 1 0 +0.26159 0.111988 0.191384 0.00862492 1 0 +0.378576 0.0868718 0.00681008 0.00500929 1 0 +0.0298629 0.0738766 0.05118 0.00925954 1 0 +0.197723 0.039046 0.0100464 0.01024 1 0 +0.273033 0.0212788 0.192444 0.00756068 1 0 +0.271806 0.0218552 0.0091431 0.00915288 1 0 +0.282277 0.0111852 0.0121297 0.00665603 1 0 +0.0912619 0.1637 0.00873324 0.00896896 1 0 +0.187463 0.109838 0.010696 0.0107031 1 0 +0.211959 0.150836 0.0463463 0.0100119 1 0 +0.276616 0.00726373 0.0208333 0.00726634 1 0 +0.269059 0.00801338 0.0365432 0.00799643 1 0 +0.350892 0.112417 0.0889808 0.00647615 1 0 +0.382318 0.104857 0.167515 0.00698831 1 0 +0.391578 0.112555 0.1718 0.00579373 1 0 +0.0383565 0.118252 0.13661 0.0118309 1 0 +0.347168 0.106342 0.0103183 0.0103355 1 0 +0.0531425 0.147131 0.189814 0.0101934 1 0 +0.0600396 0.165464 0.190941 0.00934447 1 0 +0.154216 0.190864 0.116273 0.00922074 1 0 +0.179424 0.193204 0.0949906 0.00683883 1 0 +0.212951 0.124659 0.145298 0.00716684 1 0 +0.204603 0.0185068 0.00721977 0.0072496 1 0 +0.188898 0.0204287 0.0133955 0.00869768 1 0 +0.390733 0.0440608 0.0726776 0.00928055 1 0 +0.375987 0.0444276 0.0718798 0.00765274 1 0 +0.369288 0.114453 0.0681617 0.0110147 1 0 +0.0346381 0.104006 0.194264 0.0058219 1 0 +0.276533 0.149359 0.0667189 0.0102655 1 0 +0.215694 0.192892 0.0133808 0.00725409 1 0 +0.240383 0.0400749 0.0586261 0.00904036 1 0 +0.0898222 0.0384868 0.00728664 0.00748467 1 0 +0.0845856 0.0737115 0.0110843 0.0113386 1 0 +0.315825 0.189883 0.0295578 0.0104679 1 0 +0.37166 0.193887 0.0984797 0.00613497 1 0 +0.0122528 0.0828442 0.152275 0.0115181 1 0 +0.0158326 0.0667114 0.152824 0.00501628 1 0 +0.227332 0.0458339 0.193588 0.00644537 1 0 +0.0277894 0.19127 0.0808528 0.00878933 1 0 +0.392151 0.0865789 0.141861 0.00786235 1 0 +0.168763 0.151455 0.190798 0.0092146 1 0 +0.204381 0.00966975 0.0216306 0.00967165 1 0 +0.0243094 0.150481 0.0968196 0.013393 1 0 +0.0336358 0.0203736 0.0661439 0.00692063 1 0 +0.361559 0.0637907 0.145559 0.00702253 1 0 +0.0619236 0.074084 0.16276 0.00694743 1 0 +0.0382627 0.160366 0.0558773 0.00562937 1 0 +0.0275376 0.0718734 0.0836242 0.00512013 1 0 +0.228784 0.0149795 0.112927 0.0135174 1 0 +0.395161 0.0898583 0.106136 0.00496068 1 0 +0.25985 0.18758 0.0639603 0.00819434 1 0 +0.0299818 0.0347722 0.183721 0.0061519 1 0 +0.21549 0.186948 0.122246 0.00749354 1 0 +0.361217 0.177099 0.150076 0.0109281 1 0 +0.067308 0.149657 0.0302269 0.00524767 1 0 +0.0991941 0.0200913 0.0677805 0.00556428 1 0 +0.367458 0.0270138 0.0999109 0.00656395 1 0 +0.382911 0.0385284 0.126089 0.00554315 1 0 +0.15259 0.102064 0.170509 0.0103504 1 0 +0.204226 0.159285 0.105587 0.00643247 1 0 +0.106211 0.0611613 0.0650592 0.00502375 1 0 +0.200173 0.191619 0.170332 0.00501194 1 0 +0.271079 0.0587953 0.0365451 0.00707767 1 0 +0.311446 0.0565969 0.10969 0.0084572 1 0 +0.375804 0.0736045 0.0865151 0.00564715 1 0 +0.374788 0.00974941 0.169654 0.00494595 1 0 +0.307617 0.0594108 0.141521 0.0052979 1 0 +0.282294 0.0255418 0.127101 0.00550773 1 0 +0.270122 0.0111254 0.154309 0.0114169 1 0 +0.278578 0.161938 0.192902 0.00495567 1 0 +0.185316 0.109793 0.154663 0.00911126 1 0 +0.293049 0.024156 0.145083 0.00759668 1 0 +0.0265287 0.096412 0.0693108 0.00547116 1 0 +0.241683 0.0191683 0.0860944 0.0082177 1 0 +0.368118 0.0918938 0.184249 0.00616362 1 0 +0.0420928 0.0663928 0.129828 0.00604567 1 0 +0.272006 0.172145 0.0138445 0.00574495 1 0 +0.358694 0.104248 0.124013 0.00698951 1 0 +0.172924 0.0295833 0.0470859 0.00846439 1 0 +0.0390121 0.0491533 0.0682909 0.00614668 1 0 +0.375885 0.0784083 0.117374 0.00590407 1 0 +0.129273 0.172145 0.145903 0.00501788 1 0 +0.391118 0.093988 0.0385701 0.00534297 1 0 +0.105125 0.00750422 0.0121776 0.0078184 1 0 +0.245577 0.0643043 0.163627 0.0144505 1 0 +0.133484 0.113119 0.0700113 0.00774841 1 0 +0.292684 0.0677731 0.0443244 0.00523317 1 0 +0.0766266 0.0592614 0.0541753 0.00998487 1 0 +0.0920868 0.096747 0.0403876 0.0139767 1 0 +0.355631 0.0369208 0.00910917 0.00678582 1 0 +0.187383 0.152005 0.00844206 0.00556809 1 0 +0.18167 0.0620785 0.179408 0.00537936 1 0 +0.0159403 0.00601645 0.0343362 0.00609946 1 0 +0.273759 0.040202 0.0598429 0.00721707 1 0 +0.383771 0.152815 0.084718 0.0127205 1 0 +0.365547 0.1106 0.0219998 0.00868864 1 0 +0.382057 0.169898 0.0993032 0.0068623 1 0 +0.381343 0.0643481 0.0134882 0.00679037 1 0 +0.0639149 0.00754483 0.168317 0.00764772 1 0 +0.0255336 0.192066 0.158187 0.00553389 1 0 +0.373082 0.165629 0.128448 0.0101101 1 0 +0.252547 0.191844 0.100086 0.00835748 1 0 +0.0965972 0.0845669 0.0638608 0.0128504 1 0 +0.14744 0.0175978 0.0433787 0.00617132 1 0 +0.284139 0.0201847 0.081076 0.0116354 1 0 +0.0265165 0.16914 0.138529 0.00627887 1 0 +0.137475 0.0306754 0.0699326 0.00572817 1 0 +0.0227494 0.144802 0.0482607 0.00688008 1 0 +0.379247 0.0677962 0.188607 0.00720059 1 0 +0.261495 0.142099 0.0245236 0.00738447 1 0 +0.106169 0.0378184 0.09608 0.00499535 1 0 +0.310725 0.0197461 0.0571708 0.00509167 1 0 +0.19151 0.0413327 0.142497 0.00732389 1 0 +0.139872 0.105686 0.0266184 0.0108939 1 0 +0.373959 0.0564584 0.0614421 0.00513291 1 0 +0.146353 0.0271243 0.18695 0.00509141 1 0 +0.0298808 0.136673 0.014959 0.0056102 1 0 +0.340704 0.0146383 0.141235 0.00932259 1 0 +0.366728 0.120761 0.130942 0.00918468 1 0 +0.221367 0.186752 0.102372 0.00531139 1 0 +0.0996498 0.0980634 0.092229 0.0132821 1 0 +0.170107 0.0277319 0.0112926 0.00509826 1 0 +0.168886 0.177023 0.0442298 0.0074665 1 0 +0.0497445 0.0241692 0.132148 0.0109974 1 0 +0.389449 0.0608805 0.0214952 0.00511992 1 0 +0.188863 0.129071 0.0421877 0.012663 1 0 +0.168 0.0388015 0.189779 0.00500258 1 0 +0.0361613 0.0111184 0.0808431 0.0100163 1 0 +0.0330297 0.027338 0.131563 0.00602515 1 0 +0.380836 0.174758 0.191983 0.00805852 1 0 +0.191985 0.140342 0.160274 0.0073124 1 0 +0.0475619 0.155101 0.0135935 0.00636649 1 0 +0.089078 0.0771357 0.130195 0.0143848 1 0 +0.386624 0.131859 0.169841 0.00552843 1 0 +0.163404 0.0272597 0.139457 0.00697779 1 0 +0.317549 0.0334651 0.0588785 0.00950924 1 0 +0.251437 0.157781 0.182183 0.00593932 1 0 +0.0862738 0.0444398 0.144012 0.00885247 1 0 +0.144082 0.165439 0.105567 0.0095987 1 0 +0.162451 0.163006 0.0706732 0.0123462 1 0 +0.377191 0.0348654 0.0993471 0.00595367 1 0 +0.0292483 0.0558257 0.19181 0.00845751 1 0 +0.0731428 0.104323 0.0409557 0.00643389 1 0 +0.0198718 0.17265 0.11226 0.0139851 1 0 +0.236318 0.163423 0.0677451 0.00765444 1 0 +0.229331 0.119425 0.108368 0.00565285 1 0 +0.0618705 0.108585 0.148216 0.00855224 1 0 +0.0472707 0.190341 0.0339418 0.00579053 1 0 +0.252217 0.157224 0.00623357 0.00624238 1 0 +0.0962091 0.0159385 0.081255 0.00563935 1 0 +0.00817874 0.0253714 0.146558 0.0083663 1 0 +0.291538 0.171609 0.0445923 0.00670552 1 0 +0.192874 0.0346911 0.0760032 0.00985719 1 0 +0.186361 0.103634 0.0473216 0.0134073 1 0 +0.0741433 0.188066 0.14553 0.0114578 1 0 +0.337023 0.158487 0.194499 0.00550687 1 0 +0.314179 0.0840405 0.072824 0.014068 1 0 +0.133116 0.0246177 0.141414 0.00578305 1 0 +0.394011 0.0446063 0.149989 0.00599448 1 0 +0.37493 0.0385825 0.0159213 0.0066536 1 0 +0.22654 0.143138 0.126695 0.00520927 1 0 +0.268222 0.192866 0.175692 0.00715241 1 0 +0.283563 0.0645575 0.16196 0.00723602 1 0 +0.212596 0.0829564 0.0372903 0.0113053 1 0 +0.123976 0.161412 0.0117908 0.00607324 1 0 +0.162715 0.0962505 0.18281 0.00660952 1 0 +0.0501585 0.00739969 0.0403256 0.00761423 1 0 +0.338479 0.102953 0.0632961 0.00772136 1 0 +0.210651 0.0578669 0.112459 0.0136824 1 0 +0.0662949 0.0647975 0.151469 0.0083119 1 0 +0.289129 0.0209543 0.0975938 0.00563666 1 0 +0.031921 0.0468844 0.0111795 0.00631896 1 0 +0.374995 0.0812476 0.0630345 0.00757385 1 0 +0.240684 0.182445 0.153056 0.00545292 1 0 +0.052213 0.0903392 0.0549818 0.00533031 1 0 +0.371036 0.0137309 0.0852819 0.00547397 1 0 +0.286823 0.129083 0.131978 0.0140184 1 0 +0.063446 0.182761 0.102616 0.0076676 1 0 +0.020394 0.00826111 0.173178 0.00829914 1 0 +0.0312729 0.139892 0.0824798 0.00574432 1 0 +0.00863994 0.083511 0.0249144 0.00519484 1 0 +0.0488243 0.0851716 0.190139 0.00732035 1 0 +0.021921 0.0320327 0.0063651 0.00619372 1 0 +0.0320102 0.0409486 0.0967865 0.0058844 1 0 +0.319167 0.0835592 0.143631 0.00670174 1 0 +0.0782541 0.146147 0.0872911 0.00606958 1 0 +0.225196 0.0554171 0.125535 0.00602916 1 0 +0.128068 0.159785 0.0950072 0.0103182 1 0 +0.335086 0.144369 0.0208107 0.0122591 1 0 +0.309413 0.0449647 0.0811385 0.00659358 1 0 +0.139213 0.00758794 0.153068 0.00558374 1 0 +0.112588 0.0974011 0.00905504 0.00553724 1 0 +0.354749 0.0447492 0.15183 0.00550329 1 0 +0.0586951 0.146078 0.0365589 0.00602574 1 0 +0.250268 0.0762195 0.0341256 0.0131473 1 0 +0.0961069 0.193018 0.0469953 0.00699127 1 0 +0.144597 0.0535251 0.0484729 0.00521266 1 0 +0.383755 0.143112 0.0443475 0.00609051 1 0 +0.177372 0.0558999 0.142282 0.0068624 1 0 +0.149436 0.0717535 0.0217132 0.00809978 1 0 +0.0869359 0.175095 0.0724519 0.00555306 1 0 +0.279529 0.172596 0.089291 0.00978439 1 0 +0.250355 0.0597187 0.137615 0.0123911 1 0 +0.119589 0.0328563 0.0105656 0.00746041 1 0 +0.133067 0.163118 0.0460139 0.006435 1 0 +0.230063 0.025654 0.00788834 0.00633899 1 0 +0.0355784 0.114217 0.101586 0.00617914 1 0 +0.217434 0.184185 0.0825201 0.00708441 1 0 +0.335162 0.0848649 0.0984859 0.0080474 1 0 +0.113069 0.114581 0.144575 0.0147412 1 0 +0.174078 0.166055 0.0859442 0.00708755 1 0 +0.274922 0.125237 0.164978 0.0106713 1 0 +0.346199 0.184401 0.0697786 0.0111541 1 0 +0.142237 0.0228484 0.102594 0.00962491 1 0 +0.14345 0.0678292 0.0349685 0.00696443 1 0 +0.394852 0.0819298 0.0230254 0.00518911 1 0 +0.232323 0.0944074 0.142046 0.0072955 1 0 +0.044562 0.116355 0.0848029 0.00741468 1 0 +0.353889 0.109415 0.17346 0.00846082 1 0 +0.0355702 0.125228 0.171647 0.00577467 1 0 +0.0219492 0.169303 0.194138 0.00592133 1 0 +0.189144 0.0431386 0.0602557 0.00839812 1 0 +0.210267 0.167803 0.187758 0.00653748 1 0 +0.371833 0.0125051 0.0272674 0.00523647 1 0 +0.235904 0.0268693 0.129898 0.00839309 1 0 +0.00800912 0.0936409 0.106956 0.00614546 1 0 +0.152239 0.0664404 0.148093 0.00787896 1 0 +0.0727944 0.116542 0.0759453 0.00635603 1 0 +0.256759 0.110831 0.177046 0.00796748 1 0 +0.0171044 0.142267 0.0374209 0.00560163 1 0 +0.388409 0.15406 0.161688 0.00604898 1 0 +0.212628 0.0445981 0.0184521 0.00840461 1 0 +0.287804 0.0212483 0.00898011 0.00524894 1 0 +0.103648 0.142195 0.00915061 0.00918398 1 0 +0.0249615 0.0944006 0.00999414 0.00581314 1 0 +0.17413 0.101717 0.0223372 0.0090261 1 0 +0.221216 0.134036 0.0650604 0.0125142 1 0 +0.204726 0.070397 0.144764 0.0101323 1 0 +0.283783 0.00667192 0.0360334 0.00686949 1 0 +0.307041 0.163873 0.140303 0.00930808 1 0 +0.372003 0.107226 0.0994053 0.00614495 1 0 +0.0436736 0.10863 0.12283 0.00579659 1 0 +0.34477 0.108323 0.0249005 0.00519196 1 0 +0.0377104 0.15348 0.184693 0.00731607 1 0 +0.121077 0.183774 0.11724 0.0057677 1 0 +0.185975 0.191251 0.0741351 0.00816562 1 0 +0.229029 0.132523 0.15296 0.00991017 1 0 +0.190654 0.0233533 0.00723081 0.00727075 1 0 +0.36508 0.126326 0.0566512 0.0060488 1 0 +0.118158 0.188182 0.158422 0.00502799 1 0 +0.0271665 0.103701 0.1749 0.00535086 1 0 +0.279837 0.149124 0.0515643 0.00524692 1 0 +0.207288 0.192364 0.0321903 0.00772377 1 0 +0.23098 0.0647793 0.0732639 0.0135387 1 0 +0.214176 0.0155511 0.163247 0.00500672 1 0 +0.0209887 0.072175 0.0348169 0.00943272 1 0 +0.0305213 0.134868 0.138194 0.00660834 1 0 +0.0777922 0.0430145 0.0142222 0.0049973 1 0 +0.250382 0.186598 0.0369264 0.00617653 1 0 +0.369015 0.0664313 0.1323 0.00841746 1 0 +0.163825 0.0656479 0.0972373 0.0128942 1 0 +0.0139643 0.101756 0.151244 0.00749925 1 0 +0.105723 0.0334557 0.118016 0.00623026 1 0 +0.0242189 0.0717604 0.155129 0.00504056 1 0 +0.244405 0.0437342 0.178231 0.00539913 1 0 +0.0868532 0.0275435 0.013115 0.00530271 1 0 +0.238417 0.118837 0.138676 0.00530997 1 0 +0.248809 0.0411882 0.0203365 0.00538804 1 0 +0.271743 0.164873 0.0723046 0.00690452 1 0 +0.259549 0.0164941 0.0393869 0.00505907 1 0 +0.0336293 0.184633 0.106557 0.00512952 1 0 +0.0961337 0.069566 0.0259228 0.00794518 1 0 +0.261421 0.0946635 0.0449094 0.0109537 1 0 +0.16721 0.147574 0.178979 0.0079243 1 0 +0.162571 0.0175805 0.15751 0.00737101 1 0 +0.0681521 0.156908 0.15673 0.00858295 1 0 +0.371311 0.188827 0.17645 0.0056506 1 0 +0.382051 0.0326958 0.0660182 0.00679611 1 0 +0.370883 0.097932 0.0722141 0.00607098 1 0 +0.189375 0.0100781 0.0223039 0.00496697 1 0 +0.293977 0.128725 0.155733 0.0107931 1 0 +0.294931 0.106278 0.116439 0.0147434 1 0 +0.319684 0.118009 0.126407 0.0144058 1 0 +0.333114 0.100453 0.142545 0.0129627 1 0 +0.233056 0.0821008 0.185284 0.0135691 1 0 +0.222491 0.107745 0.186574 0.0136897 1 0 +0.205985 0.0856081 0.180974 0.0140664 1 0 +0.209378 0.0980333 0.160304 0.0102888 1 0 +0.0183493 0.171206 0.088728 0.00963997 1 0 +0.0138642 0.130553 0.0946587 0.0092099 1 0 +0.00880729 0.14103 0.109349 0.00910086 1 0 +0.0455904 0.15159 0.109242 0.0112735 1 0 +0.0248175 0.0292809 0.0651985 0.00564902 1 0 +0.051736 0.0417432 0.0745267 0.00867866 1 0 +0.34206 0.0568584 0.130516 0.00768926 1 0 +0.351697 0.0751907 0.157835 0.00494477 1 0 +0.0670896 0.0864491 0.169068 0.00786377 1 0 +0.0512748 0.0963263 0.151133 0.0056313 1 0 +0.0507137 0.0645705 0.163841 0.00779486 1 0 +0.0223355 0.190893 0.0607357 0.00673162 1 0 +0.0467381 0.191243 0.0507055 0.00669401 1 0 +0.299576 0.14876 0.0144156 0.008239 1 0 +0.323826 0.152206 0.0430153 0.00768271 1 0 +0.00617829 0.0719664 0.0851172 0.00587751 1 0 +0.00679986 0.0963776 0.0785689 0.00696181 1 0 +0.0420936 0.072806 0.0881394 0.0101486 1 0 +0.392841 0.0130103 0.0241736 0.00733186 1 0 +0.392432 0.0186516 0.0607261 0.00636687 1 0 +0.374975 0.0243043 0.043706 0.00560077 1 0 +0.0871383 0.0936887 0.187415 0.0112409 1 0 +0.142323 0.107156 0.187424 0.0100812 1 0 +0.145518 0.0811453 0.142775 0.0091413 1 0 +0.215674 0.0140729 0.108765 0.0140781 1 0 +0.222644 0.016739 0.0890476 0.011201 1 0 +0.249043 0.0290925 0.103992 0.0127402 1 0 +0.393134 0.1016 0.0826434 0.00716053 1 0 +0.366581 0.0771724 0.102847 0.0105666 1 0 +0.22542 0.187068 0.0617098 0.00676333 1 0 +0.245887 0.16773 0.0766569 0.00611283 1 0 +0.0157395 0.037729 0.189653 0.0105725 1 0 +0.0536306 0.0208592 0.191866 0.00717096 1 0 +0.214248 0.187878 0.137434 0.00777375 1 0 +0.231408 0.167212 0.109112 0.00631698 1 0 +0.370209 0.186792 0.131924 0.0115277 1 0 +0.348265 0.188219 0.175274 0.00525853 1 0 +0.357703 0.16075 0.122765 0.00699528 1 0 +0.348719 0.169077 0.156321 0.00518334 1 0 +0.0777636 0.163008 0.0142156 0.00567678 1 0 +0.0703331 0.140071 0.0105286 0.00591555 1 0 +0.107597 0.0123506 0.0706847 0.00622383 1 0 +0.0858999 0.00550219 0.062506 0.00576121 1 0 +0.369151 0.00818008 0.0940423 0.00506689 1 0 +0.380448 0.0115654 0.123048 0.0101947 1 0 +0.361218 0.00529068 0.0991335 0.00545717 1 0 +0.21127 0.107896 0.037595 0.0136718 1 0 +0.19285 0.098723 0.0741582 0.0146363 1 0 +0.208754 0.0675954 0.0481468 0.00789315 1 0 +0.190332 0.0714759 0.0516261 0.0112526 1 0 +0.386695 0.0279839 0.124866 0.0057263 1 0 +0.391511 0.0471853 0.123585 0.00691367 1 0 +0.362912 0.0409177 0.12372 0.00493753 1 0 +0.0819763 0.098613 0.165435 0.0117008 1 0 +0.0732932 0.088342 0.117281 0.00888556 1 0 +0.0762444 0.12042 0.121165 0.00973858 1 0 +0.109151 0.0843392 0.112748 0.0131693 1 0 +0.157145 0.101235 0.154726 0.00609758 1 0 +0.156414 0.0947529 0.141875 0.00831439 1 0 +0.141156 0.0819152 0.157509 0.0062447 1 0 +0.311691 0.0225125 0.189756 0.0105256 1 0 +0.277398 0.0425153 0.191083 0.00918601 1 0 +0.31954 0.0655847 0.185438 0.0122109 1 0 +0.199689 0.169705 0.103668 0.00509297 1 0 +0.202364 0.140992 0.101095 0.011787 1 0 +0.222034 0.150856 0.0986253 0.010356 1 0 +0.195383 0.149282 0.0816558 0.00618624 1 0 +0.234882 0.00824154 0.0210247 0.00850376 1 0 +0.227894 0.00967124 0.0485354 0.00981243 1 0 +0.119952 0.0603646 0.0313592 0.0116434 1 0 +0.0929176 0.0649489 0.0678022 0.00749513 1 0 +0.119362 0.0624182 0.0864577 0.00812881 1 0 +0.103313 0.0438392 0.0487169 0.00568792 1 0 +0.189872 0.191278 0.190833 0.00620737 1 0 +0.218556 0.191504 0.183794 0.0088616 1 0 +0.256878 0.0572496 0.0376613 0.00725023 1 0 +0.272126 0.0751648 0.0726282 0.0106756 1 0 +0.251638 0.0481765 0.0465315 0.00647808 1 0 +0.226605 0.183384 0.0126504 0.0076126 1 0 +0.22612 0.155581 0.0104955 0.00612659 1 0 +0.225868 0.00918519 0.182376 0.00962794 1 0 +0.217444 0.0456945 0.187116 0.00535896 1 0 +0.216067 0.126527 0.0469773 0.00773177 1 0 +0.225386 0.109266 0.0975421 0.00970786 1 0 +0.243769 0.106338 0.0993678 0.00899614 1 0 +0.227952 0.126064 0.0859668 0.0108525 1 0 +0.316443 0.042169 0.113368 0.00724812 1 0 +0.326654 0.0517949 0.108777 0.00751662 1 0 +0.301954 0.0583803 0.0999651 0.00524896 1 0 +0.29274 0.0347683 0.132402 0.0060409 1 0 +0.343566 0.0597269 0.018211 0.005781 1 0 +0.352622 0.0502169 0.0402065 0.00618205 1 0 +0.369643 0.0714826 0.0475044 0.00510766 1 0 +0.394229 0.0737736 0.0944807 0.0059695 1 0 +0.394376 0.0620919 0.0670473 0.00591046 1 0 +0.394948 0.0939468 0.076593 0.00516962 1 0 +0.367544 0.0646222 0.0903772 0.00715182 1 0 +0.00818188 0.0126094 0.0228858 0.00838371 1 0 +0.0147844 0.0120618 0.0580327 0.00618432 1 0 +0.31466 0.0730897 0.166658 0.00859344 1 0 +0.319997 0.0525574 0.119828 0.00540728 1 0 +0.300218 0.0662144 0.131142 0.0059512 1 0 +0.282304 0.0498985 0.104559 0.00836055 1 0 +0.251758 0.18354 0.132704 0.00661005 1 0 +0.256939 0.160326 0.111173 0.00568273 1 0 +0.247454 0.15754 0.141038 0.00505592 1 0 +0.236481 0.165237 0.140116 0.00649243 1 0 +0.249384 0.00719792 0.180125 0.00758229 1 0 +0.285711 0.0124466 0.191211 0.0059783 1 0 +0.21456 0.186543 0.153079 0.00793122 1 0 +0.226593 0.180792 0.150642 0.00562627 1 0 +0.083875 0.0293033 0.189486 0.0110144 1 0 +0.0897915 0.0688272 0.191879 0.00823789 1 0 +0.106315 0.053566 0.188127 0.0119741 1 0 +0.111229 0.0439213 0.176073 0.00592557 1 0 +0.0550361 0.190197 0.174822 0.00669825 1 0 +0.0652126 0.164537 0.14202 0.00824646 1 0 +0.267189 0.18792 0.191085 0.00915243 1 0 +0.301131 0.171959 0.186846 0.00580245 1 0 +0.275044 0.14871 0.191894 0.00855422 1 0 +0.0975724 0.182156 0.191598 0.00897754 1 0 +0.117908 0.145176 0.184706 0.0136715 1 0 +0.10357 0.157952 0.149551 0.01374 1 0 +0.202562 0.121477 0.182416 0.0104515 1 0 +0.186167 0.0940157 0.190579 0.00955469 1 0 +0.185097 0.109625 0.185197 0.00700597 1 0 +0.193167 0.106857 0.167044 0.00584006 1 0 +0.325806 0.0498837 0.176862 0.00674515 1 0 +0.327219 0.0434707 0.135695 0.009877 1 0 +0.306853 0.00505278 0.129738 0.00514724 1 0 +0.284301 0.00970246 0.141233 0.00973076 1 0 +0.279911 0.024517 0.14259 0.00577992 1 0 +0.0139161 0.0761074 0.0511881 0.00684258 1 0 +0.0193503 0.0978804 0.0773104 0.00537681 1 0 +0.0312895 0.104381 0.0594031 0.008106 1 0 +0.338556 0.0576895 0.071032 0.00952752 1 0 +0.345385 0.0400912 0.0418604 0.00637311 1 0 +0.259771 0.012368 0.0639415 0.00821059 1 0 +0.234281 0.00979121 0.078925 0.00571495 1 0 +0.261934 0.0151467 0.0961373 0.00781128 1 0 +0.259949 0.0384556 0.0902831 0.00712307 1 0 +0.391538 0.0733979 0.181127 0.00823926 1 0 +0.386642 0.103587 0.194456 0.0057173 1 0 +0.353589 0.0933042 0.189377 0.00930854 1 0 +0.368799 0.0965009 0.17087 0.00800324 1 0 +0.0172555 0.065784 0.127555 0.00757448 1 0 +0.0482225 0.0691234 0.119297 0.00644119 1 0 +0.0294276 0.0847632 0.137985 0.00519188 1 0 +0.0442468 0.0580953 0.140519 0.00765787 1 0 +0.0114241 0.186249 0.0561499 0.0059827 1 0 +0.262791 0.180463 0.0104332 0.00712933 1 0 +0.294967 0.180725 0.00756748 0.00765309 1 0 +0.285215 0.168706 0.0109914 0.00819881 1 0 +0.381007 0.113507 0.121441 0.00943741 1 0 +0.356667 0.0880347 0.110332 0.00593489 1 0 +0.351332 0.127097 0.103414 0.00650858 1 0 +0.361994 0.107448 0.135957 0.00580829 1 0 +0.155172 0.0084073 0.0683292 0.00890522 1 0 +0.188438 0.012146 0.0976326 0.00587874 1 0 +0.188594 0.00995718 0.0690544 0.00765734 1 0 +0.164749 0.0103023 0.0215641 0.0106028 1 0 +0.148297 0.0125693 0.0549953 0.00651599 1 0 +0.181856 0.00865314 0.0566887 0.00648529 1 0 +0.18013 0.0188051 0.0511475 0.00512225 1 0 +0.0135713 0.0284825 0.0616517 0.00617028 1 0 +0.0168143 0.0550432 0.0534702 0.00544081 1 0 +0.0409675 0.0512215 0.0813284 0.00719788 1 0 +0.0315788 0.0446527 0.0458322 0.00519363 1 0 +0.385172 0.0707297 0.121669 0.00688846 1 0 +0.374496 0.103002 0.129779 0.00547061 1 0 +0.36727 0.0697245 0.118015 0.00634524 1 0 +0.00772959 0.129551 0.178176 0.00705005 1 0 +0.00816046 0.138058 0.150509 0.00565004 1 0 +0.0289621 0.137907 0.164141 0.00587197 1 0 +0.0308662 0.118011 0.16402 0.00573116 1 0 +0.369926 0.0178553 0.192356 0.00551679 1 0 +0.340425 0.0223486 0.192848 0.00726053 1 0 +0.11975 0.194485 0.158475 0.00575396 1 0 +0.123894 0.160886 0.143244 0.00774069 1 0 +0.38433 0.118675 0.0362219 0.00799993 1 0 +0.383284 0.102965 0.0460323 0.00553318 1 0 +0.375325 0.156401 0.0123866 0.00920127 1 0 +0.357718 0.185092 0.00968631 0.00792417 1 0 +0.347141 0.186821 0.121368 0.0135055 1 0 +0.326057 0.18231 0.153424 0.00539424 1 0 +0.350309 0.194901 0.11039 0.0056395 1 0 +0.346212 0.166812 0.115758 0.00776566 1 0 +0.386697 0.192126 0.181588 0.00799521 1 0 +0.391156 0.161996 0.18664 0.00904983 1 0 +0.390692 0.174385 0.154308 0.00550439 1 0 +0.0981993 0.0080985 0.00848544 0.00689311 1 0 +0.130053 0.00832591 0.00885153 0.00577159 1 0 +0.394383 0.0239477 0.190847 0.00572692 1 0 +0.134318 0.12667 0.172249 0.0140221 1 0 +0.120571 0.140802 0.136533 0.0136934 1 0 +0.153977 0.137668 0.159255 0.0119829 1 0 +0.238908 0.0637111 0.182828 0.00588483 1 0 +0.217927 0.0660372 0.181256 0.00886203 1 0 +0.213215 0.0882626 0.14329 0.00970245 1 0 +0.23219 0.049967 0.161982 0.00523379 1 0 +0.150521 0.116093 0.0410209 0.0080791 1 0 +0.171537 0.113958 0.0821499 0.0127537 1 0 +0.14791 0.109908 0.0683858 0.00711928 1 0 +0.119181 0.11991 0.0577099 0.0123017 1 0 +0.280074 0.0657231 0.0256561 0.00865399 1 0 +0.315154 0.0634001 0.0129531 0.00810922 1 0 +0.284546 0.0676017 0.0591255 0.00532716 1 0 +0.287665 0.0444101 0.0328449 0.00617395 1 0 +0.103511 0.0542246 0.0293572 0.00602015 1 0 +0.0695044 0.04998 0.0409961 0.00763791 1 0 +0.0777995 0.108209 0.0272184 0.0085827 1 0 +0.105089 0.0831391 0.0281576 0.00846905 1 0 +0.085815 0.0790746 0.0487101 0.00653949 1 0 +0.0968583 0.116976 0.0358279 0.00730169 1 0 +0.23678 0.180027 0.189891 0.00785738 1 0 +0.227769 0.143544 0.185132 0.00749987 1 0 +0.374033 0.01768 0.00744475 0.0059995 1 0 +0.339686 0.00677261 0.00975196 0.00758317 1 0 +0.345282 0.0433209 0.00911013 0.00944693 1 0 +0.172435 0.170777 0.00790899 0.0071469 1 0 +0.164953 0.130355 0.0128714 0.00969678 1 0 +0.158948 0.0614367 0.187529 0.00543337 1 0 +0.189978 0.0716632 0.177366 0.00746771 1 0 +0.178238 0.0797084 0.15281 0.00515117 1 0 +0.165762 0.0528525 0.170612 0.00763925 1 0 +0.0212608 0.0094604 0.0249075 0.00532478 1 0 +0.0403634 0.0072238 0.0517658 0.00747519 1 0 +0.272598 0.106078 0.104539 0.0105631 1 0 +0.287075 0.128572 0.101641 0.0131448 1 0 +0.267112 0.132629 0.0860788 0.01249 1 0 +0.268691 0.137384 0.115787 0.0116689 1 0 +0.27002 0.0257179 0.0636094 0.00820884 1 0 +0.273264 0.0592573 0.0810021 0.00733734 1 0 +0.28318 0.0354773 0.0531312 0.00527753 1 0 +0.389817 0.174931 0.080054 0.0106338 1 0 +0.384445 0.132558 0.0788915 0.00836827 1 0 +0.378701 0.139814 0.0972384 0.00602715 1 0 +0.368813 0.141861 0.0898128 0.00650638 1 0 +0.375492 0.110279 0.0315041 0.00507147 1 0 +0.357443 0.0867631 0.00909228 0.00870971 1 0 +0.375897 0.17125 0.088069 0.00602091 1 0 +0.393984 0.161636 0.116134 0.00619005 1 0 +0.373611 0.161616 0.0966576 0.00525879 1 0 +0.238039 0.00638372 0.171919 0.00666163 1 0 +0.216858 0.00703131 0.152268 0.00513398 1 0 +0.248589 0.00675868 0.148564 0.00687499 1 0 +0.250447 0.0211514 0.146636 0.00776452 1 0 +0.0113154 0.182689 0.00817339 0.00538843 1 0 +0.0238939 0.157768 0.00645951 0.00671657 1 0 +0.0526952 0.185282 0.00720097 0.00766273 1 0 +0.352161 0.0664096 0.0153645 0.00547242 1 0 +0.366475 0.0528956 0.0311387 0.00678152 1 0 +0.365266 0.0710618 0.0239861 0.00520902 1 0 +0.00559995 0.0871335 0.18492 0.00598431 1 0 +0.0112576 0.123259 0.187933 0.00508419 1 0 +0.00679544 0.114603 0.150888 0.00721419 1 0 +0.331843 0.0232473 0.0106033 0.00564219 1 0 +0.332571 0.0501213 0.0120277 0.00731454 1 0 +0.163805 0.12126 0.0301393 0.0098536 1 0 +0.183228 0.124309 0.0663082 0.00949033 1 0 +0.16112 0.149977 0.0571642 0.00646968 1 0 +0.0363436 0.00966209 0.145313 0.0101949 1 0 +0.0688378 0.00717589 0.182349 0.00732408 1 0 +0.0901335 0.00996526 0.15139 0.00727241 1 0 +0.0971279 0.0886962 0.172203 0.0076308 1 0 +0.123389 0.0696746 0.17629 0.0142557 1 0 +0.124882 0.0519842 0.162996 0.00792356 1 0 +0.0127854 0.18895 0.187874 0.0060405 1 0 +0.0175302 0.185317 0.159172 0.0049817 1 0 +0.0525532 0.194899 0.185444 0.00556042 1 0 +0.293887 0.136954 0.174997 0.0101556 1 0 +0.292423 0.15219 0.135484 0.0100152 1 0 +0.282663 0.14629 0.152378 0.0103683 1 0 +0.38584 0.172299 0.134702 0.0055863 1 0 +0.382557 0.152871 0.130059 0.00586379 1 0 +0.357948 0.153628 0.110573 0.00712653 1 0 +0.370099 0.157471 0.142381 0.00630911 1 0 +0.231197 0.192268 0.0787137 0.0079133 1 0 +0.255548 0.165874 0.0866424 0.00790485 1 0 +0.104601 0.0696791 0.0710747 0.0055276 1 0 +0.121347 0.0793999 0.0725771 0.0138937 1 0 +0.107036 0.102437 0.0568728 0.00899351 1 0 +0.283468 0.0231189 0.0642061 0.005501 1 0 +0.302915 0.0162019 0.0810346 0.00755809 1 0 +0.0142963 0.174362 0.133416 0.00796007 1 0 +0.0146243 0.145628 0.132304 0.00815538 1 0 +0.0505912 0.153131 0.131263 0.00849822 1 0 +0.0272526 0.160361 0.151105 0.00523692 1 0 +0.13311 0.0181588 0.0707926 0.00755563 1 0 +0.127461 0.0404578 0.0564505 0.00617569 1 0 +0.151748 0.0383447 0.0530821 0.00513729 1 0 +0.00679267 0.169096 0.0536077 0.00703579 1 0 +0.00651555 0.128824 0.0595809 0.00620981 1 0 +0.199676 0.173535 0.126518 0.0114282 1 0 +0.355852 0.0615542 0.189935 0.00529508 1 0 +0.363794 0.0772269 0.169744 0.00559938 1 0 +0.0653017 0.125566 0.174107 0.00626643 1 0 +0.0706548 0.124027 0.145934 0.00508993 1 0 +0.0437616 0.136513 0.163371 0.00505446 1 0 +0.0403833 0.118787 0.153449 0.00513884 1 0 +0.0668814 0.177731 0.0527361 0.00573733 1 0 +0.0839827 0.158633 0.0492808 0.00631288 1 0 +0.244283 0.130233 0.0206647 0.0134639 1 0 +0.248042 0.142193 0.0542112 0.00985963 1 0 +0.127496 0.0235248 0.0806035 0.00495716 1 0 +0.112549 0.0236483 0.117163 0.00574903 1 0 +0.102698 0.0328561 0.104551 0.00541704 1 0 +0.121179 0.0419633 0.103427 0.00550955 1 0 +0.0949815 0.00750083 0.183421 0.00782525 1 0 +0.134652 0.00614998 0.184862 0.00637881 1 0 +0.116839 0.0088601 0.154427 0.00920183 1 0 +0.31655 0.00700799 0.0248976 0.00751269 1 0 +0.290853 0.00645499 0.0473027 0.00643783 1 0 +0.198169 0.0451707 0.154014 0.00652276 1 0 +0.202753 0.0641795 0.129688 0.00629429 1 0 +0.231726 0.0501635 0.148392 0.00836477 1 0 +0.0806751 0.186693 0.0947945 0.00588621 1 0 +0.0980923 0.193862 0.114456 0.00659301 1 0 +0.0927057 0.166659 0.0945026 0.00576554 1 0 +0.131037 0.0979195 0.0154893 0.00529982 1 0 +0.119759 0.0958302 0.0614018 0.00604038 1 0 +0.117254 0.105551 0.0450691 0.00692544 1 0 +0.180049 0.0968475 0.0963658 0.0110648 1 0 +0.147055 0.0681246 0.0888777 0.00600637 1 0 +0.165325 0.0730319 0.0647813 0.0116055 1 0 +0.356389 0.0605846 0.0771528 0.00670138 1 0 +0.0090253 0.146891 0.178321 0.00943242 1 0 +0.00766876 0.177799 0.147082 0.00803472 1 0 +0.284654 0.182165 0.0777849 0.00603437 1 0 +0.317912 0.188593 0.0821801 0.010196 1 0 +0.31526 0.170622 0.0967369 0.00954165 1 0 +0.157011 0.0204114 0.191012 0.00814343 1 0 +0.0246857 0.126178 0.0110075 0.00674863 1 0 +0.0583965 0.11981 0.0136165 0.00686965 1 0 +0.0423734 0.131397 0.0355498 0.00524297 1 0 +0.359164 0.0155869 0.1297 0.0124649 1 0 +0.346991 0.00989893 0.149958 0.00993081 1 0 +0.335926 0.0173156 0.11971 0.0128885 1 0 +0.351904 0.0330754 0.118387 0.00959278 1 0 +0.394389 0.0194257 0.0160663 0.00555908 1 0 +0.379919 0.129378 0.133306 0.00674795 1 0 +0.343983 0.13786 0.10791 0.00727759 1 0 +0.353387 0.128435 0.141138 0.00927701 1 0 +0.360604 0.139797 0.147167 0.0054718 1 0 +0.210437 0.166175 0.0492754 0.00567761 1 0 +0.333137 0.0762092 0.17059 0.0105529 1 0 +0.304235 0.104976 0.172225 0.0128493 1 0 +0.335688 0.0988857 0.167769 0.0124404 1 0 +0.202789 0.187561 0.113687 0.00783417 1 0 +0.216769 0.19414 0.0854304 0.0061718 1 0 +0.226591 0.167311 0.0969075 0.00680436 1 0 +0.0790982 0.1003 0.091185 0.00741713 1 0 +0.0916304 0.108721 0.10674 0.00642763 1 0 +0.124019 0.099056 0.0987964 0.0119762 1 0 +0.099967 0.113614 0.0782024 0.00766243 1 0 +0.322068 0.132654 0.161504 0.0110719 1 0 +0.328964 0.137853 0.116072 0.00981602 1 0 +0.347629 0.119456 0.153756 0.00724557 1 0 +0.343041 0.14108 0.150765 0.00968606 1 0 +0.308067 0.0305676 0.014255 0.00749486 1 0 +0.288222 0.0486479 0.00726165 0.00755659 1 0 +0.322953 0.0477624 0.00519321 0.00532254 1 0 +0.163145 0.0244185 0.00512858 0.00531505 1 0 +0.143503 0.0521922 0.0141325 0.00602348 1 0 +0.176407 0.0560466 0.00779385 0.00804853 1 0 +0.171945 0.0484305 0.027348 0.00827547 1 0 +0.170499 0.19428 0.0274052 0.00537 1 0 +0.156708 0.193111 0.0620835 0.0071917 1 0 +0.185673 0.194117 0.0511677 0.00612124 1 0 +0.0331075 0.0116814 0.124277 0.0112441 1 0 +0.0663881 0.017704 0.134001 0.00695376 1 0 +0.0509858 0.0401183 0.121398 0.00752897 1 0 +0.0536159 0.0388033 0.139584 0.00586791 1 0 +0.377357 0.0513898 0.0351915 0.00492737 1 0 +0.379201 0.0777361 0.037615 0.00548177 1 0 +0.205056 0.128243 0.0246036 0.0112558 1 0 +0.194766 0.119397 0.0757122 0.00618427 1 0 +0.181175 0.145115 0.0499636 0.00675236 1 0 +0.148696 0.0473235 0.193751 0.00638771 1 0 +0.1805 0.0491506 0.19158 0.00866147 1 0 +0.0218087 0.0143186 0.108466 0.00836723 1 0 +0.0478675 0.0219623 0.0896958 0.00823181 1 0 +0.0512223 0.0421287 0.0966569 0.0133643 1 0 +0.0207695 0.021881 0.119874 0.00535858 1 0 +0.0215509 0.0467649 0.120322 0.00641871 1 0 +0.0360928 0.0484112 0.104878 0.00496479 1 0 +0.0326386 0.0525415 0.145065 0.00598976 1 0 +0.381427 0.190418 0.194281 0.00586092 1 0 +0.373734 0.16649 0.18837 0.00498055 1 0 +0.205452 0.154565 0.177984 0.00579418 1 0 +0.194448 0.131231 0.149231 0.00721404 1 0 +0.0229852 0.137984 0.00566485 0.00616599 1 0 +0.0607551 0.169837 0.00924403 0.00965325 1 0 +0.0609532 0.142705 0.00515321 0.00524266 1 0 +0.0845293 0.0785676 0.161161 0.00895357 1 0 +0.0760292 0.0631132 0.116189 0.00934452 1 0 +0.109096 0.0662653 0.125401 0.0088934 1 0 +0.0992344 0.0589427 0.143979 0.0105978 1 0 +0.273636 0.0785978 0.180015 0.0113957 1 0 +0.31771 0.0863584 0.178826 0.00966627 1 0 +0.29521 0.110289 0.191138 0.00918946 1 0 +0.381769 0.130907 0.179692 0.00549505 1 0 +0.384951 0.132232 0.147066 0.00501827 1 0 +0.368263 0.120297 0.157834 0.00564419 1 0 +0.372344 0.141301 0.154623 0.00518439 1 0 +0.015366 0.18067 0.0718755 0.00991698 1 0 +0.0571934 0.17713 0.0784465 0.00840477 1 0 +0.0608721 0.163181 0.103517 0.00874349 1 0 +0.0402299 0.146705 0.0580912 0.00834893 1 0 +0.254209 0.193453 0.0136025 0.00692331 1 0 +0.293146 0.193828 0.00583723 0.00565197 1 0 +0.273439 0.190697 0.0328814 0.00943147 1 0 +0.148158 0.0224957 0.0751162 0.0086904 1 0 +0.169855 0.0328631 0.104474 0.00539417 1 0 +0.161211 0.0397703 0.0704683 0.00845554 1 0 +0.14024 0.0469873 0.122983 0.010578 1 0 +0.336735 0.0202872 0.0803728 0.00662079 1 0 +0.331173 0.0418264 0.0836408 0.00698085 1 0 +0.248925 0.170773 0.189235 0.0074251 1 0 +0.262339 0.153703 0.191569 0.00510053 1 0 +0.228363 0.152946 0.194167 0.00555304 1 0 +0.253545 0.153824 0.172184 0.00501869 1 0 +0.085673 0.0219495 0.128863 0.00810289 1 0 +0.0787165 0.0476022 0.114194 0.00652346 1 0 +0.0980547 0.0314382 0.144821 0.00871123 1 0 +0.0709612 0.0486933 0.147475 0.00741279 1 0 +0.146003 0.180965 0.107392 0.00615155 1 0 +0.151935 0.175908 0.116585 0.00590186 1 0 +0.131311 0.156841 0.111757 0.006995 1 0 +0.156763 0.164613 0.0522469 0.00700493 1 0 +0.166162 0.131633 0.0940256 0.00920817 1 0 +0.169708 0.159475 0.0531444 0.00695105 1 0 +0.391928 0.014103 0.0938668 0.00815456 1 0 +0.391359 0.0211293 0.117583 0.00530946 1 0 +0.375048 0.0429505 0.106888 0.00530811 1 0 +0.0461391 0.0699646 0.193821 0.00627914 1 0 +0.0622147 0.0345418 0.191454 0.00898645 1 0 +0.0593306 0.0684257 0.192418 0.00508167 1 0 +0.0397629 0.0590945 0.170099 0.00595525 1 0 +0.0661161 0.112209 0.0346864 0.00584907 1 0 +0.0797103 0.0967227 0.0580186 0.00598094 1 0 +0.0568741 0.114675 0.041708 0.00601682 1 0 +0.0822935 0.121589 0.0590197 0.00649001 1 0 +0.0084868 0.184703 0.0965632 0.0086322 1 0 +0.00581197 0.179899 0.124047 0.00594827 1 0 +0.0193344 0.15123 0.117751 0.00813427 1 0 +0.0373418 0.165335 0.111805 0.00496009 1 0 +0.0069464 0.0203693 0.00957193 0.00729029 1 0 +0.0114912 0.0644476 0.0186047 0.00692857 1 0 +0.23016 0.15093 0.070759 0.00659564 1 0 +0.239476 0.169123 0.048159 0.00817471 1 0 +0.216925 0.162977 0.0570597 0.00494897 1 0 +0.256492 0.108796 0.106756 0.00592031 1 0 +0.239834 0.122034 0.101258 0.0072955 1 0 +0.250444 0.134166 0.118395 0.00695265 1 0 +0.0669046 0.0202201 0.0606514 0.00578 1 0 +0.0667976 0.109972 0.163301 0.00737749 1 0 +0.0647391 0.0862293 0.128114 0.00507807 1 0 +0.0730489 0.126344 0.135373 0.0059837 1 0 +0.0487948 0.104113 0.14207 0.00657197 1 0 +0.028089 0.193995 0.0135611 0.00631276 1 0 +0.0674378 0.193956 0.0187955 0.00627478 1 0 +0.0560479 0.192898 0.040999 0.00736616 1 0 +0.262174 0.14737 0.00768132 0.00782649 1 0 +0.110871 0.0181432 0.0802059 0.00539194 1 0 +0.0877005 0.00667963 0.0836161 0.00686255 1 0 +0.104632 0.00847264 0.10825 0.00872388 1 0 +0.0824788 0.0353326 0.0842433 0.00699519 1 0 +0.14732 0.10401 0.105935 0.0128921 1 0 +0.131004 0.0929942 0.120441 0.0115619 1 0 +0.124891 0.124973 0.0770648 0.00850322 1 0 +0.367253 0.00909377 0.0543428 0.00926423 1 0 +0.341448 0.00752611 0.0337154 0.00700713 1 0 +0.353185 0.00671947 0.0658624 0.00679685 1 0 +0.360068 0.0192233 0.0458931 0.00610856 1 0 +0.00526509 0.0409069 0.136276 0.00535184 1 0 +0.00810634 0.0521513 0.169336 0.00845315 1 0 +0.00898223 0.0516547 0.135279 0.00540738 1 0 +0.0272917 0.0344396 0.154164 0.00617013 1 0 +0.28683 0.192156 0.0542309 0.00529478 1 0 +0.306074 0.167622 0.0566469 0.00537123 1 0 +0.19755 0.0334298 0.0932068 0.00801512 1 0 +0.189077 0.0691788 0.103897 0.0121385 1 0 +0.191992 0.113584 0.0278815 0.0086521 1 0 +0.162067 0.106234 0.0287016 0.00534139 1 0 +0.179901 0.11 0.0638109 0.00541145 1 0 +0.17278 0.0881559 0.0541978 0.00830241 1 0 +0.288755 0.0755487 0.0109192 0.0110888 1 0 +0.308569 0.0795913 0.0189497 0.01037 1 0 +0.296556 0.0983438 0.0125803 0.0125357 1 0 +0.383772 0.0259801 0.193385 0.00537695 1 0 +0.386942 0.0526887 0.193606 0.00647137 1 0 +0.365199 0.047121 0.19492 0.0052279 1 0 +0.0519969 0.181546 0.139662 0.00596041 1 0 +0.073405 0.189449 0.169333 0.0107301 1 0 +0.0877081 0.173817 0.141113 0.00870525 1 0 +0.341047 0.169722 0.193253 0.00654535 1 0 +0.330376 0.150117 0.192594 0.00496002 1 0 +0.114133 0.161206 0.130073 0.00865552 1 0 +0.303032 0.188236 0.140302 0.0117671 1 0 +0.315833 0.195507 0.114557 0.00504126 1 0 +0.284501 0.189967 0.127885 0.0104032 1 0 +0.312477 0.161431 0.113936 0.0101568 1 0 +0.327634 0.0793802 0.0481969 0.0100093 1 0 +0.324448 0.0752109 0.0906867 0.0083484 1 0 +0.31356 0.104172 0.0805245 0.00749451 1 0 +0.327746 0.101416 0.0747659 0.00806205 1 0 +0.121771 0.0134248 0.122837 0.00852373 1 0 +0.159631 0.0150029 0.128638 0.00980085 1 0 +0.392511 0.0522317 0.169404 0.00783913 1 0 +0.395162 0.0501463 0.134408 0.00498903 1 0 +0.272107 0.170806 0.116229 0.013434 1 0 +0.281281 0.155885 0.101404 0.0095132 1 0 +0.266574 0.153585 0.107595 0.00660862 1 0 +0.264709 0.153674 0.119585 0.00552586 1 0 +0.38681 0.0562555 0.00638283 0.00528748 1 0 +0.365455 0.0437473 0.0107899 0.00529517 1 0 +0.210022 0.123308 0.12934 0.00556125 1 0 +0.250494 0.193287 0.180336 0.00706519 1 0 +0.258499 0.192009 0.147804 0.00855534 1 0 +0.281498 0.0581577 0.178437 0.0105608 1 0 +0.303242 0.0692587 0.176297 0.00683264 1 0 +0.279185 0.0677835 0.134067 0.00571929 1 0 +0.283695 0.0478234 0.161373 0.00950883 1 0 +0.201343 0.0885042 0.00865546 0.00499766 1 0 +0.217247 0.0657974 0.0338116 0.00681007 1 0 +0.184647 0.0707221 0.0238142 0.00558769 1 0 +0.109721 0.184804 0.00937792 0.00961705 1 0 +0.329991 0.0107204 0.0287114 0.0058961 1 0 +0.324986 0.00709674 0.065553 0.00544047 1 0 +0.320655 0.0241156 0.0465631 0.00626207 1 0 +0.246404 0.0691349 0.00781767 0.00828671 1 0 +0.222941 0.103933 0.0111598 0.011335 1 0 +0.216109 0.0696221 0.00799544 0.00826141 1 0 +0.157528 0.0899447 0.191168 0.00507421 1 0 +0.155537 0.100229 0.191591 0.00540953 1 0 +0.177525 0.0943671 0.150699 0.00861897 1 0 +0.0348592 0.00813347 0.015002 0.00828149 1 0 +0.0512365 0.0192255 0.0153088 0.00517423 1 0 +0.342655 0.0798171 0.0361204 0.00926937 1 0 +0.3391 0.0812289 0.0784261 0.0116296 1 0 +0.338672 0.111785 0.0750774 0.00700406 1 0 +0.330466 0.129438 0.187166 0.00655636 1 0 +0.361513 0.120336 0.171651 0.00498052 1 0 +0.205291 0.0302313 0.114125 0.0145174 1 0 +0.20977 0.0267413 0.0944394 0.00597039 1 0 +0.205971 0.0681862 0.0953955 0.00680038 1 0 +0.233346 0.0592739 0.0989024 0.0127908 1 0 +0.0729556 0.0741033 0.169157 0.00580497 1 0 +0.0687666 0.0753065 0.130455 0.00601045 1 0 +0.0846709 0.0567052 0.156714 0.00887761 1 0 +0.0667951 0.0521266 0.1623 0.00836534 1 0 +0.29608 0.0149178 0.0917873 0.00524784 1 0 +0.283962 0.0466343 0.0910075 0.00567696 1 0 +0.0622957 0.0349496 0.0106501 0.0110784 1 0 +0.0495625 0.0756888 0.00622606 0.00642553 1 0 +0.386469 0.0770333 0.0583167 0.00552774 1 0 +0.387526 0.0946109 0.0661314 0.00621954 1 0 +0.362512 0.0757967 0.0849561 0.00624904 1 0 +0.241755 0.185676 0.178927 0.00544206 1 0 +0.234978 0.173823 0.150145 0.00528781 1 0 +0.0631754 0.100075 0.0342654 0.00630015 1 0 +0.0490861 0.10025 0.0597905 0.00612054 1 0 +0.0448321 0.0676857 0.0483798 0.00556852 1 0 +0.357979 0.0272896 0.0764568 0.00501178 1 0 +0.278958 0.131248 0.150856 0.00519829 1 0 +0.280979 0.110705 0.130202 0.00534803 1 0 +0.302751 0.12933 0.116301 0.00833201 1 0 +0.27393 0.140098 0.141054 0.00521546 1 0 +0.0373405 0.191358 0.126653 0.00727957 1 0 +0.0677841 0.191625 0.0901428 0.00869273 1 0 +0.0844209 0.191969 0.124443 0.00855905 1 0 +0.0775465 0.162201 0.109099 0.0082593 1 0 +0.0207555 0.0053754 0.188771 0.00547368 1 0 +0.0455209 0.00928189 0.181845 0.00561126 1 0 +0.0245158 0.167059 0.0749526 0.00601204 1 0 +0.0568859 0.143012 0.0981434 0.00673649 1 0 +0.0311157 0.142002 0.0668341 0.00512793 1 0 +0.00911201 0.111889 0.0105822 0.00952419 1 0 +0.0289019 0.0987202 0.0405127 0.00667252 1 0 +0.0153248 0.0709797 0.185047 0.00708259 1 0 +0.0468106 0.0975161 0.194603 0.00576613 1 0 +0.0330428 0.088288 0.168913 0.00655303 1 0 +0.0319882 0.0658179 0.164622 0.00569154 1 0 +0.327932 0.0661663 0.0347492 0.00884639 1 0 +0.325235 0.0611186 0.0757851 0.00502571 1 0 +0.301791 0.0719827 0.0647257 0.00502249 1 0 +0.140444 0.0208043 0.00857616 0.00554489 1 0 +0.13206 0.0531746 0.0191259 0.00650001 1 0 +0.0227459 0.0405526 0.0137735 0.00512675 1 0 +0.0139517 0.0311413 0.0791735 0.00739728 1 0 +0.00812655 0.0462816 0.0920372 0.00831147 1 0 +0.0100434 0.0603263 0.0679059 0.00747143 1 0 +0.0330852 0.0595645 0.0875891 0.00587617 1 0 +0.01453 0.0759006 0.120222 0.00521403 1 0 +0.0151535 0.103402 0.114357 0.0067483 1 0 +0.0287214 0.0951057 0.139099 0.00523436 1 0 +0.0133948 0.0273098 0.111089 0.00733124 1 0 +0.00839056 0.0392552 0.105564 0.00674924 1 0 +0.0335484 0.0517292 0.0957753 0.00505228 1 0 +0.321536 0.0865347 0.161924 0.00723207 1 0 +0.336144 0.0797876 0.125265 0.00618701 1 0 +0.306447 0.0747709 0.124501 0.0063047 1 0 +0.338491 0.0802498 0.140048 0.00809261 1 0 +0.0724714 0.172504 0.0723751 0.00867382 1 0 +0.077077 0.155879 0.0945479 0.00612652 1 0 +0.0603146 0.142855 0.064314 0.00788684 1 0 +0.0873398 0.153674 0.0624092 0.00743584 1 0 +0.0837064 0.168728 0.18948 0.00889523 1 0 +0.0796081 0.136161 0.182522 0.013425 1 0 +0.0984236 0.143756 0.174245 0.00848882 1 0 +0.090862 0.139998 0.157997 0.00982194 1 0 +0.120833 0.0169722 0.0755527 0.00566548 1 0 +0.0890771 0.0475762 0.0844198 0.00691428 1 0 +0.111386 0.0351207 0.0575203 0.0053293 1 0 +0.220659 0.0305815 0.129607 0.00729992 1 0 +0.20806 0.0804905 0.123909 0.0118058 1 0 +0.238003 0.061297 0.120152 0.00905688 1 0 +0.233536 0.0524825 0.134068 0.00625855 1 0 +0.246734 0.133539 0.040288 0.00658618 1 0 +0.261156 0.116553 0.0379597 0.0120144 1 0 +0.253954 0.128533 0.0491202 0.00587193 1 0 +0.0659653 0.0123689 0.0890542 0.0122615 1 0 +0.0753169 0.0123982 0.113778 0.0125732 1 0 +0.0701547 0.0311356 0.0969636 0.00853032 1 0 +0.124168 0.167553 0.0768115 0.00984731 1 0 +0.154698 0.126665 0.106738 0.00861596 1 0 +0.114986 0.142254 0.0860121 0.0133329 1 0 +0.346007 0.153192 0.00795461 0.00800824 1 0 +0.318942 0.148861 0.0113152 0.0115475 1 0 +0.318348 0.0348712 0.0863439 0.00785672 1 0 +0.303844 0.0561051 0.0899067 0.0052354 1 0 +0.313022 0.0358319 0.074224 0.00541661 1 0 +0.152268 0.0076484 0.173852 0.00786869 1 0 +0.13011 0.0144056 0.154271 0.00585279 1 0 +0.165082 0.0119672 0.144377 0.00713006 1 0 +0.0871026 0.125344 0.0093217 0.0096307 1 0 +0.122601 0.0934845 0.0107429 0.00534686 1 0 +0.390935 0.0680353 0.16854 0.00545651 1 0 +0.391784 0.0660705 0.137733 0.0081494 1 0 +0.368876 0.0851037 0.157602 0.00681751 1 0 +0.3435 0.0532953 0.184997 0.0059137 1 0 +0.0678451 0.116635 0.0213229 0.00572971 1 0 +0.0831903 0.134643 0.0428236 0.0073013 1 0 +0.315142 0.019002 0.154585 0.00509271 1 0 +0.318834 0.0287574 0.124498 0.0082297 1 0 +0.331325 0.0384706 0.118156 0.00881685 1 0 +0.257485 0.0774816 0.0149607 0.00737033 1 0 +0.243986 0.105343 0.0208968 0.0114293 1 0 +0.250893 0.0810976 0.056506 0.00976706 1 0 +0.241362 0.071397 0.0497077 0.00543699 1 0 +0.0951764 0.190812 0.0352198 0.005069 1 0 +0.105909 0.1918 0.0552695 0.0055431 1 0 +0.0838705 0.19237 0.0559887 0.00778471 1 0 +0.0909871 0.168167 0.046449 0.00585127 1 0 +0.138129 0.0547823 0.0314965 0.00737256 1 0 +0.133008 0.0625234 0.0701167 0.00598886 1 0 +0.131467 0.0487513 0.0499509 0.0050972 1 0 +0.392729 0.17308 0.0543232 0.00762244 1 0 +0.390069 0.140352 0.0309828 0.00894587 1 0 +0.392483 0.144524 0.0675016 0.00668198 1 0 +0.365541 0.139541 0.0628607 0.00767386 1 0 +0.181917 0.072989 0.122854 0.00848093 1 0 +0.151607 0.0618207 0.010758 0.00684657 1 0 +0.170956 0.0743141 0.00515087 0.00535107 1 0 +0.151276 0.100927 0.0089466 0.00913301 1 0 +0.159422 0.0740842 0.0305408 0.00543141 1 0 +0.115667 0.180416 0.0794904 0.0058022 1 0 +0.0994465 0.155809 0.0923839 0.00718233 1 0 +0.0999845 0.154006 0.0694851 0.00705776 1 0 +0.273075 0.179113 0.0764238 0.0060175 1 0 +0.273414 0.182999 0.100381 0.00660443 1 0 +0.294461 0.167567 0.0871492 0.00611654 1 0 +0.267046 0.169424 0.0821706 0.00493232 1 0 +0.263157 0.0743531 0.166745 0.00603747 1 0 +0.236311 0.0883744 0.127816 0.00866709 1 0 +0.262038 0.0760561 0.129225 0.00937597 1 0 +0.260806 0.0583165 0.152129 0.00554879 1 0 +0.127913 0.0401208 0.0105813 0.0108419 1 0 +0.139949 0.188361 0.0447094 0.00963688 1 0 +0.156756 0.175254 0.0466356 0.00502514 1 0 +0.0182403 0.0775134 0.0207589 0.00585374 1 0 +0.049628 0.0861852 0.0125484 0.00534557 1 0 +0.0386586 0.104817 0.0341019 0.00649825 1 0 +0.0504136 0.0672162 0.0286269 0.00617965 1 0 +0.241949 0.0263184 0.0058993 0.00573091 1 0 +0.252068 0.0556234 0.00921361 0.00637274 1 0 +0.22369 0.0526726 0.0183509 0.0052916 1 0 +0.232494 0.0511763 0.0241064 0.00533218 1 0 +0.19112 0.181137 0.00602503 0.00537962 1 0 +0.202486 0.159753 0.0127104 0.00927223 1 0 +0.0752446 0.00953644 0.0199405 0.00785062 1 0 +0.0762035 0.00765303 0.0478329 0.00785765 1 0 +0.0933209 0.00532339 0.0221773 0.00561959 1 0 +0.103481 0.0147954 0.0398048 0.00544491 1 0 +0.0277912 0.120626 0.096511 0.00511143 1 0 +0.0426447 0.126149 0.114312 0.00516252 1 0 +0.196674 0.18675 0.102437 0.0049966 1 0 +0.211756 0.1794 0.0726919 0.00523377 1 0 +0.223498 0.175543 0.0884482 0.00502362 1 0 +0.200843 0.175993 0.0680288 0.00711302 1 0 +0.342708 0.0784478 0.109096 0.0064675 1 0 +0.301046 0.0851749 0.11395 0.00736852 1 0 +0.326322 0.112953 0.104599 0.00894385 1 0 +0.33831 0.112264 0.129564 0.00533993 1 0 +0.146632 0.119854 0.155857 0.00758345 1 0 +0.113839 0.124127 0.123163 0.00871534 1 0 +0.147431 0.104285 0.128928 0.0101026 1 0 +0.130699 0.107509 0.132492 0.00730589 1 0 +0.110278 0.121507 0.179754 0.0116856 1 0 +0.0956274 0.122005 0.158534 0.00879957 1 0 +0.119865 0.0920174 0.138423 0.00961322 1 0 +0.219451 0.0418365 0.0510078 0.00644042 1 0 +0.173338 0.00866538 0.177793 0.00550045 1 0 +0.211117 0.00543773 0.18246 0.00561183 1 0 +0.187216 0.00837054 0.155071 0.00872445 1 0 +0.1664 0.17484 0.0827415 0.00501124 1 0 +0.177999 0.143392 0.0931468 0.00585077 1 0 +0.109717 0.192946 0.0137512 0.00724742 1 0 +0.14143 0.184762 0.0195865 0.00684492 1 0 +0.122259 0.190175 0.0476535 0.0102463 1 0 +0.0667361 0.169401 0.0599992 0.00531496 1 0 +0.082868 0.146826 0.0508342 0.00564837 1 0 +0.0552552 0.154891 0.0433447 0.00561681 1 0 +0.310689 0.151778 0.181469 0.00665367 1 0 +0.330094 0.152012 0.136954 0.0113277 1 0 +0.345349 0.156333 0.145413 0.00664196 1 0 +0.251394 0.126454 0.166924 0.0114056 1 0 +0.267385 0.108622 0.136848 0.00553662 1 0 +0.263938 0.13864 0.160479 0.00723252 1 0 +0.360484 0.188651 0.0759512 0.00497759 1 0 +0.331221 0.188418 0.0363829 0.00560804 1 0 +0.331933 0.192602 0.0717644 0.00779763 1 0 +0.347752 0.165414 0.0682079 0.00796147 1 0 +0.136251 0.00928 0.0920064 0.00859638 1 0 +0.129956 0.0161276 0.112292 0.00509584 1 0 +0.152579 0.0159942 0.115424 0.00520984 1 0 +0.136703 0.036157 0.110096 0.00662378 1 0 +0.100961 0.00493377 0.154156 0.00544695 1 0 +0.13546 0.0669218 0.0237618 0.0068288 1 0 +0.142736 0.0815677 0.0644031 0.00910591 1 0 +0.155592 0.0620349 0.0396216 0.00727139 1 0 +0.23071 0.0941707 0.0424577 0.0106171 1 0 +0.231904 0.080267 0.0565854 0.00924055 1 0 +0.136849 0.055555 0.169806 0.00630133 1 0 +0.13647 0.0580592 0.135486 0.00654245 1 0 +0.150866 0.0539106 0.165846 0.00803573 1 0 +0.394575 0.07269 0.0171423 0.0055546 1 0 +0.39486 0.110574 0.0118853 0.00550496 1 0 +0.387951 0.0869387 0.0294716 0.00538716 1 0 +0.254035 0.0737726 0.183436 0.00907811 1 0 +0.227242 0.108008 0.16302 0.0103512 1 0 +0.22171 0.101723 0.147955 0.0068841 1 0 +0.246732 0.0983579 0.13288 0.00662683 1 0 +0.0335488 0.109202 0.0863888 0.00581296 1 0 +0.0513091 0.0948092 0.0875527 0.00611939 1 0 +0.05679 0.122306 0.0980262 0.00517686 1 0 +0.052778 0.114593 0.0733525 0.00678807 1 0 +0.377528 0.112721 0.191255 0.00636142 1 0 +0.323421 0.118747 0.192828 0.00747939 1 0 +0.0202821 0.127857 0.185543 0.00532221 1 0 +0.0456882 0.121297 0.189231 0.00619298 1 0 +0.0278125 0.163137 0.185644 0.00614243 1 0 +0.0407269 0.184969 0.19302 0.00713734 1 0 +0.202317 0.0380069 0.0635513 0.0061186 1 0 +0.196048 0.0690914 0.0860807 0.00683945 1 0 +0.214552 0.0556608 0.0504908 0.00558046 1 0 +0.187018 0.0565114 0.0598651 0.00514824 1 0 +0.192447 0.179866 0.191769 0.00552928 1 0 +0.382976 0.00933654 0.00800821 0.00624409 1 0 +0.379462 0.00880123 0.0393308 0.00900867 1 0 +0.228739 0.0357554 0.140074 0.00689897 1 0 +0.253924 0.0245816 0.129793 0.00977247 1 0 +0.254756 0.0552683 0.117164 0.0089968 1 0 +0.244956 0.0366762 0.141704 0.00942559 1 0 +0.284401 0.126071 0.0301732 0.0129644 1 0 +0.280462 0.111896 0.0848258 0.0114435 1 0 +0.294088 0.127276 0.0774395 0.0103921 1 0 +0.280271 0.135028 0.0733615 0.0059669 1 0 +0.00563921 0.0823402 0.11215 0.00596405 1 0 +0.00684844 0.11187 0.11031 0.0057838 1 0 +0.0379734 0.0850477 0.0989356 0.00668566 1 0 +0.148048 0.0673697 0.16165 0.00634128 1 0 +0.16632 0.0802059 0.13652 0.0100819 1 0 +0.153832 0.0715793 0.136283 0.00509827 1 0 +0.164782 0.0570918 0.149821 0.00786055 1 0 +0.0708317 0.0947185 0.0813214 0.00661075 1 0 +0.0669437 0.121838 0.0984773 0.00499761 1 0 +0.0644455 0.124797 0.0716368 0.00615064 1 0 +0.090339 0.120408 0.0696529 0.00689617 1 0 +0.262019 0.0920942 0.188904 0.00850721 1 0 +0.266705 0.121891 0.180648 0.00733623 1 0 +0.243492 0.119364 0.185346 0.00985739 1 0 +0.265228 0.0970171 0.153937 0.00631729 1 0 +0.386732 0.186006 0.0490056 0.0075897 1 0 +0.391645 0.153252 0.0174181 0.00874731 1 0 +0.0164142 0.169571 0.0469836 0.00510672 1 0 +0.0162801 0.146559 0.0269116 0.00578039 1 0 +0.0336765 0.137425 0.0465965 0.00640884 1 0 +0.0352034 0.153494 0.042736 0.00671905 1 0 +0.393189 0.145792 0.170589 0.00703241 1 0 +0.393971 0.175462 0.142844 0.00637997 1 0 +0.393145 0.142807 0.143542 0.006247 1 0 +0.378366 0.151838 0.156955 0.00527381 1 0 +0.381775 0.0767982 0.00497851 0.00506417 1 0 +0.384389 0.110274 0.00625307 0.00656743 1 0 +0.0501918 0.0651677 0.0751153 0.00698474 1 0 +0.0522839 0.0587165 0.0514569 0.00649157 1 0 +0.217106 0.0220904 0.0114196 0.00546845 1 0 +0.20051 0.0538623 0.0172405 0.0068967 1 0 +0.222733 0.0473342 0.0279354 0.00572104 1 0 +0.261327 0.0222179 0.186737 0.00551997 1 0 +0.300809 0.0175195 0.00825984 0.0083 1 0 +0.278985 0.0387736 0.00632486 0.00651096 1 0 +0.0868131 0.14207 0.00723754 0.00730909 1 0 +0.111635 0.139991 0.0197633 0.00503765 1 0 +0.103829 0.139937 0.0308627 0.00710114 1 0 +0.0486418 0.113671 0.00631207 0.00680382 1 0 +0.0276864 0.110959 0.0271024 0.00789287 1 0 +0.189698 0.0844834 0.00680689 0.00718779 1 0 +0.165699 0.11211 0.0107286 0.00868968 1 0 +0.213054 0.136856 0.0377959 0.00641269 1 0 +0.205379 0.128465 0.0764922 0.00779672 1 0 +0.210352 0.14347 0.0803363 0.00847115 1 0 +0.19583 0.147316 0.0427877 0.00687583 1 0 +0.203294 0.0652706 0.173102 0.00790694 1 0 +0.195976 0.0856479 0.140561 0.00794527 1 0 +0.198447 0.0571985 0.161029 0.00740396 1 0 +0.271409 0.00778163 0.00978963 0.0049704 1 0 +0.294126 0.00627609 0.01453 0.00645502 1 0 +0.28841 0.183894 0.158858 0.00510762 1 0 +0.269919 0.183373 0.131083 0.00614539 1 0 +0.29785 0.164485 0.122122 0.00688027 1 0 +0.377503 0.106226 0.0875702 0.00694416 1 0 +0.386703 0.127112 0.110159 0.00913205 1 0 +0.357162 0.124419 0.0912405 0.00725182 1 0 +0.0095061 0.116134 0.0277109 0.0070637 1 0 +0.00773396 0.0931842 0.051083 0.0050224 1 0 +0.00649546 0.115939 0.0538062 0.00667849 1 0 +0.0282208 0.110772 0.0450519 0.00622384 1 0 +0.394226 0.100204 0.186616 0.00590458 1 0 +0.390406 0.111207 0.183462 0.0060037 1 0 +0.371822 0.111796 0.16477 0.00589004 1 0 +0.320528 0.0880744 0.0322957 0.00945677 1 0 +0.298506 0.108633 0.0320131 0.00953935 1 0 +0.27853 0.09926 0.0699264 0.00818781 1 0 +0.31458 0.122673 0.0613605 0.0144611 1 0 +0.0293974 0.107606 0.126394 0.00543034 1 0 +0.0588922 0.124193 0.121338 0.00801985 1 0 +0.0424652 0.102032 0.131962 0.00553475 1 0 +0.364571 0.122046 0.00864333 0.0089966 1 0 +0.327554 0.121654 0.0148372 0.0124066 1 0 +0.333016 0.124314 0.0330948 0.00683507 1 0 +0.105421 0.0127092 0.192345 0.00790702 1 0 +0.137771 0.0134939 0.193549 0.00659779 1 0 +0.122142 0.0399081 0.190873 0.00657837 1 0 +0.0360628 0.14824 0.195135 0.00498531 1 0 +0.0487747 0.130945 0.194461 0.00520711 1 0 +0.0114236 0.190122 0.0171162 0.00624084 1 0 +0.00719424 0.185625 0.043441 0.00751635 1 0 +0.150284 0.191552 0.11361 0.00847748 1 0 +0.113937 0.170589 0.114578 0.00946019 1 0 +0.157242 0.195396 0.0739888 0.004951 1 0 +0.187169 0.191199 0.104521 0.0057037 1 0 +0.191458 0.179219 0.0751372 0.00509441 1 0 +0.179449 0.177476 0.0741934 0.00707689 1 0 +0.220758 0.131729 0.172635 0.0110727 1 0 +0.235641 0.14715 0.150809 0.00628522 1 0 +0.174845 0.0173726 0.00679136 0.00715132 1 0 +0.389 0.0262074 0.0765676 0.00740518 1 0 +0.385725 0.0576259 0.0716836 0.00494275 1 0 +0.369562 0.0489367 0.0886258 0.00875958 1 0 +0.389473 0.125925 0.0240515 0.00707116 1 0 +0.384935 0.114117 0.0640126 0.00517591 1 0 +0.358025 0.129177 0.065102 0.00532288 1 0 +0.380652 0.114116 0.0493804 0.00640348 1 0 +0.0925978 0.185847 0.176284 0.00817487 1 0 +0.103581 0.173693 0.138901 0.00526595 1 0 +0.169338 0.185191 0.144271 0.0124284 1 0 +0.190417 0.142733 0.141853 0.00703344 1 0 +0.0145455 0.0827114 0.192269 0.00671582 1 0 +0.0201515 0.118411 0.19059 0.00538755 1 0 +0.0447295 0.10804 0.190066 0.00589401 1 0 +0.372658 0.186009 0.0342008 0.00586944 1 0 +0.341111 0.193211 0.0297643 0.00725038 1 0 +0.291381 0.145337 0.0695375 0.00537388 1 0 +0.262009 0.149087 0.0586692 0.0063418 1 0 +0.272672 0.157725 0.0471531 0.00678475 1 0 +0.177522 0.191702 0.0151077 0.00871947 1 0 +0.195951 0.192488 0.042442 0.0075691 1 0 +0.223972 0.0441119 0.066088 0.00943428 1 0 +0.216549 0.0621694 0.0881533 0.00736065 1 0 +0.248009 0.0605968 0.0849173 0.00751538 1 0 +0.222064 0.056697 0.058959 0.005155 1 0 +0.204322 0.00865878 0.149084 0.00905007 1 0 +0.0179466 0.0646345 0.0477057 0.00580657 1 0 +0.0279603 0.0870887 0.0391257 0.00507917 1 0 +0.0583118 0.138382 0.13237 0.0075169 1 0 +0.0310013 0.14362 0.151161 0.00524737 1 0 +0.0781885 0.0332649 0.0108671 0.00532103 1 0 +0.0690375 0.0649554 0.0147177 0.00651158 1 0 +0.104554 0.0463637 0.00797568 0.00810448 1 0 +0.291221 0.19255 0.0657017 0.00699412 1 0 +0.314641 0.193615 0.0665849 0.00653856 1 0 +0.322512 0.174957 0.0655721 0.0117791 1 0 +0.246221 0.191961 0.0279806 0.00505252 1 0 +0.26026 0.192866 0.0414315 0.0063595 1 0 +0.226439 0.194878 0.0503368 0.0053088 1 0 +0.381734 0.0627377 0.129848 0.00505232 1 0 +0.359458 0.0626474 0.123117 0.00536539 1 0 +0.368474 0.0544648 0.140028 0.00583783 1 0 +0.371952 0.186986 0.0786659 0.00541608 1 0 +0.373149 0.188049 0.110842 0.00521248 1 0 +0.348782 0.174456 0.0904933 0.0109357 1 0 +0.370339 0.0202183 0.145735 0.00762078 1 0 +0.353047 0.036823 0.134046 0.00654898 1 0 +0.173665 0.0688826 0.112392 0.00546214 1 0 +0.00601937 0.0813715 0.168923 0.00635341 1 0 +0.00602729 0.0869847 0.136085 0.00609493 1 0 +0.0184638 0.0953948 0.160977 0.0049687 1 0 +0.0871605 0.0551548 0.11149 0.00512355 1 0 +0.121243 0.0613418 0.116861 0.00674977 1 0 +0.0104101 0.0605892 0.180056 0.00544866 1 0 +0.0264487 0.0799943 0.162158 0.00601263 1 0 +0.0255322 0.0594446 0.155259 0.00734574 1 0 +0.236368 0.0362734 0.192409 0.00762552 1 0 +0.220529 0.0553839 0.190136 0.00524858 1 0 +0.251545 0.0452632 0.169149 0.00625398 1 0 +0.258667 0.0495091 0.076911 0.0063627 1 0 +0.0844778 0.0171772 0.0142944 0.00539746 1 0 +0.104986 0.0472937 0.020959 0.00496815 1 0 +0.234017 0.123122 0.165273 0.00636487 1 0 +0.215883 0.114482 0.137351 0.00607392 1 0 +0.255968 0.107054 0.134688 0.00618773 1 0 +0.242199 0.129011 0.143615 0.00661564 1 0 +0.254621 0.0204878 0.0150463 0.0063895 1 0 +0.260334 0.046401 0.00768789 0.00812479 1 0 +0.247893 0.0462226 0.0316245 0.00700558 1 0 +0.221421 0.134262 0.0282345 0.00655456 1 0 +0.180824 0.0228593 0.187996 0.00638733 1 0 +0.213041 0.0133159 0.19237 0.00780685 1 0 +0.194998 0.0338827 0.189502 0.0106018 1 0 +0.272619 0.189084 0.0698362 0.00594189 1 0 +0.302616 0.154225 0.0769161 0.00934855 1 0 +0.264127 0.154008 0.0797161 0.00829343 1 0 +0.269698 0.168629 0.0506287 0.0050404 1 0 +0.254899 0.0132178 0.0246547 0.00566253 1 0 +0.262937 0.0114562 0.0492763 0.00654525 1 0 +0.0232101 0.185494 0.094236 0.00642635 1 0 +0.0189702 0.190582 0.104327 0.00564361 1 0 +0.394705 0.0831134 0.171396 0.0056949 1 0 +0.384951 0.0759243 0.143572 0.00518763 1 0 +0.391195 0.109337 0.137347 0.00919292 1 0 +0.377732 0.0936121 0.147022 0.00939294 1 0 +0.0611988 0.0576605 0.0342762 0.00552004 1 0 +0.132409 0.152308 0.0376554 0.00724506 1 0 +0.257384 0.0913827 0.0213397 0.00792487 1 0 +0.273538 0.105342 0.0198757 0.0126039 1 0 +0.249536 0.115752 0.00706078 0.00712634 1 0 +0.273484 0.0906132 0.0559532 0.00589563 1 0 +0.00905115 0.0140949 0.160302 0.00928439 1 0 +0.195107 0.12811 0.194695 0.00562069 1 0 +0.170111 0.136759 0.187004 0.00585134 1 0 +0.17994 0.131085 0.156562 0.00832547 1 0 +0.164357 0.0123431 0.173025 0.00531164 1 0 +0.17351 0.0145689 0.152659 0.00496858 1 0 +0.0701793 0.171675 0.188997 0.00495742 1 0 +0.0748005 0.143099 0.15452 0.00690164 1 0 +0.374541 0.189631 0.155372 0.00811457 1 0 +0.380585 0.0188822 0.0672238 0.00714736 1 0 +0.382836 0.0435632 0.061077 0.00516762 1 0 +0.364107 0.0429161 0.0770429 0.00538829 1 0 +0.37229 0.041059 0.0512871 0.00493193 1 0 +0.355692 0.0860349 0.0875009 0.00631317 1 0 +0.349618 0.116454 0.0780361 0.00525851 1 0 +0.364768 0.0981785 0.0596607 0.00789483 1 0 +0.179002 0.0116066 0.0194827 0.00589101 1 0 +0.216723 0.0137037 0.0181508 0.00529219 1 0 +0.198619 0.00990967 0.0413414 0.0101715 1 0 +0.186634 0.0338454 0.044727 0.00608557 1 0 +0.4 0.03 0.03 0.01 2 0 +0 0.03 0.03 0.01 2 0 +0.4 0.03 0.17 0.01 2 0 +0 0.03 0.17 0.01 2 0 +0.4 0.17 0.03 0.01 2 0 +0 0.17 0.03 0.01 2 0 +0.4 0.17 0.17 0.01 2 0 +0 0.17 0.17 0.01 2 0 +0.02 0.03 0.03 0.01 2 0 +0.04 0.03 0.03 0.01 2 0 +0.06 0.03 0.03 0.01 2 0 +0.08 0.03 0.03 0.01 2 0 +0.1 0.03 0.03 0.01 2 0 +0.12 0.03 0.03 0.01 2 0 +0.14 0.03 0.03 0.01 2 0 +0.16 0.03 0.03 0.01 2 0 +0.18 0.03 0.03 0.01 2 0 +0.2 0.03 0.03 0.01 2 0 +0.22 0.03 0.03 0.01 2 0 +0.24 0.03 0.03 0.01 2 0 +0.26 0.03 0.03 0.01 2 0 +0.28 0.03 0.03 0.01 2 0 +0.3 0.03 0.03 0.01 2 0 +0.32 0.03 0.03 0.01 2 0 +0.34 0.03 0.03 0.01 2 0 +0.36 0.03 0.03 0.01 2 0 +0.38 0.03 0.03 0.01 2 0 +0.02 0.03 0.17 0.01 2 0 +0.04 0.03 0.17 0.01 2 0 +0.06 0.03 0.17 0.01 2 0 +0.08 0.03 0.17 0.01 2 0 +0.1 0.03 0.17 0.01 2 0 +0.12 0.03 0.17 0.01 2 0 +0.14 0.03 0.17 0.01 2 0 +0.16 0.03 0.17 0.01 2 0 +0.18 0.03 0.17 0.01 2 0 +0.2 0.03 0.17 0.01 2 0 +0.22 0.03 0.17 0.01 2 0 +0.24 0.03 0.17 0.01 2 0 +0.26 0.03 0.17 0.01 2 0 +0.28 0.03 0.17 0.01 2 0 +0.3 0.03 0.17 0.01 2 0 +0.32 0.03 0.17 0.01 2 0 +0.34 0.03 0.17 0.01 2 0 +0.36 0.03 0.17 0.01 2 0 +0.38 0.03 0.17 0.01 2 0 +0.02 0.17 0.03 0.01 2 0 +0.04 0.17 0.03 0.01 2 0 +0.06 0.17 0.03 0.01 2 0 +0.08 0.17 0.03 0.01 2 0 +0.1 0.17 0.03 0.01 2 0 +0.12 0.17 0.03 0.01 2 0 +0.14 0.17 0.03 0.01 2 0 +0.16 0.17 0.03 0.01 2 0 +0.18 0.17 0.03 0.01 2 0 +0.2 0.17 0.03 0.01 2 0 +0.22 0.17 0.03 0.01 2 0 +0.24 0.17 0.03 0.01 2 0 +0.26 0.17 0.03 0.01 2 0 +0.28 0.17 0.03 0.01 2 0 +0.3 0.17 0.03 0.01 2 0 +0.32 0.17 0.03 0.01 2 0 +0.34 0.17 0.03 0.01 2 0 +0.36 0.17 0.03 0.01 2 0 +0.38 0.17 0.03 0.01 2 0 +0.02 0.17 0.17 0.01 2 0 +0.04 0.17 0.17 0.01 2 0 +0.06 0.17 0.17 0.01 2 0 +0.08 0.17 0.17 0.01 2 0 +0.1 0.17 0.17 0.01 2 0 +0.12 0.17 0.17 0.01 2 0 +0.14 0.17 0.17 0.01 2 0 +0.16 0.17 0.17 0.01 2 0 +0.18 0.17 0.17 0.01 2 0 +0.2 0.17 0.17 0.01 2 0 +0.22 0.17 0.17 0.01 2 0 +0.24 0.17 0.17 0.01 2 0 +0.26 0.17 0.17 0.01 2 0 +0.28 0.17 0.17 0.01 2 0 +0.3 0.17 0.17 0.01 2 0 +0.32 0.17 0.17 0.01 2 0 +0.34 0.17 0.17 0.01 2 0 +0.36 0.17 0.17 0.01 2 0 +0.38 0.17 0.17 0.01 2 0 +0.347522 0.0798775 0.189345 0.00542525 1 0 +0.0978862 0.0443223 0.157324 0.00881265 1 0 +0.392662 0.0990343 0.149296 0.00665244 1 0 +0.27 0.186275 0.156019 0.00669684 1 0 +0.356951 0.162534 0.138065 0.00842663 1 0 +0.282853 0.0239922 0.154694 0.00641626 1 0 +0.03 0.152792 0.169299 0.005642 1 0 +0.102813 0.149965 0.130103 0.0072981 1 0 +0.246362 0.124006 0.0878291 0.00776572 1 0 +0.134712 0.0782273 0.00486166 0.00518048 1 0 +0.145202 0.0420336 0.160607 0.00612731 1 0 +0.1331 0.191055 0.13096 0.00492461 1 0 +0.178568 0.0439534 0.0151785 0.00628492 1 0 +0.0369389 0.0587979 0.0362255 0.00831987 1 0 +0.324462 0.104118 0.060766 0.00656953 1 0 +0.242014 0.156239 0.0521801 0.00555918 1 0 +0.347445 0.0793337 0.0940084 0.00614759 1 0 +0.176037 0.0328676 0.119084 0.00524276 1 0 +0.203878 0.107329 0.173163 0.00650472 1 0 +0.275532 0.0453966 0.0313616 0.00608947 1 0 +0.26178 0.155021 0.0948649 0.00706965 1 0 +0.39 0.158236 0.172488 0.00563869 1 0 +0.105644 0.0790286 0.176016 0.00580547 1 0 +0.20005 0.0366356 0.0493124 0.0083647 1 0 +0.0185075 0.160973 0.130327 0.00501499 1 0 +0.300174 0.155686 0.0955826 0.00747518 1 0 +0.113642 0.0321054 0.151243 0.00816062 1 0 +0.0507885 0.15975 0.145708 0.00739224 1 0 +0.271194 0.0350138 0.151904 0.00620918 1 0 +0.201468 0.195442 0.130678 0.00505288 1 0 +0.188726 0.172934 0.0671716 0.0054132 1 0 +0.370376 0.156378 0.178879 0.00812185 1 0 +0.212651 0.051505 0.0344394 0.00698105 1 0 +0.0728915 0.0702816 0.0670054 0.00733578 1 0 +0.27 0.0222001 0.0413285 0.00700511 1 0 +0.209838 0.078913 0.158632 0.00692605 1 0 +0.0313396 0.169454 0.0453461 0.00637858 1 0 +0.380556 0.0338425 0.153157 0.00728474 1 0 +0.327886 0.154734 0.118663 0.00729678 1 0 +0.35 0.157495 0.0225033 0.00747683 1 0 +0.0649327 0.050875 0.110639 0.00808269 1 0 +0.152733 0.0857879 0.179473 0.00634748 1 0 +0.288763 0.147693 0.0341985 0.0094579 1 0 +0.11 0.0433635 0.0307431 0.00670737 1 0 +0.361312 0.0139639 0.152203 0.00512422 1 0 +0.220006 0.095739 0.171783 0.00552227 1 0 +0.339671 0.181996 0.18433 0.00656595 1 0 +0.267395 0.194784 0.109548 0.00565878 1 0 +0.308662 0.0124479 0.173343 0.00896394 1 0 +0.253811 0.0926573 0.109213 0.0106235 1 0 +0.392837 0.123744 0.178331 0.00689455 1 0 +0.220257 0.0991966 0.0646123 0.0143061 1 0 +0.149942 0.0119581 0.0950768 0.00568721 1 0 +0.021108 0.192638 0.0225377 0.00513947 1 0 +0.202093 0.121861 0.111158 0.00779051 1 0 +0.364844 0.0434614 0.0223083 0.00624303 1 0 +0.0816671 0.141038 0.0995708 0.00766147 1 0 +0.356446 0.160479 0.0471579 0.00994152 1 0 +0.0450777 0.18198 0.0420726 0.0054801 1 0 +0.359875 0.0893131 0.177108 0.00504329 1 0 +0.0983642 0.130066 0.170333 0.00574947 1 0 +0.0337275 0.0454853 0.184088 0.00520309 1 0 +0.260472 0.183642 0.0225082 0.00557063 1 0 +0.320423 0.153275 0.0290202 0.00675951 1 0 +0.142201 0.152845 0.144419 0.0122891 1 0 +0.236239 0.12794 0.17545 0.00511185 1 0 +0.253457 0.0513097 0.0973065 0.00889881 1 0 +0.292661 0.0883479 0.0835194 0.0103442 1 0 +0.29 0.019008 0.0211345 0.00730379 1 0 +0.206797 0.109716 0.0158543 0.00644442 1 0 +0.00485992 0.157468 0.0570503 0.00495699 1 0 +0.151719 0.0532074 0.109485 0.00820095 1 0 +0.207828 0.170978 0.14269 0.00686123 1 0 +0.207725 0.0420149 0.179824 0.00733632 1 0 +0.270731 0.14459 0.099749 0.0060311 1 0 +0.184316 0.122176 0.187476 0.00577481 1 0 +0.140387 0.0445274 0.0230222 0.00612092 1 0 +0.160369 0.1527 0.0415237 0.00674556 1 0 +0.300792 0.147145 0.15994 0.00929333 1 0 +0.0525256 0.0915602 0.179181 0.00589334 1 0 +0.129693 0.175565 0.0426627 0.00688964 1 0 +0.299318 0.0291523 0.0845295 0.00620838 1 0 +0.00962742 0.0170789 0.119014 0.00614714 1 0 +0.26608 0.0134887 0.0245473 0.0055224 1 0 +0.359626 0.145645 0.018462 0.00831556 1 0 +0.264127 0.048321 0.0226428 0.00742254 1 0 +0.296538 0.081742 0.100029 0.00744197 1 0 +0.345111 0.0473617 0.172251 0.00823776 1 0 +0.0868119 0.108331 0.0569456 0.00585534 1 0 +0.174245 0.131957 0.0322579 0.00524247 1 0 +0.12388 0.118941 0.0234175 0.00751806 1 0 +0.334458 0.0902555 0.188535 0.0100815 1 0 +0.195442 0.0683869 0.120811 0.00520101 1 0 +0.33765 0.0317681 0.0132248 0.00499725 1 0 +0.0139264 0.0661681 0.057607 0.00498931 1 0 +0.366444 0.176412 0.0907763 0.00508473 1 0 +0.251406 0.18165 0.175613 0.00552709 1 0 +0.0480855 0.0204338 0.179939 0.00598943 1 0 +0.342488 0.0409397 0.10765 0.00671023 1 0 +0.172764 0.118587 0.043688 0.00660758 1 0 +0.33 0.0380642 0.179743 0.0061229 1 0 +0.177923 0.116745 0.0232329 0.00649864 1 0 +0.0434834 0.147828 0.0215313 0.0051462 1 0 +0.130758 0.0473001 0.0975034 0.00695327 1 0 +0.272865 0.0192001 0.132966 0.00589323 1 0 +0.265019 0.150946 0.168352 0.00741564 1 0 +0.24418 0.0141703 0.0369479 0.00778553 1 0 +0.336748 0.170515 0.077577 0.0071526 1 0 +0.184562 0.178649 0.112849 0.00958207 1 0 +0.362317 0.110098 0.0861787 0.00522559 1 0 +0.157402 0.116345 0.119616 0.00810692 1 0 +0.208746 0.0329015 0.0825929 0.00742124 1 0 +0.0497274 0.0591842 0.0861661 0.00559058 1 0 +0.01 0.0185565 0.177554 0.00697095 1 0 +0.0728359 0.0892859 0.0249654 0.00991388 1 0 +0.00664008 0.149212 0.0165518 0.00717416 1 0 +0.214491 0.0193724 0.180289 0.00578476 1 0 +0.277068 0.191227 0.0809189 0.00619127 1 0 +0.0424533 0.104161 0.0716172 0.00799191 1 0 +0.31 0.0402308 0.0232237 0.00582996 1 0 +0.27754 0.184929 0.172891 0.00540447 1 0 +0.252694 0.158786 0.0735484 0.00554851 1 0 +0.3085 0.0988447 0.149485 0.0110854 1 0 +0.146358 0.0654075 0.176887 0.00852953 1 0 +0.15028 0.0850435 0.124902 0.0097613 1 0 +0.331544 0.04829 0.19056 0.00819168 1 0 +0.351251 0.101156 0.135048 0.00589803 1 0 +0.186782 0.165407 0.083592 0.00584857 1 0 +0.325097 0.166509 0.185233 0.00643767 1 0 +0.0918322 0.180427 0.0413606 0.00745013 1 0 +0.160433 0.0312632 0.152793 0.00725904 1 0 +0.17575 0.0105614 0.189975 0.00706232 1 0 +0.11 0.0178155 0.165291 0.00645094 1 0 +0.209597 0.178443 0.177733 0.00493965 1 0 +0.0474925 0.152649 0.157478 0.00674388 1 0 +0.0970484 0.187071 0.0748803 0.00561971 1 0 +0.127766 0.16398 0.184554 0.00756034 1 0 +0.138599 0.0762437 0.189021 0.00663846 1 0 +0.091639 0.0976758 0.118241 0.00951811 1 0 +0.37809 0.0472335 0.165234 0.0079822 1 0 +0.09 0.155653 0.166236 0.0078889 1 0 +0.222052 0.0741071 0.101548 0.00603959 1 0 +0.360558 0.156651 0.0895007 0.0104342 1 0 +0.0209121 0.156322 0.178298 0.00574117 1 0 +0.275085 0.0433949 0.176447 0.00565728 1 0 +0.132939 0.151075 0.159076 0.00513916 1 0 +0.338449 0.0869435 0.0180735 0.00838531 1 0 +0.255873 0.0180861 0.178487 0.00519845 1 0 +0.19 0.178801 0.0412054 0.0074073 1 0 +0.24197 0.150359 0.0663884 0.00600992 1 0 +0.366987 0.0483655 0.151525 0.00651083 1 0 +0.258204 0.0950625 0.0787748 0.0143746 1 0 +0.313156 0.0696813 0.0855558 0.00515003 1 0 +0.0224121 0.161022 0.017894 0.00526373 1 0 +0.378217 0.181987 0.0709204 0.0053618 1 0 +0.336389 0.151644 0.165116 0.00933514 1 0 +0.265528 0.039234 0.181998 0.00611775 1 0 +0.0774819 0.181246 0.0528093 0.0054311 1 0 +0.366662 0.0219018 0.158378 0.00565348 1 0 +0.159721 0.0359766 0.0451912 0.00632694 1 0 +0.153264 0.142666 0.0149768 0.00576333 1 0 +0.267688 0.0789297 0.0281816 0.00545798 1 0 +0.359133 0.041135 0.10209 0.00997302 1 0 +0.27 0.156557 0.179664 0.00615902 1 0 +0.157162 0.0928317 0.0624114 0.00930508 1 0 +0.24382 0.0682745 0.191382 0.00498369 1 0 +0.030824 0.119874 0.0824092 0.00589828 1 0 +0.0607368 0.0719771 0.121373 0.006561 1 0 +0.182555 0.0870453 0.131754 0.00758449 1 0 +0.249288 0.171861 0.00902276 0.00894261 1 0 +0.128277 0.140272 0.0478176 0.00904013 1 0 +0.39 0.0408851 0.179636 0.00764493 1 0 +0.344839 0.0246951 0.0561511 0.00517938 1 0 +0.374681 0.124486 0.022 0.00793192 1 0 +0.172293 0.0940976 0.0800211 0.00723459 1 0 +0.189986 0.15199 0.152309 0.0069387 1 0 +0.0808306 0.0847432 0.0775252 0.00801434 1 0 +0.35 0.0244296 0.180218 0.00534406 1 0 +0.29128 0.068629 0.089716 0.00854914 1 0 +0.370536 0.00948985 0.15318 0.00517375 1 0 +0.138975 0.029358 0.0148715 0.0051768 1 0 +0.229972 0.163942 0.156787 0.0076274 1 0 +0.0458068 0.0745883 0.105977 0.00800304 1 0 +0.387971 0.13337 0.0972578 0.005263 1 0 +0.267418 0.123144 0.103298 0.00717081 1 0 +0.289479 0.116327 0.166929 0.00597564 1 0 +0.0076274 0.0163704 0.0386944 0.00763753 1 0 +0.168509 0.182954 0.0239459 0.006639 1 0 +0.15 0.176936 0.0391289 0.00521332 1 0 +0.37 0.158822 0.0381978 0.00639058 1 0 +0.393535 0.192952 0.0828301 0.0070797 1 0 +0.220561 0.152147 0.0267704 0.0081512 1 0 +0.0723325 0.16431 0.182063 0.00538414 1 0 +0.334911 0.0744686 0.0606515 0.00522857 1 0 +0.235834 0.026813 0.0458702 0.00671452 1 0 +0.195435 0.0170165 0.162842 0.00551265 1 0 +0.269892 0.0607274 0.109486 0.00883171 1 0 +0.343501 0.0709899 0.0209709 0.0057976 1 0 +0.222355 0.0915619 0.123518 0.00627954 1 0 +0.14512 0.0672658 0.124313 0.00713699 1 0 +0.0789361 0.0122478 0.165528 0.00833777 1 0 +0.303859 0.120825 0.105216 0.00568384 1 0 +0.0668885 0.187978 0.0470427 0.0057157 1 0 +0.0474666 0.176518 0.156891 0.00643413 1 0 +0.0546208 0.00894538 0.0542628 0.00499468 1 0 +0.163881 0.165255 0.0156245 0.00562792 1 0 +0.264941 0.0352942 0.0524973 0.00526542 1 0 +0.0682807 0.131748 0.126804 0.00521273 1 0 +0.31 0.0414694 0.0383149 0.00734023 1 0 +0.293551 0.0411853 0.146535 0.00674033 1 0 +0.259371 0.101169 0.0300947 0.00535567 1 0 +0.0236936 0.19498 0.117863 0.00556218 1 0 +0.194553 0.0960323 0.00662746 0.00534121 1 0 +0.144031 0.00765253 0.0145084 0.00790903 1 0 +0.387286 0.0283025 0.183463 0.00540204 1 0 +0.190849 0.085665 0.042132 0.0058276 1 0 +0.337163 0.0493615 0.0297166 0.00957028 1 0 +0.0702921 0.0508055 0.0761078 0.00887061 1 0 +0.363204 0.079317 0.031058 0.00585507 1 0 +0.0239026 0.0171388 0.0732999 0.00558563 1 0 +0.31 0.171377 0.0410328 0.00495384 1 0 +0.242897 0.0431399 0.157876 0.00764433 1 0 +0.0232279 0.0625859 0.0569853 0.00499752 1 0 +0.308419 0.154837 0.0283139 0.00536722 1 0 +0.351596 0.0296902 0.0490809 0.00580207 1 0 +0.00724216 0.107479 0.173821 0.0052565 1 0 +0.320234 0.110807 0.157754 0.00760032 1 0 +0.10993 0.17569 0.0450187 0.00888243 1 0 +0.0556015 0.0166924 0.153296 0.0118053 1 0 +0.255539 0.0102831 0.109715 0.00796557 1 0 +0.146502 0.158052 0.0927089 0.00542645 1 0 +0.105747 0.0703886 0.184545 0.00523508 1 0 +0.32732 0.123906 0.044966 0.00633809 1 0 +0.167621 0.160837 0.179697 0.00536462 1 0 +0.156603 0.15324 0.169971 0.00710102 1 0 +0.308484 0.164311 0.181512 0.00539052 1 0 +0.0635922 0.181646 0.183508 0.00623565 1 0 +0.0488876 0.155546 0.17358 0.00734124 1 0 +0.05 0.161337 0.0228354 0.00504587 1 0 +0.333482 0.115593 0.0639115 0.00588445 1 0 +0.311958 0.0137062 0.111868 0.00852586 1 0 +0.07 0.0223539 0.18273 0.00591058 1 0 +0.00719179 0.070529 0.0416848 0.00606667 1 0 +0.101032 0.0195252 0.155612 0.00685467 1 0 +0.0254764 0.0434224 0.0366104 0.00593267 1 0 +0.0697503 0.14859 0.103677 0.00703194 1 0 +0.0853097 0.164886 0.121862 0.00635816 1 0 +0.261932 0.182529 0.103209 0.0052298 1 0 +0.287308 0.151721 0.168501 0.00726717 1 0 +0.0169782 0.15904 0.0805994 0.0050559 1 0 +0.14364 0.0674591 0.13787 0.0055179 1 0 +0.231317 0.120206 0.0514386 0.00936835 1 0 +0.0573314 0.122786 0.19436 0.00603971 1 0 +0.0281059 0.0184631 0.021398 0.00499663 1 0 +0.263591 0.0639061 0.174787 0.00656042 1 0 +0.0581201 0.184798 0.163389 0.00631669 1 0 +0.179217 0.044415 0.158281 0.00766895 1 0 +0.0731051 0.0881463 0.180648 0.00529527 1 0 +0.09 0.0359271 0.0194755 0.0049713 1 0 +0.23 0.157473 0.178684 0.0080108 1 0 +0.341498 0.194203 0.0117522 0.00650448 1 0 +0.391166 0.10602 0.0685237 0.0059928 1 0 +0.358029 0.0186959 0.108716 0.00560939 1 0 +0.329772 0.17071 0.121833 0.00909976 1 0 +0.335608 0.0574737 0.173582 0.0057023 1 0 +0.331246 0.159417 0.103862 0.0085865 1 0 +0.0563992 0.0102386 0.185024 0.00576244 1 0 +0.213145 0.0479381 0.170198 0.00519868 1 0 +0.0938822 0.161259 0.0546349 0.00524396 1 0 +0.264021 0.027745 0.0944503 0.00506959 1 0 +0.140928 0.0777212 0.176066 0.00495326 1 0 +0.161296 0.115551 0.0985767 0.00666958 1 0 +0.280353 0.130673 0.178957 0.00528118 1 0 +0.156516 0.136071 0.178792 0.00753372 1 0 +0.251158 0.0395676 0.121355 0.00764725 1 0 +0.326188 0.034959 0.0461858 0.00591718 1 0 +0.217008 0.055159 0.00923339 0.0062824 1 0 +0.24511 0.0178481 0.0217576 0.00554719 1 0 +0.192659 0.033758 0.130776 0.00667871 1 0 +0.134313 0.00674791 0.123773 0.00571604 1 0 +0.25894 0.00798155 0.142322 0.00527416 1 0 +0.0989189 0.138211 0.188624 0.00693057 1 0 +0.188807 0.154195 0.0314249 0.00814928 1 0 +0.0465999 0.0158036 0.0306726 0.00566998 1 0 +0.21 0.178166 0.16205 0.00516225 1 0 +0.103462 0.0747507 0.162656 0.00566988 1 0 +0.232491 0.186303 0.165265 0.00743411 1 0 +0.0948224 0.0458309 0.0355574 0.00719834 1 0 +0.137066 0.0453262 0.182442 0.00595659 1 0 +0.0606057 0.0509872 0.139644 0.00577137 1 0 +0.118997 0.0803134 0.0169132 0.00963772 1 0 +0.0648667 0.150087 0.129484 0.00620631 1 0 +0.13 0.168638 0.0183636 0.00540324 1 0 +0.328037 0.00816448 0.0789749 0.00836521 1 0 +0.261785 0.0674796 0.0860459 0.00765607 1 0 +0.265839 0.12281 0.0595413 0.0109387 1 0 +0.125226 0.108533 0.114202 0.00615113 1 0 +0.215342 0.155261 0.153166 0.0062645 1 0 +0.189995 0.0465725 0.0353405 0.00970266 1 0 +0.0885535 0.0561785 0.184883 0.00626981 1 0 +0.121939 0.169556 0.15395 0.00617321 1 0 +0.11 0.174743 0.0199283 0.00496436 1 0 +0.331276 0.142067 0.0574075 0.0114335 1 0 +0.0469555 0.0789318 0.0751397 0.00502226 1 0 +0.20313 0.095668 0.132944 0.0065325 1 0 +0.0264725 0.182658 0.163376 0.00525103 1 0 +0.0549236 0.0830398 0.0891248 0.0062925 1 0 +0.309388 0.0495779 0.0630322 0.00534495 1 0 +0.234442 0.182998 0.0358474 0.00529841 1 0 +0.206371 0.159944 0.0584285 0.00581264 1 0 +0.306901 0.125028 0.0251801 0.010106 1 0 +0.101812 0.0251804 0.129384 0.00802216 1 0 +0.369995 0.173609 0.181455 0.00562445 1 0 +0.349316 0.114621 0.138382 0.00538571 1 0 +0.330089 0.129989 0.143439 0.00887266 1 0 +0.115997 0.191979 0.0698904 0.00832214 1 0 +0.177899 0.0857562 0.112367 0.00852281 1 0 +0.072263 0.030518 0.111296 0.00596901 1 0 +0.352759 0.136596 0.0576396 0.00644424 1 0 +0.230748 0.0966892 0.17339 0.00538032 1 0 +0.0458287 0.0433015 0.158147 0.00874561 1 0 +0.0980732 0.171347 0.0552498 0.00569654 1 0 +0.305693 0.155839 0.127417 0.00593698 1 0 +0.335309 0.126327 0.0706772 0.00693509 1 0 +0.314188 0.143696 0.103088 0.0107034 1 0 +0.142819 0.173227 0.0858479 0.0112391 1 0 +0.31 0.0348089 0.180252 0.00510729 1 0 +0.15 0.0436508 0.0331577 0.00721381 1 0 +0.19796 0.0280548 0.148822 0.00873619 1 0 +0.287608 0.0440149 0.181191 0.00508972 1 0 +0.234242 0.0276053 0.0936894 0.00535566 1 0 +0.200447 0.0930969 0.0415927 0.00509391 1 0 +0.33 0.0395939 0.0215398 0.00504401 1 0 +0.108655 0.0741489 0.140021 0.00772278 1 0 +0.23 0.0336803 0.155098 0.00832 1 0 +0.05 0.0465513 0.0365519 0.0095876 1 0 +0.102633 0.158261 0.0806719 0.00520046 1 0 +0.30296 0.116641 0.142802 0.00871556 1 0 +0.146636 0.0086573 0.0811116 0.00646753 1 0 +0.248061 0.150212 0.159558 0.00759468 1 0 +0.0511742 0.126609 0.00468162 0.00493993 1 0 +0.160765 0.14026 0.105735 0.00630499 1 0 +0.203703 0.132457 0.169937 0.00620977 1 0 +0.287417 0.086656 0.114549 0.00635341 1 0 +0.0993595 0.191428 0.098834 0.00507766 1 0 +0.313624 0.145026 0.121706 0.00796975 1 0 +0.122538 0.15124 0.154183 0.00635657 1 0 +0.0604078 0.0152021 0.123458 0.00542286 1 0 +0.0223381 0.125728 0.135981 0.00585759 1 0 +0.315672 0.149159 0.0607302 0.00602484 1 0 +0.3332 0.164513 0.0123964 0.00965288 1 0 +0.37582 0.172889 0.0147571 0.00606757 1 0 +0.052553 0.0588091 0.110053 0.00604681 1 0 +0.140355 0.0965998 0.0802462 0.0122419 1 0 +0.0973348 0.00627142 0.0760289 0.00540746 1 0 +0.279178 0.0296219 0.185108 0.00513539 1 0 +0.00445371 0.0476518 0.120346 0.00494855 1 0 +0.0644919 0.191953 0.00716455 0.00588954 1 0 +0.0869399 0.0810823 0.10593 0.0102924 1 0 +0.340655 0.171237 0.140926 0.00589336 1 0 +0.237862 0.110315 0.0055321 0.00579299 1 0 +0.320733 0.173027 0.0827873 0.00563505 1 0 +0.144934 0.0258788 0.0882664 0.00526551 1 0 +0.101809 0.0163963 0.176675 0.00526074 1 0 +0.107666 0.0199858 0.0178321 0.00611792 1 0 +0.0498234 0.0372418 0.0210861 0.00511295 1 0 +0.110865 0.0949012 0.0684746 0.0052638 1 0 +0.38057 0.176806 0.0552643 0.00512958 1 0 +0.197033 0.114059 0.138863 0.0084076 1 0 +0.249194 0.109915 0.166191 0.00529529 1 0 +0.0862794 0.154898 0.17898 0.00540933 1 0 +0.27033 0.12531 0.0158457 0.00713187 1 0 +0.32917 0.0623616 0.0191554 0.00725251 1 0 +0.0834931 0.060607 0.0794537 0.00790831 1 0 +0.00791223 0.0940613 0.176638 0.00505783 1 0 +0.0787373 0.191473 0.104354 0.00497613 1 0 +0.354648 0.0809409 0.165555 0.00512381 1 0 +0.195343 0.0213989 0.0684254 0.00535459 1 0 +0.202165 0.116979 0.091119 0.011077 1 0 +0.183385 0.12038 0.10588 0.0066955 1 0 +0.100627 0.181147 0.150607 0.00892321 1 0 +0.184063 0.182109 0.0222756 0.00492635 1 0 +0.269945 0.0508076 0.0970386 0.00613515 1 0 +0.223061 0.0442632 0.164099 0.00573653 1 0 +0.379559 0.149125 0.1674 0.00558254 1 0 +0.166691 0.0981379 0.126571 0.0102523 1 0 +0.146453 0.178477 0.0102732 0.00546206 1 0 +0.250081 0.139208 0.105752 0.00666326 1 0 +0.0828624 0.049343 0.0991538 0.00917406 1 0 +0.114047 0.157075 0.0674288 0.00748147 1 0 +0.325864 0.0379841 0.102682 0.00760018 1 0 +0.0865448 0.0333339 0.154956 0.00674158 1 0 +0.179765 0.0194648 0.159028 0.00521305 1 0 +0.158754 0.0550893 0.0664386 0.00526478 1 0 +0.268519 0.0975019 0.126336 0.00843922 1 0 +0.0780719 0.0491939 0.0311838 0.00541201 1 0 +0.333234 0.187204 0.0596276 0.00554904 1 0 +0.209764 0.108087 0.146589 0.0067205 1 0 +0.184083 0.128664 0.130131 0.0123429 1 0 +0.286562 0.0698164 0.19439 0.0059234 1 0 +0.03 0.167223 0.158687 0.00535208 1 0 +0.0905275 0.0637841 0.115981 0.00517076 1 0 +0.0903216 0.0828469 0.0253702 0.00656234 1 0 +0.21 0.181115 0.0256308 0.00557701 1 0 +0.392997 0.123522 0.0881469 0.00713771 1 0 +0.27 0.177572 0.0390839 0.00548721 1 0 +0.341463 0.070823 0.130651 0.00521516 1 0 +0.0368654 0.0432709 0.0217789 0.00592252 1 0 +0.19 0.0188588 0.0323655 0.00515657 1 0 +0.11 0.0373125 0.019389 0.00609366 1 0 +0.102 0.0568128 0.166768 0.00737801 1 0 +0.37 0.16207 0.157379 0.0079496 1 0 +0.372113 0.105287 0.140051 0.00531965 1 0 +0.00599721 0.0650202 0.0947234 0.00597836 1 0 +0.24746 0.0529289 0.0668096 0.00629904 1 0 +0.0104065 0.136024 0.0294409 0.00654423 1 0 +0.231698 0.130363 0.18604 0.00628433 1 0 +0.29 0.0290446 0.044384 0.00754462 1 0 +0.028435 0.130973 0.0597217 0.00492464 1 0 +0.367429 0.109044 0.174486 0.00512261 1 0 +0.262766 0.0628471 0.0261988 0.00537886 1 0 +0.258736 0.100411 0.00488452 0.00494719 1 0 +0.321904 0.12017 0.085994 0.0113597 1 0 +0.262991 0.0494983 0.190873 0.00682598 1 0 +0.03 0.0189616 0.177748 0.00507591 1 0 +0.0587581 0.0997631 0.159554 0.00614663 1 0 +0.0638137 0.00656929 0.0414673 0.00611381 1 0 +0.11821 0.026267 0.0533042 0.00661779 1 0 +0.33 0.0415766 0.169184 0.005005 1 0 +0.345193 0.112954 0.163829 0.00498868 1 0 +0.392254 0.0472032 0.0473154 0.0054577 1 0 +0.0286494 0.11133 0.0760248 0.0049874 1 0 +0.27 0.0365696 0.0170355 0.00686145 1 0 +0.13948 0.0741076 0.165953 0.00537703 1 0 +0.152228 0.180271 0.0220904 0.00511481 1 0 +0.11 0.159652 0.175278 0.0053276 1 0 +0.130342 0.0749803 0.127891 0.00794283 1 0 +0.37 0.0455926 0.178018 0.007069 1 0 +0.174904 0.15232 0.159484 0.0097671 1 0 +0.258567 0.142183 0.0704392 0.00773136 1 0 +0.221933 0.0370084 0.0950801 0.00995903 1 0 +0.273527 0.0201031 0.0938819 0.00499655 1 0 +0.374264 0.12754 0.119256 0.00628468 1 0 +0.118483 0.012984 0.0645129 0.00630568 1 0 +0.241122 0.0152128 0.15513 0.00617623 1 0 +0.0291186 0.0337872 0.0429776 0.00617698 1 0 +0.333775 0.066065 0.0826432 0.00498637 1 0 +0.37 0.181074 0.0233665 0.00632907 1 0 +0.223202 0.18819 0.0923402 0.00498807 1 0 +0.346015 0.0269364 0.134661 0.00559914 1 0 +0.07 0.0416623 0.178629 0.00762019 1 0 +0.280236 0.0510122 0.119443 0.00670719 1 0 +0.261681 0.0470373 0.126408 0.005187 1 0 +0.307872 0.125585 0.172237 0.00807778 1 0 +0.37691 0.0493025 0.0547169 0.00512084 1 0 +0.199809 0.142591 0.11782 0.00520728 1 0 +0.290256 0.175235 0.122551 0.00533184 1 0 +0.359318 0.162337 0.0625626 0.00527138 1 0 +0.266254 0.130207 0.0276945 0.00581197 1 0 +0.216126 0.102205 0.136049 0.00568307 1 0 +0.305954 0.165733 0.085845 0.00559505 1 0 +0.194504 0.103429 0.179534 0.00548175 1 0 +0.0595778 0.17011 0.0454706 0.00547673 1 0 +0.120786 0.149805 0.0197906 0.00838019 1 0 +0.226249 0.0744244 0.115243 0.00828741 1 0 +0.229092 0.0811134 0.0322316 0.0060468 1 0 +0.0234179 0.155289 0.0264939 0.00512035 1 0 +0.0953025 0.0401542 0.182022 0.00642255 1 0 +0.24542 0.121912 0.0445354 0.0058618 1 0 +0.250948 0.153357 0.027401 0.00830815 1 0 +0.14512 0.0114577 0.184325 0.00537055 1 0 +0.229495 0.0740694 0.0408994 0.00512964 1 0 +0.245814 0.0900784 0.0454943 0.00532297 1 0 +0.3414 0.125404 0.0907135 0.00854917 1 0 +0.0809721 0.133603 0.142928 0.00715165 1 0 +0.01 0.0400683 0.175232 0.00512425 1 0 +0.175861 0.00960354 0.101807 0.0076149 1 0 +0.110409 0.0662879 0.0110968 0.00780684 1 0 +0.068644 0.126408 0.0158185 0.00551588 1 0 +0.341462 0.0416071 0.0919578 0.00625069 1 0 +0.237534 0.0419936 0.0999316 0.00501946 1 0 +0.0621255 0.0923219 0.0886774 0.0050362 1 0 +0.219184 0.0495255 0.0811933 0.00731089 1 0 +0.387963 0.0545049 0.0624941 0.00501702 1 0 +0.139508 0.0367064 0.0988393 0.00498963 1 0 +0.11 0.0189772 0.0326292 0.00511339 1 0 +0.266344 0.0950372 0.139461 0.00509116 1 0 +0.307471 0.185989 0.0714464 0.00500287 1 0 +0.181953 0.0950166 0.00545282 0.0055711 1 0 +0.118734 0.0115042 0.0312841 0.00512618 1 0 +0.15 0.160336 0.0231105 0.00551957 1 0 +0.22619 0.0202691 0.0185718 0.00623608 1 0 +0.276323 0.0724613 0.123032 0.00660369 1 0 +0.220569 0.076601 0.172806 0.00492155 1 0 +0.100232 0.131322 0.143208 0.00639902 1 0 +0.394782 0.0236983 0.13031 0.00492271 1 0 +0.382281 0.0185517 0.0169469 0.00592855 1 0 +0.22683 0.0322293 0.0166972 0.00511889 1 0 +0.0489981 0.170903 0.18261 0.0055178 1 0 +0.349467 0.075473 0.0104567 0.00518068 1 0 +0.139219 0.109415 0.0104712 0.00569116 1 0 +0.240757 0.104913 0.175124 0.00559638 1 0 +0.0937754 0.0174482 0.140284 0.00660599 1 0 +0.218027 0.187273 0.070854 0.00499785 1 0 +0.246405 0.0970869 0.0365274 0.00607323 1 0 +0.287901 0.18408 0.0332955 0.00647807 1 0 +0.376126 0.100972 0.0352068 0.00496434 1 0 +0.209984 0.155755 0.164863 0.00661049 1 0 +0.0273352 0.180617 0.179068 0.00577195 1 0 +0.175007 0.0219339 0.0183149 0.00505085 1 0 +0.0228989 0.0946957 0.170487 0.00554807 1 0 +0.0314103 0.0460342 0.165143 0.00751195 1 0 +0.370248 0.0450066 0.0410144 0.00626097 1 0 +0.27816 0.0123399 0.0452198 0.00530145 1 0 +0.39 0.176178 0.18115 0.00620133 1 0 +0.256466 0.186298 0.11359 0.00675823 1 0 +0.357651 0.140973 0.158994 0.00677486 1 0 +0.33 0.176801 0.161228 0.00494019 1 0 +0.28369 0.16306 0.0484567 0.00552614 1 0 +0.209807 0.0179606 0.135153 0.00640212 1 0 +0.374754 0.113029 0.0121099 0.00503982 1 0 +0.0743218 0.0220835 0.0127212 0.00599074 1 0 +0.18094 0.170539 0.128215 0.00762202 1 0 +0.09 0.0187735 0.176421 0.00634823 1 0 +0.05 0.181269 0.0284853 0.00514207 1 0 +0.382123 0.104338 0.155546 0.00499356 1 0 +0.32331 0.0201479 0.0853821 0.0060223 1 0 +0.21477 0.166049 0.0164699 0.00503424 1 0 +0.360868 0.0609557 0.111799 0.00616562 1 0 +0.18085 0.0321406 0.14269 0.00675333 1 0 +0.376028 0.1525 0.195405 0.00500279 1 0 +0.23225 0.024593 0.184328 0.00716327 1 0 +0.101793 0.10075 0.0728653 0.00600643 1 0 +0.12091 0.179599 0.0179687 0.00541848 1 0 +0.0640294 0.159891 0.0402461 0.00494685 1 0 +0.154054 0.185061 0.159621 0.00923332 1 0 +0.132175 0.0181216 0.17936 0.0067317 1 0 +0.23 0.180445 0.0248208 0.00535967 1 0 +0.11 0.15442 0.0350109 0.00917913 1 0 +0.156521 0.0697386 0.118669 0.00582222 1 0 +0.309131 0.137733 0.184422 0.00778363 1 0 +0.366573 0.021133 0.181724 0.00603386 1 0 +0.358072 0.127979 0.121924 0.005249 1 0 +0.12069 0.108055 0.166835 0.00967485 1 0 +0.35182 0.095704 0.174893 0.00547524 1 0 +0.27 0.167186 0.0407491 0.00494861 1 0 +0.13 0.0433101 0.031196 0.00669101 1 0 +0.0081316 0.173136 0.0422839 0.00506157 1 0 +0.122184 0.140332 0.0098268 0.00543885 1 0 +0.0236819 0.0581298 0.119657 0.0051633 1 0 +0.07 0.0351198 0.155468 0.00836856 1 0 +0.10544 0.111304 0.04461 0.00622339 1 0 +0.31127 0.0701473 0.114328 0.0058661 1 0 +0.354215 0.0480357 0.0842499 0.00633501 1 0 +0.0804859 0.0484113 0.171363 0.0068126 1 0 +0.172237 0.115855 0.106807 0.00537165 1 0 +0.0455084 0.160394 0.0412336 0.00577368 1 0 +0.202462 0.0695508 0.160314 0.00511081 1 0 +0.127363 0.189716 0.0842867 0.00989146 1 0 +0.0967372 0.10246 0.175354 0.00649448 1 0 +0.29834 0.054986 0.0621569 0.00507099 1 0 +0.339449 0.0122872 0.0219697 0.00582351 1 0 +0.339266 0.172422 0.0589719 0.00640596 1 0 +0.33 0.0206983 0.181778 0.00636567 1 0 +0.266732 0.100053 0.0608677 0.00607784 1 0 +0.380859 0.0514983 0.1034 0.00560041 1 0 +0.335886 0.0528022 0.0844396 0.00499071 1 0 +0.35 0.0212422 0.0391845 0.00539966 1 0 +0.381987 0.173518 0.0456676 0.00511331 1 0 +0.271273 0.161918 0.0586698 0.00555117 1 0 +0.0925863 0.183631 0.132173 0.00543901 1 0 +0.258335 0.12838 0.125804 0.00532049 1 0 +0.332545 0.139745 0.1934 0.00566671 1 0 +0.269576 0.0853788 0.0088008 0.00833053 1 0 +0.230941 0.017388 0.16918 0.00554991 1 0 +0.339962 0.0828962 0.156992 0.00606685 1 0 +0.289594 0.099299 0.0979231 0.0057516 1 0 +0.140955 0.193737 0.0954806 0.00640935 1 0 +0.118922 0.195137 0.118187 0.00530406 1 0 +0.0591231 0.0998853 0.0219789 0.00663882 1 0 +0.319005 0.15718 0.158883 0.00699831 1 0 +0.127877 0.155594 0.057736 0.00769139 1 0 +0.318294 0.16287 0.129378 0.0064074 1 0 +0.36565 0.0218976 0.0162911 0.00645217 1 0 +0.00566143 0.076938 0.179819 0.00541591 1 0 +0.293948 0.0438732 0.017724 0.00529041 1 0 +0.0624557 0.0779759 0.0326174 0.00502421 1 0 +0.376266 0.00748401 0.0779648 0.00547678 1 0 +0.0682995 0.172801 0.154954 0.00740985 1 0 +0.0594805 0.127945 0.0586856 0.00525666 1 0 +0.347452 0.0663356 0.119742 0.0069306 1 0 +0.184045 0.0231649 0.0428077 0.00507048 1 0 +0.316409 0.118177 0.0351041 0.0052505 1 0 +0.351999 0.141379 0.092419 0.00731385 1 0 +0.09 0.0212043 0.159808 0.00506732 1 0 +0.0585221 0.017857 0.0399701 0.00578099 1 0 +0.155197 0.00481838 0.142725 0.00492107 1 0 +0.30678 0.0953303 0.0300757 0.00624598 1 0 +0.393444 0.136023 0.0439173 0.00510526 1 0 +0.125353 0.0507762 0.110233 0.00638261 1 0 +0.351042 0.145311 0.0675031 0.00682948 1 0 +0.254195 0.0381235 0.0413503 0.00511698 1 0 +0.01 0.180899 0.0322408 0.00495998 1 0 +0.0483639 0.0473283 0.0625009 0.00500291 1 0 +0.194708 0.0966212 0.170253 0.00499734 1 0 +0.187264 0.183601 0.170186 0.00542055 1 0 +0.222129 0.115037 0.148178 0.00643828 1 0 +0.0430709 0.0295178 0.149118 0.0066055 1 0 +0.128507 0.0100832 0.0801202 0.00561299 1 0 +0.233596 0.122146 0.0371903 0.00519093 1 0 +0.0971237 0.130173 0.0772085 0.00719146 1 0 +0.00891847 0.0214366 0.052843 0.00603167 1 0 +0.333253 0.0299159 0.0869719 0.00556045 1 0 +0.139007 0.146844 0.179856 0.00804221 1 0 +0.0889269 0.120896 0.17275 0.0069551 1 0 +0.076424 0.0383375 0.0433011 0.00610034 1 0 +0.115177 0.0947907 0.177942 0.00848365 1 0 +0.0519639 0.0337147 0.182047 0.00495052 1 0 +0.280811 0.147314 0.124882 0.00644796 1 0 +0.175351 0.0993935 0.0629356 0.00616285 1 0 +0.232532 0.140507 0.00982939 0.00553772 1 0 +0.3443 0.0707592 0.0655399 0.00521791 1 0 +0.148259 0.169095 0.147212 0.005276 1 0 +0.0806145 0.0696028 0.148441 0.00697314 1 0 +0.377057 0.0938253 0.0614691 0.00526754 1 0 +0.176727 0.163044 0.0167244 0.00534095 1 0 +0.3747 0.183974 0.167391 0.00517088 1 0 +0.116467 0.129337 0.00737408 0.00584774 1 0 +0.265312 0.0469076 0.162889 0.00895888 1 0 +0.210312 0.136884 0.0516481 0.0050044 1 0 +0.382313 0.188611 0.0781563 0.00508364 1 0 +0.256426 0.156039 0.0443755 0.00729046 1 0 +0.110251 0.153492 0.110863 0.00841988 1 0 +0.153164 0.18907 0.0510826 0.00505197 1 0 +0.135832 0.105832 0.171815 0.00641906 1 0 +0.215764 0.0305541 0.0723022 0.00525438 1 0 +0.310033 0.142274 0.171375 0.00606043 1 0 +0.15 0.164059 0.0410785 0.00606329 1 0 +0.372926 0.0870483 0.194764 0.00526985 1 0 +0.277151 0.166751 0.184336 0.00497332 1 0 +0.233981 0.116093 0.174304 0.00507903 1 0 +0.170618 0.0208526 0.19461 0.00533624 1 0 +0.31 0.176127 0.0200096 0.00540617 1 0 +0.101048 0.0762601 0.0845436 0.00718604 1 0 +0.0542891 0.0249088 0.109028 0.00805957 1 0 +0.124952 0.117632 0.0917484 0.00791336 1 0 +0.347463 0.0241088 0.106902 0.00563985 1 0 +0.0329361 0.150373 0.120633 0.00579599 1 0 +0.0245338 0.0119199 0.158341 0.00647275 1 0 +0.172233 0.146717 0.0576079 0.00512017 1 0 +0.0883143 0.156751 0.100443 0.00659294 1 0 +0.214205 0.160449 0.179897 0.00492494 1 0 +0.135415 0.0877608 0.169698 0.00815181 1 0 +0.170844 0.0282051 0.128725 0.00611538 1 0 +0.153428 0.110489 0.144807 0.00597814 1 0 +0.193851 0.0220132 0.0994787 0.00552583 1 0 +0.323255 0.167198 0.0474381 0.00795909 1 0 +0.179707 0.164925 0.0747548 0.005482 1 0 +0.0511664 0.13624 0.0541774 0.00719237 1 0 +0.338068 0.176277 0.153188 0.00581013 1 0 +0.364839 0.0856002 0.0571979 0.00492247 1 0 +0.245009 0.190734 0.148366 0.00500709 1 0 +0.208114 0.0832033 0.0596652 0.00637513 1 0 +0.295831 0.116129 0.0184326 0.0056183 1 0 +0.34496 0.165245 0.132476 0.00507771 1 0 +0.0531677 0.18774 0.096376 0.00534642 1 0 +0.382862 0.132041 0.0397941 0.00514877 1 0 +0.322868 0.132797 0.0297669 0.00680391 1 0 +0.345811 0.139817 0.0350729 0.00615701 1 0 +0.0995122 0.174468 0.0147702 0.00587915 1 0 +0.24042 0.0930751 0.0560819 0.0061489 1 0 +0.35639 0.0526969 0.14479 0.00524043 1 0 +0.288497 0.168296 0.150794 0.0110711 1 0 +0.337262 0.163029 0.0517847 0.00558953 1 0 +0.261944 0.0256295 0.116649 0.00566127 1 0 +0.251957 0.095516 0.0101884 0.0049549 1 0 +0.0698836 0.0221234 0.0433974 0.00682977 1 0 +0.0137647 0.149326 0.195047 0.00556836 1 0 +0.250432 0.074121 0.109003 0.00821935 1 0 +0.179564 0.047218 0.171751 0.006094 1 0 +0.0331699 0.0224626 0.0413483 0.00523962 1 0 +0.329789 0.137961 0.0388322 0.00571604 1 0 +0.249914 0.140583 0.151655 0.00499878 1 0 +0.319055 0.0264271 0.106152 0.0062552 1 0 +0.0386856 0.0573807 0.156485 0.00602484 1 0 +0.35 0.177304 0.0190771 0.00651221 1 0 +0.255732 0.0438077 0.179543 0.00496818 1 0 +0.23 0.01902 0.0359562 0.00600114 1 0 +0.29 0.0182661 0.035311 0.00630612 1 0 +0.190535 0.0462154 0.167995 0.00554567 1 0 +0.226768 0.173457 0.0439585 0.00508207 1 0 +0.195773 0.086384 0.0930442 0.00811178 1 0 +0.25161 0.0879304 0.126099 0.0067339 1 0 +0.244441 0.0160123 0.172747 0.00493063 1 0 +0.043296 0.151548 0.0918601 0.00625959 1 0 +0.307593 0.0272495 0.0769788 0.0051061 1 0 +0.00725937 0.181249 0.160883 0.00619715 1 0 +0.175231 0.00533157 0.147991 0.00552298 1 0 +0.0631338 0.0584774 0.0477833 0.00496594 1 0 +0.0472304 0.0284223 0.0444217 0.00620969 1 0 +0.0937202 0.0200306 0.00855072 0.00585216 1 0 +0.00876345 0.191816 0.153383 0.00684825 1 0 +0.317627 0.0683682 0.0252238 0.00535805 1 0 +0.0717525 0.130556 0.107098 0.00817232 1 0 +0.146068 0.0287704 0.0437635 0.00509176 1 0 +0.274603 0.0963645 0.03542 0.00537813 1 0 +0.190315 0.0552909 0.0503652 0.00498143 1 0 +0.34227 0.0424943 0.128558 0.00680922 1 0 +0.224546 0.0717756 0.0894152 0.0052022 1 0 +0.16485 0.144163 0.116683 0.00601526 1 0 +0.31 0.0264071 0.159299 0.00508062 1 0 +0.337475 0.0525507 0.117738 0.00655369 1 0 +0.223739 0.0170824 0.0614024 0.00560669 1 0 +0.299231 0.0440644 0.161454 0.00647538 1 0 +0.0335832 0.0789404 0.0370472 0.00503675 1 0 +0.167133 0.07712 0.119504 0.00701539 1 0 +0.222646 0.152381 0.0815839 0.00666112 1 0 +0.256102 0.122997 0.109313 0.00494815 1 0 +0.217144 0.136513 0.0915481 0.0051836 1 0 +0.248134 0.0112451 0.0967474 0.00654313 1 0 +0.13 0.024322 0.0192746 0.00572495 1 0 +0.269567 0.00820065 0.0760283 0.00789579 1 0 +0.221619 0.0680395 0.0552225 0.00679536 1 0 +0.33895 0.13243 0.132953 0.00507055 1 0 +0.119456 0.0226494 0.183848 0.00514542 1 0 +0.31 0.16474 0.156743 0.00495294 1 0 +0.333612 0.104095 0.0213189 0.0057855 1 0 +0.157879 0.174185 0.130036 0.00890416 1 0 +0.300888 0.122424 0.0414241 0.00732578 1 0 +0.365243 0.103443 0.182958 0.00526612 1 0 +0.052821 0.0599626 0.150999 0.00601089 1 0 +0.389875 0.0408276 0.0233581 0.00608927 1 0 +0.00600313 0.18337 0.178389 0.00501887 1 0 +0.34897 0.111007 0.128003 0.00550693 1 0 +0.294398 0.161156 0.0182559 0.00573325 1 0 +0.181712 0.0226184 0.108846 0.00628206 1 0 +0.232003 0.0810735 0.0908776 0.00680589 1 0 +0.192502 0.0130733 0.0573592 0.00506112 1 0 +0.0286125 0.0500802 0.0806136 0.00523027 1 0 +0.0493994 0.121428 0.149163 0.00518747 1 0 +0.08476 0.158288 0.0380256 0.00497445 1 0 +0.0951523 0.159668 0.111227 0.0065057 1 0 +0.112207 0.191503 0.168551 0.00718012 1 0 +0.114836 0.191245 0.149378 0.00508199 1 0 +0.0904455 0.160321 0.133842 0.00686734 1 0 +0.118465 0.0969585 0.152407 0.00528396 1 0 +0.325616 0.136625 0.131179 0.00570646 1 0 +0.170373 0.171284 0.0552724 0.00506681 1 0 +0.279831 0.0253967 0.0541884 0.00539711 1 0 +0.204186 0.100462 0.0951556 0.00604524 1 0 +0.241027 0.140553 0.188586 0.00632563 1 0 +0.01 0.0305452 0.158786 0.00503532 1 0 +0.154831 0.106833 0.0213084 0.00502078 1 0 +0.356808 0.00512252 0.0769753 0.00500051 1 0 +0.148342 0.0586842 0.18959 0.0057163 1 0 +0.171288 0.0323468 0.182402 0.00533673 1 0 +0.277129 0.149936 0.137827 0.00562111 1 0 +0.172076 0.136966 0.111224 0.00555198 1 0 +0.285579 0.118203 0.066372 0.00625782 1 0 +0.0164121 0.194575 0.0894871 0.00544476 1 0 +0.375279 0.142649 0.0228584 0.00808403 1 0 +0.15 0.0391444 0.176967 0.00523655 1 0 +0.154845 0.0844059 0.0919995 0.00855174 1 0 +0.114847 0.0530955 0.17119 0.00507901 1 0 +0.161215 0.0463565 0.158803 0.00658422 1 0 +0.244294 0.0749789 0.127429 0.00693151 1 0 +0.201621 0.169863 0.056274 0.00539321 1 0 +0.115581 0.0706966 0.056733 0.00508092 1 0 +0.106464 0.112311 0.0671209 0.00524916 1 0 +0.291234 0.0553339 0.0958209 0.00526472 1 0 +0.316176 0.00764799 0.0855426 0.0052024 1 0 +0.275018 0.050031 0.0102281 0.0060469 1 0 +0.150034 0.0206415 0.178561 0.0061308 1 0 +0.263767 0.191992 0.0760477 0.00525599 1 0 +0.130293 0.116906 0.0351914 0.00604257 1 0 +0.186688 0.0872507 0.0579731 0.0061373 1 0 +0.230104 0.106871 0.03155 0.00613509 1 0 +0.173996 0.0709171 0.0506331 0.00512285 1 0 +0.0207845 0.0177262 0.0390978 0.0052981 1 0 +0.0211481 0.0258574 0.0156478 0.00498216 1 0 +0.332627 0.115789 0.15882 0.00579958 1 0 +0.263268 0.157899 0.0664981 0.00551224 1 0 +0.337952 0.0433085 0.15956 0.006886 1 0 +0.34815 0.131308 0.0763117 0.00704923 1 0 +0.115767 0.0923186 0.0853965 0.00514234 1 0 +0.39 0.0189152 0.0358037 0.00601733 1 0 +0.136347 0.131356 0.149812 0.00898847 1 0 +0.34661 0.147226 0.136929 0.00586783 1 0 +0.295703 0.0581534 0.0112684 0.00518624 1 0 +0.0870268 0.00678368 0.0133139 0.00534889 1 0 +0.047278 0.0610762 0.0980137 0.0060369 1 0 +0.178609 0.136398 0.0584243 0.0056634 1 0 +0.202349 0.1576 0.189478 0.00649183 1 0 +0.270943 0.132336 0.191526 0.00832911 1 0 +0.110306 0.122519 0.0741579 0.00656935 1 0 +0.114864 0.0526981 0.143973 0.00623323 1 0 +0.293011 0.0684381 0.183414 0.00565701 1 0 +0.274135 0.0932081 0.160943 0.00563774 1 0 +0.303815 0.140585 0.0694233 0.00626015 1 0 +0.302754 0.191723 0.0147281 0.00550898 1 0 +0.127051 0.00535971 0.111888 0.0055462 1 0 +0.16405 0.0356627 0.0568418 0.00542532 1 0 +0.216114 0.15051 0.19106 0.00731595 1 0 +0.0585163 0.0784101 0.193673 0.00501427 1 0 +0.164093 0.159871 0.117253 0.00903389 1 0 +0.171427 0.150318 0.145285 0.00498805 1 0 +0.01 0.178751 0.0212145 0.00593001 1 0 +0.126596 0.135693 0.0659915 0.00700331 1 0 +0.142394 0.0700104 0.010219 0.00549211 1 0 +0.28283 0.0597229 0.012684 0.00496416 1 0 +0.346125 0.065843 0.0811333 0.00549911 1 0 +0.0192994 0.155884 0.0432481 0.00504566 1 0 +0.0620351 0.177468 0.141743 0.00507261 1 0 +0.395852 0.0603702 0.179532 0.00498008 1 0 +0.196962 0.184654 0.0324529 0.0051657 1 0 +0.279714 0.0566011 0.19426 0.005438 1 0 +0.33 0.0204775 0.0218146 0.00605239 1 0 +0.166458 0.103195 0.147391 0.00591854 1 0 +0.0617074 0.043718 0.0241343 0.00501687 1 0 +0.193501 0.0107412 0.111082 0.00846357 1 0 +0.196351 0.0464952 0.106671 0.00548262 1 0 +0.075906 0.0671244 0.160934 0.00537679 1 0 +0.309361 0.00933187 0.0990245 0.0052889 1 0 +0.0627181 0.0634413 0.168156 0.00501112 1 0 +0.046994 0.112873 0.0364355 0.00532616 1 0 +0.183407 0.0707565 0.00836969 0.00530652 1 0 +0.232014 0.188669 0.181532 0.00507663 1 0 +0.0555723 0.144624 0.121058 0.00569052 1 0 +0.0343206 0.0954366 0.0503161 0.0050001 1 0 +0.0290338 0.173999 0.187396 0.00492787 1 0 +0.309574 0.0839854 0.160007 0.00514783 1 0 +0.0969705 0.169712 0.184873 0.00518084 1 0 +0.0658485 0.150003 0.179707 0.0062944 1 0 +0.108433 0.119435 0.163223 0.00507743 1 0 +0.206247 0.0766513 0.105902 0.0066949 1 0 +0.0864436 0.0643843 0.103629 0.00657068 1 0 +0.182244 0.133136 0.104595 0.00617659 1 0 +0.0471952 0.00624242 0.0945309 0.00649479 1 0 +0.0527607 0.0109981 0.11591 0.00611499 1 0 +0.10993 0.119343 0.0931493 0.0072709 1 0 +0.103207 0.0969803 0.129359 0.00654085 1 0 +0.170271 0.0187429 0.167282 0.00512471 1 0 +0.164726 0.0409384 0.179983 0.00554499 1 0 +0.326465 0.0283705 0.135593 0.00524226 1 0 +0.140623 0.0711734 0.0772951 0.00581126 1 0 +0.0850976 0.191205 0.0768463 0.00685597 1 0 +0.09 0.183533 0.0269557 0.00709967 1 0 +0.375296 0.139669 0.0715155 0.00536797 1 0 +0.156343 0.119418 0.0174718 0.00496351 1 0 +0.201745 0.155548 0.03555 0.00549744 1 0 +0.283227 0.187762 0.109832 0.00782879 1 0 +0.0651253 0.0846026 0.00611225 0.00671016 1 0 +0.165103 0.164994 0.0433823 0.00517184 1 0 +0.230469 0.142552 0.0262646 0.00565048 1 0 +0.0644654 0.0126289 0.0524089 0.00567865 1 0 +0.193453 0.160545 0.0700145 0.00542249 1 0 +0.169417 0.181557 0.0684874 0.00516442 1 0 +0.334088 0.127733 0.102483 0.00550088 1 0 +0.0956108 0.121131 0.123297 0.00975789 1 0 +0.123709 0.127416 0.188492 0.00539229 1 0 +0.0979571 0.108096 0.156332 0.00547353 1 0 +0.251707 0.016391 0.19019 0.00624543 1 0 +0.0661633 0.179022 0.041344 0.00492435 1 0 +0.355416 0.193746 0.0841065 0.00589224 1 0 +0.347893 0.18288 0.0297822 0.00510758 1 0 +0.136844 0.0199226 0.083017 0.00534729 1 0 +0.39235 0.147579 0.183273 0.00580378 1 0 +0.01 0.0411491 0.0267012 0.00533574 1 0 +0.0588663 0.13177 0.102265 0.00539944 1 0 +0.0978903 0.11469 0.0541935 0.00643746 1 0 +0.308283 0.122379 0.18741 0.00743573 1 0 +0.381485 0.00477065 0.0532761 0.0053672 1 0 +0.274681 0.123917 0.0450574 0.00494249 1 0 +0.274508 0.141622 0.0266256 0.00580575 1 0 +0.170151 0.0674314 0.143951 0.00518518 1 0 +0.158682 0.0638484 0.15911 0.0051452 1 0 +0.378616 0.181401 0.180389 0.00548654 1 0 +0.0459767 0.150753 0.0466611 0.00506987 1 0 +0.0454381 0.151814 0.0341858 0.00532984 1 0 +0.188361 0.0534292 0.0140177 0.00568027 1 0 +0.217714 0.125165 0.0343887 0.00503698 1 0 +0.110836 0.126499 0.0383373 0.00694862 1 0 +0.096231 0.130024 0.0342919 0.0058512 1 0 +0.201951 0.139456 0.0361176 0.00511319 1 0 +0.191894 0.0976474 0.14744 0.00647568 1 0 +0.35 0.171579 0.181703 0.00547433 1 0 +0.30885 0.0795745 0.0344666 0.00514951 1 0 +0.296265 0.116872 0.0586386 0.00494227 1 0 +0.314284 0.103333 0.0673027 0.00555231 1 0 +0.092611 0.0159843 0.19321 0.0053434 1 0 +0.13 0.0210197 0.163043 0.00513412 1 0 +0.027443 0.148809 0.189908 0.00511117 1 0 +0.121856 0.159182 0.118894 0.00508099 1 0 +0.156883 0.181267 0.0743892 0.0062106 1 0 +0.363206 0.0564425 0.0982633 0.00501058 1 0 +0.00889184 0.161165 0.0418842 0.00670472 1 0 +0.39 0.156352 0.032948 0.00717421 1 0 +0.196193 0.191986 0.0554252 0.00542604 1 0 +0.212932 0.0369344 0.0594619 0.00530686 1 0 +0.246057 0.0820164 0.0902824 0.00684233 1 0 +0.262212 0.194978 0.0528194 0.005386 1 0 +0.349212 0.161169 0.102484 0.00696689 1 0 +0.0212278 0.053785 0.165676 0.00526682 1 0 +0.25 0.0222123 0.160308 0.00595556 1 0 +0.13 0.0338003 0.0415081 0.00571234 1 0 +0.251398 0.0134418 0.052878 0.00555353 1 0 +0.283035 0.0380155 0.017362 0.00527007 1 0 +0.256399 0.00663239 0.0405731 0.00536133 1 0 +0.277872 0.0151422 0.0301644 0.00501034 1 0 +0.29 0.0331873 0.156387 0.00535195 1 0 +0.310051 0.159968 0.0644506 0.00626058 1 0 +0.23 0.0400195 0.0252136 0.00494321 1 0 +0.00597915 0.192857 0.113782 0.00614966 1 0 +0.26478 0.0856209 0.0621084 0.0058759 1 0 +0.170888 0.0249568 0.149919 0.00528423 1 0 +0.0862489 0.178614 0.156334 0.00675943 1 0 +0.0765856 0.148868 0.166939 0.00690831 1 0 +0.0769549 0.152726 0.14279 0.00842565 1 0 +0.374428 0.101105 0.0515387 0.00506034 1 0 +0.208821 0.0315649 0.0177298 0.00519243 1 0 +0.213451 0.0158765 0.0324657 0.00576198 1 0 +0.2004 0.0441061 0.0243762 0.00519107 1 0 +0.21 0.0282458 0.0431743 0.00602494 1 0 +0.258037 0.0375442 0.0171449 0.00503405 1 0 +0.13 0.0397069 0.163478 0.00538679 1 0 +0.341736 0.0212705 0.157989 0.00494933 1 0 +0.33 0.0107095 0.169753 0.00926678 1 0 +0.39 0.0244424 0.159316 0.00565326 1 0 +0.123273 0.184883 0.0328546 0.00550323 1 0 +0.0582003 0.154851 0.0294708 0.00526422 1 0 +0.0687158 0.163556 0.0197289 0.0049326 1 0 +0.343047 0.152234 0.0418529 0.00666205 1 0 +0.260138 0.181753 0.0392608 0.00496383 1 0 +0.323838 0.181046 0.0401489 0.00548408 1 0 +0.39 0.17758 0.03934 0.00564262 1 0 +0.0114031 0.169948 0.157271 0.00536005 1 0 +0.105449 0.182977 0.175277 0.00503166 1 0 +0.181274 0.184416 0.182946 0.0067919 1 0 +0.17 0.174714 0.158959 0.00562471 1 0 +0.243437 0.155565 0.17436 0.0054662 1 0 +0.198594 0.177974 0.183018 0.00533083 1 0 +0.357939 0.155902 0.154586 0.00588195 1 0 +0.0678736 0.0194877 0.193962 0.00587428 1 0 +0.261094 0.031613 0.143196 0.00641111 1 0 +0.0544616 0.0115973 0.103615 0.00631154 1 0 +0.300243 0.18462 0.180876 0.00679718 1 0 +0.381482 0.00919082 0.15216 0.00582408 1 0 +0.3597 0.172902 0.127903 0.00513018 1 0 +0.27607 0.152288 0.115059 0.00497727 1 0 +0.33 0.165643 0.156947 0.00701088 1 0 +0.168644 0.0373118 0.1599 0.00517157 1 0 +0.110805 0.0247741 0.0426208 0.00646617 1 0 +0.277394 0.0310717 0.04549 0.00527087 1 0 +0.370097 0.00686026 0.142097 0.00622595 1 0 +0.10914 0.070801 0.0234014 0.00536059 1 0 +0.062817 0.0164829 0.177108 0.00493717 1 0 +0.340361 0.121672 0.136124 0.00623336 1 0 +0.177069 0.166193 0.116547 0.00541707 1 0 +0.0717111 0.0222557 0.159741 0.00529445 1 0 +0.173048 0.126401 0.105637 0.00526965 1 0 +0.370588 0.141092 0.00823424 0.00735295 1 0 +0.311732 0.112762 0.10386 0.00566651 1 0 +0.224861 0.0108757 0.0111513 0.00580825 1 0 +0.282403 0.0378644 0.150256 0.00501103 1 0 +0.183624 0.0128695 0.0433923 0.00525007 1 0 +0.342352 0.149326 0.0994858 0.00704412 1 0 +0.23 0.164717 0.0399481 0.00506231 1 0 +0.342001 0.179746 0.00588706 0.0062753 1 0 +0.198251 0.0879786 0.0521409 0.00683441 1 0 +0.0955366 0.15961 0.122925 0.00519878 1 0 +0.00593014 0.161319 0.084341 0.00603019 1 0 +0.18029 0.154792 0.145996 0.00496599 1 0 +0.0281417 0.143236 0.173569 0.0049881 1 0 +0.352748 0.152499 0.0343066 0.00563147 1 0 +0.260024 0.10054 0.0972566 0.00498755 1 0 +0.159265 0.0614676 0.177132 0.00496797 1 0 +0.273013 0.066809 0.168266 0.00526 1 0 +0.0961053 0.158912 0.0425576 0.00541757 1 0 +0.38805 0.112274 0.0864649 0.00526447 1 0 +0.264119 0.0605599 0.0966643 0.00523095 1 0 +0.329591 0.159137 0.176464 0.00586786 1 0 +0.0730028 0.0412287 0.106009 0.00531919 1 0 +0.264012 0.178833 0.14807 0.00573042 1 0 +0.263282 0.135521 0.013621 0.00547357 1 0 +0.0967876 0.145384 0.10407 0.00751144 1 0 +0.230225 0.160641 0.0228926 0.00528607 1 0 +0.325794 0.0266551 0.0951936 0.00597996 1 0 +0.149199 0.0800426 0.0786346 0.00659869 1 0 +0.238664 0.165512 0.184353 0.00509723 1 0 +0.21 0.0406293 0.1602 0.00757887 1 0 +0.187799 0.0417546 0.177593 0.00538602 1 0 +0.0331917 0.0228511 0.156774 0.0065044 1 0 +0.216288 0.0735893 0.0648644 0.00554062 1 0 +0.19795 0.00662434 0.163804 0.00522254 1 0 +0.332126 0.00415627 0.0198734 0.0051572 1 0 +0.205507 0.0201568 0.158537 0.00588187 1 0 +0.170897 0.173902 0.120927 0.00523435 1 0 +0.248516 0.014429 0.120122 0.005256 1 0 +0.0361242 0.15799 0.157262 0.00581867 1 0 +0.138548 0.147702 0.123506 0.00907352 1 0 +0.149799 0.0372451 0.151687 0.00499184 1 0 +0.177965 0.159118 0.180328 0.00514079 1 0 +0.392538 0.0189895 0.180817 0.00561277 1 0 +0.382243 0.101195 0.0750976 0.00609491 1 0 +0.0836357 0.0219441 0.00512935 0.00496743 1 0 +0.33 0.161926 0.0377196 0.00499244 1 0 +0.336211 0.177032 0.132754 0.00506622 1 0 +0.0532224 0.134385 0.114407 0.0055477 1 0 +0.276116 0.156167 0.163396 0.0058125 1 0 +0.0348003 0.115308 0.0677341 0.00607577 1 0 +0.0440233 0.146143 0.166868 0.00519442 1 0 +0.120917 0.0561351 0.0994865 0.00526409 1 0 +0.256449 0.107859 0.061902 0.00687425 1 0 +0.171845 0.0215487 0.117558 0.00692348 1 0 +0.255654 0.161876 0.0169731 0.00532026 1 0 +0.144031 0.154944 0.170114 0.00558662 1 0 +0.145005 0.0179794 0.0223569 0.00509841 1 0 +0.128038 0.0977233 0.174511 0.00514635 1 0 +0.201338 0.0257893 0.133051 0.00532102 1 0 +0.166681 0.100641 0.0706421 0.00550443 1 0 +0.12131 0.166423 0.0453309 0.00579703 1 0 +0.0658001 0.154509 0.11645 0.00642682 1 0 +0.0572581 0.165887 0.155183 0.0056194 1 0 +0.187662 0.191443 0.00509992 0.00542144 1 0 +0.0944134 0.0383697 0.0973631 0.0068424 1 0 +0.318418 0.111156 0.144915 0.00537137 1 0 +0.286851 0.123289 0.175289 0.00521646 1 0 +0.161594 0.113297 0.134391 0.00755107 1 0 +0.18948 0.156254 0.0181854 0.00526632 1 0 +0.177931 0.155843 0.0650242 0.00562178 1 0 +0.100584 0.0462843 0.173604 0.00525411 1 0 +0.169914 0.139955 0.1501 0.00653871 1 0 +0.263616 0.116388 0.0769037 0.00648812 1 0 +0.31668 0.128179 0.105431 0.00518582 1 0 +0.100492 0.0735251 0.0144766 0.00492659 1 0 +0.132923 0.17577 0.18249 0.00547233 1 0 +0.34078 0.0083426 0.186336 0.00818907 1 0 +0.29936 0.142034 0.0951274 0.00620868 1 0 +0.269367 0.0277092 0.18182 0.00525473 1 0 +0.325954 0.0773823 0.00821037 0.00871461 1 0 +0.385832 0.013629 0.080827 0.0053703 1 0 +0.271175 0.194405 0.138624 0.00629957 1 0 +0.176297 0.1553 0.0249634 0.00597416 1 0 +0.367395 0.155817 0.0259312 0.00650447 1 0 +0.242305 0.045509 0.129572 0.00581364 1 0 +0.170596 0.167333 0.189563 0.00681678 1 0 +0.143312 0.0364464 0.184318 0.0050612 1 0 +0.0838401 0.0723796 0.0732097 0.00542222 1 0 +0.164174 0.164756 0.146673 0.00878473 1 0 +0.343979 0.0134402 0.16495 0.00576487 1 0 +0.296169 0.0723779 0.0760541 0.00519839 1 0 +0.343016 0.131144 0.0620836 0.00527033 1 0 +0.176588 0.144532 0.0358948 0.0059744 1 0 +0.257508 0.0394345 0.133334 0.00567279 1 0 +0.0289996 0.142579 0.113386 0.00555155 1 0 +0.11092 0.182559 0.0602423 0.00608611 1 0 +0.0607705 0.0760141 0.076644 0.00607164 1 0 +0.16066 0.0425497 0.147777 0.00509363 1 0 +0.0715801 0.0833763 0.104049 0.00535127 1 0 +0.15 0.170787 0.157919 0.00570278 1 0 +0.327064 0.164185 0.0820805 0.00526258 1 0 +0.317055 0.15458 0.171205 0.00574498 1 0 +0.347806 0.153938 0.0778674 0.00703853 1 0 +0.293947 0.171232 0.133718 0.00556929 1 0 +0.156684 0.149419 0.111223 0.00512589 1 0 +0.252732 0.131396 0.0968162 0.00549874 1 0 +0.01425 0.0215658 0.0708055 0.00532287 1 0 +0.0763223 0.156665 0.176082 0.00511058 1 0 +0.124446 0.127437 0.039473 0.00674084 1 0 +0.359546 0.118236 0.0804413 0.00511047 1 0 +0.0887918 0.0346958 0.0417275 0.00539093 1 0 +0.177854 0.108789 0.142292 0.00537027 1 0 +0.0968535 0.0707884 0.111793 0.00515489 1 0 +0.302334 0.145584 0.0277289 0.00572278 1 0 +0.3148 0.0091965 0.159974 0.00610153 1 0 +0.0650404 0.077735 0.111273 0.00583579 1 0 +0.35 0.157852 0.167876 0.00587751 1 0 +0.0687925 0.0473 0.0986019 0.00505409 1 0 +0.351393 0.00584318 0.10956 0.00633544 1 0 +0.250902 0.0661362 0.0970678 0.00614813 1 0 +0.199256 0.151144 0.160893 0.00572317 1 0 +0.081642 0.174244 0.0457985 0.00526858 1 0 +0.21976 0.170596 0.149192 0.00673337 1 0 +0.310973 0.131476 0.0090823 0.00770685 1 0 +0.171225 0.0350769 0.148616 0.00492495 1 0 +0.0422254 0.0146582 0.108313 0.00714824 1 0 +0.25391 0.150461 0.103458 0.00533219 1 0 +0.328306 0.142198 0.15002 0.00511059 1 0 +0.382755 0.00781137 0.0192031 0.00505643 1 0 +0.127577 0.145161 0.167248 0.0062849 1 0 +0.0600214 0.130019 0.0487371 0.0049201 1 0 +0.110918 0.0619143 0.156475 0.00676531 1 0 +0.293273 0.158535 0.00771861 0.00518306 1 0 +0.1195 0.145898 0.0623842 0.0059389 1 0 +0.109317 0.0465481 0.165315 0.00531158 1 0 +0.315361 0.10605 0.0312039 0.007184 1 0 +0.0817801 0.153306 0.155881 0.00553843 1 0 +0.0487354 0.0470424 0.0517937 0.005316 1 0 +0.37 0.0372783 0.160129 0.0058242 1 0 +0.0778138 0.0743938 0.0561003 0.00531565 1 0 +0.346521 0.143338 0.049699 0.00569743 1 0 +0.307383 0.11418 0.156362 0.00575875 1 0 +0.277046 0.158534 0.144477 0.00524865 1 0 +0.13 0.0361391 0.180559 0.00578534 1 0 +0.206529 0.0269038 0.0694898 0.00506644 1 0 +0.358316 0.0430172 0.177113 0.00492916 1 0 +0.00654987 0.0696918 0.0295163 0.00614741 1 0 +0.0899527 0.0570072 0.172679 0.00604206 1 0 +0.202863 0.180004 0.154309 0.00552596 1 0 +0.148523 0.177151 0.140333 0.00532119 1 0 +0.13307 0.0630071 0.121302 0.00599325 1 0 +0.0780002 0.0448977 0.160222 0.00513026 1 0 +0.238688 0.0248954 0.150031 0.0050339 1 0 +0.33353 0.0754906 0.0249002 0.00582627 1 0 +0.256402 0.0357335 0.152655 0.00492271 1 0 +0.234174 0.0957673 0.0900119 0.00807268 1 0 +0.192198 0.127593 0.100147 0.00505887 1 0 +0.00825974 0.126987 0.0225671 0.00501073 1 0 +0.13 0.174395 0.159837 0.00492019 1 0 +0.367878 0.149816 0.162361 0.00544743 1 0 +0.274419 0.0773807 0.019342 0.00563982 1 0 +0.262616 0.0135154 0.193305 0.00545901 1 0 +0.306531 0.148053 0.0546813 0.00499252 1 0 +0.0517323 0.176959 0.0189973 0.00510163 1 0 +0.237788 0.0894483 0.0749374 0.00714378 1 0 +0.0893069 0.189382 0.152218 0.00516745 1 0 +0.0323866 0.126165 0.0357112 0.00522841 1 0 +0.314882 0.0714174 0.0349756 0.00500877 1 0 +0.33603 0.1587 0.0660504 0.00571842 1 0 +0.108816 0.151105 0.169317 0.00516 1 0 +0.364708 0.051628 0.167371 0.00626463 1 0 +0.100349 0.108523 0.130208 0.0053807 1 0 +0.170666 0.0892365 0.068069 0.0057705 1 0 +0.0999165 0.142379 0.0745268 0.00561466 1 0 +0.0597816 0.185221 0.027062 0.0055033 1 0 +0.238633 0.179517 0.0175771 0.005709 1 0 +0.107246 0.085266 0.131911 0.00559302 1 0 +0.0861326 0.0451846 0.187098 0.00520339 1 0 +0.0637139 0.192531 0.157391 0.00495527 1 0 +0.267139 0.069563 0.0327794 0.00499077 1 0 +0.0864614 0.191535 0.0401115 0.0049512 1 0 +0.0237336 0.120119 0.0736767 0.00535296 1 0 +0.211425 0.00508826 0.0340575 0.00523903 1 0 +0.0575627 0.0483748 0.151254 0.00577812 1 0 +0.243244 0.0831797 0.102024 0.00528776 1 0 +0.261577 0.0796649 0.114792 0.00550874 1 0 +0.103909 0.0607845 0.0205837 0.00494194 1 0 +0.227431 0.195448 0.0180965 0.00494513 1 0 +0.29699 0.120724 0.180025 0.00600489 1 0 +0.122431 0.0146929 0.166487 0.00531487 1 0 +0.356335 0.0460945 0.0299408 0.00548702 1 0 +0.25 0.165995 0.040633 0.0051361 1 0 +0.245868 0.116582 0.0693421 0.00872676 1 0 +0.215962 0.117685 0.0750916 0.0073751 1 0 +0.0934349 0.0583919 0.0966913 0.00495829 1 0 +0.359399 0.151389 0.059909 0.00510121 1 0 +0.259602 0.143109 0.0989046 0.00502089 1 0 +0.0356892 0.0457494 0.032632 0.00527195 1 0 +0.180834 0.0330256 0.1308 0.0051692 1 0 +0.0631825 0.193286 0.183238 0.00541475 1 0 +0.343546 0.167816 0.0445428 0.00512738 1 0 +0.239506 0.0748118 0.116467 0.00503154 1 0 +0.365153 0.133028 0.0180349 0.0054654 1 0 +0.214868 0.00513958 0.006055 0.00538041 1 0 +0.0779447 0.00933514 0.133271 0.00725011 1 0 +0.37 0.171148 0.0439746 0.00681272 1 0 +0.106816 0.139283 0.119261 0.00843925 1 0 +0.394734 0.0786798 0.128928 0.00549414 1 0 +0.096486 0.153221 0.187963 0.00829006 1 0 +0.17 0.156997 0.0352682 0.00551604 1 0 +0.0556346 0.033688 0.15095 0.0053515 1 0 +0.226596 0.0350846 0.043546 0.00590146 1 0 +0.0777909 0.165915 0.148506 0.00597243 1 0 +0.340627 0.165863 0.150643 0.00521091 1 0 +0.393511 0.111386 0.0591638 0.00504775 1 0 +0.324017 0.170214 0.108676 0.00527019 1 0 +0.278548 0.116772 0.191291 0.00493263 1 0 +0.208638 0.131575 0.0885691 0.00509302 1 0 +0.24394 0.127435 0.0543049 0.00545812 1 0 +0.233082 0.0215367 0.159692 0.00502445 1 0 +0.0802463 0.0952664 0.128303 0.00587113 1 0 +0.35373 0.142419 0.0794802 0.00578166 1 0 +0.332804 0.119654 0.0538804 0.00495888 1 0 +0.14254 0.0523675 0.0987686 0.00593462 1 0 +0.238221 0.0238557 0.0159596 0.005277 1 0 +0.276343 0.155965 0.0355368 0.00552434 1 0 +0.389898 0.166025 0.0423102 0.00628806 1 0 +0.20734 0.0934415 0.107873 0.00881958 1 0 +0.113326 0.0465527 0.155473 0.00531565 1 0 +0.287784 0.152427 0.0201663 0.0053834 1 0 +0.19 0.174441 0.0195105 0.00515748 1 0 +0.0933412 0.0662663 0.0868433 0.0056423 1 0 +0.0535527 0.170707 0.140558 0.00502638 1 0 +0.056345 0.0447936 0.167543 0.00543527 1 0 +0.319714 0.173203 0.0138602 0.00532904 1 0 +0.318993 0.159075 0.14688 0.00515332 1 0 +0.132172 0.073621 0.0140572 0.00541312 1 0 +0.186738 0.0355362 0.152613 0.00527402 1 0 +0.354687 0.148664 0.144741 0.00546032 1 0 +0.143956 0.0873215 0.111676 0.00507434 1 0 +0.33 0.0263341 0.0406133 0.00503598 1 0 +0.239281 0.184703 0.0268573 0.00494154 1 0 +0.317241 0.121443 0.147915 0.0054086 1 0 +0.0155774 0.155562 0.0334974 0.00539621 1 0 +0.0467048 0.164738 0.157204 0.0051868 1 0 +0.0907433 0.128642 0.136023 0.00580039 1 0 +0.226558 0.0050429 0.0680593 0.00546214 1 0 +0.160818 0.101567 0.0900302 0.00542622 1 0 +0.0578329 0.0527018 0.0826996 0.00535188 1 0 +0.190631 0.0849595 0.120363 0.00498892 1 0 +0.0855674 0.0739422 0.0906115 0.00557382 1 0 +0.079236 0.0838242 0.173243 0.00524543 1 0 +0.317096 0.134697 0.0196558 0.00492943 1 0 +0.22179 0.164076 0.0472665 0.005254 1 0 +0.035521 0.024448 0.141908 0.00500036 1 0 +0.121423 0.153796 0.0454467 0.00630561 1 0 +0.243375 0.157456 0.0401662 0.0056814 1 0 +0.216065 0.156221 0.0151389 0.00496757 1 0 +0.288644 0.161478 0.0391054 0.00517417 1 0 +0.305165 0.129215 0.093237 0.00602047 1 0 +0.326572 0.0931579 0.0556699 0.0057005 1 0 +0.142905 0.188128 0.00832213 0.00500349 1 0 +0.303122 0.183253 0.0234914 0.0050918 1 0 +0.0513195 0.131298 0.0421085 0.00585023 1 0 +0.137058 0.141451 0.159999 0.00536984 1 0 +0.257599 0.0941042 0.134262 0.00512517 1 0 +0.19656 0.0472216 0.181399 0.0050835 1 0 +0.133371 0.0855867 0.135726 0.00558747 1 0 +0.297211 0.148201 0.0460843 0.00513294 1 0 +0.27 0.18092 0.166627 0.00518641 1 0 +0.117472 0.0642168 0.142115 0.00572231 1 0 +0.37979 0.152412 0.0390155 0.0053394 1 0 +0.21 0.0393582 0.0384033 0.00606831 1 0 +0.227068 0.0301736 0.0720983 0.00605722 1 0 +0.341191 0.0251477 0.0454776 0.00610949 1 0 +0.364764 0.147722 0.152537 0.00496601 1 0 +0.331248 0.0630576 0.114729 0.00602514 1 0 +0.187503 0.160421 0.160779 0.00526709 1 0 +0.0607547 0.036431 0.111339 0.00504444 1 0 +0.0249341 0.140233 0.059008 0.00500066 1 0 +0.277753 0.0891442 0.0799665 0.00500209 1 0 +0.241637 0.138237 0.158558 0.00502118 1 0 +0.107164 0.192643 0.156784 0.00567281 1 0 +0.121535 0.112179 0.124726 0.00558203 1 0 +0.12679 0.109329 0.188589 0.00564646 1 0 +0.192212 0.116073 0.195068 0.00500692 1 0 +0.176887 0.14295 0.103954 0.00502218 1 0 +0.200576 0.118743 0.0119407 0.00519626 1 0 +0.179161 0.124561 0.0950849 0.00562769 1 0 +0.101414 0.125129 0.0662452 0.00561635 1 0 +0.252938 0.0644826 0.194418 0.00534798 1 0 +0.241464 0.0230279 0.194617 0.00567851 1 0 +0.14585 0.154364 0.0333299 0.0049201 1 0 +0.13 0.162097 0.15985 0.00629393 1 0 +0.374508 0.0444107 0.028399 0.00521957 1 0 +0.163322 0.111215 0.109167 0.00495191 1 0 +0.325752 0.186974 0.117146 0.00507565 1 0 +0.235053 0.112389 0.0399197 0.0050449 1 0 +0.310614 0.134246 0.0798435 0.00715402 1 0 +0.337052 0.175091 0.108946 0.00633609 1 0 +0.258904 0.122522 0.0117143 0.00533354 1 0 +0.119023 0.128715 0.105223 0.0094116 1 0 +0.0621116 0.0146283 0.00623177 0.00653622 1 0 +0.0110308 0.159897 0.123493 0.00517159 1 0 +0.106056 0.161993 0.0567978 0.00669773 1 0 +0.319037 0.128427 0.186393 0.00494375 1 0 +0.0707372 0.138259 0.1358 0.00492486 1 0 +0.0951466 0.0410084 0.194366 0.00577235 1 0 +0.215184 0.0511051 0.0949013 0.00567067 1 0 +0.152345 0.15892 0.128689 0.00738893 1 0 +0.116686 0.0767524 0.0309955 0.00507058 1 0 +0.208835 0.142381 0.170932 0.00500633 1 0 +0.0834147 0.087441 0.0911852 0.00614729 1 0 +0.113349 0.0109536 0.0221073 0.00516509 1 0 +0.00816041 0.155564 0.108356 0.00548171 1 0 +0.0962057 0.0661762 0.15883 0.0061964 1 0 +0.327568 0.116904 0.148792 0.00548791 1 0 +0.164068 0.082941 0.0800338 0.00662652 1 0 +0.244047 0.0375086 0.0431852 0.00521327 1 0 +0.141397 0.176393 0.154309 0.00518206 1 0 +0.178245 0.168578 0.0633801 0.00529997 1 0 +0.160227 0.051309 0.0342094 0.00494937 1 0 +0.170286 0.124796 0.116129 0.00569779 1 0 +0.203984 0.106266 0.184599 0.0049814 1 0 +0.325401 0.161488 0.0918087 0.00496851 1 0 +0.306247 0.00665273 0.089148 0.00540779 1 0 +0.316238 0.015265 0.0931219 0.0055432 1 0 +0.240079 0.145881 0.0296839 0.00507972 1 0 +0.32467 0.132036 0.0980336 0.00576958 1 0 +0.157623 0.132844 0.122606 0.00866231 1 0 +0.169955 0.15008 0.108074 0.00561139 1 0 +0.194824 0.187497 0.0649106 0.00515682 1 0 +0.239326 0.0150519 0.181313 0.00509233 1 0 +0.318191 0.159187 0.0564939 0.00514918 1 0 +0.0792881 0.016866 0.180201 0.00517011 1 0 +0.260323 0.0685592 0.11658 0.00542457 1 0 +0.239286 0.106852 0.0810619 0.00706377 1 0 +0.334289 0.0982624 0.0122789 0.00499393 1 0 +0.226025 0.118987 0.0279885 0.00713664 1 0 +0.344845 0.189664 0.0855549 0.00553181 1 0 +0.253551 0.0766101 0.0827654 0.00506928 1 0 +0.345822 0.188583 0.154599 0.00880407 1 0 +0.0827703 0.0235384 0.0445821 0.00618839 1 0 +0.333985 0.040954 0.0412785 0.00507434 1 0 +0.278721 0.0594964 0.0952742 0.00546562 1 0 +0.019205 0.0449667 0.0239296 0.00500779 1 0 +0.149741 0.117969 0.0247541 0.00497227 1 0 +0.148458 0.0655767 0.112763 0.00500424 1 0 +0.185581 0.113329 0.0951075 0.00636539 1 0 +0.314931 0.172481 0.184316 0.00538804 1 0 +0.151307 0.191604 0.0841679 0.00742714 1 0 +0.215391 0.0778268 0.0526149 0.00509487 1 0 +0.116938 0.0537562 0.0111887 0.00632439 1 0 +0.123704 0.145119 0.105583 0.0063281 1 0 +0.349979 0.189299 0.0221952 0.00504719 1 0 +0.373207 0.0786809 0.0262685 0.00511944 1 0 +0.119987 0.0826799 0.127211 0.00497848 1 0 +0.119432 0.0344412 0.044668 0.00533614 1 0 +0.125114 0.0259125 0.148706 0.00512049 1 0 +0.0491786 0.102561 0.165362 0.00540046 1 0 +0.187451 0.00754914 0.195216 0.00498253 1 0 +0.0993061 0.0379254 0.016514 0.00499695 1 0 +0.134012 0.118456 0.140878 0.00687643 1 0 +0.274864 0.191863 0.165327 0.00519948 1 0 +0.338764 0.184065 0.0196136 0.00661261 1 0 +0.30909 0.155887 0.1521 0.00508481 1 0 +0.281038 0.179616 0.0434301 0.00495262 1 0 +0.284824 0.0573723 0.0853284 0.00514923 1 0 +0.152 0.0776878 0.110776 0.0062575 1 0 +0.352751 0.0402944 0.0504634 0.00495409 1 0 +0.06202 0.039623 0.0415275 0.00515143 1 0 +0.253638 0.0493509 0.152362 0.00593247 1 0 +0.17658 0.177998 0.016944 0.00513947 1 0 +0.315916 0.152921 0.0712626 0.00516184 1 0 +0.222567 0.157874 0.0384202 0.00498412 1 0 +0.178055 0.0404681 0.180863 0.00497207 1 0 +0.0640356 0.136959 0.117493 0.00598804 1 0 +0.269722 0.170038 0.152649 0.00571176 1 0 +0.252802 0.16212 0.0986709 0.00499185 1 0 +0.209844 0.0545797 0.177965 0.00554082 1 0 +0.13029 0.0507768 0.0401549 0.00497506 1 0 +0.366953 0.146216 0.0774128 0.00517086 1 0 +0.371563 0.0342949 0.0441009 0.00496373 1 0 +0.27 0.178611 0.0224494 0.00494871 1 0 +0.26675 0.138843 0.061017 0.00518781 1 0 +0.114366 0.178677 0.155083 0.0057361 1 0 +0.221864 0.0366978 0.0793678 0.00501016 1 0 +0.207612 0.0444648 0.193214 0.00627639 1 0 +0.271776 0.149236 0.0896579 0.00512745 1 0 +0.121741 0.14519 0.0354793 0.00576319 1 0 +0.262546 0.0115259 0.0141798 0.00560513 1 0 +0.300685 0.155898 0.0352115 0.00504962 1 0 +0.174803 0.111176 0.0338426 0.00552079 1 0 +0.104673 0.128424 0.132813 0.00527037 1 0 +0.315444 0.160233 0.189164 0.00572812 1 0 +0.251209 0.129378 0.074338 0.00601193 1 0 +0.190451 0.192302 0.115137 0.00546215 1 0 +0.249307 0.185526 0.00612246 0.00502701 1 0 +0.203934 0.0225659 0.18315 0.0051549 1 0 +0.302241 0.100337 0.134276 0.00542858 1 0 +0.347415 0.0902788 0.136673 0.00554412 1 0 +0.0795558 0.105547 0.122701 0.00494732 1 0 +0.301311 0.0235448 0.154751 0.00513585 1 0 +0.114762 0.0984224 0.124566 0.00605229 1 0 +0.0258172 0.13008 0.0854701 0.00587416 1 0 +0.192188 0.0787302 0.129962 0.00526632 1 0 +0.24031 0.16392 0.0162384 0.00504816 1 0 +0.173767 0.182968 0.0343716 0.00503739 1 0 +0.187492 0.121202 0.145904 0.00543631 1 0 +0.121307 0.0911066 0.163532 0.00760362 1 0 +0.306121 0.039887 0.0508405 0.00586732 1 0 +0.0313969 0.187535 0.116287 0.00526618 1 0 +0.205244 0.0530181 0.00474848 0.00533448 1 0 +0.318555 0.0988328 0.162645 0.00544252 1 0 +0.384049 0.150213 0.18977 0.00506271 1 0 +0.35882 0.0705367 0.0071012 0.00591425 1 0 +0.374241 0.107337 0.150027 0.0050843 1 0 +0.0585332 0.133693 0.194195 0.00493436 1 0 +0.0855199 0.118215 0.184505 0.0055736 1 0 +0.158235 0.138137 0.19419 0.00609273 1 0 +0.122416 0.07642 0.139554 0.0062318 1 0 +0.00479918 0.192651 0.081544 0.00545332 1 0 +0.27634 0.123768 0.072765 0.00597458 1 0 +0.0486482 0.0469649 0.145052 0.00514093 1 0 +0.19 0.0254881 0.159743 0.00501905 1 0 +0.37864 0.120691 0.00630193 0.00533048 1 0 +0.25 0.162741 0.161173 0.0051858 1 0 +0.0566476 0.069124 0.110854 0.00507997 1 0 +0.0116925 0.0406675 0.11733 0.0050623 1 0 +0.315558 0.141102 0.0689741 0.00550287 1 0 +0.180223 0.0123022 0.113459 0.00511602 1 0 +0.273171 0.138287 0.0113356 0.00504578 1 0 +0.26461 0.0518817 0.0868252 0.00543732 1 0 +0.229094 0.159702 0.0881235 0.00508333 1 0 +0.26882 0.0938501 0.113402 0.00500452 1 0 +0.349178 0.0540905 0.119842 0.00543585 1 0 +0.0760557 0.0196645 0.0539054 0.00560242 1 0 +0.242801 0.116421 0.034328 0.00532604 1 0 +0.313923 0.155856 0.0894238 0.00559722 1 0 +0.195836 0.105589 0.190249 0.00495681 1 0 +0.0559161 0.179048 0.149599 0.00500992 1 0 +0.252497 0.141266 0.0333844 0.00527091 1 0 +0.0868643 0.111262 0.116764 0.0049587 1 0 +0.350233 0.0345982 0.092011 0.00497733 1 0 +0.09 0.0412077 0.171813 0.00512945 1 0 +0.155742 0.155361 0.0307641 0.00526499 1 0 +0.15503 0.153165 0.0171135 0.00496063 1 0 +0.275704 0.0855324 0.120332 0.0067578 1 0 +0.102093 0.142054 0.139593 0.00507751 1 0 +0.239529 0.0907062 0.0290642 0.00558211 1 0 +0.206284 0.164971 0.15529 0.00676775 1 0 +0.033003 0.0442111 0.152608 0.00525452 1 0 +0.0275063 0.0428424 0.176527 0.0049388 1 0 +0.35862 0.149303 0.170872 0.00662706 1 0 +0.07 0.0215284 0.0227742 0.00496596 1 0 +0.115516 0.132417 0.0702031 0.00529467 1 0 +0.366673 0.153534 0.191388 0.00523087 1 0 +0.0213304 0.141411 0.194224 0.00541128 1 0 +0.106137 0.148663 0.0220844 0.00548936 1 0 +0.295259 0.0650414 0.0597985 0.0057072 1 0 +0.116732 0.150019 0.00547719 0.0057373 1 0 +0.298718 0.00847115 0.0998693 0.00542173 1 0 +0.103477 0.0980706 0.184761 0.00544981 1 0 +0.380526 0.154388 0.0254918 0.00504119 1 0 +0.270214 0.0877797 0.0223453 0.00543992 1 0 +0.314709 0.146188 0.157199 0.00492299 1 0 +0.0183423 0.184847 0.028443 0.00502048 1 0 +0.0872812 0.109532 0.177678 0.00554028 1 0 +0.104323 0.10894 0.166694 0.00671663 1 0 +0.310986 0.115453 0.0435155 0.0051215 1 0 +0.261494 0.0451588 0.14497 0.00564139 1 0 +0.214052 0.0206624 0.0755293 0.00529037 1 0 +0.106893 0.081013 0.0946225 0.00539707 1 0 +0.298594 0.155871 0.148747 0.00506892 1 0 +0.2684 0.0265539 0.125613 0.00542403 1 0 +0.271924 0.155568 0.128731 0.00627654 1 0 +0.190981 0.0881231 0.1063 0.00609074 1 0 +0.317668 0.162075 0.0759067 0.00525105 1 0 +0.161501 0.138712 0.135025 0.00560976 1 0 +0.275306 0.11263 0.0685627 0.0056332 1 0 +0.224296 0.141754 0.0863415 0.00509894 1 0 +0.162671 0.187559 0.127827 0.00547326 1 0 +0.215382 0.0994359 0.0865149 0.00813389 1 0 +0.175097 0.141131 0.121027 0.00551912 1 0 +0.142482 0.0456714 0.17182 0.00515071 1 0 +0.0871426 0.193219 0.0885682 0.00521211 1 0 +0.1382 0.120316 0.0420877 0.00498942 1 0 +0.182786 0.0783669 0.0664189 0.0067264 1 0 +0.139911 0.136595 0.136115 0.00610351 1 0 +0.153271 0.127392 0.136792 0.00714609 1 0 +0.134296 0.0259236 0.153496 0.00523579 1 0 +0.177675 0.144073 0.138335 0.00625251 1 0 +0.307612 0.0216726 0.0937214 0.00521856 1 0 +0.23 0.179957 0.176114 0.0053792 1 0 +0.190162 0.128682 0.112774 0.00604757 1 0 +0.0763513 0.183133 0.0817355 0.00601091 1 0 +0.202471 0.162916 0.0429757 0.0049886 1 0 +0.059156 0.0903555 0.0147954 0.00529511 1 0 +0.0774759 0.0907105 0.00848086 0.0064719 1 0 +0.104679 0.12904 0.107042 0.00505079 1 0 +0.156928 0.0667936 0.168618 0.00496171 1 0 +0.109435 0.114802 0.0340654 0.00526307 1 0 +0.202898 0.0988148 0.144118 0.00507812 1 0 +0.247038 0.0932036 0.0948382 0.00527664 1 0 +0.25441 0.0812233 0.0986122 0.00498023 1 0 +0.207974 0.0236615 0.0530072 0.00501154 1 0 +0.216544 0.0188464 0.0440366 0.0054604 1 0 +0.347109 0.15848 0.157316 0.00508872 1 0 +0.275296 0.175117 0.141214 0.00660876 1 0 +0.00496755 0.1067 0.119988 0.00513157 1 0 +0.297911 0.040944 0.040722 0.00499771 1 0 +0.159434 0.0956141 0.0793437 0.00573121 1 0 +0.283499 0.191069 0.14746 0.0062051 1 0 +0.0369525 0.147064 0.159164 0.00530303 1 0 +0.22607 0.161718 0.14422 0.00523933 1 0 +0.108679 0.0368119 0.0413441 0.00582451 1 0 +0.160892 0.158663 0.1593 0.00561418 1 0 +0.117058 0.136609 0.0401125 0.0050545 1 0 +0.307358 0.147503 0.0894396 0.00502678 1 0 +0.245616 0.147308 0.0379248 0.0049501 1 0 +0.392621 0.0111457 0.151269 0.00552043 1 0 +0.236105 0.110368 0.0613037 0.00536382 1 0 +0.245302 0.0805854 0.0785322 0.0050188 1 0 +0.0652638 0.0836976 0.083807 0.00535354 1 0 +0.32297 0.0769884 0.0234433 0.00493859 1 0 +0.0138609 0.156448 0.0232398 0.0050417 1 0 +0.360794 0.0355947 0.0448732 0.00591051 1 0 +0.178974 0.0989185 0.137006 0.00588317 1 0 +0.175662 0.152784 0.0430227 0.00496919 1 0 +0.0770389 0.0916468 0.0998569 0.00500567 1 0 +0.130172 0.156197 0.173118 0.0064809 1 0 +0.357743 0.0473451 0.116656 0.00592238 1 0 +0.195747 0.0966667 0.101135 0.00497218 1 0 +0.00530248 0.149842 0.121771 0.00585836 1 0 +0.306338 0.116316 0.00953368 0.00781098 1 0 +0.244299 0.0236894 0.182913 0.00500193 1 0 +0.215106 0.0280928 0.153081 0.00542675 1 0 +0.361435 0.15433 0.070999 0.00655125 1 0 +0.0932397 0.190976 0.141447 0.00640936 1 0 +0.153466 0.0468423 0.0457411 0.00518046 1 0 +0.191824 0.0385899 0.160921 0.00493513 1 0 +0.115354 0.154888 0.0550774 0.00509607 1 0 +0.0862296 0.163467 0.155967 0.00555456 1 0 +0.328104 0.185124 0.128874 0.00534291 1 0 +0.34386 0.153777 0.0544861 0.00600231 1 0 +0.162034 0.132633 0.144444 0.00561354 1 0 +0.360377 0.177149 0.0473056 0.00500698 1 0 +0.236277 0.19483 0.0243622 0.00525474 1 0 +0.118413 0.11688 0.0402421 0.0054435 1 0 +0.305835 0.155644 0.170986 0.00552785 1 0 +0.129544 0.141282 0.114632 0.00510482 1 0 +0.376786 0.018156 0.156706 0.00527047 1 0 +0.147745 0.185436 0.146696 0.00515421 1 0 +0.272266 0.15953 0.0903589 0.00520212 1 0 +0.22723 0.104227 0.0822697 0.00533343 1 0 +0.385255 0.175893 0.0649707 0.00515363 1 0 +0.23857 0.129915 0.0724236 0.00678225 1 0 +0.0351287 0.115887 0.0370834 0.00515281 1 0 +0.23379 0.0768889 0.102961 0.00529133 1 0 +0.311395 0.182793 0.00742186 0.00531421 1 0 +0.35 0.0342712 0.0193649 0.00502089 1 0 +0.163462 0.0941723 0.0980868 0.00582487 1 0 +0.220885 0.0883698 0.0979634 0.0050954 1 0 +0.381986 0.112109 0.0779516 0.00518927 1 0 +0.349757 0.149435 0.160687 0.00492043 1 0 +0.163168 0.149353 0.150924 0.00505876 1 0 +0.320919 0.180746 0.109715 0.00575719 1 0 +0.335675 0.0176508 0.0384298 0.00556491 1 0 +0.126986 0.115883 0.105086 0.00569101 1 0 +0.325076 0.0168704 0.0376704 0.0050906 1 0 +0.145427 0.117636 0.136501 0.00537628 1 0 +0.236591 0.177699 0.00704534 0.00517186 1 0 +0.149068 0.155496 0.116311 0.00586574 1 0 +0.155506 0.124715 0.148408 0.00498151 1 0 +0.170478 0.112538 0.118343 0.00557105 1 0 +0.25196 0.095997 0.0590623 0.00538771 1 0 +0.363179 0.151149 0.00658791 0.00524601 1 0 +0.333096 0.138546 0.101435 0.0054084 1 0 +0.0678159 0.156327 0.170413 0.0051171 1 0 +0.110907 0.0718823 0.0908004 0.00528436 1 0 +0.0145692 0.194365 0.0779644 0.0050922 1 0 +0.0956187 0.0132816 0.129183 0.00509384 1 0 +0.165112 0.161259 0.132262 0.00607402 1 0 +0.209558 0.0908923 0.0945273 0.00494699 1 0 +0.251909 0.00908388 0.014914 0.00533323 1 0 +0.261593 0.118391 0.0209312 0.00511847 1 0 +0.196188 0.0813525 0.0631632 0.00502461 1 0 +0.0258493 0.18743 0.124911 0.00498865 1 0 +0.360149 0.042735 0.161188 0.00548699 1 0 +0.35 0.0403613 0.161944 0.004963 1 0 +0.309527 0.124847 0.154487 0.00528182 1 0 +0.244683 0.101301 0.0655127 0.0055659 1 0 +0.325279 0.155186 0.066466 0.00559949 1 0 +0.226617 0.195266 0.00806071 0.00512528 1 0 +0.169953 0.0999186 0.108535 0.00504286 1 0 +0.137916 0.186472 0.184189 0.0064584 1 0 +0.0972162 0.134765 0.110854 0.00509749 1 0 +0.303273 0.0299333 0.0454584 0.00580123 1 0 +0.279745 0.0864832 0.0184272 0.0049462 1 0 +0.116074 0.0774425 0.154193 0.00638064 1 0 +0.248656 0.176256 0.0414543 0.00524495 1 0 +0.11719 0.0834206 0.0961585 0.00528837 1 0 +0.229539 0.118874 0.0684492 0.00511033 1 0 +0.173123 0.195374 0.111901 0.00501602 1 0 +0.136327 0.0396209 0.195201 0.0051349 1 0 +0.158862 0.147049 0.127001 0.00625819 1 0 +0.0991766 0.0235319 0.0445431 0.00538577 1 0 +0.201657 0.0487937 0.17149 0.00500199 1 0 +0.312662 0.0232805 0.0848822 0.00508772 1 0 +0.35945 0.135313 0.00927028 0.00523795 1 0 +0.104058 0.068495 0.17199 0.00518088 1 0 +0.037409 0.146655 0.174523 0.00493557 1 0 +0.148805 0.153965 0.160534 0.0051623 1 0 +0.328463 0.160841 0.0579076 0.00514102 1 0 +0.0221549 0.157353 0.194761 0.00500206 1 0 +0.322146 0.13593 0.192839 0.00542503 1 0 +0.286297 0.149768 0.00908993 0.00610423 1 0 +0.280655 0.166453 0.133761 0.00601319 1 0 +0.169994 0.185952 0.11743 0.00584323 1 0 +0.132045 0.045301 0.172359 0.00530653 1 0 +0.0777551 0.161616 0.131273 0.00552788 1 0 +0.199873 0.172401 0.0460262 0.00510947 1 0 +0.272171 0.0594096 0.160745 0.00532387 1 0 +0.165046 0.00600323 0.109875 0.00521884 1 0 +0.142337 0.0812874 0.0878795 0.00498215 1 0 +0.0924792 0.0732765 0.150215 0.00557322 1 0 +0.056255 0.16237 0.117474 0.00507203 1 0 +0.175249 0.16002 0.136546 0.00500027 1 0 +0.155973 0.175395 0.149447 0.00493138 1 0 +0.118544 0.152403 0.165247 0.00546414 1 0 +0.343404 0.159514 0.0899321 0.00495426 1 0 +0.128004 0.141325 0.154959 0.0049926 1 0 +0.244713 0.0307325 0.155689 0.00508441 1 0 +0.181902 0.141143 0.112709 0.00522801 1 0 +0.307729 0.138997 0.0192935 0.00507574 1 0 +0.331633 0.0900834 0.00664554 0.00528612 1 0 +0.216766 0.0824641 0.108869 0.00568365 1 0 +0.211694 0.10536 0.101931 0.00519168 1 0 +0.179299 0.0286834 0.154585 0.00503082 1 0 +0.00631072 0.147677 0.0345265 0.00543485 1 0 +0.332261 0.0910282 0.0655754 0.00591895 1 0 +0.326055 0.0639492 0.104676 0.00532498 1 0 +0.104297 0.0712327 0.152123 0.0049905 1 0 +0.337664 0.118813 0.146655 0.00500696 1 0 +0.16796 0.0880324 0.0899783 0.00520396 1 0 +0.151126 0.144095 0.117993 0.0051249 1 0 +0.167151 0.122918 0.127015 0.00578551 1 0 +0.347149 0.181876 0.140827 0.00657185 1 0 +0.353949 0.191197 0.140731 0.00496706 1 0 +0.28435 0.189917 0.0435792 0.00586862 1 0 +0.222213 0.0143369 0.0721368 0.00557794 1 0 +0.279042 0.0945755 0.11326 0.00519755 1 0 +0.210267 0.0545971 0.188648 0.00515023 1 0 +0.317678 0.147377 0.193662 0.00621996 1 0 +0.250707 0.128303 0.0628843 0.00550307 1 0 +0.0200183 0.12112 0.083305 0.00501581 1 0 +0.177239 0.118432 0.146594 0.00520612 1 0 +0.111327 0.0824235 0.166339 0.00591941 1 0 +0.155479 0.146328 0.186009 0.0050508 1 0 +0.0919961 0.140076 0.142581 0.00563671 1 0 +0.269316 0.144037 0.131719 0.00560771 1 0 +0.150699 0.139069 0.133101 0.00536768 1 0 +0.209042 0.108432 0.0794174 0.00496219 1 0 +0.216699 0.112429 0.0861932 0.00492981 1 0 +0.101038 0.133943 0.0973033 0.00644403 1 0 +0.0966487 0.120678 0.107036 0.00523101 1 0 +0.202327 0.02737 0.0603728 0.0049831 1 0 +0.193253 0.0784818 0.0730075 0.00564155 1 0 +0.0868005 0.12796 0.110006 0.00531148 1 0 +0.238097 0.139762 0.0654122 0.00531521 1 0 +0.154478 0.00735788 0.109484 0.00544259 1 0 +0.103283 0.128144 0.0876139 0.0050692 1 0 +0.270558 0.16535 0.0986312 0.00505513 1 0 +0.157723 0.105315 0.0744188 0.00528203 1 0 +0.169762 0.151644 0.135452 0.00507249 1 0 +0.125053 0.149402 0.11914 0.00521138 1 0 +0.268898 0.165729 0.134488 0.00578782 1 0 +0.170716 0.13527 0.138964 0.00498681 1 0 +0.171308 0.127188 0.14667 0.00536928 1 0 +0.277086 0.157709 0.00506657 0.00534523 1 0 +0.1712 0.00837622 0.119438 0.00530001 1 0 +0.355425 0.144238 0.00571681 0.00517774 1 0 +0.166652 0.083414 0.0995339 0.00524142 1 0 +0.119505 0.139675 0.114664 0.00506236 1 0 +0.204039 0.110165 0.106515 0.00494264 1 0 +0.39225 0.188542 0.150983 0.00565893 1 0 +0.148649 0.136782 0.143078 0.00506248 1 0 +0.22953 0.112953 0.0768692 0.0051831 1 0 +0.0694713 0.0871968 0.0941546 0.00546271 1 0 +0.259241 0.149048 0.128677 0.00604828 1 0 +0.170321 0.17059 0.134922 0.00493746 1 0 +0.275538 0.146728 0.00487594 0.00536114 1 0 +0.169881 0.149538 0.125133 0.00519197 1 0 +0.159116 0.151902 0.139595 0.00532538 1 0 +0.165307 0.125014 0.137586 0.00514797 1 0 +0.187238 0.105113 0.140191 0.00492454 1 0 +0.0980079 0.195089 0.151294 0.00527918 1 0 +0.0896188 0.149924 0.139441 0.00497002 1 0 +0.109522 0.139505 0.105479 0.0049669 1 0 +0.168901 0.107365 0.101898 0.00498716 1 0 +0.0467424 0.143688 0.176425 0.00504098 1 0 +0.258472 0.137915 0.130327 0.00523309 1 0 +0.264116 0.173093 0.0996929 0.00507272 1 0 +0.175687 0.0787602 0.0994242 0.00492242 1 0 +0.190441 0.0686624 0.0757399 0.00493151 1 0 diff --git a/src/Tools/padder/resources/padderexe/med2/concrete.med b/src/Tools/padder/resources/padderexe/med2/concrete.med new file mode 100644 index 000000000..3b39b27a3 Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/concrete.med differ diff --git a/src/Tools/padder/resources/padderexe/med2/data.txt b/src/Tools/padder/resources/padderexe/med2/data.txt new file mode 100644 index 000000000..f7a6b44c2 --- /dev/null +++ b/src/Tools/padder/resources/padderexe/med2/data.txt @@ -0,0 +1,5 @@ +concrete.med concrete +nbSteelFiles 2 +ferrtran.med ferrtran +ferraill.med ferraill +output.med diff --git a/src/Tools/padder/resources/padderexe/med2/ferraill.med b/src/Tools/padder/resources/padderexe/med2/ferraill.med new file mode 100644 index 000000000..79cda889c Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/ferraill.med differ diff --git a/src/Tools/padder/resources/padderexe/med2/ferrtran.med b/src/Tools/padder/resources/padderexe/med2/ferrtran.med new file mode 100644 index 000000000..0a8667061 Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/ferrtran.med differ diff --git a/src/Tools/padder/resources/padderexe/med2/padder.exe b/src/Tools/padder/resources/padderexe/med2/padder.exe new file mode 100755 index 000000000..8591550ed Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/padder.exe differ diff --git a/src/Tools/padder/resources/padderexe/med3/concrete.med b/src/Tools/padder/resources/padderexe/med3/concrete.med new file mode 100644 index 000000000..3b39b27a3 Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med3/concrete.med differ diff --git a/src/Tools/padder/resources/padderexe/med3/data.txt b/src/Tools/padder/resources/padderexe/med3/data.txt new file mode 100644 index 000000000..04cabc7e5 --- /dev/null +++ b/src/Tools/padder/resources/padderexe/med3/data.txt @@ -0,0 +1,4 @@ +concrete.med concrete +nbSteelbarMesh= 1 +ferraill.med ferraill +FinalEDMesh.med diff --git a/src/Tools/padder/resources/padderexe/med3/ferraill.med b/src/Tools/padder/resources/padderexe/med3/ferraill.med new file mode 100644 index 000000000..79cda889c Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med3/ferraill.med differ diff --git a/src/Tools/padder/resources/padderexe/med3/padder.exe b/src/Tools/padder/resources/padderexe/med3/padder.exe new file mode 100755 index 000000000..3eca741f1 Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med3/padder.exe differ diff --git a/src/Tools/padder/resources/padderexe/padder.sh b/src/Tools/padder/resources/padderexe/padder.sh new file mode 100755 index 000000000..d68b56145 --- /dev/null +++ b/src/Tools/padder/resources/padderexe/padder.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# This script emulates the launcher script that will be generated by +# the padder SALOME component and give as the "job file" to the SALOME +# launcher to execute the padder job. +# The script is supposed to be executed where the data are located. + +here=$(dirname $0) + +# >>> This part should be written by the component +binpath=$here/padder.exe +envpath=$here/envPadder.sh +# <<< + +. $envpath +$binpath $here/data.txt diff --git a/src/Tools/padder/resources/padderexe/particules.png b/src/Tools/padder/resources/padderexe/particules.png new file mode 100644 index 000000000..a1b97eca4 Binary files /dev/null and b/src/Tools/padder/resources/padderexe/particules.png differ diff --git a/src/Tools/padder/spadderpy/Makefile.am b/src/Tools/padder/spadderpy/Makefile.am new file mode 100644 index 000000000..c28a874ce --- /dev/null +++ b/src/Tools/padder/spadderpy/Makefile.am @@ -0,0 +1,36 @@ +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +SUBDIRS = + +if SMESH_ENABLE_GUI +SUBDIRS += gui plugin +endif + +DIST_SUBDIRS = gui plugin + +spadderpydir=$(smeshpypkgdir)/spadder +spadderpy_PYTHON = \ + __init__.py \ + configreader.py + +salomeplugins_DATA = \ + padder.cfg diff --git a/src/Tools/padder/spadderpy/__init__.py b/src/Tools/padder/spadderpy/__init__.py new file mode 100644 index 000000000..911cf5b96 --- /dev/null +++ b/src/Tools/padder/spadderpy/__init__.py @@ -0,0 +1,93 @@ +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author(s): Guillaume Boulant (23/03/2011) +# + +# TODO: put all this stuff in the unitests package + +import os +def getRootDir(): + ''' + This returns the root directory where the module SPADDER is + installed. All test files are looked up from this location. + ''' + return os.environ['SMESH_ROOT_DIR'] + +def getTestDataDir(): + ''' + This function gives the absolute path to the directory containing + the data files for test (realistic med files). + ''' + datadir=os.path.join(getRootDir(),"share/salome/resources/smesh/padderexe") + return datadir + +import MESHJOB # to get the enum constant values +from MESHJOB import MeshJobParameter, MeshJobParameterList + +DEFAULT_CONCRETE_FILENAME=os.path.join(getTestDataDir(),'concrete.med') +DEFAULT_STEELBAR_LISTFILENAME=[ + os.path.join(getTestDataDir(),'ferraill.med') + ] + +def getMeshJobParameterList(concrete_filename=DEFAULT_CONCRETE_FILENAME, + steelbar_listfilename=DEFAULT_STEELBAR_LISTFILENAME): + ''' + This helper function creates a complete set of parameters (a + MeshJobParameterList) for a simple test case, i.e. a case with a + concrete filename and a single steelbar filename. + ''' + # Note that a CORBA sequence (MeshJobParameterList) is mapped on a + # simple list in python + meshJobParameterList = [] + # We can add some parameters + param = MeshJobParameter( + file_name = concrete_filename, + file_type = MESHJOB.MED_CONCRETE, + group_name = "concrete") + meshJobParameterList.append(param) + + for steelbar_filename in steelbar_listfilename: + param = MeshJobParameter( + file_name = steelbar_filename, + file_type = MESHJOB.MED_STEELBAR, + group_name = "steelbar") + meshJobParameterList.append(param) + + return meshJobParameterList + + +def getSpadderCatalogFilename(): + filename=os.path.join(getRootDir(),"share/salome/resources/smesh/SPADDERCatalog.xml") + return filename + +def loadSpadderCatalog(): + import salome + salome.salome_init() + obj = salome.naming_service.Resolve('Kernel/ModulCatalog') + import SALOME_ModuleCatalog + catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog) + if not catalog: + raise RuntimeError, "Can't accesss module catalog" + + filename = getSpadderCatalogFilename() + catalog.ImportXmlCatalogFile(filename) + + from salome.kernel import services + print "The list of SALOME components is now:" + print services.getComponentList() diff --git a/src/Tools/padder/spadderpy/configreader.py b/src/Tools/padder/spadderpy/configreader.py new file mode 100644 index 000000000..ceacf543f --- /dev/null +++ b/src/Tools/padder/spadderpy/configreader.py @@ -0,0 +1,140 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author(s): Guillaume Boulant (23/03/2011) +# + +import sys, os +import ConfigParser +from MESHJOB import ConfigParameter +from salome.kernel.uiexception import AdminException, UiException + +from salome_pluginsmanager import PLUGIN_PATH_PATTERN +CONFIG_RELPATH = os.path.join(PLUGIN_PATH_PATTERN,'smesh') +CONFIG_FILENAME = "padder.cfg" +TYPE_LOCAL = 'local' +TYPE_REMOTE = 'remote' +TYPES=[TYPE_LOCAL, TYPE_REMOTE] + +class ConfigReader: + def __init__(self): + # The first step is to look for the config file. This file + # is supposed to be located in the same directory than the + # padder plugin. Then, we have to scan the directories + # specified in the SALOME plugins path. + self.__configFilename = None + try: + smeshpath=os.environ["SMESH_ROOT_DIR"] + except KeyError, ex: + raise AdminException("You should define the variable SMESH_ROOT_DIR") + + pluginspath = os.path.join(smeshpath,CONFIG_RELPATH) + filename = os.path.join(pluginspath,CONFIG_FILENAME) + if os.path.exists(filename): + self.__configFilename = filename + else: + msg = "The configuration file %s can't be found in the SMESH plugins path %s" + raise AdminException(msg%(CONFIG_FILENAME,pluginspath)) + + print "The configuration file is : %s"%self.__configFilename + self.__configparser = ConfigParser.RawConfigParser() + try: + self.__configparser.read(self.__configFilename) + except ConfigParser.ParsingError, ex: + raise AdminException(ex.message) + + def getLocalConfig(self): + return self.__getConfig(TYPE_LOCAL) + + def getRemoteConfig(self): + return self.__getConfig(TYPE_REMOTE) + + def getDefaultConfig(self): + defaultType = self.__getDefaultType() + return self.__getConfig(defaultType) + + def __getConfig(self, type=TYPE_LOCAL): + configName = self.__configparser.get('resources', type) + resname = self.__configparser.get(configName, 'resname') + binpath = self.__configparser.get(configName, 'binpath') + envpath = self.__configparser.get(configName, 'envpath') + config = ConfigParameter(resname, binpath, envpath) + config.resname = resname + return config + + def __getDefaultType(self): + '''This returns the default type read in the config file ([resources], default)''' + defaultType = self.__configparser.get('preferences', 'defaultres') + if defaultType not in TYPES: + return TYPE_LOCAL + return defaultType + + +def printConfig(config): + print "PADDER CONFIGURATION:" + print "\tconfig.resname = %s"%config.resname + print "\tconfig.binpath = %s"%config.binpath + print "\tconfig.envpath = %s"%config.envpath + + +# +# ========================================================================= +# Test runner +# ========================================================================= +# +def TEST_getDefaultConfig(): + try: + configReader = ConfigReader() + defaultConfig = configReader.getDefaultConfig() + print defaultConfig.resname + print defaultConfig.binpath + print defaultConfig.envpath + except Exception, ex: + sys.stderr.write('ERROR: %s\n' % str(ex)) + return False + + return True + +def TEST_getDefaultConfig_withError(): + global CONFIG_FILENAME + CONFIG_FILENAME = "toto.cfg" + try: + configReader = ConfigReader() + defaultConfig = configReader.getDefaultConfig() + except UiException, err: + print 'ERROR: %s' % str(err) + return True + + return False + + +from salome.kernel import unittester +moduleName = "configreader" + +def testsuite(): + unittester.run(moduleName, "TEST_getDefaultConfig") + unittester.run(moduleName, "TEST_getDefaultConfig_withError") + +if __name__ == "__main__": + #import os, sys + #pluginspath=os.environ["SALOME_PLUGINS_PATH"] + #for path in pluginspath.split(":"): + # sys.path.insert(0,path) + + testsuite() diff --git a/src/Tools/padder/spadderpy/gui/Makefile.am b/src/Tools/padder/spadderpy/gui/Makefile.am new file mode 100644 index 000000000..02d4ffd75 --- /dev/null +++ b/src/Tools/padder/spadderpy/gui/Makefile.am @@ -0,0 +1,60 @@ +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# +# Files that compose the spadder graphical interface used by the +# plugin. They are installed in the spadder python package, under the +# sub-package plugins. +# +spadderpydir=$(smeshpypkgdir)/spadder/gui +dist_spadderpy_PYTHON = \ + __init__.py \ + plugindialog.py \ + inputdialog.py \ + inputdata.py + +PYUIC_FILES = \ + plugindialog_ui.py \ + inputframe_ui.py + +nodist_spadderpy_PYTHON = $(PYUIC_FILES) +CLEANFILES = $(PYUIC_FILES) + +dist_spadderpy_DATA= \ + parameters.png \ + input.png \ + select.png \ + compute.png \ + refresh.png \ + publish.png \ + clear.png \ + addinput.png \ + deleteinput.png \ + concrete.png \ + steelbar.png + +%_ui.py:%.ui + $(PYUIC) -x $< -o $@ + +%_rc.py:%.qrc + $(PYRCC) $< -o $@ + +EXTRA_DIST += $(PYUIC_FILES:%_ui.py=%.ui) diff --git a/src/Tools/padder/spadderpy/gui/__init__.py b/src/Tools/padder/spadderpy/gui/__init__.py new file mode 100644 index 000000000..4bde9bc53 --- /dev/null +++ b/src/Tools/padder/spadderpy/gui/__init__.py @@ -0,0 +1,20 @@ +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author(s): Guillaume Boulant (23/03/2011) +# diff --git a/src/Tools/padder/spadderpy/gui/addinput.png b/src/Tools/padder/spadderpy/gui/addinput.png new file mode 100644 index 000000000..408b6b49e Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/addinput.png differ diff --git a/src/Tools/padder/spadderpy/gui/clear.png b/src/Tools/padder/spadderpy/gui/clear.png new file mode 100644 index 000000000..642001bdc Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/clear.png differ diff --git a/src/Tools/padder/spadderpy/gui/compute.png b/src/Tools/padder/spadderpy/gui/compute.png new file mode 100644 index 000000000..37c77a5df Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/compute.png differ diff --git a/src/Tools/padder/spadderpy/gui/concrete.png b/src/Tools/padder/spadderpy/gui/concrete.png new file mode 100644 index 000000000..33af04609 Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/concrete.png differ diff --git a/src/Tools/padder/spadderpy/gui/deleteinput.png b/src/Tools/padder/spadderpy/gui/deleteinput.png new file mode 100644 index 000000000..86c3e36f9 Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/deleteinput.png differ diff --git a/src/Tools/padder/spadderpy/gui/input.png b/src/Tools/padder/spadderpy/gui/input.png new file mode 100644 index 000000000..a8a67db7b Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/input.png differ diff --git a/src/Tools/padder/spadderpy/gui/inputdata.py b/src/Tools/padder/spadderpy/gui/inputdata.py new file mode 100644 index 000000000..2aa54e650 --- /dev/null +++ b/src/Tools/padder/spadderpy/gui/inputdata.py @@ -0,0 +1,77 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Guillaume Boulant (EDF) +# + +from salome.kernel.enumerate import Enumerate +from salome.kernel.datamodeler import DataModeler, TypeString, TypeInteger + +# __MEM__: Note that this module does not depend on the SPADDER +# component on purpose (we could have use a derived structure of +# SPADDER_ORB.MeshJobParameter). This choice is made to ease the test +# and development of the gui part of the plugin. If this data +# structure becomes too important, we could make another arrangement +# and use directly a SPADDER_ORB.MeshJobParameter. + +class InputData(DataModeler): + MESHTYPES=Enumerate([ + 'CONCRETE', + 'STEELBAR' + ]) + + def __init__(self): + DataModeler.__init__(self) + self.addAttribute( + name = "meshObject", + void = True + ) + self.addAttribute( + name = "meshName", + type = TypeString, + range = None + ) + self.addAttribute( + name = "meshType", + type = TypeInteger, + range = self.MESHTYPES.listvalues() + ) + self.addAttribute( + name = "groupName", + type = TypeString, + range = None + ) + +# +# ============================================================================== +# Basic use cases and unit tests +# ============================================================================== +# +def TEST_getName(): + testdata = InputData() + testdata.meshName = "myMesh" + testdata.meshObject = None + testdata.meshType = InputData.MESHTYPES.CONCRETE + if testdata.meshName != "myMesh" : + return False + return True + +if __name__ == "__main__": + from salome.kernel.unittester import run + run("inputdata","TEST_getName") diff --git a/src/Tools/padder/spadderpy/gui/inputdialog.py b/src/Tools/padder/spadderpy/gui/inputdialog.py new file mode 100644 index 000000000..c9d8ae618 --- /dev/null +++ b/src/Tools/padder/spadderpy/gui/inputdialog.py @@ -0,0 +1,376 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Guillaume Boulant (EDF) +# + +import os + +import salome +from salome.kernel import studyedit +from salome.gui.genericdialog import GenericDialog +from salome.gui import helper as guihelper +from salome.smesh.smeshstudytools import SMeshStudyTools + +from omniORB import CORBA + +from PyQt4.QtCore import QObject, SIGNAL, SLOT +from PyQt4.QtGui import QIcon, QStandardItemModel, QStandardItem, QMessageBox + +from inputframe_ui import Ui_InputFrame +from inputdata import InputData + +DEBUG_MODE=True +GROUPNAME_MAXLENGTH=8 + +class InputDialog(GenericDialog): + + TBL_HEADER_LABEL=["Input Mesh", "Output group name"] + + def __init__(self, parent=None, name="InputDialog", modal=0): + """ + This initializes a dialog windows to define the input data of + the plugin function. The input data consist in a list of + meshes characterizes each by a name, a pointer to the smesh + servant object, a type and a group name (see data model in the + inputdata.py). + """ + GenericDialog.__init__(self, parent, name, modal) + # Set up the user interface from Designer. + self.__ui = Ui_InputFrame() + # BE CAREFULL HERE, the ui form is NOT drawn in the global + # dialog (already containing some generic widgets) but in the + # center panel created in the GenericDialog as a void + # container for the form. The InputFrame form is supposed + # here to create only the widgets to be placed in the center + # panel. Then, the setupUi function of this form draws itself + # in the specified panel, i.e. the panel returned by + # self.getPanel(). + self.__ui.setupUi(self.getPanel()) + + self.setWindowTitle("Specification of input files") + + # The icon are supposed to be located in the plugin folder, + # i.e. in the same folder than this python module file + iconfolder=os.path.dirname(os.path.abspath(__file__)) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"select.png")) + self.__ui.btnSmeshObject.setIcon(icon) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"addinput.png")) + self.__ui.btnAddInput.setIcon(icon) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"deleteinput.png")) + self.__ui.btnDeleteInput.setIcon(icon) + + # We specify here the items in the combo box (even if already + # defined in the designer) so that we can be sure of the item + # indexation. + self.MESHTYPE_ICONS = {} + meshTypeIndex = InputData.MESHTYPES.CONCRETE + self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Béton") + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"concrete.png")) + self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon) + self.MESHTYPE_ICONS[meshTypeIndex] = icon + + meshTypeIndex = InputData.MESHTYPES.STEELBAR + self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Acier") + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"steelbar.png")) + self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon) + self.MESHTYPE_ICONS[meshTypeIndex] = icon + + # The click on btnSmeshObject (signal clicked() emitted by the + # button btnSmeshObject) is connected to the slot + # onSelectSmeshObject, etc ... + self.connect(self.__ui.btnSmeshObject, SIGNAL('clicked()'), self.onSelectSmeshObject ) + self.connect(self.__ui.btnAddInput, SIGNAL('clicked()'), self.onAddInput ) + self.connect(self.__ui.btnDeleteInput, SIGNAL('clicked()'), self.onDeleteInput ) + + # Set up the model of the Qt table list + self.__inputModel = QStandardItemModel(0,2) + self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL) + self.__ui.tblListInput.setModel(self.__inputModel) + self.__ui.tblListInput.verticalHeader().hide() + self.__ui.tblListInput.horizontalHeader().setStretchLastSection(True) + # Note that the type is not display explicitly in the Qt table + # because it is specified using an icon on the text of the + # name item. + + # Note that PADDER does not support group name longer than 8 + # characters. We apply then this limit in the gui field. + self.__ui.txtGroupName.setMaxLength(GROUPNAME_MAXLENGTH) + + self.clear() + + self.smeshStudyTool = SMeshStudyTools() + + def clear(self): + """ + This function clears the data gui area and associated values. + """ + self.__ui.txtSmeshObject.setText("") + self.__ui.txtGroupName.setText("") + self.__inputModel.clear() + self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL) + if not DEBUG_MODE: + self.__ui.txtSmeshObject.setEnabled(False) + self.__ui.btnAddInput.setEnabled(False) + self.__selectedMesh = None + self.__dictInputData = {} + self.__nbConcreteMesh = 0 + self.__nbSteelbarMesh = 0 + + def accept(self): + """ + This function is the slot connected to the button OK + """ + # The dialog is raised in a non modal mode to get + # interactivity with the parents windows. Then we have to emit + # a signal to warn the parent observer that the dialog has + # been validated so that it can process the event + GenericDialog.accept(self) + if self.wasOk(): + self.emit(SIGNAL('inputValidated()')) + + def onSelectSmeshObject(self): + ''' + This function is the slot connected on the mesh selection + button. It memorizes the selected mesh and put its name in the + text field of the dialog box. + ''' + mySObject, myEntry = guihelper.getSObjectSelected() + if CORBA.is_nil(mySObject): + self.__ui.txtSmeshObject.setText("You must choose a mesh") + self.__ui.txtGroupName.setText("") + self.__ui.txtSmeshObject.setEnabled(False) + self.__ui.btnAddInput.setEnabled(False) + self.__selectedMesh = None + return + + self.smeshStudyTool.updateStudy(studyedit.getActiveStudyId()) + self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject) + if CORBA.is_nil(self.__selectedMesh): + self.__ui.txtSmeshObject.setText("The selected object is not a mesh") + self.__ui.txtGroupName.setText("") + self.__ui.txtSmeshObject.setEnabled(False) + self.__ui.btnAddInput.setEnabled(False) + self.__selectedMesh = None + return + myName = mySObject.GetName() + self.__ui.txtSmeshObject.setText(myName) + self.__ui.txtSmeshObject.setEnabled(True) + self.__ui.btnAddInput.setEnabled(True) + + # We can suggest a default group name from the mesh name + self.__ui.txtGroupName.setText(myName) + + def onAddInput(self): + """ + This function is the slot connected to the Add button. It + creates a new entry in the list of input data, or updates this + entry if it already exists. + """ + meshName = str(self.__ui.txtSmeshObject.text().trimmed()) + meshObject = self.__selectedMesh + meshType = self.__ui.cmbMeshType.currentIndex() + groupName = str(self.__ui.txtGroupName.text().trimmed()) + + self.__addInputInGui(meshName, meshObject, meshType, groupName) + self.__addInputInMap(meshName, meshObject, meshType, groupName) + + def __addInputInGui(self, meshName, meshObject, meshType, groupName): + """ + This function adds an entry with the specified data int the + GUI table (for data visualization purpose). + """ + # The mesh name is used as the key index in the model. We have + # to check first if this item already exists in the list. + tblItems = self.__inputModel.findItems(meshName) + row = self.__inputModel.rowCount() + if not tblItems: + tblItems = [] + tblItems.append(QStandardItem()) # input mesh name + tblItems.append(QStandardItem()) # output group name + else: + row = tblItems[0].index().row() + tblItems.append(self.__inputModel.item(row,1)) + + tblItems[0].setText(meshName) + tblItems[0].setIcon(self.MESHTYPE_ICONS[meshType]) + tblItems[1].setText(groupName) + self.__inputModel.setItem(row,0,tblItems[0]) + self.__inputModel.setItem(row,1,tblItems[1]) + self.__ui.tblListInput.setCurrentIndex(tblItems[0].index()) + + def __addInputInMap(self, meshName, meshObject, meshType, groupName): + """ + This function adds an entry with the specified data in the + internal map (for data management purpose). + """ + # if the entry already exists, we remove it to replace by a + # new one + if self.__dictInputData.has_key(meshName): + self.__delInputFromMap(meshName) + + inputData = InputData() + inputData.meshName = meshName + inputData.meshObject = meshObject + inputData.meshType = meshType + inputData.groupName = groupName + # The key of the map is the mesh name + self.__dictInputData[meshName] = inputData + if inputData.meshType == InputData.MESHTYPES.CONCRETE: + self.__nbConcreteMesh += 1 + else: + self.__nbSteelbarMesh += 1 + + print inputData + print "meshType = ",inputData.meshType + print "nb concrete mesh ",self.__nbConcreteMesh + print "nb steelbar mesh ",self.__nbSteelbarMesh + + + def onDeleteInput(self): + """ + This function is the slot connected to the Delete button. It + remove from the data list the entry selected in the Qt table. + """ + selectedIdx = self.__ui.tblListInput.selectedIndexes() + if selectedIdx: + row = selectedIdx[0].row() + tblItem = self.__inputModel.item(row,0) + meshName = str(tblItem.text()) + self.__inputModel.takeRow(row) + # Don't forget to remove this entry from the mesh object + # internal dictionnary + self.__delInputFromMap(meshName) + + def __delInputFromMap(self, meshName): + """ + This function removes the specified entry from the internal + map (for data management purpose) + """ + inputData = self.__dictInputData.pop(meshName) + if inputData.meshType == InputData.MESHTYPES.CONCRETE: + self.__nbConcreteMesh -= 1 + else: + self.__nbSteelbarMesh -= 1 + + print inputData + print "nb concrete mesh ",self.__nbConcreteMesh + print "nb steelbar mesh ",self.__nbSteelbarMesh + + + def setData(self, listInputData=[]): + """ + This function fills the dialog widgets with values provided by + the specified data list. + """ + self.clear() + for inputData in listInputData: + + meshName = inputData.meshName + meshObject = inputData.meshObject + meshType = inputData.meshType + groupName = inputData.groupName + + self.__addInputInGui(meshName, meshObject, meshType, groupName) + self.__addInputInMap(meshName, meshObject, meshType, groupName) + + if not DEBUG_MODE: + self.onSelectSmeshObject() + + def getData(self): + """ + This function returns a list of InputData that corresponds to + the data in the dialog widgets of the current dialog. + """ + # Note that the values() function returns a copy of the list + # of values. + return self.__dictInputData.values() + + def checkData(self): + """ + This function checks if the data are valid, from the dialog + window point of view. + """ + if self.__nbConcreteMesh < 1: + self.checkDataMessage = "You must define at least one CONCRETE mesh" + return False + if self.__nbConcreteMesh > 1: + self.checkDataMessage = "You define multiple CONCRETE meshes." + self.checkDataMessage += "You should verify first that your version of PADDER support this configuration." + # just warn the user, but don't block + QMessageBox.information(self, "Info", self.checkDataMessage) + return True + if self.__nbSteelbarMesh < 1: + self.checkDataMessage = "You must define at least one STEELBAR mesh" + return False + return True + + +# ============================================================================== +# Basic use case +# ============================================================================== +# +def TEST_InputDialog(): + import sys + from PyQt4.QtCore import QObject, SIGNAL, SLOT + from PyQt4.QtGui import QApplication + app = QApplication(sys.argv) + QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + + dlg=InputDialog() + dlg.displayAndWait() + if dlg.wasOk(): + print "OK has been pressed" + +def TEST_InputDialog_setData(): + import sys + from PyQt4.QtCore import QObject, SIGNAL, SLOT + from PyQt4.QtGui import QApplication + app = QApplication(sys.argv) + QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + + dlg=InputDialog() + + from inputdata import InputData + inputData = InputData() + inputData.meshName = "myMesh" + inputData.meshObject = None + inputData.meshType = InputData.MESHTYPES.CONCRETE + inputData.groupName = "myGroup" + listInputData = [] + listInputData.append(inputData) + + dlg.setData2(listInputData) + + dlg.displayAndWait() + if dlg.wasOk(): + print "OK has been pressed" + outputListInputData = dlg.getData2() + print outputListInputData + + +if __name__ == "__main__": + #TEST_InputDialog() + TEST_InputDialog_setData() + diff --git a/src/Tools/padder/spadderpy/gui/inputframe.ui b/src/Tools/padder/spadderpy/gui/inputframe.ui new file mode 100644 index 000000000..9f98eb991 --- /dev/null +++ b/src/Tools/padder/spadderpy/gui/inputframe.ui @@ -0,0 +1,204 @@ + + InputFrame + + + + 0 + 0 + 509 + 307 + + + + Input parameters + + + + 9 + + + 6 + + + + + 0 + + + 6 + + + + + Input MESH / Output group name / Type : + + + + + + + 0 + + + 6 + + + + + 0 + + + 6 + + + + + 0 + + + 6 + + + + + 0 + + + 6 + + + + + + 0 + 0 + 0 + 0 + + + + + 31 + 16777215 + + + + + + + select.png + + + + + + + + + + + + + + + + Qt::Vertical + + + + + + + + + + + + + + Qt::Vertical + + + + + + + + + + + Béton + + + concrete.png + + + + + Acier + + + steelbar.png + + + + + + + + + + + + + + + 0 + + + 6 + + + + + + + + addinput.png + + + + + + + + + + deleteinput.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + diff --git a/src/Tools/padder/spadderpy/gui/parameters.png b/src/Tools/padder/spadderpy/gui/parameters.png new file mode 100644 index 000000000..a8a67db7b Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/parameters.png differ diff --git a/src/Tools/padder/spadderpy/gui/plugindialog.py b/src/Tools/padder/spadderpy/gui/plugindialog.py new file mode 100644 index 000000000..2cf4c15d8 --- /dev/null +++ b/src/Tools/padder/spadderpy/gui/plugindialog.py @@ -0,0 +1,403 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Guillaume Boulant (EDF) +# + +from PyQt4.QtGui import QDialog, QIcon +from PyQt4.QtCore import QObject, SIGNAL, SLOT, Qt + +from plugindialog_ui import Ui_PluginDialog +from inputdialog import InputDialog +from inputdata import InputData +# __GBO__: uncomment this line and comment the previous one to use the +# demo input dialog instead of the real one. +#from demoinputdialog import InputDialog + +import os +import salome +from salome.kernel import studyedit +from salome.kernel.uiexception import AdminException + +from omniORB import CORBA +import SMESH +import smesh +import MESHJOB + +gui_states = ["CAN_SELECT", "CAN_COMPUTE", "CAN_REFRESH", "CAN_PUBLISH"] + +run_states = ["CREATED", "IN_PROCESS", "QUEUED", "RUNNING", "PAUSED"]; +end_states = ["FINISHED", "ERROR"] +all_states = run_states+end_states; + +# The SALOME launcher resource is specified by its name as defined in +# the file CatalogResources.xml (see root directory of the +# application). We could have a check box in the dialog to specify +# wether we want a local execution or a remote one. +resource_name = "localhost" +from salome.smesh.spadder.configreader import ConfigReader + + +class PluginDialog(QDialog): + + def __init__(self,parent = None,name = None,modal = 0,fl = 0): + QDialog.__init__(self,parent) + # Set up the user interface from Designer. + self.__ui = Ui_PluginDialog() + self.__ui.setupUi(self) + + # The default display strategy is to use a separate dialog box + # to select the input data. + self.viewInputFrame(False) + + # The icon are supposed to be located in the plugin folder, + # i.e. in the same folder than this python module file + iconfolder=os.path.dirname(os.path.abspath(__file__)) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"input.png")) + self.__ui.btnInput.setIcon(icon) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"compute.png")) + self.__ui.btnCompute.setIcon(icon) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"refresh.png")) + self.__ui.btnRefresh.setIcon(icon) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"publish.png")) + self.__ui.btnPublish.setIcon(icon) + icon = QIcon() + icon.addFile(os.path.join(iconfolder,"clear.png")) + self.__ui.btnClear.setIcon(icon) + + # Then, we can connect the slot to there associated button event + self.connect(self.__ui.btnInput, SIGNAL('clicked()'), self.onInput ) + self.connect(self.__ui.btnCompute, SIGNAL('clicked()'), self.onCompute ) + self.connect(self.__ui.btnRefresh, SIGNAL('clicked()'), self.onRefresh ) + self.connect(self.__ui.btnPublish, SIGNAL('clicked()'), self.onPublish ) + self.connect(self.__ui.btnClear, SIGNAL('clicked()'), self.onClear ) + + self.clear() + + self.setupJobManager() + + + def setupJobManager(self): + ''' + This function configures the jobmanager by transmiting the + parameters required for a local execution and a remote + execution. The choice between "local" and "remote" is done at + the initialize step, by specifing the name of the resource to + be used. + ''' + # We first + + configReader = ConfigReader() + config = configReader.getLocalConfig() + configId = config.resname + self.__getJobManager().configure(configId, config) + # Note that the resname parameter is used as the key identifier of + # the configuration in the job manager. As is, there can be then + # only one configuration for each machine defined in the resources + # catalog (no need to have further, I thing) + config = configReader.getRemoteConfig() + configId = config.resname + self.__getJobManager().configure(configId, config) + + # We specify the default configuration identifier as the + # resource name of the default configuration + self.__configId = configReader.getDefaultConfig().resname + + + def viewInputFrame(self, view=True): + # By default, the top input frame is visible and the input + # button is not visible. + if view is False: + self.__ui.frameInput.setVisible(False) + self.__ui.btnInput.setVisible(True) + # We create the input dialog that will be displayed when + # button input is pressed: + self.__inputDialog = InputDialog(self) + # The window is kept on the top to ease the selection of + # items in the object browser: + self.__inputDialog.setWindowFlags( + self.__inputDialog.windowFlags() | Qt.WindowStaysOnTopHint) + # The signal inputValidated emited from inputDialog is + # connected to the slot function onProcessInput: + self.connect(self.__inputDialog, SIGNAL('inputValidated()'), self.onProcessInput) + + else: + self.__ui.frameInput.setVisible(True) + self.__ui.btnInput.setVisible(False) + # This case is NOT IMPLEMENTED YET (not really). It could + # be used to draw the input frame directly in the frame + # frameInput of this dialog box. + + def getInputFrame(self): + return self.__ui.frameInput + + def __setGuiState(self,states=["CAN_SELECT"]): + if "CAN_SELECT" in states: + self.__ui.btnInput.setEnabled(True) + else: + self.__ui.btnInput.setEnabled(False) + + if "CAN_COMPUTE" in states: + self.__ui.btnCompute.setEnabled(True) + else: + self.__ui.btnCompute.setEnabled(False) + + if "CAN_REFRESH" in states: + self.__ui.btnRefresh.setEnabled(True) + else: + self.__ui.btnRefresh.setEnabled(False) + + if "CAN_PUBLISH" in states: + self.__ui.btnPublish.setEnabled(True) + else: + self.__ui.btnPublish.setEnabled(False) + + def __getJobManager(self): + """ + This function requests a pointer to the MeshJobManager + servant. Note that the component is loaded on first demand, + and then the reference is recycled. + """ + if self.__dict__.has_key("__jobManager") and self.__jobManager is not None: + return self.__jobManager + + # WARN: we first have to update the SALOME components catalog + # with the SPADDER components (because they are not defined in + # the SMESH catalog, and then they are not in the default + # catalog) + from salome.smesh import spadder + spadder.loadSpadderCatalog() + # Then we can load the MeshJobManager component + component=salome.lcc.FindOrLoadComponent("FactoryServer","MeshJobManager") + if component is None: + msg="ERR: the SALOME component MeshJobManager can't be reached" + self.__log(msg) + raise AdminException(msg) + + self.__jobManager = component + return self.__jobManager + + def __log(self, message): + """ + This function prints the specified message in the log area + """ + self.__ui.txtLog.append(message) + + def __exportMesh(self, meshName, meshObject): + ''' + This function exports the specified mesh object to a med + file whose name (basepath) is built from the specified mesh + name. This returns the filename. + ''' + filename=str("/tmp/padder_inputfile_"+meshName+".med") + meshObject.ExportToMEDX( filename, 0, SMESH.MED_V2_2, 1 ) + return filename + + def clear(self): + """ + This function clears the log area and the states of the buttons + """ + self.__listInputData = [] + self.__ui.txtLog.clear() + self.__setGuiState(["CAN_SELECT"]) + self.__isRunning = False + self.__ui.lblStatusBar.setText("Ready") + + def update(self): + ''' + This function can be used to programmatically force the + refresh of the dialog box, the job state in particular. + ''' + if self.__isRunning: + self.onRefresh() + + def onInput(self): + ''' + This function is the slot connected to the Input button + (signal clicked()). It opens the dialog window to input + data. The dialog is opened in a window modal mode so that the + SALOME study objects can be selected. In conterpart, this + class must listen to signals emitted by the child dialog + windows to process the validation event (see the slot + onProcessInput which is connected to this event). + ''' + self.__inputDialog.setData(self.__listInputData) + self.__inputDialog.open() + + def onProcessInput(self): + """ + This function is the slot connected to the signal + inputValidated(), emit by the input dialog window when it's + validated, i.e. OK is pressed and data are valid. + """ + # The processing simply consists in requesting the input data + # from the dialog window. + self.__listInputData = self.__inputDialog.getData() + self.__ui.lblStatusBar.setText("Input data OK") + self.__log("INF: Press \"Compute\" to start the job") + self.__setGuiState(["CAN_SELECT", "CAN_COMPUTE"]) + + def onCompute(self): + ''' + This function is the slot connected to the Compute button. It + initializes a mesh computation job and start it using the + SALOME launcher. + ''' + # We first have to create the list of parameters for the + # initialize function. For that, we have to create the files + # from the mesh objects: + meshJobParameterList=[] + concreteIndex=0 + for inputData in self.__listInputData: + # For each input data, we have to create a + # MeshJobParameter and add it to the list. + filename = self.__exportMesh(inputData.meshName, inputData.meshObject) + if inputData.meshType == InputData.MESHTYPES.CONCRETE: + filetype = MESHJOB.MED_CONCRETE + else: + filetype = MESHJOB.MED_STEELBAR + + parameter = MESHJOB.MeshJobParameter( + file_name = filename, + file_type = filetype, + group_name = inputData.groupName) + meshJobParameterList.append(parameter) + + jobManager = self.__getJobManager() + self.__jobid = jobManager.initialize(meshJobParameterList, self.__configId) + if self.__jobid < 0: + self.__log("ERR: the job can't be initialized") + return + self.__log("INF: the job has been initialized with jobid = "+str(self.__jobid)) + + startOk = jobManager.start(self.__jobid) + if not startOk: + self.__log("ERR: the job with jobid = "+str(self.__jobid)+" can't be started") + return + self.__log("INF: the job "+str(self.__jobid)+" has been started") + self.__ui.lblStatusBar.setText("Submission OK") + self.__setGuiState(["CAN_REFRESH"]) + self.__isRunning = True + + def onRefresh(self): + """ + This function is the slot connected on the Refresh button. It + requests the mesh job manager to get the state of the job and + display it in the log area. + """ + jobManager = self.__getJobManager() + state = jobManager.getState(self.__jobid) + self.__log("INF: job state = "+str(state)) + self.__ui.lblStatusBar.setText("") + if state in run_states: + return + + self.__isRunning = False + if state == "FINISHED": + self.__setGuiState(["CAN_PUBLISH"]) + else: + self.__setGuiState(["CAN_SELECT"]) + + + def onPublish(self): + """ + This function is the slot connected on the Publish button. It + requests the mesh job manager to download the results data + from the computation resource host and load the med file in + the SALOME study. + """ + jobManager = self.__getJobManager() + state = jobManager.getState(self.__jobid) + if state in run_states: + self.__log("WRN: jobid = "+str(self.__jobid)+" is not finished (state="+str(state)+")") + return + + if state not in end_states: + self.__log("ERR: jobid = "+str(self.__jobid)+" ended abnormally with state="+str(state)) + return + + meshJobResults = jobManager.finalize(self.__jobid) + if state == "ERROR": + self.__log("ERR: jobid = "+str(self.__jobid)+" ended with error: "+meshJobResults.status) + return + + logsdirname = os.path.join(meshJobResults.results_dirname, "logs") + self.__log("INF: jobid="+str(self.__jobid)+" ended normally : "+meshJobResults.status) + self.__log("INF: jobid="+str(self.__jobid)+" see log files in : "+logsdirname) + + medfilename = os.path.join(meshJobResults.results_dirname, + meshJobResults.outputmesh_filename) + + smesh.SetCurrentStudy(studyedit.getActiveStudy()) + ([outputMesh], status) = smesh.CreateMeshesFromMED(medfilename) + + # By convention, the name of the output mesh in the study is + # build from a constant string 'padder' and the session jobid + meshname = 'padder_'+str(self.__jobid) + smesh.SetName(outputMesh.GetMesh(), meshname) + if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(0) + + self.__ui.lblStatusBar.setText("Publication OK") + self.__setGuiState(["CAN_SELECT"]) + + def onClear(self): + """ + This function is the slot connected on the Clear button. It + erases data in the dialog box and cancel the current job if + one is running. + """ + self.clear() + + + +__dialog=None +def getDialog(): + """ + This function returns a singleton instance of the plugin dialog. + """ + global __dialog + if __dialog is None: + __dialog = PluginDialog() + return __dialog + +# +# ============================================================================== +# Basic use cases and unit test functions +# ============================================================================== +# +def TEST_PluginDialog(): + import sys + from PyQt4.QtGui import QApplication + from PyQt4.QtCore import QObject, SIGNAL, SLOT + app = QApplication(sys.argv) + QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + + dlg=PluginDialog() + dlg.exec_() + +if __name__ == "__main__": + TEST_PluginDialog() + + + diff --git a/src/Tools/padder/spadderpy/gui/plugindialog.ui b/src/Tools/padder/spadderpy/gui/plugindialog.ui new file mode 100644 index 000000000..c6af08f68 --- /dev/null +++ b/src/Tools/padder/spadderpy/gui/plugindialog.ui @@ -0,0 +1,168 @@ + + + PluginDialog + + + true + + + + 0 + 0 + 649 + 367 + + + + Create a mesh with PADDER + + + + 6 + + + 9 + + + + + 6 + + + 0 + + + + + QFrame::Raised + + + 1 + + + 0 + + + + 6 + + + 9 + + + + + + + + 6 + + + 0 + + + + + + + + 6 + + + 0 + + + + + Input + + + + parameters.pngparameters.png + + + + + + + Compute + + + + compute.pngcompute.png + + + + + + + Refresh + + + + refresh.pngrefresh.png + + + + + + + Publish + + + + publish.pngpublish.png + + + + + + + Qt::Vertical + + + + 75 + 101 + + + + + + + + Clear + + + + clear.pngclear.png + + + + + + + + + + + true + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + + + + + + + diff --git a/src/Tools/padder/spadderpy/gui/publish.png b/src/Tools/padder/spadderpy/gui/publish.png new file mode 100644 index 000000000..bfe8802a2 Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/publish.png differ diff --git a/src/Tools/padder/spadderpy/gui/refresh.png b/src/Tools/padder/spadderpy/gui/refresh.png new file mode 100644 index 000000000..2683e9814 Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/refresh.png differ diff --git a/src/Tools/padder/spadderpy/gui/select.png b/src/Tools/padder/spadderpy/gui/select.png new file mode 100644 index 000000000..8eea6a94d Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/select.png differ diff --git a/src/Tools/padder/spadderpy/gui/steelbar.png b/src/Tools/padder/spadderpy/gui/steelbar.png new file mode 100644 index 000000000..ce27fe3a0 Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/steelbar.png differ diff --git a/src/Tools/padder/spadderpy/padder.cfg.in b/src/Tools/padder/spadderpy/padder.cfg.in new file mode 100644 index 000000000..4962a336a --- /dev/null +++ b/src/Tools/padder/spadderpy/padder.cfg.in @@ -0,0 +1,35 @@ +# This section specify the configurations to be used respectively for +# the local execution and the remote execution. The value for 'local' +# and 'remote' keys must be the name of a configuration section in +# this file. The default key must specify a value between "local" or +# "remote" to indicate the user preference. +[resources] +local = localhost +remote = nepal + +[preferences] +defaultres = local + +# The following sections defines the available configurations. +# The name of the section can be choosen arbitrary. But the value of +# the resname key MUST be the name of a SALOME resource defined in the +# catalog of resources (CatalogResources.xml). + +# For each section: +# - resname : the name of the SALOME resource to be used in this configuration +# - binpath : the path to the padder executable program on this resource +# - envpath : the path to the environment file on this resource +[localhost] +resname = localhost +binpath = @PADDERHOME@/padder.exe +envpath = @PADDERHOME@/padder.env + +[venus] +resname = gboulant@venus +binpath = /usr/local/bin/padder.exe +envpath = /usr/local/share/envPadder.sh + +[nepal] +resname = nepal@nepal +binpath = /usr/local/bin/padder.exe +envpath = /usr/local/share/envPadder.sh diff --git a/src/Tools/padder/spadderpy/plugin/Makefile.am b/src/Tools/padder/spadderpy/plugin/Makefile.am new file mode 100644 index 000000000..e05fd636c --- /dev/null +++ b/src/Tools/padder/spadderpy/plugin/Makefile.am @@ -0,0 +1,33 @@ +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# +# Files that strictly concern the SALOME plugins registration and +# configuration. They are installed in a dedicated folder named +# plugins and created in the root installation directory. +# +salomeplugins_PYTHON = \ + spadderPlugin.py + +#salomeplugins_DATA = \ +# envPlugins.sh + + diff --git a/src/Tools/padder/spadderpy/plugin/envPlugins.sh.in b/src/Tools/padder/spadderpy/plugin/envPlugins.sh.in new file mode 100644 index 000000000..aa7c39a7f --- /dev/null +++ b/src/Tools/padder/spadderpy/plugin/envPlugins.sh.in @@ -0,0 +1,22 @@ +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SPADDER_PLUGINS_PATH=@prefix@/plugins +export SALOME_PLUGINS_PATH=$SALOME_PLUGINS_PATH:$SPADDER_PLUGINS_PATH + diff --git a/src/Tools/padder/spadderpy/plugin/spadderPlugin.py b/src/Tools/padder/spadderpy/plugin/spadderPlugin.py new file mode 100644 index 000000000..67f78264b --- /dev/null +++ b/src/Tools/padder/spadderpy/plugin/spadderPlugin.py @@ -0,0 +1,36 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Guillaume Boulant (EDF) +# + +def runSpadderPlugin(context): + from salome.smesh.spadder.gui import plugindialog + from salome.kernel.uiexception import UiException + try: + dialog=plugindialog.getDialog() + except UiException, err: + from PyQt4.QtGui import QMessageBox + QMessageBox.critical(None,"An error occurs during PADDER configuration", + err.getUIMessage()) + return + + dialog.update() + dialog.show() + diff --git a/src/Tools/padder/unittests/Makefile.am b/src/Tools/padder/unittests/Makefile.am new file mode 100644 index 000000000..42fad276c --- /dev/null +++ b/src/Tools/padder/unittests/Makefile.am @@ -0,0 +1,31 @@ +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +spadderpydir=$(smeshpypkgdir)/spadder/unittests + +spadderpy_PYTHON = \ + __init__.py \ + usecase_meshJobManager.py \ + usecase_spadderPluginTester.py + +spadderbindir=$(bindir)/spadder +spadderbin_SCRIPTS = \ + autotest.sh diff --git a/src/Tools/padder/unittests/__init__.py b/src/Tools/padder/unittests/__init__.py new file mode 100644 index 000000000..faa0a86b0 --- /dev/null +++ b/src/Tools/padder/unittests/__init__.py @@ -0,0 +1,18 @@ +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# diff --git a/src/Tools/padder/unittests/autotest.sh.in b/src/Tools/padder/unittests/autotest.sh.in new file mode 100644 index 000000000..7ff1ece28 --- /dev/null +++ b/src/Tools/padder/unittests/autotest.sh.in @@ -0,0 +1,61 @@ +#!/bin/bash +# Copyright (C) 2010-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Guillaume Boulant (EDF) +# + + +# This script should be executed in a SALOME shell session, +# for example the shell obtained from the command runSession +# provided by the SALOME application. + +# This list contains the filenames where test suites are to be +# executed. The path are defined relative to the PYTHON installation +# directory of the SALOME module. +listfiles="\ + configreader.py \ + unittests/usecase_meshJobManager.py \ + gui/inputdata.py" + +INSTALL_DIR=@prefix@ +PYTHON_DIR=$INSTALL_DIR/lib/python@PYTHON_VERSION@/site-packages/salome +PYTHONPATH=$PYTHON_DIR:$PYTHONPATH +export PYTHONPATH + +stderr=2 +while getopts 'ql' OPTION +do + case $OPTION in + q) stderr=1 ;; + l) for f in $listfiles; do echo $f; done; exit 0;; + ?) printf "Usage: %s: [-q] [-l]\n" $(basename $0) >&2; exit 2;; + esac +done +shift $(($OPTIND - 1)) + +here=$(pwd) +package_path="salome/smesh/spadder" +cd $PYTHON_DIR +for file in $listfiles; do + # Uncomment this line (and comment the next one) to display + # the start line of a test and not only the result: + python $package_path/$file 2>&$stderr | grep '^\[TEST' + #python $package_path/$file $filter | grep '^\[TEST' | grep -v 'test in progress' +done +cd $here diff --git a/src/Tools/padder/unittests/usecase_meshJobManager.py b/src/Tools/padder/unittests/usecase_meshJobManager.py new file mode 100644 index 000000000..09a8c09ea --- /dev/null +++ b/src/Tools/padder/unittests/usecase_meshJobManager.py @@ -0,0 +1,102 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author(s): Guillaume Boulant (23/03/2011) +# + +# This script illustrates the standard use case of the component +# MeshJobManager from within a SALOME script. + + +# +# Preparing the configuration parameters +# +import os +from salome.smesh.spadder.configreader import ConfigReader, printConfig + +configReader = ConfigReader() +defaultConfig = configReader.getDefaultConfig() +printConfig(defaultConfig) + +from salome.smesh import spadder +file_concrete=os.path.join(spadder.getTestDataDir(),"concrete.med") +file_steelbar=os.path.join(spadder.getTestDataDir(),"ferraill.med") + +import salome +import MESHJOB + +# +# Setup the configuration in the component. When first have to load +# the catalog of SPADDER components, then load the component +# MeshJobManager, and finally configure this component. +# +spadder.loadSpadderCatalog() + +salome.salome_init() +component = salome.lcc.FindOrLoadComponent("FactoryServer","MeshJobManager") +config = MESHJOB.ConfigParameter(resname=defaultConfig.resname, + binpath=defaultConfig.binpath, + envpath=defaultConfig.envpath) +component.configure("localhost",config) + +# +# Prepare the job parameters and initialize the job +# +meshJobParameterList = [] +param = MESHJOB.MeshJobParameter(file_name=file_concrete, + file_type=MESHJOB.MED_CONCRETE, + group_name="concrete") +meshJobParameterList.append(param) + +param = MESHJOB.MeshJobParameter(file_name=file_steelbar, + file_type=MESHJOB.MED_STEELBAR, + group_name="steelbar") +meshJobParameterList.append(param) +jobid = component.initialize(meshJobParameterList, "localhost") + +# +# Start the execution of the job identified by its job id. +# +ok=component.start(jobid) + +# +# This part illustrates how you can follow the execution of the job. +# +run_states = ["CREATED", "IN_PROCESS", "QUEUED", "RUNNING", "PAUSED"]; +end_states = ["FINISHED", "ERROR"] +all_states = run_states+end_states; + +ended = False +nbiter = 0 +import time +while not ended: + state = component.getState(jobid) + print "MeshJobManager ["+str(nbiter)+"] : state = "+str(state) + if state not in run_states: + ended=True + time.sleep(0.5) + nbiter+=1 + +if state not in end_states: + print "ERR: jobid = "+str(jobid)+" ended abnormally with state="+str(state) +else: + print "OK: jobid = "+str(jobid)+" ended with state="+str(state) + meshJobResults = component.finalize(jobid) + print meshJobResults + print "You will find the results files in the directory:\n%s"%meshJobResults.results_dirname diff --git a/src/Tools/padder/unittests/usecase_spadderPluginTester.py b/src/Tools/padder/unittests/usecase_spadderPluginTester.py new file mode 100644 index 000000000..164cf8a33 --- /dev/null +++ b/src/Tools/padder/unittests/usecase_spadderPluginTester.py @@ -0,0 +1,51 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author(s): Guillaume Boulant (23/03/2011) +# + +# This script illustrates the standard use case of the component +# SPADDERPluginTester from within a SALOME script. This component is +# dedicated to test purpose only + +import salome +import SPADDERPluginTest + +# We first have to update the SALOME components list by loading the +# SPADDER catalog (load on demand only) +from salome.smesh import spadder +spadder.loadSpadderCatalog() + +# Basic test +print "Basic tests" +c=salome.lcc.FindOrLoadComponent("FactoryServer","SPADDERPluginTester") +z=c.demo(2.,3.) + +# Test of usage of KERNEL services from the test component +print "Test of usage of KERNEL services from the test component" +c.testkernel() + +# Test of usage of SMESH engine from the test component +# WARN: the SMESH engine must be loaded first +print "Test of usage of SMESH engine from the test component" +import SMESH +salome.lcc.FindOrLoadComponent("FactoryServer","SMESH") +c.testsmesh(salome.myStudyId) + +print "Test completed : OK" diff --git a/src/Tools/smesh_plugins.py b/src/Tools/smesh_plugins.py new file mode 100644 index 000000000..612e0faa8 --- /dev/null +++ b/src/Tools/smesh_plugins.py @@ -0,0 +1,33 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2011-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Guillaume Boulant (EDF) +# +import salome_pluginsmanager + +from spadderPlugin import runSpadderPlugin +from meshcut_plugin import MeshCut + +salome_pluginsmanager.AddFunction('PADDER mesher', + 'Create a mesh with PADDER', + runSpadderPlugin) + +salome_pluginsmanager.AddFunction('MeshCut', + 'Cut a tetrahedron mesh by a plane', + MeshCut)