From c701e968eb75a1e2b284915bab159efffc1e3c0c Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 9 Aug 2012 11:51:48 +0000 Subject: [PATCH] Merge from V6_main_20120808 08Aug12 --- AUTHORS | 3 +- BLSURFPLUGIN_version.h.in | 28 +- ChangeLog | 3 +- INSTALL | 3 +- Makefile.am | 46 +- NEWS | 3 +- adm_local/Makefile.am | 29 +- adm_local/cmake_files/FindBLSURF.cmake | 46 + adm_local/cmake_files/Makefile.am | 26 + adm_local/unix/Makefile.am | 27 +- adm_local/unix/config_files/Makefile.am | 27 +- adm_local/unix/config_files/check_BLSURF.m4 | 78 +- .../unix/config_files/check_BLSURFPLUGIN.m4 | 89 +- adm_local/unix/make_common_starter.am | 35 +- bin/Makefile.am | 27 +- bin/VERSION.in | 4 +- build_cmake | 27 + build_cmake.bat | 20 + build_configure | 97 +- clean_configure | 38 +- configure.ac | 171 +- doc/Makefile.am | 32 + doc/salome/Makefile.am | 38 + doc/salome/gui/BLSURFPLUGIN/Makefile.am | 66 + doc/salome/gui/BLSURFPLUGIN/doxyfile.in | 72 + doc/salome/gui/BLSURFPLUGIN/doxyfile_py.in | 159 + .../BLSURFPLUGIN/images/blsurf_attractors.png | Bin 0 -> 195990 bytes .../images/blsurf_attractors2.png | Bin 0 -> 117901 bytes .../images/blsurf_const_size_near_shape.png | Bin 0 -> 64430 bytes .../images/blsurf_const_size_near_shape2.png | Bin 0 -> 57870 bytes .../BLSURFPLUGIN/images/blsurf_parameters.png | Bin 0 -> 37081 bytes .../images/blsurf_parameters_advanced.png | Bin 0 -> 36675 bytes .../blsurf_parameters_enforced_vertices.png | Bin 0 -> 30233 bytes .../images/blsurf_parameters_sizemap.png | Bin 0 -> 19241 bytes .../images/blsurf_parameters_sizemap1.png | Bin 0 -> 27840 bytes .../images/blsurf_parameters_sizemap2.png | Bin 0 -> 36939 bytes doc/salome/gui/BLSURFPLUGIN/images/head.png | Bin 0 -> 78545 bytes .../gui/BLSURFPLUGIN/input/blsurf_hypo.doc | 458 +++ .../input/blsurfplugin_python_interface.doc | 159 + doc/salome/gui/BLSURFPLUGIN/input/index.doc | 20 + .../gui/BLSURFPLUGIN/static/doxygen.css | 836 +++++ .../gui/BLSURFPLUGIN/static/footer.html | 12 + .../gui/BLSURFPLUGIN/static/header.html.in | 20 + .../gui/BLSURFPLUGIN/static/header_py.html.in | 21 + doc/salome/gui/Makefile.am | 31 + doc/salome/tui/Makefile.am | 42 + doc/salome/tui/doxyfile.in | 260 ++ doc/salome/tui/images/Application-About.png | Bin 0 -> 19226 bytes doc/salome/tui/images/application.gif | Bin 0 -> 2602 bytes doc/salome/tui/images/html_comments.gif | Bin 0 -> 156 bytes doc/salome/tui/images/logocorp.gif | Bin 0 -> 1792 bytes doc/salome/tui/static/doxygen.css | 152 + doc/salome/tui/static/footer.html | 10 + doc/salome/tui/static/myheader.html | 13 + idl/BLSURFPlugin_Algorithm.idl | 257 +- idl/Makefile.am | 45 +- resources/BLSURFPlugin.xml | 12 +- resources/Makefile.am | 28 +- resources/SalomeApp.xml | 5 +- resources/mesh_select_BLSURF.png | Bin 0 -> 1143 bytes src/BLSURFPlugin/BLSURFPluginDC.py | 308 ++ src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx | 332 ++ src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx | 145 + src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx | 2165 ++++++++++++- src/BLSURFPlugin/BLSURFPlugin_BLSURF.hxx | 93 +- src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.cxx | 35 +- src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.hxx | 31 +- src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx | 1683 ++++++++-- src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx | 334 +- .../BLSURFPlugin_Hypothesis_i.cxx | 2169 ++++++++++++- .../BLSURFPlugin_Hypothesis_i.hxx | 194 +- src/BLSURFPlugin/BLSURFPlugin_i.cxx | 38 +- src/BLSURFPlugin/Makefile.am | 69 +- src/GUI/BLSURFPluginGUI.cxx | 35 +- src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx | 2771 +++++++++++++++-- src/GUI/BLSURFPluginGUI_HypothesisCreator.h | 323 +- src/GUI/BLSURFPlugin_images.ts | 27 +- src/GUI/BLSURFPlugin_msg_en.ts | 489 ++- src/GUI/BLSURFPlugin_msg_fr.ts | 355 +++ src/GUI/Makefile.am | 47 +- src/Makefile.am | 29 +- 81 files changed, 13698 insertions(+), 1549 deletions(-) create mode 100644 adm_local/cmake_files/FindBLSURF.cmake create mode 100644 adm_local/cmake_files/Makefile.am create mode 100755 build_cmake create mode 100644 build_cmake.bat create mode 100644 doc/Makefile.am create mode 100644 doc/salome/Makefile.am create mode 100644 doc/salome/gui/BLSURFPLUGIN/Makefile.am create mode 100755 doc/salome/gui/BLSURFPLUGIN/doxyfile.in create mode 100755 doc/salome/gui/BLSURFPLUGIN/doxyfile_py.in create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_attractors.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_attractors2.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_const_size_near_shape.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_const_size_near_shape2.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_advanced.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_enforced_vertices.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_sizemap.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_sizemap1.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_sizemap2.png create mode 100755 doc/salome/gui/BLSURFPLUGIN/images/head.png create mode 100644 doc/salome/gui/BLSURFPLUGIN/input/blsurf_hypo.doc create mode 100644 doc/salome/gui/BLSURFPLUGIN/input/blsurfplugin_python_interface.doc create mode 100644 doc/salome/gui/BLSURFPLUGIN/input/index.doc create mode 100755 doc/salome/gui/BLSURFPLUGIN/static/doxygen.css create mode 100755 doc/salome/gui/BLSURFPLUGIN/static/footer.html create mode 100755 doc/salome/gui/BLSURFPLUGIN/static/header.html.in create mode 100644 doc/salome/gui/BLSURFPLUGIN/static/header_py.html.in create mode 100644 doc/salome/gui/Makefile.am create mode 100644 doc/salome/tui/Makefile.am create mode 100755 doc/salome/tui/doxyfile.in create mode 100755 doc/salome/tui/images/Application-About.png create mode 100755 doc/salome/tui/images/application.gif create mode 100755 doc/salome/tui/images/html_comments.gif create mode 100755 doc/salome/tui/images/logocorp.gif create mode 100755 doc/salome/tui/static/doxygen.css create mode 100755 doc/salome/tui/static/footer.html create mode 100755 doc/salome/tui/static/myheader.html create mode 100644 resources/mesh_select_BLSURF.png create mode 100644 src/BLSURFPlugin/BLSURFPluginDC.py create mode 100644 src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx create mode 100644 src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx create mode 100755 src/GUI/BLSURFPlugin_msg_fr.ts diff --git a/AUTHORS b/AUTHORS index 8173fb7..7bdd20e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2008 OPEN CASCADE, CEA/DEN, EDF R&D +# 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 @@ -16,6 +16,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # --- # # File : AUTHORS diff --git a/BLSURFPLUGIN_version.h.in b/BLSURFPLUGIN_version.h.in index c90b4f2..facaf9b 100644 --- a/BLSURFPLUGIN_version.h.in +++ b/BLSURFPLUGIN_version.h.in @@ -1,21 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPLUGIN_version.h // Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -30,5 +31,6 @@ #define BLSURFPLUGIN_VERSION_STR "@VERSION@" #define BLSURFPLUGIN_VERSION @XVERSION@ +#define BLSURFPLUGIN_DEVELOPMENT @VERSION_DEV@ #endif // __BLSURFPLUGIN_VERSION_H__ diff --git a/ChangeLog b/ChangeLog index ca38f41..edde3d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2008 OPEN CASCADE, CEA/DEN, EDF R&D +# 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 @@ -16,6 +16,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # --- # # File : ChangeLog diff --git a/INSTALL b/INSTALL index 9c9abf9..9b0b3a0 100644 --- a/INSTALL +++ b/INSTALL @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2008 OPEN CASCADE, CEA/DEN, EDF R&D +# 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 @@ -16,6 +16,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # --- # # File : INSTALL diff --git a/Makefile.am b/Makefile.am index d5c2257..d70863f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -38,17 +39,28 @@ else !BLSURFPLUGIN_ENABLE_GUI -I ${SMESH_ROOT_DIR}/adm_local/unix/config_files endif -SUBDIRS = idl adm_local resources src bin +SUBDIRS = idl adm_local resources src bin doc -DIST_SUBDIRS = idl adm_local resources src 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 = BLSURFPLUGIN_version.h EXTRA_DIST += \ build_configure \ - clean_configure + clean_configure \ + build_cmake \ + build_cmake.bat dist-hook: rm -rf `find $(distdir) -name CVS` + +usr_docs: + (cd doc && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +docs: usr_docs + +dev_docs: + (cd doc && $(MAKE) $(AM_MAKEFLAGS) dev_docs) + diff --git a/NEWS b/NEWS index 6a0b1eb..d22503a 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2008 OPEN CASCADE, CEA/DEN, EDF R&D +# 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 @@ -16,6 +16,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # --- # # File : NEWS diff --git a/adm_local/Makefile.am b/adm_local/Makefile.am index 3f9a07d..6b3c7d7 100644 --- a/adm_local/Makefile.am +++ b/adm_local/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -23,4 +24,4 @@ # include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS = unix +SUBDIRS = unix cmake_files diff --git a/adm_local/cmake_files/FindBLSURF.cmake b/adm_local/cmake_files/FindBLSURF.cmake new file mode 100644 index 0000000..5fea852 --- /dev/null +++ b/adm_local/cmake_files/FindBLSURF.cmake @@ -0,0 +1,46 @@ +# 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 +# + +SET(BLSURFHOME $ENV{BLSURFHOME}) +FIND_PATH(BLSURF_INCLUDES_DIR distene/blsurf.h ${BLSURFHOME}/include) +SET(BLSURF_INCLUDES) +SET(BLSURF_INCLUDES ${BLSURF_INCLUDES} -I${BLSURF_INCLUDES_DIR}) + +SET(BLSURF_LIBS_PATHS) +SET(BLSURF_LIBS_PATHS ${BLSURF_LIBS_PATHS} ${BLSURFHOME}/lib) +IF(WINDOWS) + SET(BLSURF_LIBS_PATHS ${BLSURF_LIBS_PATHS} ${BLSURFHOME}/lib/WinXP_VC9) +ELSE(WINDOWS) + IF(CMAKE_SIZEOF_VOID_P STREQUAL 8) + SET(BLSURF_LIBS_PATHS ${BLSURF_LIBS_PATHS} ${BLSURFHOME}/lib/Linux_64) + ELSE() + SET(BLSURF_LIBS_PATHS ${BLSURF_LIBS_PATHS} ${BLSURFHOME}/lib/Linux) + ENDIF() +ENDIF(WINDOWS) + +FIND_LIBRARY(BLSurf BLSurf PATHS ${BLSURF_LIBS_PATHS}) +FIND_LIBRARY(PreCAD PreCAD PATHS ${BLSURF_LIBS_PATHS}) +FIND_LIBRARY(distene distene PATHS ${BLSURF_LIBS_PATHS}) + +SET(BLSURF_LIBS) +SET(BLSURF_LIBS ${BLSURF_LIBS} ${BLSurf}) +SET(BLSURF_LIBS ${BLSURF_LIBS} ${PreCAD}) +IF(distene) + SET(BLSURF_LIBS ${BLSURF_LIBS} ${distene}) +ENDIF(distene) diff --git a/adm_local/cmake_files/Makefile.am b/adm_local/cmake_files/Makefile.am new file mode 100644 index 0000000..b21e68d --- /dev/null +++ b/adm_local/cmake_files/Makefile.am @@ -0,0 +1,26 @@ +# 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 +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +admlocal_cmakedir = $(admlocaldir)/cmake_files + +dist_admlocal_cmake_DATA = \ +FindBLSURF.cmake + diff --git a/adm_local/unix/Makefile.am b/adm_local/unix/Makefile.am index f70a09e..55a47ce 100644 --- a/adm_local/unix/Makefile.am +++ b/adm_local/unix/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) diff --git a/adm_local/unix/config_files/Makefile.am b/adm_local/unix/config_files/Makefile.am index 5091235..01174b3 100644 --- a/adm_local/unix/config_files/Makefile.am +++ b/adm_local/unix/config_files/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) diff --git a/adm_local/unix/config_files/check_BLSURF.m4 b/adm_local/unix/config_files/check_BLSURF.m4 index cfe354a..ae7bab8 100644 --- a/adm_local/unix/config_files/check_BLSURF.m4 +++ b/adm_local/unix/config_files/check_BLSURF.m4 @@ -1,30 +1,31 @@ -dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D 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 + dnl File : check_BLSURF.m4 dnl Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) - +dnl AC_DEFUN([CHECK_BLSURF],[ AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_PROG_CXXCPP])dnl -AC_CHECKING(for BLSURF commercial product) +AC_CHECKING([for BLSURF commercial product]) AC_LANG_SAVE AC_LANG_CPLUSPLUS @@ -32,7 +33,7 @@ AC_LANG_CPLUSPLUS BLSURF_INCLUDES="" BLSURF_LIBS="" -AC_ARG_WITH(blsurf, +AC_ARG_WITH([blsurf], [ --with-blsurf=DIR root directory path of BLSURF installation]) BLSURF_ok=no @@ -58,34 +59,43 @@ if test "$with_blsurf" != "no" ; then echo BLSURF commercial product to generate 2D mesh. echo - BLSURF_INCLUDES="-I$BLSURF_HOME/include" - BLSURF_LIBS="-L$BLSURF_HOME/lib -lBLSurf" + LOCAL_INCLUDES="-I$BLSURF_HOME/include" + LOCAL_LIBS="-L$BLSURF_HOME/lib/Linux" + archtest="$(`which arch`)" + if test "x$archtest" = "x" ; then + archtest="`uname -m`" + fi + if test $archtest = "x86_64" ; then + LOCAL_LIBS="-L$BLSURF_HOME/lib/Linux_64" + fi + LOCAL_LIBS="${LOCAL_LIBS} -ldistene -lBLSurf -lPreCAD" CPPFLAGS_old="$CPPFLAGS" CXXFLAGS_old="$CXXFLAGS" - CPPFLAGS="$BLSURF_INCLUDES $CPPFLAGS" - CXXFLAGS="$BLSURF_INCLUDES $CXXFLAGS" + CPPFLAGS="$LOCAL_INCLUDES $CPPFLAGS" + CXXFLAGS="$LOCAL_INCLUDES $CXXFLAGS" - AC_MSG_CHECKING(for BLSURF header file) + AC_MSG_CHECKING([for BLSURF header file]) - AC_CHECK_HEADER(distene/api.h,BLSURF_ok=yes,BLSURF_ok=no) + AC_CHECK_HEADER([distene/api.h],[BLSURF_ok=yes],[BLSURF_ok=no]) if test "x$BLSURF_ok" == "xyes"; then - AC_MSG_CHECKING(for BLSURF library) + AC_MSG_CHECKING([for BLSURF library]) - LDFLAGS_old="$LDFLAGS" - LDFLAGS="-L. -$BLSURF_LIBS $LDFLAGS" + LIBS_old="$LIBS" + LIBS="-L. $LOCAL_LIBS $LIBS" AC_TRY_LINK( - #include "distene/api.h", - BLSURF_init();, +extern "C" { +#include "distene/api.h" +}, distene_context_new(), BLSURF_ok=yes,BLSURF_ok=no ) - LDFLAGS="$LDFLAGS_old" + LIBS="$LIBS_old" - AC_MSG_RESULT($BLSURF_ok) + AC_MSG_RESULT([$BLSURF_ok]) fi CPPFLAGS="$CPPFLAGS_old" @@ -95,11 +105,13 @@ if test "$with_blsurf" != "no" ; then fi if test "x$BLSURF_ok" == xno ; then - AC_MSG_RESULT(for BLSURF: no) - AC_MSG_WARN(BLSURF includes or libraries are not found or are not properly installed) - AC_MSG_WARN(Cannot build without BLSURF. Use --with-blsurf option to define BLSURF installation.) + AC_MSG_RESULT([for BLSURF: no]) + AC_MSG_WARN([BLSURF includes or libraries are not found or are not properly installed]) + AC_MSG_WARN([Cannot build without BLSURF. Use --with-blsurf option to define BLSURF installation.]) else - AC_MSG_RESULT(for BLSURF: yes) + BLSURF_INCLUDES=$LOCAL_INCLUDES + BLSURF_LIBS=$LOCAL_LIBS + AC_MSG_RESULT([for BLSURF: yes]) fi AC_SUBST(BLSURF_INCLUDES) diff --git a/adm_local/unix/config_files/check_BLSURFPLUGIN.m4 b/adm_local/unix/config_files/check_BLSURFPLUGIN.m4 index 1756adf..767c9f2 100644 --- a/adm_local/unix/config_files/check_BLSURFPLUGIN.m4 +++ b/adm_local/unix/config_files/check_BLSURFPLUGIN.m4 @@ -1,24 +1,25 @@ -dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D 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 + dnl File : check_BLSURFPLUGIN.m4 dnl Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) - +dnl AC_DEFUN([CHECK_BLSURFPLUGIN],[ AC_CHECKING(for BLSURF mesh plugin) @@ -29,36 +30,46 @@ BLSURFPLUGIN_LDFLAGS="" BLSURFPLUGIN_CXXFLAGS="" AC_ARG_WITH(BLSURFplugin, - [ --with-BLSURFplugin=DIR root directory path of BLSURF mesh plugin installation ]) + --with-BLSURFplugin=DIR root directory path of BLSURF mesh plugin installation, + BLSURFPLUGIN_DIR="$withval",BLSURFPLUGIN_DIR="") -if test "$with_BLSURFplugin" != "no" ; then - if test "$with_BLSURFplugin" == "yes" || test "$with_BLSURFplugin" == "auto"; then - if test "x$BLSURFPLUGIN_ROOT_DIR" != "x" ; then - BLSURFPLUGIN_DIR=$BLSURFPLUGIN_ROOT_DIR - fi - else - BLSURFPLUGIN_DIR="$with_BLSURFplugin" - fi +if test "x$BLSURFPLUGIN_DIR" = "x" ; then + +# no --with-BLSURFplugin option used + + if test "x$BLSURFPLUGIN_ROOT_DIR" != "x" ; then + + # SALOME_ROOT_DIR environment variable defined + BLSURFPLUGIN_DIR=$BLSURFPLUGIN_ROOT_DIR - if test "x$BLSURFPLUGIN_DIR" != "x" ; then - if test -f ${BLSURFPLUGIN_DIR}/lib${LIB_LOCATION_SUFFIX}/salome/libBLSURFEngine.so ; then - BLSURFplugin_ok=yes - AC_MSG_RESULT(Using BLSURF mesh plugin distribution in ${BLSURFPLUGIN_DIR}) - BLSURFPLUGIN_ROOT_DIR=${BLSURFPLUGIN_DIR} - BLSURFPLUGIN_LDFLAGS=-L${BLSURFPLUGIN_DIR}/lib${LIB_LOCATION_SUFFIX}/salome - BLSURFPLUGIN_CXXFLAGS=-I${BLSURFPLUGIN_DIR}/include/salome - else - AC_MSG_WARN("Cannot find compiled BLSURF mesh plugin distribution") - fi - else - AC_MSG_WARN("Cannot find compiled BLSURF mesh plugin distribution") + else + + # search Salome binaries in PATH variable + AC_PATH_PROG(TEMP, libBLSURFEngine.so) + if test "x$TEMP" != "x" ; then + BLSURFPLUGIN_DIR=`dirname $TEMP` fi + + fi + fi -AC_MSG_RESULT(for BLSURF mesh plugin: $BLSURFplugin_ok) +if test -f ${BLSURFPLUGIN_DIR}/lib${LIB_LOCATION_SUFFIX}/salome/libBLSURFEngine.so ; then + BLSURFplugin_ok=yes + AC_MSG_RESULT(Using BLSURF mesh plugin distribution in ${BLSURFPLUGIN_DIR}) -AC_SUBST(BLSURFPLUGIN_ROOT_DIR) -AC_SUBST(BLSURFPLUGIN_LDFLAGS) -AC_SUBST(BLSURFPLUGIN_CXXFLAGS) + if test "x$BLSURFPLUGIN_ROOT_DIR" == "x" ; then + BLSURFPLUGIN_ROOT_DIR=${BLSURFPLUGIN_DIR} + fi + BLSURFPLUGIN_CXXFLAGS+=-I${BLSURFPLUGIN_ROOT_DIR}/include/salome + BLSURFPLUGIN_LDFLAGS+=-L${BLSURFPLUGIN_ROOT_DIR}/lib${LIB_LOCATION_SUFFIX}/salome + AC_SUBST(BLSURFPLUGIN_ROOT_DIR) + AC_SUBST(BLSURFPLUGIN_LDFLAGS) + AC_SUBST(BLSURFPLUGIN_CXXFLAGS) +else + AC_MSG_WARN("Cannot find compiled BLSURF mesh plugin distribution") +fi + +AC_MSG_RESULT(for BLSURF mesh plugin: $BLSURFplugin_ok) ])dnl diff --git a/adm_local/unix/make_common_starter.am b/adm_local/unix/make_common_starter.am index 56185e3..623dfe5 100644 --- a/adm_local/unix/make_common_starter.am +++ b/adm_local/unix/make_common_starter.am @@ -1,25 +1,34 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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 : make_common_starter.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@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 diff --git a/bin/Makefile.am b/bin/Makefile.am index 4af7144..24e249a 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) diff --git a/bin/VERSION.in b/bin/VERSION.in index 8dc58d9..b5c7064 100755 --- a/bin/VERSION.in +++ b/bin/VERSION.in @@ -1 +1,3 @@ -THIS IS SALOME - BLSURFPLUGIN VERSION: @VERSION@ +[SALOME BLSURFPLUGIN] : @VERSION@ +[DEVELOPMENT] : @VERSION_DEV@ +[DESCRIPTION] : DISTENE BLSurf meshing plug-in for SALOME Mesh module diff --git a/build_cmake b/build_cmake new file mode 100755 index 0000000..2a9a278 --- /dev/null +++ b/build_cmake @@ -0,0 +1,27 @@ +#!/bin/sh +# 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 +# + +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 --blsurfplugin +status=$? +cd ${CURRENT_DIR} +exit $status diff --git a/build_cmake.bat b/build_cmake.bat new file mode 100644 index 0000000..de8ae03 --- /dev/null +++ b/build_cmake.bat @@ -0,0 +1,20 @@ +@REM Copyright (C) 2007-2012 CEA/DEN, EDF R&D +@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 --blsurfplugin diff --git a/build_configure b/build_configure index 0307b0e..1b0e6de 100755 --- a/build_configure +++ b/build_configure @@ -1,22 +1,23 @@ #!/bin/bash -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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 : build_configure # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -24,7 +25,6 @@ # ORIG_DIR=`pwd` CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` -BLSURFPLUGIN_WITH_GUI="yes" ######################################################################## # Test if the KERNEL_ROOT_DIR is set correctly @@ -41,28 +41,6 @@ fi # exit #fi -for option -do - case $option in - -with-gui | --with-gui) - BLSURFPLUGIN_WITH_GUI="yes" - break;; - -without-gui | --without-gui | -with-gui=no | --with-gui=no) - BLSURFPLUGIN_WITH_GUI="no" - break;; - esac -done - -######################################################################## -# Test if the GUI_ROOT_DIR is set correctly - -if test ${BLSURFPLUGIN_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 @@ -91,40 +69,17 @@ cd ${CONF_DIR} ABS_CONF_DIR=`pwd` ####################################################################### -# Update configure.ac script: to set BLSURFPLUGIN_WITH_GUI variable -sed -e s/BLSURFPLUGIN_WITH_GUI=[a-z]*/BLSURFPLUGIN_WITH_GUI=${BLSURFPLUGIN_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 -#cp -f ${SMESH_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 +# custom macro embedded in the directory adm_local/unix/config_files # and KERNEL config_files directory. # output: # aclocal.m4 # autom4te.cache (directory) -echo "====================================================== aclocal" +echo "======================================================= aclocal" -if test ${BLSURFPLUGIN_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 \ @@ -145,10 +100,10 @@ fi # 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 @@ -168,11 +123,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 8f00366..d117926 100755 --- a/clean_configure +++ b/clean_configure @@ -1,22 +1,23 @@ #!/bin/bash -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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 : clean_configure # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -25,13 +26,6 @@ rm -rf autom4te.cache aclocal.m4 configure make_config find . -name "*~" -print -exec rm {} \; find . -name "*.pyc" -print -exec rm {} \; +find . -name Makefile.in | xargs rm -f +( cd adm_local/unix/config_files && rm -f config.* depcomp install-sh l*.m4 ltmain.sh missing py-compile ) -# ... - -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 src -name Makefile.in | xargs rm -f -rm -f Makefile.in diff --git a/configure.ac b/configure.ac index 57c3fd7..a8d2a7e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,35 +1,38 @@ #!/bin/bash -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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 : configure.ac # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) # --- # -AC_INIT([Salome2 Project BLSURFPLUGIN module], [5.1.0], [webmaster.salome@opencascade.com], [SalomeBLSURFPLUGIN]) -AC_CONFIG_AUX_DIR(salome_adm/unix/config_files) +AC_INIT([Salome2 Project BLSURFPLUGIN module], [6.5.0], [webmaster.salome@opencascade.com], [SalomeBLSURFPLUGIN]) +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=blsurfplugin @@ -71,6 +74,7 @@ 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 ! @@ -92,7 +96,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='\${KERNEL_ROOT_DIR}'/salome_adm/unix/config_files/install-sh + INSTALL='\${KERNEL_ROOT_DIR}'/adm_local/unix/config_files/install-sh ;; esac @@ -152,7 +156,15 @@ dnl testing MPICH dnl --------------------------------------------- dnl -CHECK_MPICH +dnl CHECK_MPICH + +echo +echo --------------------------------------------- +echo testing MPI +echo --------------------------------------------- +echo + +CHECK_MPI echo echo --------------------------------------------- @@ -228,11 +240,34 @@ AC_SUBST_FILE(CORBA) corba=make_$ORB CORBA=adm_local/unix/$corba -BLSURFPLUGIN_WITH_GUI=yes +echo +echo --------------------------------------------- +echo Testing GUI +echo --------------------------------------------- +echo -AM_CONDITIONAL(BLSURFPLUGIN_ENABLE_GUI, [test "${BLSURFPLUGIN_WITH_GUI}" = "yes"]) +CHECK_GUI_MODULE -if test "${BLSURFPLUGIN_WITH_GUI}" = "yes"; then +gui_ok=no +if test "${SalomeGUI_need}" != "no" -a "${FullGUI_ok}" = "yes" ; then + gui_ok=yes +fi + +AM_CONDITIONAL(BLSURFPLUGIN_ENABLE_GUI, [test "${gui_ok}" = "yes"]) + +if test "${SalomeGUI_need}" == "yes"; then + if test "${FullGUI_ok}" != "yes"; then + AC_MSG_WARN(For configure BLSURFPLUGIN 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 "${gui_ok}" = "yes"; then echo echo --------------------------------------------- echo testing openGL @@ -248,35 +283,15 @@ if test "${BLSURFPLUGIN_WITH_GUI}" = "yes"; then echo CHECK_QT +fi - echo - echo --------------------------------------------- - echo testing VTK - echo --------------------------------------------- - echo - - CHECK_VTK - - echo - echo --------------------------------------------- - echo Testing GUI - echo --------------------------------------------- - echo - - CHECK_SALOME_GUI - - echo - echo --------------------------------------------- - echo Testing full GUI - echo --------------------------------------------- - echo +echo +echo --------------------------------------------- +echo testing VTK +echo --------------------------------------------- +echo - CHECK_CORBA_IN_GUI - if test "x${CORBA_IN_GUI}" != "xyes"; then - echo "failed : For configure BLSURFPLUGIN module necessary full GUI !" - exit - fi -fi +CHECK_VTK echo echo --------------------------------------------- @@ -351,11 +366,13 @@ echo #AM_CONDITIONAL( USE_GFORTRAN, [test "$F77" = "gfortran"]) echo Configure -if test "${BLSURFPLUGIN_WITH_GUI}" = "yes"; then -variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok SMesh_ok SalomeGUI_ok BLSURF_ok" -fi -if test "${BLSURFPLUGIN_WITH_GUI}" = "no"; then -variables="cc_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 SMesh_ok BLSURF_ok" + +if test "${gui_ok}" = "yes"; then + variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok SMesh_ok gui_ok BLSURF_ok" +elif test "${SalomeGUI_need}" != "no"; then + variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok SMesh_ok gui_ok BLSURF_ok" +else + variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok SMesh_ok BLSURF_ok" fi for var in $variables @@ -376,6 +393,9 @@ else AC_SUBST(SETX) SETX="set -x" fi +dnl Build with SMESH cancel compute feature +AC_DEFINE(WITH_SMESH_CANCEL_COMPUTE) + dnl copy shells and utilities contained in the bin directory dnl excluding .in files (treated in AC-OUTPUT below) and CVS dnl directory @@ -391,22 +411,43 @@ 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 \ - ./idl/Makefile \ - ./resources/Makefile \ - ./src/Makefile \ - ./src/BLSURFPlugin/Makefile \ - ./src/GUI/Makefile \ - ./BLSURFPLUGIN_version.h \ + adm_local/Makefile \ + adm_local/unix/Makefile \ + adm_local/unix/config_files/Makefile \ + adm_local/cmake_files/Makefile \ + doc/Makefile \ + doc/salome/Makefile \ + doc/salome/gui/Makefile \ + doc/salome/gui/BLSURFPLUGIN/Makefile \ + doc/salome/gui/BLSURFPLUGIN/doxyfile \ + doc/salome/gui/BLSURFPLUGIN/doxyfile_py \ + doc/salome/gui/BLSURFPLUGIN/static/header.html \ + doc/salome/gui/BLSURFPLUGIN/static/header_py.html \ + doc/salome/tui/Makefile \ + doc/salome/tui/doxyfile \ + bin/VERSION \ + bin/Makefile \ + idl/Makefile \ + resources/Makefile \ + src/Makefile \ + src/BLSURFPlugin/Makefile \ + src/GUI/Makefile \ + BLSURFPLUGIN_version.h \ Makefile \ ]) diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..7c206a5 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,32 @@ +# 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 +# + +# -* Makefile *- +# Author : Patrick GOLDBRONN (CEA) +# Date : 30/11/2001 +# +SUBDIRS = salome + +usr_docs: + (cd salome && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +docs: usr_docs + +dev_docs: + (cd salome && $(MAKE) $(AM_MAKEFLAGS) dev_docs) diff --git a/doc/salome/Makefile.am b/doc/salome/Makefile.am new file mode 100644 index 0000000..f5de046 --- /dev/null +++ b/doc/salome/Makefile.am @@ -0,0 +1,38 @@ +# 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 +# + +# -* Makefile *- +# Author : Patrick GOLDBRONN (CEA) +# Date : 30/11/2001 +# +SUBDIRS = tui gui +SUBDIRSTUI = tui +SUBDIRSGUI = gui + +usr_docs: + @@SETX@; for d in $(SUBDIRSGUI); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done; + +docs: usr_docs + +dev_docs: + @@SETX@; for d in $(SUBDIRSTUI); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done; diff --git a/doc/salome/gui/BLSURFPLUGIN/Makefile.am b/doc/salome/gui/BLSURFPLUGIN/Makefile.am new file mode 100644 index 0000000..1746a98 --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/Makefile.am @@ -0,0 +1,66 @@ +# 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 +# + +# File : Makefile.in +# Author : Vasily Rusyaev (Open Cascade NN) +# Module : doc +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +EXTRA_DIST += images input static/footer.html static/doxygen.css + +guidocdir = $(docdir)/gui/BLSURFPLUGIN +guidoc_DATA = images/head.png + + +usr_docs: doxyfile + echo "===========================================" ; \ + echo "Generating Python interface documentation"; \ + echo "===========================================" ; \ + $(DOXYGEN) doxyfile_py \ + echo "===========================================" ; \ + echo "Generating GUI documentation" ; \ + echo "===========================================" ; \ + $(DOXYGEN) doxyfile ; + +docs: usr_docs + +clean-local: + @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/BLSURFPLUGIN + @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/BLSURFPLUGIN ;; \ + esac ; \ + done ; + cp -rp $(srcdir)/images/head.png $(DESTDIR)$(docdir)/gui/BLSURFPLUGIN/blsurfpluginpy_doc/ ; + +uninstall-local: + rm -rf $(DESTDIR)$(docdir)/gui/BLSURFPLUGIN \ No newline at end of file diff --git a/doc/salome/gui/BLSURFPLUGIN/doxyfile.in b/doc/salome/gui/BLSURFPLUGIN/doxyfile.in new file mode 100755 index 0000000..1a8f9a5 --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/doxyfile.in @@ -0,0 +1,72 @@ +# 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 +# + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "BLSURFPLUGIN Module Reference Manual v.@VERSION@" +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 +IMAGE_PATH = @srcdir@/images + +#--------------------------------------------------------------------------- +#HTML related options +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_HEADER = @builddir@/static/header.html +HTML_FOOTER = @srcdir@/static/footer.html +HTML_STYLESHEET = @srcdir@/static/doxygen.css +TOC_EXPAND = YES +DISABLE_INDEX = NO +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 300 + +#--------------------------------------------------------------------------- +#LaTeX related option +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO + +#--------------------------------------------------------------------------- +#RTF related options +#--------------------------------------------------------------------------- +GENERATE_RTF = NO + +#--------------------------------------------------------------------------- +#External reference options +#--------------------------------------------------------------------------- + +#rnv: 07.04.2011 Workaround for the doxygen 1.7.3: +#because it wrongly defines location of the html files for search. +TAGFILES = blsurfpluginpy_doc.tag=../BLSURFPLUGIN/blsurfpluginpy_doc +SEARCHENGINE = YES \ No newline at end of file diff --git a/doc/salome/gui/BLSURFPLUGIN/doxyfile_py.in b/doc/salome/gui/BLSURFPLUGIN/doxyfile_py.in new file mode 100755 index 0000000..68057ba --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/doxyfile_py.in @@ -0,0 +1,159 @@ +# 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 +# + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "SALOME BLSURFPLUGIN User's Guide" +OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = NO +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 5 +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = YES +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = YES +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +MAX_INITIALIZER_LINES = 25 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +EXCLUDE_SYMLINKS = NO +EXAMPLE_RECURSIVE = NO + +#--------------------------------------------------------------------------- +#Input related options +#--------------------------------------------------------------------------- +INPUT = @top_srcdir@/src/BLSURFPlugin/BLSURFPluginDC.py +FILE_PATTERNS = +IMAGE_PATH = @srcdir@/images +RECURSIVE = NO +EXAMPLE_PATH = + +#--------------------------------------------------------------------------- +#HTML related options +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = blsurfpluginpy_doc +HTML_HEADER = @builddir@/static/header_py.html +HTML_FOOTER = @srcdir@/static/footer.html +HTML_STYLESHEET = @srcdir@/static/doxygen.css +TOC_EXPAND = YES +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO + +#--------------------------------------------------------------------------- +#LaTeX related option +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO + +#--------------------------------------------------------------------------- +#RTF related options +#--------------------------------------------------------------------------- +GENERATE_RTF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = NO +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +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 +MAX_DOT_GRAPH_HEIGHT = 1200 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = NO +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +#External reference options +#--------------------------------------------------------------------------- +GENERATE_TAGFILE = blsurfpluginpy_doc.tag +SEARCHENGINE = YES \ No newline at end of file diff --git a/doc/salome/gui/BLSURFPLUGIN/images/blsurf_attractors.png b/doc/salome/gui/BLSURFPLUGIN/images/blsurf_attractors.png new file mode 100644 index 0000000000000000000000000000000000000000..a0e0276c3b3203693abbf6aa5e9b4f2cb9799703 GIT binary patch literal 195990 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 z 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±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

    X*0kEJ7z!;bl{K44r(Aaa2q;`H~eiB|pwH zKg|Iw;(2Z~f({XxUriivg|92tWL9DhjqGL>@8|PehZUWRghwI3=7wBByPjVxSEL58 zPM=b^`JMgL<{EBI4f)F}xN|3W?h>&Yz_GBI@S}gik`u^tKYyJ3{GZ9S*y?k_y7hOs zJ=ZrkarfL!T&tLI0vujGfQnK~xzSpK-5t1TD`5!?N_=@6=^nuIU&G`QECt-bWpY7@ z(gMzvfI&bWC_ysKnJBWUl-plt;%II;LDmrN`UF|XVn-3zzBxa+IiFFXV;gn03-@h9 zD3AFFxw($J>f;8z!jGq7?gR-EZIYroZ2TowyuC2rEQ`jHsTd>lxcy3pL1vcRp<{mW z?&Xd;>n~qC-4jo*FVQ~4%d09)%XI}K5}tR_A6kvCDK*xmvM>MoosNCYsL-yCPLEHW zqW7P0*5}lZu5IrQS^o8q~?JjIGj;t|PfAtlB&w&6*p;0ZAlmu4d z-dpQ~Cp_)bt7YKmPrluoqvx3z~Wm~pTt%hLBMg$bihhW6OVO7 zFE0BhFJ(r%&|Fowt@2oG`i_gtAUjc*&I%6?S-lxgTe)~^#mue-{r8^F9{8Z1<7h(g z3zOpl*p^Z??jV&P-5r6V`hQ23US7(!}#rq<9B<1%ULzIEa{ zp1|TosRFc!KIJ4k%gIlk#qttz9C~_5B94<6(Km+43EZ#~Iu*$qj*!kyL;<}45)pzc_?Mqza0F2b?{-6>z+wPqC0-dqa~&4*c+-vTWyB`q z8U%S0pUw%$R4n(@JW)u9PR@Pk#UF#DK?nttozXIb8Wbu~!zZd7apvi~mG%_os2%7f ztWZs@Qsm@R>}n*bR;Aj?gw6V7V*#l&kzX90EwXET;ebgYnv?0WOjakQHW($cZ2Ej8 z<22~o4WgE{j`l=?uaZ3SR_}#rkJX~R$>S~8a{LyHjhCd9T;pErIs9CdKNX?>{)N4j z<#AQ%a_Lp$M170mj)HYdBeH*ep6xwcx67PcQ&aKq2W#&vANgQFx)hLu$AacS6O}mm z>zxfLLBXBxQs1~cI_gPqF(sSjml`LPg8FD=;qUwKz)Q2s2@MDVC=kk(beSEw?{DCF z=;aTmZ(;IUiFj2kOo+v+%DUg|kQbPQvey=g`|3V0dE}}8wAClUKFgc&)k%Z`wczC9 z1SQJz-#W7R#|Mhv(LZy0%Z|?Xd61+0{{U&qxv^zIveiT3J z(v8}AGLLU1kqUYhE5|G5Pg88~g6wv7=S8vkAo`nzi?$ellus4QQAjl#lEDRfaOu6y z%MmGEl#z&g7uVg`61Gc=Et>HSx&~|ck%(DM11PC z!C-!te`h=86=s`CXnlEB9H(#Dj&&^vCZRRKzl>5lR#p&Cpst3Ro_gV$tv(0qV28=P zKb_G=lgK3TZ%^Rr5?bmZlfoNDR)#1KQYkKvaZSZUD8Nbp{xsx#&dd=OIN{0-d14_} z6pta`4c((poc0LHWz^Xq`JpQLA5Jy+ADm0lX91PCsWi4^Pic8v(#tP9$)0+8X zf;c10Y?bTkTK`yM9jY}f*eOF_tXssKZWrIQ7&e8{H1gy>ZN(9QKoFAarn8p*uj()T zv4d@DNSUqN!S2=9cWvlm=P!)Pi?@t-+~_J2tB*}z<;xP^>A<-$))N!}gb@7j=FGFb zk~x17cv;tqYQkq|vn3iU{qLR=+}Rd>{7&QgA1y^v@?4Z@Z8N^`clCx=L0Q|%@{HKo zEllYXw1!S6a__vje7fH`a4B$CbjSMAW|dfK5vp~bY|CP)vaY%_nY24S|8}CQ$SiXD z6C$;M5p!3fesN8~i*H>TJvcmGsZKG19b!wJAm1WTou2T%|5|q`MX&G)Ka?=Hl}rJJ zW=;QcG#$;X(}-Fb?v>fFGng#YNDeO~7X3+OntrC4nVUC&2=a*B%w_9>I#Vov$fV-Pnany zNcF7dY%=Z!8^2t_8F~2}DH>T1@z~-r zU&^OxGC<)fNsmOG?Lyu?U}!1{RlLy1rc5z&4e^%pWcCG~9EY=+erBGhycFk0*3>dx zN>{8Vd8?WOFLOG7gDP<8sD(G#*G z&!v6R<()<9gCAeo|I^l4Z-rLFAMGrNCx9IF!aw%(`EPjPqFJX{{X+dnBF4XPl?4N^ zygLdecGX(Hc(Lg5bxVI8=6r7JmAPzLjUSrG*URbq>;5u!uKdH}D^-H*dKJBvm-{W~CVS@$y;nLe_3a)Quc!R>UuvfW0Nx4#`9I>gX@IB>bNr57fR){73G$_8<`xHFJyWLZN9Sq!QOlSxm8{3 z|Ia=}y=$Z?nkr52_7soH*yD-~Hocb+0-+=%KnR2+H$W;RHwh4KLIQ*uAeas=xVLc` zPw%~trbwev@8_KT{ej%v`uPL+UY=i1k@o8)ye{*eC#dqD##cZ%5&okE2$Rh9V z{;+Osoie{T;`DpltX;QmU;X+I>C0{8WIy@h9#rh^@_q}>_!_LOe z_Ax1%6sYJ$QX^Nt_1gm`YwAN=*K{!g-Qc)>&xUj_JM{k80oPPxeoB9@PixbKBk@#+ zwToi>_)w9x7va++Ws)t|61y3h8E73N3ZTFNQ9v+&GiQ*Oj-!VFkS$xK z6UW`a#jj}frIw8s>tsN zq%<0cN~9?jjJBRL$J_bvawIw6toCpeGZKBMmE?qIs#s;-=T) zvEO}UZ7SBuxs~ooH31&IQuxiuOmGySkXT6UY&2Ax$vv`Rw8NttNZQ85Q6$*dA`x}b zZQD(4t-kgi!OYv&Zww2{NKrxF$v;Y+7u_;FS6ZWX)G7r*cK($<=V-9-8b@kFI+vz7 zIyC2R>3{5&&5lg_h$$%+>C99&J}=5grOR!u_H)vFAhfs=PWXh?t5aTnztcSss@qni zC`k+RTwZAoS%~R{#8qbg@NiJ0Wbzq89cFJ>Sav6J6~tuXygsT+*XC)s2%{;;j!i~M zS%y3$kO{w(%dtgTW?7&we9EoKA}_s#bwwCo#K;5+v*C|H6i`|K1q;0bY7Mfou;hY9 zv$VMQ>HiP@vE2V*TBTB~l0<0rP$>~-ph%!|08~QXD266bUxjod^74p_NqSwfBuy6S zl&&Zl48~xTT~R9kXwVyVhx9p_2A{}_#FwN~QI|}SGOTAsnbcTjO`lu7VAN?ec6pqV z;pvKeTcjxOPWGHOD;H)U4 zy^sh5{;vF)0GIjsg5is)gE3JCP{iIig#2>@ngTqZq|S^EE?MLlnB}K0&rt2#bRw>r z_77ckY{aG(=*F54$D#%Q(p&T1n&{S<_x{%9Xm6!#S?k*E4MJJy(;f{7m5}5)fr{qu zyurMEFLSipy|8S-KR+WWS7_$0S+jg))nd9TBmv3P70YGf-8+zQatotukJs&$`BjD1 z$jOr9qjR3jl#03q0;cfZcnP0MlT2~GHoHhXuZmZspagXi(mU)U#}+||{I zuW0opmP&2&`WsffC@#UOD#W!|n!~yp_`Kj4G}U2d0S+7fb{K3XsdtcK3p4D7lnxh- zm*gp4?wc~0RYHvLG%=SDFV9yE_~YWFAKB(*MYJMQ_sOxL%oUIQlFHZKKfh{CL8{I4 zrjlQhGpnZ-FHl@pUv}_ZUr^1MwW`6~RF`r&iwUYG*!Ozd#HpnlACUd2rDgU5%Zs~H zZY`)8J3Hk~GZhZHj=C2d8!Nk=dpmlL?P|E$kdyL@)GJ=4twVp(u0-Us&c%&4imr=d z=OK-AJm-pUP4f!z%vo914TJKH~t-Y@O? z0ZRZ#41{Ebz3;o5oc5Hdch45rSnZ2?&zd6UtvBj6IMnjYVMEi@om!1TmMZOGqHBT~ zxuysoOEXszi2gkvP7dDAsUlNJS8^hfXEQWx+|qL_5k4AuO>lni=5_g04Aa2*S0|u? zV~;ssrt_;JnX9EaAK?f)XPqAXSf84zO|Mtg$TXJn@?mGpduTGfk&LIP&HlvKuP=Pf z7f}I_u^xlW=1n-2Tvk*nvTN29YgUwOWOYh8;olpJGz$umGU;(?G9cvW$#Njcv9hTc z8H|dL)UclpN^^7UH!qR6 zmR1?*iggWIosKFLm|wuyD6ZLtiyc_M8h`r)t^nc!mIY)v=&n^kwri$p6y1@LEaM)fJn+{dom=;h#~@QY1-P zUZK$ZOQWXEEuMGFDJB2KoR?%99f1@q&PGjBsX5>{5DG}3QiFfy_DeQCsBUzJp@cxF zl$2?n!wy*@@TbJfU{&~^^8h#+4F^IPbs=?V%Cfvr1X&!A3^G>EU_KZFhcTDlk!0K!5T7hjl zxG0W?g@|;nJ$!gtkc+6wP*j`Q+wxS~i@2XvD!fs7@0_q0M>5ELEr%^hCD%Au9*E8{ zX*OxjO+IR-*(nf2^z{>?j4ZDp%>ppE{zgzhh{2%O+A^>CDz^Ia$`}aU(%B8Kmt3(M z<4!=tCr7a2!~9x5;Ji} zeY9mJu9ZtWv$YzZkk5$g%N6hYWuvv3m!#m^-(E*e>a--TWpON?c=P<6d@iu(nsU#A z@0FuN<>l#hcWgZZTDQtkd7$qHubf#`n3kQPdE;+0_RR2|a!iukGnGvhybaa<8p(Un;GP3rT_E3NyOtnVlCuV0z#QKfHo^?!oIfD)VA zR@JGtmDsZ_c~*I@9Vri0vQnN)O!|11j4Vc9j9jp!#9!==OfOY|VZabD0vJpO!WZU? zc4^&NsfOqK^Apm4Eo(|lre*Su)pMU50AxU$ztK|?ku#cqV2)v{JyVZeyX9-qihuxc z^ovxCp%OU0Nx1t+e*4$YJ^xzv{Sf2-<%KczeS6wYIdwPXTTPa8PFDi}P&QpQo59UZ zMXLY_y!84Y_l+&r-rM)De;%och~k_5t^<4euiue7v6ROUN(ci&A*mjGQ?>7YGbh`7 z`cX3ET6pL!N5@1~ETS-^%oSUgTAG_iPRzb^h3sG(hqx{pHB2R9x4BbU$ga!Xh)hCIx(p5gXHLaA*0TK=hh;|xoD9ZMI+xrUq4@(fC?mqh#` z7MTzBMX%qIHxVdXI2LgZSEXuuiFIOjQ#Z+n8CZle2OKR{{D$ z8d8_10z4R5W zzO)NB81(i$e9(&Lp2ai&hVuh(Wa7*@gd%vR1>3eF8mC#=q`Ux87q>MZMd{?Xy+L=b z_{%IqVkBOsk`on1U12_iUVnU3Hg{tVh=%WUMh-PQWs9M8mlP#~k@-O2vW>YPoSlv< zWr3wYMx%YlTKhQ}_Xuco&=mDo>aIVTF5EM0()c>Y`t~*n_z0=<{67?MpRl#g))}=|p?+5D*FgECEeGL|u--A@6(OwD;=GdH)Ey7_QPadTvvyI#NwV=^yw1 zC&Kv{-3DhQK$A@;9m%`4U3j{O%5)=o&yRlR`0j(r-+ZZI7|kF3O}I5b!26G8gPNngO5Y^YZE=PDXfWUtH!KX0_c z$e!?%jiq|`OyqM9zQ0QI(-Wcli{!uRVG;sOY6P=YzOsPr*<@2D+dYQsbJ*v4Bo&x8 z7dGZ0qNj6Cva{k^1~Zqm_LXTYXuj)@ZYHR{4FfW@62H zT1rjxGqbbk;DABCB`hHDO0UV z(6uTgm1L_*_S%SBr#FAr7tSMzA6`}P)8q5CR^_k87oj35U*eu?D!XWC_Z6kH-7CL) ze>j@1-qe)yc`XHB;AaKc{oA{YUwWa?p%Cv}WP&9cAv2!rl6)detAYs-K$edCbVqH)z|Oks442 zMEru7RKk{%Iqg5-p3XrAYK&e?VWZ>hHw5eA6^ZlOcJr++u_{rXgwLn(7MOPxS z5xufAA%P`{x#X|>Y~w2BQ(>&mwNuhw%0mON6+&;;U(cydXq&4qIr zg-awHqdPYcQ3A)J`6A*=5EGC@5{u*fg&bfH@Yz?i`VyAw7~RT>eR_tjswUnba_lH8 zgP6p*K|q6@4`N3>efuabsbYqvMCUw7Gcq?75wjXcCh%mYB59><6j?F)4RZLD#TAzE> z1qB5l5K^@~adA`1#^sXcyaq_Zf3Ktev)o0cL%OEtBka4vGxy;N0D{OAI7U6p+|2Z) z5R_n;AGO7vuGQYsC2;bbfy7Op_n!n;^Y82aLjT(yvbyF8^q> zD7Vw+Z`i1;f3c?>a{ljKp1W_)aGRz3*vEd_{2T~@#4UDj?iD>%>raScF(km8tlcEZ z74-B>_*c#qdNKhX8LQ|6+Z2g$@h69Xuo{B;fj!BVjC0bW;l!Nvm)o+u387^r8cZ|I zkBAc|mXkJ>Jzsxkh3XfbLF!DLY7eZlDY~6vd5J1#D$x_f+zNd(hwt*?p$$f!P?o1# zEd+#FlOpf(QPIujYDKx6J~u#f71)_hSUb5il{{FD_kbxUU0X}u{S<*1(kUM53b|@mNwI)T8X?IcTg^y-j(L`FNd}um~ zl=(gD!be}X$D+(^tNywxX`44-u0h4J_Vfjxre=k!c81gE*ISVh(>B?2e|BQ|)T!+L zj_h@Xp#$^2O0#Bo!~|A?#94CN?^~bz=?7bQS#oRL#s0*If2tIO>dZ4wULM;&p=+LZ z-CC0Meus(@3NUeZZe*-3BdM~NHP09Zs~st+RkLn!MevzK5nEG+GP0`kRUO~_jWQ|( zkU-gPU241Q?Sizc{3WMz8z71Qfhva0bWh(P&h5*n8R3io1tFkl7BcRUny=$qA{ks% zN#ZHX<4*h7Y%wSgLaC(KRxo+oB{``4*}^}+K5CneRhDA!chbKg4W@7p#`u4utf z0JRwkhCA04w3Tk_>^NNoQHijzP?a`s|EQ8JJ#FzAku{pDhdO|b%Rr(%ng<4 zDz$jxU7T_TpSmLRSWCdD=5F1n`+18mPeq7QT3JwlA#1je?|rH1mW}SSJ;|d-($4!5 zJF?~5Rf@Ptes!(6pg=>7{PPM%?UCeJO80W&wi<2R%+1dvTL)qV*|KSuXc3u8PWnTa zba*PUK7&0N!N>~zY*@P4%oH+&NMtcYQdmaEkT(W!OE%F+_|x0C*oLxva=r)k)yPiA zEqn0zzu_m}!z+JATL$P0jT5@+Za8Js;r_}lXJ*xVjv;qJsg8N*y>X(|68u^U5O!Lu7 zw7Fw55>_x02#trb6_)dBY%b4Y_6Eb!FM6sHk{S|W*tlNdPu0Y-^x`kJyb{nV?o2QK z&NtMy)UrS#VSCFBa%#!5GLQW~u@xIKYXEXDnW7F)0>X1{lI6H3j`IYr+Mu+=KNt6l8 z665nc^6R!mDLVjcl1owi3mMQ^Lb#yurve zM`(Xv{IWv6X8{o}ArviMnyw^`7Q*m!dm%YCM-QJS+X`{#bvSwfIxS`v5eOp?fl-A` ztHDr&{P_4IVlpBxZ=|#HD_VW|Bu`DdHZ83r7zEEkrAK-mRy^3W7B(A_F)}yDT(*vu z=M$%oc$G9Fqf1dzVrI|!g-dc3Qw&N~q)yM+wJ@uhi%y}}B|ydWyQ3LMW)&DLMp>BW z)}||cLHgqywvRAA9cRf_v2l^j(_CJgc_bn1k!#~!(dt!fc1>gwQH6r7DH{tVoS4eg z*7ch!rYjqKs~yr_(RBx{U7j|-(Hg$coYU@^D?$331KcBa`|0r{Wkk7U=Dr5`3kP(f z$mJH#Y6(9zV#z9Mzov>lduTnC7=UOv*`}(#&(B!R*5w=4FPtv-JD>Vb#Wj75{HyWGlk*((8HmIsDQ;Rbe7l4G%U~i; zX*64cDW<5==3(`V3PaGZm`ll;tzJD^UpH1DWpNk7W zYp}T$$%~W8-~!|KD)P*1P!rg+%HKRm!}Hc9r{RuG{-eY4RK4!l3-E`@!@J;@;Y=6G@}O5^-h-k{_##+UjNiYFR4q;%L(^uc)i4=D zU0o-Dm9J>^rSgTU3{9J#>FkoPs)kaDX%Cco31ik#w^)$e_Ltq}`8Sm#4ABn$^%!?5w8P|gq0Ro22S(>;>oc$ns?HFeO{bFB_f)YR`6^Km9k{W>}eP6mEk!g(D ztS*~|wQ(uqm@LjeRjm%MIB8C{?B3O9@2TxBw@RU8*~z)|KXhq+c6?X!QqGU-yGEVz zK!6$QVC-wG53dsg5us~JPbF+BvO4LhiQ&p{Tvy?6n=NDYX7=NW#*1S%s68-D)|bSx zDtZQ#ey!4*u=q0aN7D;N(u)SuO>rA*?PL0zWM#_5n(lG+(KdPeptj#B*UD5mdTw^X znjWssO_kCshm`!7-GEV(Nj}HsrV&n;6qEw395G65*m(rv^t}n;stoSW=K@9p!==eq zWyvB6WM;^E0#ZF8{%B$%DNfBKVC0&zl&8*nks=hN@P2)a;ng>@`TIL`M>^DfT~)n< z*~{YckIQVY97{3S1trJ2Cgs`HgBpW(q`N%oHOvwJ?pmpHrSCgcnJ<2p4ypwq9-mZ^ zORKWSvX#oc=Nn=%IVcOt3W$@GuG{icRobb6`Rbl23pf#kt^}<=*wpj!m@62_sLh$Z ztvc}F2L)!`;rp5K*^v`9eZ%J78MacDAJxo-lu><3LY>N*vJ%u9Zqiv@gjmw71v-@@n~Q3s zYw}ZiW#03n25=;zV59<>)+!$vPsEeduV-PG=cn)|4}>Iv)|SXssVt)OXixIeJT@7p z1xDtRJ|R`jygenY)-#{XP(sM04?MwzCEQp_sDQ;e)R-_ih4O67&ZB)8DkTyztgS%n z05+_KJA{r?$h4uO0~3>A7)@Tz$n^AyuW0pUl1yH;b<3SfCDH4lR8YB=l$GLS8!gNu zgEM&KR-8PCVIPWeNktjF<79Z0W~LFVnnGZz@>vk%iI}FO(L%y*%y_Wi!zsTM1;ZJb zx@^X(2diat+49XgvMge(C*h3)3>_SeCnU0=RFSms73#>mujtY9-T;?o3Mdl!cOJ2J0la^QPEjFBu*h^ z3Z^N@gSzbDT_sC<$N33y5rzpE$6*|&hDlk<^v&gia|`9KpRcA82O@!y#Hi6~YhGgf%mvzeold813Z(Rux-N3ulgUna{LgFU7o^VD$tQ>{${uH0b41eSsm zz=#0R$b^Shb^Ya#d&yV4rZ^gRTaPVH$9gl?R`^f!WM8`hL&3Jmu`&q!cq~#_&gG_a zotnXrX)Ye(#L-npnvKKVc{kPi`$n}}4E8f;%i%46FAFQyD|b&F>&T{Y-TF-z`&;TD zkAaI?E85K_96P>g%c==?A|7<-AecEeY+k>fE-kt`T&~_@71K__1XK-1V}@dGYzi@p zE@>oGrFE-iCzNeB>KjT*W$796LN((d)M1fT+2yQ`U2kB!gyecPSDqzP8(61?$piA_ zq#~7#Xc((ROgvd*VU$`X6VMZ6${89Xc`B3|;hHCkDAIN49L9B*;iGm~)!1NzCkmMb z9D_&*)kXN|IPSOtr%&LL?eMJ7V36cH`uqD2eC1&HG69;9OQSK2Pa-W1D?ZZa6Ke%x zH8E;AvdsAKC{-!R?sQ^esdo-NE?BckE{g*qsWBs60ksLwED-mEux0~)FedKQvPK(% z46EX?HJ|xuOkxrovmkCX(RT+EB#oOFP{@*mM0nH-93xx37t(x z99H3z)ADaNMMv^no*@$)hqrR&-|M%6l9d@%t9|7=TU=ccZX^H{bwiYHEH$@K=e2nm zQf%&y>KQ^A01TBaabt5xsVf%BOUKE77&RF|N)BVZuJG2J$e{_39}`;;Oa;rm*J1zj zrS#pj$t`(`nqQ|vm5g~U%YlF(asWYyfAN;&3xDm+{$Adj;z^aN;yahc<`XqM5S+JEJO?!4+cs_qW*6-E}jv>G3@OM z{PCLxmus}LAan1}JTE@FYEw;fMMeIHP8I?|@z}cUQ6a;4HZjpjKi}BcmW>ehI&M4OPXsY#oV4 z>HZ1o4v-WDDKsPQfyYQT7vqowfx+*O2v=q@HPswRqE^GCtKstF;*zA`@JxSli-Pob zCwfJau_89N$0i5kl~wYx0-1}5+jb})x>|Q_p`6lSI}tZna)!r^u^80FD}0oLTl01+ z-?S>MVin)qwDRj_ijV=R&O}~+Uu=NdCO74z-M=&W-AiNNzcSH+#XK@KtQdVWa_Z>2 z*B<%k(jy=4{%l{Ja;YQ-`sSsjLmxLC*?aksy?c)A-E-uMNf-&s4lw^eq=z^ zdiGM!f&-!kl58euV~O-1j}rkz{s-eLO{$Td%eQh0{TuG84^hw_pEwTZD?1OmH^MacH)_vv?^6RAqnixGY{M^1_Px1n8J=#DUnQg zO^BGmQ83Bd?Cbu}x)fZowhlOUul7K(ge0@2P}aU2j!Fq6jZeK-`p}hL=*ClZG(B&= z-5r4t`XSIgTOuE|@N+BbR(EoDeE>1OKA#3vkvC2jZpz~2sxkN($Rjo? zn?K_)>K2Ba%PY&mTv!;G6^N18vY98C}6gtqKf)s`b!NB|cQn*B5Y4M+7J#YDrEyYc!H3BXcn-ofxNWt+=*0@y4mx$Rc}3qxRx*v?@I| zKA>=WkX(`aUG~BN03ZNKL_t)mE#ge$bDD60TE~8EYji_Jbc0>6n->R@k@g|$nRE7@ z4o6p~eStr`M^!T%5!m5Pqr(RQsd^V{v?m?{HDK}nu%E=8@J^2DFNDS6BH zX8ZxB@it5QFS*BV(muAozH=%9iMh2gem+q(9{9o*@DCSzD5>lAW*nM#ST*xax{x_% z=Ba4*+0M%rXA6-qf)POgiPWUJGqusrCi1{apcF)PYxISu%LBzzcZV3=50q!$UpD-W zx#Ez=^e^@iKIv%HC6 zMuG9j>WaA6E+*?T*@%IuGP5nc0x!}O8(X6#pY(|-YLc5mXb=~t(Ud{TO|WTje-$1( z0!<2z&0&2iUT6d7Lj?=194-$Ea!^-=XJ1E25r_vVX54c(_U}Vl+R{M(K49UiOz=yB zXO>;RVcjdQ;TyMOdKxmG6l7sj6~;snJj1cXvqY5{gb}egM<3V*Xz<<`x~37gVx5N^ zb>YWN93^P;L954gxu7zZgg|59Ow76l1w(Kufh}tM$iQ)S&YM7c6jMkpCZcn_Y{11J z0XdME;Fp;Ad%&Z+bRR@~E2ZSF^}0Nb;vyNWW%4#?wC7#ozYedE*<4Lbwt7oTuDY0s z=L|T_;6+5058tTz)u~8ADt~0lQqOq?oCKAtx_C0^Eu21emHw_z8OH?-)I(yy2wC>- zYNPen2aB)Vu#zP=PPiFdxC})4(+Nftgc&2AEGO&faZ%rJ?6*QAzg20|}A; zf{+0F*CQiW*O_mBlH2g(bt$}34eLuIpU=KnAR>+g!*SA#)5I=j)m0rCbvMN$CS6V! z$0uga-2pxp59z0eHcFxw~z~0K$L&6mV>8P|LDH4gT|qbxiSc9FmZ6wsk0Ri z-PgUT(ffFt3{pA>W<1>ah4{VewL@Mq=cVAplNU>VbkESav>ttZeymkOgdOY6TwCE> ze*n&~<4f$z#BSz9HOLh2d#16g7O{h2=Tb#i(N zY8C2B38G-*;38;GAXQ1$+Oa2%J~>ZL_E3X`*0J>T45nvkZi2aT6L~&LC+8`W^zka@ zh?@!toI9R`lGLr{G&4+pl&MQ$&bgUjxd#jjNBl`#$Ls%-d<+zoK-08w(`ui4-KdG)~i zO>OihoUTay$S0RO$`neh3E?)FtJ*Yua{LnDu*j3y-zfCEGjag3H; z(Mx}6J8`P?mGuMPOiKT?a3L}FOs7G&QOkb%$9MX~0K2OG!L*8=sVE0U@{3y(Joj%W z$KL&+`s78~WQcAr&>fwc1?2$&gdCp=JBo!j8@D|%GT;md|M-T4M(bX?=rUGkM*k2$ zj>aIEBn0}kO3kI(?cMsZBpXCS_=_{g=5&l`86=`KA6yLrF!W?=*`~US67tby14jo} zBw0Ybt%7e^mVfISRjQIOp!GJk$)-tC+UibRogaH+iG2MAWsZ)iA#^#4n^$qa=@r+i z87U2CdZct6`Fb&PF-Zdvy1YPk%1BI(58U*LVmvW|EtIrQ!D4~ihwY_!uNjFD9=RQF zeu9d8Famz^7><9A^fcUfGe$;WGJc8EssDqtk^@N3#2vTe>hHw727spWd)%Sj&viTN0klN*5UnS{B8k+CCLQcQb-7;pU+`7fiykij?gD&=*`*W zlWB3$#>8Fp^vPt?7Jh9y(+8wz(K{y2&2h>GVXcEXE(f~wik#r))g)iVzc>)tZ3+MJ z5QC5w#{P9B{?`s)^8Fq3M2kd4My`ld zIwL<^YkKN4Z+`v=^%u_0r9z(QYOQ+g_H$>>mWYBfGyh__KJEE72YA7|RG693$LdnV zhzS7L#7{S5-~K%R>${VP=_X&j`TMD(DVwHmFR{wxBPnUx{!cR*FsE^Jx7Sej!U9y8 zp!grH%U>9&V3Y^$%0KqYs=@ot)&8~h@;5L4WIEuueE+xqZR;mTuafWnv^p6dFE`9l@la(hDwMu16LvjA!_er;1 z<9+7t%AcJ0D82FOz{Htj@2Z!Xj>~JGXuSXQzy4_rh(s8PVTiPl`(aD>_pkr#ffug2 zVe`x*M-pEg)dfCI69(7R#`%J`gzS!0DUluN78yeTAdwSg1Lv5Y+X^cj$uyB9lpOQB zc2B>)MPZ+RBHbZcQUD16iG02s)P(hwQf?EsF*9o1Gno`Lh{)T9T-g_f? z`US`Z@Em4l(b0;HP54rG3;y4u74w8fgWGOFFoZ=HXb9601VVW94us-3)Ph|b5Q(9E z9NQb<^r2-I#DZtfB4EbWRGbWA#EnKf1dd#*A&U_dr%_EF^VAqkC=n`QAIl|ApB9uF zGBPLKatZHtis@qVWH4d2lDPrK+K||&ArW)nevvsk&K>Mw)r@k^5U8+ny#ZQVF*Gon z7n!vzhkeG}@XEMGm)D%f+7685gH0s;Nve&qwV!#t+05J*C&W;0epRTT*OHNwW{jOZ zYX>KS5wTq1@pl^XdzSjEZ&)|^>WNDrOM)TCXF|6avg=IQ7s5eEc=FB`@AfP?-8>@|et)=8abo|EKDzCXv!{pBL_voC%oT~@ z*=T_-^l8)Yf{AR?o7aV+4k#i32xy8j{H^_W-&p zZtW)<(#(ZgZ3mXGH8u`;t-n6zheSaMTCdo#tHY8L#Y)MOd&|J`0ENKbb@TGsG3`0^ z_~G~Kkko*}kRsLW2qN>u!O{4#vkah>sWLIu!Ag_9sP~CeGBA=^!&N!rc|1EU23I%< zA_xOTL^4K&l_V6r7$M7wpa!#oqL@3?FJ76>Zf;H()Vnv($01*K&v3V3p5%c zdq;6g1(D1y+HrRb+62)~&|7ACag31W0)BF8ua)(CV=L66EJ& zaNsiFL!j@gJ;5)9;-N5p`wV8CXxfgvT-uo9#*i%{s$;(|{OzXyIF zrX(oC(1+jzy}69oc&d!k4n2K-9xn~y*-pu(1Z2dLD|Lp&+yc63Gjq*qEC{s3mN29{ zzj3warrpc8U*lSr6XVRdfSxzTdxpBBh>Br>xTB=NC}UDb?NfC}Flt5&`(w9!C zzFlW3C_SGm%f8U%04IV-g3qqfyNveJkVtMpTe05oS+kX8#jub_%UpuUKq9Hx(>qGz z5vqIdK+%V zU{fe=2Os+<%_s%rp}+Tjt6^{b ze`gjKx?}e4HLZ=mtyrqZq9Z?X@8yvnzMkIJt%F%Oc)&}d5B>GIY}wm6Q7S(B%)-}q z2r~1W+O$l+XzNjmzxhOa&y_vraX$B|*KfW1vs-Uy-N@JMyP!KZ2xUyS=<_rmtwhU> zXuSz-H!97`tFmysGczF(-I~LY36P15E*8${Z9d$T7hack$%|m*kV#qTagE#%8?Grz zE@BkuHTN7*fX4lU>1Nqq(3?Ov@|Qv~pSNR_G}&dPt6A2Y(8TL&bbPO0xIXc!@3W2ci%J4z3=j9egD9I*lYa84Bwm+8?%V~ z8j>KPKu%70V9-;s)NG zjZ$eSx1bFUcsz8BmoAZkfI;(4IKRTp@=*gH-3W3Y&k{pR#Bi8O2_$?{&c;10!mz4v zhU77UfKVrriqx($?YhlnTCwE;5a3c2H%DWd7v-6z!R726b3EUW5h&8Rh5ZHr6Xy%$ zxf{j;yCHu=pKqh2+g34em5WO?L8Cxw(1#8Bpo%T7s~s-Ud;c_S@`YuP76TwiDdqBL zUeWmcrt)(;eP?#Nz5L}^k?gJzmHS{!Tuk~ zCPx5=q^h8gRy>*=vMHz!`(kgO)q;=!f(S+fokyt1X1p{nOs{gJ zRUoyRsv*e55T^&c!J?i`775XO1R{J$XKpsNdyN=;p!&N79$lO z#W^$nM1D+T!2T_=Y1v&6#uqlQ`Arvz3(lS)&AWIB;RN#t$ zk3l9Q%2k5RjYm1GN${5vDSL>S93Xiq)Sgc!?2w5`&9pe}7uFXm6RU)WA*8y3#%}QL_vH`VaMV-B@&0cehuULhpOO&H1E0w3kB8}UJ zHr8RW)0ows9gF!T?{*tFi~w;w^TZx)efLzNrD=6nw)4hvm_*`@`Rz0RTk#uPw@S3* z!aHgZaJDVwyA#yWy7+gF4VD@NQi0%9;l&TuYri(wH0jv|{P=&Dv@ltsUTV`jKU}X1 zrNw{{5G)|{@p?s(BJogO$dJza#@epa0RtfMt->|{`oCy}0h7QXp!uab|HCEo&(^=K z(I^a>i5M@;(+9J~a&ICTj8G7im(>coQ*V8#X15?M`RkH>=?(Vr$5dinC=kw}&FS(( zo?NXsu3p>7))8E&8ti?4ScV)sxgvq=1+dkg(#~n4X zG?|?h5Q?L2x8#nU(XLfd(rbi77Ec_OlwC`BN*b%_>)V;QElWU%@@lWz*Guni6m`X7 zL7Qa8EqGyX1B7%Gamnvr_>@+E2l~PnUwQK_+}MbmTToO4K^6)M z!0!hJfD+)wToj{mh=So&q|XLxHslvTmJ~{qkd8ti0re8_dZ0j#849h%Azuno71$y$ zy@@-`#A1-UF+miU(^iVIv&8+ChkQE|F-WkH%!hX^^%X#Y|Iw=d6`36ExENisgAjw3rQvK6sK?_Me%pHa`R zs^(XebN*0m)!f>84!K?a{uTYaOEABfHNRk42-|YB*d)~0*9|;T9OVwH%(n81%@Q+` zsBi2uvOnuVA%_7lA4n#zW~8ZzxH>Lw?NTc{xDj`s%D?R7oTRV&{b7#z%tt zc8Mm|(C2s47f0j(BH*CBAg(EzA6d{OyecH1J39L(hZ{k)adPka*$eeRYnU`I&T^%t z%Sc2@&7P(H9qFVH0G9pS?PZy?Vk2Kv(myN)R^SS-cNX&}QjX(IhSR-Lh>9SgOQysv zWy`LFL`JF{QAOvjq>eznG3Kb8jK%ntLNZrJEK;c&BbjBCIy`K-7;PX#WiX*5as?yJB!SjLAmt;A6zCvI$#9#TI6n;*5#r16UtN%mQG*HzIDBIm?Qe$* z*WuCI!L|vl%`n&tz=7L?#bSbh3r^?cr?mPzQ2WmBojrrpS`Y|8BnLtRlXKwQ1d|0? zYf;Y_)@#w>9dPCfs<8m8h4Y(`r35YwGh5&b;tCFpd%>(kZ)`!f9HtVWPUCJTw&W2V zdFZMiXAoga5lwX&T18R}QD-45i%7YK3{yx0s6k6)j6{tgb1fWrbO&2$;bXDf&ibP~ zr)zbWb5@u3$!^XnSJT%|s;p;RB2B>1HK0g^loDa2wQ6L0sU|JVhy}DKAj2d^h=20V zb3-#$=X$xh@`h`(IOQsUm;qcx_Z^t^E_5LE`si56kCJmYG6s=n1%}5 zw~m6v8WRa+!$D_~6@8|}$>An%W;PKw0;2ww)^Sv^a`9w=>(2|-+X)e15*VV!DA;%4 z^mN*e1BL?KVBbommmh4Z9cxn?#(6#9uEN0H&h(jeh8O(JKzWbkxqj9%b|QZ;L(uOy zntr>~c6F=#(UL3fgznXqyYj>{Kl+#-kC{GqFj1D18l3a*Zft#P zDn*q3<|6;%X|-=k15xRoqyG0sJ!sp|*%BKYE&+nI7WpM&m>wwug75U==3G9gRwYt` zl168{?*Nhk7DYXh0*&yl+ThvLnkz+tA_OWgNEj!_9IFeCroicwfi4U(SeAI(OC}Ox zYT70OWeAjE4+kX-}lj!|J7d7_eh`8F1pCMu~ZcS zQwYs0Ff}Hsn8Lr>zXY{8Ct^AQFWnf`d}@i)~y&fk}eAYuGJBPgh|BAd?bp zs31+lsZxR_0I-0fNWGp=rqJm$Cm-X&B-^Y*@hy5yLYnpbA%60SolKV}NoJ^cKdUYb z*BD9$Gnu7rMKX>ct$1*+_v~ct3N1a^9KGBx0db_bVi+fkwyC`vT-TGi%;GE=V-PNV zqlsVs-e@_fz1wuG(Son|IbeB(?U&?g@8HLK=F^tPJ2!v+n;J-K;}`~41m-GNPNNLM z*3oHFZC(3^okFg2?T>>Sg$nI`4eP)C-wtr{ys3rXDI5RwUt?Q!<3{6g$FvSOvZ8SL zD~Gt&LOkMiZKe(3^j5i2_{`MtD%Ene=?~AhM&4V6j~okwYxjX5@n78=1OPN2)H7eG zmoAI?dRLSibIr8{$vSNL#YX;WG~2hD<`-Rha*vN{Ufx3 z*Y?eXcPvHap_J}cC4RpFelU%fJo(2-*OoFeVuX|cFvD^H5@y>*T8af6P0kCjHJ{jL z6km(rYB_O8!S7q6XGFx^IpiDH(|5EAUb8_Uf=^nICjo5|B&VS=3-x+&u@MjPp`C^t zEh^DqhacyufJZ=^7CGIpV29IJfiHnX8p08f%K>wclLJ%1BLG(ce4oaA_9B%5a&o~~fR+~UsoPOl1phJx`?H~z009Hfl*2E( z;UpjasS-t57;u3P@I(e~GobpI|}}}$L_fJgX1N=_Q2=ftDwc^+YhatTR8BYVn2@x{C;7dlox-`#(k;$_uVx_ z_tu*~pDMVrX-+VF02E76WhJY(?-_Y@DG=^?FqsfQMgrst0~|rokkL7}I0zm)GfN`V zP+irzD)nNvrseyF$)C>EUE2PdD<$SwF`!#%CUIZMFDayYW#I|HqDA`y4UKPf&8C(d zg-^fU*ipLv#g4Td9lRfZZ8TsKv_H`N%HooIm4E1N^ZfqFuG7`v)82XkbX@wAms8(; zBKnte8)_-KG?xOF2QePhUP$pmBB4koN`FPZmn?|KX>MTKH{{FYiRD^Jn3tOG{%cD* zB|->e3}O-crIR+-Hv6ZAG1+zpkeO6M^Tb^=Uv=%hzAVaH1^}EOqi(WWWvH5OI#H6I zSKB^zrrF^VjQC(qwbjT;5=O5kcQgs!ainF4Xf33gMT929y~H8dW=@q-4f)h%7e~{$ zQjg{W__&GqLqFE0V8scAt$;NUk>Tbd)H8zvHaJ)bfFKfvH!gxf47=-r0odFEwF6zfp$BEB4g zS_ArU4jNQYZ-DCy;D~@b38!69sR1jXpN?@V6Udc-GvG;Mg8<%~$9HH^-#S~>!t>6s z<{b3m1iS6xj#LmLJ<1?-vO-8I(7PWe=cvrRNiZF*fnyuT_(oNn-sZ7;9*aQ>7+g0b$=w{CL%3CU6 zej+R6702UbY&n0^mnttW``zH{Gn3mFa!m_-VNAJ2n&y^vEZfteLX{9?Uy|Uf>r%@1B@t<62yJkx#`B%&No-&`CnPJo}Yd& z%8D@%KyYyDC_P5stUkXU6Mne54-ml@_)D@!TsFPmqe!vDl1*7yUn(%k&u88U|2FUN zXY;3X&uB+>+e@Zv%ji^8v~82`y)Dvf-)5G|qj5@=u{7=-iSg;_sKZjT`tUL5q5Aah z60*mcw#g^n>gA7rboa!B$+=LFoG)+8=GN(80{~M%tiRnj;0gy_#(094NE4OifjK6) z;Yrr2gyZ9d@gz=XyV@#Qf6pFq!R5vA=6D(>l7v)3>`)4Ao7>lIL=prKR&x95qdXtM z7D~9d@aB~S0O<5YB8=S&Op}=kh=||#xGxowdvd5fLUf5n{VSYOf_9t8UN3%Up6fIb zopN+m&SXhYsgkJB!cQ;b)E0WA4B0nPEDpCff<=RJ&G56Afky&~!K8sr2S_C#S3pHM zOiZk}T^|8NKJ{CD!o}k_7#fDXdthP)u3dp6JK;zxY;Qx*gFDJm{{&DXpv35zDkzde zUOv3x!b%=g3W12@RtrR%#sOmd``G_wvPS+(jox zA%Ha6p22^*%B`f}!93m-yz&0kU@*erQNF;;fiWX74^{BZV>j*s9{a&src^FHapLU- z+8MI707k$P^mvu7bS)=qYizCzFx=V*jBRCPZP)iYdEf4f0sc>Ga>xXt2wDBkE^BmR zx-yZtHSz|rjT*(yS0E+H%C#5OpP!sp!dx>>$o}*HV?+!0?%0aQ)$V%AhNqx z*YEh^+a6yEi~63eIQFZ78RK_%4y=`?GgOf&RamlpbE5)MhJTx9pDM!A|NMS}mTbf| zzn;6_`oZ&04k}Ak3Ku_cTKrGv&mIdcbpj&-!~y#M@qcn?r&00cx);J5d(TZ2lxUrI zH}!(h2AKSB69Y#3jl?B40|DV)Fkx0e;4Ke`~`VF2Kfct^AQ<_hJS>tKcc?AigK z$)~bSZ!M)iUgmD2+Mwx0;3zR4S>@EZSp^Q5Epp$?pzc>MmH%)!!D+c(irH^wpbUpZ zcr(IP7{~+7!U-=Yol1-1+%L{2el$)0s|PeB`awPQcp*6(z-A%&!(CKeG3wUC*LRV( z)uFC9=mYR<6FO0khJ3iR9G)l7gOIxOxqEeEj$7 z?Eartv0_=cbPjYhG!t z4lKd)cM5mkeZ>FV)1%LQZt}S=jQ!yL)QIR@8ytDIIs4mf;>NaV*zqQ+>sb)5>~5Tx zvMW~IVj$UDmL+zhl@s}(8Q1=E5chx!!UyXYq$n5089Pl_#eL9{Ik1Gf9bZIw8LwA^^IeJ z%<%E%3n1LS6^;Q*Jz4b}!|~sk{x(n?ig zzQQlvl^3-OF6?}#@WBWPeEE{8;=pA>kOWMS0#5nR_&2{P+zF3}{rkT8ityE6p9q|P z3`aD;A(S_SyT5$n^xf?pQ@|p?I9JV2u&^1=fV-}1S-9)uOMo~c#||kmOt$)h((tym zw8#cxH<1;xO0lslBq5{XLF)-V^+B zi}1N){FBv0UOqXC@!VYI4-V!DE5%ch&sOp-kEI%A_`BojKd-X~^hku6@7&DHc({FG z_{B#Y%Zwi@)tbx^Pn*g`r24wQmc z4mC=Y3$V5Xza0Ui2!1>alnA}d$8AOM!(ldzP_~jVNYPjbzqZU7D6|&hG8i7NrYH$2 z)uWcR}&y_9L=`29DeZ@Z$8mGBPM#~g8vS2)r}67M;x#N`f4VdOK7%#!j-JM3?k z8=5uLPOYF#%U=QqlJ&nIQhYGP_H3{{8%)nS>SB6K67wK+?ax!mUT&t^Og~hh-Km!u z6oDi`)L8iYi+D@gE?h9g_mq?T%siU@R&jj{Zw}nd4@P;w5|xdv?Nr!1SEja3K6gm- z^kd7r?$uB9%^mtWEfZ8vzUw~lNaoPPs#M=UtnxN1aM6k<4w%Tvirju+^}=e~hN~WU zX`8$8WYLmVcBaR<7XSbw00bD77xgw5fArB`51%raemShws@6YS&D+i_xg$9&hXAAh z&IDr?M3S!@dl3PC;KMIU1nIBTkDXcNFK)Nlwp0b?#eHVkMo67tNWf&fxwlpc|32FZ z#4W1?8G^07MJ`V=UVXd&;x%c;s{(-LTKJ@zD~#w(n-({IBM|@|E&w z_2uQRqu=-zvPuj;{%C9~VQl+(w zX_8r(E&u{;&D7uD;T#CL4&<0d6G6{PHc;HAk0{OC)>K7h3fa<#E|DZ4YD%)Gde_H# zVad3k2`uX(5Unfpq@rq1KymV<^4=(c1Ngy4#M6P-fOnOE zGlQDdAd^8=8?mhdC4k(Eop$cdGV+6EChld2`N*UuQ*!kB3KJZni?c|P9?iLEdRsQK zC>{@Gtfnw0P8}xqWEn!OQn8W~yzigWkW^I2d*NMuZ?C*}OnhTpNSfc-m%NiFNUtvI z+37lPo57>pSL960R(EET!()Za^xl=3{GOY+*JpSVX+)!Q{KY-}@icofFK4IP(9pEd z(6C%i=7bIB1ccJn0~i+oFD>^ zo<9Wy$0NC~){lL(MlE=10Si_(^kMNpbHlrItUM5xeY~gd=@HRlU#6#ZU(fTIwTzRYAFJhc%_Ael%dv=r3A`R+|GZA`$>){Ii8FCHl}k2gNTrxC z$_XNcn~kU~hn#TY1|mY7QOwx z^yZ*^dY)gRv#CNdEy^YM;Pvw{A~a_EgH5iV{nf%y{M*#p$xQ%8tZjX>L1Danv&AJ{ z*kzE+EoT9r0g}!svSlmj$#r!-KR+;Xysxjge>k^)jp%oU*DdGTB^3d+n_s>tmEdGd zK&w~U3^{_D^Tsvv`+xKbKkK@)!pdW|dN!R+Qlrw7|H^Cf>Q?5)WOXR48k}VwK9PxS zK#pF~yf<&wkze)AYMXL5QRxs<w(CZT%BMF&@Dt%-CjXB;sQlEh&#`qdVDW1VryNLL&?0p4Hb=1CM!;zWw`$8e*H z7!YwI3kdnZEyB?>vS{!^1hP1yFNjaJqpNfHyAPwmQKVMG+B&K&fDg|Ap9jOEkedUs z$Sbkfr?mQnTSMFbSI>1aCl|K2p{5!*0U#0zbAZQ#1qbdZCe~eOF@|MAIB^GThtO02 zT8coyhvf*cG`w!dQ6b!8C6;MyCn2$j^)j$nh#SjXJ_9(P)TvOVhWyoNW^|hQOa;|- zIW_8H%W|ofLSBsA%91-uvV9w2bbf^~Yu487;#@&_Izk46JavwvvU+%avF4^j^bbwc zz#N~U0{7ne_PHr@WbuHUk2Kb$r41D+4BpqVczVo`3>o}h#i;|+mlsJ$>V)!8L-pd; zV%^+|XlLuP!!Ha+q8P$ak%oFx{UX}_kXj8@joVM(B{da6dDdHyfgKnPTA z^kJ>#%3s%zCAteA_|2;+mt^ATLCfVEb;&dVG0o_5>gea*svvfZ*xNCmiLy~hsQ@u9 zU&ZmFF}>{iRd@CA#*dXa@Vk#I!W#`BOag~mvWXbj`|Y(1M?HuD`uxcw_nyAnMlS4WHzmtXTQR*?U2l_*?azWP>g}BVD_r`T01?TheWsD7BhL z-t?hvhiG(q&y**fXI`+c7Ur9IhT2ILqut~-l`1YHb=$i*elcsRR2rcCFCPtDd&Z9~ zlyZkxEfj4{WXYvuQ9d4vu5XQHmlsFnYBntL73BqouIvUDfoaX06)((UOxD#E6K(#F8`gO^n4m0 zHB){sdqhW_8&B6{kvtLP2od7A)fD<>8`-msEK(Tt;JZuEO&`9)LJ(=-XV8EPb3Rlr zKwJc6Y0>NomWmO9Vaoxb02qxhJq~;KKp=3==bQVKR-b6?-t%nFb;4=|YY~XVfP|2w zvD=O8UWmt#8*!7X(6IwR0^0zSHV}zme-4b;2}cG$T8Jo&L~7{H;A2^+dy*}%5H&hf zszi(sY1HU;E&8PoCxW;lhF8@@OBUHTlR2y*lLpqK;5sPw;zp)>SnXQQ1Np+^g~~U& zDxE3bsVd$LyQi&ciAyUc7IGk=Fk8bxzgSdou|jC*>T3lM#EFzvAC6uvsz3A7MM_HPw>pq{Cn{N->tP%Ll=(tMRX`RJ}2 z&1y!ZbbXL=OF7ZCn@6E5m_kg9yv62YgTT|u} z`x$dWuu@DGt`X&NXFty&->PfPDPef4nGASMRx3RgTmxtM)~2+n*3)jvI+N*Z)>;bl zVukHv#(cNH;EJ$}k`hiY>w1P2Gi!pG{@j^0ysypK)m?DAft{G;!2DPCy7nc%75#8+!-B=OUQKXpUSE?lE*?1u( z$|>cGc__PpM**QnAfw^Y0-jw!$b77v!zLa1U>>yukRU-T#C)3Q+r}A;59kRI0t(>F z0_Kv4qo7WY*1gylfZ0`4Xau_h7#eMF0RpfV!ooa|JkV;uZu3MUH~#L(k_5aqwK#O`ffyR+K;+Jz1XXF&$jZh3UeRNj7_ zFAXn^>|nl%rVYk!5htYH@;X?+6OEE$^Gr|Vj%fxNE;ke&F9Z{uxs~N^@@za=c^l^ z{iUMo9rw&e@Cezu^IN3HO8=U?zRfO3HHxd`A5xe6c3#5O)z12!OP?&GamuW`Zh$RS-ig1{E=mfi{y~1#u$YLWUD?M4lWpJjjuQmxGVyaXE=5WB5Qm zal!xzDKQwwn*?AM#ljF(68Txgn4LMQBuqIZs~|lDb8V7cSYo9dHb|MSer(b6R9V7J z-nGwVYyaGv0}P*Kz$Nq^tR5kfrP6rLex0bc5SJJ5igim$N}yL}H&jMz%aZkFwA{2| zmH8_KRzr5GMqsK_DjId-G2W`feCakLZ@K4w+lmHw3;@Xl)%zMZC!AzT+xPi$!+*SG z&Lm`Vldn+AA0N~M$1^q0mgQxNRF*gY#kO`e<$mhTdf&c_;Wx8Y`xZtxrAWUu8++h! zUC&bXW+?W^qwCY5oQ28T;;!JOaRTfg4FtW^ig3six#W3`^7N}o5gx7vvi z<#OsyR=!!K(*1jXQC0EU7k1c?WUgnq=*(12Y^(DAw$VXv=KawJ5-H)~+7IKb%;n7m z0zkH0mt$X>FO9^6Kr!GiwA0%sJ61PfF&F3i$B=6%+H7sgvC0|a@>+PUvApH{@Gvu^ zxc6&WrKQvtPEBrM7apFh*lXrU4UU%;<~ zwD95E?e9(UQ{F6FkTRRxdB!vqE0pK?hV3Lo)hkZb!!^v!&EzAyHE)imAvD4dp($OZ?{x5tS%epvYXGgW?>q!=I6hGJQ)K`vP56Dd_g% z8kXpCarqRn>S1{d+^{iP1^875RHQ=rMsSCr zG#8a-fy)ad0iy#Tm4LMv)GBbfX2YR#0Lf2j^~qId=d(UPArgVv1WgUFv<(vr7-O`& zjw;P?s1lJC+><+qOY7ibVAzSZGU#@LRY;VJQNoL!ss=uwJQDrXjl>kUU}tufQfFr9 zMLV~nfI4L$3UtKfG+s$UixR!M&K=e9r?%61+H*z6w z>}X4J)e*{F%OB}+b^c>y&z`DlOYa=4duZ@&smmMM^FCx(> zCZ4K`{%NQ!Az6Ip!M?Cyv;WFH+v^1u8B=0eyfRzsvemg=7AGCawoV>v+U!JWt4g3T zid(EhuZ-nho2y^m&cn1MzwEuc%6-4M{+VRb=nWeKQT36!52CEp?al$kYF(~vZN4-T zkwH?>aP;lFc5J=UR~5E(?yFfV+fO4bxzxX$)hwvlstDFOcJQrdmuI)%7bHdQn%l9g zh-fZ1&N$&P%%`s<3;!6Zjbrg`_QKO33`Np>kU~y0?ASL#N_g;;x;6a~JA> zqktpBF|oC#-)zZ*Jh}F1DR7953#Jmm&m5SOE6ck7N&*Hp&JT0+{^q%rv}}Gx3<+j_ zQ}j?N8L!;(MonwO$vB6KO45ZIK^nx}Q)!Ew(W%)@PHpk)?9<`Vz)8sDP~1pph+@-Q@Cx$j?Eg8YM_9;(;xR9ZrP3XnhHW$Kde?VR#e- zJjls`5-W_2&jka2f3*4^H7EEO0D%FtTBxss{t<`?ptc4jD0t#t+}Dj>-v*`-&rJ{) zH1NF!po(z;BBn#^0_Hq6fCPGD7G2`luV#}A)3l|E>@21Tz$}FxZ6P@w@#Q2~*VvWm zH01M)1yp1x)7L8e*6rf4MC|lBZ7ks5Y2i8Kn_2vWpUZ;Zd4nj01=CDT>Aa38cWj8J zZ(tw^5Ia75Y~%F>@*hhJ{yHZHpB4Z~HLim8sc=vv^yNoKtg)!z)+EX+o|&)RCic^g zpWEV6q-dxRe%C^AiP3T1WG7EMHCSOE(gGp?bC3~%I11*8gNKr?>(PZ+@Q9frvbTB1 z+~s&*W81xBVPbH~0d}K8AG!SzoRXub^Y||fS~uo9fe{12au^3Qbgh86wfhAGn~(1O z;Ks7hF}?p%{ZId?+WKg>Y2N#kS`zE17=G^9;&ym`HPX$p<@E>NuFcK7(3PLGAIKyn zfC-YM34%t51I$lFRojbA0b9+GX{xt!@>{&Bv-B%7A3PssQ-FE5EbKCghalKU+ysaP zjOHDc7}!%SgL!<_M+q;+B%*~NoB!$)%aa+`YXdEjm7Q{3W^;Y|waL?;KUo_kNEkEz zQue~vtapq+gXAJ0E(z^@)TAhz5ApPaeR(LYGLX)$;T0#-yr%UpIar^!-eeIb1CrSt_ki7 zw^4|K>uz?3j%u_JsTiO%&td_I5d5B_A zs}ZFmL=VjgDV${>tOnGzMsIRZQBTziQND)w*v@8Cuo>pK7(8a7_Lfu6PGvww0uNa#WBN z(r1*L4lxj^TP$}EA~JiG{_y3$M8TA{b?3{cUObk1SzT2U(%_G865C12jdhTnMm(YQCCr3FA>08R>K8J|BJWD>C) zAXxx{O-c?GdiIv~1YLLY&4HV4FZgPJ$^b&ZQ3k`<;R5!x$yN^Ex+;i#5!0xLyRGU& zwPjSyqbAw;FCOr|Xxm=C@|9E|7k~`WNo?4zN$6ku9rwUP26D$pb#80-BXRj1Zf%b7 zj*7M)oP9f^;k60sr{;X%%?1{??hlOjYp(VR|JUdI*OzD+C9OI1@zA^&{3U?UmRBIl zov&{gOJL(8C0U&ZU7an_&I+zUtr>vT7vr{Jw{b8S9|$LUKazLUWmesh*SjMl1CpE5 z=@mOiYRCe4@X{4@CO{3x>5H61DA%uwqt_$+@778xg|dE3$u-1Nb&{PrzA_0#MrMT- za$$6KDP66jelnAp4#HN7v}n+=9C9lLod&`gBVU`tUsDslZB&|tHlt7?LCx7nsln5; zDDFd_y#rY!xT_ylF#DwwgXrH55282R?8wM zbiA;n{&tP5XEaTcZ2Qi^Wv6O-woG4;Ea0TJ==#a_jVqHmaZm1=Wc%?(+%u>&8zcK$ zW?sEi38CDI+?dBS;By)wspz=-1%zukSvx|EE76fuOdqDf;yv zQWXViIab%IRUJjX1C2x1P#0`<0!J#5BCqVmT+_4Q0^@UDF7J6f*hT5HpnGnIe;)Qf=6%vy;5cC zUoh*o?tWu+^O<8#CmjxL76Hiu$1@nm4i~VmO|)?s!QW>6a4K%TY0o=iV9Hd`VxoTC zV~tEaggG7n0SE&vGKl$FFf8Q6miG>+4IiG~ z3w%0TgJ?dpyK3=TU~_At6F4DkX0(#`|beXpSXkNO{fLOBsx++uV!eC;pKJ$ibf34o!~y^)Z4cZrd2K{^*kJtU z3spZjvc~79m$ywEuz-`U(Cztvm|$2?bl4%)HUtB zNV6XB=^>{0?Qz>5R(uQ24!{HeAc7STJh6W8c*9tZ-p1#}w_v(Sk@TjRRNTw}0~`f_ zb(~o(PA>Q+@M`}04NZkPCy?*BRJgYL=^D-$-584-MEc0Ct%P-(P~~tNGb-f+V4PnbnghUrHV{kbj)xj_0D@ z7-z#ccL9wgadR%ngvcMkSu&`p#KTKyWE>rAf~#ZDHw<}Zh^NqONrD(ftmcgl6c?Cb=^#QIZiG_ z>f-SICh^bD@S<*}$igeHjjpBReun`N^^>vWx2xE%l&O9>4jMUDa=h&=q0%~-t6=1d z{||fb-5u9)rF-wH6FTSI4WI!ua?T(?kOVU+Qj#gjk}OMdyiQ|}$JZXm@z`U{*pqyH zZI6>?oD{5JnY2WSIf5XFOyrD4Xf(Rf=$yMxsP_-eU9;YAU@vQbgj%P5=Xsv0z3XYM zRHavodY$mI+3dd*Q{{|fak&x{36Q2?r8_N(T*=^9&&+)H54AuG01)T7g=ntT!9X6@ zb=}zz=A%p1u@u%4El>hrDs}0|&oAe)IrG21aXTAezVXD-Z)iT!LiYa^{QXzI_~wZ( zm(JbDe*I^$u07hn`r&MBsd{zl3uEh*B?Ti?q8jGD@}1v&;kzR;4Xt{1-+hg7ra{fE zPaOzvR{-LHU?2cUyfgk0y^H_>gg{a<^5A0^W|yQpgH4o3i;?AE&V=n`xkHhum5>Ag68Ai!ja2|_q*bIy9U9qB@ht<0M5xJIkR@R zvGVS>4y^t2slgbeeQ^y>%$GuxJ8JpH{*7OK^yfW${==xq$z{oz#75ARKGskQV!Ef( zdR=m_eB=@PWxnsDvvMUy|F@6WBlM7Y;m1~)KdCK`V+2G*AkFKI#I2y8f^YT1{P-q( z<3;6*&$ni;AL!*8W_GzhzVcY_o&`pc1cJ2^Y*)~}ka%NCVaXOYH*A7DCD;>`S4#-F zH&$538f|-r3@kk!$wON6;$8Y!W5Qm=hdBa1UL3dH3TK}=6E9QIHwIv4iZ<0|wM{t5 z0KN#J94Mu!zk4NdFDMLpVSgFD*Mdtd_$`l+%83+0GoGA^LXtAn>_RWa`I!t^NkF9y z-MNSBjK~uJf08ID(%lN76ojMjAHRhC`=G=Lt1F;X0RA%+Dt}qpN~t>TUPtX6pf^H! z1!&YTu>cL_VAjKnqvC_j==KJ2>hM$)%x2hc$4UZ231ZP<#Gqpad@UdzlMvpFB{>+L z6ZB=cl0m5qkrYr@F(!go07T&7Vg|m`fQiC?dzFo?=#mm*bf(S}gx9_LbVjFF(keR} zGTv~B4U%NjVH-4B8Cg-fNiCxg*1Je^o!C&DYpCIRY~s3fSmxbdsMUq5Ck*Danr7p2 z@7~ti{+Qf1eI&~yAS)LLhs;YIb~G8z?{!8Nu5^ZX)Z_HEuhU<Yv} z2TA~cuY0w5BD>R5xMK#3N*&-uR)OSkDoAoF04ihu{x_QKul83IHjF=bXlix5YNEda za+-(sx^J&Jk~}***D;n}|Jua?2)+4RS|7yqz==O!O}_owM}3>IX22DW0r zh}nqg{+PX@Y`3E0ZjXj+ClRNN^|&_P*D;`zbKhI`Ul@2|b*th~@y_oyq^BH)m+zc; zYr!!PO#D@)`FQIElX*Iy(-laSS;_s7G~WGWs{aCWd%*L}$Ik@oN2``PHp-`i)f>i8 zF&Admu4g(QO0pH(;boWXknf2ziVCp2y}cYKzMb)g+;$1D0`PSE!SVTpqP0!6#uDgk zU6@}sD=nFF8$W)l9Aw<0hdR<25=zo4wfz3LTFoL8ivy7SMjN}vq7A>w#3Chc78LwL z<^Gpev__s%tFVaa?jrg|QXoMZfreeZK zkkrXgg^o5!V2_r;S)!5vTSDqgSR$elD}p$R?f}ce!6x|Ou=wmgbn!Y`UW4{}2<*Vz z9M~-|I}crZU~~PasnmN;@K2alAO6Vk>sOIn37ze*umWZWIBejHz)pgkYQ@nc+DSuC z8N4=5iZN#8WRoLKBP_>74TDl5>?Y9pHNhsKem5#SSx1+uu~~x>0`w)tN6dI=H1Elf zo*H)BKtCuA$yqe((H5FnQUpq)&`K+0YOB>QEzvXW_UJBM!HV*s&FrOcb|{y~8a#2i za4RLfHqH(&z_6PPd*YVT#h3FDS;pMAlYPI*TqKp2m_b=IeSoSDGYXB8msKoVM7>@~ zv8e)C#Z9X!zPm1+Tb6<-gW{>Zn##Tf4pgB>&)nY_2ffuWd2^%aSmd)$w=7zw+3SVN zzY6(2JNym!$0xsgYvW22P_Xw9(v_FqoY&A4daC1{+na@ntQG(P#bMQUTgjH4uU(3y zhvME^qqNbrNtIkQBE29;B3Z@hvaP#ORMmd_&O4o}gAG7az{BaTtyON_7pMYEatX(s zEmTvqxxYwMDBVQ`6Mr1-onP(*{NLI6|Ims;fJET5Yk{Q8mSA-Y6$Vj>i{}#JZ~6}p zPo089BM7Q8=TND6b9(Y)M75?UdD}btR6N-6&P>f@+HaSb9;{uoXt(0ZTwQPM?6275 zNFl^EI!Z0uw-e2;JfwecTsC4WVzTS1wb9tA_S(Usi?wYfHOZ=8sdTohI1$mxQ8q)V*XY_}v;md*eo>}wV8)b*GLTh3@#KLPu5Su@9$3iU zmCW2wR5qw4#ul2N5oDU|o@DRkOM_*9EA-IsJGVWmoH!5&ruC)Cx`(qf^QU*CMlM=W zSG1gj)Mn5{2nK?x+g`6WrhnD9x5?(?w|lPLeBW5yS1T`Y6fK%8Yg%3MxJ5aw|Lxd2 zPezu?L6HUoz)`2Ww${WY_j=d6nFAlQFD00^>e))$`an$W^LB+}Y7p_eoj3nOD?|h2 zN^I#f~FM2rtnOCmo8bb{ebS| z#q{#^A1T4(lqWdWsMbah*rgexlq^fLR2G|pF~Ctq+%dpp}PzE??S)_r%u7@%1{67 zQue>N&YNNvEUf?mKoo3y!D&Gfo9K;^r5&g&1sTBqxg=J&NR}o`>u7NoUEURU6Jkt2 zg&Yynq{2jj8h`;!g7;cTzfUNT;}d19Ac3Yjs;7(A+mVaJ{wd3Iyy9$s=G@)HMryDoBZ_$VYwQ(1$<n;W?LRivyhR4h~K@@BZ@QtfJlP?wKeYJ`zJP&rfc4k&5W_6ZuU%@kJ9b{5C3mW zD1y9{l_lPHWa!kvYgFF!#vGg`hn8-9y1nJKVhshr10Wz2C^jgWH?(~Ua%KqjoZF<2 zc3lQR3IG5(xy^IDTDg%>c~kH(`w@HZ)|pQQKJW>G+vnbRV@H>$c;Wj~t9PSPFt^m! zWC*(Q{XpchmBf6fKjsCU_rFgbiNrHmygqKItC@ea1`m0Jw9Z@D5IA)>cIx!*U0(3% zy){aZY@22_s5kn>^)an~Q?;~|P6|t_3vpPNs8e(Ul04zT3f-{MoQdyEDhO;I~#=>(4MBw8*WVz8;_UyGJFVGh_95Z9jF0a}Vd_24v5(P8AkhI~&}>Rf=i%`qkfoua4l)_IKMAk@5z5O! zt%F<+$e-Z=(Z4KO5dzL)*xiNV5{Slu#=uFSxfVUu3$c03#n50{c;aCwwE;GYV_}j6 z6367pVro8sBzcr!F{6Nys9?^KOHr``k$iw>)ktTg^DK#^gqcO*hC5P?#K0ZCUV=c6 z3QLoPHf~~2wY|n@9a3k9x5U8T=yw83ZZ7gAMS{9>vXqtI8+QSxxb5ZZ90)XlCwmuu zKW>EG+B8m&#uJAtIN&oiEt5>fG_zP5*s$9Qy);cgB0yRr6S+#OcZ}bdT~DoDXj#uk zPdx1V;Qp!^m@e#?dSP?|!UnD}RO(3XIjoz56*Wj`N$TqSqAS>W<3<{-R{VZ@;6qPU zH1sIWj~4@P1SA5LADlnwGHwxG3Cg8MJBEf9n&xXOZP&i>>`K>>TOjoTCq+m=h!CCzwfmW#9b4_aIgfsFswMBQ9l7u9A8cEa zE3}g+bfoUwsZg ze2UbSsmQ?;owiA!KnG4rrefWdXYY?y({=vY&G&!Ymr1gK01(NM?Bu9YjNqlR-yEsX zeDI`L*S5Q3@$8JbgrM0UV)+0!xaHrP(8HGgu!Eh+CT|TCIMXE+?Q1~T0tYMy#KZ>M zKdU=SV6n{0?=Hx0P1BDa${#2puPx=%^LS* z3d~?BK-@$(bv?de7kF>th$Q#RH6wiWI=Q{wtaRVJx~gy~4v^7YL; zBuxO&(Q^fl9tiHLH6Rq@h>se)z8Tcr&>YPvnDkZ#`yU8hnM$EL6U zN3dsK&DB96II9Pa+FllPpL`>Vizb5t00mJShy)_e4|EQW$X|G*F?oKvde_|x7y*Dx zlC_&>cfyub(h7h;HTTJf`Yy~Q5g)77=zsfqZ%W9wwof&crKY3FHluMqwX0Rw&Kw=R znOa>MITlzi&r#9Z`pdFR<(j)@H>^knonCYQf5fPV0SnzG*}~co7u^RUl3efhO|8sD|UO&CLjMm_p4v` zH^~bmJ)6bJ`hnzq@D)nyGY7k^6&hK;5L&;}vNC5_UDWtI>eHHnw|2b{bkuZ>#Z$`6 zj-h#PXn8@M460VQ6%BiqRN8c>y7;xN1o)UtfCXLpWL@-5PQ8(!K~I@P$s-o5)TI3p z)gy9Tp`ecxQWhz)Mxc@49W`z*#mi~5G{%J!;wKJBBRu?JG}mQB9yL>i@VO1HN{c!q z6s?DFhQwl+5ugYmtsFHJimL&X-^Q6dJg}Esn?Ngz;9ek`YpAOO)GFWwsH%kf_amv~ zJpkc7TK$RA>cD~H1qEnl2h;`_pN7ZIKsX3T+tGzFR9=D>+|b-8s&Z(S6IBXSq{qWq z(o>BB8Zx}aH!G;)h15ifJZQ(|#q@F>EeqsoU&clOqodxM%%8Ed)3*5OBJs_)<&eig zBH(K8w~>jB8TPa*x@u%d9pAvhK}%UrgS@Me?Wk02OB7v9QEicGZyV}rfrE9bH`G^a zr3JM{dzV4isZb?Mu~kJlZ(2B_&h`y8g}n}-07U7SWb|Xwqa$A2e&Qu|yWsYn!U7}F zXfun8THqCNZu5~IX{o&Y7oYbn-o_in6NYjQf!3j@O{9`z-_9WuWiizEpHoAOh7;F6 z_YwPb`OWXJ-?A02?=6dV)oyk*tn6!Dy_mYXzfiZDCgXQM1R#5N>PsM@YIN)fX}vdS zhCKeX;Fh-b1@Q}s@-q2$t)+U=lbZl*@14}IW}_lTi6ZN8S)WNytAZcXpYCrkh= zC*NqQyiXFf%RV!RvRGUZ@fWQnBc|%fP3Gp0`-``RkL7s@00u(IEE6sAt|2eZ6Fw8y zhoVef$7L$zs;>DhO4f}mw}D83Y8Q&`f5_DCGOfOpbNg?6IFe8RpcB7mEg}^aTwSmHmm8<+p_Dr#2GRQ(Xmh z);i7JJ<`7El$Me1Wew*SvZ-x5TFXV|>r16-lQzAaJop@TPjIQ=~p-@t5POeGLXVE7;Vv#uv~Hz zU_wB0hHht=`4oP{$+#>GmZCNVMjWVEs4S+6bEv_L*AO^ayfOtCL#qiV^yIZ=p#)(u zNj4Eln#sMJC>2AA7#~i@XjMsqnS5xZi}DG%z5d zgeX2A5=ln@(YhzgK@<54xCP=>%D*!~4e$9WFz@>Ohh zQw8sblC$q{v1}RAe;kt^W5lE-P$dH9p{Ajv6I% zqRxp+KfPc6O3~)bmI!OEcwDr0UjbM>!L~eiOAk1Qum~aso&lZvV;|ajD>mWOJ9jn& zAiT`H{vmkk*5U-SuC6)WvSypv(`$R@ZnW`f&&ehSkyrj`^~Sf@AKl0-KmYc#vf>eN zOn^x9ytJw!rJ$ty^wMDU%$OfTs1@iu@GRkFmWtP5?NfhsAoJ?%>h59(2#jawBk<@5 zU=c(~Dj~UXx%bZY+ti6Wo3g}>@nUYh2M`7<1=ZV8001BWNklRQ zf9=k}(ipGzuo(TH-CwqX^-K06|L)j?m2#j6QFuVP2~ZCNegB=7FMV|Q-`wj2mvlZ= z^UGJKKJi$w{VS8ntBZ~Eo%U+wn@6tki^q{lNJq2RUP$$RJ(QqSfep)zU*+=~(tV%F z{Pu16=brHV;3iKz4FH5-0j9fv5^juIkM=Bo=TQE|CD?YxnhUij>@wuQh?Q|dNsPrm z%;o4!Nae}XrSeDA(eL%gGnqQ8yk`U1MO4M7R{Yz=iY1tmtbkrHPmm{8&&nz}NV z`|^Itb7Nf4%^j&?i>+8L$B*uj_FC{7rFcHT-0|=O*HW^=m^LRVBFyM;hWDlRI%CmA zu1cjGWk_N}%p3fFyNCbIb%owY(-~^p&E%z_r}hSK&q_;;_--hk9xBaktCyA}>#2OuRTYd+%-Y7f$T`@%jDrwF5(I zx_qEE@2$&wTKJUkWMx(xJ^0Vb-&E@HM_SxX<#W4SKAg=sb3Jj`)mL55Y46Y7=@mH% z07x0wSGRtpzZ6&=M4Bi)kDrVcz zzVQA(Ja@TL4pjO22Yz~uZasV#7(TLI3?ljPfxxsdva;4hL!Ep%1%U}DD?Qnrj zm_ggW3-1mLcHACo$Vg|NwW9Ce-T!w7B0))Vch%x7oxzs7>+V{}nh6oGZ*Nie#b+uX z`tH54)Sb+(Jla!k*Vw6)D`X=LX2h)-Czi#XfB4((J$tSGRkq2{JUz3qJMI91G-ZxVH-)fc3*$7Q*p z0mv^iE(%L^=$E6}&vfy9J9$3LerTWazos$~Klfk_JsBW%MbhQ5d{!jYwbWV^9kwyQ z9nF5AK{6Q>A9S!w38Bb=hF1h9;71$L_uRyWVSN_kUDyet3sdB8wD{tZ$ZN=!RLsUu z6~Q$YxP1?35p}krdwpbn1(n!fY6dVsIt`x92`+!(&r4hV1<|Uv_ba#iY>MngyT~VSd;EK1lWIouiTOBEd-J7?pxia|f`CPszy)RNZ zK=l>9KNlvOr_s@sRG9fM>sahY**0b{Af&7N@HYeImTDe8>})Xzf#yWc6-D z2MB;;+xJ|Gp!CbWjel~L{N(pvyRld`DZg>Bbmyto#iZ#*n>Ea^>33dxh)XNqU0x|G z9PJ+IkFVsn8$rAIOhTOV+w` zKYjI6e5_RG7^uy3_092-fTe!lfT-Jw`pk#xf@}G}`dSMBO*;pVHwQlaz^GlKUqjQA zGkfp!AA%hh;iN>M4>Sy}rp2|16ZhPP`g#we%*(hGrJq?}ufb_6Y4q5u!be>_*Y)Q- zZ-pUZ5JGZ^R_MPqYe~rSr5joP4%2iTpeX&VSKVZ zJ?+Ma8&s>T=$poO-NH9di+#I_1ErF_;cR4^|-wW>*E~W z;3gB|7Z1uW?Fcioxl#k}bDscLxqOz_JG|y1}=Bo_rrn&%&YoFuwq)6htBuT<*_|R)1k;e6XBdOcElaTGZl~jc|1v zc4g=X+rk0@A3}#?LRBSRmXY}HGTFF@nwd+$h0!A=Nu0#W{mF5krqhl$Gk$fiAA&^k*7Nj-n@49VJ={f#-&w^ z5wHLZ4~ym9DKm)lbE}u7oc!B|9Z&!5s#v*B%+s}w_{Mcja)&!mU4FCS@;AR-hJYGF zb84WdW&K^vtpFw?(%YXS0s}x83_Rfgi{Z_} zk;?~;HYDrzPf)7B+Qf$$$6W9G|MSbIH~o^Ozk8+Z_Oi$YYm)SGZ?zlHyN-rGWWoJ@ z1~B9^lDqx&mV#tO;}&qGPz=v}(EII9nPf|MY16Bw#jpOYrv0yHqcUH3L(|k)cJ5cp zv#&-4QQ1EJ=pAABVB;Q;a&(?r7)g##ZJg;8z_3er431rpIH!eGIJeK7N zlP8i+l|!#K0CK3skJn1S*{Yy1Q%B%PwdAX()n96m6?3Fej-GST%`|f9aR4D^9o=>d zfB)CaKlbrIndeU#P?sLD3UP}Se|Saw`D;*S1f?7}rzjeLBOsLkB?VD{PzcVQ2b&eP zy^u=$`R(7oAZ>M^_p5z`{v~{9b3mPpEcha#C~P)U>(m= zOmsuBY*~<{bw?j8;0qRJM%~T!nyz4dpWH3CBpN%dnUv-3KbaT*l?GyUl--?Lt^mS+=49X5KrX!W7!an`nAnmH#kURtodqn=IY+03FSf4yYV-aB z>W+i^=G@wTd8jT!_)6R`$z18GXOam#a-|aTru+7v|3k0z^8GfEfDkRYIbGV>e!Iox zVN_c^y21#=F5i4KpV7SgMBtNqh6lGJ-Yo|(d?sWX8?v^xZnZn&QS11zn%tUS`O2kw z|M&v{5{GNb8a~vwU@vSv%cmUim<6o2_Pac{r;b6!0!ZXVVDdCqFjS>cKbqU~!T`E( zUAnO)@oJ}^wN*X$lVn{DeewjJLvwbQ*&H=y7!H)uP$kvM6od%9Qn1brD_vIWZTFU9 zhN|eGO(kR{m!SPN#UcI^Cu*L^9QY^x%DrEAMwhjak}~>SMNxKOQOYfqHSC++2`U+j zSZ7B={qmetNGE0cYr#~S*$yf)cJ>)7W3N$H)7m~N{%pOrg~5J|evx4dHO!5KcwtKz z%z#HqBLXi>=WlNEeg!j`$6ExQn-ZmI^nNq0(_?cIPlnL{s-T=A8V{iZEYio2cMavU zh$$5Y`f*7fT|SQ=XhAQZhbNAcbPNd?8Y*GM4Z$FEwu8?%k;}g41pid4vEh@8%i5-9 z?3tsMkCta(r<3hR0CU^RYw7>P1SssshbeqLPOMq@!(%c0l9pv%Ln3)#Ql z%f2$6Q>CE7#U3lc7gzZ>2Nf1<(II^rH!3N6F@2Pw?#Ad=r?jqwaaFQOP?hn@QXO4c z#CEq(QEAo!MWqT=RSB*xp)8e1ugI2g@^n_IEae$<-oVl!?aoPEUY{v{tFIIo4q}=j zsZyeiuJ};zfnhP7zc*^|t7o5~PTtrG0;1BpH0a`49g?S|`>5LLClfwyzJe*rIr!`R zSni_iXl>0zpL=tMi+Y^1L+M5T&SOW4^v5UqmnuRF2LX!!Sf&hGONKV08fn3(&F)?s z|9m>D284$2t$%FJUYuzHU;vTBH4A<+q1ir6Qs~0(Pu%tSo+>M??7p2cPSrZH*t(eU zl?_~Sfv5&RQu|_W6@7KAO(f{uK`slMW~Th+GrEq!fcmYw-RZdT|A`~`^uEy-R@U?0 z_IDMC-oR^2-W7A78k_#}LhaVjgOE1@ou?$pLTi-TdU$$8lM?x!LUB80$XYHQcI0jj zJ_gc6r7>ArF!j7#q5Fmro1uT$h~4|y8Cm8)XIVRI{^7;7@~|#!@l`kj zexF6i(hpmV>m;$_VS+JCZx>hXpKH`87BWaeWV&i7sDKkX{h%aaF~bpB`4b;MxSZeb zV(*8<$WHRb^O^M>aj%mmF`-x`29`LL6nAPVw~uRZ;*5tsRm4n1`FagWaKwml#sHV& z{O}fOb)vi#emR>f1m=hLiAsVtcS)3o8U?Xa)h20o&FC&W)n(E-~3*ah- zNCaA2U}bqCnRt&@f2!pVlpi_LZZV^~_h4fS>}Dt_27!UP1It;rADlV=GC8HRKISnsn^HozIMo@}tXq&>WO0xob)Kx>v9g zNwY>`)6uCS?_rt#atbWvF^2}REZS8B3svbHuta<$0CYAUr=(K8ORp&`nY_QUZ+piDfB}mT?l@98b0zG9cy&?Hg0r}PaHL$C zHd~z2o~;7j+cq}p9FO`>n93>Js){$=8B?djYT)ERFyoj#Qbk`KZxcld1dKI-eGOh@ z^sK?QS)tX)SToCba#_eq0O3<@gV$HYtfz_6Z&$TUbsxD4nl&BE;%J3R#(IKM;AH@y zSLXM%kKghN$yi}3A=4MkSnZo?RWwQXc*b5|dB3q>C!3d?_X@T0-0*t2QlhJ>9_D#E z9<+eJ@W7s}+gE6yDKVtl##?#aibCh&XsOi(m*2eQ$~G6Y8vHOH(uPketCMN8nM-P# zIFo_ZnY6E5OAfz8U`L{_%KI|B7|xe8`nS9mr-MtI{k~N-$f=w<*JgIqx%~G4bru?& z1aF7nYCfx0)5&G=XdVs z=o0o&4Z9tM`&0Qw6ZP?Cb}UHlEpi`jXHQj9-+Pnyal}!~cCj!-iM>@wMZ?k#8R?*w~Y&Ikj=u|Fk_4wl_fAaz=bHQgm z0dHOee;Bk5;tOIrjVXeRI&!oL%?IIV1B~s!xLjDQlyrnZ4tG~VJe1TATm(0*sFHkUdYvTuM`BtzA@3JP%QRs$Sl=46#DC zC~-fdbV&;JHjPp&ZO=D764{U&pMv*$liP~2u_9Jo+Av)z)0k}QmeM<`LDS6qG05rw zVIUMxoZN8Vqz(9d9bFAKm;AY%`Q|NgeM z{jMzSvJO`t_{i{!E9=T$BQJx>ya}DL*rBCwFPaVgIB3|_lDG3?r-Z}SiDtP zRUBOMNJj5jmweP#kak%EWxBXG&)6Iw*YSQP3i9ovP1J_yafEZX-p00CCBx*fe5don zvT?dmk28-J2_10O;hW~omyd0#Rk$Nse zrxm+Y>4X}REYa8K7>Rz<&#ZxJ6~g5Une1nq*LLFtQt9$=e;c$&MJxws!|C3|ez{!7H~lPRiF^_7Im7ba8;@v*CJJU)RBHYX=&nL*-tk^BbofT*#BAk{}*Hdt?68UqYFO3ySXf?q74bi3s zN`dq;bk8kz6yOvGau!k%c=$o!IAG}aX!YlCmpzk3gg`D2N)~FW;mRbGm4HKm*0N%; z1}!e31{XYk0m}%AX;54ta0ZREtkMv?JF8k-Rsu(t z>rvjE4a@v3wQGx$C0l;wn%et>s&IIN0Rb6IexrORmzIWC^$Q!wR+T!~LL-AGs-2-y zxq+XkbBcuZkn(VgD%?00Qv_lJb)mv}w0m^zfq(nOf02$vLGvNow(I4e`&LGU!bUny z3h&>s?`xC|&g=S=i1ji(pa82s#o`vNnDIkZI8`H z@WTC`wbfEUEGT^Cr3-wtdOcup+l_BM z(DK3Ym33`i8nmygtjgWKMCakk^NXIWKm5?+Y9Ys0s~vr-`QGEEQiqkIC6!A4{A_k% zR2d7>pvoPnBX3<&^MGoa!kDEMa><65#H3g+XAhSv96IT$gxk%t5haEwqOvG%z^Rlt zG@7fi(d$vjv#_2bV+;IV7ya@IUtq;X2~r7gV@GHzLTzSzZIkq+`Pw2%5<{v%|0Z&DC^mWz+afQ96VVbxUt1GT>%W`@-jY*iDZvBE4%Bivv;J;=(b{ z^5Na>`t`MzHN%xHG33&SVWse8 z%%DF4p|V6!vo>8~w(`rS$-QFFi|2c?DJ?KO00vp0ymX$ARImGNK=U9%oz!`#`z<9) z-U?6c*VoK0NP$xULfA6j1YOfh<|HS8AluoMaFtg+R%xQS^5%{iPQP|{qGEQa*KFL@ zXUqDAyKCDov7x454uLdaFTJQuwal;A0tJvq;C%Jto%bu$S~IR)65VXH^ub!!oax6=3GWPB)BS;?r2nJN)(59D?b?rC5Y1hfg# zsX-5yV3I;EjGI`hQwK^3)?s8);RmD;@L?5;Y-%LINUtEnlR#&2g_C5`=vTjj=0-Sm z9L~K71$J0j`SVNJ|Drl?005dAp}QN_H=v>v?hFB5M{N~QWrSN%p;1r$aD#lI8PXG= zqVf9+fs&xx+w?OAP-oz!RkDKMuPc#64nG*-wOa8rU6Pe`K^hdwEjYp8BBmsnJrnxLz6{R;ilX80)`FDHPJ}%w=v-skd;)UP3G}NqfefaaGYx>!tDao#v1zx!0 z$+YUTM?aZNM@s+mT0xrLY%UFKZarv|MB@7G1%Hz#DFXl){sfpNC56+~*{X|)#Rod1 zWd~BfnaTbn9QkYwD={XYzm7wb)xhvT07=pyj{zc(RJab!WtE9`D1UB!;42?lz5Lc^ zCW5j5-xr4fa%@B8qP6PUtM`k)v@g9qTRDZu=l=TsA1)VdkF)?1g`}Q{41fRv4GGOc zdi6EM>_PDh|24*d``K(BLt1^(ruk#+W-Q*`*Wdl6M_>BK3*Ep=1cF%%zym0}uI6)R z4Cdc0>my3%x9TKxOdU*we|@eBti310*ym2tKg}ba z<|POLPf#)RG#gkg|0*O_JfNBZE+?iG1YFdei?F|k-~k*G0b_tw;p{s9@E$g5#vu>i zV5SZR#LhbAN4w<92W5;5g?C{+jn{JI`UG@sf|5dgYho@hK2(Rj8M5jX4S8x+jw`xE zDgr-z2bD4)CQ)}a+#G}yha@?8=4n`(gV)bOIQ(Zh=J+qs32u4O?_LMMKuN${1YJ$w z+kxSEXemWn2HI-yzzX63?rO!|6n-Z_wlODKq27)!EDI&2kW`RuFEPsCXe;yGNlwk7 zQ&n_Gg|?>ieO~_KRji^AA|lM*&anuvy#N3p07*naRPSi1Gj{CZ@_U@r`FFS`IUO>h z-8HeHGbK?71B0^tPJI1sD()zLO!>|Hg|5-< zG!Q7S$Y!&!wWMr%WXfXMzI{)+&uhAJ(U)Aq`9s^9tbKSVaNKx0x|9f7QjeE8XU>IQ zc*Fap4?gpqFAal8^0u`42%3mDv^$+oA6FmjQMmQ|F|Fl$chUWMXEsNi%zPl5w;PNWKBJi@WwuF8#!grQ#TpPB|jUKq3SUOyleqXh!NCN#?_vG81Aku(9 zC7~)E!tiDqwkll*XUjTP`(NF&zd3aM%11|{@rFHrJYlm8FPK5)EqBfG;kxzpqK_X~ zkyN~S?b7t4$pIlGZp{NcGveQ(X(rr6KapJ^yMG%Ne%TmW^I zwgB7WnRQop&HSxTdi zl{42w*j^BM392fg!aU3*0hBanhLZ;B*Jrat1e!vJ%IUa-Tiqf-H{!I&X{I)m(Wed4 z*RDvp7(UQU`f_;)L1R zE9V?g5jg{$6VRDCQ=&vul$CAC;~A}XJnOM#Yb8&R?e#cIvL%WXgP24%$<7ho4Rkj` z1C5*tC{#ctRL=Da&%W^4-LwAzb6D^j_U|a)5p07vKKyPv82+56|3W`)Wg< zGqmniKVKevD(?Cyo_}XMcOz7O!B!okYR+~4MiB#DHo8XaQfhv6Pb%I#+!BbRcs}C= zksj{3ze!Cb?mgVY_{J-XVq_nre2WwP1xakx6gZ?-5Z?J>dsIo$HPzZ-PyHr+;qJ&wLQMle93QxQ zHPC>qy~U8TT9I}SO;wrg*2=#7=HGnh#ifT^lz(NN#S{7@1rX3NEk90HI6{vJ$yuh6sdsp z+FSGDyaZWjgy?2h$5*H=>w`oVJ~#_~z3|-A;C8_1GI(sLrxosu zp!F4a=n$#Y5|=k|vw#H+k;=liOr%0aTwTS_d+3KORHK1gXc)4R`*oy}0~ZBH^yEn+ z>E{s;#Gy`lxQp5Cre+ELKViC@p>l32pdoe}_}{hSzqvq_8VE383-2tlh-mCZN3?f_3*sx<>P06b)mK1Ks&8Jea_l) zf6fi02pB)KzdWSYe1G!|OT+u+#k+c6$dmeZD&#FabtG!&|o(J4K!W zk*;hVn5+j+9vC@f!(F!ECt)Hm`8nWK|2B!?_`uz(>kWwZ1I-n;O}s#M9~?J(*B|m2 zemuT?<<;jQw2P6}_Vy;ueQ=O6Z0~kctLru}P48B;JlOEpcoGPKq&QBqa8L8GOwv7@ zIelgFD3?=MNi3K4NzAoAsE!;^4XPybJ)_%}CCZYh&zmNPO`SxRh{BP7Sq4UfwV5QIPLt(ZwPT zT&~Y7@n2@qND1Cu=D)Xxo+!g%2Qe})WTHY>D^*6I!{~?}@iiorh^K9o4+F7-)(Ysg z`@lue`7xLoCDt=yw;kQag13s42(3lng~#xZ-$qaLfk_J+VF+wMJORa3Jy`#eF7T?o+XEJOr zq&k4&c2d@p?SWNpd)S+w&Lv{ghX6C0YOC9|HofQqff_tHn<2yY*~iCoYa8!9b2CtE z_0}FgRN>qcNSm2Gw=X&01gro&abzfVPkMn14+8)I!Dm`?P}a13oTxOdtsE*8wSfQa z1q=Q^tq7i!G@R~O#CdCniu~r4=c>~ufE0ibS!I5AcXD*JJ6>woJll4u)?(R8H*g?f zrb(=F-yJ%9{t18CEK3{3ZUf=4k!hN8?~L_0<-e3nbYabb;nuay zP}^Sb`1a2B`KsutZ?_W9Iec&5%Ut~F)-6ThtIdwp?bPE(U?PsKGFm1>>oJfU*rJSl z!AhqURJ};Ndbu|HfPY3qjF)kDC)EIGa#3Lhm9~Vj9R4rI*+vZxP-s^ht*(Qtfu?eB zW*wYTs4C&TgfJ3BJytN7Ayj~qUf3ew_c{?*MFc`81Mj{M zecizGFgFRi_Q1-@y;AWa0RNd*pWd6`$PJ{{!gsz2fAv#1aRLtZ!H1X8wFUf#f8H3G zA)A#D5g^W@f?8BjcuOfdSj;F%lLJMf{1X;ZWhW+Lcy>$tdN&oflF?PZxFsmuwA?}F zDmWArhHS*GZNcp)`;EkAOniibJ2xBiNe*OOzk+%^{_97pu{5MnFx~bl|}8{T)L4nVI#2MaNPw`ph2>F0IKnrpY8Kb$CfdS?=rN zf{5B$aDzwyl*dr%`@2h+TAoeXmDpV+>zL+}b=g4kRIfAq&bdLTs{uf%sJc3CKgg9O zjOJi(Z2Y4Zt&A_4rZelUkh5-1yGK(gm$#H{l;dGVqpZda5_ocWI6S&j=Oc#!uv(Yx z?z=x|l-D>-ozwc2NKY$^Je`#SZK%==^;l^);$BS*xzdgu@S;_8J|Bp*6_mLN^PQ z8bF0Oyj%PFUvDol<)`~4Sq98XDPfa5)+@;uNKi2gm}hH3Vhd;nbsuKNX1JY**xX0A z8;N)xyVb-KHfkPVvIy6Cbah#blE|lkat#X{bZgL=b>R1BmOgrl z5T9s;l_=cEzz{)fEr@rf#ra%aBtg(i^cdP5gsmAfMpDBzv`yhyke@zl1QG~W{vc<+ z9W6HR%{n_0N?JSio1KqeUAwap_|DTu`Slr_{&=-paR@g__`b+?F{|)81zBTXT#IeQ7LRSRd`O~S{NX9jm_zSgi4+y z49QkoRj=lnxsE{Gc;b| zKq8PeGPVb z(c#??3PU0Z_r_si0S5bFW%>K1(#~gpf}h@EhlgJtxj_gRBHMrwJaH20RR99J&BSa; zEU56YE>fXDzqkjF+Ng~jG2*64P~bv^$L9Po(HXD=z23ysJ*3texb<>TD9AdPL#<8!Yica!XOUt;9C4?r9m5E*xH^oEonBp;sfwtFkizGa=9ZS|HmihQS=vuni3sOVMLXqqaf_Ly0Nb-P8kT~S8$+Q#i0-D~%{q3G=C3niuNflrPK(n^n4 z%qR2>>)c@E55{8KT1R&O&|2Mp%^`Je7L@Ovc{CpE23||Dwf%d}hQh5|37gqBSEv}v zIfKkze91-rav5IsvOk{Y7Gl8G*b}YkRE(!oO6lp*=_|e zJ?cm4EXtR#fkiA0eN8a22rL0UF9r7D!ILr#s``(ddfz7^p6bDTd&9(k~-6MdMBs(f1 zE!7*dN`uso4xW&!{(cS~Jn$^7xR%1YWl8>FPyPBl{iueWTvBZYO^X4gL(acjU3|xxu8JalQsR*bcRqy{44afC6DTQMgvbtpEiEV-Nm=Xu4NL25jI$CMvE z4h(>ZdwQeW5mh>B&#gIX%~Q`0$YaF1L=K`k-n(aw6eM$7Rd=nso#{*^j2VsxB+4|Q zmv#kT8ELE56jo!#$+rZm?9;n5<16yiio9yU-X#XNKvzkc*;TCGJOVqA)$bV1Zc5iR~VP1(-TgeGbocnGG+rs z=IMRgHz$-@hO1K1jq!tlkaRP}%Ctp6KW{Ns545YLhEgQkII=4-BE9^zJ*}_3OE@2LvKv30!`eujHt8j$X7j=;*mojx|7=YwJB>x|+ngCNE-FR*w&1uKf65;Gx zWtYuT=EQPL3kZ7p!_j45I;jGNFN92$&g)P4l%gTS%X7;M)~V|)9ahA#k@K7IL_a^V zVgQ6m-+M>czH1Zv0Ta!}TEjV`w}VjBOfM_M1`0Ls?{$+`P~b^-_5I5ZKC8?!^)^43 zijb^c-eF)Svcf*IbotD3F^oeT&HxU&OF7WQk5T`f9w18(9gsE{M zQ50H9;=LmE_%8aJ4@+NuOj=fBLu=s+M@q$=%JL|xR4^?8NK-pI#ocy%Qf&LjyM;UH z!imQ$&pzsuwXh_CveM)oYO@d8E%19Bej2R=6L#9GQJT~$d7J<0{q=gP^!(F@gWG88 z!a9^1Bp@I}{mHrKPcVxcU8@PDKyd4;rjb?lo5NvH?~ojQ%t)S3HuyTT7B#rs>k>oa zxCdRyM`|hcnML{I-9^9*kYFX1zNT1|k5Kaiw{B@EQ|ikvC8dmQub+PVdabx-0)_*T z09_1BK`2uXA0@MzjIiE%f30~zT>r+?=e&Jqp{xQ-0>U6Nz)67#y?E;S60A+$`C=0? zBsY~S6D>VQ=Zqa8D6@bO5F7{;lv(iI-Dj6BNh0BG+l}`Rg&wp(UEO9RQ(`$iXN{22 zt^?D+voCj*el{ZoLV$+kR)F26NsCr{uS#?F>X#mAd~+9f7jj?fFsu~qH6sHZjg%To zSn}YYs-;H}7|Wl(nDPKIRpe(TB1vibt@Ti41B>B0fnvd65!=*aYXV&ZkiPT2k zn62HvSKCPnrJ8tWw3doBI$MYk1CMr)hrGm3rUWC#B!_!d5UFAVhK)Eb0SZxY%82Gt zpcUY!A$-7rrela8@T&o;IM%~`&+s6^xvsg z2*KzW$Ye0k1DCD=Uk9TG|LE_D`6={Yj>Bw7*yqCG1aUsgeQOu0>+x(({KMU7mB9uH z&LZr$!*~tvSHZ1q!RAJ9^Wfm%jWAvYq(G>jMqe8w|KkuPL(tnw(jk0nL#ztGs1T^( zm>Zh4;;S3tPy{YtZk$=%c+KU%X6t~=f8zcf2lksKiI}`Hn9*YVGZ|Oz0@xTrUf-8PL;b`fe zbagByXIx?fRYF}x2B7;DhNAqfsg*@Db?;OuE8U#5jKAOW@m2W^E;hwh4NY;dY(aws zgn_OBCpz}TC5I=LC(L|ao-L|ZRtC@Cc%--M&gY+g1E?6TtE#4Jrnal!dGhLHOu4W! zklS%%BmhRC1=rHu*2kY*>wIXjN|nT_9Gb6v^ShJZdqFsRL*oZ?l_5OsWvH=$2?2}5 z_5jrMAHCy$s08~@9}S@qu5l(Mq#^C6l%y#8 z&j#stn*tPMr9`rHk;~bLeNkguWh7si575n*G30`2Hkf zIn-kWj|vUS2#E?sVDxNQ%}o5nPiVuOR>^7&OcBUxG#Fmqx}Jbl5sliWMr_eqX8qE0%?q}xI@-W zOiiYll=6G*9bp{XYOr9ffuSKt^jXJp8K<}Jdm0rQfMz9v(!7%ovx$XKdE{nSy3>1x@hjL*(0A zYj@u~nGM>G9*Dj7MrZ#(Sq!;yrqPbQ_jfkBl4&(?)ZOj+@TvDa)HnC^h)2DMmcq?K zP@xG~>P_cw=r7GssV%moihq^W-KwBW37x%P#)=UzW?s+U#*3o?{T*m`COfA)@vTDh4cn} z3E0mevks)|4&QBi{zZj9=OQi5%56bVBI(kN0M%nVZE|D;eBs0O)O6~olD%APEPNE` z+O2(bmngdW68XVwr0n%uIY8e_e=gqq2O3BZ(`ZS-dhU`vHJP9@{WQ%b55{NSB?SOC;wH)I6&BTpO6rzRZHu&TwOr~)S z6Bk2peFN-LR3*^ECUn$DoUp*P61u%Css-5JMsjAfwjvr3gb|9b;s31-AwA*2_y;SH zAko*m36GX20=z%PiD3)|bjV4Lt_z1x@n7sFew{3~SBY2OOePro(q6-eF?`Zy{NVkK zi%URvJ(V?dn0U^aC&Dy%7qQRTW2`sThuMR0BvGux9oH|<4iC72K) zW&G~9iNBw|dCWz<@;~-07c+nMJJPN$o+lfmJF>vP$yfhW* z2&R?2%}WJ3@yXcZsZb990t5i?|7ryUk5l#ySlIU5Qjn4}KR=L}?r&5X;@GPPt;XvY zJ+vvmy9dv2B|7cWoz0G9h5<`r@4h^t=T{;fZ?4ux&si4c75$1@y;LN@zKQ8%l7SlW zC#Q=)xJ{&4>IoA$`hehc!ayHRWyv;%nYvTGJl7bV;YX9gH<~q0lG@_LzgtV)oQr7? zU6DyBwPG!nInn9((La6UXC=W7*LJB7shJvZFUD zNQT@!l#f7%%xE$7LJ9^cv>+uRltvv=q*tQXX7KGI`lD9-^C0Roz+pMG(y+6G z7DDKa%c!>rMQHKmKKSGRi|Dc;n;Xh$sMf%00Ro}e_Eup1XB?ONOsh|CHa8t#`}(o9 zbwC72SU5BU2lvAK2AmniU1oB63ms^ICLM8m4UX*=>m(A*Si#^Y+lVU_JgA0OLSlu4 z>j^ZTLx0hQTzaBF!D$57HgJ|ib~XA^Gy0n>TAve#y=df$P)x%D2X+g%Np#H1Sp4*| z0`{0lsiP*;>u+4nDWycWk{Q2ODi*nWWZ|gZ*-B7*yUlEyY`vL2p%eSMsGqzy`tY&t zEBIOtWdNShL(@^D??%j@#WKHZX>!|)PL(RRuvIJ;JT7acOF=6apM6Yx%GmM!_Y+_3 z+w=Wsevg#;Z@2R!cdFOtY8HjeXOz4()3|uOF|y2qPuMC6dzi|P&XOZz@{wt3b({2= zw6`m_s%6#h`Yk8-)safwq!Jg^Z%>`w4Kv3dXi10ant`RK9xj2zEG_DQ`zCf0KWISADM zPb*n^|LO6EhZgf>VPECRrCDRC0sx5cO&zisZ(aB8lz7^ies%zDs? z5{J~|huE%LpSUpzz^2`;_nB<#$Lr=7+o)hvT4@gtA@$8^1)C-Mdf}eH?RSu@fJd)# zyBzeojx0nP*a+W$RQcxS4Xo zDpgUQmVHPt$jrZ_`6sE&Hldye>yTc3{qa4Ii}C{;^PT&fYnPUwB*;vv_b<+Uu1RTj zYXcg_<1@Ut#~PkZ4mPPME#Whet0mlHr@}#wQIIFq1cl&g67FtbH4jb|ygG&bdNia# z2Q=^xtI#3E6pOy>f_e?jM&OGsh-T0)7Qv{2uz(#b{ALurcm)0MhiK$y=+b#;cEQ>@ ztZe{GfSzsI|icx{MIPE zxE~rtB3nTREZ|e21P>1?VxO8&$PmY%+dKFN?eJfxF=s#{Wk?IK$3iGA=$mHrcQwe* ziMRwuI?(Mcc;*z*ZiEL_C@k~;GG4FCQH!1U5=qX=h?{Tj@D(g`k==4;e7!V0EIZh% zve5F^|7!BgTF7LPbu=5b)p}W`oa&LqusI8-j&e`AF;bCybS3fXX7W!4`mX%y<4u}g z4r0{tGxT5G1RZ(%<{<)zpsgm z#zamle5sds?FKg)760>5;r1*G3Vd)7rVC5^HQ}XO{&N@fHyS%OIpxwC-X|{{Q0|Tw z`FyU{)|#Ri>A)W9+UwF<4h^4*jG!B^)~}@GeJ01c=gI*S>gh`-Q_^Ba8?}G@@__Qj z)IM5Padh1O($VD)@3r&WZki4LdR6vJC*f*c*^bx*kv!CM=jLYB1omfMz91su?NNTn z==$KM^z#SRs}WqQ5`=f=kkN5#)Bz2q!J)SPsKlPw)21Le>A#$n2ZfKnW^Xwc(l#5I ztt|!UH$7UO3l4`ja7R~T4fEd}6n->@pw8A2-c|@d=wh-o{^WrusSD3c44fj14 z`=g&Hr5R!G9?j+P^vrbrspAf%Su%;x(B3AcluQUjvszbHNZRlf$65|GEf-53i;j=xFMKp>e5Cyp%LFvC*Z$mkP<-(b5J#GS0cR zgj|620MBzkn-DDlbw=2GShpf2Sc-F-NHFp8T=~qUXfs7ef;(c2Gqlnt&E6lr^5*2A zrU!KMLd{Tf^-&>AH`?mvy2XCNY`QqJYV=zrUOijRf8lE<{C-bogXyX2&lOlcOjWA< zAHCH1Kd1AML1KpBJ-DM^&g;}mt6XBH(c`6xCi0+Lm`VuoIbiFo&m_#s3%ePWQd1ed zrs&WY$T{#(_B#Q1+2cRIs4wgRIT>be(Arp`TM-3k+jcmnXqu1Xi zm>-%;r4#k}y*C~(&p#C^GnuS(`*4$HDcE`Bp^tl2s((1Ms}$*Kc5R5drLDQs({~Od zRrYg-He}L<)36dy&U|hcapA6E>cV~iwyQUqyxSWfb~;Z)5=+L0ZT85<_ijbENlVeu zv12ij(uVKNi~8AXR>sWp;^O|swY2+Py88jp{+ zv#*U*qILMa7CPPlqk!LBgBCq{H-KOApkJ+`KXAih4SX!VwSyiqz``a{b7*f91Z%ij zgx4mqU5W-g2shx;ZTS6{;o>z2h5-cNIS6blX40Q&^=Xge$j~!yzX^ziu677UAe8~F z87eHgn-V8dFyuu(BdV9tbQ*rQ7lq2;wn3x>lV!LTgH8q7WrQOJWK-aYGGr3qH6e)v zbXt_>fR>_Pj^Jx4+-oNsa>$h-kP(%6(Zmu88Gs%=(Myb^YWsBTU;p#QolN~pU24|B zT1jk**WbGmRv45v1zD5Sho984qSUG*uW2)&OU1Z^r?$U^s1?{8gBu|g% zWk2V06>qL?$9L{WbDbK^{cPhO-@4z*;TN85zGIPE^{SeJ(OIP$EzPSWcD*7l5SYQn zW_pE2FWD$o%FnNfdX`A?!V+qHxsQlpT#O5`bs=4q?QTwNt+jD=`uT^;cca-Ovg&K+ zat~IG{XYDRyY~zp4NNHcj0zfXf;@R0U9dO$PCvrG{z=%Y19{0ee{OIhlsdAfVQ&vA zNS() z&!_1HU9o2+;dC??`@NN*QgWQoS~#*xf=m?rYo>TwE?v$NznpH2Zt!X~d4MEtHDE|5 z>F89F4rx+Bo^Z+^vq={h(}W1Ya^20-LSD2QH6Kg|k94~K=~vgC8VyCr54ddUXr{`G z{VFz9#IhYi&cZx^g%)Qy@Y%d-DBcXFmaNnShewTkL$nx?UgUP)I^Ip ztC4m&l&hE7{B^0F}?Q`ZQ;5 zX!y@ZZbC;V7>uyG0sYWz;t zr}&z9*e)5H$(y8P5&#tJ7jnW4HD$6W_OzRpd}Nasy?15i$br@k5-;gWP!l}-GtE+Y zmBEIrU0Gw2JPz-qo^EwXw{`*q^>Mz~((R$wDidP?(>_loS7T^8$Wd~;XmU733C*r= zC?M|)Y^W?ISy;ck7S+a9chzfZAO#Q!&%bH4)dN*4u&G`hE4PhQ<*Bi1ritt?=cz_s z3i_>XUoE!ePM67@S-t2Fo^F?BGRD-4WOfM%b0B$};ft8Tx+ zCc>p62V40;hw?Ys#?{f-|K6>cMU2%GMBO(qmW#Rf`Y0 z-K?TsBQ$B&B*3ji;gCTyo=SGu48I;bBly4U5GMmn9)GG}t9ZidMdXGSz zjaM=vI(IRVHL(RHyR_M$jnwFJ{ob7lucmf5beu)MSgg)12zyydUxz~m>H*1FjoW^s z5Q9cqOgh`fk2SY_G@malORM^gy-s?0!rk4)N?W3O$yR9Gq>xD+1I3hW`istvk!WS* zZ3{?{!-6FWSYOm?6!gA9BAnE9w*+LdA|21*%Cv%smn_K>Jq-P#xcp4qqOrd?ZD z-FBX~=RR1>AEfpwJ2rM=YL1BYDDB%T&U6Y}cEvnq&g5_S>DIsdr&@5v3hJ!Spv+A7 z#Fe>rvm(G;KW5e6xIO?_;5}JvO?iwKL8D5B;o2Cz-OxWLm;ZFE^rsKwi|a^E)5m*- z*G3TLz|hHBT=eu(Ex66S&?UK^;E#7o3iSUTAn_sCq)^=YcLGxTpef*do*aZ1gmwCX?JlF)Fx%G zUAk-an_A39+&$Y*`i9R2ATzgpi%*o8Nw+9H88PIR*8O!Y%{=C3;_+9 z3d{oN)xgqdpA|4di#gn-L1_*x5V(VZd<6?q^vM$5XF?V&8l-SiK!N~i4RKhGq6X5z za8$C6vfSoU(P5E@UTL?AsjBhR+4Z?Qv9CVX`u6CiLC18pSs)UN%q;C{@2s2gxTu1X zsfCs`Gqj_C>OmysF*YJ6#g`DJa2v<(Ej@m+k16nb5pnk2yN3?9yUaQ&FVIC{DO{s8 zvO9H{3lz;B1#6W$`&82@AvRSt$_bB$k=tmGj=DTq6KJ8|L9N{pRziYZ&#w|iHm+NTw5ne}TRz_`8cZqz8-sks+WF@{_ z4JHea&^wz;w7wAEv<&XAMR93;RR8?Z;!n>!&x^FhvDD@Z#7a_~gs*EC3pw|Rz9ovO zoS*K>MtY76jEu}kmPYm~jivp2vqjC8wdh^1=6CHYI`?ffN)nAVc6Z&`QuYSpRfo51 z@y3>xw42LRe<#ap?-6`cL#{bCK)VL=1!iS{d9uo@b9q^09qAnsQv)x}LrPZeZxJ`^ z2O!)=H=4^kTG-sMM@3 zl}ASdL)S!Mp(5k~RE?@e#)^%akSB8`X08OiN_??`201K5P$i8udX(XajRMw5WKouI zsidA$A)9TZn?O5w$j}E^39`p?W!@~K?;POCKgw0Lx+2O+pkP)!!sQAu3 z^!s~|T81bL6oz~aT`l56X81UQ+6|B<;TuhWFjPeZG9cB2P!nuYxRMaJH#w`8kT+4y zN+KLB-kHslW>!++?@VL~yX=@pZYy(IgVZWv9w4mlP|NG(ZjHc@c%Mmq(JBuZh)FTu zQ+Ff~>ZgIr6OuGyR8W>8M>!|tN}Ef;5~Ipdo_x%2o}U&2-JJ zGk7J8kE?W2SVj>;Ub$L8&1Q12iP34vyLu|8LbHoC2n(^a__ck^l?|@PBbprbGo#4t zR7rNod)KN-M(1j`K2G$Ug-r!ErsxW_Wf?Fkwyg7ho%{BsMxU=7)y!uD_DTsIJE|jz zwZM$_@n?CtoXiLrs$;&njVh7E?5GCn^x@+hBeT2mX~$O5tdnw`-8WB}RDK0R>bBDH z_FMCPP_Y0Z4E2tUY;q9k&%~7#swQil^_#_kE@4Z)zI3H!@t*$aBc<2hG95ZCMq{K? z+fa5*&n!w{%e$ydJ=>ku>AFM>5fm!T3EQV%GsOfxQcj0LEz2$;DFL+WQrQPThBxq{A{#{OtRaFMw^C3 zJNdN;*JjczZ140dnSmxXl2BO3kak&`q!R+sM?xxvlEu)8CXJPcd*OgQcCsBp`u;(vmc$EfWB6o%fh!FK`SA& z5k;*{FjmBN1>6e4bInLV&?JRm4n!HkB%Ue4kQUxt6Lnf-lq0AJH)k8&cJgisHY2>V ziB{`~7t379%x=+y+Ad`gHg;-!g`!6*`E@8a{n5&XS^mWXO--ysPYZ9Y2MWEeq)N4_ zq|3t-rCCAOour>pz4)cdz`>!B*4B)_ev0Yi@!J={)>H3W$S6goKM ztG{-$3R{FqLz>)-!LE3s*BUFb8&Z8Mx?N+N9^I|<`te0H^`wuUo;4zmWifZU&Xyn7D zvc7nHuRK_cYwNnTIj{XdcG(FH zb-*pzUZegD{*}W#nt7+SNkka zv9Lx+eH!MYEaq#Xye1rTDiSr+tEWR%RNNu<+k~?#_=JxL6sm&?b|WpysVr6I{Iki2X~o8vRVGPkq6ZX8(cbZ{3E|C%|rpPcESL zgIt4x78~*US+xJO@Uv0;azCM$gM&roD$2>Q$&BwN;anV!SwR4FIf`pE^lQ=e6#i-( zQQ$-^gRDBztt4)V_*(;PE>^B#ys%lma4*yCmPPGS35}@HtxLB;gS)M_rsK(-a(lOF zP%j&K@8Wfn@}d4dgH(P6BfcSrhN4F%acm<_K>Jy|K>pwCy=RbQS#_wp_VIbr`^rjF z-kYwf_TAN8?WV`{co+s|aAG9T6-eSrx(FGNc!CRpi$DmZ5ikRc>+zI?&Wu&Zj3m6d zIR_NgfT8c0r(c?c&^{na6)xX{O*kVdujgf_71cU3t6LTjDIjp)uHk;S1paoeef-h8 z10wG$5fy#f&dCW%5D@gfb*w?vf7zalq8J-H)b006L~V<+tBHND`1XE{rOs%%bb$g4 zs@nN38}1+8?QoI)Ai2+^x!=K_T`x{tPtDKd7(3g@qaP-vKX!4Fjua@O$-yWrXm&7} zkWinCJvW+fJ*v!<#4Uf>BuFn^j+FJZpe2qJ=^sz#E=QBUSE&l|if>ghQKPcnrY>>x zP12Z*6>%tb$if@dg+!qWVA$eMYC; z%F7u9sWR%HT<&q0c3adbjp5DV^`Vu-Juc0AgNvVQH|u%jc(C-weE7JNzc#;9E@{4U zfC7o$N+7w28WhA%TI{U{4TWtS`PQls@em*ooplh2z-J$W_pX3R1Bn=Pv_d{Rw7PN@ zAbHzX|J5PT&Y|8v9~lL`5xikIcnGc!5S1pPc2BujAS#t;e+~M!TRdVTf*2ogpiCOX z0*VUg;YM7gM?ZAKpSPl70VN4Iq>co~Vigr@uucEM#EtMph_cvylpTgiNeVIp|Xc)CKn5d>EuJFP3HsYLo#`}I8a#XDC`iG8cnlJZf*@Ls~uyx z%O{%TV@KPbc`s7(kbUg_{_;&&Z>iR4AMdTdRGw#|&iAYl^=VAEo#=EZU#4o%`<)oz(;d`d(l!<4(L6K{}(p~7gG0Rmr z(cxB8+Ff`#nE$Yu8(YX{8kxs6)OS{rj|JFojc09jOoxNnQ4&*uQXC_&F~@YIP(h;c z#OQcRElAE?+8sMr&&cDKeHUhnA3vZcCArP1d+N2BBF#^^BbQcv4Gk6dh*XP8(O#)} zYMyxg5;B+3ofc?Np*;#PV;H{*ldpr803QzvB1nq>1i%t1C#W4ab~DIc%T}qBK9-p^ z+j=vp#jWUmv-VK6v8!4?lm{n8n6Nk%fxRZO#mv97%{e*kEl;-7%>DHZZ<|)zZbFmW zL^4HeY!PObJhxOVMX0ZRf}B}}H4l&gwYb74Bp{Xp|EPzFYVkEk+p6St`QE%}B?Ha<&)o7_I8 zwck_cGAiz^Hhld{|Kx73K2f1xsL+gn7?f2|rXhnK6`?r{`3>CHfa(+A&Ve`qT$uXC z9okJmE+Kgr5tr;0pEI*&1|9BliB40HA?~R$eA|!kk>#r*D@m%alp<5S?Oa3RYiawUrC>AQf&G2W(3|FsY)xC4&`bYO4Or< z8pZ5ez5*Glsf%w;D!qqDrAEA%$f2CGuc~3_Y=!sY20;-Tz_}469O&OY7*<*+i`W!-8B#(E9$nN zXrN@(3|qU?%e8*@nX1H6Ywxaf!ZdZ`r3#aSX|7ak%Jau+^!?Xtd{46P?u^K1UYIv5 zTtJYddk%z?ID287ec}PWe*}6DtgN{0fo)Amq1e-AUW}Etw{k~!YloxdFP+eS60}t@L{Z)!k?w6#oV3u_WH@D{>YJ6v_G)XIlye9j)YE$^xP4v5z5^O< zme?lP>PmF5+w$X>V7D8iMn0a%OeQnKg0wjuvE}*4TgfIXKpF;jpoN0X97I#Fw;qOO zp*jt_Xz*c>)&bN2QIG>Dzkstlh*6;i9r_S~Ryb8Elkw|xKYMd@L?Axx)HyUNcbW1D zl90*g1^oR3ij5e0sF52Cz}mXH!H9H>^zv-(11;>M`_Pyh$_Y}(5~H(7$l_zWkQ}VatT{_cyXn0pM!orLDne6!GU0< zk?Bu}@4x4(*=zCu@gWuZ+7*u}QS3Zof76$>RcVaX2KScVc7B-sgO5B`Vfczn1P}!& z3j9Q^fHb!t;e)AlFjDB%9Vi8Wj=%vsJh=?-2}rHLQLRGDl7oQ+t=E44`O7&4%_($; z(pW*E<2J6;s)mIa6%QzKTylMb;SKv=4V5h z+5Q|fF?|)x^FQ@{uvNVzLz977+(~D*Gnsvs94`515*zuQCyqcy+zIQLkN|2$kK9N&y`&aG$ zA(Q1mrnWLzpZp+s$oEi>eq=3Hh@;Om9!P~mpSS$zndG|*C1J%bI`geIVpo;_wRv;b zooy%f88b3ET*)78*RnLpH*)K5M>aDO8^c|#iunlIe?WP8r{Ic7qie#eBRRoLf|A{o7h#|_%ADwsMT_5stSS2kCxKBr|b zPiuEO(UKpYdK=LtI9Lal7NO_|r3y+2(i|Mz2NZxsgq=L#Wq=3(0EtmP2wQK$Fe4$ClUKreYkM^U?i4edqP%iUL>5%cC?7EF~Z0;DL5!KaW~1if4mm|9Ziv zpdP8D-`y^7HpLe-)F>w07|D?`VI=li=z*K55Ak0K>i zsQ!RY5o_>xI6~ISmC6y-ErCchMEk-iT^UP&$^XYzg$jbr9jPpTxXWEfP^(z3swKlo zSxWGY4auBx+rQ`ltOzb}Tlc^Hm--L9yySi3dBK#{b{|^*rzuZsRedN?=;-v$4YU`F zlqVxN?s~bK`q=K)141%?b}UvEmxd=3udL@n4*JUsB{ZsL6{OasIB27=NwK_`39jZl z52}L^Ia$X(tiUhN=YFS6b@gVt+CV;0#SX8P-&oB)X5%SNujEzpkz`91f4V|*EH7PL z_hL?YZpK%u;$9pmUZ0lh4fN&3u)VBkvJkr)U~mA=w1L$GAun8cABrJZ7==R>aA6RH zMPOy1)1Y+2F%ld*;3`6mfUAAz(m8bH8Vn3U{{R{o1pf?b=8^1%b1#DTWn8hzKBiKF zn%GV&Hp6khz`r+zn{-K&LZPPRy_M91UG$B4tf0`qBvj~OeG6z3kPLDeH&!DGLKn~f zDZtHN)lKK$ytx%p@ZFuAC)PLM4K7$rz~^?uPuAcL7c>~) zAJ;*_f|Atztv0uwy6n$q zfXI5JJN0x6Ew{HQu$f74WS5ooEakUJG*A%lV8B|hP)Xo}vP?6k4xK^GG-(+_S^DW{ z1nar;W1a^(wT4dKwbr#(b6p?roO@raFsL-Oo)v+r>ai);itfb9#n(x#j(M!=*fLss zqaVskDo|zXJF+>y(-%`5{z$S|!uPG*_YBitNf}SoN4Idakk?l+Dx_cAj_M4^eBkK0 zyk`65p^l@Ci!TfnnpJgsTcpK^RBg`X_?^JI$yAH?KM?8C)-Pjj;wi3}B8|3^y*@d4 zRoUdMkvgx{X^Rs}cC&`p?d2CN+rI-3e=)MW{ZhPypt;?g3JJxMq%Da`JNxy^@y|A^ z8?_Y8QXE1v8BtrrHCoE6An$Ev|M_AJWaw^G`f2KuP27tEi8`ZtAs|I!@I*CTgP=z( z3@!5;zFeJ4ig9Ly$p)29SEA~ZOuLS@EAb!fRvl|4G8sIxf-nuZ2t#9VV-NrV0SG7JiaV zKlQ71hv09xtuV(f?AiCHmoDM$AlmXmSq6t47zQeBxSnMqIlOnT!Ge^f!s!L(1OqD{&!15H?&6MAT; z+1Iy2Du?OrX2&?9W-y)#An+nsKyaRbGKLfaH<%O9XoH0?RMkRJfJeJwHV5$(oMJ$& z#8-o~#BdIt4F$1Bm(OmQq?xsZ!6(zf&JA zmF#4;ZeGCPxPn5j7Rn zvAYmdkf^Cy88Xnjtjt7OGUym9M?|#jCvw!(25wg?jTkwxT&0Ki67o`_m|=CTdK6VL zISSQfiDpq$3TSLrT-hKc5kv{O{V=-)J3*wx5DmgR7vbZlfWi<9flUi89T0i!ppjV% zsWePYrWoEgH|BtxYFYD`c95V0hoXaInQbR3Kp2uDCD0SHKq zVBs2i>vb4if_6RjM`=oA{_umClo3O~gU7(L1JxBUZ~@o5kR-sm`(3~H6TiBu`pvWz zAf(jkA1jr$o&el=3iNuIT7-SOAe2D73RFs@0`l@aBxSj!NhAq8=D|y894w3VTCz!l zM}mT{EU)L0B$jto@_G*0QF+Fj$!hqEQ~nm0_KZcb8OdxEgtz8BjXh4$q-{|$R}s#p zP|%B{L4W~(H2?}=3$ZycN)Qe~lLIOVKmtrIfrtwsf@&!*avyiNg>!O z7?R}*Gatv&D}Eu7lr5}0;?2u6tx=#dDjqYkY$m_sr+w}s5u;yPEolfsO-MC0l&kKSAlpw8u|&q^8nuiI1BI` zzzE;!I9c$A zVi;M5);fG+tL%Ws_NJ(o9;|e1egZ!0QdmX06Cx&peO;9p_l?rgwPsP zDWQ^ql}$KphuJkCBq(F>m!~H zj0Tq?i&xBqwrpr%6SzD+K;x(m5b1Lb-rqt`E_49`C}=avvegl2QRswxb0Oh~rrDpj z5AEx`)xTW;Pa9DYwmajo_XQl;psOu^%-7Kfe zIVk5(Uyj2DIPaTO7OX?@@(F`w;))n7kbRBDO-WK$vTbI?lmdQ7$7?O@*|)s8Xi@7_ z8VJH($%!(eQl(A6V>c7qJl9Og?<^-ivRji%6LDFtu`_lpy<34YsbZ?Y{a~?VH!)pG zW@#PQ+a#exMG34iQ|kdpufXy&RIA~g*Wk1Fz>C-5$s&EEiA4CJWl`&{>m3i!fzsy(Wt1cdw635x3{Bk6uLS< zrvrw8SOypl2m)vo9H+(^kjkcf<6Q0ES&6wf)^62AjTnE1gjCS z02LMh1{ex6OF3=P|iIZ zuIQ_*)6kMdajeVCD5wxi6^n576;CQEfBaO#&#s=kt6KHylXNsKH5i>*N2#MuvrEW@{8s!9ZS(cQB%ZG281?=8n$zr7Yn9-UGG(tR>zsJ7S$l1w2aLf3ySH|^ z^0$H{Q>YZO4$>0tHBz(L66CnP&dL6Z9m=-t51mW|Q`nReDuET%U7v_$Q-Rx-&`SUx^#C`>0S>P zV$(@vrOjF4vnNCp}U&**C^g6pLk;5Gf#c857qGSYs zf}d}4{UV#oU^9Ye9UC;rA4Kb`=d$U~1C0GTly?6{+6otP1)BNo3L7)K2#xhHy9T>j zA(DpskHa^fg|24oFd!8}EJVfixFjMXrlP;3lh)8Jo(kQ;*A5L|(@2XYZe`=Q1RW*&Mwp+W(A z1MLp$n%q}wjcu6@9yeq)zEn0ov!J?fKf#&vKK9Q^;@;ow$k=yab}Zv^o)LL z%X@5pq5r%Zddt6ekKMs2LOb@$Z|;cH*6s%W(%blh$7`RO*D6K#u5C9kez<>~7 z00IDEKnN31mXLSL59k|!zXq`K>yfv=nYIF1E(;}nb@hIR!HesNpg>0O{ty%;U^z%- z5n@2A1h*gYYO&UcyKK~(3q)E%O=fy2#2lzZ3q?G(yyNoHZ~sHszEr_(kPFwj)d8Xu z!4WT7-hg}_N+JRRGC7FFAr^;d3~~i16rqrZSOkI*$Y(&Ogn`T0p+z6L2Q($fhvCL` zu$kbY{jjtKH>RMy8u|yoXo6GqU?5<014}737e!2rD#WqEkUn82^>Sn^q|Z~toeh!- zL3cI#?2>TYM*aPaPemF`7N$uqjRgv>THaydmNoRAD&?)|m{zNJ+`@jBAU9W%(TQ+P zy*`!^e1WVJp@fR;e}ARE-NNoOjJ?0kMB!i?Jt%H;Iy;g$n$PWQ&%*lUVzJv)R2W@K zr7xOEI~N|RX-I^OQB?tkRe4rep4IJ4R@u9K_trSIgj{7Zyf$gwSgy^amB7bZ+NRP; zvoB~)W>`*1Czn>FaO4A-DB|C1ux0Nc2`|I^<8S%q++t1w$ z-BYjq;dJ62f*2jn++kNw=dufH>6=leN6%j0ECMAbD7k}`-Wm>^*>Cv%1@BT`*3_Er z$f5EM{m%QSnYY_htFjGJ!09HWR{);>&07wKVQOupk(vJcD0_699 z6;IgQw$=ZOQZBnK2zyLM$G*K-t3fSIP%OZoJOMXn;ESJxcZMLE#db4t>dEC0sZyfP z_Yzw%^yDn@(RTRGc(`s%TYOhFc8=8u>Zu{hyNOaMToMrws9eTk2>~FW0hE`Z_%0A{ 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 M07*qoM6N<$f)B>UumAu6 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/BLSURFPLUGIN/images/blsurf_const_size_near_shape.png b/doc/salome/gui/BLSURFPLUGIN/images/blsurf_const_size_near_shape.png new file mode 100644 index 0000000000000000000000000000000000000000..9e5ad6c0cb7a9ef2a647d095174d18e9f2a8c130 GIT binary patch literal 64430 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 Qhk!4*tg=j@l%e1M0Ej~Zf&c&j literal 0 HcmV?d00001 diff --git a/doc/salome/gui/BLSURFPLUGIN/images/blsurf_const_size_near_shape2.png b/doc/salome/gui/BLSURFPLUGIN/images/blsurf_const_size_near_shape2.png new file mode 100644 index 0000000000000000000000000000000000000000..68620f39e863710870f9b4379ab44a14b75feb34 GIT binary patch literal 57870 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

    w6YKb{3bmH{|yrDpX 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 E0J3qxDF6Tf literal 0 HcmV?d00001 diff --git a/doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_advanced.png b/doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_advanced.png new file mode 100644 index 0000000000000000000000000000000000000000..4fadb6b489bfadef4355128d9dc4014f9811c40e GIT binary patch literal 36675 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 L)z4*}Q$iB}+#jCU literal 0 HcmV?d00001 diff --git a/doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_enforced_vertices.png b/doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_enforced_vertices.png new file mode 100644 index 0000000000000000000000000000000000000000..4a76b1a73cd7269d0375e24bdf8dee40a8fd7822 GIT binary patch literal 30233 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_sizemap.png b/doc/salome/gui/BLSURFPLUGIN/images/blsurf_parameters_sizemap.png new file mode 100644 index 0000000000000000000000000000000000000000..2b38197590c86d043083e5449add00cd839f55d0 GIT binary patch literal 19241 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/BLSURFPLUGIN/images/head.png b/doc/salome/gui/BLSURFPLUGIN/images/head.png new file mode 100755 index 0000000000000000000000000000000000000000..307d9ef9a4c07f8fba2c8721309a978433bcf63c GIT binary patch literal 78545 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 D4zrO! literal 0 HcmV?d00001 diff --git a/doc/salome/gui/BLSURFPLUGIN/input/blsurf_hypo.doc b/doc/salome/gui/BLSURFPLUGIN/input/blsurf_hypo.doc new file mode 100644 index 0000000..1964dbe --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/input/blsurf_hypo.doc @@ -0,0 +1,458 @@ +/*! + +\page blsurf_hypo_page BLSURF Parameters hypothesis + +\anchor blsurf_top +BLSURF Parameters hypothesis works only with \b DISTENE \b BLSurf 2d +algorithm. This algorithm is a commercial software. To obtain a +licence, visit http://www.distene.com/corp/eval-distene.html + +\tableofcontents + +\section blsurf_general_parameters General parameters + +\image html blsurf_parameters.png + +- Name - allows defining the name of the hypothesis (BLSURF +Parameters_n by default). + +- Physical Mesh - can be set to None, Custom + or Size Map + + - if set to Custom, allows user input in the in User size, + Max Physical Size and Min Physical Size fields. + + - if set to Size Map, behaves like Custom mode and takes into + account the custom elements sizes given in the Size Map tab. + +- 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. If both the User size and the +geometrical size are defined, the eventual element size +corresponds 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. + +\ref blsurf_top "Back to top" + +\section blsurf_advanced_parameters Advanced parameters + +The notion of diag used in the descriptions means the diagonal +of the bounding box of the geometrical object to mesh. + +\image html blsurf_parameters_advanced.png + +- Verbosity level - defines the percentage of "verbosity" of +BLSURF [0-100]. + +- Topology - allows creation of a conform mesh on a shell of +not sewed faces. The following choices are allowed: + + - "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. + + - "PreCAD" is an auxiliary CAD pre-processing module which has + two main goals: + + - Complete missing or inadequate CAD descriptions. + + - Perform topology reconstruction and specific geometry + enhancement for mesh generation. + + \n This module requires a specific licence. The following PreCAD + options are the most significant and important ones: + + - Merge Edges - allows PreCAD to optimize the geometry by merging some + edges. This option is 0 by default. + + - Remove nano edges - allows PreCAD to optimize the geometry by removing + the nano edges whenever possible. This option is 0 by default. + + - Nano edge length - gives the length below which an edge is considered as nano + for the topology processing. See also the \b remove_nano_edges option. If unset, PreCAD + default value is \f$\mathrm{diag} \times 10^{-5}\f$. + + - Discard input topology - computes the CAD topology from scratch, + without considering the topological information contained in the original CAD + (useful for iges files). This option is 0 by default. + +- ExportGMF - saves the computed mesh into a GMF file (.mesh or .meshb). + +- Add option - provides the choice of multiple PreCAD and BLSURF +advanced options, which appear, if selected, in a table where it is +possible to input the value of the option and edit it later. + +- Clear option - removes the option selected in the table. + +The following BLSURF options are commonly usable: + +- \b topo_eps1 (real) - is the tolerance level inside a CAD +patch. By default is equal to \f$\mathrm{diag} \times 10^{-4}\f$. This tolerance is used to +identify nodes to merge within one geometrical face when \b Topology +option is to pre-process. + +- \b topo_eps2 (real) - is the tolerance level between two CAD +patches. By default is equal to \f$\mathrm{diag} \times 10^{-4}\f$. This tolerance is used to +identify nodes to merge over different geometrical faces when +\b Topology option is to pre-process. + +- \b LSS (real) - is an abbreviation for "length of sub-segment". It is +a maximal allowed length of a mesh edge. Default is \f$0.5\f$. + +- \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. + + \n Default is 0. + +- \anchor blsurf_hinterpol_flag \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: \f$v = h1 + t (h2 - h1 )\f$ + + - 1 - the interpolation is geometric: \f$v = h1 \times \left( \frac{h1}{h2} \right)^{t}\f$ + + - 2 - the interpolation is sinusoidal: \f$v = \frac{h1+h2}{2} + \frac{h1-h2}{2 \cdot \cos(\pi \cdot t)}\f$ + + \n Default is 0. + +- \anchor blsurf_hmean_flag \b hmean_flag (integer) - determines the computation of the average of several +values: + + - -1 - the minimum is computed. + + - 0 or 2 - the arithmetic average is computed. + + - 1 - the geometric average is computed. + + \n Default is 0. + +- \b CheckAdjacentEdges, \b CheckCloseEdges and \b CheckWellDefined +(integers) - give 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, that sometimes constitutes an error. A message is printed +if \f$\left|P2-P1\right| < eps\_ends\f$, where P1 and P2 are the +extremities of a curve. Default is \f$\frac{\mathrm{diag}}{500.0}\f$. + +- \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. + +The following PreCAD options are commonly usable. + +- \b closed_geometry (int) - describes whether the working geometry +should be closed or not. When activated, this option helps PreCAD to process +the dirtiest geometries. By default this option is 0. + +- \b debug (int) - If debug = 1 PreCAD will be very verbose and will output +some intermediate files in the working directory. By default this +option is 0. + +- \b eps_nano_relative (real) - the same as \b eps_nano, but relatively to +the diagonal of the box bounding the geometry. By default this option is \f$10^{-5}\f$. + +- \b eps_sewing (real) - tolerance of the assembly. It rarely requires to be tuned. +By default this option is \f$\mathrm{diag} \times 5 \cdot 10^{-4}\f$. + +- \b eps_sewing_relative (real) - the same as \b eps_nano but relatively to +the diagonal of the box bounding the geometry. By default this option +is \f$5 \cdot 10^{-4}\f$. + +- \b manifold_geometry (int) - describes whether the working geometry should be manifold or not. +When activated, this option helps PreCAD to process the dirtiest +geometries. By default this option is 0. + +- \b create_tag_collision (int) - creates new tags from original ones in case +of collision (entity merge or association for example). By default +this option is 0. + +- \b periodic_tolerance (real) - defines the maximum distance error accepted between +two sets of periodic entities. By default this option is \f$\mathrm{diag} \times 10^{-5}\f$. + +- \b periodic_tolerance_relative (real) - the same as \b periodic_tolerance but in a relative unit. +By default this option is \f$10^{-5}\f$. + +- \b periodic_split_tolerance (real) - This periodicity processing related option defines +the minimum distance between a CAD point and an imprinted point. It allows to indirectly +control the number of created points and small edges. By default this +option is \f$\mathrm{diag} \times 10^{-4}\f$. + +- \b periodic_split_tolerance_relative (real - the same as \b +periodic_split_tolerance but in a relative unit. By default this +option is \f$10^{-4}\f$. + +The following advanced options are not documented and you can use them +at your own risk. + +- Integer variables: + - addsurf_ivertex + - anisotropic + - 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 + - anisotropic_ratio + - eps_pardom +- String variables: + - export_format + - export_option + - import_option + +\ref blsurf_top "Back to top" + +\section blsurf_local_size Local size + +Local sizes can be defined on faces, edges or vertices: + +- The faces, edges and vertices can belong to the meshed geometrical +object or to its sub-shapes (created using Explode command). + +- Groups of faces, edges and vertices are also handled. + +- It is possible to attribute the same size to several geometries using multi-selection. + +- The sizes are constant values or python functions. + +- In case of a python function, the following rules must be respected: + + - The name of the function is f. + + - If geometry is a face or a group of faces, the function is f(u,v). + + - If geometry is an edge or a group of edges, the function is f(t). + + - If geometry is a vertex or a group of vertices, the function is f(). + + - The function must return a double. + +3 different types of size maps can be defined: + +-# \ref blsurf_sizemap_computation "Computation of the physical size" +-# \ref blsurf_attractor "Advanced maps" +-# \ref blsurf_attractor_computation "Computation of attractors" + +\ref blsurf_top "Back to top" + +\subsection blsurf_sizemap_computation Computation of the physical size + +\image html blsurf_parameters_sizemap1.png + +The physical size is obtained by querying sizemap functions associated +to the input CAD object for surfaces, curves and points. +Each function can either return a value h (which is then trimmed +between the two bounds hphymin and hphymax), or "no answer" (by not +assigning a value to h), thus providing great flexibility in the +specification of the sizes. The computation depends on whether point P +is internal to a surface, internal to a curve, or at the end of +several curves: + +- If point P is internal to a surface, the CAD surface size function +is queried. If no answer is returned, one interpolates with the values +at the vertices of the discretized interface curves. + +- If point P is internal to a curve, the CAD curve size function is +queried first. If no answer is returned, the surface size function is +queried for every adjacent surface and the mean value of the returned +values is computed. If no answer is returned, sizes h1 and h2 at both +ends of the curve are considered (see next item) and the interpolated +value is computed. + +- If point P is at the extremity of several curves, the CAD point size +function is queried first. If no answer is returned, the curve size +function is queried for every adjacent curve and the mean value of the +returned values is computed. If no answer is returned, the surface +size function is queried for every adjacent surface and the mean value +of the returned values is computed. If there is still no answer +returned, the default value hphydef is kept. + +In order to compute the mean of several values, the arithmetic mean is +used by default, but this can be modified by the parameter +\ref blsurf_hmean_flag "hmean flag". In the same way, in order to +interpolate two values, a linear interpolation is used by default, but +this can be modified by \ref blsurf_hinterpol_flag "hinterpol flag". + +\ref blsurf_local_size "Back to \"Local size\""\n +\ref blsurf_top "Back to top" + +\subsection blsurf_attractor Advanced maps + +\image html blsurf_parameters_sizemap2.png + +More specific size maps can be defined on faces. + +- Attractors allow to define the size of the mesh elements +on a face so that the mesh is the finest on the attractor shape and +becomes coarser when getting far from this shape. + + - The selected attractor can be a Vertex, an Edge, a Wire or a + Compound mixing several entities of those types. + + - The attractor doesn't have to be a sub-shape of the shape to mesh. + + - The size will grow exponentially (see the formula below) but is + bounded by gradation, \n so if you want the formula to be strictly + respected, you should set the gradation + to its maximum (2.5) in the arguments tab. + +- Furthermore you can choose to keep the size constant +until a certain distance from a shape. This option can be combined or +not with an attractor size map described above. + + - If the two options are combined the size will remain constant + until the distance specified in "constant over" and grow then as + prescribed by the attractor function. + + - Else the growing is only controled by the standard arguments of + BLSURF (gradation ...). + +\image html blsurf_const_size_near_shape2.png "Example of size map with constant size option, the size is kept constant on the left side of the surface until a certain distance" + +\note The validation of the hypothesis might take a few seconds if +attractors are defined or the "constant size" option is used because a +map of distances has to be built on the whole surface for each face +where such a hypothesis has been defined. + +\sa Sample TUI Script of the \ref tui_blsurf "creation of a BLSurf hypothesis", including size map. + +\ref blsurf_local_size "Back to \"Local size\""\n +\ref blsurf_top "Back to top" + +\subsection blsurf_attractor_computation Computation of attractors + +The size grows exponentially following the equation : +\f$h(d) = \mathrm{User Size} + (\mathrm{h\_start} - \mathrm{User Size}) \times e ^ { - \left( \frac{d}{R} \right) ^ {2} }\f$ + +Where : + +- h_start is the desired size on the given attractor shape + +- d is the distance of the current point from the attractor +shape. The distance is the geodesic distance (i.e. calculated by following the surface to be meshed) + +- R is called the distance of influence and allows controlling the growth rate of the mesh + +\image html blsurf_attractors2.png "Example of mesh created using attractors, the attractors here are the side edges and the size grows from the side of the surface towards the apex" + +\ref blsurf_local_size "Back to \"Local size\""\n +\ref blsurf_top "Back to top" + +\section blsurf_enforced_elements Enforced vertices + +\image html blsurf_parameters_enforced_vertices.png + +It is possible to define some enforced vertices to BLSurf algorithm. +An enforced vertex is defined on a Face or a Compound by + +- selecting an existing Vertex or Compound, + +- or creating a new vertex given its coordinates. + +The enforced vertex is the projection of a point defined by its +(x,y,z) coordinates on the selected face. + +- It is possible to define several enforced vertices on a face or a group of faces. + +- If the projected point is on the boundary or outside of the face, it will be ignored. + +- If a group name is specified, the enforced nodes will be added in the group. If the group does not exist it will be created. + +\sa Sample TUI Script of the \ref tui_blsurf "creation of a BLSurf hypothesis", including enforced vertices. + +\ref blsurf_top "Back to top" + +\section blsurf_limitations Limitations + +Currently BLSURF plugin has the following limitations. + +- 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; + + - BLSURF + Projection 2D from faces meshed by BLSURF; + + - local BLSURF + Extrusion 3D; + +\ref blsurf_top "Back to top" + +*/ diff --git a/doc/salome/gui/BLSURFPLUGIN/input/blsurfplugin_python_interface.doc b/doc/salome/gui/BLSURFPLUGIN/input/blsurfplugin_python_interface.doc new file mode 100644 index 0000000..0d3efc1 --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/input/blsurfplugin_python_interface.doc @@ -0,0 +1,159 @@ +/*! + +\page blsurfplugin_python_interface_page Python Interface + +Python package \ref BLSURFPluginDC "BLSURFPlugin" defines several classes, destined for creation of the 2D meshes. + +Documentation for BLSURFPlugin package is available in linear form grouped by classes, declared in the BLSURFPluginDC.py file. + +Below you can see an example of usage of the BLSURFPlugin package for mesh generation: + +\anchor tui_blsurf + +\section blsurf_construct_mesh Construction of Mesh using BLSurf algorithm + +\subsection blsurf_construct_mesh_basic_hypo Basic hypothesis +\code +import geompy +import smesh +import BLSURFPlugin + +# create a box +box = geompy.MakeBoxDXDYDZ(200., 200., 200.) +geompy.addToStudy(box, "box") + +# get sub-shapes +Face_1 = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])[0] +Edge_1 = geompy.SubShapeAllSorted(box, geompy.ShapeType["EDGE"])[0] +Vertex_1 = geompy.SubShapeAllSorted(box, geompy.ShapeType["VERTEX"])[0] + +Face_2 = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])[5] +Wire_1 = geompy.SubShapeAllSorted(Face_2, geompy.ShapeType["WIRE"])[0] + +# Geom object with sizemaps can be unpublished in study. +# They will then be automatically published. +geompy.addToStudyInFather(box,Face_1, "Face_1") +geompy.addToStudyInFather(box,Edge_1, "Edge_1") +geompy.addToStudyInFather(box,Vertex_1, "Vertex_1") + +geompy.addToStudyInFather(box ,Face_2, "Face_2") +geompy.addToStudyInFather(Face_2,Wire_1, "Wire_1") + +# create a mesh on the box +blsurfMesh = smesh.Mesh(box,"box: BLSurf mesh") + +# create a BLSurf algorithm for faces +algo2d = blsurfMesh.Triangle(algo=smesh.BLSURF) + +# End of script +\endcode + +\subsection blsurf_construct_mesh_sizemaps Adding sizemaps +\code +# optional - set physical mesh to 2 = Size Map +algo2d.SetPhysicalMesh( 2 ) + +# optional - set global mesh size +algo2d.SetPhySize( 34.641 ) + +# set size on Face_1 +algo2d.SetSizeMap(Face_1, 'def f(u,v): return 10' ) +# set size on Edge_1 +algo2d.SetSizeMap(Edge_1, 'def f(t): return 5' ) +# set size on Vertex_1 +algo2d.SetSizeMap(Vertex_1, 'def f(): return 2' ) + +# compute the mesh +blsurfMesh.Compute() + +# End of script +\endcode + +\subsection blsurf_construct_mesh_enforced_vertices Adding enforced vertices +\code +# Add enforced vertex for Face_1 on (50, 50, 50) +# The projection coordinates will be (50, 50, 0) +algo2d.SetEnforcedVertex(Face_1, 50, 50, 50) + +# Add another enforced vertex on (150, 150, 150) +algo2d.SetEnforcedVertex(Face_1, 150, 150, 150) + +# Retrieve and print the list of enforced vertices defines on Face_1 +enfList = algo2d.GetEnforcedVertices(Face_1) +print "List of enforced vertices for Face_1: " +print enfList + +# compute the mesh +blsurfMesh.Compute() + +# Remove an enforced vertex and print the list +algo2d.UnsetEnforcedVertex(Face_1, 50, 50, 50) +enfList = algo2d.GetEnforcedVertices(Face_1) +print "List of enforced vertices for Face_1: " +print enfList + +# compute the mesh +blsurfMesh.Compute() + +# Remove all enforced vertices defined on Face_1 +algo2d.UnsetEnforcedVertices(Face_1) + +# compute the mesh +blsurfMesh.Compute() + +# End of script +\endcode + +\subsection blsurf_construct_mesh_attractor Adding an attractor +\code +# Add an attractor on Face_2, which shape is Wire_1 + +# The size on Wire_1 is 1 and will grow until a maximum of 36.641 (physical size set above) +# The influence distance of the attractor is 20 +# The size is kept constant until a distance of 10 +algo2d.SetAttractorGeom(Face_2, Wire_1, 1, 36.641, 20, 10) + +# In order to let the attractor control the growing of the mesh let set +# the gradation to its maximum +algo2d.SetGradation( 2.5 ) + +# compute the mesh +blsurfMesh.Compute() + +# End of script +\endcode + +\subsection blsurf_construct_mesh_internal_vertices Using internal vertices +\code +# Creating a geometry containing internal vertices +Face_3 = geompy.MakeFaceHW(1, 1, 1) +Vertex_2 = geompy.MakeVertex(0.2, 0.2, 0) +Partition_1 = geompy.MakePartition([Face_3, Vertex_2], [], [], [], geompy.ShapeType["FACE"], 0, [], 0) +OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +Multi_Translation_1 = geompy.MakeMultiTranslation2D(Partition_1, OX, 1, 10, OY, 1, 10) +geompy.addToStudy( Face_3, 'Face_3' ) +geompy.addToStudy( Vertex_2, 'Vertex_2' ) +geompy.addToStudy( Partition_1, 'Partition_1' ) +geompy.addToStudy( OX, 'OX' ) +geompy.addToStudy( OY, 'OY' ) +geompy.addToStudy( Multi_Translation_1, 'Multi-Translation_1' ) + +# The mesh on the geometry with internal vertices +blsurfMesh_internal = smesh.Mesh(Multi_Translation_1, "blsurfMesh_internal") +algo2d = blsurfMesh_internal.Triangle(algo=smesh.BLSURF) +algo2d.SetPhySize( 0.1 ) + +# Allows BLSURF to take into account internal vertices +algo2d.SetInternalEnforcedVertexAllFaces( True ) + +# Add the created nodes into a group +algo2d.SetInternalEnforcedVertexAllFacesGroup( "my group" ) + +# compute the mesh +blsurfMesh_internal.Compute() + +# End of script +\endcode + +*/ diff --git a/doc/salome/gui/BLSURFPLUGIN/input/index.doc b/doc/salome/gui/BLSURFPLUGIN/input/index.doc new file mode 100644 index 0000000..3a35d84 --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/input/index.doc @@ -0,0 +1,20 @@ +/*! + +\mainpage Introduction to BLSURFPLUGIN + +\b BLSURFPLUGIN SALOME module represents a meshing plug-in that can be +used within the SALOME Mesh module for generation of 2D mesh. + +\note BLSURFPLUGIN plugin uses DISTENE BLSurf commercial meshing +software and requires a license at the run time (to work within the +Mesh module). + +\b BLSURFPLUGIN plugin is destined for: +- Meshing of the 2D geometric entities. + +To manage parameters of the BLSURFPLUGIN, use \subpage blsurf_hypo_page. + +Also, all BLSURFPLUGIN functionalities are accessible via the +\subpage blsurfplugin_python_interface_page "BLSURFPLUGIN Python interface". + +*/ diff --git a/doc/salome/gui/BLSURFPLUGIN/static/doxygen.css b/doc/salome/gui/BLSURFPLUGIN/static/doxygen.css new file mode 100755 index 0000000..7a2dcbd --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/static/doxygen.css @@ -0,0 +1,836 @@ +/* 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; +} + +.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 */ + +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; +} + +#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; +} + diff --git a/doc/salome/gui/BLSURFPLUGIN/static/footer.html b/doc/salome/gui/BLSURFPLUGIN/static/footer.html new file mode 100755 index 0000000..4c89a2b --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/static/footer.html @@ -0,0 +1,12 @@ +

    + + +
    +
    + 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/BLSURFPLUGIN/static/header.html.in b/doc/salome/gui/BLSURFPLUGIN/static/header.html.in new file mode 100755 index 0000000..4571b43 --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/static/header.html.in @@ -0,0 +1,20 @@ + + + + + +$title + +$treeview +$search +$mathjax + + + + +
    +
    Version: @VERSION@
    + +
    diff --git a/doc/salome/gui/BLSURFPLUGIN/static/header_py.html.in b/doc/salome/gui/BLSURFPLUGIN/static/header_py.html.in new file mode 100644 index 0000000..61414bb --- /dev/null +++ b/doc/salome/gui/BLSURFPLUGIN/static/header_py.html.in @@ -0,0 +1,21 @@ + + + + + +$title + +$treeview +$search +$mathjax + + + + +
    diff --git a/doc/salome/gui/Makefile.am b/doc/salome/gui/Makefile.am new file mode 100644 index 0000000..fab0fec --- /dev/null +++ b/doc/salome/gui/Makefile.am @@ -0,0 +1,31 @@ +# 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 +# + +# File : Makefile.in +# Author : Vasily Rusyaev (Open Cascade NN) +# Module : doc +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +SUBDIRS = BLSURFPLUGIN + +usr_docs: + (cd BLSURFPLUGIN && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +docs: usr_docs diff --git a/doc/salome/tui/Makefile.am b/doc/salome/tui/Makefile.am new file mode 100644 index 0000000..c0aef17 --- /dev/null +++ b/doc/salome/tui/Makefile.am @@ -0,0 +1,42 @@ +# 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 +# + +# 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 + +dev_docs: doxyfile + echo "Running doxygen in directory: "`pwd`; \ + $(DOXYGEN) $<; + +clean-local: + -rm -fr BLSURFPLUGIN doxygen.bak + +install-data-local: + if test -d BLSURFPLUGIN; then \ + $(INSTALL) -d $(DESTDIR)$(docdir)/tui ; \ + cp -rp BLSURFPLUGIN $(DESTDIR)$(docdir)/tui ; \ + fi; + +uninstall-local: + rm -rf $(DESTDIR)$(docdir)/tui/BLSURFPLUGIN diff --git a/doc/salome/tui/doxyfile.in b/doc/salome/tui/doxyfile.in new file mode 100755 index 0000000..e553b43 --- /dev/null +++ b/doc/salome/tui/doxyfile.in @@ -0,0 +1,260 @@ +# 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 +# + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "BLSURFPLUGIN Module Programming Guide v.@VERSION@" +PROJECT_NUMBER = +OUTPUT_DIRECTORY = BLSURFPLUGIN +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = NO +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = @top_srcdir@ @top_builddir@ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 5 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = YES +BUILTIN_STL_SUPPORT = @DOXYGEN_SUPPORT_STL@ +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 25 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +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@ +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = YES +IMAGE_PATH = @srcdir@/images +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 3 +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_FILE_EXTENSION = .html +HTML_HEADER = @srcdir@/static/myheader.html +HTML_FOOTER = @srcdir@/static/footer.html +HTML_STYLESHEET = @srcdir@/static/doxygen.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = YES +TOC_EXPAND = YES +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = NO + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = jpg +DOT_FONTNAME = Arial +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1200 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = NO +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/doc/salome/tui/images/Application-About.png b/doc/salome/tui/images/Application-About.png new file mode 100755 index 0000000000000000000000000000000000000000..7b58330d50856e28562e8f9ed80dae72d6e6dda3 GIT binary patch literal 19226 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

    5r3>=?gKv-6#gF2kVYm^Euk4pDx%bDo{L~m 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 KJ9x`c0029x$~vY1 literal 0 HcmV?d00001 diff --git a/doc/salome/tui/images/logocorp.gif b/doc/salome/tui/images/logocorp.gif new file mode 100755 index 0000000000000000000000000000000000000000..7697e0837777ed6aa775741b68962a9533f62caa GIT binary patch literal 1792 zcmV+b2mkm-Nk%w1VT%AS0M!5hoSdBI=H|`K&1h+9yr%&i92}?s9Q4@(`}_LWPNmY) z(&*@(Mny)&y^n7I4{B!vuhPw}5?2IXir|z73~g1|qP6eq%$#@+9iPydLQ8d@5mkyJ+Hc*mQgIAO1%kNT04UJv^Xbjgu+dWmns}MAyYSKDkey3~zS-CTdiC?|VXDsV z?d^iw_xI-Rw^eTF^5`PJ@#MM6alNa@g__&l+iiR_0!%suKW6s!_KJ#%u&}WA_xAt* z0RH~|A^8LV00000EC2ui0E+-G000L6z*cWaEEFMdcUl8%k6r< z;IMd1E}O}{fWnGByWjA*T%KNE=i^n!GwFL42zY{nZ*^>hTQ53UFBcbmep(_Th?SOE zhIfM}6$ufa2{khhq>dLJA}%tkt1fMquyC2LZ!MHr03W&$x*ru47a5Ko78?>EAQ;LR zlsynM5HYdSVzXyGA}K7$$tgND9|gU-Gg%fED_O=l6359lG$r!$(A4%@)?Wxcfm$Z) z+}cSnp@6}-4=_%6F(H9MJ7g>%P{2W9o;(`&GUn6L2mz)+Fwufcx-*5n z@S9e57v2cMNN|`;0+1OSJ2C?x832H11!4j05dFhO7aal;cOEccbmAW^GY8IM0|4vM zhksbPEnti2(ORrz9?he0i{HaDW6G*2O9saoP)wdqokZ?102s91F@Ql~9t>;`7(2i- zfFG>61YiJqy^r_r8JI>7e@7Mp4B*GdRX~4%9gFk;Ujg$Cpq~!~Fd%>q{T=ATa(2-2 z0yq)CaDxWaO{c+z(ue{79uHb{#sC7~{jdUS1AwT-4h0Ob#d@IS7ax2B=+HugJ}~e@ z4?DbzJjJh0`Z8sx@TKUyeIKw9A87XWzTiFV$eUnaR;06o6Prl|-ND&qjL4msWr z4JIiZ4=XT8=m-F=1ptGaX!3yE z9WH>MhsQqu;KHmES)|GT*?<|$ydU1;59BgPK3Vaqg06dts+nHOeQ0fXKj!BaGW5yrqS)CJ^53@nK7h&4>24SnH6jU+IN4Il=mK7d6eYO#a{$YB?sI3=~j1U z#t5qaagB`mA|f(i!x7H$j}mkM4ey9YSnv=IaO~qB7a0N?MxcO&q>CO2kw`@{@`w>A zMyi3R{9CN;T9OC0hId_1Ed%V>ZMK(dsTIHem}kjgq@F#;8UjC{3wKSIW|sy7Z+T iFpX*a^t7Gi*z~42&8bdz%F~|u^rt`#YI0B%1OPi{2poO@ literal 0 HcmV?d00001 diff --git a/doc/salome/tui/static/doxygen.css b/doc/salome/tui/static/doxygen.css new file mode 100755 index 0000000..4893b5e --- /dev/null +++ b/doc/salome/tui/static/doxygen.css @@ -0,0 +1,152 @@ +H1 { + text-align: center; +} + +CAPTION { + font-weight: bold +} + +/* Link in the top navbar */ +A.qindex {} + +A.qindexRef {} + +/* Link to any cross-referenced Doxygen element */ +A.el { + text-decoration: none; + font-weight: bold +} + +A.elRef { + font-weight: bold +} + +/* Link to any cross-referenced Doxygen element inside a code section + (ex: header) +*/ +A.code { + text-decoration: none; + font-weight: normal; + color: #4444ee +} + +A.codeRef { + font-weight: normal; + color: #4444ee +} + +A:hover { + text-decoration: none; + background-color: lightblue +} + +DL.el { + margin-left: -1cm +} + +/* A code fragment (ex: header) */ +DIV.fragment { + width: 100%; + border: none; + background-color: #CCCCCC +} + +/* 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 +} + +/* Method name (+ type) */ +TD.md { + background-color: lightblue; + font-weight: bold; +} + +/* 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 +} + +/* BODY { + background: url(sources/bg_salome.gif) +} */ + +div.tabs { + text-align: justify; + 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/tui/static/footer.html b/doc/salome/tui/static/footer.html new file mode 100755 index 0000000..29e07ad --- /dev/null +++ b/doc/salome/tui/static/footer.html @@ -0,0 +1,10 @@ + + + + + +
    +
    Copyright © 2007-2012 CEA DEN, EDF R&D
    +
    + + diff --git a/doc/salome/tui/static/myheader.html b/doc/salome/tui/static/myheader.html new file mode 100755 index 0000000..d2efb75 --- /dev/null +++ b/doc/salome/tui/static/myheader.html @@ -0,0 +1,13 @@ + + + + + + Main Page + + + + +  + + diff --git a/idl/BLSURFPlugin_Algorithm.idl b/idl/BLSURFPlugin_Algorithm.idl index 026602a..d26ce56 100644 --- a/idl/BLSURFPlugin_Algorithm.idl +++ b/idl/BLSURFPlugin_Algorithm.idl @@ -1,30 +1,33 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_Algorithm.idl // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) +// Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- // #ifndef _SMESH_BLSURFALGORITHM_IDL_ #define _SMESH_BLSURFALGORITHM_IDL_ #include "SMESH_Hypothesis.idl" +#include "GEOM_Gen.idl" #include "SALOME_Exception.idl" /*! @@ -34,6 +37,79 @@ module BLSURFPlugin { typedef sequence string_array; + // Enforced vertex name + typedef string TEnfName; + // Entry + typedef string TEntry; + typedef sequence TEntryList; + // Group name + typedef string TEnfGroupName; + + // Coordinates of enforced vertex + typedef sequence TEnfVertexCoords; + // List of coords + typedef sequence TEnfVertexCoordsList; + + // Enforced vertex + struct TEnfVertex { + TEnfName name; + TEntry geomEntry; + TEnfVertexCoords coords; + TEnfGroupName grpName; + TEntryList faceEntries; + }; + // List of enforced vertices + typedef sequence TEnfVertexList; + + // Map Face Entry / List of enforced vertices + struct TFaceEntryEnfVertexListMapElement { + TEntry faceEntry; + TEnfVertexList enfVertexList; + }; + typedef sequence TFaceEntryEnfVertexListMap; + + // Map Face Entry / List of coords + struct TFaceEntryCoordsListMapElement { + TEntry faceEntry; + TEnfVertexCoordsList coordsList; + }; + typedef sequence TFaceEntryCoordsListMap; + + // Map Face Entry / List of enf vertex entries + struct TFaceEntryEnfVertexEntryListMapElement { + TEntry faceEntry; + TEntryList enfVertexEntryList; + }; + typedef sequence TFaceEntryEnfVertexEntryListMap; + + // Map Coords / Enforced vertex + struct TCoordsEnfVertexElement { + TEnfVertexCoords coords; + TEnfVertex enfVertex; + }; + typedef sequence TCoordsEnfVertexMap; + + // Map Enf Vertex Entry / Enforced vertex + struct TEnfVertexEntryEnfVertexElement { + TEntry enfVertexEntry; + TEnfVertex enfVertex; + }; + typedef sequence TEnfVertexEntryEnfVertexMap; + + // List of Face Entry with internal enforced vertices activated + typedef sequence TFaceEntryInternalVerticesList; + + // Attractors + struct TAttractorParams { + string faceEntry; + string attEntry; + double startSize; + double endSize; + double infDist; + double constDist; + }; + typedef sequence TAttParamsMap; + /*! * BLSURFPlugin_BLSURF: interface of BLSURF algorithm */ @@ -50,6 +126,7 @@ module BLSURFPlugin * Sets topology usage way defining how mesh conformity is assured * value=0 - mesh conformity is assured by conformity of a shape * value=1,2 - mesh conformity is assured by pre-processing a CAD model + * value=3 - mesh conformity is assured by pre-processing a CAD model with Pre-CAD */ void SetTopology(in long way); long GetTopology(); @@ -58,6 +135,7 @@ module BLSURFPlugin * Sets a way to define size of mesh elements to generate * 0 - size is defined automatically * 1 - size is set by SetPhySize() method + * 2 - size is set by SetPhySize() method. A sizemap is defined. */ void SetPhysicalMesh(in long isCustom); long GetPhysicalMesh(); @@ -136,16 +214,45 @@ module BLSURFPlugin void SetVerbosity(in short theVal) raises (SALOME::SALOME_Exception); short GetVerbosity(); + /*! + * To merges edges. + */ + void SetPreCADMergeEdges(in boolean toMergeEdges); + boolean GetPreCADMergeEdges(); + + /*! + * To remove nano edges. + */ + void SetPreCADRemoveNanoEdges(in boolean toRemoveNanoEdges); + boolean GetPreCADRemoveNanoEdges(); + + /*! + * To compute topology from scratch + */ + void SetPreCADDiscardInput(in boolean toDiscardInput); + boolean GetPreCADDiscardInput(); + + /*! + * Sets the length below which an edge is considered as nano + * for the topology processing. + */ + void SetPreCADEpsNano(in double epsNano); + double GetPreCADEpsNano(); + /*! * Sets advanced option value */ void SetOptionValue(in string optionName, in string optionValue) raises (SALOME::SALOME_Exception); + void SetPreCADOptionValue(in string optionName, + in string optionValue) raises (SALOME::SALOME_Exception); string GetOptionValue(in string optionName) raises (SALOME::SALOME_Exception); + string GetPreCADOptionValue(in string optionName) raises (SALOME::SALOME_Exception); /*! * Unsets advanced option */ void UnsetOption(in string optionName); + void UnsetPreCADOption(in string optionName); /*! * Return array of strings each of which is option name concatenated @@ -154,14 +261,136 @@ module BLSURFPlugin * Note: the method is mostly for interaction with GUI. */ string_array GetOptionValues(); + string_array GetPreCADOptionValues(); /*! * Set option values each in the form "option_name[:option_value]". * Note: the method is mostly for interaction with GUI. */ void SetOptionValues(in string_array options); - }; + void SetPreCADOptionValues(in string_array options); + + /*! + * SizeMap + */ + void SetSizeMapEntries(in string_array sizeMaps); + void ClearSizeMaps(); + + void UnsetEntry(in string entry); + + /*! + * Set/unset a SizeMap on geom object + */ + void SetSizeMap(in GEOM::GEOM_Object GeomObj, in string sizeMap); + void UnsetSizeMap(in GEOM::GEOM_Object GeomObj); + + /*! + * Set a SizeMap on geom object given by entry + */ + void SetSizeMapEntry(in string entry, in string sizeMap); + string GetSizeMapEntry(in string entry); + string_array GetSizeMapEntries(); + /*! + * Set/unset an attractor on geom object + */ + void SetAttractor(in GEOM::GEOM_Object GeomObj, in string attractor); + void UnsetAttractor(in GEOM::GEOM_Object GeomObj); + + /*! + * Set an attractor on geom object given by entry + */ + void SetAttractorEntry(in string entry, in string attractor); + string GetAttractorEntry(in string entry); + string_array GetAttractorEntries(); + + /*! + * Set/unset an attractor given as geom object on another geom object + */ + void SetAttractorGeom(in GEOM::GEOM_Object GeomObj, in GEOM::GEOM_Object AttractorShape, in double StartSize, in double EndSize, in double ActionRadius, in double ConstantRadius); + void UnsetAttractorGeom(in GEOM::GEOM_Object GeomObj); + + /*! + * Set an attractor given by entry on a geom object given by entry + */ + void SetClassAttractorEntry(in string entry, in string att_entry, in double StartSize, in double EndSize, in double ActionRadius, in double ConstantRadius ); + BLSURFPlugin::TAttParamsMap GetAttractorParams(); + +/* + void SetCustomSizeMapEntry(in string entry, in string sizeMap); + string GetCustomSizeMapEntry(in string entry); + void SetCustomSizeMap(in GEOM::GEOM_Object GeomObj, in string sizeMap); + void UnsetCustomSizeMap(in GEOM::GEOM_Object GeomObj); + string_array GetCustomSizeMapEntries(); +*/ + /////////////////////// + // ENFORCED VERTEXES // + /////////////////////// + + TFaceEntryEnfVertexListMap GetAllEnforcedVerticesByFace(); + TEnfVertexList GetAllEnforcedVertices(); + + TFaceEntryCoordsListMap GetAllCoordsByFace(); + TCoordsEnfVertexMap GetAllEnforcedVerticesByCoords(); + + TFaceEntryEnfVertexEntryListMap GetAllEnfVertexEntriesByFace(); + TEnfVertexEntryEnfVertexMap GetAllEnforcedVerticesByEnfVertexEntry(); + + void ClearAllEnforcedVertices(); + + /*! + * Set/get/unset an enforced vertex on geom face + */ + boolean SetEnforcedVertex(in GEOM::GEOM_Object theFace, in double x, in double y, in double z) raises (SALOME::SALOME_Exception); + boolean SetEnforcedVertexNamed(in GEOM::GEOM_Object theFace, in double x, in double y, in double z, in TEnfName theVertexName) raises (SALOME::SALOME_Exception); + boolean SetEnforcedVertexGeom(in GEOM::GEOM_Object theFace, in GEOM::GEOM_Object theVertex) raises (SALOME::SALOME_Exception); + boolean SetEnforcedVertexWithGroup(in GEOM::GEOM_Object theFace, in double x, in double y, in double z, in TEnfGroupName groupName) raises (SALOME::SALOME_Exception); + boolean SetEnforcedVertexNamedWithGroup(in GEOM::GEOM_Object theFace, in double x, in double y, in double z, in TEnfName theVertexName, in TEnfGroupName groupName) raises (SALOME::SALOME_Exception); + boolean SetEnforcedVertexGeomWithGroup(in GEOM::GEOM_Object theFace, in GEOM::GEOM_Object theVertex, in TEnfGroupName groupName) raises (SALOME::SALOME_Exception); + + + TEnfVertexList GetEnforcedVertices(in GEOM::GEOM_Object theFace) raises (SALOME::SALOME_Exception); + + boolean UnsetEnforcedVertex(in GEOM::GEOM_Object theFace, in double x, in double y, in double z) raises (SALOME::SALOME_Exception); + boolean UnsetEnforcedVertexGeom(in GEOM::GEOM_Object theFace, in GEOM::GEOM_Object theVertex) raises (SALOME::SALOME_Exception); + boolean UnsetEnforcedVertices(in GEOM::GEOM_Object theFace) raises (SALOME::SALOME_Exception); + + /*! + * Set/get/unset an enforced vertex on geom face given by entry + */ + boolean SetEnforcedVertexEntry(in TEntry theFaceEntry, in double x, in double y, in double z, + in TEnfName theVertexName, in TEntry theVertexEntry, in TEnfGroupName groupName) raises (SALOME::SALOME_Exception); + + TEnfVertexList GetEnforcedVerticesEntry(in TEntry theFaceEntry) raises (SALOME::SALOME_Exception); + boolean UnsetEnforcedVertexEntry(in TEntry theFaceEntry, in double x, in double y, in double z, in TEntry theVertexEntry) raises (SALOME::SALOME_Exception); +// boolean UnsetEnforcedVertexEntryGeom(in TEntry theFaceEntry, in TEntry theVertexEntry) raises (SALOME::SALOME_Exception); + boolean UnsetEnforcedVerticesEntry(in TEntry theFaceEntry) raises (SALOME::SALOME_Exception); + + /*! + * To get/set internal vertices as enforced vertices + */ + void SetInternalEnforcedVertexAllFaces(in boolean toEnforceInternalVertices); + boolean GetInternalEnforcedVertexAllFaces(); + void SetInternalEnforcedVertexAllFacesGroup(in TEnfGroupName groupName); + TEnfGroupName GetInternalEnforcedVertexAllFacesGroup(); + +// Enable internal enforced vertices on specific face if requested by user +// void SetInternalEnforcedVertex(in GEOM::GEOM_Object theFace,in boolean toEnforceInternalVertices) raises (SALOME::SALOME_Exception); +// void SetInternalEnforcedVertexWithGroup(in GEOM::GEOM_Object theFace, in boolean toEnforceInternalVertices, in TEnfGroupName groupName) raises (SALOME::SALOME_Exception); +// void SetInternalEnforcedVertexEntry(in TEntry theFaceEntry, in boolean toEnforceInternalVertices, in TEnfGroupName groupName) raises (SALOME::SALOME_Exception); +// boolean GetInternalEnforcedVertex(in GEOM::GEOM_Object theFace) raises (SALOME::SALOME_Exception); +// boolean GetInternalEnforcedVertexEntry(in TEntry theFaceEntry) raises (SALOME::SALOME_Exception); +// TFaceEntryInternalVerticesList GetAllInternalEnforcedVerticesFaces(); + /////////////////////// + + /*! + * Sets the file for export resulting mesh in GMF format + */ +// void SetGMFFile(in string theFileName, in boolean isBinary); + void SetGMFFile(in string theFileName); + string GetGMFFile(); +// boolean GetGMFFileMode(); + }; }; #endif diff --git a/idl/Makefile.am b/idl/Makefile.am index d12329e..e9e3d92 100644 --- a/idl/Makefile.am +++ b/idl/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -29,6 +30,8 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am BASEIDL_FILES = BLSURFPlugin_Algorithm.idl +BASEIDL_FILES_PY=$(BASEIDL_FILES:%.idl=%_idl.py) + # This variable defines the files to be installed dist_salomeidl_DATA = $(BASEIDL_FILES) @@ -47,7 +50,6 @@ libSalomeIDLBLSURFPLUGIN_la_CPPFLAGS = \ $(SMESH_CXXFLAGS) \ @CORBA_CXXFLAGS@ \ @CORBA_INCLUDES@ \ - -I$(top_builddir)/salome_adm/unix \ -I$(top_builddir)/idl libSalomeIDLBLSURFPLUGIN_la_LDFLAGS = -no-undefined -version-info=0:0:0 @@ -72,8 +74,7 @@ IDLCXXFLAGS = \ -I$(top_builddir)/idl/salome \ -I$(KERNEL_ROOT_DIR)/idl/salome \ -I$(GEOM_ROOT_DIR)/idl/salome \ - -I$(SMESH_ROOT_DIR)/idl/salome \ - -I$(top_builddir)/salome_adm/unix + -I$(SMESH_ROOT_DIR)/idl/salome IDLPYFLAGS = \ @IDLPYFLAGS@ \ -I$(KERNEL_ROOT_DIR)/idl/salome \ @@ -93,9 +94,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 BLSURFPlugin ; 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 @@ -109,7 +116,7 @@ mostlyclean-local: @for dep in $^ dummy; do \ if [ $$dep != "dummy" ]; then \ echo Building dependencies for $$dep; \ - $(CPP) $(C_DEPEND_FLAG) -x c -I$(srcdir) -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(SMESH_ROOT_DIR)/idl/salome -I$(top_builddir)/salome_adm/unix $$dep 2>/dev/null | \ + $(CPP) $(C_DEPEND_FLAG) -x c -I$(srcdir) -I$(KERNEL_ROOT_DIR)/idl/salome -I$(GEOM_ROOT_DIR)/idl/salome -I$(SMESH_ROOT_DIR)/idl/salome $$dep 2>/dev/null | \ sed 's/\.o/\SK.cc/' >>$@; \ fi; \ done ; diff --git a/resources/BLSURFPlugin.xml b/resources/BLSURFPlugin.xml index ab99b32..ff40d4c 100644 --- a/resources/BLSURFPlugin.xml +++ b/resources/BLSURFPlugin.xml @@ -1,7 +1,7 @@ +
    + +
    diff --git a/resources/mesh_select_BLSURF.png b/resources/mesh_select_BLSURF.png new file mode 100644 index 0000000000000000000000000000000000000000..ecb252ab77e4d4b1c8b37de449155e4e77806fd8 GIT binary patch literal 1143 zcmV--1c>{IP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ*Y z+1|@J&vTys*x8s(A9y&=ABPX$@Ar2R#uxzVK5M}eVA}#m3ZfBZ@`~am4@2{B2*kg@6q&*BNEwM?&B@+_EcgOBFPbq)fl4T!YS@w}t zFVDWmkpfEygkanm1x6e}ti+})Zj&gJl$S{orION^4KN{5Ud{{4>Hywey>xcXnpdU^ zrOY^>9C?&PZQ`Xi@t94l#NwI9rp^VH0yU-aL{&Q7&jSk=qk`z-UEi)-47^pla@I!R z8mbt{@XMVYl*J`Wp1gAbuzXHs^@|Tb`aE;0?qkxevlz^2GOi+>_33PD%CS{TeJaziQldy^CkLzy55TqhE(>~8;uAP9aj#$*8>=mlDV z%OSJ~1Y?1RF1MZ}lj=tKMI0xJ5JCc(Vj=&Y5Te@{(;r&%LUkP>tN;Xn8J(1OKW)?| z(4U<8>jw;m@|$iW5{<`&5INwYG3M{E03-Jja23df6*kw5p4J*;%$DPazoU@LAZ3IZ z6*btlT@k9d8dkC^{H8*i=DM?NOn~qE?Y@`a@O%A60II4V$F}7nA%q2}(3%^n@@h9X zn;R|%hWpWYo>$k_dVI&xgWD)8pG4)ok07Od6>vt(tlM~A*KWEnelv^(3SqH!{b>Uf zl~V8gd%Avi!~U&Q&wrL%CeL_UN;waR@_&yvR44?NWdkTbOZ1|fK+8*w^>#Xem1^}qu>hx~?yEOm+002ov JPDHLkV1g&y5jFq- literal 0 HcmV?d00001 diff --git a/src/BLSURFPlugin/BLSURFPluginDC.py b/src/BLSURFPlugin/BLSURFPluginDC.py new file mode 100644 index 0000000..8dffd50 --- /dev/null +++ b/src/BLSURFPlugin/BLSURFPluginDC.py @@ -0,0 +1,308 @@ +# 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 +# + +from smesh import Mesh_Algorithm, AssureGeomPublished + +# Topology treatment way of BLSURF +FromCAD, PreProcess, PreProcessPlus, PreCAD = 0,1,2,3 + +# Element size flag of BLSURF +DefaultSize, DefaultGeom, BLSURF_Custom, SizeMap = 0,0,1,2 + + +# import BLSURFPlugin module if possible +noBLSURFPlugin = 0 +try: + import BLSURFPlugin +except ImportError: + noBLSURFPlugin = 1 + pass + + + +# a constant to call Mesh.Triangle(BLSURF,geom=0) +BLSURF = "BLSURF" + +## BLSURF 2D algorithm. It is created by calling Mesh.Triangle(BLSURF,geom=0) +# +class BLSURF_Algorithm(Mesh_Algorithm): + + meshMethod = "Triangle" + algoType = BLSURF + + _angleMeshS = 8 + _gradation = 1.1 + + ## Private constructor. + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + if noBLSURFPlugin: + print "Warning: BLSURFPlugin module unavailable" + self.Create(mesh, geom, BLSURF, "libBLSURFEngine.so") + self.params=None + #self.SetPhysicalMesh() - PAL19680 + + ## Sets a way to define size of mesh elements to generate. + # @param thePhysicalMesh is: DefaultSize, BLSURF_Custom or SizeMap. + def SetPhysicalMesh(self, thePhysicalMesh=DefaultSize): + self.Parameters().SetPhysicalMesh(thePhysicalMesh) + + ## Sets size of mesh elements to generate. + def SetPhySize(self, theVal): + self.Parameters().SetPhySize(theVal) + + ## Sets lower boundary of mesh element size (PhySize). + def SetPhyMin(self, theVal=-1): + self.Parameters().SetPhyMin(theVal) + + ## Sets upper boundary of mesh element size (PhySize). + def SetPhyMax(self, theVal=-1): + self.Parameters().SetPhyMax(theVal) + + ## Sets a way to define maximum angular deflection of mesh from CAD model. + # @param theGeometricMesh is: 0 (None) or 1 (Custom) + def SetGeometricMesh(self, theGeometricMesh=0): + if self.Parameters().GetPhysicalMesh() == 0: theGeometricMesh = 1 + self.Parameters().SetGeometricMesh(theGeometricMesh) + + ## Sets angular deflection (in degrees) of a mesh face from CAD surface. + def SetAngleMeshS(self, theVal=_angleMeshS): + if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS + self.Parameters().SetAngleMeshS(theVal) + + ## Sets angular deflection (in degrees) of a mesh edge from CAD curve. + def SetAngleMeshC(self, theVal=_angleMeshS): + if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS + self.Parameters().SetAngleMeshC(theVal) + + ## Sets lower boundary of mesh element size computed to respect angular deflection. + def SetGeoMin(self, theVal=-1): + self.Parameters().SetGeoMin(theVal) + + ## Sets upper boundary of mesh element size computed to respect angular deflection. + def SetGeoMax(self, theVal=-1): + self.Parameters().SetGeoMax(theVal) + + ## Sets maximal allowed ratio between the lengths of two adjacent edges. + def SetGradation(self, theVal=_gradation): + if self.Parameters().GetGeometricMesh() == 0: theVal = self._gradation + self.Parameters().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
    • + #
    • PreCAD - by pre-processing with PreCAD a CAD model
    + def SetTopology(self, way): + self.Parameters().SetTopology(way) + + ## To respect geometrical edges or not. + def SetDecimesh(self, toIgnoreEdges=False): + self.Parameters().SetDecimesh(toIgnoreEdges) + + ## Sets verbosity level in the range 0 to 100. + def SetVerbosity(self, level): + self.Parameters().SetVerbosity(level) + + ## To optimize merges edges. + def SetPreCADMergeEdges(self, toMergeEdges=False): + self.Parameters().SetPreCADMergeEdges(toMergeEdges) + + ## To remove nano edges. + def SetPreCADRemoveNanoEdges(self, toRemoveNanoEdges=False): + self.Parameters().SetPreCADRemoveNanoEdges(toRemoveNanoEdges) + + ## To compute topology from scratch + def SetPreCADDiscardInput(self, toDiscardInput=False): + self.Parameters().SetPreCADDiscardInput(toDiscardInput) + + ## Sets the length below which an edge is considered as nano + # for the topology processing. + def SetPreCADEpsNano(self, epsNano): + self.Parameters().SetPreCADEpsNano(epsNano) + + ## Sets advanced option value. + def SetOptionValue(self, optionName, level): + self.Parameters().SetOptionValue(optionName,level) + + ## Sets advanced PreCAD option value. + # Keyword arguments: + # optionName: name of the option + # optionValue: value of the option + def SetPreCADOptionValue(self, optionName, optionValue): + self.Parameters().SetPreCADOptionValue(optionName,optionValue) + + ## Sets GMF file for export at computation + def SetGMFFile(self, fileName): + self.Parameters().SetGMFFile(fileName) + + ## Enforced vertices (BLSURF) + + ## To get all the enforced vertices + def GetAllEnforcedVertices(self): + return self.Parameters().GetAllEnforcedVertices() + + ## To get all the enforced vertices sorted by face (or group, compound) + def GetAllEnforcedVerticesByFace(self): + return self.Parameters().GetAllEnforcedVerticesByFace() + + ## To get all the enforced vertices sorted by coords of input vertices + def GetAllEnforcedVerticesByCoords(self): + return self.Parameters().GetAllEnforcedVerticesByCoords() + + ## To get all the coords of input vertices sorted by face (or group, compound) + def GetAllCoordsByFace(self): + return self.Parameters().GetAllCoordsByFace() + + ## To get all the enforced vertices on a face (or group, compound) + # @param theFace : GEOM face (or group, compound) on which to define an enforced vertex + def GetEnforcedVertices(self, theFace): + AssureGeomPublished( self.mesh, theFace ) + return self.Parameters().GetEnforcedVertices(theFace) + + ## To clear all the enforced vertices + def ClearAllEnforcedVertices(self): + return self.Parameters().ClearAllEnforcedVertices() + + ## To set an enforced vertex on a face (or group, compound) given the coordinates of a point. If the point is not on the face, it will projected on it. If there is no projection, no enforced vertex is created. + # @param theFace : GEOM face (or group, compound) on which to define an enforced vertex + # @param x : x coordinate + # @param y : y coordinate + # @param z : z coordinate + # @param vertexName : name of the enforced vertex + # @param groupName : name of the group + def SetEnforcedVertex(self, theFace, x, y, z, vertexName = "", groupName = ""): + AssureGeomPublished( self.mesh, theFace ) + if vertexName == "": + if groupName == "": + return self.Parameters().SetEnforcedVertex(theFace, x, y, z) + else: + return self.Parameters().SetEnforcedVertexWithGroup(theFace, x, y, z, groupName) + else: + if groupName == "": + return self.Parameters().SetEnforcedVertexNamed(theFace, x, y, z, vertexName) + else: + return self.Parameters().SetEnforcedVertexNamedWithGroup(theFace, x, y, z, vertexName, groupName) + + ## To set an enforced vertex on a face (or group, compound) given a GEOM vertex, group or compound. + # @param theFace : GEOM face (or group, compound) on which to define an enforced vertex + # @param theVertex : GEOM vertex (or group, compound) to be projected on theFace. + # @param groupName : name of the group + def SetEnforcedVertexGeom(self, theFace, theVertex, groupName = ""): + AssureGeomPublished( self.mesh, theFace ) + AssureGeomPublished( self.mesh, theVertex ) + if groupName == "": + return self.Parameters().SetEnforcedVertexGeom(theFace, theVertex) + else: + return self.Parameters().SetEnforcedVertexGeomWithGroup(theFace, theVertex,groupName) + + ## To remove an enforced vertex on a given GEOM face (or group, compound) given the coordinates. + # @param theFace : GEOM face (or group, compound) on which to remove the enforced vertex + # @param x : x coordinate + # @param y : y coordinate + # @param z : z coordinate + def UnsetEnforcedVertex(self, theFace, x, y, z): + AssureGeomPublished( self.mesh, theFace ) + return self.Parameters().UnsetEnforcedVertex(theFace, x, y, z) + + ## To remove an enforced vertex on a given GEOM face (or group, compound) given a GEOM vertex, group or compound. + # @param theFace : GEOM face (or group, compound) on which to remove the enforced vertex + # @param theVertex : GEOM vertex (or group, compound) to remove. + def UnsetEnforcedVertexGeom(self, theFace, theVertex): + AssureGeomPublished( self.mesh, theFace ) + AssureGeomPublished( self.mesh, theVertex ) + return self.Parameters().UnsetEnforcedVertexGeom(theFace, theVertex) + + ## To remove all enforced vertices on a given face. + # @param theFace : face (or group/compound of faces) on which to remove all enforced vertices + def UnsetEnforcedVertices(self, theFace): + AssureGeomPublished( self.mesh, theFace ) + return self.Parameters().UnsetEnforcedVertices(theFace) + + ## To tell BLSURF to add a node on internal vertices + # @param toEnforceInternalVertices : boolean; if True the internal vertices are added as enforced vertices + def SetInternalEnforcedVertexAllFaces(self, toEnforceInternalVertices): + return self.Parameters().SetInternalEnforcedVertexAllFaces(toEnforceInternalVertices) + + ## To know if BLSURF will add a node on internal vertices + def GetInternalEnforcedVertexAllFaces(self): + return self.Parameters().GetInternalEnforcedVertexAllFaces() + + ## To define a group for the nodes of internal vertices + # @param groupName : string; name of the group + def SetInternalEnforcedVertexAllFacesGroup(self, groupName): + return self.Parameters().SetInternalEnforcedVertexAllFacesGroup(groupName) + + ## To get the group name of the nodes of internal vertices + def GetInternalEnforcedVertexAllFacesGroup(self): + return self.Parameters().GetInternalEnforcedVertexAllFacesGroup() + + ## Attractors + + ## Sets an attractor on the chosen face. The mesh size will decrease exponentially with the distance from theAttractor, following the rule h(d) = theEndSize - (theEndSize - theStartSize) * exp [ - ( d / theInfluenceDistance ) ^ 2 ] + # @param theFace : face on which the attractor will be defined + # @param theAttractor : geometrical object from which the mesh size "h" decreases exponentially + # @param theStartSize : mesh size on theAttractor + # @param theEndSize : maximum size that will be reached on theFace + # @param theInfluenceDistance : influence of the attractor ( the size grow slower on theFace if it's high) + # @param theConstantSizeDistance : distance until which the mesh size will be kept constant on theFace + def SetAttractorGeom(self, theFace, theAttractor, theStartSize, theEndSize, theInfluenceDistance, theConstantSizeDistance): + AssureGeomPublished( self.mesh, theFace ) + AssureGeomPublished( self.mesh, theAttractor ) + self.Parameters().SetAttractorGeom(theFace, theAttractor, theStartSize, theEndSize, theInfluenceDistance, theConstantSizeDistance) + + ## Unsets an attractor on the chosen face. + # @param theFace : face on which the attractor has to be removed + def UnsetAttractorGeom(self, theFace): + AssureGeomPublished( self.mesh, theFace ) + self.Parameters().SetAttractorGeom(theFace) + + ## Size maps (BLSURF) + + ## To set a size map on a face, edge or vertex (or group, compound) given Python function. + # If theObject is a face, the function can be: def f(u,v): return u+v + # If theObject is an edge, the function can be: def f(t): return t/2 + # If theObject is a vertex, the function can be: def f(): return 10 + # @param theObject : GEOM face, edge or vertex (or group, compound) on which to define a size map + # @param theSizeMap : Size map defined as a string + def SetSizeMap(self, theObject, theSizeMap): + AssureGeomPublished( self.mesh, theObject ) + self.Parameters().SetSizeMap(theObject, theSizeMap) + + ## To remove a size map defined on a face, edge or vertex (or group, compound) + # @param theObject : GEOM face, edge or vertex (or group, compound) on which to define a size map + def UnsetSizeMap(self, theObject): + AssureGeomPublished( self.mesh, theObject ) + self.Parameters().UnsetSizeMap(theObject) + + ## To remove all the size maps + def ClearSizeMaps(self): + self.Parameters().ClearSizeMaps() + + ## Sets QuadAllowed flag. + def SetQuadAllowed(self, toAllow=True): + self.Parameters().SetQuadAllowed(toAllow) + + ## Defines hypothesis having several parameters + # + def Parameters(self): + if not self.params: + self.params = self.Hypothesis("BLSURF_Parameters", [], + "libBLSURFEngine.so", UseExisting=0) + return self.params diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx new file mode 100644 index 0000000..57ce592 --- /dev/null +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx @@ -0,0 +1,332 @@ +// 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 +// + +// --- +// File : BLSURFPlugin_Attractor.cxx +// Authors : Renaud Nédélec (OCC) +// --- +// +// The idea of the algorithm used to calculate the distance on a +// non-euclidian parametric surface has been found in the ref. below: +// +// Ref:"Accurate Anisotropic Fast Marching for Diffusion-Based Geodesic Tractography" +// S. Jbabdi, P. Bellec, R. Toro, Daunizeau, M. Pélégrini-Issac, and H. Benali1 +// + +#include "BLSURFPlugin_Attractor.hxx" +#include +#include +#include + +// cascade include +#include "ShapeAnalysis.hxx" +#include "ShapeConstruct_ProjectCurveOnSurface.hxx" +#include + +BLSURFPlugin_Attractor::BLSURFPlugin_Attractor () + : _face(), + _attractorShape(), + _attEntry(), + _gridU(0), + _gridV(0), + _vectU(), + _vectV(), + _DMap(), + _known(), + _trial(), + _u1 (0.), + _u2 (0.), + _v1 (0.), + _v2 (0.), + _startSize(-1), + _endSize(-1), + _actionRadius(-1), + _constantRadius(-1), + _type(-1), + _isMapBuilt(false), + _isEmpty(true){ MESSAGE("construction of a void attractor"); } + +BLSURFPlugin_Attractor::BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, const std::string& attEntry) + : _face(), + _attractorShape(), + _attEntry(attEntry), + _gridU(), + _gridV(), + _vectU(), + _vectV(), + _DMap(), + _known(), + _trial(), + _u1 (0.), + _u2 (0.), + _v1 (0.), + _v2 (0.), + _startSize(-1), + _endSize(-1), + _actionRadius(-1), + _constantRadius(-1), + _type(0), + _isMapBuilt(false), + _isEmpty(false) +{ + _face = Face; + _attractorShape = Attractor; + + init(); +} + +bool BLSURFPlugin_Attractor::init(){ + Standard_Real u0,v0; + int i,j,i0,j0 ; + _known.clear(); + _trial.clear(); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(_face); + + // Calculation of the bounds of the face + ShapeAnalysis::GetFaceUVBounds(_face,_u1,_u2,_v1,_v2); + + _gridU = 300; + _gridV = 300; + + for (i=0; i<=_gridU; i++){ + _vectU.push_back(_u1+i*(_u2-_u1)/_gridU) ; + } + for (j=0; j<=_gridV; j++){ + _vectV.push_back(_v1+j*(_v2-_v1)/_gridV) ; + } + + // Initialization of _DMap and _known + std::vector temp(_gridV+1,std::numeric_limits::infinity()); // Set distance of all "far" points to Infinity + for (i=0; i<=_gridU; i++){ + _DMap.push_back(temp); + } + std::vector temp2(_gridV+1,false); + for (i=0; i<=_gridU; i++){ + _known.push_back(temp2); + } + + + // Determination of the starting points + TopExp_Explorer anEdgeExp(_attractorShape, TopAbs_EDGE, TopAbs_FACE); + TopExp_Explorer aVertExp(_attractorShape, TopAbs_VERTEX, TopAbs_EDGE); + + for(; anEdgeExp.More(); anEdgeExp.Next()){ + const TopoDS_Edge& anEdge = TopoDS::Edge(anEdgeExp.Current()); + edgeInit(aSurf, anEdge); + } + + for(; aVertExp.More(); aVertExp.Next()){ + const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVertExp.Current()); + Trial_Pnt TPnt(3,0); + gp_Pnt P = BRep_Tool::Pnt(aVertex); + GeomAPI_ProjectPointOnSurf projector( P, aSurf ); + projector.LowerDistanceParameters(u0,v0); + i0 = floor ( (u0 - _u1) * _gridU / (_u2 - _u1) + 0.5 ); + j0 = floor ( (v0 - _v1) * _gridV / (_v2 - _v1) + 0.5 ); + TPnt[0]=0.; // Set the distance of the starting point to 0. + TPnt[1]=i0; + TPnt[2]=j0; + _DMap[i0][j0] = 0.; + _trial.insert(TPnt); // Move starting point to _trial + } + + return true; +} + +void BLSURFPlugin_Attractor::edgeInit(Handle(Geom_Surface) theSurf, const TopoDS_Edge& anEdge){ + gp_Pnt2d P2; + double first; + double last; + int i,j,i0,j0; + Trial_Pnt TPnt(3,0); + Handle(Geom2d_Curve) aCurve2d; + Handle(Geom_Curve) aCurve3d = BRep_Tool::Curve (anEdge, first, last); + ShapeConstruct_ProjectCurveOnSurface curveProjector; + curveProjector.Init(theSurf, Precision::Confusion()); + curveProjector.PerformAdvanced (aCurve3d, first, last, aCurve2d); + + int N = 1200; + for (i=0; i<=N; i++){ + P2 = aCurve2d->Value(first + i * (last-first) / N); + i0 = floor( (P2.X() - _u1) * _gridU / (_u2 - _u1) + 0.5 ); + j0 = floor( (P2.Y() - _v1) * _gridV / (_v2 - _v1) + 0.5 ); + TPnt[0] = 0.; + TPnt[1] = i0; + TPnt[2] = j0; + _DMap[i0][j0] = 0.; + _trial.insert(TPnt); + } +} + + +void BLSURFPlugin_Attractor::SetParameters(double Start_Size, double End_Size, double Action_Radius, double Constant_Radius){ + _startSize = Start_Size; + _endSize = End_Size; + _actionRadius = Action_Radius; + _constantRadius = Constant_Radius; +} + +double BLSURFPlugin_Attractor::_distance(double u, double v){ + + // BLSURF seems to perform a linear interpolation so it's sufficient to give it a non-continuous distance map + int i = floor ( (u - _u1) * _gridU / (_u2 - _u1) + 0.5 ); + int j = floor ( (v - _v1) * _gridV / (_v2 - _v1) + 0.5 ); + + return _DMap[i][j]; +} + + +double BLSURFPlugin_Attractor::GetSize(double u, double v){ + double myDist = 0.5 * (_distance(u,v) - _constantRadius + fabs(_distance(u,v) - _constantRadius)); + switch(_type) + { + case TYPE_EXP: + if (fabs(_actionRadius) <= std::numeric_limits::epsilon()){ + if (myDist <= std::numeric_limits::epsilon()){ + return _startSize; + } + else { + return _endSize; + } + } + else{ + return _endSize - (_endSize - _startSize) * exp(- myDist * myDist / (_actionRadius * _actionRadius) ); + } + break; + case TYPE_LIN: + return _startSize + ( 0.5 * (_distance(u,v) - _constantRadius + abs(_distance(u,v) - _constantRadius)) ) ; + break; + } +} + + +void BLSURFPlugin_Attractor::BuildMap(){ + + MESSAGE("building the map"); + int i, j, k, n; + int count = 0; + int ip, jp, kp, np; + int i0, j0; + gp_Pnt P; + gp_Vec D1U,D1V; + double Guu, Gvv, Guv; // Components of the local metric tensor + double du, dv; + double D_Ref = 0.; + double Dist = 0.; + bool Dist_changed; + IJ_Pnt Current_Pnt(2,0); + Trial_Pnt TPnt(3,0); + TTrialSet::iterator min; + TTrialSet::iterator found; + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(_face); + + // While there are points in "Trial" (representing a kind of advancing front), loop on them ----------------------------------------------------------- + while (_trial.size() > 0 ){ + min = _trial.begin(); // Get trial point with min distance from start + i0 = (*min)[1]; + j0 = (*min)[2]; + _known[i0][j0] = true; // Move it to "Known" + _trial.erase(min); // Remove it from "Trial" + + // Loop on neighbours of the trial min -------------------------------------------------------------------------------------------------------------- + for (i=i0 - 1 ; i <= i0 + 1 ; i++){ + if (!aSurf->IsUPeriodic()){ // Periodic conditions in U + if (i > _gridU ){ + break; } + else if (i < 0){ + i++; } + } + ip = (i + _gridU + 1) % (_gridU+1); // We get a periodic index : + for (j=j0 - 1 ; j <= j0 + 1 ; j++){ // ip=modulo(i,N+2) so that i=-1->ip=N; i=0 -> ip=0 ; ... ; i=N+1 -> ip=0; + if (!aSurf->IsVPeriodic()){ // Periodic conditions in V . + if (j > _gridV ){ + break; } + else if (j < 0){ + j++; + } + } + jp = (j + _gridV + 1) % (_gridV+1); + + if (!_known[ip][jp]){ // If the distance is not known yet + aSurf->D1(_vectU[ip],_vectV[jp],P,D1U,D1V); // Calculate the metric tensor at (i,j) + // G(i,j) = | ||dS/du||**2 * | + // | ||dS/dv||**2 | + Guu = D1U.X()*D1U.X() + D1U.Y()*D1U.Y() + D1U.Z()*D1U.Z(); // Guu = ||dS/du||**2 + Gvv = D1V.X()*D1V.X() + D1V.Y()*D1V.Y() + D1V.Z()*D1V.Z(); // Gvv = ||dS/dv||**2 + Guv = D1U.X()*D1V.X() + D1U.Y()*D1V.Y() + D1U.Z()*D1V.Z(); // Guv = Gvu = < dS/du,dS/dv > + D_Ref = _DMap[ip][jp]; // Set a ref. distance of the point to its value in _DMap + TPnt[0] = D_Ref; // (may be infinite or uncertain) + TPnt[1] = ip; + TPnt[2] = jp; + Dist_changed = false; + + // Loop on neighbours to calculate the min distance from them --------------------------------------------------------------------------------- + for (k=i - 1 ; k <= i + 1 ; k++){ + if (!aSurf->IsUPeriodic()){ // Periodic conditions in U + if(k > _gridU ){ + break; + } + else if (k < 0){ + k++; } + } + kp = (k + _gridU + 1) % (_gridU+1); // periodic index + for (n=j - 1 ; n <= j + 1 ; n++){ + if (!aSurf->IsVPeriodic()){ // Periodic conditions in V + if(n > _gridV){ + break; + } + else if (n < 0){ + n++; } + } + np = (n + _gridV + 1) % (_gridV+1); + if (_known[kp][np]){ // If the distance of the neighbour is known + // Calculate the distance from (k,n) + du = (k-i) * (_u2 - _u1) / _gridU; + dv = (n-j) * (_v2 - _v1) / _gridV; + Dist = _DMap[kp][np] + sqrt( Guu * du*du + 2*Guv * du*dv + Gvv * dv*dv ); // ds**2 = du'Gdu + 2*du'Gdv + dv'Gdv (G is always symetrical) + if (Dist < D_Ref) { // If smaller than ref. distance -> update ref. distance + D_Ref = Dist; + Dist_changed = true; + } + } + } + } // End of the loop on neighbours -------------------------------------------------------------------------------------------------------------- + + if (Dist_changed) { // If distance has been updated, update _trial + found=_trial.find(TPnt); + if (found != _trial.end()){ + _trial.erase(found); // Erase the point if it was already in _trial + } + TPnt[0] = D_Ref; + TPnt[1] = ip; + TPnt[2] = jp; + _DMap[ip][jp] = D_Ref; // Set it distance to the minimum distance found during the loop above + _trial.insert(TPnt); // Insert it (or reinsert it) in _trial + } + } // end if (!_known[ip][jp]) + } // for + } // for + } // while (_trial) + _known.clear(); + _trial.clear(); + _isMapBuilt = true; +} // end of BuildMap() + + + diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx new file mode 100644 index 0000000..2c8cb8b --- /dev/null +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx @@ -0,0 +1,145 @@ +// 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 +// + +// --- +// File : BLSURFPlugin_Attractor.hxx +// Authors : Renaud Nédélec (OCC) +// --- +// +// The idea of the algorithm used to calculate the distance on a +// non-euclidian parametric surface has been found in the ref. below: +// +// Ref:"Accurate Anisotropic Fast Marching for Diffusion-Based Geodesic Tractography" +// S. Jbabdi, P. Bellec, R. Toro, Daunizeau, M. Pélégrini-Issac, and H. Benali1 +// + +#ifndef _BLSURFPlugin_Attractor_HXX_ +#define _BLSURFPlugin_Attractor_HXX_ + +#include +#include +#include +#include +#include +#include +#include + +// OPENCASCADE includes +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef WNT +#include +#endif + +#include +#include +#include +#include +#include +#include + +#define TYPE_EXP 0 +#define TYPE_LIN 1 + +class BLSURFPlugin_Attractor { + + public: + + BLSURFPlugin_Attractor (); + BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, const std::string& attEntry); + + bool init(); // Calculates the discrete points correponding to attractor + // and intialises the map of distances + void edgeInit(Handle(Geom_Surface) aSurf, const TopoDS_Edge& anEdge); + + double GetSize (double u, double v); + TopoDS_Face GetFace() const { return _face; } + TopoDS_Shape GetAttractorShape() const { return _attractorShape; } + std::string GetAttractorEntry() const { return _attEntry; } + std::vector GetParameters() const + { + double tab_params[] = {_startSize, _endSize, _actionRadius, _constantRadius}; + std::vector params (tab_params, tab_params + sizeof(tab_params) / sizeof(double) ); + return params; + } + + void SetParameters(double Start_Size, double End_Size, double Action_Radius, double Constant_Radius); + void SetType(int type){ _type = type; } + + void BuildMap(); // Builds the map of distances between source point and any point P(u,v) + bool IsMapBuilt() const { return _isMapBuilt; } // Controls if the map has been built + bool Empty() const { return _isEmpty; } + + typedef std::vector TDiscreteParam; + typedef std::vector< std::vector > TDistMap; + typedef std::vector< std::vector > TPointSet; + typedef std::set< std::vector > TTrialSet; + typedef std::vector Trial_Pnt; + typedef std::vector IJ_Pnt; + + private: + + TopoDS_Face _face; + TopoDS_Shape _attractorShape; + std::string _attEntry; + TDiscreteParam _vectU; + TDiscreteParam _vectV; + TDistMap _DMap; + TPointSet _known; + TTrialSet _trial; + int _type; // Type of function used to calculate the size from the distance (unused for now) + int _gridU; // Number of grid points in U direction + int _gridV; // Number of grid points in V direction + double _u1, _u2, _v1, _v2; // Bounds of the parametric space of the face + double _startSize, _endSize; // User parameters + double _actionRadius, _constantRadius; // + + bool _isMapBuilt; + bool _isEmpty; + + double _distance(double u, double v); // Retrieve the value of the distance map at point (u,v) of the parametric space of _face +}; + +#endif diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx index 39e7d49..4743bba 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx @@ -1,53 +1,66 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// 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 : BLSURFPlugin_BLSURF.cxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) // & Aurelien ALLEAUME (DISTENE) +// Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- -// + #include "BLSURFPlugin_BLSURF.hxx" #include "BLSURFPlugin_Hypothesis.hxx" +#include "BLSURFPlugin_Attractor.hxx" + +extern "C"{ +#include +#include +#include +} + +#include + + +#include +#include +#include #include +#include #include -#include - -#include -#include -#include +#include +#include +#include #include +#include #include #include +#include +#include +// OPENCASCADE includes #include #include #include #include #include -#include - -extern "C"{ -#include -} #include #include @@ -55,22 +68,170 @@ extern "C"{ #include #include #include +#include #include #include #include #include -#include + #include +#include #include +#include +#include +#include #include +#include +#include +#include + #ifndef WNT #include #endif +#include +#include +#include +#include +#include +// #include +#include + +/* ================================== + * =========== PYTHON ============== + * ==================================*/ + +typedef struct { + PyObject_HEAD + int softspace; + std::string *out; + } PyStdOut; + +static void +PyStdOut_dealloc(PyStdOut *self) +{ + PyObject_Del(self); +} + +static PyObject * +PyStdOut_write(PyStdOut *self, PyObject *args) +{ + char *c; + int l; + if (!PyArg_ParseTuple(args, "t#:write",&c, &l)) + return NULL; + + //std::cerr << c ; + *(self->out)=*(self->out)+c; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef PyStdOut_methods[] = { + {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, + PyDoc_STR("write(string) -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef PyStdOut_memberlist[] = { + {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0, + (char*)"flag indicating that a space needs to be printed; used by print"}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject PyStdOut_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "PyOut", /*tp_name*/ + sizeof(PyStdOut), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PyStdOut_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + /* softspace is writable: we must supply tp_setattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PyStdOut_methods, /*tp_methods*/ + PyStdOut_memberlist, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +PyObject * newPyStdOut( std::string& out ) +{ + PyStdOut *self; + self = PyObject_New(PyStdOut, &PyStdOut_Type); + if (self == NULL) + return NULL; + self->softspace = 0; + self->out=&out; + return (PyObject*)self; +} + + +////////////////////////END PYTHON/////////////////////////// + +//////////////////MY MAPS//////////////////////////////////////// +TopTools_IndexedMapOfShape FacesWithSizeMap; +std::map FaceId2SizeMap; +TopTools_IndexedMapOfShape EdgesWithSizeMap; +std::map EdgeId2SizeMap; +TopTools_IndexedMapOfShape VerticesWithSizeMap; +std::map VertexId2SizeMap; + +std::map FaceId2PythonSmp; +std::map EdgeId2PythonSmp; +std::map VertexId2PythonSmp; + +std::map > FaceId2AttractorCoords; +std::map FaceId2ClassAttractor; +std::map FaceIndex2ClassAttractor; + +TopTools_IndexedMapOfShape FacesWithEnforcedVertices; +std::map< int, BLSURFPlugin_Hypothesis::TEnfVertexCoordsList > FaceId2EnforcedVertexCoords; +std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexCoords > EnfVertexCoords2ProjVertex; +std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexList > EnfVertexCoords2EnfVertexList; + +bool HasSizeMapOnFace=false; +bool HasSizeMapOnEdge=false; +bool HasSizeMapOnVertex=false; +//bool HasAttractorOnFace=false; + //============================================================================= /*! - * + * */ //============================================================================= @@ -82,15 +243,62 @@ BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId, _name = "BLSURF"; _shapeType = (1 << TopAbs_FACE); // 1 bit /shape type - _compatibleHypothesis.push_back("BLSURF_Parameters"); - _requireDescretBoundary = false; + _compatibleHypothesis.push_back(BLSURFPlugin_Hypothesis::GetHypType()); + _requireDiscreteBoundary = false; _onlyUnaryInput = false; _hypothesis = NULL; + _supportSubmeshes = true; + + smeshGen_i = SMESH_Gen_i::GetSMESHGen(); + CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject); + + MESSAGE("studyid = " << _studyId); + + myStudy = NULL; + myStudy = aStudyMgr->GetStudyByID(_studyId); + if (myStudy) + MESSAGE("myStudy->StudyId() = " << myStudy->StudyId()); + + /* Initialize the Python interpreter */ + assert(Py_IsInitialized()); + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + main_mod = NULL; + main_mod = PyImport_AddModule("__main__"); + + main_dict = NULL; + main_dict = PyModule_GetDict(main_mod); + + PyRun_SimpleString("from math import *"); + PyGILState_Release(gstate); + + FacesWithSizeMap.Clear(); + FaceId2SizeMap.clear(); + EdgesWithSizeMap.Clear(); + EdgeId2SizeMap.clear(); + VerticesWithSizeMap.Clear(); + VertexId2SizeMap.clear(); + FaceId2PythonSmp.clear(); + EdgeId2PythonSmp.clear(); + VertexId2PythonSmp.clear(); + FaceId2AttractorCoords.clear(); + FaceId2ClassAttractor.clear(); + FaceIndex2ClassAttractor.clear(); + FacesWithEnforcedVertices.Clear(); + FaceId2EnforcedVertexCoords.clear(); + EnfVertexCoords2ProjVertex.clear(); + EnfVertexCoords2EnfVertexList.clear(); + +#ifdef WITH_SMESH_CANCEL_COMPUTE + _compute_canceled = false; +#endif } //============================================================================= /*! - * + * */ //============================================================================= @@ -99,9 +307,10 @@ BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF() MESSAGE("BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF"); } + //============================================================================= /*! - * + * */ //============================================================================= @@ -165,7 +374,320 @@ inline std::string to_string(int i) return o.str(); } -void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsurf_session_t *bls) +double _smp_phy_size; +// #if BLSURF_VERSION_LONG >= "3.1.1" +// // sizemap_t *geo_sizemap_e, *geo_sizemap_f; +// sizemap_t *iso_sizemap_p, *iso_sizemap_e, *iso_sizemap_f; +// // sizemap_t *clean_geo_sizemap_e, *clean_geo_sizemap_f; +// sizemap_t *clean_iso_sizemap_p, *clean_iso_sizemap_e, *clean_iso_sizemap_f; +// #endif +status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data); +status_t size_on_edge(integer edge_id, real t, real *size, void *user_data); +status_t size_on_vertex(integer vertex_id, real *size, void *user_data); + +double my_u_min=1e6,my_v_min=1e6,my_u_max=-1e6,my_v_max=-1e6; + +typedef struct { + gp_XY uv; + gp_XYZ xyz; +} projectionPoint; +///////////////////////////////////////////////////////// +projectionPoint getProjectionPoint(const TopoDS_Face& face, const gp_Pnt& point) +{ + projectionPoint myPoint; + Handle(Geom_Surface) surface = BRep_Tool::Surface(face); + GeomAPI_ProjectPointOnSurf projector( point, surface ); + if ( !projector.IsDone() || projector.NbPoints()==0 ) + throw "getProjectionPoint: Can't project"; + + Quantity_Parameter u,v; + projector.LowerDistanceParameters(u,v); + myPoint.uv = gp_XY(u,v); + gp_Pnt aPnt = projector.NearestPoint(); + myPoint.xyz = gp_XYZ(aPnt.X(),aPnt.Y(),aPnt.Z()); + //return gp_XY(u,v); + return myPoint; +} +///////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////// +double getT(const TopoDS_Edge& edge, const gp_Pnt& point) +{ + Standard_Real f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, f,l); + GeomAPI_ProjectPointOnCurve projector( point, curve); + if ( projector.NbPoints() == 0 ) + throw; + return projector.LowerDistanceParameter(); +} + +///////////////////////////////////////////////////////// +TopoDS_Shape BLSURFPlugin_BLSURF::entryToShape(std::string entry) +{ + MESSAGE("BLSURFPlugin_BLSURF::entryToShape "<FindObjectID( entry.c_str() ); + 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 = myStudy->ConvertIORToObject(aVal); + aGeomObj = GEOM::GEOM_Object::_narrow(obj); + } + if ( !aGeomObj->_is_nil() ) + S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); + return S; +} + +void _createEnforcedVertexOnFace(TopoDS_Face faceShape, gp_Pnt aPnt, BLSURFPlugin_Hypothesis::TEnfVertex *enfVertex) +{ + BLSURFPlugin_Hypothesis::TEnfVertexCoords enf_coords, coords, s_coords; + enf_coords.clear(); + coords.clear(); + s_coords.clear(); + + // Get the (u,v) values of the enforced vertex on the face + projectionPoint myPoint = getProjectionPoint(faceShape,aPnt); + + MESSAGE("Enforced Vertex: " << aPnt.X() << ", " << aPnt.Y() << ", " << aPnt.Z()); + MESSAGE("Projected Vertex: " << myPoint.xyz.X() << ", " << myPoint.xyz.Y() << ", " << myPoint.xyz.Z()); + MESSAGE("Parametric coordinates: " << myPoint.uv.X() << ", " << myPoint.uv.Y() ); + + enf_coords.push_back(aPnt.X()); + enf_coords.push_back(aPnt.Y()); + enf_coords.push_back(aPnt.Z()); + + coords.push_back(myPoint.uv.X()); + coords.push_back(myPoint.uv.Y()); + coords.push_back(myPoint.xyz.X()); + coords.push_back(myPoint.xyz.Y()); + coords.push_back(myPoint.xyz.Z()); + + s_coords.push_back(myPoint.xyz.X()); + s_coords.push_back(myPoint.xyz.Y()); + s_coords.push_back(myPoint.xyz.Z()); + + // Save pair projected vertex / enf vertex + MESSAGE("Storing pair projected vertex / enf vertex:"); + MESSAGE("("<< myPoint.xyz.X() << ", " << myPoint.xyz.Y() << ", " << myPoint.xyz.Z() <<") / (" << aPnt.X() << ", " << aPnt.Y() << ", " << aPnt.Z()<<")"); + EnfVertexCoords2ProjVertex[s_coords] = enf_coords; + MESSAGE("Group name is: \"" << enfVertex->grpName << "\""); + pair ret; + BLSURFPlugin_Hypothesis::TEnfVertexList::iterator it; + ret = EnfVertexCoords2EnfVertexList[s_coords].insert(enfVertex); + if (ret.second == false) { + it = ret.first; + (*it)->grpName = enfVertex->grpName; + } + + int key = 0; + if (! FacesWithEnforcedVertices.Contains(faceShape)) { + key = FacesWithEnforcedVertices.Add(faceShape); + } + else { + key = FacesWithEnforcedVertices.FindIndex(faceShape); + } + + // If a node is already created by an attractor, do not create enforced vertex + int attractorKey = FacesWithSizeMap.FindIndex(faceShape); + bool sameAttractor = false; + if (attractorKey >= 0) + if (FaceId2AttractorCoords.count(attractorKey) > 0) + if (FaceId2AttractorCoords[attractorKey] == coords) + sameAttractor = true; + + if (FaceId2EnforcedVertexCoords.find(key) != FaceId2EnforcedVertexCoords.end()) { + MESSAGE("Map of enf. vertex has key " << key) + MESSAGE("Enf. vertex list size is: " << FaceId2EnforcedVertexCoords[key].size()) + if (! sameAttractor) + FaceId2EnforcedVertexCoords[key].insert(coords); // there should be no redondant coords here (see std::set management) + else + MESSAGE("An attractor node is already defined: I don't add the enforced vertex"); + MESSAGE("New Enf. vertex list size is: " << FaceId2EnforcedVertexCoords[key].size()) + } + else { + MESSAGE("Map of enf. vertex has not key " << key << ": creating it") + if (! sameAttractor) { + BLSURFPlugin_Hypothesis::TEnfVertexCoordsList ens; + ens.insert(coords); + FaceId2EnforcedVertexCoords[key] = ens; + } + else + MESSAGE("An attractor node is already defined: I don't add the enforced vertex"); + } +} + +///////////////////////////////////////////////////////// +void BLSURFPlugin_BLSURF::createEnforcedVertexOnFace(TopoDS_Shape faceShape, BLSURFPlugin_Hypothesis::TEnfVertexList enfVertexList) +{ + BLSURFPlugin_Hypothesis::TEnfVertex* enfVertex; + gp_Pnt aPnt; + + BLSURFPlugin_Hypothesis::TEnfVertexList::const_iterator enfVertexListIt = enfVertexList.begin(); + + for( ; enfVertexListIt != enfVertexList.end() ; ++enfVertexListIt ) { + enfVertex = *enfVertexListIt; + // Case of manual coords + if (enfVertex->coords.size() != 0) { + aPnt.SetCoord(enfVertex->coords[0],enfVertex->coords[1],enfVertex->coords[2]); + _createEnforcedVertexOnFace( TopoDS::Face(faceShape), aPnt, enfVertex); + } + + // Case of geom vertex coords + if (enfVertex->geomEntry != "") { + TopoDS_Shape GeomShape = entryToShape(enfVertex->geomEntry); + TopAbs_ShapeEnum GeomType = GeomShape.ShapeType(); + if (GeomType == TopAbs_VERTEX){ + aPnt = BRep_Tool::Pnt(TopoDS::Vertex(GeomShape)); + _createEnforcedVertexOnFace( TopoDS::Face(faceShape), aPnt, enfVertex); + } + // Group Management + if (GeomType == TopAbs_COMPOUND){ + for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){ + if (it.Value().ShapeType() == TopAbs_VERTEX){ + aPnt = BRep_Tool::Pnt(TopoDS::Vertex(it.Value())); + _createEnforcedVertexOnFace( TopoDS::Face(faceShape), aPnt, enfVertex); + } + } + } + } + } +} + +///////////////////////////////////////////////////////// +void createAttractorOnFace(TopoDS_Shape GeomShape, std::string AttractorFunction) +{ + MESSAGE("Attractor function: "<< AttractorFunction); + double xa, ya, za; // Coordinates of attractor point + double a, b; // Attractor parameter + double d = 0.; + bool createNode=false; // To create a node on attractor projection + int pos1, pos2; + const char *sep = ";"; + // atIt->second has the following pattern: + // ATTRACTOR(xa;ya;za;a;b;True|False;d) + // where: + // xa;ya;za : coordinates of attractor + // a : desired size on attractor + // b : distance of influence of attractor + // d : distance until which the size remains constant + // + // We search the parameters in the string + // xa + pos1 = AttractorFunction.find(sep); + if (pos1!=string::npos) + xa = atof(AttractorFunction.substr(10, pos1-10).c_str()); + // ya + pos2 = AttractorFunction.find(sep, pos1+1); + if (pos2!=string::npos) { + ya = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str()); + pos1 = pos2; + } + // za + pos2 = AttractorFunction.find(sep, pos1+1); + if (pos2!=string::npos) { + za = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str()); + pos1 = pos2; + } + // a + pos2 = AttractorFunction.find(sep, pos1+1); + if (pos2!=string::npos) { + a = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str()); + pos1 = pos2; + } + // b + pos2 = AttractorFunction.find(sep, pos1+1); + if (pos2!=string::npos) { + b = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str()); + pos1 = pos2; + } + // createNode + pos2 = AttractorFunction.find(sep, pos1+1); + if (pos2!=string::npos) { + string createNodeStr = AttractorFunction.substr(pos1+1, pos2-pos1-1); + MESSAGE("createNode: " << createNodeStr); + createNode = (AttractorFunction.substr(pos1+1, pos2-pos1-1) == "True"); + pos1=pos2; + } + // d + pos2 = AttractorFunction.find(")"); + if (pos2!=string::npos) { + d = atof(AttractorFunction.substr(pos1+1, pos2-pos1-1).c_str()); + } + + // Get the (u,v) values of the attractor on the face + projectionPoint myPoint = getProjectionPoint(TopoDS::Face(GeomShape),gp_Pnt(xa,ya,za)); + gp_XY uvPoint = myPoint.uv; + gp_XYZ xyzPoint = myPoint.xyz; + Standard_Real u0 = uvPoint.X(); + Standard_Real v0 = uvPoint.Y(); + Standard_Real x0 = xyzPoint.X(); + Standard_Real y0 = xyzPoint.Y(); + Standard_Real z0 = xyzPoint.Z(); + std::vector coords; + coords.push_back(u0); + coords.push_back(v0); + coords.push_back(x0); + coords.push_back(y0); + coords.push_back(z0); + // We construct the python function + ostringstream attractorFunctionStream; + attractorFunctionStream << "def f(u,v): return "; + attractorFunctionStream << _smp_phy_size << "-(" << _smp_phy_size <<"-" << a << ")"; + //attractorFunctionStream << "*exp(-((u-("<= "3.1.1" +// cad_t * c, +// #endif + const BLSURFPlugin_Hypothesis* hyp, + blsurf_session_t * bls, + precad_session_t * pcs, + SMESH_Mesh& mesh, + bool * use_precad + ) { int _topology = BLSURFPlugin_Hypothesis::GetDefaultTopology(); int _physicalMesh = BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh(); @@ -178,6 +700,13 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu bool _decimesh = BLSURFPlugin_Hypothesis::GetDefaultDecimesh(); int _verb = BLSURFPlugin_Hypothesis::GetDefaultVerbosity(); + // PreCAD + int _precadMergeEdges = BLSURFPlugin_Hypothesis::GetDefaultPreCADMergeEdges(); + int _precadRemoveNanoEdges = BLSURFPlugin_Hypothesis::GetDefaultPreCADRemoveNanoEdges(); + int _precadDiscardInput = BLSURFPlugin_Hypothesis::GetDefaultPreCADDiscardInput(); + double _precadEpsNano = BLSURFPlugin_Hypothesis::GetDefaultPreCADEpsNano(); + + if (hyp) { MESSAGE("BLSURFPlugin_BLSURF::SetParameters"); _topology = (int) hyp->GetTopology(); @@ -190,7 +719,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu _quadAllowed = hyp->GetQuadAllowed(); _decimesh = hyp->GetDecimesh(); _verb = hyp->GetVerbosity(); - if ( hyp->GetPhyMin() != ::BLSURFPlugin_Hypothesis::undefinedDouble() ) blsurf_set_param(bls, "hphymin", to_string(hyp->GetPhyMin()).c_str()); if ( hyp->GetPhyMax() != ::BLSURFPlugin_Hypothesis::undefinedDouble() ) @@ -204,36 +732,418 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu BLSURFPlugin_Hypothesis::TOptionValues::const_iterator opIt; for ( opIt = opts.begin(); opIt != opts.end(); ++opIt ) if ( !opIt->second.empty() ) { -#ifdef _DEBUG_ - cout << "blsurf_set_param(): " << opIt->first << " = " << opIt->second << endl; -#endif + MESSAGE("blsurf_set_param(): " << opIt->first << " = " << opIt->second); blsurf_set_param(bls, opIt->first.c_str(), opIt->second.c_str()); } + + const BLSURFPlugin_Hypothesis::TOptionValues & preCADopts = hyp->GetPreCADOptionValues(); + for ( opIt = preCADopts.begin(); opIt != preCADopts.end(); ++opIt ) + if ( !opIt->second.empty() ) { + if (_topology == BLSURFPlugin_Hypothesis::PreCAD) { + MESSAGE("precad_set_param(): " << opIt->first << " = " << opIt->second); + blsurf_set_param(bls, opIt->first.c_str(), opIt->second.c_str()); + } + } + + // PreCAD + _precadMergeEdges = hyp->GetPreCADMergeEdges(); + _precadRemoveNanoEdges = hyp->GetPreCADRemoveNanoEdges(); + _precadDiscardInput = hyp->GetPreCADDiscardInput(); + _precadEpsNano = hyp->GetPreCADEpsNano(); } else { + //0020968: EDF1545 SMESH: Problem in the creation of a mesh group on geometry + // GetDefaultPhySize() sometimes leads to computation failure + _phySize = mesh.GetShapeDiagonalSize() / _gen->GetBoundaryBoxSegmentation(); MESSAGE("BLSURFPlugin_BLSURF::SetParameters using defaults"); } - - blsurf_set_param(bls, "topo_points", _topology > 0 ? "1" : "0"); - blsurf_set_param(bls, "topo_curves", _topology > 0 ? "1" : "0"); - blsurf_set_param(bls, "topo_project", _topology > 0 ? "1" : "0"); - blsurf_set_param(bls, "clean_boundary", _topology > 1 ? "1" : "0"); - blsurf_set_param(bls, "close_boundary", _topology > 1 ? "1" : "0"); + + // PreCAD + if (_topology == BLSURFPlugin_Hypothesis::PreCAD) { + *use_precad = true; + precad_set_param(pcs, "verbose", to_string(_verb).c_str()); + precad_set_param(pcs, "merge_edges", _precadMergeEdges ? "1" : "0"); + precad_set_param(pcs, "remove_nano_edges", _precadRemoveNanoEdges ? "1" : "0"); + precad_set_param(pcs, "discard_input_topology", _precadDiscardInput ? "1" : "0"); + if ( _precadEpsNano != ::BLSURFPlugin_Hypothesis::undefinedDouble() ) + precad_set_param(pcs, "eps_nano", to_string(_precadEpsNano).c_str()); + } + + _smp_phy_size = _phySize; + blsurf_set_param(bls, "topo_points", _topology == BLSURFPlugin_Hypothesis::Process || _topology == BLSURFPlugin_Hypothesis::Process2 ? "1" : "0"); + blsurf_set_param(bls, "topo_curves", _topology == BLSURFPlugin_Hypothesis::Process || _topology == BLSURFPlugin_Hypothesis::Process2 ? "1" : "0"); + blsurf_set_param(bls, "topo_project", _topology == BLSURFPlugin_Hypothesis::Process || _topology == BLSURFPlugin_Hypothesis::Process2 ? "1" : "0"); + blsurf_set_param(bls, "clean_boundary", _topology == BLSURFPlugin_Hypothesis::Process2 ? "1" : "0"); + blsurf_set_param(bls, "close_boundary", _topology == BLSURFPlugin_Hypothesis::Process2 ? "1" : "0"); blsurf_set_param(bls, "hphy_flag", to_string(_physicalMesh).c_str()); blsurf_set_param(bls, "hphydef", to_string(_phySize).c_str()); blsurf_set_param(bls, "hgeo_flag", to_string(_geometricMesh).c_str()); + blsurf_set_param(bls, "relax_size", _decimesh ? "0": to_string(_geometricMesh).c_str()); blsurf_set_param(bls, "angle_meshs", to_string(_angleMeshS).c_str()); blsurf_set_param(bls, "angle_meshc", to_string(_angleMeshC).c_str()); blsurf_set_param(bls, "gradation", to_string(_gradation).c_str()); blsurf_set_param(bls, "patch_independent", _decimesh ? "1" : "0"); blsurf_set_param(bls, "element", _quadAllowed ? "q1.0" : "p1"); blsurf_set_param(bls, "verb", to_string(_verb).c_str()); + + if (_physicalMesh == BLSURFPlugin_Hypothesis::SizeMap){ + TopoDS_Shape GeomShape; + TopoDS_Shape AttShape; + TopAbs_ShapeEnum GeomType; + // + // Standard Size Maps + // + MESSAGE("Setting a Size Map"); + const BLSURFPlugin_Hypothesis::TSizeMap sizeMaps = BLSURFPlugin_Hypothesis::GetSizeMapEntries(hyp); + BLSURFPlugin_Hypothesis::TSizeMap::const_iterator smIt = sizeMaps.begin(); + for ( ; smIt != sizeMaps.end(); ++smIt ) { + if ( !smIt->second.empty() ) { + MESSAGE("blsurf_set_sizeMap(): " << smIt->first << " = " << smIt->second); + GeomShape = entryToShape(smIt->first); + GeomType = GeomShape.ShapeType(); + MESSAGE("Geomtype is " << GeomType); + int key = -1; + // Group Management + if (GeomType == TopAbs_COMPOUND){ + for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){ + // Group of faces + if (it.Value().ShapeType() == TopAbs_FACE){ + HasSizeMapOnFace = true; + if (! FacesWithSizeMap.Contains(TopoDS::Face(it.Value()))) { + key = FacesWithSizeMap.Add(TopoDS::Face(it.Value())); + } + else { + key = FacesWithSizeMap.FindIndex(TopoDS::Face(it.Value())); +// MESSAGE("Face with key " << key << " already in map"); + } + FaceId2SizeMap[key] = smIt->second; + } + // Group of edges + if (it.Value().ShapeType() == TopAbs_EDGE){ + HasSizeMapOnEdge = true; + HasSizeMapOnFace = true; + if (! EdgesWithSizeMap.Contains(TopoDS::Edge(it.Value()))) { + key = EdgesWithSizeMap.Add(TopoDS::Edge(it.Value())); + } + else { + key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(it.Value())); +// MESSAGE("Edge with key " << key << " already in map"); + } + EdgeId2SizeMap[key] = smIt->second; + } + // Group of vertices + if (it.Value().ShapeType() == TopAbs_VERTEX){ + HasSizeMapOnVertex = true; + HasSizeMapOnEdge = true; + HasSizeMapOnFace = true; + if (! VerticesWithSizeMap.Contains(TopoDS::Vertex(it.Value()))) { + key = VerticesWithSizeMap.Add(TopoDS::Vertex(it.Value())); + } + else { + key = VerticesWithSizeMap.FindIndex(TopoDS::Vertex(it.Value())); + MESSAGE("Group of vertices with key " << key << " already in map"); + } + MESSAGE("Group of vertices with key " << key << " has a size map: " << smIt->second); + VertexId2SizeMap[key] = smIt->second; + } + } + } + // Single face + if (GeomType == TopAbs_FACE){ + HasSizeMapOnFace = true; + if (! FacesWithSizeMap.Contains(TopoDS::Face(GeomShape))) { + key = FacesWithSizeMap.Add(TopoDS::Face(GeomShape)); + } + else { + key = FacesWithSizeMap.FindIndex(TopoDS::Face(GeomShape)); +// MESSAGE("Face with key " << key << " already in map"); + } + FaceId2SizeMap[key] = smIt->second; + } + // Single edge + if (GeomType == TopAbs_EDGE){ + HasSizeMapOnEdge = true; + HasSizeMapOnFace = true; + if (! EdgesWithSizeMap.Contains(TopoDS::Edge(GeomShape))) { + key = EdgesWithSizeMap.Add(TopoDS::Edge(GeomShape)); + } + else { + key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(GeomShape)); +// MESSAGE("Edge with key " << key << " already in map"); + } + EdgeId2SizeMap[key] = smIt->second; + } + // Single vertex + if (GeomType == TopAbs_VERTEX){ + HasSizeMapOnVertex = true; + HasSizeMapOnEdge = true; + HasSizeMapOnFace = true; + if (! VerticesWithSizeMap.Contains(TopoDS::Vertex(GeomShape))) { + key = VerticesWithSizeMap.Add(TopoDS::Vertex(GeomShape)); + } + else { + key = VerticesWithSizeMap.FindIndex(TopoDS::Vertex(GeomShape)); + MESSAGE("Vertex with key " << key << " already in map"); + } + MESSAGE("Vertex with key " << key << " has a size map: " << smIt->second); + VertexId2SizeMap[key] = smIt->second; + } + } + } + + // + // Attractors + // + // TODO appeler le constructeur des attracteurs directement ici + MESSAGE("Setting Attractors"); + const BLSURFPlugin_Hypothesis::TSizeMap attractors = BLSURFPlugin_Hypothesis::GetAttractorEntries(hyp); + BLSURFPlugin_Hypothesis::TSizeMap::const_iterator atIt = attractors.begin(); + for ( ; atIt != attractors.end(); ++atIt ) { + if ( !atIt->second.empty() ) { + MESSAGE("blsurf_set_attractor(): " << atIt->first << " = " << atIt->second); + GeomShape = entryToShape(atIt->first); + GeomType = GeomShape.ShapeType(); + // Group Management + if (GeomType == TopAbs_COMPOUND){ + for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){ + if (it.Value().ShapeType() == TopAbs_FACE){ + HasSizeMapOnFace = true; + createAttractorOnFace(it.Value(), atIt->second); + } + } + } + + if (GeomType == TopAbs_FACE){ + HasSizeMapOnFace = true; + createAttractorOnFace(GeomShape, atIt->second); + } +/* + if (GeomType == TopAbs_EDGE){ + HasSizeMapOnEdge = true; + HasSizeMapOnFace = true; + EdgeId2SizeMap[TopoDS::Edge(GeomShape).HashCode(IntegerLast())] = atIt->second; + } + if (GeomType == TopAbs_VERTEX){ + HasSizeMapOnVertex = true; + HasSizeMapOnEdge = true; + HasSizeMapOnFace = true; + VertexId2SizeMap[TopoDS::Vertex(GeomShape).HashCode(IntegerLast())] = atIt->second; + } +*/ + } + } + + // Class Attractors + // temporary commented out for testing + // TODO + // - Fill in the BLSURFPlugin_Hypothesis::TAttractorMap map in the hypothesis + // - Uncomment and complete this part to construct the attractors from the attractor shape and the passed parameters on each face of the map + // - To do this use the public methodss: SetParameters(several double parameters) and SetType(int type) + // OR, even better: + // - Construct the attractors with an empty dist. map in the hypothesis + // - build the map here for each face with an attractor set and only if the attractor shape as changed since the last call to _buildmap() + // -> define a bool _mapbuilt in the class that is set to false by default and set to true when calling _buildmap() OK + + const BLSURFPlugin_Hypothesis::TAttractorMap class_attractors = BLSURFPlugin_Hypothesis::GetClassAttractorEntries(hyp); + int key=-1; + BLSURFPlugin_Hypothesis::TAttractorMap::const_iterator AtIt = class_attractors.begin(); + for ( ; AtIt != class_attractors.end(); ++AtIt ) { + if ( !AtIt->second->Empty() ) { + // MESSAGE("blsurf_set_attractor(): " << AtIt->first << " = " << AtIt->second); + GeomShape = entryToShape(AtIt->first); + AttShape = AtIt->second->GetAttractorShape(); + GeomType = GeomShape.ShapeType(); + // Group Management +// if (GeomType == TopAbs_COMPOUND){ +// for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){ +// if (it.Value().ShapeType() == TopAbs_FACE){ +// HasAttractorOnFace = true; +// myAttractor = BLSURFPluginAttractor(GeomShape, AttShape); +// } +// } +// } + + if (GeomType == TopAbs_FACE + && (AttShape.ShapeType() == TopAbs_VERTEX + || AttShape.ShapeType() == TopAbs_EDGE + || AttShape.ShapeType() == TopAbs_WIRE + || AttShape.ShapeType() == TopAbs_COMPOUND) ){ + HasSizeMapOnFace = true; + + if (! FacesWithSizeMap.Contains(TopoDS::Face(GeomShape)) ) { + key = FacesWithSizeMap.Add(TopoDS::Face(GeomShape) ); + } + else { + key = FacesWithSizeMap.FindIndex(TopoDS::Face(GeomShape)); +// MESSAGE("Face with key " << key << " already in map"); + } + + FaceId2ClassAttractor[key] = AtIt->second; + } + else{ + MESSAGE("Wrong shape type !!") + } + + } + } + + + // + // Enforced Vertices + // + MESSAGE("Setting Enforced Vertices"); + const BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap entryEnfVertexListMap = BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace(hyp); + BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap::const_iterator enfIt = entryEnfVertexListMap.begin(); + for ( ; enfIt != entryEnfVertexListMap.end(); ++enfIt ) { + if ( !enfIt->second.empty() ) { + GeomShape = entryToShape(enfIt->first); + GeomType = GeomShape.ShapeType(); + // Group Management + if (GeomType == TopAbs_COMPOUND){ + for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){ + if (it.Value().ShapeType() == TopAbs_FACE){ + HasSizeMapOnFace = true; + createEnforcedVertexOnFace(it.Value(), enfIt->second); + } + } + } + + if (GeomType == TopAbs_FACE){ + HasSizeMapOnFace = true; + createEnforcedVertexOnFace(GeomShape, enfIt->second); + } + } + } + + // Internal vertices + bool useInternalVertexAllFaces = BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFaces(hyp); + if (useInternalVertexAllFaces) { + std::string grpName = BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFacesGroup(hyp); + MESSAGE("Setting Internal Enforced Vertices"); + GeomShape = mesh.GetShapeToMesh(); + gp_Pnt aPnt; + TopExp_Explorer exp (GeomShape, TopAbs_FACE); + for (; exp.More(); exp.Next()){ + MESSAGE("Iterating shapes. Shape type is " << exp.Current().ShapeType()); + TopExp_Explorer exp_face (exp.Current(), TopAbs_VERTEX); + for (; exp_face.More(); exp_face.Next()) + { + // Get coords of vertex + // Check if current coords is already in enfVertexList + // If coords not in enfVertexList, add new enfVertex + aPnt = BRep_Tool::Pnt(TopoDS::Vertex(exp_face.Current())); + MESSAGE("Found vertex on face at " << aPnt.X() <<", "<coords.push_back(aPnt.X()); + enfVertex->coords.push_back(aPnt.Y()); + enfVertex->coords.push_back(aPnt.Z()); + enfVertex->name = ""; + enfVertex->faceEntries.clear(); + enfVertex->geomEntry = ""; + enfVertex->grpName = grpName; + _createEnforcedVertexOnFace( TopoDS::Face(exp.Current()), aPnt, enfVertex); + HasSizeMapOnFace = true; + } + } + } + + MESSAGE("Setting Size Map on FACES "); +// #if BLSURF_VERSION_LONG < "3.1.1" + blsurf_data_set_sizemap_iso_cad_face(bls, size_on_surface, &_smp_phy_size); +// #else +// if (*use_precad) +// iso_sizemap_f = sizemap_new(c, distene_sizemap_type_iso_cad_face, (void *)size_on_surface, NULL); +// else +// clean_iso_sizemap_f = sizemap_new(c, distene_sizemap_type_iso_cad_face, (void *)size_on_surface, NULL); +// #endif + + if (HasSizeMapOnEdge){ + MESSAGE("Setting Size Map on EDGES "); +// #if BLSURF_VERSION_LONG < "3.1.1" + blsurf_data_set_sizemap_iso_cad_edge(bls, size_on_edge, &_smp_phy_size); +// #else +// if (*use_precad) +// iso_sizemap_e = sizemap_new(c, distene_sizemap_type_iso_cad_edge, (void *)size_on_edge, NULL); +// else +// clean_iso_sizemap_e = sizemap_new(c, distene_sizemap_type_iso_cad_edge, (void *)size_on_edge, NULL); +// #endif + } + if (HasSizeMapOnVertex){ + MESSAGE("Setting Size Map on VERTICES "); +// #if BLSURF_VERSION_LONG < "3.1.1" + blsurf_data_set_sizemap_iso_cad_point(bls, size_on_vertex, &_smp_phy_size); +// #else +// if (*use_precad) +// iso_sizemap_p = sizemap_new(c, distene_sizemap_type_iso_cad_point, (void *)size_on_vertex, NULL); +// else +// clean_iso_sizemap_p = sizemap_new(c, distene_sizemap_type_iso_cad_point, (void *)size_on_vertex, NULL); +// #endif + } + } } +namespace +{ + /*! + * \brief Class correctly terminating usage of BLSURF library at destruction + */ + class BLSURF_Cleaner + { + context_t * _ctx; + blsurf_session_t* _bls; + cad_t * _cad; + dcad_t * _dcad; + public: + BLSURF_Cleaner(context_t * ctx, + blsurf_session_t* bls, + cad_t * cad, + dcad_t * dcad) + : _ctx ( ctx ), + _bls ( bls ), + _cad ( cad ), + _dcad( dcad ) + { + } + ~BLSURF_Cleaner() + { + blsurf_session_delete(_bls); + + // #if BLSURF_VERSION_LONG >= "3.1.1" + // // if(geo_sizemap_e) + // // distene_sizemap_delete(geo_sizemap_e); + // // if(geo_sizemap_f) + // // distene_sizemap_delete(geo_sizemap_f); + // if(iso_sizemap_p) + // distene_sizemap_delete(iso_sizemap_p); + // if(iso_sizemap_e) + // distene_sizemap_delete(iso_sizemap_e); + // if(iso_sizemap_f) + // distene_sizemap_delete(iso_sizemap_f); + // + // // if(clean_geo_sizemap_e) + // // distene_sizemap_delete(clean_geo_sizemap_e); + // // if(clean_geo_sizemap_f) + // // distene_sizemap_delete(clean_geo_sizemap_f); + // if(clean_iso_sizemap_p) + // distene_sizemap_delete(clean_iso_sizemap_p); + // if(clean_iso_sizemap_e) + // distene_sizemap_delete(clean_iso_sizemap_e); + // if(clean_iso_sizemap_f) + // distene_sizemap_delete(clean_iso_sizemap_f); + // #endif + + cad_delete(_cad); + dcad_delete(_dcad); + context_delete(_ctx); + } + }; +} // namespace + status_t curv_fun(real t, real *uv, real *dt, real *dtt, void *user_data); status_t surf_fun(real *uv, real *xyz, real*du, real *dv, - real *duu, real *duv, real *dvv, void *user_data); -status_t message_callback(message_t *msg, void *user_data); + real *duu, real *duv, real *dvv, void *user_data); +status_t message_cb(message_t *msg, void *user_data); +status_t interrupt_cb(integer *interrupt_status, void *user_data); //============================================================================= /*! @@ -245,104 +1155,506 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) MESSAGE("BLSURFPlugin_BLSURF::Compute"); - if (aShape.ShapeType() == TopAbs_COMPOUND) { - cout << " the shape is a COMPOUND" << endl; - } - else { - cout << " the shape is UNKNOWN" << endl; - }; + // Fix problem with locales + Kernel_Utils::Localizer aLocalizer; + + /* create a distene context (generic object) */ + status_t status = STATUS_ERROR; context_t *ctx = context_new(); - context_set_message_callback(ctx, message_callback, &_comment); + /* Set the message callback in the working context */ + context_set_message_callback(ctx, message_cb, &_comment); +#ifdef WITH_SMESH_CANCEL_COMPUTE + _compute_canceled = false; + context_set_interrupt_callback(ctx, interrupt_cb, this); +#else + context_set_interrupt_callback(ctx, interrupt_cb, NULL); +#endif + + /* create the CAD object we will work on. It is associated to the context ctx. */ cad_t *c = cad_new(ctx); - + dcad_t *dcad = dcad_new(c); + + FacesWithSizeMap.Clear(); + FaceId2SizeMap.clear(); + FaceId2ClassAttractor.clear(); + FaceIndex2ClassAttractor.clear(); + EdgesWithSizeMap.Clear(); + EdgeId2SizeMap.clear(); + VerticesWithSizeMap.Clear(); + VertexId2SizeMap.clear(); + + SMESH_MesherHelper helper( aMesh ); + // do not call helper.IsQuadraticSubMesh() because submeshes + // may be cleaned and helper.myTLinkNodeMap gets invalid in such a case + const bool haveQudraticSubMesh = SMESH_MesherHelper( aMesh ).IsQuadraticSubMesh( aShape ); + helper.SetIsQuadratic( haveQudraticSubMesh ); + bool needMerge = false; + set< SMESH_subMesh* > edgeSubmeshes; + + /* Now fill the CAD object with data from your CAD + * environement. This is the most complex part of a successfull + * integration. + */ + + // PreCAD + // If user requests it, send the CAD through Distene preprocessor : PreCAD + cad_t *cleanc = NULL; + precad_session_t *pcs = precad_session_new(ctx); + precad_data_set_cad(pcs, c); + + blsurf_session_t *bls = blsurf_session_new(ctx); + + // an object that correctly deletes all blsurf objects at destruction + BLSURF_Cleaner cleaner( ctx,bls,c,dcad ); + + MESSAGE("BEGIN SetParameters"); + bool use_precad = false; + SetParameters( +// #if BLSURF_VERSION_LONG >= "3.1.1" +// c, +// #endif + _hypothesis, bls, pcs, aMesh, &use_precad); + MESSAGE("END SetParameters"); + + // needed to prevent the opencascade memory managmement from freeing things + vector curves; + vector surfaces; + + surfaces.resize(0); + curves.resize(0); + TopTools_IndexedMapOfShape fmap; TopTools_IndexedMapOfShape emap; TopTools_IndexedMapOfShape pmap; - vector curves; - vector surfaces; fmap.Clear(); + FaceId2PythonSmp.clear(); emap.Clear(); + EdgeId2PythonSmp.clear(); pmap.Clear(); - surfaces.resize(0); - curves.resize(0); + VertexId2PythonSmp.clear(); + + assert(Py_IsInitialized()); + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + string theSizeMapStr; + /**************************************************************************************** + FACES + *****************************************************************************************/ int iface = 0; + string bad_end = "return"; + int faceKey = -1; + TopTools_IndexedMapOfShape _map; + TopExp::MapShapes(aShape,TopAbs_VERTEX,_map); + int ienf = _map.Extent(); + for (TopExp_Explorer face_iter(aShape,TopAbs_FACE);face_iter.More();face_iter.Next()) { TopoDS_Face f=TopoDS::Face(face_iter.Current()); + + // make INTERNAL face oriented FORWARD (issue 0020993) + if (f.Orientation() != TopAbs_FORWARD && f.Orientation() != TopAbs_REVERSED ) + f.Orientation(TopAbs_FORWARD); + if (fmap.FindIndex(f) > 0) continue; - + fmap.Add(f); iface++; surfaces.push_back(BRep_Tool::Surface(f)); - cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back()); + + /* create an object representing the face for blsurf */ + /* where face_id is an integer identifying the face. + * surf_function is the function that defines the surface + * (For this face, it will be called by blsurf with your_face_object_ptr + * as last parameter. + */ + cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back()); + + /* by default a face has no tag (color). The following call sets it to the same value as the face_id : */ cad_face_set_tag(fce, iface); + + /* Set face orientation (optional if you want a well oriented output mesh)*/ if(f.Orientation() != TopAbs_FORWARD){ cad_face_set_orientation(fce, CAD_ORIENTATION_REVERSED); } else { cad_face_set_orientation(fce, CAD_ORIENTATION_FORWARD); } - + + if (HasSizeMapOnFace && !use_precad){ +// MESSAGE("A size map is defined on a face") +// std::cout << "A size map is defined on a face" << std::endl; + // Classic size map + faceKey = FacesWithSizeMap.FindIndex(f); + + + if (FaceId2SizeMap.find(faceKey)!=FaceId2SizeMap.end()){ + MESSAGE("A size map is defined on face :"< >::iterator attractor_iter = FaceId2AttractorCoords.begin(); + + for (; attractor_iter != FaceId2AttractorCoords.end(); ++attractor_iter) { + if (attractor_iter->first == faceKey) { + MESSAGE("Face indice: " << iface); + MESSAGE("Adding attractor"); + + double xyzCoords[3] = {attractor_iter->second[2], + attractor_iter->second[3], + attractor_iter->second[4]}; + + MESSAGE("Check position of vertex =(" << xyzCoords[0] << "," << xyzCoords[1] << "," << xyzCoords[2] << ")"); + gp_Pnt P(xyzCoords[0],xyzCoords[1],xyzCoords[2]); + BRepClass_FaceClassifier scl(f,P,1e-7); + // scl.Perform() is bugged. The function was rewritten +// scl.Perform(); + BRepClass_FaceClassifierPerform(&scl,f,P,1e-7); + TopAbs_State result = scl.State(); + MESSAGE("Position of point on face: "<second[0],attractor_iter->second[1]}; + ienf++; + MESSAGE("Add cad point on (u,v)=(" << uvCoords[0] << "," << uvCoords[1] << ") with id = " << ienf); + cad_point_t* point_p = cad_point_new(fce, ienf, uvCoords); + cad_point_set_tag(point_p, ienf); + } + FaceId2AttractorCoords.erase(faceKey); + } + } + + // Class Attractors + std::map::iterator clAttractor_iter = FaceId2ClassAttractor.find(faceKey); + if (clAttractor_iter != FaceId2ClassAttractor.end()){ + MESSAGE("Face indice: " << iface); + MESSAGE("Adding attractor"); + FaceIndex2ClassAttractor[iface]=clAttractor_iter->second; + FaceId2ClassAttractor.erase(clAttractor_iter); + } + } + + // Enforced Vertices + faceKey = FacesWithEnforcedVertices.FindIndex(f); + std::map::const_iterator evmIt = FaceId2EnforcedVertexCoords.find(faceKey); + if (evmIt != FaceId2EnforcedVertexCoords.end()) { + MESSAGE("Some enforced vertices are defined"); + BLSURFPlugin_Hypothesis::TEnfVertexCoordsList evl; + MESSAGE("Face indice: " << iface); + MESSAGE("Adding enforced vertices"); + evl = evmIt->second; + MESSAGE("Number of vertices to add: "<< evl.size()); + BLSURFPlugin_Hypothesis::TEnfVertexCoordsList::const_iterator evlIt = evl.begin(); + for (; evlIt != evl.end(); ++evlIt) { + BLSURFPlugin_Hypothesis::TEnfVertexCoords xyzCoords; + xyzCoords.push_back(evlIt->at(2)); + xyzCoords.push_back(evlIt->at(3)); + xyzCoords.push_back(evlIt->at(4)); + MESSAGE("Check position of vertex =(" << xyzCoords[0] << "," << xyzCoords[1] << "," << xyzCoords[2] << ")"); + gp_Pnt P(xyzCoords[0],xyzCoords[1],xyzCoords[2]); + BRepClass_FaceClassifier scl(f,P,1e-7); + // OCC 6.3sp6 : scl.Perform() is bugged. The function was rewritten +// BRepClass_FaceClassifierPerform(&scl,f,P,1e-7); + // OCC 6.5.2: scl.Perform() is not bugged anymore + scl.Perform(f, P, 1e-7); + TopAbs_State result = scl.State(); + MESSAGE("Position of point on face: "<at(0),evlIt->at(1)}; + ienf++; + MESSAGE("Add cad point on (u,v)=(" << uvCoords[0] << "," << uvCoords[1] << ") with id = " << ienf); + cad_point_t* point_p = cad_point_new(fce, ienf, uvCoords); + cad_point_set_tag(point_p, ienf); + } + } + FaceId2EnforcedVertexCoords.erase(faceKey); + } +// else +// std::cout << "No enforced vertex defined" << std::endl; +// } + + + /**************************************************************************************** + EDGES + now create the edges associated to this face + *****************************************************************************************/ + int edgeKey = -1; for (TopExp_Explorer edge_iter(f,TopAbs_EDGE);edge_iter.More();edge_iter.Next()) { TopoDS_Edge e = TopoDS::Edge(edge_iter.Current()); int ic = emap.FindIndex(e); if (ic <= 0) - ic = emap.Add(e); - + ic = emap.Add(e); + double tmin,tmax; curves.push_back(BRep_Tool::CurveOnSurface(e, f, tmin, tmax)); + + if (HasSizeMapOnEdge){ + edgeKey = EdgesWithSizeMap.FindIndex(e); + if (EdgeId2SizeMap.find(edgeKey)!=EdgeId2SizeMap.end()) { + MESSAGE("Sizemap defined on edge with index " << edgeKey); + theSizeMapStr = EdgeId2SizeMap[edgeKey]; + if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1)) + continue; + // Expr To Python function, verification is performed at validation in GUI + PyObject * obj = NULL; + obj= PyRun_String(theSizeMapStr.c_str(), Py_file_input, main_dict, NULL); + Py_DECREF(obj); + PyObject * func = NULL; + func = PyObject_GetAttrString(main_mod, "f"); + EdgeId2PythonSmp[ic]=func; + EdgeId2SizeMap.erase(edgeKey); + } + } + + /* attach the edge to the current blsurf face */ cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back()); + + /* by default an edge has no tag (color). The following call sets it to the same value as the edge_id : */ cad_edge_set_tag(edg, ic); + + /* by default, an edge does not necessalry appear in the resulting mesh, + unless the following property is set : + */ cad_edge_set_property(edg, EDGE_PROPERTY_SOFT_REQUIRED); + + /* by default an edge is a boundary edge */ if (e.Orientation() == TopAbs_INTERNAL) cad_edge_set_property(edg, EDGE_PROPERTY_INTERNAL); + // pass existing nodes of sub-meshes to BLSURF + SMESH_subMesh* sm = aMesh.GetSubMesh( e ); + if ( !sm->IsEmpty() ) + { + edgeSubmeshes.insert( sm ); + + StdMeshers_FaceSide edgeOfFace( f, e, &aMesh, e.Orientation() == TopAbs_FORWARD, + /*ignoreMedium=*/haveQudraticSubMesh); + if ( edgeOfFace.MissVertexNode() ) + return error(COMPERR_BAD_INPUT_MESH,"No node on vertex"); + + const int nbNodes = edgeOfFace.NbPoints(); + + dcad_edge_discretization_t *dedge; + dcad_get_edge_discretization(dcad, edg, &dedge); + dcad_edge_discretization_set_vertex_count( dedge, nbNodes ); + + const std::vector& nodeData = edgeOfFace.GetUVPtStruct(); + for ( int iN = 0; iN < nbNodes; ++iN ) + { + const UVPtStruct& nData = nodeData[ iN ]; + double t = nData.param; + real uv[2] = { nData.u, nData.v }; + SMESH_TNodeXYZ nXYZ( nData.node ); + dcad_edge_discretization_set_vertex_coordinates( dedge, iN+1, t, uv, nXYZ._xyz ); + } + dcad_edge_discretization_set_property(dedge, DISTENE_DCAD_PROPERTY_REQUIRED); + } + + /**************************************************************************************** + VERTICES + *****************************************************************************************/ + int npts = 0; int ip1, ip2, *ip; gp_Pnt2d e0 = curves.back()->Value(tmin); gp_Pnt ee0 = surfaces.back()->Value(e0.X(), e0.Y()); Standard_Real d1=0,d2=0; + + int vertexKey = -1; for (TopExp_Explorer ex_edge(e ,TopAbs_VERTEX); ex_edge.More(); ex_edge.Next()) { - TopoDS_Vertex v = TopoDS::Vertex(ex_edge.Current()); - - ++npts; - if (npts == 1){ - ip = &ip1; - d1 = ee0.SquareDistance(BRep_Tool::Pnt(v)); - } else { - ip = &ip2; + TopoDS_Vertex v = TopoDS::Vertex(ex_edge.Current()); + ++npts; + if (npts == 1){ + ip = &ip1; + d1 = ee0.SquareDistance(BRep_Tool::Pnt(v)); + } else { + ip = &ip2; d2 = ee0.SquareDistance(BRep_Tool::Pnt(v)); - } - *ip = pmap.FindIndex(v); - if(*ip <= 0) - *ip = pmap.Add(v); + } + *ip = pmap.FindIndex(v); + if(*ip <= 0) + *ip = pmap.Add(v); + + if (HasSizeMapOnVertex){ + vertexKey = VerticesWithSizeMap.FindIndex(v); + if (VertexId2SizeMap.find(vertexKey)!=VertexId2SizeMap.end()){ + theSizeMapStr = VertexId2SizeMap[vertexKey]; + //MESSAGE("VertexId2SizeMap[faceKey]: " << VertexId2SizeMap[vertexKey]); + if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1)) + continue; + // Expr To Python function, verification is performed at validation in GUI + PyObject * obj = NULL; + obj= PyRun_String(theSizeMapStr.c_str(), Py_file_input, main_dict, NULL); + Py_DECREF(obj); + PyObject * func = NULL; + func = PyObject_GetAttrString(main_mod, "f"); + VertexId2PythonSmp[*ip]=func; + VertexId2SizeMap.erase(vertexKey); // do not erase if using a vector + } + } } if (npts != 2) { - // should not happen - cout << "An edge does not have 2 extremities." << endl; + // should not happen + MESSAGE("An edge does not have 2 extremities."); } else { - if (d1 < d2) - cad_edge_set_extremities(edg, ip1, ip2); - else - cad_edge_set_extremities(edg, ip2, ip1); + if (d1 < d2) { + // This defines the curves extremity connectivity + cad_edge_set_extremities(edg, ip1, ip2); + /* set the tag (color) to the same value as the extremity id : */ + cad_edge_set_extremities_tag(edg, ip1, ip2); + } + else { + cad_edge_set_extremities(edg, ip2, ip1); + cad_edge_set_extremities_tag(edg, ip2, ip1); + } } } // for edge } //for face + // Clear mesh from already meshed edges if possible else + // remember that merge is needed + set< SMESH_subMesh* >::iterator smIt = edgeSubmeshes.begin(); + for ( ; smIt != edgeSubmeshes.end(); ++smIt ) + { + SMESH_subMesh* sm = *smIt; + SMESH_subMeshIteratorPtr subsmIt = sm->getDependsOnIterator( /*includeSelf=*/true, + /*complexFirst=*/false); + while ( subsmIt->more() ) + { + sm = subsmIt->next(); + if ( SMESHDS_SubMesh* smDS = sm->GetSubMeshDS() ) + { + SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); + if ( nIt->more() ) + { + const SMDS_MeshNode* n = nIt->next(); + if ( n->NbInverseElements( SMDSAbs_Face ) > 0 ) + { + needMerge = true; + // add existing medium nodes to helper + if ( aMesh.NbEdges( ORDER_QUADRATIC ) > 0 ) + { + SMDS_ElemIteratorPtr edgeIt = smDS->GetElements(); + while ( edgeIt->more() ) + helper.AddTLinks( static_cast(edgeIt->next())); + } + } + else + { + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + } + } + } + } + } + PyGILState_Release(gstate); + if (use_precad){ + /* Now launch the PreCAD process */ + status = precad_process(pcs); + if(status != STATUS_OK){ + cout << "PreCAD processing failed with error code " << status << "\n"; + // Now we can delete the PreCAD session + precad_session_delete(pcs); + } + else { + // retrieve the pre-processed CAD object + cleanc = precad_new_cad(pcs); + if(!cleanc){ + cout << "Unable to retrieve PreCAD result \n"; + } + cout << "PreCAD processing successfull \n"; + +// #if BLSURF_VERSION_LONG >= "3.1.1" +// /* We can now get the updated sizemaps (if any) */ +// // if(geo_sizemap_e) +// // clean_geo_sizemap_e = precad_new_sizemap(pcs, geo_sizemap_e); +// // +// // if(geo_sizemap_f) +// // clean_geo_sizemap_f = precad_new_sizemap(pcs, geo_sizemap_f); +// +// if(iso_sizemap_p) +// clean_iso_sizemap_p = precad_new_sizemap(pcs, iso_sizemap_p); +// +// if(iso_sizemap_e) +// clean_iso_sizemap_e = precad_new_sizemap(pcs, iso_sizemap_e); +// +// if(iso_sizemap_f) +// clean_iso_sizemap_f = precad_new_sizemap(pcs, iso_sizemap_f); +// #endif + + // Now we can delete the PreCAD session + precad_session_delete(pcs); + } + } - blsurf_session_t *bls = blsurf_session_new(ctx); - blsurf_data_set_cad(bls, c); + blsurf_data_set_dcad(bls, dcad); + if (cleanc) { + // Give the pre-processed CAD object to the current BLSurf session + blsurf_data_set_cad(bls, cleanc); + } + else { + // Use the original one + blsurf_data_set_cad(bls, c); + } - SetParameters(_hypothesis, bls); +// #if BLSURF_VERSION_LONG >= "3.1.1" +// blsurf_data_set_sizemap(bls, clean_iso_sizemap_p); +// blsurf_data_set_sizemap(bls, clean_iso_sizemap_e); +// blsurf_data_set_sizemap(bls, clean_iso_sizemap_f); +// #endif - cout << endl; - cout << "Beginning of Surface Mesh generation" << endl; - cout << endl; + std::cout << std::endl; + std::cout << "Beginning of Surface Mesh generation" << std::endl; + std::cout << std::endl; // Issue 0019864. On DebianSarge, FE signals do not obey to OSD::SetSignal(false) #ifndef WNT @@ -350,8 +1662,6 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) int oldFEFlags = fedisableexcept( FE_ALL_EXCEPT ); #endif - status_t status = STATUS_ERROR; - try { OCC_CATCH_SIGNALS; @@ -373,28 +1683,49 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) _comment = "Exception in blsurf_compute_mesh()"; } if ( status != STATUS_OK) { - blsurf_session_delete(bls); - cad_delete(c); - context_delete(ctx); - - return error(_comment); + // There was an error while meshing + //return error(_comment); } - cout << endl; - cout << "End of Surface Mesh generation" << endl; - cout << endl; + std::cout << std::endl; + std::cout << "End of Surface Mesh generation" << std::endl; + std::cout << std::endl; - mesh_t *msh; + mesh_t *msh = NULL; blsurf_data_get_mesh(bls, &msh); if(!msh){ - blsurf_session_delete(bls); - cad_delete(c); - context_delete(ctx); - + /* release the mesh object */ + blsurf_data_regain_mesh(bls, msh); return error(_comment); - //return false; } - + + std::string GMFFileName = BLSURFPlugin_Hypothesis::GetDefaultGMFFile(); + if (_hypothesis) + GMFFileName = _hypothesis->GetGMFFile(); + if (GMFFileName != "") { +// bool GMFFileMode = _hypothesis->GetGMFFileMode(); + bool asciiFound = (GMFFileName.find(".mesh",GMFFileName.length()-5) != std::string::npos); + bool binaryFound = (GMFFileName.find(".meshb",GMFFileName.length()-6) != std::string::npos); + if (!asciiFound && !binaryFound) + GMFFileName.append(".mesh"); + /* + if (GMFFileMode) { + if (!binaryFound) { + if (asciiFound) + GMFFileName.append("b"); + else + GMFFileName.append(".meshb"); + } + } + else { + if (!asciiFound) + GMFFileName.append(".mesh"); + } + */ + mesh_write_mesh(msh, GMFFileName.c_str()); + } + + /* retrieve mesh data (see distene/mesh.h) */ integer nv, ne, nt, nq, vtx[4], tag; real xyz[3]; @@ -403,17 +1734,86 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) mesh_get_triangle_count(msh, &nt); mesh_get_quadrangle_count(msh, &nq); - + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); SMDS_MeshNode** nodes = new SMDS_MeshNode*[nv+1]; bool* tags = new bool[nv+1]; + /* enumerated vertices */ for(int iv=1;iv<=nv;iv++) { mesh_get_vertex_coordinates(msh, iv, xyz); - mesh_get_vertex_tag(msh, iv, &tag); + mesh_get_vertex_tag(msh, iv, &tag); + // Issue 0020656. Use vertex coordinates + if ( tag > 0 && tag <= pmap.Extent() ) { + TopoDS_Vertex v = TopoDS::Vertex(pmap(tag)); + double tol = BRep_Tool::Tolerance( v ); + gp_Pnt p = BRep_Tool::Pnt( v ); + if ( p.IsEqual( gp_Pnt( xyz[0], xyz[1], xyz[2]), 2*tol)) + xyz[0] = p.X(), xyz[1] = p.Y(), xyz[2] = p.Z(); + else + tag = 0; // enforced or attracted vertex + } nodes[iv] = meshDS->AddNode(xyz[0], xyz[1], xyz[2]); + + // Create group of enforced vertices if requested + BLSURFPlugin_Hypothesis::TEnfVertexCoords projVertex; + projVertex.clear(); + projVertex.push_back((double)xyz[0]); + projVertex.push_back((double)xyz[1]); + projVertex.push_back((double)xyz[2]); + std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexList >::const_iterator enfCoordsIt = EnfVertexCoords2EnfVertexList.find(projVertex); + if (enfCoordsIt != EnfVertexCoords2EnfVertexList.end()) { + MESSAGE("Found enforced vertex @ " << xyz[0] << ", " << xyz[1] << ", " << xyz[2]); + BLSURFPlugin_Hypothesis::TEnfVertexList::const_iterator enfListIt = enfCoordsIt->second.begin(); + BLSURFPlugin_Hypothesis::TEnfVertex *currentEnfVertex; + for (; enfListIt != enfCoordsIt->second.end(); ++enfListIt) { + currentEnfVertex = (*enfListIt); + if (currentEnfVertex->grpName != "") { + bool groupDone = false; + SMESH_Mesh::GroupIteratorPtr grIt = aMesh.GetGroups(); + MESSAGE("currentEnfVertex->grpName: " << currentEnfVertex->grpName); + MESSAGE("Parsing the groups of the mesh"); + while (grIt->more()) { + SMESH_Group * group = grIt->next(); + if ( !group ) continue; + MESSAGE("Group: " << group->GetName()); + SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + if ( !groupDS ) continue; + MESSAGE("group->SMDSGroup().GetType(): " << (groupDS->GetType())); + MESSAGE("group->SMDSGroup().GetType()==SMDSAbs_Node: " << (groupDS->GetType()==SMDSAbs_Node)); + MESSAGE("currentEnfVertex->grpName.compare(group->GetStoreName())==0: " << (currentEnfVertex->grpName.compare(group->GetName())==0)); + if ( groupDS->GetType()==SMDSAbs_Node && currentEnfVertex->grpName.compare(group->GetName())==0) { + SMESHDS_Group* aGroupDS = static_cast( groupDS ); + aGroupDS->SMDSGroup().Add(nodes[iv]); + MESSAGE("Node ID: " << nodes[iv]->GetID()); + // How can I inform the hypothesis ? +// _hypothesis->AddEnfVertexNodeID(currentEnfVertex->grpName,nodes[iv]->GetID()); + groupDone = true; + MESSAGE("Successfully added enforced vertex to existing group " << currentEnfVertex->grpName); + break; + } + } + if (!groupDone) + { + int groupId; + SMESH_Group* aGroup = aMesh.AddGroup(SMDSAbs_Node, currentEnfVertex->grpName.c_str(), groupId); + aGroup->SetName( currentEnfVertex->grpName.c_str() ); + SMESHDS_Group* aGroupDS = static_cast( aGroup->GetGroupDS() ); + aGroupDS->SMDSGroup().Add(nodes[iv]); + MESSAGE("Successfully created enforced vertex group " << currentEnfVertex->grpName); + groupDone = true; + } + if (!groupDone) + throw SALOME_Exception(LOCALIZED("An enforced vertex node was not added to a group")); + } + else + MESSAGE("Group name is empty: '"<grpName<<"' => group is not created"); + } + } + + // internal point are tagged to zero - if(tag){ + if(tag > 0 && tag <= pmap.Extent() ){ meshDS->SetNodeOnVertex(nodes[iv], TopoDS::Vertex(pmap(tag))); tags[iv] = false; } else { @@ -421,27 +1821,28 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) } } + /* enumerate edges */ for(int it=1;it<=ne;it++) { - mesh_get_edge_vertices(msh, it, vtx); - SMDS_MeshEdge* edg = meshDS->AddEdge(nodes[vtx[0]], nodes[vtx[1]]); - mesh_get_edge_tag(msh, it, &tag); + mesh_get_edge_vertices(msh, it, vtx); + mesh_get_edge_tag(msh, it, &tag); if (tags[vtx[0]]) { - meshDS->SetNodeOnEdge(nodes[vtx[0]], TopoDS::Edge(emap(tag))); + Set_NodeOnEdge(meshDS, nodes[vtx[0]], emap(tag)); tags[vtx[0]] = false; }; if (tags[vtx[1]]) { - meshDS->SetNodeOnEdge(nodes[vtx[1]], TopoDS::Edge(emap(tag))); + Set_NodeOnEdge(meshDS, nodes[vtx[1]], emap(tag)); tags[vtx[1]] = false; }; + SMDS_MeshEdge* edg = helper.AddEdge(nodes[vtx[0]], nodes[vtx[1]]); meshDS->SetMeshElementOnShape(edg, TopoDS::Edge(emap(tag))); - } + /* enumerate triangles */ for(int it=1;it<=nt;it++) { mesh_get_triangle_vertices(msh, it, vtx); - SMDS_MeshFace* tri = meshDS->AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]]); - mesh_get_triangle_tag(msh, it, &tag); + SMDS_MeshFace* tri = helper.AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]]); + mesh_get_triangle_tag(msh, it, &tag); meshDS->SetMeshElementOnShape(tri, TopoDS::Face(fmap(tag))); if (tags[vtx[0]]) { meshDS->SetNodeOnFace(nodes[vtx[0]], TopoDS::Face(fmap(tag))); @@ -457,10 +1858,11 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) }; } + /* enumerate quadrangles */ for(int it=1;it<=nq;it++) { mesh_get_quadrangle_vertices(msh, it, vtx); - SMDS_MeshFace* quad = meshDS->AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]], nodes[vtx[3]]); - mesh_get_quadrangle_tag(msh, it, &tag); + SMDS_MeshFace* quad = helper.AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]], nodes[vtx[3]]); + mesh_get_quadrangle_tag(msh, it, &tag); meshDS->SetMeshElementOnShape(quad, TopoDS::Face(fmap(tag))); if (tags[vtx[0]]) { meshDS->SetNodeOnFace(nodes[vtx[0]], TopoDS::Face(fmap(tag))); @@ -480,30 +1882,131 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) }; } - delete nodes; + // SetIsAlwaysComputed( true ) to sub-meshes of degenerated EDGEs + TopLoc_Location loc; double f,l; + for (int i = 1; i <= emap.Extent(); i++) + if ( BRep_Tool::Curve(TopoDS::Edge( emap( i )), loc, f,l).IsNull() ) + if ( SMESH_subMesh* sm = aMesh.GetSubMeshContaining( emap( i ))) + sm->SetIsAlwaysComputed( true ); + for (int i = 1; i <= pmap.Extent(); i++) + if ( SMESH_subMesh* sm = aMesh.GetSubMeshContaining( pmap( i ))) + if ( !sm->IsMeshComputed() ) + sm->SetIsAlwaysComputed( true ); + + if ( needMerge ) + { + set< SMESH_subMesh* >::iterator smIt = edgeSubmeshes.begin(); + for ( ; smIt != edgeSubmeshes.end(); ++smIt ) + { + SMESH_subMesh* sm = *smIt; + SMESH_subMeshIteratorPtr subsmIt = sm->getDependsOnIterator( /*includeSelf=*/true, + /*complexFirst=*/false); + TIDSortedNodeSet nodesOnEdge; + double mergeTolerance = 1e-7, tol; + while ( subsmIt->more() ) + { + // get nodes from an edge + sm = subsmIt->next(); + if ( SMESHDS_SubMesh* smDS = sm->GetSubMeshDS() ) + { + SMDS_NodeIteratorPtr nIt = smDS->GetNodes(); + while ( nIt->more() ) + nodesOnEdge.insert( nIt->next() ); + } + // get max tolerance + TopoDS_Shape subShape = sm->GetSubShape(); + if ( subShape.ShapeType() == TopAbs_EDGE ) + tol = BRep_Tool::Tolerance( TopoDS::Edge( subShape )); + else + tol = BRep_Tool::Tolerance( TopoDS::Vertex( subShape )); + mergeTolerance = Max( tol, mergeTolerance ); + } + // find nodes to merge + SMESH_MeshEditor::TListOfListOfNodes nodeGroupsToMerge; + SMESH_MeshEditor editor( &aMesh ); + editor.FindCoincidentNodes( nodesOnEdge, mergeTolerance*2, nodeGroupsToMerge ); + // merge + editor.MergeNodes( nodeGroupsToMerge ); + } + } + + delete [] nodes; /* release the mesh object */ blsurf_data_regain_mesh(bls, msh); - /* clean up everything */ - blsurf_session_delete(bls); - cad_delete(c); - - context_delete(ctx); - // Issue 0019864. On DebianSarge, FE signals do not obey to OSD::SetSignal(false) #ifndef WNT - if ( oldFEFlags > 0 ) + if ( oldFEFlags > 0 ) feenableexcept( oldFEFlags ); feclearexcept( FE_ALL_EXCEPT ); #endif + /* + std::cout << "FacesWithSizeMap" << std::endl; + FacesWithSizeMap.Statistics(std::cout); + std::cout << "EdgesWithSizeMap" << std::endl; + EdgesWithSizeMap.Statistics(std::cout); + std::cout << "VerticesWithSizeMap" << std::endl; + VerticesWithSizeMap.Statistics(std::cout); + std::cout << "FacesWithEnforcedVertices" << std::endl; + FacesWithEnforcedVertices.Statistics(std::cout); + */ + + MESSAGE("END OF BLSURFPlugin_BLSURF::Compute()"); return true; } +#ifdef WITH_SMESH_CANCEL_COMPUTE +void BLSURFPlugin_BLSURF::CancelCompute() +{ + _compute_canceled = true; +} +#endif + +//============================================================================= +/*! + * SetNodeOnEdge + */ +//============================================================================= + +void BLSURFPlugin_BLSURF::Set_NodeOnEdge(SMESHDS_Mesh* meshDS, SMDS_MeshNode* node, const TopoDS_Shape& ed) { + const TopoDS_Edge edge = TopoDS::Edge(ed); + + gp_Pnt pnt(node->X(), node->Y(), node->Z()); + + Standard_Real p0 = 0.0; + Standard_Real p1 = 1.0; + TopLoc_Location loc; + Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, loc, p0, p1); + + if ( !loc.IsIdentity() ) pnt.Transform( loc.Transformation().Inverted() ); + GeomAPI_ProjectPointOnCurve proj(pnt, curve, p0, p1); + + double pa = 0.; + if ( proj.NbPoints() > 0 ) + { + pa = (double)proj.LowerDistanceParameter(); + // Issue 0020656. Move node if it is too far from edge + gp_Pnt curve_pnt = curve->Value( pa ); + double dist2 = pnt.SquareDistance( curve_pnt ); + double tol = BRep_Tool::Tolerance( edge ); + if ( 1e-14 < dist2 && dist2 <= 1000*tol ) // large enough and within tolerance + { + curve_pnt.Transform( loc ); + meshDS->MoveNode( node, curve_pnt.X(), curve_pnt.Y(), curve_pnt.Z() ); + } + } +// GProp_GProps LProps; +// BRepGProp::LinearProperties(ed, LProps); +// double lg = (double)LProps.Mass(); + + meshDS->SetNodeOnEdge(node, edge, pa); +} + //============================================================================= /*! - * + * */ //============================================================================= @@ -514,7 +2017,7 @@ ostream & BLSURFPlugin_BLSURF::SaveTo(ostream & save) //============================================================================= /*! - * + * */ //============================================================================= @@ -525,7 +2028,7 @@ istream & BLSURFPlugin_BLSURF::LoadFrom(istream & load) //============================================================================= /*! - * + * */ //============================================================================= @@ -536,7 +2039,7 @@ ostream & operator << (ostream & save, BLSURFPlugin_BLSURF & hyp) //============================================================================= /*! - * + * */ //============================================================================= @@ -545,34 +2048,61 @@ istream & operator >> (istream & load, BLSURFPlugin_BLSURF & hyp) return hyp.LoadFrom( load ); } +/* Curve definition function See cad_curv_t in file distene/cad.h for + * more information. + * NOTE : if when your CAD systems evaluates second + * order derivatives it also computes first order derivatives and + * function evaluation, you can optimize this example by making only + * one CAD call and filling the necessary uv, dt, dtt arrays. + */ status_t curv_fun(real t, real *uv, real *dt, real *dtt, void *user_data) { + /* t is given. It contains the t (time) 1D parametric coordintaes + of the point PreCAD/BLSurf is querying on the curve */ + + /* user_data identifies the edge PreCAD/BLSurf is querying + * (see cad_edge_new later in this example) */ const Geom2d_Curve*pargeo = (const Geom2d_Curve*) user_data; if (uv){ + /* BLSurf is querying the function evaluation */ gp_Pnt2d P; P=pargeo->Value(t); uv[0]=P.X(); uv[1]=P.Y(); } if(dt) { + /* query for the first order derivatives */ gp_Vec2d V1; V1=pargeo->DN(t,1); dt[0]=V1.X(); dt[1]=V1.Y(); } if(dtt){ + /* query for the second order derivatives */ gp_Vec2d V2; V2=pargeo->DN(t,2); dtt[0]=V2.X(); dtt[1]=V2.Y(); } - return 0; + return STATUS_OK; } +/* Surface definition function. + * See cad_surf_t in file distene/cad.h for more information. + * NOTE : if when your CAD systems evaluates second order derivatives it also + * computes first order derivatives and function evaluation, you can optimize + * this example by making only one CAD call and filling the necessary xyz, du, dv, etc.. + * arrays. + */ status_t surf_fun(real *uv, real *xyz, real*du, real *dv, - real *duu, real *duv, real *dvv, void *user_data) + real *duu, real *duv, real *dvv, void *user_data) { + /* uv[2] is given. It contains the u,v coordinates of the point + * PreCAD/BLSurf is querying on the surface */ + + /* user_data identifies the face PreCAD/BLSurf is querying (see + * cad_face_new later in this example)*/ const Geom_Surface* geometry = (const Geom_Surface*) user_data; if(xyz){ @@ -584,33 +2114,169 @@ status_t surf_fun(real *uv, real *xyz, real*du, real *dv, if(du && dv){ gp_Pnt P; gp_Vec D1U,D1V; - + geometry->D1(uv[0],uv[1],P,D1U,D1V); du[0]=D1U.X(); du[1]=D1U.Y(); du[2]=D1U.Z(); dv[0]=D1V.X(); dv[1]=D1V.Y(); dv[2]=D1V.Z(); } if(duu && duv && dvv){ + gp_Pnt P; gp_Vec D1U,D1V; gp_Vec D2U,D2V,D2UV; - + geometry->D2(uv[0],uv[1],P,D1U,D1V,D2U,D2V,D2UV); duu[0]=D2U.X(); duu[1]=D2U.Y(); duu[2]=D2U.Z(); duv[0]=D2UV.X(); duv[1]=D2UV.Y(); duv[2]=D2UV.Z(); - dvv[0]=D2V.X(); dvv[1]=D2V.Y(); dvv[2]=D2V.Z(); + dvv[0]=D2V.X(); dvv[1]=D2V.Y(); dvv[2]=D2V.Z(); } - return 0; + return STATUS_OK; } -status_t message_callback(message_t *msg, void *user_data) + +status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data) +{ + if (face_id == 1) { + if (my_u_min > uv[0]) { + my_u_min = uv[0]; + } + if (my_v_min > uv[1]) { + my_v_min = uv[1]; + } + if (my_u_max < uv[0]) { + my_u_max = uv[0]; + } + if (my_v_max < uv[1]) { + my_v_max = uv[1]; + } + } + //MESSAGE("size_on_surface") + if (FaceId2PythonSmp.count(face_id) != 0){ + //MESSAGE("A size map is used to calculate size on face : "<Empty()) + double result = FaceIndex2ClassAttractor[face_id]->GetSize(uv[0],uv[1]); + *size = result; + // MESSAGE("f(" << uv[0] << "," << uv[1] << ")" << " = " << result); + } + else { + // MESSAGE("List of attractor is empty !!!") + *size = *((double*)user_data); + } + return STATUS_OK; +} + +status_t size_on_edge(integer edge_id, real t, real *size, void *user_data) +{ + if (EdgeId2PythonSmp.count(edge_id) != 0){ + PyObject * pyresult = NULL; + PyObject* new_stderr = NULL; + assert(Py_IsInitialized()); + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + pyresult = PyObject_CallFunction(EdgeId2PythonSmp[edge_id],(char*)"(f)",t); + double result; + if ( pyresult == NULL){ + fflush(stderr); + string err_description=""; + new_stderr = newPyStdOut(err_description); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + MESSAGE("Can't evaluate f(" << t << ")" << " error is " << err_description); + result = *((double*)user_data); + } + else { + result = PyFloat_AsDouble(pyresult); + Py_DECREF(pyresult); + } + *size = result; + PyGILState_Release(gstate); + } + else { + *size = *((double*)user_data); + } + return STATUS_OK; +} + +status_t size_on_vertex(integer point_id, real *size, void *user_data) +{ + if (VertexId2PythonSmp.count(point_id) != 0){ + PyObject * pyresult = NULL; + PyObject* new_stderr = NULL; + assert(Py_IsInitialized()); + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + pyresult = PyObject_CallFunction(VertexId2PythonSmp[point_id],(char*)""); + double result; + if ( pyresult == NULL){ + fflush(stderr); + string err_description=""; + new_stderr = newPyStdOut(err_description); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + MESSAGE("Can't evaluate f()" << " error is " << err_description); + result = *((double*)user_data); + } + else { + result = PyFloat_AsDouble(pyresult); + Py_DECREF(pyresult); + } + *size = result; + PyGILState_Release(gstate); + } + else { + *size = *((double*)user_data); + } + return STATUS_OK; +} + +/* + * The following function will be called for PreCAD/BLSurf message + * printing. See context_set_message_callback (later in this + * template) for how to set user_data. + */ +status_t message_cb(message_t *msg, void *user_data) { integer errnumber = 0; char *desc; message_get_number(msg, &errnumber); message_get_description(msg, &desc); - if ( errnumber < 0 ) { + string err( desc ); + if ( errnumber < 0 || err.find("license") != string::npos ) { string * error = (string*)user_data; // if ( !error->empty() ) // *error += "\n"; @@ -621,7 +2287,234 @@ status_t message_callback(message_t *msg, void *user_data) error->append( desc, len ); } else { - cout << desc; + std::cout << desc << std::endl; } return STATUS_OK; } + +/* This is the interrupt callback. PreCAD/BLSurf will call this + * function regularily. See the file distene/interrupt.h + */ +status_t interrupt_cb(integer *interrupt_status, void *user_data) +{ + integer you_want_to_continue = 1; +#ifdef WITH_SMESH_CANCEL_COMPUTE + BLSURFPlugin_BLSURF* tmp = (BLSURFPlugin_BLSURF*)user_data; + you_want_to_continue = !tmp->computeCanceled(); +#endif + + if(you_want_to_continue) + { + *interrupt_status = INTERRUPT_CONTINUE; + return STATUS_OK; + } + else /* you want to stop BLSurf */ + { + *interrupt_status = INTERRUPT_STOP; + return STATUS_ERROR; + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= +bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + int _physicalMesh = BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh(); + double _phySize = BLSURFPlugin_Hypothesis::GetDefaultPhySize(); + //int _geometricMesh = BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh(); + //double _angleMeshS = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshS(); + double _angleMeshC = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshC(); + bool _quadAllowed = BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed(); + if(_hypothesis) { + _physicalMesh = (int) _hypothesis->GetPhysicalMesh(); + _phySize = _hypothesis->GetPhySize(); + //_geometricMesh = (int) hyp->GetGeometricMesh(); + //_angleMeshS = hyp->GetAngleMeshS(); + _angleMeshC = _hypothesis->GetAngleMeshC(); + _quadAllowed = _hypothesis->GetQuadAllowed(); + } + + bool IsQuadratic = false; + + // ---------------- + // evaluate 1D + // ---------------- + TopTools_DataMapOfShapeInteger EdgesMap; + double fullLen = 0.0; + double fullNbSeg = 0; + for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) { + TopoDS_Edge E = TopoDS::Edge( exp.Current() ); + if( EdgesMap.IsBound(E) ) + continue; + SMESH_subMesh *sm = aMesh.GetSubMesh(E); + double aLen = SMESH_Algo::EdgeLength(E); + fullLen += aLen; + int nb1d = 0; + if(_physicalMesh==1) { + nb1d = (int)( aLen/_phySize + 1 ); + } + else { + // use geometry + double f,l; + Handle(Geom_Curve) C = BRep_Tool::Curve(E,f,l); + double fullAng = 0.0; + double dp = (l-f)/200; + gp_Pnt P1,P2,P3; + C->D0(f,P1); + C->D0(f+dp,P2); + gp_Vec V1(P1,P2); + for(int j=2; j<=200; j++) { + C->D0(f+dp*j,P3); + gp_Vec V2(P2,P3); + fullAng += fabs(V1.Angle(V2)); + V1 = V2; + P2 = P3; + } + nb1d = (int)( fullAng/_angleMeshC + 1 ); + } + fullNbSeg += nb1d; + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i 0 ) { + aVec[SMDSEntity_Node] = 2*nb1d - 1; + aVec[SMDSEntity_Quad_Edge] = nb1d; + } + else { + aVec[SMDSEntity_Node] = nb1d - 1; + aVec[SMDSEntity_Edge] = nb1d; + } + aResMap.insert(std::make_pair(sm,aVec)); + EdgesMap.Bind(E,nb1d); + } + double ELen = fullLen/fullNbSeg; + // ---------------- + // evaluate 2D + // ---------------- + // try to evaluate as in MEFISTO + for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { + TopoDS_Face F = TopoDS::Face( exp.Current() ); + SMESH_subMesh *sm = aMesh.GetSubMesh(F); + GProp_GProps G; + BRepGProp::SurfaceProperties(F,G); + double anArea = G.Mass(); + int nb1d = 0; + std::vector nb1dVec; + for (TopExp_Explorer exp1(F,TopAbs_EDGE); exp1.More(); exp1.Next()) { + int nbSeg = EdgesMap.Find(exp1.Current()); + nb1d += nbSeg; + nb1dVec.push_back( nbSeg ); + } + int nbQuad = 0; + int nbTria = (int) ( anArea/( ELen*ELen*sqrt(3.) / 4 ) ); + int nbNodes = (int) ( ( nbTria*3 - (nb1d-1)*2 ) / 6 + 1 ); + if ( _quadAllowed ) + { + if ( nb1dVec.size() == 4 ) // quadrangle geom face + { + int n1 = nb1dVec[0], n2 = nb1dVec[ nb1dVec[1] == nb1dVec[0] ? 2 : 1 ]; + nbQuad = n1 * n2; + nbNodes = (n1 + 1) * (n2 + 1); + nbTria = 0; + } + else + { + nbTria = nbQuad = nbTria / 3 + 1; + } + } + std::vector aVec(SMDSEntity_Last,0); + if( IsQuadratic ) { + int nb1d_in = (nbTria*3 - nb1d) / 2; + aVec[SMDSEntity_Node] = nbNodes + nb1d_in; + aVec[SMDSEntity_Quad_Triangle] = nbTria; + aVec[SMDSEntity_Quad_Quadrangle] = nbQuad; + } + else { + aVec[SMDSEntity_Node] = nbNodes; + aVec[SMDSEntity_Triangle] = nbTria; + aVec[SMDSEntity_Quadrangle] = nbQuad; + } + aResMap.insert(std::make_pair(sm,aVec)); + } + + // ---------------- + // evaluate 3D + // ---------------- + GProp_GProps G; + BRepGProp::VolumeProperties(aShape,G); + double aVolume = G.Mass(); + double tetrVol = 0.1179*ELen*ELen*ELen; + int nbVols = int(aVolume/tetrVol); + int nb1d_in = int(( nbVols*6 - fullNbSeg ) / 6 ); + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i 0x06040000 // Porting to OCCT6.5.1 + Standard_Real d = myExtrem.SquareDistance(i); +#else + Standard_Real d = myExtrem.Value(i); + d = Abs(d); +#endif + if (d <= MaxDist) { + MaxDist = d; + indice = i; + } + } + } + if (indice) { + gp_Pnt2d Puv; + Standard_Real U1,U2; + myExtrem.Point(indice).Parameter(U1, U2); + Puv.SetCoord(U1, U2); + fc->Perform(face, Puv, Tol); + } + else { + fc->Perform(face, gp_Pnt2d(U1-1.0,V1 - 1.0), Tol); //-- NYI etc BUG PAS BEAU En attendant l acces a rejected + //-- le resultat est TopAbs_OUT; + } +} diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.hxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.hxx index 8dd022f..3067dc4 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.hxx @@ -1,38 +1,77 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_BLSURF.hxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) // & Aurelien ALLEAUME (DISTENE) +// Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- // #ifndef _BLSURFPlugin_BLSURF_HXX_ #define _BLSURFPlugin_BLSURF_HXX_ +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_FINITE +#undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined +#endif +// rnv: avoid compilation warning on Linux : "_POSIX_C_SOURCE" and "_XOPEN_SOURCE" are redefined +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#ifdef _XOPEN_SOURCE +#undef _XOPEN_SOURCE +#endif + +#include #include "SMESH_2D_Algo.hxx" #include "SMESH_Mesh.hxx" +#include +#include +#include +#include +#include +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(GEOM_Gen) #include "Utils_SALOME_Exception.hxx" + extern "C"{ +#include "distene/blsurf.h" #include "distene/api.h" +#include "distene/precad.h" } -class BLSURFPlugin_Hypothesis; +#include +#include +#include +#include + +#include "BLSURFPlugin_Hypothesis.hxx" + +class TopoDS_Shape; class BLSURFPlugin_BLSURF: public SMESH_2D_Algo { public: @@ -44,10 +83,18 @@ class BLSURFPlugin_BLSURF: public SMESH_2D_Algo { const TopoDS_Shape& aShape, SMESH_Hypothesis::Hypothesis_Status& aStatus); - void SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsurf_session_t *bls); + void SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsurf_session_t *bls, precad_session_t *pcs, SMESH_Mesh& aMesh, bool *use_precad); virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); +#ifdef WITH_SMESH_CANCEL_COMPUTE + virtual void CancelCompute(); + bool computeCanceled() { return _compute_canceled;}; +#endif + + virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap); + ostream & SaveTo(ostream & save); istream & LoadFrom(istream & load); friend ostream & operator << (ostream & save, BLSURFPlugin_BLSURF & hyp); @@ -55,6 +102,22 @@ class BLSURFPlugin_BLSURF: public SMESH_2D_Algo { protected: const BLSURFPlugin_Hypothesis* _hypothesis; + + private: + TopoDS_Shape entryToShape(std::string entry); + void createEnforcedVertexOnFace(TopoDS_Shape FaceShape, BLSURFPlugin_Hypothesis::TEnfVertexList enfVertexList); + void Set_NodeOnEdge(SMESHDS_Mesh* meshDS, SMDS_MeshNode* node, const TopoDS_Shape& ed); + void BRepClass_FaceClassifierPerform(BRepClass_FaceClassifier* fc, const TopoDS_Face& face, const gp_Pnt& P, const Standard_Real Tol); + + private: + PyObject * main_mod; + PyObject * main_dict; + SALOMEDS::Study_var myStudy; + SMESH_Gen_i* smeshGen_i; + +#ifdef WITH_SMESH_CANCEL_COMPUTE + volatile bool _compute_canceled; +#endif }; #endif diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.cxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.cxx index 24fa3c2..68750c7 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.cxx @@ -1,21 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_BLSURF_i.cxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) @@ -36,8 +37,8 @@ //============================================================================= BLSURFPlugin_BLSURF_i::BLSURFPlugin_BLSURF_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 ), @@ -45,8 +46,8 @@ BLSURFPlugin_BLSURF_i::BLSURFPlugin_BLSURF_i( PortableServer::POA_ptr thePOA, { MESSAGE( "BLSURFPlugin_BLSURF_i::BLSURFPlugin_BLSURF_i" ); myBaseImpl = new ::BLSURFPlugin_BLSURF( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.hxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.hxx index 85bb614..97885cf 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF_i.hxx @@ -1,21 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_BLSURF_i.hxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) @@ -40,8 +41,8 @@ class BLSURFPlugin_BLSURF_i: public: // Constructor BLSURFPlugin_BLSURF_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ); + int theStudyId, + ::SMESH_Gen* theGenImpl ); // Destructor virtual ~BLSURFPlugin_BLSURF_i(); diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx index ad35365..1856a70 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx @@ -1,130 +1,173 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_Hypothesis.cxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) // & Aurelien ALLEAUME (DISTENE) +// Size maps development: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- // -#include +#include "BLSURFPlugin_Hypothesis.hxx" +#include "BLSURFPlugin_Attractor.hxx" +#include "SMESH_Gen_i.hxx" #include +#include +#include +#include + +// cascade include +#include "ShapeAnalysis.hxx" + +// CORBA includes +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(GEOM_Gen) //============================================================================= -BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis (int hypId, int studyId, - SMESH_Gen * gen) - : SMESH_Hypothesis(hypId, studyId, gen), - _topology(GetDefaultTopology()), - _physicalMesh(GetDefaultPhysicalMesh()), - _phySize(GetDefaultPhySize()), - _phyMax(GetDefaultMaxSize()), - _phyMin(GetDefaultMinSize()), - _hgeoMax(GetDefaultMaxSize()), - _hgeoMin(GetDefaultMinSize()), - _geometricMesh(GetDefaultGeometricMesh()), - _angleMeshS(GetDefaultAngleMeshS()), - _angleMeshC(GetDefaultAngleMeshC()), - _gradation(GetDefaultGradation()), - _quadAllowed(GetDefaultQuadAllowed()), - _decimesh(GetDefaultDecimesh()), - _verb( GetDefaultVerbosity() ) +BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen) : + SMESH_Hypothesis(hypId, studyId, gen), _topology(GetDefaultTopology()), + _physicalMesh(GetDefaultPhysicalMesh()), + _phySize(GetDefaultPhySize()), + _phyMax(GetDefaultMaxSize()), + _phyMin(GetDefaultMinSize()), + _hgeoMax(GetDefaultMaxSize()), + _hgeoMin(GetDefaultMinSize()), + _geometricMesh(GetDefaultGeometricMesh()), + _angleMeshS(GetDefaultAngleMeshS()), + _angleMeshC(GetDefaultAngleMeshC()), + _gradation(GetDefaultGradation()), + _quadAllowed(GetDefaultQuadAllowed()), + _decimesh(GetDefaultDecimesh()), + _verb(GetDefaultVerbosity()), + _preCADMergeEdges(GetDefaultPreCADMergeEdges()), + _preCADRemoveNanoEdges(GetDefaultPreCADRemoveNanoEdges()), + _preCADDiscardInput(GetDefaultPreCADDiscardInput()), + _preCADEpsNano(GetDefaultPreCADEpsNano()), + _sizeMap(GetDefaultSizeMap()), + _attractors(GetDefaultSizeMap()), + _classAttractors(GetDefaultAttractorMap()), + _faceEntryEnfVertexListMap(GetDefaultFaceEntryEnfVertexListMap()), + _enfVertexList(GetDefaultEnfVertexList()), + _faceEntryCoordsListMap(GetDefaultFaceEntryCoordsListMap()), + _coordsEnfVertexMap(GetDefaultCoordsEnfVertexMap()), + _faceEntryEnfVertexEntryListMap(GetDefaultFaceEntryEnfVertexEntryListMap()), + _enfVertexEntryEnfVertexMap(GetDefaultEnfVertexEntryEnfVertexMap()), + _groupNameNodeIDMap(GetDefaultGroupNameNodeIDMap()), + _GMFFileName(GetDefaultGMFFile()), + _enforcedInternalVerticesAllFaces(GetDefaultInternalEnforcedVertex()) { _name = "BLSURF_Parameters"; _param_algo_dim = 2; - - // to desable writing boundaries - //_phyMin = _phyMax = _hgeoMin = _hgeoMax = undefinedDouble(); +// _GMFFileMode = false; // GMF ascii mode + + // to disable writing boundaries + //_phyMin = _phyMax = _hgeoMin = _hgeoMax = undefinedDouble(); + - const char* intOptionNames[] = { - "addsurf_ivertex", - "background", - "CheckAdjacentEdges", - "CheckCloseEdges", - "CheckWellDefined", - "coiter", - "communication", - "decim", - "export_flag", - "file_h", - "frontal", - "gridnu", - "gridnv", - "hinterpol_flag", - "hmean_flag", - "intermedfile", - "memory", - "normals", - "optim", - "pardom_flag", - "pinch", - "refs", - "rigid", - "surforient", - "tconf", - "topo_collapse", - "" // mark of end - }; - const char* doubleOptionNames[] = { - "addsurf_angle", - "addsurf_R", - "addsurf_H", - "addsurf_FG", - "addsurf_r", - "addsurf_PA", - "angle_compcurv", - "angle_ridge", - "CoefRectangle", - "eps_collapse", - "eps_ends", - "eps_pardom", - "LSS", - "topo_eps1", - "topo_eps2", - "" // mark of end - }; - const char* charOptionNames[] = { - "export_format", - "export_option", - "import_option", - "prefix", - "" // mark of end - }; + const char* intOptionNames[] = { "addsurf_ivertex", "anisotropic", "background", "CheckAdjacentEdges", "CheckCloseEdges", + "CheckWellDefined", "coiter", "communication", "debug", "decim", "export_flag", "file_h", "frontal", "gridnu", "gridnv", + "hinterpol_flag", "hmean_flag", "intermedfile", "memory", "normals", "optim", "pardom_flag", "pinch", "refs", + "rigid", "surforient", "tconf", "topo_collapse", + "proximity", "prox_nb_layer", "prox_ratio", // detects the volumic proximity of surfaces + "" // mark of end + }; + const char* doubleOptionNames[] = { "addsurf_angle", "addsurf_R", "addsurf_H", "addsurf_FG", "addsurf_r", + "addsurf_PA", "angle_compcurv", "angle_ridge", "anisotropic_ratio", "CoefRectangle", "eps_collapse", "eps_ends", "eps_pardom", "LSS", + "topo_eps1", "topo_eps2", "" // mark of end + }; + const char* charOptionNames[] = { "export_format", "export_option", "import_option", "prefix", "" // mark of end + }; + // PreCAD advanced options + const char* preCADintOptionNames[] = { "closed_geometry", "debug", "manifold_geometry", "create_tag_on_collision","" // mark of end + }; + const char* preCADdoubleOptionNames[] = { "eps_nano_relative", "eps_sewing", "eps_sewing_relative", "periodic_tolerance", + "periodic_tolerance_relative", "periodic_split_tolerance", "periodic_split_tolerance_relative", "" // mark of end + }; + int i = 0; - while ( intOptionNames[i][0] ) - _option2value[ intOptionNames[i++] ].clear(); + while (intOptionNames[i][0]) + _option2value[intOptionNames[i++]].clear(); + + i = 0; + while (preCADintOptionNames[i][0]) + _preCADoption2value[preCADintOptionNames[i++]].clear(); i = 0; - while ( doubleOptionNames[i][0] ) { - _doubleOptions.insert( doubleOptionNames[i] ); - _option2value[ doubleOptionNames[i++] ].clear(); + while (doubleOptionNames[i][0]) { + _doubleOptions.insert(doubleOptionNames[i]); + _option2value[doubleOptionNames[i++]].clear(); } i = 0; - while ( charOptionNames[i][0] ) { - _charOptions.insert( charOptionNames[i] ); - _option2value[ charOptionNames[i++] ].clear(); + while (preCADdoubleOptionNames[i][0]) { + _preCADdoubleOptions.insert(preCADdoubleOptionNames[i]); + _preCADoption2value[preCADdoubleOptionNames[i++]].clear(); + } + i = 0; + while (charOptionNames[i][0]) { + _charOptions.insert(charOptionNames[i]); + _option2value[charOptionNames[i++]].clear(); + } + + + + _sizeMap.clear(); + _attractors.clear(); + _faceEntryEnfVertexListMap.clear(); + _enfVertexList.clear(); + _faceEntryCoordsListMap.clear(); + _coordsEnfVertexMap.clear(); + _faceEntryEnfVertexEntryListMap.clear(); + _enfVertexEntryEnfVertexMap.clear(); + _groupNameNodeIDMap.clear(); + + /* TODO GROUPS + _groupNameEnfVertexListMap.clear(); + _enfVertexGroupNameMap.clear(); + */ +} + +TopoDS_Shape BLSURFPlugin_Hypothesis::entryToShape(std::string entry) +{ + MESSAGE("BLSURFPlugin_Hypothesis::entryToShape "<GetCurrentStudy(); + + TopoDS_Shape S = TopoDS_Shape(); + SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() ); + 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 = myStudy->ConvertIORToObject(aVal); + aGeomObj = GEOM::GEOM_Object::_narrow(obj); } + if ( !aGeomObj->_is_nil() ) + S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); + return S; } //============================================================================= -void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology) -{ +void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology) { if (theTopology != _topology) { _topology = theTopology; NotifySubMeshesHypothesisModification(); @@ -132,32 +175,28 @@ void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetPhysicalMesh(PhysicalMesh thePhysicalMesh) -{ +void BLSURFPlugin_Hypothesis::SetPhysicalMesh(PhysicalMesh thePhysicalMesh) { if (thePhysicalMesh != _physicalMesh) { _physicalMesh = thePhysicalMesh; - switch( _physicalMesh ) { - case DefaultSize: - default: - _phySize = GetDefaultPhySize(); - break; - } NotifySubMeshesHypothesisModification(); } } //============================================================================= -void BLSURFPlugin_Hypothesis::SetPhySize(double theVal) -{ +void BLSURFPlugin_Hypothesis::SetPhySize(double theVal) { if (theVal != _phySize) { - _phySize = theVal; + if (theVal == 0) { + _phySize = GetPhyMax(); + MESSAGE("Warning: nul physical size is not allowed"); + } + else + _phySize = theVal; NotifySubMeshesHypothesisModification(); } } //============================================================================= -void BLSURFPlugin_Hypothesis::SetPhyMin(double theMinSize) -{ +void BLSURFPlugin_Hypothesis::SetPhyMin(double theMinSize) { if (theMinSize != _phyMin) { _phyMin = theMinSize; NotifySubMeshesHypothesisModification(); @@ -165,18 +204,15 @@ void BLSURFPlugin_Hypothesis::SetPhyMin(double theMinSize) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetPhyMax(double theMaxSize) -{ +void BLSURFPlugin_Hypothesis::SetPhyMax(double theMaxSize) { if (theMaxSize != _phyMax) { _phyMax = theMaxSize; NotifySubMeshesHypothesisModification(); } } - //============================================================================= -void BLSURFPlugin_Hypothesis::SetGeoMin(double theMinSize) -{ +void BLSURFPlugin_Hypothesis::SetGeoMin(double theMinSize) { if (theMinSize != _hgeoMin) { _hgeoMin = theMinSize; NotifySubMeshesHypothesisModification(); @@ -184,8 +220,7 @@ void BLSURFPlugin_Hypothesis::SetGeoMin(double theMinSize) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetGeoMax(double theMaxSize) -{ +void BLSURFPlugin_Hypothesis::SetGeoMax(double theMaxSize) { if (theMaxSize != _hgeoMax) { _hgeoMax = theMaxSize; NotifySubMeshesHypothesisModification(); @@ -193,24 +228,22 @@ void BLSURFPlugin_Hypothesis::SetGeoMax(double theMaxSize) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetGeometricMesh(GeometricMesh theGeometricMesh) -{ +void BLSURFPlugin_Hypothesis::SetGeometricMesh(GeometricMesh theGeometricMesh) { if (theGeometricMesh != _geometricMesh) { _geometricMesh = theGeometricMesh; - switch( _geometricMesh ) { + switch (_geometricMesh) { case DefaultGeom: default: _angleMeshS = GetDefaultAngleMeshS(); - _gradation = GetDefaultGradation(); + _gradation = GetDefaultGradation(); break; - } + } NotifySubMeshesHypothesisModification(); } } //============================================================================= -void BLSURFPlugin_Hypothesis::SetAngleMeshS(double theVal) -{ +void BLSURFPlugin_Hypothesis::SetAngleMeshS(double theVal) { if (theVal != _angleMeshS) { _angleMeshS = theVal; NotifySubMeshesHypothesisModification(); @@ -218,8 +251,7 @@ void BLSURFPlugin_Hypothesis::SetAngleMeshS(double theVal) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetAngleMeshC(double theVal) -{ +void BLSURFPlugin_Hypothesis::SetAngleMeshC(double theVal) { if (theVal != _angleMeshC) { _angleMeshC = theVal; NotifySubMeshesHypothesisModification(); @@ -227,8 +259,7 @@ void BLSURFPlugin_Hypothesis::SetAngleMeshC(double theVal) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetGradation(double theVal) -{ +void BLSURFPlugin_Hypothesis::SetGradation(double theVal) { if (theVal != _gradation) { _gradation = theVal; NotifySubMeshesHypothesisModification(); @@ -236,8 +267,7 @@ void BLSURFPlugin_Hypothesis::SetGradation(double theVal) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetQuadAllowed(bool theVal) -{ +void BLSURFPlugin_Hypothesis::SetQuadAllowed(bool theVal) { if (theVal != _quadAllowed) { _quadAllowed = theVal; NotifySubMeshesHypothesisModification(); @@ -245,8 +275,7 @@ void BLSURFPlugin_Hypothesis::SetQuadAllowed(bool theVal) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetDecimesh(bool theVal) -{ +void BLSURFPlugin_Hypothesis::SetDecimesh(bool theVal) { if (theVal != _decimesh) { _decimesh = theVal; NotifySubMeshesHypothesisModification(); @@ -254,57 +283,139 @@ void BLSURFPlugin_Hypothesis::SetDecimesh(bool theVal) } //============================================================================= -void BLSURFPlugin_Hypothesis::SetVerbosity(int theVal) -{ +void BLSURFPlugin_Hypothesis::SetVerbosity(int theVal) { if (theVal != _verb) { _verb = theVal; NotifySubMeshesHypothesisModification(); } } + +//============================================================================= +void BLSURFPlugin_Hypothesis::SetPreCADMergeEdges(bool theVal) { + if (theVal != _preCADMergeEdges) { + SetTopology(PreCAD); + _preCADMergeEdges = theVal; + NotifySubMeshesHypothesisModification(); + } +} + //============================================================================= -void BLSURFPlugin_Hypothesis::SetOptionValue(const std::string& optionName, - const std::string& optionValue) - throw (std::invalid_argument) +void BLSURFPlugin_Hypothesis::SetPreCADRemoveNanoEdges(bool theVal) { + if (theVal != _preCADRemoveNanoEdges) { + SetTopology(PreCAD); + _preCADRemoveNanoEdges = theVal; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void BLSURFPlugin_Hypothesis::SetPreCADDiscardInput(bool theVal) { + if (theVal != _preCADDiscardInput) { + SetTopology(PreCAD); + _preCADDiscardInput = theVal; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void BLSURFPlugin_Hypothesis::SetPreCADEpsNano(double theVal) { + if (theVal != _preCADEpsNano) { + SetTopology(PreCAD); + _preCADEpsNano = theVal; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +// void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName, bool isBinary) +void BLSURFPlugin_Hypothesis::SetGMFFile(const std::string& theFileName) { - TOptionValues::iterator op_val = _option2value.find( optionName ); - if ( op_val == _option2value.end() ) { + _GMFFileName = theFileName; +// _GMFFileMode = isBinary; + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +void BLSURFPlugin_Hypothesis::SetOptionValue(const std::string& optionName, const std::string& optionValue) + throw (std::invalid_argument) { + TOptionValues::iterator op_val = _option2value.find(optionName); + if (op_val == _option2value.end()) { std::string msg = "Unknown BLSURF option: '" + optionName + "'"; throw std::invalid_argument(msg); } - if ( op_val->second != optionValue ) { + if (op_val->second != optionValue) { const char* ptr = optionValue.c_str(); // strip white spaces - while ( ptr[0] == ' ' ) + while (ptr[0] == ' ') ptr++; - int i = strlen( ptr ); - while ( i != 0 && ptr[i-1] == ' ') + int i = strlen(ptr); + while (i != 0 && ptr[i - 1] == ' ') i--; // check value type bool typeOk = true; std::string typeName; - if ( i == 0 ) { + if (i == 0) { // empty string - } - else if ( _charOptions.find( optionName ) != _charOptions.end() ) { + } else if (_charOptions.find(optionName) != _charOptions.end()) { // do not check strings - } - else if ( _doubleOptions.find( optionName ) != _doubleOptions.end() ) { + } else if (_doubleOptions.find(optionName) != _doubleOptions.end()) { // check if value is double char * endPtr; strtod(ptr, &endPtr); - typeOk = ( ptr != endPtr ); + typeOk = (ptr != endPtr); typeName = "real"; + } else { + // check if value is int + char * endPtr; + strtol(ptr, &endPtr, 10); + typeOk = (ptr != endPtr); + typeName = "integer"; } - else { + if (!typeOk) { + std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName; + throw std::invalid_argument(msg); + } + op_val->second = optionValue; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void BLSURFPlugin_Hypothesis::SetPreCADOptionValue(const std::string& optionName, const std::string& optionValue) + throw (std::invalid_argument) { + TOptionValues::iterator op_val = _preCADoption2value.find(optionName); + if (op_val == _preCADoption2value.end()) { + std::string msg = "Unknown BLSURF option: '" + optionName + "'"; + throw std::invalid_argument(msg); + } + if (op_val->second != optionValue) { + const char* ptr = optionValue.c_str(); + // strip white spaces + while (ptr[0] == ' ') + ptr++; + int i = strlen(ptr); + while (i != 0 && ptr[i - 1] == ' ') + i--; + // check value type + bool typeOk = true; + std::string typeName; + if (i == 0) { + // empty string + } else if (_preCADdoubleOptions.find(optionName) != _preCADdoubleOptions.end()) { + // check if value is double + char * endPtr; + strtod(ptr, &endPtr); + typeOk = (ptr != endPtr); + typeName = "real"; + } else { // check if value is int char * endPtr; - strtol(ptr, &endPtr,10); - typeOk = ( ptr != endPtr ); + strtol(ptr, &endPtr, 10); + typeOk = (ptr != endPtr); typeName = "integer"; } - if ( !typeOk ) { - std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + - "' but must be " + typeName; + if (!typeOk) { + std::string msg = "PreCAD advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName; throw std::invalid_argument(msg); } op_val->second = optionValue; @@ -313,11 +424,9 @@ void BLSURFPlugin_Hypothesis::SetOptionValue(const std::string& optionName, } //============================================================================= -std::string BLSURFPlugin_Hypothesis::GetOptionValue(const std::string& optionName) - throw (std::invalid_argument) -{ - TOptionValues::iterator op_val = _option2value.find( optionName ); - if ( op_val == _option2value.end() ) { +std::string BLSURFPlugin_Hypothesis::GetOptionValue(const std::string& optionName) throw (std::invalid_argument) { + TOptionValues::iterator op_val = _option2value.find(optionName); + if (op_val == _option2value.end()) { std::string msg = "Unknown BLSURF option: <"; msg += optionName + ">"; throw std::invalid_argument(msg); @@ -326,44 +435,814 @@ std::string BLSURFPlugin_Hypothesis::GetOptionValue(const std::string& optionNam } //============================================================================= -void BLSURFPlugin_Hypothesis::ClearOption(const std::string& optionName) -{ - TOptionValues::iterator op_val = _option2value.find( optionName ); - if ( op_val != _option2value.end() ) +std::string BLSURFPlugin_Hypothesis::GetPreCADOptionValue(const std::string& optionName) throw (std::invalid_argument) { + TOptionValues::iterator op_val = _preCADoption2value.find(optionName); + if (op_val == _preCADoption2value.end()) { + std::string msg = "Unknown PRECAD option: <"; + msg += optionName + ">"; + throw std::invalid_argument(msg); + } + return op_val->second; +} + +//============================================================================= +void BLSURFPlugin_Hypothesis::ClearOption(const std::string& optionName) { + TOptionValues::iterator op_val = _option2value.find(optionName); + if (op_val != _option2value.end()) op_val->second.clear(); } //============================================================================= -std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save) +void BLSURFPlugin_Hypothesis::ClearPreCADOption(const std::string& optionName) { + TOptionValues::iterator op_val = _preCADoption2value.find(optionName); + if (op_val != _preCADoption2value.end()) + op_val->second.clear(); +} + +//======================================================================= +//function : SetSizeMapEntry +//======================================================================= +void BLSURFPlugin_Hypothesis::SetSizeMapEntry(const std::string& entry, const std::string& sizeMap) { + if (_sizeMap[entry].compare(sizeMap) != 0) { + SetPhysicalMesh(SizeMap); + _sizeMap[entry] = sizeMap; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetSizeMapEntry +//======================================================================= +std::string BLSURFPlugin_Hypothesis::GetSizeMapEntry(const std::string& entry) { + TSizeMap::iterator it = _sizeMap.find(entry); + if (it != _sizeMap.end()) + return it->second; + else + return "No_Such_Entry"; +} + +/*! + * \brief Return the size maps + */ +BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetSizeMapEntries() : GetDefaultSizeMap(); +} + +//======================================================================= +//function : SetAttractorEntry +//======================================================================= +void BLSURFPlugin_Hypothesis::SetAttractorEntry(const std::string& entry, const std::string& attractor) { + if (_attractors[entry].compare(attractor) != 0) { + SetPhysicalMesh(SizeMap); + _attractors[entry] = attractor; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetAttractorEntry +//======================================================================= +std::string BLSURFPlugin_Hypothesis::GetAttractorEntry(const std::string& entry) { + TSizeMap::iterator it = _attractors.find(entry); + if (it != _attractors.end()) + return it->second; + else + return "No_Such_Entry"; +} + +/*! + * \brief Return the attractors + */ +BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetAttractorEntries() : GetDefaultSizeMap(); +} + +//======================================================================= +//function : SetClassAttractorEntry +//======================================================================= +void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, const std::string& attEntry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) { - save << " " << (int)_topology - << " " << (int)_physicalMesh - << " " << (int)_geometricMesh - << " " << _phySize - << " " << _angleMeshS - << " " << _gradation - << " " << (int)_quadAllowed - << " " << (int)_decimesh; - save << " " << _phyMin - << " " << _phyMax - << " " << _angleMeshC - << " " << _hgeoMin - << " " << _hgeoMax - << " " << _verb; + SetPhysicalMesh(SizeMap); + + // The new attractor can't be defined on the same face as another sizemap + TSizeMap::iterator it = _sizeMap.find( entry ); + if ( it != _sizeMap.end() ) { + _sizeMap.erase(it); + NotifySubMeshesHypothesisModification(); + } + else { + TSizeMap::iterator itAt = _attractors.find( entry ); + if ( itAt != _attractors.end() ) { + _attractors.erase(itAt); + NotifySubMeshesHypothesisModification(); + } + } + + const TopoDS_Shape AttractorShape = BLSURFPlugin_Hypothesis::entryToShape(attEntry); + const TopoDS_Face FaceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(entry)); + bool attExists = (_classAttractors.find(entry) != _classAttractors.end()); + double u1,u2,v1,v2, diag; + + if ( !attExists || (attExists && _classAttractors[entry]->GetAttractorEntry().compare(attEntry) != 0)){ + ShapeAnalysis::GetFaceUVBounds(FaceShape,u1,u2,v1,v2); +// diag = sqrt((u2 - u1) * (u2 - u1) + (v2 - v1) * (v2 - v1)); + BLSURFPlugin_Attractor* myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry);//, 0.1 ); // test 0.002 * diag); + myAttractor->BuildMap(); + myAttractor->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius); + _classAttractors[entry] = myAttractor; + NotifySubMeshesHypothesisModification(); + } + else { + _classAttractors[entry]->SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius); + if (!_classAttractors[entry]->IsMapBuilt()){ + _classAttractors[entry]->BuildMap(); + } + NotifySubMeshesHypothesisModification(); + } + +} + +//======================================================================= +//function : SetConstantSizeOnAdjacentFaces +//======================================================================= +// TODO uncomment and test (include the needed .hxx) +// SetConstantSizeOnAdjacentFaces(myShape, att_entry, startSize, endSize = user_size, const_dist ) { +// TopTools_IndexedMapOfShapListOdShape anEdge2FaceMap; +// TopExp::MapShapesAnAncestors(myShape,TopAbs_EDGE, TopAbs_FACE, anEdge2FaceMap); +// TopTools_IndexedMapOfShapListOdShape::iterator it; +// for (it = anEdge2FaceMap.begin();it != anEdge2FaceMap.end();it++){ +// SetClassAttractorEntry((*it).first, att_entry, startSize, endSize, 0, const_dist) +// } + + + + + + +//======================================================================= +//function : GetClassAttractorEntry +//======================================================================= +// BLSURFPlugin_Attractor& BLSURFPlugin_Hypothesis::GetClassAttractorEntry(const std::string& entry) +// { +// TAttractorMap::iterator it = _classAttractors.find( entry ); +// if ( it != _classAttractors.end() ) +// return it->second; +// else +// return "No_Such_Entry"; +// } +// + /*! + * \brief Return the map of attractor instances + */ +BLSURFPlugin_Hypothesis::TAttractorMap BLSURFPlugin_Hypothesis::GetClassAttractorEntries(const BLSURFPlugin_Hypothesis* hyp) +{ + return hyp ? hyp->_GetClassAttractorEntries():GetDefaultAttractorMap(); +} + +//======================================================================= +//function : ClearEntry +//======================================================================= +void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry) +{ + TSizeMap::iterator it = _sizeMap.find( entry ); + + if ( it != _sizeMap.end() ) { + _sizeMap.erase(it); + NotifySubMeshesHypothesisModification(); + } + else { + TSizeMap::iterator itAt = _attractors.find( entry ); + if ( itAt != _attractors.end() ) { + _attractors.erase(itAt); + NotifySubMeshesHypothesisModification(); + } + else { + TAttractorMap::iterator it_clAt = _classAttractors.find( entry ); + if ( it_clAt != _classAttractors.end() ) { + _classAttractors.erase(it_clAt); + MESSAGE("_classAttractors.size() = "<<_classAttractors.size()) + NotifySubMeshesHypothesisModification(); + } + else + std::cout<<"No_Such_Entry"<name = theVertexName; + newEnfVertex->geomEntry = theVertexEntry; + newEnfVertex->coords.clear(); + if (theVertexEntry == "") { + newEnfVertex->coords.push_back(x); + newEnfVertex->coords.push_back(y); + newEnfVertex->coords.push_back(z); + } + newEnfVertex->grpName = theGroupName; + newEnfVertex->faceEntries.clear(); + newEnfVertex->faceEntries.insert(theFaceEntry); + + + // update _enfVertexList + TEnfVertexList::iterator it = _enfVertexList.find(newEnfVertex); + if (it != _enfVertexList.end()) { + toCreate = false; + oldEnVertex = (*it); + MESSAGE("Enforced Vertex was found => Update"); + if (oldEnVertex->name != theVertexName) { + MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theVertexName << "\""); + oldEnVertex->name = theVertexName; + toNotify = true; + } + if (oldEnVertex->grpName != theGroupName) { + MESSAGE("Update group name from \"" << oldEnVertex->grpName << "\" to \"" << theGroupName << "\""); + oldEnVertex->grpName = theGroupName; + toNotify = true; + } + TEntryList::iterator it_faceEntries = oldEnVertex->faceEntries.find(theFaceEntry); + if (it_faceEntries == oldEnVertex->faceEntries.end()) { + MESSAGE("Update face list by adding \"" << theFaceEntry << "\""); + oldEnVertex->faceEntries.insert(theFaceEntry); + _faceEntryEnfVertexListMap[theFaceEntry].insert(oldEnVertex); + toNotify = true; + } + if (toNotify) { + // update map coords / enf vertex if needed + if (oldEnVertex->coords.size()) { + _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex; + _faceEntryCoordsListMap[theFaceEntry].insert(oldEnVertex->coords); + } + + // update map geom entry / enf vertex if needed + if (oldEnVertex->geomEntry != "") { + _enfVertexEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex; + _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(oldEnVertex->geomEntry); + } + } + } + +// //////// CREATE //////////// + if (toCreate) { + toNotify = true; + MESSAGE("Creating new enforced vertex"); + _faceEntryEnfVertexListMap[theFaceEntry].insert(newEnfVertex); + _enfVertexList.insert(newEnfVertex); + if (theVertexEntry == "") { + _faceEntryCoordsListMap[theFaceEntry].insert(newEnfVertex->coords); + _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex; + } + else { + _faceEntryEnfVertexEntryListMap[theFaceEntry].insert(newEnfVertex->geomEntry); + _enfVertexEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex; + } + } + + if (toNotify) + NotifySubMeshesHypothesisModification(); + + MESSAGE("BLSURFPlugin_Hypothesis::SetEnforcedVertex END"); + return toNotify; +} + + +//======================================================================= +//function : GetEnforcedVertices +//======================================================================= + +BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetEnfVertexList(const TEntry& theFaceEntry) + throw (std::invalid_argument) { + + if (_faceEntryEnfVertexListMap.count(theFaceEntry) > 0) + return _faceEntryEnfVertexListMap[theFaceEntry]; + else + return GetDefaultEnfVertexList(); + + std::ostringstream msg; + msg << "No enforced vertex for face entry " << theFaceEntry; + throw std::invalid_argument(msg.str()); +} + +//======================================================================= +//function : GetEnfVertexCoordsList +//======================================================================= + +BLSURFPlugin_Hypothesis::TEnfVertexCoordsList BLSURFPlugin_Hypothesis::GetEnfVertexCoordsList( + const TEntry& theFaceEntry) throw (std::invalid_argument) { + + if (_faceEntryCoordsListMap.count(theFaceEntry) > 0) + return _faceEntryCoordsListMap[theFaceEntry]; + + std::ostringstream msg; + msg << "No enforced vertex coords for face entry " << theFaceEntry; + throw std::invalid_argument(msg.str()); +} + +//======================================================================= +//function : GetEnfVertexEntryList +//======================================================================= + +BLSURFPlugin_Hypothesis::TEntryList BLSURFPlugin_Hypothesis::GetEnfVertexEntryList(const TEntry& theFaceEntry) + throw (std::invalid_argument) { + + if (_faceEntryEnfVertexEntryListMap.count(theFaceEntry) > 0) + return _faceEntryEnfVertexEntryListMap[theFaceEntry]; + + std::ostringstream msg; + msg << "No enforced vertex entry for face entry " << theFaceEntry; + throw std::invalid_argument(msg.str()); +} + +//======================================================================= +//function : GetEnfVertex(TEnfVertexCoords coords) +//======================================================================= + +BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(TEnfVertexCoords coords) + throw (std::invalid_argument) { + + if (_coordsEnfVertexMap.count(coords) > 0) + return _coordsEnfVertexMap[coords]; + + std::ostringstream msg; + msg << "No enforced vertex with coords (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")"; + throw std::invalid_argument(msg.str()); +} + +//======================================================================= +//function : GetEnfVertex(const TEntry& theEnfVertexEntry) +//======================================================================= + +BLSURFPlugin_Hypothesis::TEnfVertex* BLSURFPlugin_Hypothesis::GetEnfVertex(const TEntry& theEnfVertexEntry) + throw (std::invalid_argument) { + + if (_enfVertexEntryEnfVertexMap.count(theEnfVertexEntry) > 0) + return _enfVertexEntryEnfVertexMap[theEnfVertexEntry]; + + std::ostringstream msg; + msg << "No enforced vertex with entry " << theEnfVertexEntry; + throw std::invalid_argument(msg.str()); +} + +//Enable internal enforced vertices on specific face if requested by user +////======================================================================= +////function : GetInternalEnforcedVertex +////======================================================================= + +//bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertex(const TEntry& theFaceEntry) +//{ +// if (_faceEntryInternalVerticesList.count(theFaceEntry) > 0) +// return true; +// return false; +//} + +//======================================================================= +//function : ClearEnforcedVertex +//======================================================================= + +bool BLSURFPlugin_Hypothesis::ClearEnforcedVertex(const TEntry& theFaceEntry, double x, double y, double z, + const TEntry& theVertexEntry) throw (std::invalid_argument) { + + bool toNotify = false; + std::ostringstream msg; + TEnfVertex *oldEnfVertex; + TEnfVertexCoords coords; + coords.clear(); + coords.push_back(x); + coords.push_back(y); + coords.push_back(z); + + // check that enf vertex with given enf vertex entry exists + TEnfVertexEntryEnfVertexMap::iterator it_enfVertexEntry = _enfVertexEntryEnfVertexMap.find(theVertexEntry); + if (it_enfVertexEntry != _enfVertexEntryEnfVertexMap.end()) { + // Success + MESSAGE("Found enforced vertex with geom entry " << theVertexEntry); + oldEnfVertex = it_enfVertexEntry->second; + + _enfVertexEntryEnfVertexMap.erase(it_enfVertexEntry); + + TEntryList& enfVertexEntryList = _faceEntryEnfVertexEntryListMap[theFaceEntry]; + enfVertexEntryList.erase(theVertexEntry); + if (enfVertexEntryList.size() == 0) + _faceEntryEnfVertexEntryListMap.erase(theFaceEntry); + // TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry); + // TEntryList::iterator it_entryList = it_entry_entry->second.find(theVertexEntry); + // it_entry_entry->second.erase(it_entryList); + // if (it_entry_entry->second.size() == 0) + // _faceEntryEnfVertexEntryListMap.erase(it_entry_entry); + } else { + // Fail + MESSAGE("Enforced vertex with geom entry " << theVertexEntry << " not found"); + msg << "No enforced vertex with geom entry " << theVertexEntry; + // check that enf vertex with given coords exists + TCoordsEnfVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords); + if (it_coords_enf != _coordsEnfVertexMap.end()) { + // Success + MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z); + oldEnfVertex = it_coords_enf->second; + + _coordsEnfVertexMap.erase(it_coords_enf); + + TEnfVertexCoordsList& enfVertexCoordsList = _faceEntryCoordsListMap[theFaceEntry]; + enfVertexCoordsList.erase(coords); + if (enfVertexCoordsList.size() == 0) + _faceEntryCoordsListMap.erase(theFaceEntry); + // TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry); + // TEnfVertexCoordsList::iterator it_coordsList = it_entry_coords->second.find(coords); + // it_entry_coords->second.erase(it_coordsList); + // if (it_entry_coords->second.size() == 0) + // _faceEntryCoordsListMap.erase(it_entry_coords); + } else { + // Fail + MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found"); + msg << std::endl; + msg << "No enforced vertex at " << x << ", " << y << ", " << z; + throw std::invalid_argument(msg.str()); + } + } + + MESSAGE("Remove enf vertex from _enfVertexList"); + + // update _enfVertexList + TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex); + if (it != _enfVertexList.end()) { + (*it)->faceEntries.erase(theFaceEntry); + if ((*it)->faceEntries.size() == 0){ + _enfVertexList.erase(it); + toNotify = true; + } + MESSAGE("Done"); + } + + // update _faceEntryEnfVertexListMap + TEnfVertexList& currentEnfVertexList = _faceEntryEnfVertexListMap[theFaceEntry]; + currentEnfVertexList.erase(oldEnfVertex); + + if (currentEnfVertexList.size() == 0) { + MESSAGE("Remove _faceEntryEnfVertexListMap[" << theFaceEntry <<"]"); + _faceEntryEnfVertexListMap.erase(theFaceEntry); + MESSAGE("Done"); + } + + if (toNotify) + NotifySubMeshesHypothesisModification(); + + return toNotify; +} + +//======================================================================= +//function : ClearEnforcedVertices +//======================================================================= + +bool BLSURFPlugin_Hypothesis::ClearEnforcedVertices(const TEntry& theFaceEntry) throw (std::invalid_argument) { + + bool toNotify = false; + TEnfVertex *oldEnfVertex; + + TFaceEntryCoordsListMap::iterator it_entry_coords = _faceEntryCoordsListMap.find(theFaceEntry); + if (it_entry_coords != _faceEntryCoordsListMap.end()) { + toNotify = true; + TEnfVertexCoordsList coordsList = it_entry_coords->second; + TEnfVertexCoordsList::iterator it_coordsList = coordsList.begin(); + for (; it_coordsList != coordsList.end(); ++it_coordsList) { + TEnfVertexCoords coords = (*it_coordsList); + oldEnfVertex = _coordsEnfVertexMap[coords]; + _coordsEnfVertexMap.erase(coords); + // update _enfVertexList + TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex); + if (it != _enfVertexList.end()) { + (*it)->faceEntries.erase(theFaceEntry); + if ((*it)->faceEntries.size() == 0){ + _enfVertexList.erase(it); + toNotify = true; + } + MESSAGE("Done"); + } + } + _faceEntryCoordsListMap.erase(it_entry_coords); + _faceEntryEnfVertexListMap.erase(theFaceEntry); + } + + TFaceEntryEnfVertexEntryListMap::iterator it_entry_entry = _faceEntryEnfVertexEntryListMap.find(theFaceEntry); + if (it_entry_entry != _faceEntryEnfVertexEntryListMap.end()) { + toNotify = true; + TEntryList enfVertexEntryList = it_entry_entry->second; + TEntryList::iterator it_enfVertexEntryList = enfVertexEntryList.begin(); + for (; it_enfVertexEntryList != enfVertexEntryList.end(); ++it_enfVertexEntryList) { + TEntry enfVertexEntry = (*it_enfVertexEntryList); + oldEnfVertex = _enfVertexEntryEnfVertexMap[enfVertexEntry]; + _enfVertexEntryEnfVertexMap.erase(enfVertexEntry); + // update _enfVertexList + TEnfVertexList::iterator it = _enfVertexList.find(oldEnfVertex); + if (it != _enfVertexList.end()) { + (*it)->faceEntries.erase(theFaceEntry); + if ((*it)->faceEntries.size() == 0){ + _enfVertexList.erase(it); + toNotify = true; + } + MESSAGE("Done"); + } + } + _faceEntryEnfVertexEntryListMap.erase(it_entry_entry); + _faceEntryEnfVertexListMap.erase(theFaceEntry); + } + + if (toNotify) + NotifySubMeshesHypothesisModification(); + + return toNotify; + // std::ostringstream msg; + // msg << "No enforced vertex for " << theFaceEntry; + // throw std::invalid_argument(msg.str()); +} + +//======================================================================= +//function : ClearAllEnforcedVertices +//======================================================================= +void BLSURFPlugin_Hypothesis::ClearAllEnforcedVertices() { + _faceEntryEnfVertexListMap.clear(); + _enfVertexList.clear(); + _faceEntryCoordsListMap.clear(); + _coordsEnfVertexMap.clear(); + _faceEntryEnfVertexEntryListMap.clear(); + _enfVertexEntryEnfVertexMap.clear(); +// Enable internal enforced vertices on specific face if requested by user +// _faceEntryInternalVerticesList.clear(); + NotifySubMeshesHypothesisModification(); +} + +//================================================================================ +/*! + * \brief Return the enforced vertices + */ +//================================================================================ + + +BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace( + const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetAllEnforcedVerticesByFace() : GetDefaultFaceEntryEnfVertexListMap(); +} + +//Enable internal enforced vertices on specific face if requested by user +//BLSURFPlugin_Hypothesis::TFaceEntryInternalVerticesList BLSURFPlugin_Hypothesis::GetAllInternalEnforcedVerticesByFace( +// const BLSURFPlugin_Hypothesis* hyp) { +// return hyp ? hyp->_GetAllInternalEnforcedVerticesByFace() : GetDefaultFaceEntryInternalVerticesMap(); +//} + +bool BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFaces(const BLSURFPlugin_Hypothesis* hyp) +{ + return hyp ? hyp->_GetInternalEnforcedVertexAllFaces() : GetDefaultInternalEnforcedVertex(); +} + +BLSURFPlugin_Hypothesis::TEnfGroupName BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFacesGroup(const BLSURFPlugin_Hypothesis* hyp) +{ + return hyp ? hyp->_GetInternalEnforcedVertexAllFacesGroup() : BLSURFPlugin_Hypothesis::TEnfGroupName(); +} + +BLSURFPlugin_Hypothesis::TEnfVertexList BLSURFPlugin_Hypothesis::GetAllEnforcedVertices( + const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetAllEnforcedVertices() : GetDefaultEnfVertexList(); +} + +BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap BLSURFPlugin_Hypothesis::GetAllCoordsByFace( + const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetAllCoordsByFace() : GetDefaultFaceEntryCoordsListMap(); +} + +BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByCoords( + const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetAllEnforcedVerticesByCoords() : GetDefaultCoordsEnfVertexMap(); +} + +BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap BLSURFPlugin_Hypothesis::GetAllEnfVertexEntriesByFace( + const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetAllEnfVertexEntriesByFace() : GetDefaultFaceEntryEnfVertexEntryListMap(); +} + +BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByEnfVertexEntry( + const BLSURFPlugin_Hypothesis* hyp) { + return hyp ? hyp->_GetAllEnforcedVerticesByEnfVertexEntry() : GetDefaultEnfVertexEntryEnfVertexMap(); +} + +std::set BLSURFPlugin_Hypothesis::GetEnfVertexNodeIDs(TEnfGroupName theGroupName) throw (std::invalid_argument) +{ + TGroupNameNodeIDMap::const_iterator it = _groupNameNodeIDMap.find(theGroupName); + if (it != _groupNameNodeIDMap.end()) { + return it->second; + } + std::ostringstream msg; + msg << "No group " << theGroupName; + throw std::invalid_argument(msg.str()); +} + +void BLSURFPlugin_Hypothesis::AddEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID) +{ + _groupNameNodeIDMap[theGroupName].insert(theNodeID); +} + +void BLSURFPlugin_Hypothesis::RemoveEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID) throw (std::invalid_argument) +{ + TGroupNameNodeIDMap::iterator it = _groupNameNodeIDMap.find(theGroupName); + if (it != _groupNameNodeIDMap.end()) { + std::set::iterator IDit = it->second.find(theNodeID); + if (IDit != it->second.end()) + it->second.erase(IDit); + std::ostringstream msg; + msg << "No node IDs " << theNodeID << " for group " << theGroupName; + throw std::invalid_argument(msg.str()); + } + std::ostringstream msg; + msg << "No group " << theGroupName; + throw std::invalid_argument(msg.str()); +} + + +//============================================================================= +void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFaces(bool toEnforceInternalVertices) { + if (toEnforceInternalVertices != _enforcedInternalVerticesAllFaces) { + _enforcedInternalVerticesAllFaces = toEnforceInternalVertices; + if (toEnforceInternalVertices) + SetPhysicalMesh(SizeMap); + NotifySubMeshesHypothesisModification(); + } +} + + +//============================================================================= +void BLSURFPlugin_Hypothesis::SetInternalEnforcedVertexAllFacesGroup(BLSURFPlugin_Hypothesis::TEnfGroupName theGroupName) { + if (string(theGroupName) != string(_enforcedInternalVerticesAllFacesGroup)) { + _enforcedInternalVerticesAllFacesGroup = theGroupName; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +std::ostream & BLSURFPlugin_Hypothesis::SaveTo(std::ostream & save) { + save << " " << (int) _topology << " " << (int) _physicalMesh << " " << (int) _geometricMesh << " " << _phySize << " " + << _angleMeshS << " " << _gradation << " " << (int) _quadAllowed << " " << (int) _decimesh; + save << " " << _phyMin << " " << _phyMax << " " << _angleMeshC << " " << _hgeoMin << " " << _hgeoMax << " " << _verb; + save << " " << (int) _preCADMergeEdges << " " << (int) _preCADRemoveNanoEdges << " " << (int) _preCADDiscardInput << " " << _preCADEpsNano ; TOptionValues::iterator op_val = _option2value.begin(); - for ( ; op_val != _option2value.end(); ++op_val ) { - if ( !op_val->second.empty() ) - save << " " << op_val->first - << " " << op_val->second << "%#"; // "%#" is a mark of value end + if (op_val != _option2value.end()) { + save << " " << "__OPTIONS_BEGIN__"; + for (; op_val != _option2value.end(); ++op_val) { + if (!op_val->second.empty()) + save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end + } + save << " " << "__OPTIONS_END__"; + } + + op_val = _preCADoption2value.begin(); + if (op_val != _preCADoption2value.end()) { + save << " " << "__PRECAD_OPTIONS_BEGIN__"; + for (; op_val != _preCADoption2value.end(); ++op_val) { + if (!op_val->second.empty()) + save << " " << op_val->first << " " << op_val->second << "%#"; // "%#" is a mark of value end + } + save << " " << "__PRECAD_OPTIONS_END__"; + } + + TSizeMap::iterator it_sm = _sizeMap.begin(); + if (it_sm != _sizeMap.end()) { + save << " " << "__SIZEMAP_BEGIN__"; + for (; it_sm != _sizeMap.end(); ++it_sm) { + save << " " << it_sm->first << " " << it_sm->second << "%#"; // "%#" is a mark of value end + } + save << " " << "__SIZEMAP_END__"; + } + + TSizeMap::iterator it_at = _attractors.begin(); + if (it_at != _attractors.end()) { + save << " " << "__ATTRACTORS_BEGIN__"; + for (; it_at != _attractors.end(); ++it_at) { + save << " " << it_at->first << " " << it_at->second << "%#"; // "%#" is a mark of value end + } + save << " " << "__ATTRACTORS_END__"; + } + + TAttractorMap::iterator it_At = _classAttractors.begin(); + if (it_At != _classAttractors.end()) { + std::ostringstream test; + save << " " << "__NEW_ATTRACTORS_BEGIN__"; + test << " " << "__NEW_ATTRACTORS_BEGIN__"; + for (; it_At != _classAttractors.end(); ++it_At) { + std::vector attParams; + attParams = it_At->second->GetParameters(); +// double step = it_At->second->GetStep(); + save << " " << it_At->first; + save << " " << it_At->second->GetAttractorEntry(); + save << " " << attParams[0] << " " << attParams[1] << " " << attParams[2] << " " << attParams[3]; +// save << " " << step; + test << " " << it_At->first; + test << " " << it_At->second->GetAttractorEntry(); + test << " " << attParams[0] << " " << attParams[1] << " " << attParams[2] << " " << attParams[3]; +// test << " " << step; + } + save << " " << "__NEW_ATTRACTORS_END__"; + test << " " << "__NEW_ATTRACTORS_END__"; + MESSAGE(" Attractor hypothesis saved as "<name.empty()) { + save << " " << "__BEGIN_NAME__"; + save << " " << enfVertex->name; + save << " " << "__END_NAME__"; + } + if (!enfVertex->geomEntry.empty()) { + save << " " << "__BEGIN_ENTRY__"; + save << " " << enfVertex->geomEntry; + save << " " << "__END_ENTRY__"; + } + if (!enfVertex->grpName.empty()) { + save << " " << "__BEGIN_GROUP__"; + save << " " << enfVertex->grpName; + save << " " << "__END_GROUP__"; + } + if (enfVertex->coords.size()) { + save << " " << "__BEGIN_COORDS__"; + for (int i=0;icoords.size();i++) + save << " " << enfVertex->coords[i]; + save << " " << "__END_COORDS__"; + } + TEntryList::const_iterator faceEntriesIt = enfVertex->faceEntries.begin(); + bool hasFaces = false; + if (faceEntriesIt != enfVertex->faceEntries.end()) { + hasFaces = true; + save << " " << "__BEGIN_FACELIST__"; + } + for (; faceEntriesIt != enfVertex->faceEntries.end(); ++faceEntriesIt) + save << " " << (*faceEntriesIt); + if (hasFaces) + save << " " << "__END_FACELIST__"; + save << " " << "__END_VERTEX__"; + } + save << " " << "__ENFORCED_VERTICES_END__"; } return save; } //============================================================================= -std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) -{ +std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) { bool isOK = true; int i; double val; @@ -421,60 +1300,404 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) _phyMin = val; else load.clear(std::ios::badbit | load.rdstate()); - + isOK = (load >> val); if (isOK) _phyMax = val; else load.clear(std::ios::badbit | load.rdstate()); - + isOK = (load >> val); if (isOK) _angleMeshC = val; else load.clear(std::ios::badbit | load.rdstate()); - + isOK = (load >> val); if (isOK) _hgeoMin = val; else load.clear(std::ios::badbit | load.rdstate()); - + isOK = (load >> val); if (isOK) _hgeoMax = val; else load.clear(std::ios::badbit | load.rdstate()); - + isOK = (load >> i); if (isOK) _verb = i; else load.clear(std::ios::badbit | load.rdstate()); + isOK = (load >> i); + if (isOK) + _preCADMergeEdges = (bool) i; + else + load.clear(std::ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + _preCADRemoveNanoEdges = (bool) i; + else + load.clear(std::ios::badbit | load.rdstate()); + + isOK = (load >> i); + if (isOK) + _preCADDiscardInput = (bool) i; + else + load.clear(std::ios::badbit | load.rdstate()); + + isOK = (load >> val); + if (isOK) + _preCADEpsNano = val; + else + load.clear(std::ios::badbit | load.rdstate()); + + std::string option_or_sm; + bool hasOptions = false; + bool hasPreCADOptions = false; + bool hasSizeMap = false; + bool hasAttractor = false; + bool hasNewAttractor = false; + bool hasEnforcedVertex = false; + + isOK = (load >> option_or_sm); + if (isOK) + if (option_or_sm == "__OPTIONS_BEGIN__") + hasOptions = true; + else if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__") + hasPreCADOptions = true; + else if (option_or_sm == "__SIZEMAP_BEGIN__") + hasSizeMap = true; + else if (option_or_sm == "__ATTRACTORS_BEGIN__") + hasAttractor = true; + else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__") + hasNewAttractor = true; + else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertex = true; + std::string optName, optValue; - while (isOK) { + while (isOK && hasOptions) { isOK = (load >> optName); + if (isOK) { + if (optName == "__OPTIONS_END__") + break; + isOK = (load >> optValue); + } + if (isOK) { + std::string & value = _option2value[optName]; + value = optValue; + int len = value.size(); + // continue reading until "%#" encountered + while (value[len - 1] != '#' || value[len - 2] != '%') { + isOK = (load >> optValue); + if (isOK) { + value += " "; + value += optValue; + len = value.size(); + } else { + break; + } + } + value[len - 2] = '\0'; //cut off "%#" + } + } + + if (hasOptions) { + isOK = (load >> option_or_sm); if (isOK) + if (option_or_sm == "__PRECAD_OPTIONS_BEGIN__") + hasPreCADOptions = true; + else if (option_or_sm == "__SIZEMAP_BEGIN__") + hasSizeMap = true; + else if (option_or_sm == "__ATTRACTORS_BEGIN__") + hasAttractor = true; + else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__") + hasNewAttractor = true; + else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertex = true; + } + + while (isOK && hasPreCADOptions) { + isOK = (load >> optName); + if (isOK) { + if (optName == "__PRECAD_OPTIONS_END__") + break; isOK = (load >> optValue); + } if (isOK) { - std::string & value = _option2value[ optName ]; + std::string & value = _preCADoption2value[optName]; value = optValue; int len = value.size(); // continue reading until "%#" encountered - while ( value[len-1] != '#' || value[len-2] != '%' ) - { + while (value[len - 1] != '#' || value[len - 2] != '%') { isOK = (load >> optValue); if (isOK) { value += " "; value += optValue; len = value.size(); + } else { + break; } - else { + } + value[len - 2] = '\0'; //cut off "%#" + } + } + + if (hasPreCADOptions) { + isOK = (load >> option_or_sm); + if (isOK) + if (option_or_sm == "__SIZEMAP_BEGIN__") + hasSizeMap = true; + else if (option_or_sm == "__ATTRACTORS_BEGIN__") + hasAttractor = true; + else if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__") + hasNewAttractor = true; + else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertex = true; + } + + std::string smEntry, smValue; + while (isOK && hasSizeMap) { + isOK = (load >> smEntry); + if (isOK) { + if (smEntry == "__SIZEMAP_END__") + break; + isOK = (load >> smValue); + } + if (isOK) { + std::string & value2 = _sizeMap[smEntry]; + value2 = smValue; + int len2 = value2.size(); + // continue reading until "%#" encountered + while (value2[len2 - 1] != '#' || value2[len2 - 2] != '%') { + isOK = (load >> smValue); + if (isOK) { + value2 += " "; + value2 += smValue; + len2 = value2.size(); + } else { + break; + } + } + value2[len2 - 2] = '\0'; //cut off "%#" + } + } + + if (hasSizeMap) { + isOK = (load >> option_or_sm); + if (isOK) + if (option_or_sm == "__ATTRACTORS_BEGIN__") + hasAttractor = true; + if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__") + hasNewAttractor = true; + else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertex = true; + } + + std::string atEntry, atValue; + while (isOK && hasAttractor) { + isOK = (load >> atEntry); + if (isOK) { + if (atEntry == "__ATTRACTORS_END__") + break; + isOK = (load >> atValue); + } + if (isOK) { + std::string & value3 = _attractors[atEntry]; + value3 = atValue; + int len3 = value3.size(); + // continue reading until "%#" encountered + while (value3[len3 - 1] != '#' || value3[len3 - 2] != '%') { + isOK = (load >> atValue); + if (isOK) { + value3 += " "; + value3 += atValue; + len3 = value3.size(); + } else { break; } } - value[ len-2 ] = '\0'; //cut off "%#" + value3[len3 - 2] = '\0'; //cut off "%#" + } + } + + if (hasAttractor) { + isOK = (load >> option_or_sm); + if (isOK) + if (option_or_sm == "__NEW_ATTRACTORS_BEGIN__") + hasNewAttractor = true; + else if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertex = true; + } + + std::string newAtFaceEntry, atTestString; + std::string newAtShapeEntry; + double attParams[4]; + double step; + while (isOK && hasNewAttractor) { + std::cout<<"Load new attractor"<> newAtFaceEntry); + if (isOK) { + if (newAtFaceEntry == "__NEW_ATTRACTORS_END__") + break; + isOK = (load >> newAtShapeEntry); + if (!isOK) + break; + isOK = (load >> attParams[0]>>attParams[1]>>attParams[2]>>attParams[3]); //>>step); + } + if (isOK) { + MESSAGE(" LOADING ATTRACTOR HYPOTHESIS ") + const TopoDS_Shape attractorShape = BLSURFPlugin_Hypothesis::entryToShape(newAtShapeEntry); + const TopoDS_Face faceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(newAtFaceEntry)); + BLSURFPlugin_Attractor* attractor = new BLSURFPlugin_Attractor(faceShape, attractorShape, newAtShapeEntry);//, step); + attractor->SetParameters(attParams[0], attParams[1], attParams[2], attParams[3]); + attractor->BuildMap(); + _classAttractors[newAtFaceEntry]=attractor; + } + } + + + if (hasNewAttractor) { + isOK = (load >> option_or_sm); + if (isOK) + if (option_or_sm == "__ENFORCED_VERTICES_BEGIN__") + hasEnforcedVertex = true; + } + + +// +// Here is a example of the saved stream: +// __ENFORCED_VERTICES_BEGIN__ +// __BEGIN_VERTEX__ => no name, no entry +// __BEGIN_GROUP__ mon groupe __END_GROUP__ +// __BEGIN_COORDS__ 10 10 10 __END_COORDS__ +// __BEGIN_FACELIST__ 0:1:1:1:1 __END_FACELIST__ +// __END_VERTEX__ +// __BEGIN_VERTEX__ => no coords +// __BEGIN_NAME__ mes points __END_NAME__ +// __BEGIN_ENTRY__ 0:1:1:4 __END_ENTRY__ +// __BEGIN_GROUP__ mon groupe __END_GROUP__ +// __BEGIN_FACELIST__ 0:1:1:1:3 __END_FACELIST__ +// __END_VERTEX__ +// __ENFORCED_VERTICES_END__ +// + + std::string enfSeparator; + std::string enfName; + std::string enfGeomEntry; + std::string enfGroup; + TEntryList enfFaceEntryList; + double enfCoords[3]; + bool hasCoords = false; + + _faceEntryEnfVertexListMap.clear(); + _enfVertexList.clear(); + _faceEntryCoordsListMap.clear(); + _coordsEnfVertexMap.clear(); + _faceEntryEnfVertexEntryListMap.clear(); + _enfVertexEntryEnfVertexMap.clear(); + + + while (isOK && hasEnforcedVertex) { + isOK = (load >> enfSeparator); // __BEGIN_VERTEX__ + TEnfVertex *enfVertex = new TEnfVertex(); +// MESSAGE("enfSeparator: " <> enfSeparator); + MESSAGE("enfSeparator: " <name = enfName; + enfVertex->geomEntry = enfGeomEntry; + enfVertex->grpName = enfGroup; + enfVertex->coords.clear(); + if (hasCoords) + enfVertex->coords.assign(enfCoords,enfCoords+3); + enfVertex->faceEntries = enfFaceEntryList; + + _enfVertexList.insert(enfVertex); + + if (enfVertex->coords.size()) { + _coordsEnfVertexMap[enfVertex->coords] = enfVertex; + for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) { + _faceEntryCoordsListMap[(*it)].insert(enfVertex->coords); + _faceEntryEnfVertexListMap[(*it)].insert(enfVertex); + } + } + if (!enfVertex->geomEntry.empty()) { + _enfVertexEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex; + for (TEntryList::const_iterator it = enfVertex->faceEntries.begin() ; it != enfVertex->faceEntries.end(); ++it) { + _faceEntryEnfVertexEntryListMap[(*it)].insert(enfVertex->geomEntry); + _faceEntryEnfVertexListMap[(*it)].insert(enfVertex); + } + } + + enfName.clear(); + enfGeomEntry.clear(); + enfGroup.clear(); + enfFaceEntryList.clear(); + hasCoords = false; + break; // __END_VERTEX__ + } + + if (enfSeparator == "__BEGIN_NAME__") { // __BEGIN_NAME__ + while (isOK && (enfSeparator != "__END_NAME__")) { + isOK = (load >> enfSeparator); + if (enfSeparator != "__END_NAME__") { + if (!enfName.empty()) + enfName += " "; + enfName += enfSeparator; + } + } + MESSAGE("enfName: " <> enfGeomEntry); + isOK = (load >> enfSeparator); // __END_ENTRY__ + if (enfSeparator != "__END_ENTRY__") + throw std::exception(); + MESSAGE("enfGeomEntry: " <> enfSeparator); + if (enfSeparator != "__END_GROUP__") { + if (!enfGroup.empty()) + enfGroup += " "; + enfGroup += enfSeparator; + } + } + MESSAGE("enfGroup: " <> enfCoords[0] >> enfCoords[1] >> enfCoords[2]); + isOK = (load >> enfSeparator); // __END_COORDS__ + if (enfSeparator != "__END_COORDS__") + throw std::exception(); + MESSAGE("enfCoords: " << enfCoords[0] <<","<< enfCoords[1] <<","<< enfCoords[2]); + } + + if (enfSeparator == "__BEGIN_FACELIST__") { // __BEGIN_FACELIST__ + while (isOK && (enfSeparator != "__END_FACELIST__")) { + isOK = (load >> enfSeparator); + if (enfSeparator != "__END_FACELIST__") { + enfFaceEntryList.insert(enfSeparator); + MESSAGE(enfSeparator << " was inserted into enfFaceEntryList"); + } + } + } } } @@ -482,15 +1705,13 @@ std::istream & BLSURFPlugin_Hypothesis::LoadFrom(std::istream & load) } //============================================================================= -std::ostream & operator <<(std::ostream & save, BLSURFPlugin_Hypothesis & hyp) -{ - return hyp.SaveTo( save ); +std::ostream & operator <<(std::ostream & save, BLSURFPlugin_Hypothesis & hyp) { + return hyp.SaveTo(save); } //============================================================================= -std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) -{ - return hyp.LoadFrom( load ); +std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) { + return hyp.LoadFrom(load); } //================================================================================ @@ -499,9 +1720,7 @@ std::istream & operator >>(std::istream & load, BLSURFPlugin_Hypothesis & hyp) */ //================================================================================ -bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, - const TopoDS_Shape& theShape) -{ +bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape) { return false; } @@ -512,68 +1731,72 @@ bool BLSURFPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, */ //============================================================================= -bool BLSURFPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, - const SMESH_Mesh* theMesh) -{ - return bool( _phySize = dflts._elemLength ); +bool BLSURFPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh) { + return bool(_phySize = dflts._elemLength); } //============================================================================= -BLSURFPlugin_Hypothesis::Topology BLSURFPlugin_Hypothesis::GetDefaultTopology() -{ +BLSURFPlugin_Hypothesis::Topology BLSURFPlugin_Hypothesis::GetDefaultTopology() { return FromCAD; } //============================================================================= -BLSURFPlugin_Hypothesis::PhysicalMesh BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh() -{ +BLSURFPlugin_Hypothesis::PhysicalMesh BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh() { return PhysicalUserDefined; } //============================================================================= -double BLSURFPlugin_Hypothesis::GetDefaultPhySize() -{ +double BLSURFPlugin_Hypothesis::GetDefaultPhySize() { return 10; } //====================================================================== -double BLSURFPlugin_Hypothesis::GetDefaultMaxSize() -{ +double BLSURFPlugin_Hypothesis::GetDefaultMaxSize() { return undefinedDouble(); // 1e+4; } //====================================================================== -double BLSURFPlugin_Hypothesis::GetDefaultMinSize() -{ +double BLSURFPlugin_Hypothesis::GetDefaultMinSize() { return undefinedDouble(); //1e-4; } //====================================================================== -BLSURFPlugin_Hypothesis::GeometricMesh BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh() -{ +BLSURFPlugin_Hypothesis::GeometricMesh BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh() { return DefaultGeom; } //============================================================================= -double BLSURFPlugin_Hypothesis::GetDefaultAngleMeshS() -{ +double BLSURFPlugin_Hypothesis::GetDefaultAngleMeshS() { return 8; } //============================================================================= -double BLSURFPlugin_Hypothesis::GetDefaultGradation() -{ +double BLSURFPlugin_Hypothesis::GetDefaultGradation() { return 1.1; } //============================================================================= -bool BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed() -{ +bool BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed() { return false; } //============================================================================= -bool BLSURFPlugin_Hypothesis::GetDefaultDecimesh() -{ +bool BLSURFPlugin_Hypothesis::GetDefaultDecimesh() { + return false; +} + +//====================================================================== +double BLSURFPlugin_Hypothesis::GetDefaultPreCADEpsNano() { + return undefinedDouble(); //1e-4; +} + +//====================================================================== +std::string BLSURFPlugin_Hypothesis::GetDefaultGMFFile() { + return ""; +} + +//============================================================================= +bool BLSURFPlugin_Hypothesis::GetDefaultInternalEnforcedVertex() { return false; } + diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx index a8fb7d2..f6167a5 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx @@ -1,35 +1,42 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_Hypothesis.hxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) // & Aurelien ALLEAUME (DISTENE) +// Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- // #ifndef _BLSURFPlugin_Hypothesis_HXX_ #define _BLSURFPlugin_Hypothesis_HXX_ #include "SMESH_Hypothesis.hxx" +#include #include #include #include #include +#include +#include +#include +#include "BLSURFPlugin_Attractor.hxx" // Parameters for work of BLSURF @@ -41,12 +48,14 @@ public: enum Topology { FromCAD, Process, - Process2 + Process2, + PreCAD }; enum PhysicalMesh { DefaultSize, - PhysicalUserDefined + PhysicalUserDefined, + SizeMap }; enum GeometricMesh { @@ -54,6 +63,10 @@ public: UserDefined }; + static const char* GetHypType() { return "BLSURF_Parameters"; } + + TopoDS_Shape entryToShape(std::string entry); + void SetTopology(Topology theTopology); Topology GetTopology() const { return _topology; } @@ -95,19 +108,218 @@ public: void SetVerbosity(int theVal); int GetVerbosity() const { return _verb; } + + void ClearEntry(const std::string& entry); + void ClearSizeMaps(); + + void SetPreCADMergeEdges(bool theVal); + bool GetPreCADMergeEdges() const { return _preCADMergeEdges; } + + void SetPreCADRemoveNanoEdges(bool theVal); + bool GetPreCADRemoveNanoEdges() const { return _preCADRemoveNanoEdges; } + + void SetPreCADDiscardInput(bool theVal); + bool GetPreCADDiscardInput() const { return _preCADDiscardInput; } + + void SetPreCADEpsNano(double theVal); + double GetPreCADEpsNano() const { return _preCADEpsNano; } + + typedef std::map TSizeMap; + + void SetSizeMapEntry(const std::string& entry,const std::string& sizeMap ); + std::string GetSizeMapEntry(const std::string& entry); + const TSizeMap& _GetSizeMapEntries() const { return _sizeMap; } + /*! + * \brief Return the size maps + */ + static TSizeMap GetSizeMapEntries(const BLSURFPlugin_Hypothesis* hyp); + + + void SetAttractorEntry(const std::string& entry,const std::string& attractor ); + std::string GetAttractorEntry(const std::string& entry); + const TSizeMap& _GetAttractorEntries() const { return _attractors; }; + /*! + * \brief Return the attractors + */ + static TSizeMap GetAttractorEntries(const BLSURFPlugin_Hypothesis* hyp); + + +/* + void SetCustomSizeMapEntry(const std::string& entry,const std::string& sizeMap ); + std::string GetCustomSizeMapEntry(const std::string& entry); + void UnsetCustomSizeMap(const std::string& entry); + const TSizeMap& GetCustomSizeMapEntries() const { return _customSizeMap; } + */ + + typedef std::map< std::string, BLSURFPlugin_Attractor* > TAttractorMap; + typedef std::map< std::string, std::vector > TParamsMap; //TODO à finir + + void SetClassAttractorEntry(const std::string& entry, const std::string& att_entry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius); + std::string GetClassAttractorEntry(const std::string& entry); + const TAttractorMap& _GetClassAttractorEntries() const { return _classAttractors; } + /*! + * \brief Return the attractors entries + */ + static TAttractorMap GetClassAttractorEntries(const BLSURFPlugin_Hypothesis* hyp); + + /*! + * To set/get/unset an enforced vertex + */ + // Name + typedef std::string TEnfName; + // Entry + typedef std::string TEntry; + // List of entries + typedef std::set TEntryList; + // Group name + typedef std::string TEnfGroupName; + // Coordinates + typedef std::vector TEnfVertexCoords; + typedef std::set< TEnfVertexCoords > TEnfVertexCoordsList; + + // Enforced vertex + struct TEnfVertex { + TEnfName name; + TEntry geomEntry; + TEnfVertexCoords coords; + TEnfGroupName grpName; + TEntryList faceEntries; + }; + + struct CompareEnfVertices + { + bool operator () (const TEnfVertex* e1, const TEnfVertex* e2) const { + if (e1 && e2) { + if (e1->coords.size() && e2->coords.size()) + return (e1->coords < e2->coords); + else + return (e1->geomEntry < e2->geomEntry); + } + return false; + } + }; + + // List of enforced vertices + typedef std::set< TEnfVertex*, CompareEnfVertices > TEnfVertexList; + + // Map Face Entry / List of enforced vertices + typedef std::map< TEntry, TEnfVertexList > TFaceEntryEnfVertexListMap; + + // List of Face Entry with internal enforced vertices activated + typedef std::set< TEntry > TFaceEntryInternalVerticesList; - static Topology GetDefaultTopology(); - static PhysicalMesh GetDefaultPhysicalMesh(); - static double GetDefaultPhySize(); - static double GetDefaultMaxSize(); - static double GetDefaultMinSize(); - static GeometricMesh GetDefaultGeometricMesh(); - static double GetDefaultAngleMeshS(); - static double GetDefaultAngleMeshC() { return GetDefaultAngleMeshS(); } - static double GetDefaultGradation(); - static bool GetDefaultQuadAllowed(); - static bool GetDefaultDecimesh(); - static int GetDefaultVerbosity() { return 10; } + // Map Face Entry / List of coords + typedef std::map< TEntry, TEnfVertexCoordsList > TFaceEntryCoordsListMap; + + // Map Face Entry / List of Vertex entry + typedef std::map< TEntry, TEntryList > TFaceEntryEnfVertexEntryListMap; + + // Map Coords / Enforced vertex + typedef std::map< TEnfVertexCoords, TEnfVertex* > TCoordsEnfVertexMap; + + // Map Vertex entry / Enforced vertex + typedef std::map< TEntry, TEnfVertex* > TEnfVertexEntryEnfVertexMap; + + typedef std::map< TEnfGroupName, std::set > TGroupNameNodeIDMap; + /* TODO GROUPS + // Map Group Name / List of enforced vertices + typedef std::map< TEnfGroupName , TEnfVertexList > TGroupNameEnfVertexListMap; + */ + + + bool SetEnforcedVertex(TEntry theFaceEntry, TEnfName theVertexName, TEntry theVertexEntry, TEnfGroupName theGroupName, + double x = 0.0, double y = 0.0, double z = 0.0); + TEnfVertexList GetEnfVertexList(const TEntry& theFaceEntry) throw (std::invalid_argument); + TEnfVertexCoordsList GetEnfVertexCoordsList(const TEntry& theFaceEntry) throw (std::invalid_argument); + TEntryList GetEnfVertexEntryList (const TEntry& theFaceEntry) throw (std::invalid_argument); + TEnfVertex* GetEnfVertex(TEnfVertexCoords coords) throw (std::invalid_argument); + TEnfVertex* GetEnfVertex(const TEntry& theEnfVertexEntry) throw (std::invalid_argument); + void AddEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID); + std::set GetEnfVertexNodeIDs(TEnfGroupName theGroupName) throw (std::invalid_argument); + void RemoveEnfVertexNodeID(TEnfGroupName theGroupName,int theNodeID) throw (std::invalid_argument); + + bool ClearEnforcedVertex(const TEntry& theFaceEntry, double x = 0.0, double y = 0.0, double z = 0.0, const TEntry& theVertexEntry="") throw (std::invalid_argument); + bool ClearEnforcedVertices(const TEntry& theFaceEntry) throw (std::invalid_argument); + + void ClearAllEnforcedVertices(); + + const TFaceEntryEnfVertexListMap _GetAllEnforcedVerticesByFace() const { return _faceEntryEnfVertexListMap; } + const TEnfVertexList _GetAllEnforcedVertices() const { return _enfVertexList; } + + const TFaceEntryCoordsListMap _GetAllCoordsByFace() const { return _faceEntryCoordsListMap; } + const TCoordsEnfVertexMap _GetAllEnforcedVerticesByCoords() const { return _coordsEnfVertexMap; } + + const TFaceEntryEnfVertexEntryListMap _GetAllEnfVertexEntriesByFace() const { return _faceEntryEnfVertexEntryListMap; } + const TEnfVertexEntryEnfVertexMap _GetAllEnforcedVerticesByEnfVertexEntry() const { return _enfVertexEntryEnfVertexMap; } + +// TODO GROUPS +// const TEnfVertexGroupNameMap _GetEnforcedVertexGroupNameMap() const { return _enfVertexGroupNameMap; } + + + /*! + * \brief Return the enforced vertices + */ + static TFaceEntryEnfVertexListMap GetAllEnforcedVerticesByFace(const BLSURFPlugin_Hypothesis* hyp); + static TEnfVertexList GetAllEnforcedVertices(const BLSURFPlugin_Hypothesis* hyp); + + static TFaceEntryCoordsListMap GetAllCoordsByFace(const BLSURFPlugin_Hypothesis* hyp); + static TCoordsEnfVertexMap GetAllEnforcedVerticesByCoords(const BLSURFPlugin_Hypothesis* hyp); + + static TFaceEntryEnfVertexEntryListMap GetAllEnfVertexEntriesByFace(const BLSURFPlugin_Hypothesis* hyp); + static TEnfVertexEntryEnfVertexMap GetAllEnforcedVerticesByEnfVertexEntry(const BLSURFPlugin_Hypothesis* hyp); + + /*! + * \brief Internal enforced vertices + */ + void SetInternalEnforcedVertexAllFaces(bool toEnforceInternalVertices); + const bool _GetInternalEnforcedVertexAllFaces() const { return _enforcedInternalVerticesAllFaces; } + static bool GetInternalEnforcedVertexAllFaces( const BLSURFPlugin_Hypothesis* hyp ); + void SetInternalEnforcedVertexAllFacesGroup(TEnfGroupName theGroupName); + const TEnfGroupName _GetInternalEnforcedVertexAllFacesGroup() const { return _enforcedInternalVerticesAllFacesGroup; } + static TEnfGroupName GetInternalEnforcedVertexAllFacesGroup( const BLSURFPlugin_Hypothesis* hyp ); + +// Enable internal enforced vertices on specific face if requested by user +// static TFaceEntryInternalVerticesList GetDefaultFaceEntryInternalVerticesMap() { return TFaceEntryInternalVerticesList(); } +// const TFaceEntryInternalVerticesList _GetAllInternalEnforcedVerticesByFace() const { return _faceEntryInternalVerticesList; } +// static TFaceEntryInternalVerticesList GetAllInternalEnforcedVerticesByFace(const BLSURFPlugin_Hypothesis* hyp); +// void SetInternalEnforcedVertex(TEntry theFaceEntry, bool toEnforceInternalVertices, TEnfGroupName theGroupName); +// bool GetInternalEnforcedVertex(const TEntry& theFaceEntry); + + static Topology GetDefaultTopology(); + static PhysicalMesh GetDefaultPhysicalMesh(); + static double GetDefaultPhySize(); + static double GetDefaultMaxSize(); + static double GetDefaultMinSize(); + static GeometricMesh GetDefaultGeometricMesh(); + static double GetDefaultAngleMeshS(); + static double GetDefaultAngleMeshC() { return GetDefaultAngleMeshS(); } + static double GetDefaultGradation(); + static bool GetDefaultQuadAllowed(); + static bool GetDefaultDecimesh(); + static int GetDefaultVerbosity() { return 10; } + // PreCAD + static bool GetDefaultPreCADMergeEdges() { return false; } + static bool GetDefaultPreCADRemoveNanoEdges() { return false; } + static bool GetDefaultPreCADDiscardInput() { return false; } + static double GetDefaultPreCADEpsNano(); + + static TSizeMap GetDefaultSizeMap() { return TSizeMap();} + static TAttractorMap GetDefaultAttractorMap() { return TAttractorMap(); } + + static TFaceEntryEnfVertexListMap GetDefaultFaceEntryEnfVertexListMap() { return TFaceEntryEnfVertexListMap(); } + static TEnfVertexList GetDefaultEnfVertexList() { return TEnfVertexList(); } + static TFaceEntryCoordsListMap GetDefaultFaceEntryCoordsListMap() { return TFaceEntryCoordsListMap(); } + static TCoordsEnfVertexMap GetDefaultCoordsEnfVertexMap() { return TCoordsEnfVertexMap(); } + static TFaceEntryEnfVertexEntryListMap GetDefaultFaceEntryEnfVertexEntryListMap() { return TFaceEntryEnfVertexEntryListMap(); } + static TEnfVertexEntryEnfVertexMap GetDefaultEnfVertexEntryEnfVertexMap() { return TEnfVertexEntryEnfVertexMap(); } + static TGroupNameNodeIDMap GetDefaultGroupNameNodeIDMap() { return TGroupNameNodeIDMap(); } + + static bool GetDefaultInternalEnforcedVertex(); + + /* TODO GROUPS + static TGroupNameEnfVertexListMap GetDefaultGroupNameEnfVertexListMap() { return TGroupNameEnfVertexListMap(); } + static TEnfVertexGroupNameMap GetDefaultEnfVertexGroupNameMap() { return TEnfVertexGroupNameMap(); } + */ static double undefinedDouble() { return -1.0; } @@ -116,10 +328,24 @@ public: void SetOptionValue(const std::string& optionName, const std::string& optionValue) throw (std::invalid_argument); + void SetPreCADOptionValue(const std::string& optionName, + const std::string& optionValue) throw (std::invalid_argument); std::string GetOptionValue(const std::string& optionName) throw (std::invalid_argument); + std::string GetPreCADOptionValue(const std::string& optionName) throw (std::invalid_argument); void ClearOption(const std::string& optionName); + void ClearPreCADOption(const std::string& optionName); const TOptionValues& GetOptionValues() const { return _option2value; } + const TOptionValues& GetPreCADOptionValues() const { return _preCADoption2value; } + /*! + * Sets the file for export resulting mesh in GMF format + */ +// void SetGMFFile(const std::string& theFileName, bool isBinary); + void SetGMFFile(const std::string& theFileName); + std::string GetGMFFile() const { return _GMFFileName; } + static std::string GetDefaultGMFFile(); +// bool GetGMFFileMode() const { return _GMFFileMode; } + // Persistence virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); @@ -140,18 +366,50 @@ public: */ virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + private: - Topology _topology; - PhysicalMesh _physicalMesh; - double _phySize, _phyMin, _phyMax; - GeometricMesh _geometricMesh; - double _angleMeshS, _angleMeshC, _hgeoMin, _hgeoMax; - double _gradation; - bool _quadAllowed; - bool _decimesh; - int _verb; - TOptionValues _option2value; - TOptionNames _doubleOptions, _charOptions; + Topology _topology; + PhysicalMesh _physicalMesh; + double _phySize, _phyMin, _phyMax; + GeometricMesh _geometricMesh; + double _angleMeshS, _angleMeshC, _hgeoMin, _hgeoMax; + double _gradation; + bool _quadAllowed; + bool _decimesh; + int _verb; + + bool _preCADMergeEdges; + bool _preCADRemoveNanoEdges; + bool _preCADDiscardInput; + double _preCADEpsNano; + + TOptionValues _option2value, _preCADoption2value; + TOptionNames _doubleOptions, _charOptions, _preCADdoubleOptions, _preCADcharOptions; + TSizeMap _sizeMap; + TSizeMap _attractors; + TAttractorMap _classAttractors; + TSizeMap _attEntry; + TParamsMap _attParams; + + TFaceEntryEnfVertexListMap _faceEntryEnfVertexListMap; + TEnfVertexList _enfVertexList; + // maps to get "manual" enf vertex (through their coordinates) + TFaceEntryCoordsListMap _faceEntryCoordsListMap; + TCoordsEnfVertexMap _coordsEnfVertexMap; + // maps to get "geom" enf vertex (through their geom entries) + TFaceEntryEnfVertexEntryListMap _faceEntryEnfVertexEntryListMap; + TEnfVertexEntryEnfVertexMap _enfVertexEntryEnfVertexMap; + TGroupNameNodeIDMap _groupNameNodeIDMap; + +// Enable internal enforced vertices on specific face if requested by user +// TFaceEntryInternalVerticesList _faceEntryInternalVerticesList; + bool _enforcedInternalVerticesAllFaces; + TEnfGroupName _enforcedInternalVerticesAllFacesGroup; + + std::string _GMFFileName; +// bool _GMFFileMode; + +// TSizeMap _customSizeMap; }; #endif diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx index 55ca0d8..0190ed0 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx @@ -1,34 +1,40 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_Hypothesis.cxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) +// Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- // #include "BLSURFPlugin_Hypothesis_i.hxx" #include "SMESH_Gen.hxx" +#include "SMESH_Gen_i.hxx" #include "SMESH_PythonDump.hxx" +#include "GEOM_Object.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" #include +#include +#include "boost/regex.hpp" //============================================================================= /*! @@ -37,17 +43,11 @@ * Constructor */ //============================================================================= -BLSURFPlugin_Hypothesis_i:: -BLSURFPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl) - : SALOME::GenericObj_i( thePOA ), - SMESH_Hypothesis_i( thePOA ) -{ +BLSURFPlugin_Hypothesis_i::BLSURFPlugin_Hypothesis_i(PortableServer::POA_ptr thePOA, int theStudyId, + ::SMESH_Gen* theGenImpl) : + SALOME::GenericObj_i(thePOA), SMESH_Hypothesis_i(thePOA) { MESSAGE( "BLSURFPlugin_Hypothesis_i::BLSURFPlugin_Hypothesis_i" ); - myBaseImpl = new ::BLSURFPlugin_Hypothesis (theGenImpl->GetANewId(), - theStudyId, - theGenImpl); + myBaseImpl = new ::BLSURFPlugin_Hypothesis(theGenImpl->GetANewId(), theStudyId, theGenImpl); } //============================================================================= @@ -57,8 +57,7 @@ BLSURFPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, * Destructor */ //============================================================================= -BLSURFPlugin_Hypothesis_i::~BLSURFPlugin_Hypothesis_i() -{ +BLSURFPlugin_Hypothesis_i::~BLSURFPlugin_Hypothesis_i() { MESSAGE( "BLSURFPlugin_Hypothesis_i::~BLSURFPlugin_Hypothesis_i" ); } @@ -69,11 +68,10 @@ BLSURFPlugin_Hypothesis_i::~BLSURFPlugin_Hypothesis_i() */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetTopology (CORBA::Long theValue) -{ +void BLSURFPlugin_Hypothesis_i::SetTopology(CORBA::Long theValue) { // MESSAGE("BLSURFPlugin_Hypothesis_i::SetTopology"); ASSERT(myBaseImpl); - this->GetImpl()->SetTopology((::BLSURFPlugin_Hypothesis::Topology)theValue); + this->GetImpl()->SetTopology((::BLSURFPlugin_Hypothesis::Topology) theValue); SMESH::TPythonDump() << _this() << ".SetTopology( " << theValue << " )"; } @@ -84,8 +82,7 @@ void BLSURFPlugin_Hypothesis_i::SetTopology (CORBA::Long theValue) * Get Topology */ //============================================================================= -CORBA::Long BLSURFPlugin_Hypothesis_i::GetTopology() -{ +CORBA::Long BLSURFPlugin_Hypothesis_i::GetTopology() { // MESSAGE("BLSURFPlugin_Hypothesis_i::GetTopology"); ASSERT(myBaseImpl); return this->GetImpl()->GetTopology(); @@ -101,11 +98,10 @@ CORBA::Long BLSURFPlugin_Hypothesis_i::GetTopology() */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetPhysicalMesh (CORBA::Long theValue) -{ +void BLSURFPlugin_Hypothesis_i::SetPhysicalMesh(CORBA::Long theValue) { // MESSAGE("BLSURFPlugin_Hypothesis_i::SetPhysicalMesh"); ASSERT(myBaseImpl); - this->GetImpl()->SetPhysicalMesh((::BLSURFPlugin_Hypothesis::PhysicalMesh)theValue); + this->GetImpl()->SetPhysicalMesh((::BLSURFPlugin_Hypothesis::PhysicalMesh) theValue); SMESH::TPythonDump() << _this() << ".SetPhysicalMesh( " << theValue << " )"; } @@ -116,8 +112,7 @@ void BLSURFPlugin_Hypothesis_i::SetPhysicalMesh (CORBA::Long theValue) * Get PhysicalMesh */ //============================================================================= -CORBA::Long BLSURFPlugin_Hypothesis_i::GetPhysicalMesh() -{ +CORBA::Long BLSURFPlugin_Hypothesis_i::GetPhysicalMesh() { // MESSAGE("BLSURFPlugin_Hypothesis_i::GetPhysicalMesh"); ASSERT(myBaseImpl); return this->GetImpl()->GetPhysicalMesh(); @@ -130,9 +125,8 @@ CORBA::Long BLSURFPlugin_Hypothesis_i::GetPhysicalMesh() * Set PhySize */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetPhySize (CORBA::Double theValue) -{ - // MESSAGE("BLSURFPlugin_Hypothesis_i::SetPhySize"); +void BLSURFPlugin_Hypothesis_i::SetPhySize(CORBA::Double theValue) { +// MESSAGE("BLSURFPlugin_Hypothesis_i::SetPhySize"); ASSERT(myBaseImpl); this->GetImpl()->SetPhySize(theValue); SMESH::TPythonDump() << _this() << ".SetPhySize( " << theValue << " )"; @@ -145,49 +139,42 @@ void BLSURFPlugin_Hypothesis_i::SetPhySize (CORBA::Double theValue) * Get PhySize */ //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetPhySize() -{ - // MESSAGE("BLSURFPlugin_Hypothesis_i::GetPhySize"); +CORBA::Double BLSURFPlugin_Hypothesis_i::GetPhySize() { +// MESSAGE("BLSURFPlugin_Hypothesis_i::GetPhySize"); ASSERT(myBaseImpl); return this->GetImpl()->GetPhySize(); } //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetPhyMin(CORBA::Double theMinSize) -{ +void BLSURFPlugin_Hypothesis_i::SetPhyMin(CORBA::Double theMinSize) { ASSERT(myBaseImpl); - if ( GetPhyMin() != theMinSize ) { + if (GetPhyMin() != theMinSize) { this->GetImpl()->SetPhyMin(theMinSize); SMESH::TPythonDump() << _this() << ".SetPhyMin( " << theMinSize << " )"; } } //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetPhyMin() -{ +CORBA::Double BLSURFPlugin_Hypothesis_i::GetPhyMin() { ASSERT(myBaseImpl); return this->GetImpl()->GetPhyMin(); } - //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetPhyMax(CORBA::Double theMaxSize) -{ +void BLSURFPlugin_Hypothesis_i::SetPhyMax(CORBA::Double theMaxSize) { ASSERT(myBaseImpl); - if ( GetPhyMax() != theMaxSize ) { + if (GetPhyMax() != theMaxSize) { this->GetImpl()->SetPhyMax(theMaxSize); SMESH::TPythonDump() << _this() << ".SetPhyMax( " << theMaxSize << " )"; } } //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetPhyMax() -{ +CORBA::Double BLSURFPlugin_Hypothesis_i::GetPhyMax() { ASSERT(myBaseImpl); return this->GetImpl()->GetPhyMax(); } - //============================================================================= /*! * BLSURFPlugin_Hypothesis_i::SetGeometricMesh @@ -196,11 +183,10 @@ CORBA::Double BLSURFPlugin_Hypothesis_i::GetPhyMax() */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetGeometricMesh (CORBA::Long theValue) -{ +void BLSURFPlugin_Hypothesis_i::SetGeometricMesh(CORBA::Long theValue) { // MESSAGE("BLSURFPlugin_Hypothesis_i::SetGeometricMesh"); ASSERT(myBaseImpl); - this->GetImpl()->SetGeometricMesh((::BLSURFPlugin_Hypothesis::GeometricMesh)theValue); + this->GetImpl()->SetGeometricMesh((::BLSURFPlugin_Hypothesis::GeometricMesh) theValue); SMESH::TPythonDump() << _this() << ".SetGeometricMesh( " << theValue << " )"; } @@ -211,8 +197,7 @@ void BLSURFPlugin_Hypothesis_i::SetGeometricMesh (CORBA::Long theValue) * Get GeometricMesh */ //============================================================================= -CORBA::Long BLSURFPlugin_Hypothesis_i::GetGeometricMesh() -{ +CORBA::Long BLSURFPlugin_Hypothesis_i::GetGeometricMesh() { // MESSAGE("BLSURFPlugin_Hypothesis_i::GetGeometricMesh"); ASSERT(myBaseImpl); return this->GetImpl()->GetGeometricMesh(); @@ -225,8 +210,7 @@ CORBA::Long BLSURFPlugin_Hypothesis_i::GetGeometricMesh() * Set AngleMeshS */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetAngleMeshS (CORBA::Double theValue) -{ +void BLSURFPlugin_Hypothesis_i::SetAngleMeshS(CORBA::Double theValue) { // MESSAGE("BLSURFPlugin_Hypothesis_i::SetAngleMeshS"); ASSERT(myBaseImpl); this->GetImpl()->SetAngleMeshS(theValue); @@ -240,58 +224,51 @@ void BLSURFPlugin_Hypothesis_i::SetAngleMeshS (CORBA::Double theValue) * Get AngleMeshS */ //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetAngleMeshS() -{ +CORBA::Double BLSURFPlugin_Hypothesis_i::GetAngleMeshS() { // MESSAGE("BLSURFPlugin_Hypothesis_i::GetAngleMeshS"); ASSERT(myBaseImpl); return this->GetImpl()->GetAngleMeshS(); } //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetAngleMeshC(CORBA::Double angle) -{ +void BLSURFPlugin_Hypothesis_i::SetAngleMeshC(CORBA::Double angle) { ASSERT(myBaseImpl); this->GetImpl()->SetAngleMeshC(angle); SMESH::TPythonDump() << _this() << ".SetAngleMeshC( " << angle << " )"; } //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetAngleMeshC() -{ +CORBA::Double BLSURFPlugin_Hypothesis_i::GetAngleMeshC() { ASSERT(myBaseImpl); return this->GetImpl()->GetAngleMeshC(); } //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetGeoMin(CORBA::Double theMinSize) -{ +void BLSURFPlugin_Hypothesis_i::SetGeoMin(CORBA::Double theMinSize) { ASSERT(myBaseImpl); - if ( GetGeoMin() != theMinSize ) { + if (GetGeoMin() != theMinSize) { this->GetImpl()->SetGeoMin(theMinSize); SMESH::TPythonDump() << _this() << ".SetGeoMin( " << theMinSize << " )"; } } //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetGeoMin() -{ +CORBA::Double BLSURFPlugin_Hypothesis_i::GetGeoMin() { ASSERT(myBaseImpl); return this->GetImpl()->GetGeoMin(); } //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetGeoMax(CORBA::Double theMaxSize) -{ +void BLSURFPlugin_Hypothesis_i::SetGeoMax(CORBA::Double theMaxSize) { ASSERT(myBaseImpl); - if ( GetGeoMax() != theMaxSize ) { + if (GetGeoMax() != theMaxSize) { this->GetImpl()->SetGeoMax(theMaxSize); SMESH::TPythonDump() << _this() << ".SetGeoMax( " << theMaxSize << " )"; } } //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetGeoMax() -{ +CORBA::Double BLSURFPlugin_Hypothesis_i::GetGeoMax() { ASSERT(myBaseImpl); return this->GetImpl()->GetGeoMax(); } @@ -303,8 +280,7 @@ CORBA::Double BLSURFPlugin_Hypothesis_i::GetGeoMax() * Set Gradation */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetGradation (CORBA::Double theValue) -{ +void BLSURFPlugin_Hypothesis_i::SetGradation(CORBA::Double theValue) { // MESSAGE("BLSURFPlugin_Hypothesis_i::SetGradation"); ASSERT(myBaseImpl); this->GetImpl()->SetGradation(theValue); @@ -318,8 +294,7 @@ void BLSURFPlugin_Hypothesis_i::SetGradation (CORBA::Double theValue) * Get Gradation */ //============================================================================= -CORBA::Double BLSURFPlugin_Hypothesis_i::GetGradation() -{ +CORBA::Double BLSURFPlugin_Hypothesis_i::GetGradation() { // MESSAGE("BLSURFPlugin_Hypothesis_i::GetGradation"); ASSERT(myBaseImpl); return this->GetImpl()->GetGradation(); @@ -332,12 +307,12 @@ CORBA::Double BLSURFPlugin_Hypothesis_i::GetGradation() * Set true or false */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetQuadAllowed (CORBA::Boolean theValue) -{ +void BLSURFPlugin_Hypothesis_i::SetQuadAllowed(CORBA::Boolean theValue) { // MESSAGE("BLSURFPlugin_Hypothesis_i::SetQuadAllowed"); ASSERT(myBaseImpl); this->GetImpl()->SetQuadAllowed(theValue); - SMESH::TPythonDump() << _this() << ".SetQuadAllowed( " << theValue << " )"; + std::string theValueStr = theValue ? "True" : "False"; + SMESH::TPythonDump() << _this() << ".SetQuadAllowed( " << theValueStr.c_str() << " )"; } //============================================================================= @@ -347,8 +322,7 @@ void BLSURFPlugin_Hypothesis_i::SetQuadAllowed (CORBA::Boolean theValue) * Get true or false */ //============================================================================= -CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetQuadAllowed() -{ +CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetQuadAllowed() { // MESSAGE("BLSURFPlugin_Hypothesis_i::GetQuadAllowed"); ASSERT(myBaseImpl); return this->GetImpl()->GetQuadAllowed(); @@ -361,12 +335,12 @@ CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetQuadAllowed() * Set true or false */ //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetDecimesh (CORBA::Boolean theValue) -{ +void BLSURFPlugin_Hypothesis_i::SetDecimesh(CORBA::Boolean theValue) { // MESSAGE("BLSURFPlugin_Hypothesis_i::SetDecimesh"); ASSERT(myBaseImpl); this->GetImpl()->SetDecimesh(theValue); - SMESH::TPythonDump() << _this() << ".SetDecimesh( " << theValue << " )"; + std::string theValueStr = theValue ? "True" : "False"; + SMESH::TPythonDump() << _this() << ".SetDecimesh( " << theValueStr.c_str() << " )"; } //============================================================================= @@ -376,19 +350,16 @@ void BLSURFPlugin_Hypothesis_i::SetDecimesh (CORBA::Boolean theValue) * Get true or false */ //============================================================================= -CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetDecimesh() -{ +CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetDecimesh() { // MESSAGE("BLSURFPlugin_Hypothesis_i::GetDecimesh"); ASSERT(myBaseImpl); return this->GetImpl()->GetDecimesh(); } //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetVerbosity(CORBA::Short theVal) - throw (SALOME::SALOME_Exception) -{ +void BLSURFPlugin_Hypothesis_i::SetVerbosity(CORBA::Short theVal) throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); - if ( theVal < 0 || theVal > 100 ) + if (theVal < 0 || theVal > 100) THROW_SALOME_CORBA_EXCEPTION( "Invalid verbosity level",SALOME::BAD_PARAM ); this->GetImpl()->SetVerbosity(theVal); SMESH::TPythonDump() << _this() << ".SetVerbosity( " << theVal << " )"; @@ -396,59 +367,203 @@ void BLSURFPlugin_Hypothesis_i::SetVerbosity(CORBA::Short theVal) //============================================================================= -CORBA::Short BLSURFPlugin_Hypothesis_i::GetVerbosity() -{ +CORBA::Short BLSURFPlugin_Hypothesis_i::GetVerbosity() { ASSERT(myBaseImpl); return (CORBA::Short) this->GetImpl()->GetVerbosity(); } //============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::SetPreCADMergeEdges + * + * Set true or false + */ +//============================================================================= +void BLSURFPlugin_Hypothesis_i::SetPreCADMergeEdges(CORBA::Boolean theValue) { + // MESSAGE("BLSURFPlugin_Hypothesis_i::SetPreCADMergeEdges"); + ASSERT(myBaseImpl); + this->GetImpl()->SetPreCADMergeEdges(theValue); + std::string theValueStr = theValue ? "True" : "False"; + SMESH::TPythonDump() << _this() << ".SetPreCADMergeEdges( " << theValueStr.c_str() << " )"; +} -void BLSURFPlugin_Hypothesis_i::SetOptionValue(const char* optionName, - const char* optionValue) - throw (SALOME::SALOME_Exception) -{ +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::GetPreCADMergeEdges + * + * Get true or false + */ +//============================================================================= +CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetPreCADMergeEdges() { + // MESSAGE("BLSURFPlugin_Hypothesis_i::GetPreCADMergeEdges"); + ASSERT(myBaseImpl); + return this->GetImpl()->GetPreCADMergeEdges(); +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::SetPreCADRemoveNanoEdges + * + * Set true or false + */ +//============================================================================= +void BLSURFPlugin_Hypothesis_i::SetPreCADRemoveNanoEdges(CORBA::Boolean theValue) { + // MESSAGE("BLSURFPlugin_Hypothesis_i::SetPreCADRemoveNanoEdges"); + ASSERT(myBaseImpl); + this->GetImpl()->SetPreCADRemoveNanoEdges(theValue); + std::string theValueStr = theValue ? "True" : "False"; + SMESH::TPythonDump() << _this() << ".SetPreCADRemoveNanoEdges( " << theValueStr.c_str() << " )"; +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::GetPreCADRemoveNanoEdges + * + * Get true or false + */ +//============================================================================= +CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetPreCADRemoveNanoEdges() { + // MESSAGE("BLSURFPlugin_Hypothesis_i::GetPreCADRemoveNanoEdges"); + ASSERT(myBaseImpl); + return this->GetImpl()->GetPreCADRemoveNanoEdges(); +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::SetPreCADDiscardInput + * + * Set true or false + */ +//============================================================================= +void BLSURFPlugin_Hypothesis_i::SetPreCADDiscardInput(CORBA::Boolean theValue) { + // MESSAGE("BLSURFPlugin_Hypothesis_i::SetPreCADDiscardInput"); + ASSERT(myBaseImpl); + this->GetImpl()->SetPreCADDiscardInput(theValue); + std::string theValueStr = theValue ? "True" : "False"; + SMESH::TPythonDump() << _this() << ".SetPreCADDiscardInput( " << theValueStr.c_str() << " )"; +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::GetPreCADDiscardInput + * + * Get true or false + */ +//============================================================================= +CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetPreCADDiscardInput() { + // MESSAGE("BLSURFPlugin_Hypothesis_i::GetPreCADDiscardInput"); + ASSERT(myBaseImpl); + return this->GetImpl()->GetPreCADDiscardInput(); +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::SetPreCADEpsNano + * + * Set length for nano edges + */ +//============================================================================= +void BLSURFPlugin_Hypothesis_i::SetPreCADEpsNano(CORBA::Double theValue) { + // MESSAGE("BLSURFPlugin_Hypothesis_i::SetPreCADEpsNano"); + ASSERT(myBaseImpl); + this->GetImpl()->SetPreCADEpsNano(theValue); + SMESH::TPythonDump() << _this() << ".SetPreCADEpsNano( " << theValue << " )"; +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::GetPreCADEpsNano + * + * Get length of nano edges + */ +//============================================================================= +CORBA::Double BLSURFPlugin_Hypothesis_i::GetPreCADEpsNano() { + // MESSAGE("BLSURFPlugin_Hypothesis_i::GetPreCADEpsNano"); + ASSERT(myBaseImpl); + return this->GetImpl()->GetPreCADEpsNano(); +} + +//============================================================================= + +void BLSURFPlugin_Hypothesis_i::SetOptionValue(const char* optionName, const char* optionValue) + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); bool valueChanged = false; try { - valueChanged = ( this->GetImpl()->GetOptionValue(optionName) != optionValue ); - if ( valueChanged ) + valueChanged = (this->GetImpl()->GetOptionValue(optionName) != optionValue); + if (valueChanged) this->GetImpl()->SetOptionValue(optionName, optionValue); - } - catch (const std::invalid_argument& ex) { + } catch (const std::invalid_argument& ex) { SALOME::ExceptionStruct ExDescription; ExDescription.text = ex.what(); ExDescription.type = SALOME::BAD_PARAM; ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetOptionValue(name,value)"; ExDescription.lineNumber = 0; throw SALOME::SALOME_Exception(ExDescription); - } - catch (SALOME_Exception& ex) { + } catch (SALOME_Exception& ex) { THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } - if ( valueChanged ) - SMESH::TPythonDump() << _this() << ".SetOptionValue( '" - << optionName << "', '" << optionValue << "' )"; + if (valueChanged) + SMESH::TPythonDump() << _this() << ".SetOptionValue( '" << optionName << "', '" << optionValue << "' )"; } //============================================================================= -char* BLSURFPlugin_Hypothesis_i::GetOptionValue(const char* optionName) - throw (SALOME::SALOME_Exception) -{ +void BLSURFPlugin_Hypothesis_i::SetPreCADOptionValue(const char* optionName, const char* optionValue) + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); + bool valueChanged = false; try { - return CORBA::string_dup( this->GetImpl()->GetOptionValue(optionName).c_str() ); + valueChanged = (this->GetImpl()->GetPreCADOptionValue(optionName) != optionValue); + if (valueChanged) + this->GetImpl()->SetPreCADOptionValue(optionName, optionValue); + } catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetPreCADOptionValue(name,value)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } - catch (const std::invalid_argument& ex) { + if (valueChanged) + SMESH::TPythonDump() << _this() << ".SetPreCADOptionValue( '" << optionName << "', '" << optionValue << "' )"; +} + +//============================================================================= + +char* BLSURFPlugin_Hypothesis_i::GetOptionValue(const char* optionName) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + try { + return CORBA::string_dup(this->GetImpl()->GetOptionValue(optionName).c_str()); + } catch (const std::invalid_argument& ex) { SALOME::ExceptionStruct ExDescription; ExDescription.text = ex.what(); ExDescription.type = SALOME::BAD_PARAM; ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::GetOptionValue(name)"; ExDescription.lineNumber = 0; throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } - catch (SALOME_Exception& ex) { + return 0; +} + +//============================================================================= + +char* BLSURFPlugin_Hypothesis_i::GetPreCADOptionValue(const char* optionName) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + try { + return CORBA::string_dup(this->GetImpl()->GetPreCADOptionValue(optionName).c_str()); + } catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::GetPreCADOptionValue(name)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } return 0; @@ -456,8 +571,7 @@ char* BLSURFPlugin_Hypothesis_i::GetOptionValue(const char* optionName) //============================================================================= -void BLSURFPlugin_Hypothesis_i::UnsetOption(const char* optionName) -{ +void BLSURFPlugin_Hypothesis_i::UnsetOption(const char* optionName) { ASSERT(myBaseImpl); this->GetImpl()->ClearOption(optionName); SMESH::TPythonDump() << _this() << ".UnsetOption( '" << optionName << "' )"; @@ -465,18 +579,46 @@ void BLSURFPlugin_Hypothesis_i::UnsetOption(const char* optionName) //============================================================================= -BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetOptionValues() -{ +void BLSURFPlugin_Hypothesis_i::UnsetPreCADOption(const char* optionName) { + ASSERT(myBaseImpl); + this->GetImpl()->ClearPreCADOption(optionName); + SMESH::TPythonDump() << _this() << ".UnsetPreCADOption( '" << optionName << "' )"; +} + +//============================================================================= + +BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetOptionValues() { ASSERT(myBaseImpl); BLSURFPlugin::string_array_var result = new BLSURFPlugin::string_array(); const ::BLSURFPlugin_Hypothesis::TOptionValues & opts = this->GetImpl()->GetOptionValues(); - result->length( opts.size() ); + result->length(opts.size()); + + ::BLSURFPlugin_Hypothesis::TOptionValues::const_iterator opIt = opts.begin(); + for (int i = 0; opIt != opts.end(); ++opIt, ++i) { + string name_value = opIt->first; + if (!opIt->second.empty()) { + name_value += ":"; + name_value += opIt->second; + } + result[i] = CORBA::string_dup(name_value.c_str()); + } + return result._retn(); +} + +//============================================================================= + +BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetPreCADOptionValues() { + ASSERT(myBaseImpl); + BLSURFPlugin::string_array_var result = new BLSURFPlugin::string_array(); + + const ::BLSURFPlugin_Hypothesis::TOptionValues & opts = this->GetImpl()->GetPreCADOptionValues(); + result->length(opts.size()); ::BLSURFPlugin_Hypothesis::TOptionValues::const_iterator opIt = opts.begin(); - for ( int i = 0 ; opIt != opts.end(); ++opIt, ++i ) { + for (int i = 0; opIt != opts.end(); ++opIt, ++i) { string name_value = opIt->first; - if ( !opIt->second.empty() ) { + if (!opIt->second.empty()) { name_value += ":"; name_value += opIt->second; } @@ -488,48 +630,1773 @@ BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetOptionValues() //============================================================================= void BLSURFPlugin_Hypothesis_i::SetOptionValues(const BLSURFPlugin::string_array& options) - throw (SALOME::SALOME_Exception) -{ + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); - for (int i = 0; i < options.length(); ++i) - { + for (int i = 0; i < options.length(); ++i) { string name_value = options[i].in(); - int colonPos = name_value.find( ':' ); + int colonPos = name_value.find(':'); string name, value; - if ( colonPos == string::npos ) // ':' not found + if (colonPos == string::npos) // ':' not found name = name_value; else { - name = name_value.substr( 0, colonPos); - if ( colonPos < name_value.size()-1 && name_value[colonPos] != ' ') - value = name_value.substr( colonPos+1 ); + name = name_value.substr(0, colonPos); + if (colonPos < name_value.size() - 1 && name_value[colonPos] != ' ') + value = name_value.substr(colonPos + 1); } - SetOptionValue( name.c_str(), value.c_str() ); + SetOptionValue(name.c_str(), value.c_str()); } } //============================================================================= -/*! - * BLSURFPlugin_Hypothesis_i::GetImpl - * - * Get implementation - */ + +void BLSURFPlugin_Hypothesis_i::SetPreCADOptionValues(const BLSURFPlugin::string_array& options) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + for (int i = 0; i < options.length(); ++i) { + string name_value = options[i].in(); + int colonPos = name_value.find(':'); + string name, value; + if (colonPos == string::npos) // ':' not found + name = name_value; + else { + name = name_value.substr(0, colonPos); + if (colonPos < name_value.size() - 1 && name_value[colonPos] != ' ') + value = name_value.substr(colonPos + 1); + } + SetPreCADOptionValue(name.c_str(), value.c_str()); + } +} + //============================================================================= -::BLSURFPlugin_Hypothesis* BLSURFPlugin_Hypothesis_i::GetImpl() -{ - // MESSAGE("BLSURFPlugin_Hypothesis_i::GetImpl"); - return (::BLSURFPlugin_Hypothesis*)myBaseImpl; + +void BLSURFPlugin_Hypothesis_i::SetSizeMapEntry(const char* entry, const char* sizeMap) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + MESSAGE("ENGINE : SETSIZEMAP START ENTRY : " << entry); + bool valueChanged = false; + try { + valueChanged = (this->GetImpl()->GetSizeMapEntry(entry) != sizeMap); + if (valueChanged) + this->GetImpl()->SetSizeMapEntry(entry, sizeMap); + } catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetSizeMapEntry(entry,sizemap)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + MESSAGE("ENGINE : SETSIZEMAP END ENTRY : " << entry); + if (valueChanged) + SMESH::TPythonDump() << _this() << ".SetSizeMap(" << entry << ", '" << sizeMap << "' )"; } -//================================================================================ -/*! - * \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 BLSURFPlugin_Hypothesis_i::IsDimSupported( SMESH::Dimension type ) +//============================================================================= + +void BLSURFPlugin_Hypothesis_i::SetAttractorEntry(const char* entry, const char* attractor) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + MESSAGE("ENGINE : SETATTRACTOR START ENTRY : " << entry); + bool valueChanged = false; + try { + valueChanged = ( this->GetImpl()->GetAttractorEntry(entry) != attractor ); + if ( valueChanged ) { + boost::regex re("^ATTRACTOR\\((?:(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+);){5}(True|False)(?:;(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+))?\\)$"); + if (!boost::regex_match(string(attractor), re)) + throw std::invalid_argument("Error: an attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b;True|False;d(opt.))"); + this->GetImpl()->SetAttractorEntry(entry, attractor); + } + } catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetAttractorEntry(entry,attractor)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + MESSAGE("ENGINE : SETATTRACTOR END ENTRY : " << entry); + if (valueChanged) + SMESH::TPythonDump() << _this() << ".SetAttractor(" << entry << ", '" << attractor << "' )"; +} + +//============================================================================= + +void BLSURFPlugin_Hypothesis_i::SetClassAttractorEntry(const char* entry, const char* att_entry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) //TODO à finir + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + MESSAGE("ENGINE : SETATTRACTOR START ENTRY : " << entry); + bool valueChanged = false; + try { + this->GetImpl()->SetClassAttractorEntry(entry, att_entry, StartSize, EndSize, ActionRadius, ConstantRadius); + } + catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetClassAttractorEntry(entry, att_entry, StartSize, EndSize, ActionRadius, ConstantRadius)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + MESSAGE("ENGINE : SETATTRACTOR END ENTRY : " << entry); + //if ( valueChanged ) + SMESH::TPythonDump() << _this() << ".SetAttractorGeom(" + << entry << ", " << att_entry << ", "<GetImpl()->GetSizeMapEntry(entry).c_str()); + } catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::GetSizeMapEntry(name)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + return 0; +} + +//============================================================================= + +char* BLSURFPlugin_Hypothesis_i::GetAttractorEntry(const char* entry) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + try { + return CORBA::string_dup(this->GetImpl()->GetAttractorEntry(entry).c_str()); + } catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::GetAttractorEntry(name)"; + ExDescription.lineNumber = 0; + throw SALOME::SALOME_Exception(ExDescription); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + return 0; +} + +// //============================================================================= +// +// // TODO coder cette fonction (utilisée pour savoir si la valeur a changé +// // A finir pour le dump +// char* BLSURFPlugin_Hypothesis_i::GetClassAttractorEntry(const char* entry) +// throw (SALOME::SALOME_Exception) +// { +// ASSERT(myBaseImpl); +// try { +// return CORBA::string_dup( this->GetImpl()->GetClassAttractorEntry(entry).c_str()); +// } +// catch (const std::invalid_argument& ex) { +// SALOME::ExceptionStruct ExDescription; +// ExDescription.text = ex.what(); +// ExDescription.type = SALOME::BAD_PARAM; +// ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::GetClassAttractorEntry(name)"; +// ExDescription.lineNumber = 0; +// throw SALOME::SALOME_Exception(ExDescription); +// } +// catch (SALOME_Exception& ex) { +// THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); +// } +// return 0; +// } + +//============================================================================= + +void BLSURFPlugin_Hypothesis_i::UnsetEntry(const char* entry) { + ASSERT(myBaseImpl); + this->GetImpl()->ClearEntry(entry); + // SMESH::TPythonDump() << _this() << ".UnsetSizeMap( " << entry << " )"; +} + +//============================================================================= + +BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetSizeMapEntries() { + ASSERT(myBaseImpl); + BLSURFPlugin::string_array_var result = new BLSURFPlugin::string_array(); + + const ::BLSURFPlugin_Hypothesis::TSizeMap sizeMaps = this->GetImpl()->_GetSizeMapEntries(); + result->length(sizeMaps.size()); + + ::BLSURFPlugin_Hypothesis::TSizeMap::const_iterator smIt = sizeMaps.begin(); + for (int i = 0; smIt != sizeMaps.end(); ++smIt, ++i) { + string entry_sizemap = smIt->first; + if (!smIt->second.empty()) { + entry_sizemap += "|"; + entry_sizemap += smIt->second; + } + result[i] = CORBA::string_dup(entry_sizemap.c_str()); + } + return result._retn(); +} + +//============================================================================= + +BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetAttractorEntries() { + ASSERT(myBaseImpl); + BLSURFPlugin::string_array_var result = new BLSURFPlugin::string_array(); + + const ::BLSURFPlugin_Hypothesis::TSizeMap attractors = this->GetImpl()->_GetAttractorEntries(); + result->length(attractors.size()); + + ::BLSURFPlugin_Hypothesis::TSizeMap::const_iterator atIt = attractors.begin(); + for (int i = 0; atIt != attractors.end(); ++atIt, ++i) { + string entry_attractor = atIt->first; + if (!atIt->second.empty()) { + entry_attractor += "|"; + entry_attractor += atIt->second; + } + result[i] = CORBA::string_dup(entry_attractor.c_str()); + } + return result._retn(); +} + +//============================================================================= + +BLSURFPlugin::TAttParamsMap* BLSURFPlugin_Hypothesis_i::GetAttractorParams() +{ + ASSERT(myBaseImpl); + BLSURFPlugin::TAttParamsMap_var result = new BLSURFPlugin::TAttParamsMap(); + + const ::BLSURFPlugin_Hypothesis::TAttractorMap attractors= this->GetImpl()->_GetClassAttractorEntries(); + result->length( attractors.size() ); + + ::BLSURFPlugin_Hypothesis::TAttractorMap::const_iterator atIt = attractors.begin(); + for ( int i = 0 ; atIt != attractors.end(); ++atIt, ++i ) { + string faceEntry = atIt->first; + string attEntry; + double startSize, endSize, infDist, constDist; + if ( !atIt->second->Empty() ) { + attEntry = atIt->second->GetAttractorEntry(); + MESSAGE("GetAttractorParams : attEntry ="< params = atIt->second->GetParameters(); + startSize = params[0]; + endSize = params[1]; + infDist = params[2]; + constDist = params[3]; + } + result[i].faceEntry = CORBA::string_dup(faceEntry.c_str()); + result[i].attEntry = CORBA::string_dup(attEntry.c_str()); + result[i].startSize = startSize; + result[i].endSize = endSize; + result[i].infDist = infDist; + result[i].constDist = constDist; + MESSAGE("GetAttractorParams : result[i].attEntry ="<GetName()); + MESSAGE("IDL : SETSIZEMAP ( "<< entry << " , " << sizeMap << ")"); + SetSizeMapEntry(entry.c_str(), sizeMap); +} + +//============================================================================= +void BLSURFPlugin_Hypothesis_i::UnsetSizeMap(const GEOM::GEOM_Object_ptr GeomObj) { + ASSERT(myBaseImpl); + string entry; + entry = GeomObj->GetStudyEntry(); + MESSAGE("IDL : GetName : " << GeomObj->GetName()); + MESSAGE("IDL : UNSETSIZEMAP ( "<< entry << ")"); + UnsetEntry(entry.c_str()); + SMESH::TPythonDump() << _this() << ".UnsetSizeMap( " << entry.c_str() << " )"; +} + +void BLSURFPlugin_Hypothesis_i::SetAttractor(GEOM::GEOM_Object_ptr GeomObj, const char* attractor) { + ASSERT(myBaseImpl); + string entry; + entry = GeomObj->GetStudyEntry(); + MESSAGE("IDL : GetName : " << GeomObj->GetName()); + MESSAGE("IDL : SETATTRACTOR ( "<< entry << " , " << attractor << ")"); + SetAttractorEntry(entry.c_str(), attractor); +} + +void BLSURFPlugin_Hypothesis_i::UnsetAttractor(GEOM::GEOM_Object_ptr GeomObj) { + ASSERT(myBaseImpl); + string entry; + entry = GeomObj->GetStudyEntry(); + MESSAGE("IDL : GetName : " << GeomObj->GetName()); + MESSAGE("IDL : UNSETATTRACTOR ( "<< entry << ")"); + UnsetEntry(entry.c_str()); + SMESH::TPythonDump() << _this() << ".UnsetAttractor( " << entry.c_str() << " )"; +} + +void BLSURFPlugin_Hypothesis_i::SetAttractorGeom(GEOM::GEOM_Object_ptr theFace, GEOM::GEOM_Object_ptr theAttractor, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) +{ + ASSERT(myBaseImpl); + string theFaceEntry; + string theAttEntry; + theFaceEntry = theFace->GetStudyEntry(); + theAttEntry = theAttractor->GetStudyEntry(); + + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + + if (theFaceEntry.empty()) { + aName = "Face_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + if (theAttEntry.empty()) { + if (theAttractor->GetShapeType() == GEOM::VERTEX) + aName = "Vertex_"; + if (theAttractor->GetShapeType() == GEOM::EDGE) + aName = "Edge_"; + if (theAttractor->GetShapeType() == GEOM::WIRE) + aName = "Wire_"; + if (theAttractor->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theAttractor->GetEntry(); + SALOMEDS::SObject_ptr theSAtt = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theAttractor, aName.c_str()); + if (!theSAtt->_is_nil()) + theAttEntry = theSAtt->GetID(); + } + if (theAttEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + TopoDS_Face FaceShape = TopoDS::Face(SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theFace )); + TopoDS_Shape AttractorShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theAttractor ); + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : SETATTRACTOR () ");//<< entry << " , " << att_entry << ")"); + SetClassAttractorEntry( theFaceEntry.c_str(), theAttEntry.c_str(), StartSize, EndSize, ActionRadius, ConstantRadius); +} + +void BLSURFPlugin_Hypothesis_i::UnsetAttractorGeom(GEOM::GEOM_Object_ptr theFace) +{ + ASSERT(myBaseImpl); + string theFaceEntry; + theFaceEntry = theFace->GetStudyEntry(); + + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + + if (theFaceEntry.empty()) { + aName = "Face_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : UNSETATTRACTOR ( "<< theFaceEntry << ")"); + UnsetEntry( theFaceEntry.c_str()); + SMESH::TPythonDump() << _this() << ".UnsetAttractorGeom( " << theFaceEntry.c_str() << " )"; +} + +/* + void BLSURFPlugin_Hypothesis_i::SetCustomSizeMap(GEOM::GEOM_Object_ptr GeomObj, const char* sizeMap) + {} + + void BLSURFPlugin_Hypothesis_i::UnsetCustomSizeMap(GEOM::GEOM_Object_ptr GeomObj) + {} + + void BLSURFPlugin_Hypothesis_i::SetCustomSizeMapEntry(const char* entry,const char* sizeMap ) throw (SALOME::SALOME_Exception) + {} + + char* BLSURFPlugin_Hypothesis_i::GetCustomSizeMapEntry(const char* entry) throw (SALOME::SALOME_Exception) + {} + + void BLSURFPlugin_Hypothesis_i::UnsetCustomSizeMapEntry(const char* entry) + { + ASSERT(myBaseImpl); + this->GetImpl()->UnsetCustomSizeMap(entry); + SMESH::TPythonDump() << _this() << ".UnsetCustomSizeMap( " << entry << " )"; + } + + + BLSURFPlugin::string_array* BLSURFPlugin_Hypothesis_i::GetCustomSizeMapEntries() + {} + + */ + +// /////////////////////// +// // ENFORCED VERTICES // +// /////////////////////// + + +/** + * Returns the list of enforced vertices for a given Face entry + * @return A map of Face entry / List of enforced vertices + * + */ +BLSURFPlugin::TFaceEntryEnfVertexListMap* BLSURFPlugin_Hypothesis_i::GetAllEnforcedVerticesByFace() { + MESSAGE("IDL: GetAllEnforcedVerticesByFace()"); + ASSERT(myBaseImpl); + + BLSURFPlugin::TFaceEntryEnfVertexListMap_var resultMap = new BLSURFPlugin::TFaceEntryEnfVertexListMap(); + + const ::BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap faceEntryEnfVertexListMap = + this->GetImpl()->_GetAllEnforcedVerticesByFace(); + resultMap->length(faceEntryEnfVertexListMap.size()); + MESSAGE("Face entry to Enforced Vertex map size is " << resultMap->length()); + + ::BLSURFPlugin_Hypothesis::TEnfVertexList _enfVertexList; + ::BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap::const_iterator it_entry = faceEntryEnfVertexListMap.begin(); + for (int i = 0; it_entry != faceEntryEnfVertexListMap.end(); ++it_entry, ++i) { + BLSURFPlugin::TFaceEntryEnfVertexListMapElement_var mapElement = + new BLSURFPlugin::TFaceEntryEnfVertexListMapElement(); + mapElement->faceEntry = CORBA::string_dup(it_entry->first.c_str()); + MESSAGE("Face Entry: " << mapElement->faceEntry); + + _enfVertexList = it_entry->second; + BLSURFPlugin::TEnfVertexList_var enfVertexList = new BLSURFPlugin::TEnfVertexList(); + enfVertexList->length(_enfVertexList.size()); + MESSAGE("Number of enf vertex: " << enfVertexList->length()); + + ::BLSURFPlugin_Hypothesis::TEnfVertexList::const_iterator it_enfVertex = _enfVertexList.begin(); + ::BLSURFPlugin_Hypothesis::TEnfVertex *currentEnfVertex; + for (int j = 0; it_enfVertex != _enfVertexList.end(); ++it_enfVertex, ++j) { + currentEnfVertex = (*it_enfVertex); + + BLSURFPlugin::TEnfVertex_var enfVertex = new BLSURFPlugin::TEnfVertex(); + + // Name + enfVertex->name = CORBA::string_dup(currentEnfVertex->name.c_str()); + + // Geom entry + enfVertex->geomEntry = CORBA::string_dup(currentEnfVertex->geomEntry.c_str()); + + // Coords + BLSURFPlugin::TEnfVertexCoords_var coords = new BLSURFPlugin::TEnfVertexCoords(); + coords->length(currentEnfVertex->coords.size()); + for (int i=0;ilength();i++) + coords[i] = currentEnfVertex->coords[i]; + enfVertex->coords = coords; + + // Group name + enfVertex->grpName = CORBA::string_dup(currentEnfVertex->grpName.c_str()); + + // Face entry list + BLSURFPlugin::TEntryList_var faceEntryList = new BLSURFPlugin::TEntryList(); + faceEntryList->length(currentEnfVertex->faceEntries.size()); + ::BLSURFPlugin_Hypothesis::TEntryList::const_iterator it_entry = currentEnfVertex->faceEntries.begin(); + for (int ind = 0; it_entry != currentEnfVertex->faceEntries.end();++it_entry, ++ind) + faceEntryList[ind] = CORBA::string_dup((*it_entry).c_str()); + enfVertex->faceEntries = faceEntryList; + + ostringstream msg; + msg << "Enforced vertex: \n" + << "Name: " << enfVertex->name << "\n"; + if (coords->length()) + msg << "Coords: " << enfVertex->coords[0] << ", " << enfVertex->coords[1] << ", " << enfVertex->coords[2] << "\n"; + msg << "Geom entry: " << enfVertex->geomEntry << "\n" + << "Group Name: " << enfVertex->grpName; + MESSAGE(msg.str()); + + enfVertexList[j] = enfVertex; + } + mapElement->enfVertexList = enfVertexList; + + resultMap[i] = mapElement; + + } + return resultMap._retn(); +} + +/** + * Returns the list of all enforced vertices + * @return a list of enforced vertices + * + */ +BLSURFPlugin::TEnfVertexList* BLSURFPlugin_Hypothesis_i::GetAllEnforcedVertices() { + MESSAGE("IDL: GetAllEnforcedVertices()"); + ASSERT(myBaseImpl); + BLSURFPlugin::TEnfVertexList_var resultMap = new BLSURFPlugin::TEnfVertexList(); + const ::BLSURFPlugin_Hypothesis::TEnfVertexList enfVertexList = this->GetImpl()->_GetAllEnforcedVertices(); + resultMap->length(enfVertexList.size()); + MESSAGE("Enforced Vertex map size is " << resultMap->length()); + + ::BLSURFPlugin_Hypothesis::TEnfVertexList::const_iterator evlIt = enfVertexList.begin(); + ::BLSURFPlugin_Hypothesis::TEnfVertex *currentEnfVertex; + for (int i = 0; evlIt != enfVertexList.end(); ++evlIt, ++i) { + MESSAGE("Enforced Vertex #" << i); + currentEnfVertex = (*evlIt); + BLSURFPlugin::TEnfVertex_var enfVertex = new BLSURFPlugin::TEnfVertex(); + // Name + enfVertex->name = CORBA::string_dup(currentEnfVertex->name.c_str()); + // Geom entry + enfVertex->geomEntry = CORBA::string_dup(currentEnfVertex->geomEntry.c_str()); + // Coords + BLSURFPlugin::TEnfVertexCoords_var coords = new BLSURFPlugin::TEnfVertexCoords(); + coords->length(currentEnfVertex->coords.size()); + for (int ind = 0; ind < coords->length(); ind++) + coords[ind] = currentEnfVertex->coords[ind]; + enfVertex->coords = coords; + // Group name + enfVertex->grpName = CORBA::string_dup(currentEnfVertex->grpName.c_str()); + // Face entry list + BLSURFPlugin::TEntryList_var faceEntryList = new BLSURFPlugin::TEntryList(); + faceEntryList->length(currentEnfVertex->faceEntries.size()); + ::BLSURFPlugin_Hypothesis::TEntryList::const_iterator it_entry = currentEnfVertex->faceEntries.begin(); + for (int ind = 0; it_entry != currentEnfVertex->faceEntries.end();++it_entry, ++ind) + faceEntryList[ind] = CORBA::string_dup((*it_entry).c_str()); + enfVertex->faceEntries = faceEntryList; + + ostringstream msg; + msg << "Enforced vertex: \n" + << "Name: " << enfVertex->name << "\n"; + if (coords->length()) + msg << "Coords: " << enfVertex->coords[0] << ", " << enfVertex->coords[1] << ", " << enfVertex->coords[2] << "\n"; + msg << "Geom entry: " << enfVertex->geomEntry << "\n" + << "Group Name: " << enfVertex->grpName; + MESSAGE(msg.str()); + + resultMap[i] = enfVertex; + } + return resultMap._retn(); + +} + +/** + * Returns the list of enforced vertices coords for a given Face entry. + * They are the coords of the "manual" enforced vertices. + * @return A map of Face entry / List of enforced vertices coords + * + */ +BLSURFPlugin::TFaceEntryCoordsListMap* BLSURFPlugin_Hypothesis_i::GetAllCoordsByFace() { + MESSAGE("IDL: GetAllCoordsByFace()"); + ASSERT(myBaseImpl); + + BLSURFPlugin::TFaceEntryCoordsListMap_var resultMap = new BLSURFPlugin::TFaceEntryCoordsListMap(); + + const ::BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap entryCoordsListMap = this->GetImpl()->_GetAllCoordsByFace(); + resultMap->length(entryCoordsListMap.size()); + MESSAGE("Enforced Vertex map size is " << resultMap->length()); + + ::BLSURFPlugin_Hypothesis::TEnfVertexCoordsList _coordsList; + ::BLSURFPlugin_Hypothesis::TFaceEntryCoordsListMap::const_iterator it_entry = entryCoordsListMap.begin(); + for (int i = 0; it_entry != entryCoordsListMap.end(); ++it_entry, ++i) { + BLSURFPlugin::TFaceEntryCoordsListMapElement_var mapElement = new BLSURFPlugin::TFaceEntryCoordsListMapElement(); + mapElement->faceEntry = CORBA::string_dup(it_entry->first.c_str()); + MESSAGE("Face Entry: " << mapElement->faceEntry); + + _coordsList = it_entry->second; + BLSURFPlugin::TEnfVertexCoordsList_var coordsList = new BLSURFPlugin::TEnfVertexCoordsList(); + coordsList->length(_coordsList.size()); + MESSAGE("Number of coords: " << coordsList->length()); + + ::BLSURFPlugin_Hypothesis::TEnfVertexCoordsList::const_iterator it_coords = _coordsList.begin(); + for (int j = 0; it_coords != _coordsList.end(); ++it_coords, ++j) { + BLSURFPlugin::TEnfVertexCoords_var coords = new BLSURFPlugin::TEnfVertexCoords(); + coords->length((*it_coords).size()); + for (int i=0;ilength();i++) + coords[i] = (*it_coords)[i]; + coordsList[j] = coords; + MESSAGE("Coords #" << j << ": " << coords[0] << ", " << coords[1] << ", " << coords[2]); + } + mapElement->coordsList = coordsList; + + resultMap[i] = mapElement; + + } + return resultMap._retn(); +} + +/** + * Returns a map of enforced vertices coords / enforced vertex. + * They are the coords of the "manual" enforced vertices. + */ +BLSURFPlugin::TCoordsEnfVertexMap* BLSURFPlugin_Hypothesis_i::GetAllEnforcedVerticesByCoords() { + MESSAGE("IDL: GetAllEnforcedVerticesByCoords()"); + ASSERT(myBaseImpl); + + BLSURFPlugin::TCoordsEnfVertexMap_var resultMap = new BLSURFPlugin::TCoordsEnfVertexMap(); + const ::BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap coordsEnfVertexMap = + this->GetImpl()->_GetAllEnforcedVerticesByCoords(); + resultMap->length(coordsEnfVertexMap.size()); + MESSAGE("Enforced Vertex map size is " << resultMap->length()); + + ::BLSURFPlugin_Hypothesis::TCoordsEnfVertexMap::const_iterator it_coords = coordsEnfVertexMap.begin(); + ::BLSURFPlugin_Hypothesis::TEnfVertex *currentEnfVertex; + for (int i = 0; it_coords != coordsEnfVertexMap.end(); ++it_coords, ++i) { + MESSAGE("Enforced Vertex #" << i); + currentEnfVertex = (it_coords->second); + BLSURFPlugin::TCoordsEnfVertexElement_var mapElement = new BLSURFPlugin::TCoordsEnfVertexElement(); + BLSURFPlugin::TEnfVertexCoords_var coords = new BLSURFPlugin::TEnfVertexCoords(); + coords->length(it_coords->first.size()); + for (int ind=0;indlength();ind++) + coords[ind] = it_coords->first[ind]; + mapElement->coords = coords; + MESSAGE("Coords: " << mapElement->coords[0] << ", " << mapElement->coords[1] << ", " << mapElement->coords[2]); + + BLSURFPlugin::TEnfVertex_var enfVertex = new BLSURFPlugin::TEnfVertex(); + // Name + enfVertex->name = CORBA::string_dup(currentEnfVertex->name.c_str()); + // Geom entry + enfVertex->geomEntry = CORBA::string_dup(currentEnfVertex->geomEntry.c_str()); + // Coords + BLSURFPlugin::TEnfVertexCoords_var coords2 = new BLSURFPlugin::TEnfVertexCoords(); + coords2->length(currentEnfVertex->coords.size()); + for (int ind=0;indlength();ind++) + coords2[ind] = currentEnfVertex->coords[ind]; + enfVertex->coords = coords2; + // Group name + enfVertex->grpName = CORBA::string_dup(currentEnfVertex->grpName.c_str()); + // Face entry list + BLSURFPlugin::TEntryList_var faceEntryList = new BLSURFPlugin::TEntryList(); + faceEntryList->length(currentEnfVertex->faceEntries.size()); + ::BLSURFPlugin_Hypothesis::TEntryList::const_iterator it_entry = currentEnfVertex->faceEntries.begin(); + for (int ind = 0; it_entry != currentEnfVertex->faceEntries.end();++it_entry, ++ind) + faceEntryList[ind] = CORBA::string_dup((*it_entry).c_str()); + enfVertex->faceEntries = faceEntryList; + + mapElement->enfVertex = enfVertex; + ostringstream msg; + msg << "Enforced vertex: \n" + << "Name: " << enfVertex->name << "\n"; + if (coords->length()) + msg << "Coords: " << enfVertex->coords[0] << ", " << enfVertex->coords[1] << ", " << enfVertex->coords[2] << "\n"; + msg << "Geom entry: " << enfVertex->geomEntry << "\n" + << "Group Name: " << enfVertex->grpName; + MESSAGE(msg.str()); + + resultMap[i] = mapElement; + } + return resultMap._retn(); +} + +/** + * Returns the list of enforced vertices entries for a given Face entry. + * They are the geom entries of the enforced vertices based on geom shape (vertex, compound, group). + * @return A map of Face entry / List of enforced vertices geom entries + * + */ +BLSURFPlugin::TFaceEntryEnfVertexEntryListMap* BLSURFPlugin_Hypothesis_i::GetAllEnfVertexEntriesByFace() { + MESSAGE("IDL: GetAllEnfVertexEntriesByFace()"); + ASSERT(myBaseImpl); + + BLSURFPlugin::TFaceEntryEnfVertexEntryListMap_var resultMap = new BLSURFPlugin::TFaceEntryEnfVertexEntryListMap(); + + const ::BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap entryEnfVertexEntryListMap = + this->GetImpl()->_GetAllEnfVertexEntriesByFace(); + resultMap->length(entryEnfVertexEntryListMap.size()); + MESSAGE("Enforced Vertex map size is " << resultMap->length()); + + ::BLSURFPlugin_Hypothesis::TEntryList _enfVertexEntryList; + ::BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexEntryListMap::const_iterator it_entry = + entryEnfVertexEntryListMap.begin(); + for (int i = 0; it_entry != entryEnfVertexEntryListMap.end(); ++it_entry, ++i) { + BLSURFPlugin::TFaceEntryEnfVertexEntryListMapElement_var mapElement = + new BLSURFPlugin::TFaceEntryEnfVertexEntryListMapElement(); + mapElement->faceEntry = CORBA::string_dup(it_entry->first.c_str()); + MESSAGE("Face Entry: " << mapElement->faceEntry); + + _enfVertexEntryList = it_entry->second; + BLSURFPlugin::TEntryList_var enfVertexEntryList = new BLSURFPlugin::TEntryList(); + enfVertexEntryList->length(_enfVertexEntryList.size()); + MESSAGE("Number of enf vertex entries: " << enfVertexEntryList->length()); + + ::BLSURFPlugin_Hypothesis::TEntryList::const_iterator it_enfVertexEntry = _enfVertexEntryList.begin(); + for (int j = 0; it_enfVertexEntry != _enfVertexEntryList.end(); ++it_enfVertexEntry, ++j) { + enfVertexEntryList[j] = CORBA::string_dup((*it_enfVertexEntry).c_str()); + MESSAGE("Enf Vertex Entry #" << j << ": " << enfVertexEntryList[j]); + } + mapElement->enfVertexEntryList = enfVertexEntryList; + + resultMap[i] = mapElement; + + } + return resultMap._retn(); +} + +/** + * Returns a map of enforced vertices geom entry / enforced vertex. + * They are the geom entries of the enforced vertices defined with geom shape (vertex, compound, group). + */ +BLSURFPlugin::TEnfVertexEntryEnfVertexMap* BLSURFPlugin_Hypothesis_i::GetAllEnforcedVerticesByEnfVertexEntry() { + MESSAGE("IDL: GetAllEnforcedVerticesByEnfVertexEntry()"); + ASSERT(myBaseImpl); + + BLSURFPlugin::TEnfVertexEntryEnfVertexMap_var resultMap = new BLSURFPlugin::TEnfVertexEntryEnfVertexMap(); + const ::BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap enfVertexEntryEnfVertexMap = + this->GetImpl()->_GetAllEnforcedVerticesByEnfVertexEntry(); + resultMap->length(enfVertexEntryEnfVertexMap.size()); + MESSAGE("Enforced Vertex map size is " << resultMap->length()); + + ::BLSURFPlugin_Hypothesis::TEnfVertexEntryEnfVertexMap::const_iterator it_enfVertexEntry = enfVertexEntryEnfVertexMap.begin(); + ::BLSURFPlugin_Hypothesis::TEnfVertex *currentEnfVertex; + for (int i = 0; it_enfVertexEntry != enfVertexEntryEnfVertexMap.end(); ++it_enfVertexEntry, ++i) { + MESSAGE("Enforced Vertex #" << i); + currentEnfVertex = it_enfVertexEntry->second; + BLSURFPlugin::TEnfVertexEntryEnfVertexElement_var mapElement = new BLSURFPlugin::TEnfVertexEntryEnfVertexElement(); + mapElement->enfVertexEntry = CORBA::string_dup(it_enfVertexEntry->first.c_str());; + MESSAGE("Enf Vertex Entry #" << i << ": " << mapElement->enfVertexEntry); + + BLSURFPlugin::TEnfVertex_var enfVertex = new BLSURFPlugin::TEnfVertex(); + // Name + enfVertex->name = CORBA::string_dup(currentEnfVertex->name.c_str()); + // Geom entry + enfVertex->geomEntry = CORBA::string_dup(currentEnfVertex->geomEntry.c_str()); + // Coords + BLSURFPlugin::TEnfVertexCoords_var coords = new BLSURFPlugin::TEnfVertexCoords(); + coords->length(currentEnfVertex->coords.size()); + for (int ind=0;indlength();ind++) + coords[ind] = currentEnfVertex->coords[ind]; + enfVertex->coords = coords; + // Group name + enfVertex->grpName = CORBA::string_dup(currentEnfVertex->grpName.c_str()); + // Face entry list + BLSURFPlugin::TEntryList_var faceEntryList = new BLSURFPlugin::TEntryList(); + faceEntryList->length(currentEnfVertex->faceEntries.size()); + ::BLSURFPlugin_Hypothesis::TEntryList::const_iterator it_entry = currentEnfVertex->faceEntries.begin(); + for (int ind = 0; it_entry != currentEnfVertex->faceEntries.end();++it_entry, ++ind) + faceEntryList[ind] = CORBA::string_dup((*it_entry).c_str()); + enfVertex->faceEntries = faceEntryList; + + ostringstream msg; + msg << "Enforced vertex: \n" + << "Name: " << enfVertex->name << "\n"; + if (coords->length()) + msg << "Coords: " << enfVertex->coords[0] << ", " << enfVertex->coords[1] << ", " << enfVertex->coords[2] << "\n"; + msg << "Geom entry: " << enfVertex->geomEntry << "\n" + << "Group Name: " << enfVertex->grpName; + MESSAGE(msg.str()); + + mapElement->enfVertex = enfVertex; + resultMap[i] = mapElement; + } + return resultMap._retn(); +} + +/** + * Erase all enforced vertices + */ +void BLSURFPlugin_Hypothesis_i::ClearAllEnforcedVertices() { + ASSERT(myBaseImpl); + this->GetImpl()->ClearAllEnforcedVertices(); + SMESH::TPythonDump() << _this() << ".ClearAllEnforcedVertices()"; +} + +/*! + * Set/get/unset an enforced vertex on face + */ +bool BLSURFPlugin_Hypothesis_i::SetEnforcedVertex(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, + CORBA::Double z) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : SetEnforcedVertex( "<< theFaceEntry << ", " << x << ", " << y << ", " << z << ")"); + try { + return SetEnforcedVertexEntry(theFaceEntry.c_str(), x, y, z); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +/*! + * Set/get/unset an enforced vertex with name on face + */ +bool BLSURFPlugin_Hypothesis_i::SetEnforcedVertexNamed(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, + CORBA::Double z, const char* theVertexName) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : SetEnforcedVertexNamed( "<< theFaceEntry << ", " << x << ", " << y << ", " << z << ", " << theVertexName << ")"); + try { + return SetEnforcedVertexEntry(theFaceEntry.c_str(), x, y, z, theVertexName); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +/*! + * Set/get/unset an enforced vertex with geom object on face + */ +bool BLSURFPlugin_Hypothesis_i::SetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theFace, GEOM::GEOM_Object_ptr theVertex) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theVertex shape type is not VERTEX or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM); + } + + // GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + // GEOM::GEOM_IMeasureOperations_var measureOp = geomGen->GetIMeasureOperations(this->GetImpl()->GetStudyId()); + // if (CORBA::is_nil(measureOp)) + // return false; + // + // CORBA::Double x, y, z; + // x = y = z = 0.; + // measureOp->PointCoordinates(theVertex, x, y, z); + + string theFaceEntry = theFace->GetStudyEntry(); + string theVertexEntry = theVertex->GetStudyEntry(); + + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + + if (theFaceEntry.empty()) { + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + if (theVertexEntry.empty()) { + if (theVertex->GetShapeType() == GEOM::VERTEX) + aName = "Vertex_"; + if (theVertex->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theVertex->GetEntry(); + SALOMEDS::SObject_ptr theSVertex = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theVertex, aName.c_str()); + if (!theSVertex->_is_nil()) + theVertexEntry = theSVertex->GetID(); + } + if (theVertexEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + string theVertexName = theVertex->GetName(); + MESSAGE("IDL : theFace->GetName : " << theFace->GetName()); + MESSAGE("IDL : theVertex->GetName : " << theVertexName); + MESSAGE("IDL : SetEnforcedVertexGeom( "<< theFaceEntry << ", " << theVertexEntry<< ")"); + try { + return SetEnforcedVertexEntry(theFaceEntry.c_str(), 0, 0, 0, theVertexName.c_str(), theVertexEntry.c_str()); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +/*! + * Set an enforced vertex with group name on face + */ +bool BLSURFPlugin_Hypothesis_i::SetEnforcedVertexWithGroup(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, CORBA::Double z, const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : SetEnforcedVertexWithGroup( "<< theFaceEntry << ", " << x << ", " << y << ", " << z << ", " << theGroupName << ")"); + try { + return SetEnforcedVertexEntry(theFaceEntry.c_str(), x, y, z, "", "", theGroupName); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +/*! + * Set an enforced vertex with name and group name on face + */ +bool BLSURFPlugin_Hypothesis_i::SetEnforcedVertexNamedWithGroup(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, CORBA::Double z, + const char* theVertexName, const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : SetEnforcedVertexNamedWithGroup( "<< theFaceEntry << ", " << x << ", " << y << ", " << z << ", " << theVertexName << ", " << theGroupName << ")"); + try { + return SetEnforcedVertexEntry(theFaceEntry.c_str(), x, y, z, theVertexName, "", theGroupName); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +/*! + * Set an enforced vertex with geom entry and group name on face + */ +bool BLSURFPlugin_Hypothesis_i::SetEnforcedVertexGeomWithGroup(GEOM::GEOM_Object_ptr theFace, GEOM::GEOM_Object_ptr theVertex, const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theVertex shape type is not VERTEX or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + string theVertexEntry = theVertex->GetStudyEntry(); + + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + + if (theFaceEntry.empty()) { + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + if (theVertexEntry.empty()) { + if (theVertex->GetShapeType() == GEOM::VERTEX) + aName = "Vertex_"; + if (theVertex->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theVertex->GetEntry(); + SALOMEDS::SObject_ptr theSVertex = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theVertex, aName.c_str()); + if (!theSVertex->_is_nil()) + theVertexEntry = theSVertex->GetID(); + } + if (theVertexEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + string theVertexName = theVertex->GetName(); + MESSAGE("IDL : theFace->GetName : " << theFace->GetName()); + MESSAGE("IDL : theVertex->GetName : " << theVertexName); + MESSAGE("IDL : SetEnforcedVertexGeomWithGroup( "<< theFaceEntry << ", " << theVertexEntry<< ", " << theGroupName<< ")"); + try { + return SetEnforcedVertexEntry(theFaceEntry.c_str(), 0, 0, 0, theVertexName.c_str(), theVertexEntry.c_str(), theGroupName); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +//Enable internal enforced vertices on specific face if requested by user +///*! +// * Are internal enforced vertices used for a face ? +// */ +//CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertex(GEOM::GEOM_Object_ptr theFace) +// throw (SALOME::SALOME_Exception) { +// ASSERT(myBaseImpl); + +// if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { +// MESSAGE("theFace shape type is not FACE or COMPOUND"); +// THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); +// } + +// string theFaceEntry = theFace->GetStudyEntry(); + +// if (theFaceEntry.empty()) { +// GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); +// SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); +// string aName; +// if (theFace->GetShapeType() == GEOM::FACE) +// aName = "Face_"; +// if (theFace->GetShapeType() == GEOM::COMPOUND) +// aName = "Compound_"; +// aName += theFace->GetEntry(); +// SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); +// if (!theSFace->_is_nil()) +// theFaceEntry = theSFace->GetID(); +// } +// if (theFaceEntry.empty()) +// THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + +// MESSAGE("IDL : GetName : " << theFace->GetName()); +// MESSAGE("IDL : GetInternalEnforcedVertexEntry ( "<< theFaceEntry << ")"); +// try { +// return GetInternalEnforcedVertexEntry(theFaceEntry.c_str()); +// } catch (SALOME_Exception& ex) { +// THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); +// } +//} + +/*! + * Get the list of all enforced vertices + */ +BLSURFPlugin::TEnfVertexList* BLSURFPlugin_Hypothesis_i::GetEnforcedVertices(GEOM::GEOM_Object_ptr theFace) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : GetEnforcedVerticesEntry ( "<< theFaceEntry << ")"); + try { + return GetEnforcedVerticesEntry(theFaceEntry.c_str()); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +bool BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertex(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, + CORBA::Double z) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : UnsetEnforcedVertex ( "<< theFaceEntry << ", " << x << ", " << y << ", " << z << ")"); + + try { + return UnsetEnforcedVertexEntry(theFaceEntry.c_str(), x, y, z); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +bool BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theFace, GEOM::GEOM_Object_ptr theVertex) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theVertex shape type is not VERTEX or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM); + } + + // GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + // GEOM::GEOM_IMeasureOperations_var measureOp = geomGen->GetIMeasureOperations(this->GetImpl()->GetStudyId()); + // if (CORBA::is_nil(measureOp)) + // return false; + // + // CORBA::Double x, y, z; + // x = y = z = 0.; + // measureOp->PointCoordinates(theVertex, x, y, z); + + std::string theFaceEntry = theFace->GetStudyEntry(); + std::string theVertexEntry = theVertex->GetStudyEntry(); + + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + + if (theFaceEntry.empty()) { + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + if (theVertexEntry.empty()) { + if (theVertex->GetShapeType() == GEOM::VERTEX) + aName = "Vertex_"; + if (theVertex->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theVertex->GetEntry(); + SALOMEDS::SObject_ptr theSVertex = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theVertex, aName.c_str()); + if (!theSVertex->_is_nil()) + theVertexEntry = theSVertex->GetID(); + } + if (theVertexEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + MESSAGE("IDL : UnsetEnforcedVertexGeom ( "<< theFaceEntry << ", " << theVertexEntry << ")"); + + try { + return UnsetEnforcedVertexEntry(theFaceEntry.c_str(), 0, 0, 0, theVertexEntry.c_str()); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +bool BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertices(GEOM::GEOM_Object_ptr theFace) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : UnsetEnforcedVertices ( "<< theFaceEntry << ")"); + + try { + return UnsetEnforcedVerticesEntry(theFaceEntry.c_str()); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +/*! + * Set/get/unset an enforced vertex on geom object given by entry + */ +bool BLSURFPlugin_Hypothesis_i::SetEnforcedVertexEntry(const char* theFaceEntry, CORBA::Double x, CORBA::Double y, + CORBA::Double z, const char* theVertexName, const char* theVertexEntry, const char* theGroupName) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + MESSAGE("IDL : SetEnforcedVertexEntry(" << theFaceEntry << ", " << x << ", " << y << ", " << z << ", \"" << theVertexName << "\", \"" << theVertexEntry << "\", \"" << theGroupName << "\")"); + bool newValue = false; + if (string(theVertexEntry).empty()) { + try { + ::BLSURFPlugin_Hypothesis::TEnfVertexCoordsList coordsList = + this->GetImpl()->GetEnfVertexCoordsList(theFaceEntry); + ::BLSURFPlugin_Hypothesis::TEnfVertexCoords coords; + coords.push_back(x); + coords.push_back(y); + coords.push_back(z); + if (coordsList.find(coords) == coordsList.end()) { + MESSAGE("Coords not found: add it in coordsList"); + newValue = true; + } else { + MESSAGE("Coords already found, compare names"); + ::BLSURFPlugin_Hypothesis::TEnfVertex *enfVertex = this->GetImpl()->GetEnfVertex(coords); + if ((enfVertex->name != theVertexName) || (enfVertex->grpName != theGroupName)) { + MESSAGE("The names are different: update"); +// this->GetImpl()->ClearEnforcedVertex(theFaceEntry, x, y, z); + newValue = true; + } + else { + MESSAGE("The names are identical"); + } + } + } catch (const std::invalid_argument& ex) { + // no enforced vertex for entry + MESSAGE("Face entry not found : add it to the list"); + newValue = true; + } + if (newValue) + if (string(theVertexName).empty()) + if (string(theGroupName).empty()) + SMESH::TPythonDump() << _this() << ".SetEnforcedVertex(" << theFaceEntry << ", " << x << ", " << y << ", " << z << ")"; + else + SMESH::TPythonDump() << _this() << ".SetEnforcedVertexWithGroup(" << theFaceEntry << ", " << x << ", " << y << ", " << z << ", \"" << theGroupName << "\")"; + else + if (string(theGroupName).empty()) + SMESH::TPythonDump() << _this() << ".SetEnforcedVertexNamed(" << theFaceEntry << ", " << x << ", " << y << ", " << z << ", \"" << theVertexName << "\")"; + else + SMESH::TPythonDump() << _this() << ".SetEnforcedVertexNamedWithGroup(" << theFaceEntry << ", " << x << ", " << y << ", " << z << ", \"" + << theVertexName << "\", \"" << theGroupName << "\")"; + } else { + try { + ::BLSURFPlugin_Hypothesis::TEntryList enfVertexEntryList = this->GetImpl()->GetEnfVertexEntryList(theFaceEntry); + ::BLSURFPlugin_Hypothesis::TEntryList::const_iterator it = enfVertexEntryList.find(theVertexEntry); + if ( it == enfVertexEntryList.end()) { + MESSAGE("Geom entry not found: add it in enfVertexEntryList"); + newValue = true; + } + else { + MESSAGE("Geom entry already found, compare names"); + ::BLSURFPlugin_Hypothesis::TEnfVertex *enfVertex = this->GetImpl()->GetEnfVertex((*it)); + if ((enfVertex->name != theVertexName) || (enfVertex->grpName != theGroupName)) { + MESSAGE("The names are different: update"); +// this->GetImpl()->ClearEnforcedVertex(theFaceEntry, x, y, z); + newValue = true; + } + else { + MESSAGE("The names are identical"); + } + } + } catch (const std::invalid_argument& ex) { + // no enforced vertex for entry + MESSAGE("Face entry not found : add it to the list"); + newValue = true; + } + if (newValue) + if (string(theGroupName).empty()) + SMESH::TPythonDump() << _this() << ".SetEnforcedVertexGeom(" << theFaceEntry << ", " << theVertexEntry << ")"; + else + SMESH::TPythonDump() << _this() << ".SetEnforcedVertexGeomWithGroup(" << theFaceEntry << ", " << theVertexEntry << ", \"" << theGroupName << "\")"; + } + + if (newValue) + this->GetImpl()->SetEnforcedVertex(theFaceEntry, theVertexName, theVertexEntry, theGroupName, x, y, z); + + MESSAGE("IDL : SetEnforcedVertexEntry END"); + return newValue; +} + +//Enable internal enforced vertices on specific face if requested by user +//CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertexEntry(const char* theFaceEntry) +// throw (SALOME::SALOME_Exception) { +// ASSERT(myBaseImpl); +// try { +// return this->GetImpl()->GetInternalEnforcedVertex(theFaceEntry); +// } catch (const std::exception& ex) { +// std::cout << "Exception: " << ex.what() << std::endl; +// THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); +// } +//} + +BLSURFPlugin::TEnfVertexList* BLSURFPlugin_Hypothesis_i::GetEnforcedVerticesEntry(const char* entry) + throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + MESSAGE("ENGINE : GetEnforcedVerticesEntry START ENTRY : " << entry); + + try { + BLSURFPlugin::TEnfVertexList_var vertexList = new BLSURFPlugin::TEnfVertexList(); + ::BLSURFPlugin_Hypothesis::TEnfVertexList _vList = this->GetImpl()->GetEnfVertexList(entry); + vertexList->length(_vList.size()); + MESSAGE("Number of enforced vertices: " << vertexList->length()); + ::BLSURFPlugin_Hypothesis::TEnfVertexList::const_iterator evlIt = _vList.begin(); + for (int i = 0; evlIt != _vList.end(); ++evlIt, ++i) { + ::BLSURFPlugin_Hypothesis::TEnfVertex *_enfVertex = (*evlIt); + + BLSURFPlugin::TEnfVertex_var enfVertex = new BLSURFPlugin::TEnfVertex(); + + // Name + enfVertex->name = CORBA::string_dup(_enfVertex->name.c_str()); + // Geom Vertex Entry + enfVertex->geomEntry = CORBA::string_dup(_enfVertex->geomEntry.c_str()); + // Coords + BLSURFPlugin::TEnfVertexCoords_var coords = new BLSURFPlugin::TEnfVertexCoords(); + coords->length(_enfVertex->coords.size()); + for (int ind=0;indlength();ind++) + coords[ind] = _enfVertex->coords[ind]; + enfVertex->coords = coords; + // Group Name + enfVertex->grpName = CORBA::string_dup(_enfVertex->grpName.c_str()); + // Face entry list + BLSURFPlugin::TEntryList_var faceEntryList = new BLSURFPlugin::TEntryList(); + faceEntryList->length(_enfVertex->faceEntries.size()); + ::BLSURFPlugin_Hypothesis::TEntryList::const_iterator it_entry = _enfVertex->faceEntries.begin(); + for (int ind = 0; it_entry != _enfVertex->faceEntries.end();++it_entry, ++ind) + faceEntryList[ind] = CORBA::string_dup((*it_entry).c_str()); + enfVertex->faceEntries = faceEntryList; + + vertexList[i] = enfVertex; + } + MESSAGE("ENGINE : GetEnforcedVerticesEntry END ENTRY : " << entry); + return vertexList._retn(); + } catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis_i::GetEnforcedVerticesEntry(entry)"; + ExDescription.lineNumber = 1385; + throw SALOME::SALOME_Exception(ExDescription); + } catch (const std::exception& ex) { + std::cout << "Exception: " << ex.what() << std::endl; + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +bool BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertexEntry(const char* theFaceEntry, CORBA::Double x, CORBA::Double y, + CORBA::Double z, const char* theVertexEntry) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + MESSAGE("IDL : UnsetEnforcedVertexEntry(" << theFaceEntry << "," << x << "," << y << "," << z << ", " << theVertexEntry << ")"); + + bool res = false; + try { + res = this->GetImpl()->ClearEnforcedVertex(theFaceEntry, x, y, z, theVertexEntry); + + if (string(theVertexEntry).empty()) + SMESH::TPythonDump() << "isDone = " << _this() << ".UnsetEnforcedVertex(" << theFaceEntry << ", " << x << ", " << y << ", " << z + << ")"; + else + SMESH::TPythonDump() << "isDone = " << _this() << ".UnsetEnforcedVertexGeom(" << theFaceEntry << ", " << theVertexEntry << ")"; + + } catch (const std::invalid_argument& ex) { + return false; + } catch (const std::exception& ex) { + std::cout << "Exception: " << ex.what() << std::endl; + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + + MESSAGE("ENGINE : UnsetEnforcedVertexEntry END ENTRY : " << theFaceEntry); + return res; +} + +//bool BLSURFPlugin_Hypothesis_i::UnsetEnforcedVertexEntryWithPoint(const char* theFaceEntry, const char* theVertexEntry, +// CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception) { +// MESSAGE("IDL : UnsetEnforcedVertexEntryWithPoint START theFaceEntry=" << theFaceEntry << ", theVertexEntry=" << theVertexEntry); +// +// bool ret = false; +// +// try { +// ret = _unsetEnfVertex(theFaceEntry, x, y, z); +// } catch (SALOME_Exception& ex) { +// THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); +// } +// +// if (ret) +// SMESH::TPythonDump() << _this() << ".UnsetEnforcedVertexWithPoint(" << theFaceEntry << ", " << theVertexEntry +// << ")"; +// +// MESSAGE("IDL : UnsetEnforcedVertexEntryWithPoint END ENTRY : " << theFaceEntry); +// return ret; +//} + +bool BLSURFPlugin_Hypothesis_i::UnsetEnforcedVerticesEntry(const char* theFaceEntry) throw (SALOME::SALOME_Exception) { + ASSERT(myBaseImpl); + MESSAGE("IDL : UnsetEnforcedVerticesEntry(" << theFaceEntry << ")"); + + try { + this->GetImpl()->ClearEnforcedVertices(theFaceEntry); + SMESH::TPythonDump() << _this() << ".UnsetEnforcedVertices(" << theFaceEntry << ")"; + } catch (const std::invalid_argument& ex) { + return false; + } catch (const std::exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + + MESSAGE("IDL : UnsetEnforcedVerticesEntry END ENTRY : " << theFaceEntry); + return true; +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexAllFaces + * + * Set true or false + */ +//============================================================================= +void BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexAllFaces(CORBA::Boolean theValue) { + MESSAGE("BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexAllFaces"); + ASSERT(myBaseImpl); + this->GetImpl()->SetInternalEnforcedVertexAllFaces(theValue); + std::string theValueStr = theValue ? "True" : "False"; + SMESH::TPythonDump() << _this() << ".SetInternalEnforcedVertexAllFaces( " << theValueStr.c_str() << " )"; +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertexAllFaces + * + * Get true or false + */ +//============================================================================= +CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertexAllFaces() { + MESSAGE("BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertexAllFaces"); + ASSERT(myBaseImpl); + return this->GetImpl()->_GetInternalEnforcedVertexAllFaces(); +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexAllFacesGroup + * + * Set group name + */ +//============================================================================= +void BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexAllFacesGroup(const char* groupName) { + MESSAGE("BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexAllFacesGroup"); + ASSERT(myBaseImpl); + this->GetImpl()->SetInternalEnforcedVertexAllFacesGroup(groupName); + SMESH::TPythonDump() << _this() << ".SetInternalEnforcedVertexAllFacesGroup( \"" << groupName << "\" )"; +} + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertexAllFacesGroup + * + * Get group name + */ +//============================================================================= +char* BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertexAllFacesGroup() { + MESSAGE("BLSURFPlugin_Hypothesis_i::GetInternalEnforcedVertexAllFacesGroup"); + ASSERT(myBaseImpl); + return CORBA::string_dup(this->GetImpl()->_GetInternalEnforcedVertexAllFacesGroup().c_str()); +} + +/* + * Enable internal enforced vertices on specific face if requested by user + * +void BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertex(GEOM::GEOM_Object_ptr theFace, CORBA::Boolean toEnforceInternalVertices) + throw (SALOME::SALOME_Exception) +{ + MESSAGE("BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexForFace"); + try { + SetInternalEnforcedVertexWithGroup(theFace, toEnforceInternalVertices); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +void BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexWithGroup(GEOM::GEOM_Object_ptr theFace, CORBA::Boolean toEnforceInternalVertices, const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + MESSAGE("BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexForFaceWithGroup"); + + if ((theFace->GetShapeType() != GEOM::FACE) && (theFace->GetShapeType() != GEOM::COMPOUND)) { + MESSAGE("theFace shape type is not FACE or COMPOUND"); + THROW_SALOME_CORBA_EXCEPTION("theFace shape type is not FACE or COMPOUND", SALOME::BAD_PARAM); + } + + string theFaceEntry = theFace->GetStudyEntry(); + + if (theFaceEntry.empty()) { + GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine(); + SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); + string aName; + if (theFace->GetShapeType() == GEOM::FACE) + aName = "Face_"; + if (theFace->GetShapeType() == GEOM::COMPOUND) + aName = "Compound_"; + aName += theFace->GetEntry(); + SALOMEDS::SObject_ptr theSFace = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theFace, aName.c_str()); + if (!theSFace->_is_nil()) + theFaceEntry = theSFace->GetID(); + } + if (theFaceEntry.empty()) + THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM ); + + MESSAGE("IDL : GetName : " << theFace->GetName()); + MESSAGE("IDL : GetInternalEnforcedVertexEntry ( "<< theFaceEntry << ")"); + try { + SetInternalEnforcedVertexEntry(theFaceEntry.c_str(), toEnforceInternalVertices, theGroupName); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +void BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexEntry(const char* theFaceEntry, CORBA::Boolean toEnforceInternalVertices, const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + MESSAGE("BLSURFPlugin_Hypothesis_i::SetInternalEnforcedVertexForFaceEntry"); + ASSERT(myBaseImpl); + try { + this->GetImpl()->SetInternalEnforcedVertex(theFaceEntry, toEnforceInternalVertices, theGroupName); + std::string theValueStr = toEnforceInternalVertices ? "True" : "False"; + if (string(theGroupName).empty()) + SMESH::TPythonDump() << _this() << ".SetInternalEnforcedVertex( " << theFaceEntry << ", " << theValueStr.c_str() << " )"; + else + SMESH::TPythonDump() << _this() << ".SetInternalEnforcedVertexWithGroup( " << theFaceEntry << ", " << theValueStr.c_str() << ", \"" << theGroupName << "\" )"; + } catch (const std::exception& ex) { + std::cout << "Exception: " << ex.what() << std::endl; + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +*/ + +/* TODO GROUPS + char* BLSURFPlugin_Hypothesis_i::GetEnforcedVertexGroupName(CORBA::Double x, CORBA::Double y, CORBA::Double z) + throw (SALOME::SALOME_Exception) + { + ASSERT(myBaseImpl); + MESSAGE("ENGINE : GetEnforcedVertexGroupName START "); + try { + return CORBA::string_dup( this->GetImpl()->GetEnforcedVertexGroupName(x, y, z).c_str()); + } + catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis_i::GetEnforcedVertexGroupName(entry)"; + ExDescription.lineNumber = 1146; + throw SALOME::SALOME_Exception(ExDescription); + } + catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + MESSAGE("ENGINE : GetEnforcedVertexGroupName END "); + return 0; + } + + + void BLSURFPlugin_Hypothesis_i::SetEnforcedVertexGroupName(CORBA::Double x, CORBA::Double y, CORBA::Double z, const char* groupName) + throw (SALOME::SALOME_Exception) + { + ASSERT(myBaseImpl); + MESSAGE("ENGINE : SetEnforcedVertexGroupName START "); + try { + this->GetImpl()->SetEnforcedVertexGroupName(x, y, z, groupName); + } + catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; + ExDescription.text = ex.what(); + ExDescription.type = SALOME::BAD_PARAM; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetEnforcedVertexGroupName(x,y,z)"; + ExDescription.lineNumber = 1170; + throw SALOME::SALOME_Exception(ExDescription); + } + catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + + SMESH::TPythonDump() << _this() << ".SetEnforcedVertexGroupName(" + << x << ", " << y << ", " << z << ", '" << groupName << "' )"; + + MESSAGE("ENGINE : SetEnforcedVertexGroupName END "); + } + */ +/////////////////////// + + +//================================================================================ +/*! + * \brief Sets the file for export resulting mesh in GMF format + * \param theFileName - full name of the file (.mesh, .meshb) + * + * After compute, export the resulting mesh in the given file with the GMF format (.mesh) + */ +//================================================================================ +// void BLSURFPlugin_Hypothesis_i::SetGMFFile(const char* theFileName, CORBA::Boolean isBinary) { +void BLSURFPlugin_Hypothesis_i::SetGMFFile(const char* theFileName) { + ASSERT(myBaseImpl); + MESSAGE("IDL : SetGMFFile(" << theFileName << ")"); + bool valueChanged/*, modeChanged*/ = false; + try { + valueChanged = (this->GetImpl()->GetGMFFile() != theFileName); +// modeChanged = (this->GetImpl()->GetGMFFileMode() != isBinary); + if (valueChanged)// or (!valueChanged && modeChanged)) + this->GetImpl()->SetGMFFile(theFileName);// ,isBinary); + } catch (const std::exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + if (valueChanged)// or (!valueChanged && modeChanged)) + SMESH::TPythonDump() << _this() << ".SetGMFFile(\"" << theFileName << "\")"; //", " << isBinary << ")"; + MESSAGE("IDL : SetGMFFile END "); +} + +//================================================================================ +/*! + * \brief Gets the file name for export resulting mesh in GMF format + * \retval char* - The file name + * + * Returns the GMF file name + */ +//================================================================================ +char* BLSURFPlugin_Hypothesis_i::GetGMFFile() { + ASSERT(myBaseImpl); +// MESSAGE("IDL : GetGMFFile()"); + return CORBA::string_dup(this->GetImpl()->GetGMFFile().c_str()); +} + +// //================================================================================ +// /*! +// * \brief Gets the file mode for export resulting mesh in GMF format +// * \retval CORBA::Boolean - TRUE if binary mode, FALSE if ascii mode +// * +// * Returns the GMF file mode +// */ +// //================================================================================ +// CORBA::Boolean BLSURFPlugin_Hypothesis_i::GetGMFFileMode() { +// ASSERT(myBaseImpl); +// MESSAGE("IDL : GetGMFFileMode()"); +// return this->GetImpl()->GetGMFFileMode(); +// } + +//============================================================================= +/*! + * BLSURFPlugin_Hypothesis_i::GetImpl + * + * Get implementation + */ +//============================================================================= +::BLSURFPlugin_Hypothesis* BLSURFPlugin_Hypothesis_i::GetImpl() { + // MESSAGE("BLSURFPlugin_Hypothesis_i::GetImpl"); + return (::BLSURFPlugin_Hypothesis*) 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 BLSURFPlugin_Hypothesis_i::IsDimSupported(SMESH::Dimension type) { return type == SMESH::DIM_2D; } diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx index 76b826f..2c96546 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx @@ -1,24 +1,26 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_Hypothesis.hxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) +// Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- // #ifndef _BLSURFPlugin_Hypothesis_i_HXX_ @@ -31,18 +33,15 @@ #include "BLSURFPlugin_Hypothesis.hxx" class SMESH_Gen; +class GEOM_Object; // BLSURFPlugin parameters hypothesis -class BLSURFPlugin_Hypothesis_i: - public virtual POA_BLSURFPlugin::BLSURFPlugin_Hypothesis, - public virtual SMESH_Hypothesis_i -{ - public: +class BLSURFPlugin_Hypothesis_i: public virtual POA_BLSURFPlugin::BLSURFPlugin_Hypothesis, + public virtual SMESH_Hypothesis_i { +public: // Constructor - BLSURFPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl); + BLSURFPlugin_Hypothesis_i(PortableServer::POA_ptr thePOA, int theStudyId, ::SMESH_Gen* theGenImpl); // Destructor virtual ~BLSURFPlugin_Hypothesis_i(); @@ -88,21 +87,166 @@ class BLSURFPlugin_Hypothesis_i: void SetVerbosity(CORBA::Short theVal) throw (SALOME::SALOME_Exception); CORBA::Short GetVerbosity(); - void SetOptionValue(const char* optionName, - const char* optionValue) throw (SALOME::SALOME_Exception); + void SetPreCADMergeEdges(CORBA::Boolean theValue); + CORBA::Boolean GetPreCADMergeEdges(); + + void SetPreCADRemoveNanoEdges(CORBA::Boolean theValue); + CORBA::Boolean GetPreCADRemoveNanoEdges(); + + void SetPreCADDiscardInput(CORBA::Boolean theValue); + CORBA::Boolean GetPreCADDiscardInput(); + + void SetPreCADEpsNano(CORBA::Double theValue); + CORBA::Double GetPreCADEpsNano(); + + void SetOptionValue(const char* optionName, const char* optionValue) throw (SALOME::SALOME_Exception); + void SetPreCADOptionValue(const char* optionName, const char* optionValue) throw (SALOME::SALOME_Exception); char* GetOptionValue(const char* optionName) throw (SALOME::SALOME_Exception); + char* GetPreCADOptionValue(const char* optionName) throw (SALOME::SALOME_Exception); void UnsetOption(const char* optionName); + void UnsetPreCADOption(const char* optionName); BLSURFPlugin::string_array* GetOptionValues(); + BLSURFPlugin::string_array* GetPreCADOptionValues(); void SetOptionValues(const BLSURFPlugin::string_array& options) throw (SALOME::SALOME_Exception); + void SetPreCADOptionValues(const BLSURFPlugin::string_array& options) throw (SALOME::SALOME_Exception); + + void SetSizeMapEntry(const char* entry, const char* sizeMap) throw (SALOME::SALOME_Exception); + + char* GetSizeMapEntry(const char* entry) throw (SALOME::SALOME_Exception); + + void UnsetEntry(const char* entry); + + BLSURFPlugin::string_array* GetSizeMapEntries(); + + void SetSizeMapEntries(const BLSURFPlugin::string_array& sizeMaps) throw (SALOME::SALOME_Exception); + + void SetSizeMap(GEOM::GEOM_Object_ptr GeomObj, const char* sizeMap); + + void UnsetSizeMap(GEOM::GEOM_Object_ptr GeomObj); + + void ClearSizeMaps(); + + void SetAttractor(GEOM::GEOM_Object_ptr GeomObj, const char* attractor); + + void UnsetAttractor(GEOM::GEOM_Object_ptr GeomObj); + + void SetAttractorEntry(const char* entry, const char* attractor) throw (SALOME::SALOME_Exception); + + char* GetAttractorEntry(const char* entry) throw (SALOME::SALOME_Exception); + + BLSURFPlugin::string_array* GetAttractorEntries(); + + + /*! + * Set/get/unset an attractor on a face + */ + + void SetAttractorGeom(GEOM::GEOM_Object_ptr GeomObj, GEOM::GEOM_Object_ptr Attractor, double StartSize, double EndSize, double ActionRadius, double ConstantRadius ); + + void UnsetAttractorGeom(GEOM::GEOM_Object_ptr GeomObj); + + void SetClassAttractorEntry(const char* entry, const char* att_entry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) throw (SALOME::SALOME_Exception); + + BLSURFPlugin::TAttParamsMap* GetAttractorParams(); + + + /* + void SetCustomSizeMap(GEOM::GEOM_Object_ptr GeomObj, const char* sizeMap); + + void UnsetCustomSizeMap(GEOM::GEOM_Object_ptr GeomObj); + + void SetCustomSizeMapEntry(const char* entry,const char* sizeMap ) throw (SALOME::SALOME_Exception); + + char* GetCustomSizeMapEntry(const char* entry) throw (SALOME::SALOME_Exception); + + BLSURFPlugin::string_array* GetCustomSizeMapEntries(); + */ + + /////////////////////// + // ENFORCED VERTEXES // + /////////////////////// + + BLSURFPlugin::TFaceEntryEnfVertexListMap* GetAllEnforcedVerticesByFace(); + BLSURFPlugin::TEnfVertexList* GetAllEnforcedVertices(); + + BLSURFPlugin::TFaceEntryCoordsListMap* GetAllCoordsByFace(); + BLSURFPlugin::TCoordsEnfVertexMap* GetAllEnforcedVerticesByCoords(); + + BLSURFPlugin::TFaceEntryEnfVertexEntryListMap* GetAllEnfVertexEntriesByFace(); + BLSURFPlugin::TEnfVertexEntryEnfVertexMap* GetAllEnforcedVerticesByEnfVertexEntry(); + + void ClearAllEnforcedVertices(); + + /*! + * Set/get/unset an enforced vertex on geom object + */ + bool SetEnforcedVertex(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, CORBA::Double z) + throw (SALOME::SALOME_Exception); + bool SetEnforcedVertexNamed(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, CORBA::Double z, const char* theVertexName) + throw (SALOME::SALOME_Exception); + bool SetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theFace, GEOM::GEOM_Object_ptr theVertex) + throw (SALOME::SALOME_Exception); + bool SetEnforcedVertexWithGroup(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, CORBA::Double z, const char* theGroupName) + throw (SALOME::SALOME_Exception); + bool SetEnforcedVertexNamedWithGroup(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, CORBA::Double z, const char* theVertexName, const char* theGroupName) + throw (SALOME::SALOME_Exception); + bool SetEnforcedVertexGeomWithGroup(GEOM::GEOM_Object_ptr theFace, GEOM::GEOM_Object_ptr theVertex, const char* theGroupName) + throw (SALOME::SALOME_Exception); + + BLSURFPlugin::TEnfVertexList* GetEnforcedVertices(GEOM::GEOM_Object_ptr theFace) throw (SALOME::SALOME_Exception); + + bool UnsetEnforcedVertex(GEOM::GEOM_Object_ptr theFace, CORBA::Double x, CORBA::Double y, CORBA::Double z) + throw (SALOME::SALOME_Exception); + bool UnsetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theFace, GEOM::GEOM_Object_ptr theVertex) + throw (SALOME::SALOME_Exception); + bool UnsetEnforcedVertices(GEOM::GEOM_Object_ptr theFace) throw (SALOME::SALOME_Exception); + + /*! + * Set/get/unset an enforced vertex on geom object given by entry + */ + bool SetEnforcedVertexEntry(const char* theFaceEntry, CORBA::Double x = 0, CORBA::Double y = 0, CORBA::Double z = 0, + const char* theVertexName = "", const char* theVertexEntry = "", const char* theGroupName = "") + throw (SALOME::SALOME_Exception); + + BLSURFPlugin::TEnfVertexList* GetEnforcedVerticesEntry(const char* theFaceEntry) throw (SALOME::SALOME_Exception); + + bool UnsetEnforcedVertexEntry(const char* theFaceEntry, CORBA::Double x, CORBA::Double y, CORBA::Double z, + const char* theVertexEntry = "") throw (SALOME::SALOME_Exception); + bool UnsetEnforcedVerticesEntry(const char* theFaceEntry) throw (SALOME::SALOME_Exception); + + /*! + * To add internal vertices as enforced vertices + */ + void SetInternalEnforcedVertexAllFaces(CORBA::Boolean toEnforceInternalVertices); + CORBA::Boolean GetInternalEnforcedVertexAllFaces(); + void SetInternalEnforcedVertexAllFacesGroup(const char* groupName = ""); + char* GetInternalEnforcedVertexAllFacesGroup(); + +// Enable internal enforced vertices on specific face if requested by user +// void SetInternalEnforcedVertex(GEOM::GEOM_Object_ptr theFace, CORBA::Boolean toEnforceInternalVertices) throw (SALOME::SALOME_Exception); +// void SetInternalEnforcedVertexWithGroup(GEOM::GEOM_Object_ptr theFace, CORBA::Boolean toEnforceInternalVertices, const char* theGroupName = "") throw (SALOME::SALOME_Exception); +// void SetInternalEnforcedVertexEntry(const char* theFaceEntry, CORBA::Boolean toEnforceInternalVertices, const char* theGroupName = "") throw (SALOME::SALOME_Exception); +// CORBA::Boolean GetInternalEnforcedVertex(GEOM::GEOM_Object_ptr theFace) throw (SALOME::SALOME_Exception); +// CORBA::Boolean GetInternalEnforcedVertexEntry(const char* theFaceEntry) throw (SALOME::SALOME_Exception); + + /////////////////////// + + /*! + * Sets the file for export resulting mesh in GMF format + */ +// void SetGMFFile(const char* theFileName, CORBA::Boolean isBinary); + void SetGMFFile(const char* theFileName); + char* GetGMFFile(); +// CORBA::Boolean GetGMFFileMode(); // Get implementation ::BLSURFPlugin_Hypothesis* GetImpl(); - + // Verify whether hypothesis supports given entity type - CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + CORBA::Boolean IsDimSupported(SMESH::Dimension type); }; #endif diff --git a/src/BLSURFPlugin/BLSURFPlugin_i.cxx b/src/BLSURFPlugin/BLSURFPlugin_i.cxx index 6eceece..2ca0fa9 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_i.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_i.cxx @@ -1,21 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPlugin_i.cxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) @@ -23,6 +24,16 @@ // #include "utilities.h" +#ifdef WIN32 + #if defined BLSURFPLUGIN_EXPORTS || defined BLSURFEngine_EXPORTS + #define BLSURFPLUGIN_EXPORT __declspec( dllexport ) + #else + #define BLSURFPLUGIN_EXPORT __declspec( dllimport ) + #endif +#else + #define BLSURFPLUGIN_EXPORT +#endif + #include "BLSURFPlugin_BLSURF_i.hxx" #include "BLSURFPlugin_Hypothesis_i.hxx" @@ -40,6 +51,7 @@ template class BLSURFPlugin_Creator_i:public HypothesisCreator_i extern "C" { + BLSURFPLUGIN_EXPORT GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName) { MESSAGE("GetHypothesisCreator " << aHypName); diff --git a/src/BLSURFPlugin/Makefile.am b/src/BLSURFPlugin/Makefile.am index e78b060..2d9cab3 100644 --- a/src/BLSURFPlugin/Makefile.am +++ b/src/BLSURFPlugin/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -23,39 +24,53 @@ # include $(top_srcdir)/adm_local/unix/make_common_starter.am -# header files -salomeinclude_HEADERS = +# header files +salomeinclude_HEADERS = \ + BLSURFPlugin_BLSURF.hxx \ + BLSURFPlugin_BLSURF_i.hxx \ + BLSURFPlugin_Hypothesis.hxx \ + BLSURFPlugin_Hypothesis_i.hxx \ + BLSURFPlugin_Attractor.hxx # Libraries targets lib_LTLIBRARIES = libBLSURFEngine.la dist_libBLSURFEngine_la_SOURCES = \ - BLSURFPlugin_BLSURF.hxx \ BLSURFPlugin_BLSURF.cxx \ - BLSURFPlugin_BLSURF_i.hxx \ BLSURFPlugin_BLSURF_i.cxx \ - BLSURFPlugin_Hypothesis.hxx \ BLSURFPlugin_Hypothesis.cxx \ - BLSURFPlugin_Hypothesis_i.hxx \ BLSURFPlugin_Hypothesis_i.cxx \ - BLSURFPlugin_i.cxx + BLSURFPlugin_i.cxx \ + BLSURFPlugin_Attractor.cxx libBLSURFEngine_la_CPPFLAGS = \ - $(KERNEL_CXXFLAGS) \ - $(GUI_CXXFLAGS) \ + $(QT_INCLUDES) \ + $(PYTHON_INCLUDES) \ + $(KERNEL_CXXFLAGS) \ + $(GUI_CXXFLAGS) \ $(MED_CXXFLAGS) \ $(GEOM_CXXFLAGS) \ $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(BLSURF_INCLUDES) \ $(SMESH_CXXFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ $(BOOST_CPPFLAGS) \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix + -I$(top_builddir)/idl + +#Qt uniquement necessaire pour le getActiveStudyDocument de SMeshGuiUtils.h libBLSURFEngine_la_LDFLAGS = \ ../../idl/libSalomeIDLBLSURFPLUGIN.la \ - $(BLSURF_LIBS) \ - $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lStdMeshersEngine \ - $(KERNEL_LDFLAGS) -lSalomeGenericObj + $(PYTHON_LIBS) \ + $(CAS_KERNEL) -lTKBRep -lTKGeomBase -lTKGeomAlgo -lTKTopAlgo -lTKLCAF -lTKXSBase -lTKG2d -lTKG3d -lTKShHealing \ + $(BLSURF_LIBS) \ + $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lStdMeshers -lStdMeshersEngine -lSMDS -lSMESHDS \ + $(GEOM_LDFLAGS) -lGEOMbasic \ + $(MED_LDFLAGS) -lSalomeIDLMED \ + $(KERNEL_LDFLAGS) -lOpUtil -lSalomeGenericObj -lSalomeNS -lSALOMELocalTrace -lSALOMEBasics \ + $(BOOST_LIB_REGEX) + +# Scripts to be installed. +dist_salomescript_DATA= BLSURFPluginDC.py diff --git a/src/GUI/BLSURFPluginGUI.cxx b/src/GUI/BLSURFPluginGUI.cxx index 9414ad1..bb25855 100755 --- a/src/GUI/BLSURFPluginGUI.cxx +++ b/src/GUI/BLSURFPluginGUI.cxx @@ -1,26 +1,35 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPluginGUI.cxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) // --- // +#ifdef WNT +// E.A. : On windows with python 2.6, there is a conflict +// E.A. : between pymath.h and Standard_math.h which define +// E.A. : some same symbols : acosh, asinh, ... +#include +#include +#endif + #include "BLSURFPluginGUI_HypothesisCreator.h" //============================================================================= diff --git a/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx b/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx index ba14fc8..3c6fd03 100644 --- a/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx @@ -1,43 +1,52 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// 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 free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// 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 : BLSURFPluginGUI_HypothesisCreator.cxx // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA) // & Aurelien ALLEAUME (DISTENE) +// Size maps developement: Nicolas GEIMER (OCC) & Gilles DAVID (EURIWARE) // --- // #include "BLSURFPluginGUI_HypothesisCreator.h" +// #include + +#include "GeometryGUI.h" #include #include +#include +#include "SMESHGUI_SpinBox.h" +#include "SMESH_NumberFilter.hxx" #include #include #include #include -#include +#include #include #include #include #include #include +#include #include #include #include @@ -48,19 +57,44 @@ #include #include #include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "SALOME_LifeCycleCORBA.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include #define WITH_SIZE_BOUNDARIES enum Topology { FromCAD, Process, - Process2 - }; + Process2, + PreCAD + } ; enum PhysicalMesh { DefaultSize = 0, - PhysicalUserDefined + PhysicalUserDefined, + SizeMap }; enum GeometricMesh @@ -72,66 +106,465 @@ enum GeometricMesh enum { STD_TAB = 0, ADV_TAB, + SMP_TAB, + ENF_TAB, OPTION_ID_COLUMN = 0, + OPTION_TYPE_COLUMN, OPTION_NAME_COLUMN, OPTION_VALUE_COLUMN, - NB_COLUMNS + NB_COLUMNS, + SMP_NAME_COLUMN =0, + SMP_SIZEMAP_COLUMN, + SMP_ENTRY_COLUMN, +// SMP_DIST_COLUMN, + SMP_NB_COLUMNS, +// Enforced vertices array columns + ENF_VER_NAME_COLUMN = 0, + ENF_VER_FACE_ENTRY_COLUMN, + ENF_VER_X_COLUMN, + ENF_VER_Y_COLUMN, + ENF_VER_Z_COLUMN, + ENF_VER_ENTRY_COLUMN, + ENF_VER_GROUP_COLUMN, + ENF_VER_NB_COLUMNS }; -BLSURFPluginGUI_HypothesisCreator::BLSURFPluginGUI_HypothesisCreator( const QString& theHypType ) - : SMESHGUI_GenericHypothesisCreator( theHypType ) +enum { + SMP_TAB_WDG, + SMP_ADD_BTN, + SMP_NB_LINES, + SMP_STD_TAB = 0, + ATT_TAB, + SMP_GEOM_BTN_2 = 0, + ATT_CHECK, + CONST_SIZE_CHECK, + SMP_SPACE, +// SMP_PARAMS, + SMP_ATT_SHAPE, + SMP_ATT_SIZE, + SMP_ATT_DIST, + SMP_ATT_RAD +}; + +enum { + SMP_GEOM_BTN_1, + SMP_SIZE, + SMP_SPACE2, +}; + +// Enforced vertices inputs +enum { + ENF_VER_FACE = 0, + ENF_VER_VERTEX, + ENF_VER_X_COORD, + ENF_VER_Y_COORD, + ENF_VER_Z_COORD, + ENF_VER_GROUP, +// ENF_VER_GROUP_CHECK, +// ENF_VER_SPACE, + ENF_VER_BTN, + ENF_VER_SEPARATOR, + ENF_VER_INTERNAL_ALL_FACES, + ENF_VER_INTERNAL_ALL_FACES_GROUP, +// ENF_VER_VERTEX_BTN, +// ENF_VER_REMOVE_BTN, +// ENF_VER_SEPARATOR, + ENF_VER_NB_LINES +}; + + +/************************************************** + Begin initialization Python structures and objects +***************************************************/ + +typedef struct { + PyObject_HEAD + int softspace; + std::string *out; + } PyStdOut; + +static void +PyStdOut_dealloc(PyStdOut *self) { + PyObject_Del(self); } -BLSURFPluginGUI_HypothesisCreator::~BLSURFPluginGUI_HypothesisCreator() +static PyObject * +PyStdOut_write(PyStdOut *self, PyObject *args) { + char *c; + int l; + if (!PyArg_ParseTuple(args, "t#:write",&c, &l)) + return NULL; + + //std::cerr << c ; + *(self->out)=*(self->out)+c; + + Py_INCREF(Py_None); + return Py_None; } -namespace { - inline bool isDouble( const QString& theText, const bool emptyOK=false ) { - QString str = theText.trimmed(); - bool isOk = true; - if ( !str.isEmpty() ) - str.toDouble(&isOk); - else - isOk = emptyOK; - return isOk; +static PyMethodDef PyStdOut_methods[] = { + {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, + PyDoc_STR("write(string) -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef PyStdOut_memberlist[] = { + {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0, + (char*)"flag indicating that a space needs to be printed; used by print"}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject PyStdOut_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "PyOut", /*tp_name*/ + sizeof(PyStdOut), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PyStdOut_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + /* softspace is writable: we must supply tp_setattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PyStdOut_methods, /*tp_methods*/ + PyStdOut_memberlist, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +PyObject * newPyStdOut( std::string& out ) +{ + PyStdOut *self; + self = PyObject_New(PyStdOut, &PyStdOut_Type); + if (self == NULL) + return NULL; + self->softspace = 0; + self->out=&out; + return (PyObject*)self; +} + +/************************************************* +End initialization Python structures and objects +**************************************************/ + + +// +// BEGIN EnforcedTreeWidgetDelegate +// + +EnforcedTreeWidgetDelegate::EnforcedTreeWidgetDelegate(QObject *parent) + : QItemDelegate(parent) +{ +} + +QWidget *EnforcedTreeWidgetDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem & option , + const QModelIndex & index ) const +{ + QModelIndex father = index.parent(); + QString entry = father.child(index.row(), ENF_VER_ENTRY_COLUMN).data(Qt::EditRole).toString(); + + if (index.column() == ENF_VER_X_COLUMN || \ + index.column() == ENF_VER_Y_COLUMN || \ + index.column() == ENF_VER_Z_COLUMN) + { + SMESHGUI_SpinBox *editor = new SMESHGUI_SpinBox(parent); + editor->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + editor->setReadOnly(!entry.isEmpty()); + editor->setDisabled(!entry.isEmpty()); + return editor; + } + else + { + QLineEdit *editor = new QLineEdit(parent); + if (index.column() != ENF_VER_GROUP_COLUMN) { + editor->setReadOnly(!entry.isEmpty()); + editor->setDisabled(!entry.isEmpty()); + } + return editor; } } -bool BLSURFPluginGUI_HypothesisCreator::checkParams() const +void EnforcedTreeWidgetDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const { - bool ok = true; - if ( !isDouble( myPhySize->text(), false )) { - if ( myPhySize->text().isEmpty() ) - myPhySize->setText(tr("OBLIGATORY_VALUE")); - myPhySize->selectAll(); - ok = false; + QString value = index.model()->data(index, Qt::EditRole).toString(); + + if (index.column() == ENF_VER_X_COLUMN || + index.column() == ENF_VER_Y_COLUMN || + index.column() == ENF_VER_Z_COLUMN) + { + SMESHGUI_SpinBox *lineEdit = static_cast(editor); + lineEdit->setText(value); } - if ( !isDouble( myPhyMin->text(), true )) { - myPhyMin->selectAll(); - ok = false; + else { + QLineEdit *lineEdit = static_cast(editor); + lineEdit->setText(value); } - if ( !isDouble( myPhyMax->text(), true )) { - myPhyMax->selectAll(); - ok = false; +} + +void EnforcedTreeWidgetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + QModelIndex parent = index.parent(); + QString entry = parent.child(index.row(), ENF_VER_ENTRY_COLUMN).data(Qt::EditRole).toString(); + if (index.column() == ENF_VER_X_COLUMN || index.column() == ENF_VER_Y_COLUMN || index.column() == ENF_VER_Z_COLUMN) { + SMESHGUI_SpinBox *lineEdit = static_cast(editor); + if (entry.isEmpty() && !vertexExists(model, index, lineEdit->GetString())) + model->setData(index, lineEdit->GetValue(), Qt::EditRole); + } else if (index.column() == ENF_VER_NAME_COLUMN) { + QLineEdit *lineEdit = static_cast(editor); + QString value = lineEdit->text(); + if (entry.isEmpty() && !vertexExists(model, index, value)) + model->setData(index, value, Qt::EditRole); + } else if (index.column() == ENF_VER_ENTRY_COLUMN) { + QLineEdit *lineEdit = static_cast(editor); + QString value = lineEdit->text(); + if (! vertexExists(model, index, value)) + model->setData(index, value, Qt::EditRole); + } else if (index.column() == ENF_VER_GROUP_COLUMN) { + QLineEdit *lineEdit = static_cast(editor); + model->setData(index, lineEdit->text(), Qt::EditRole); } - if ( !isDouble( myGeoMin->text(), true )) { - myGeoMin->selectAll(); - ok = false; +} + +void EnforcedTreeWidgetDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, const QModelIndex &/* index */) const +{ + editor->setGeometry(option.rect); +} + +bool EnforcedTreeWidgetDelegate::vertexExists(QAbstractItemModel *model, + const QModelIndex &index, QString value) const +{ + bool exists = false; + QModelIndex parent = index.parent(); + int row = index.row(); + int col = index.column(); + + if (parent.isValid() && !value.isEmpty()) { + if (col == ENF_VER_X_COLUMN || col == ENF_VER_Y_COLUMN || col == ENF_VER_Z_COLUMN) { + double x, y, z; + if (col == ENF_VER_X_COLUMN) { + x = value.toDouble(); + y = parent.child(row, ENF_VER_Y_COLUMN).data(Qt::EditRole).toDouble(); + z = parent.child(row, ENF_VER_Z_COLUMN).data(Qt::EditRole).toDouble(); + } + if (col == ENF_VER_Y_COLUMN) { + y = value.toDouble(); + x = parent.child(row, ENF_VER_X_COLUMN).data(Qt::EditRole).toDouble(); + z = parent.child(row, ENF_VER_Z_COLUMN).data(Qt::EditRole).toDouble(); + } + if (col == ENF_VER_Z_COLUMN) { + z = value.toDouble(); + x = parent.child(row, ENF_VER_X_COLUMN).data(Qt::EditRole).toDouble(); + y = parent.child(row, ENF_VER_Y_COLUMN).data(Qt::EditRole).toDouble(); + } + int nbChildren = model->rowCount(parent); + for (int i = 0 ; i < nbChildren ; i++) { + if (i != row) { + double childX = parent.child(i, ENF_VER_X_COLUMN).data(Qt::EditRole).toDouble(); + double childY = parent.child(i, ENF_VER_Y_COLUMN).data(Qt::EditRole).toDouble(); + double childZ = parent.child(i, ENF_VER_Z_COLUMN).data(Qt::EditRole).toDouble(); + if ((childX == x) && (childY == y) && (childZ == z)) { + exists = true; + break; + } + } + } + } + else if (col == ENF_VER_NAME_COLUMN) { + int nbChildren = model->rowCount(parent); + for (int i = 0 ; i < nbChildren ; i++) { + if (i != row) { + QString childName = parent.child(i, ENF_VER_NAME_COLUMN).data(Qt::EditRole).toString(); + if (childName == value) { + exists = true; + break; + } + } + } + } } - if ( !isDouble( myGeoMin->text(), true )) { - myGeoMin->selectAll(); - ok = false; + + return exists; +} + +// +// END EnforcedTreeWidgetDelegate +// + +// +// BEGIN BLSURFPluginGUI_ObjectReferenceParamWdg +// +//================================================================================ + +// BLSURFPluginGUI_ObjectReferenceParamWdg::BLSURFPluginGUI_ObjectReferenceParamWdg +// ( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection) +// : StdMeshersGUI_ObjectReferenceParamWdg(f, parent, multiSelection) +// { +// init(); +// } +// +// +// BLSURFPluginGUI_ObjectReferenceParamWdg::BLSURFPluginGUI_ObjectReferenceParamWdg +// ( MeshObjectType objType, QWidget* parent, bool multiSelection ) +// : StdMeshersGUI_ObjectReferenceParamWdg( objType, parent, multiSelection ) +// { +// init(); +// } +// +// BLSURFPluginGUI_ObjectReferenceParamWdg::~BLSURFPluginGUI_ObjectReferenceParamWdg() +// { +// if ( myFilter ) +// { +// mySelectionMgr->removeFilter( myFilter ); +// delete myFilter; +// } +// } +// +// void BLSURFPluginGUI_ObjectReferenceParamWdg::init() +// { +// StdMeshersGUI_ObjectReferenceParamWdg::init(); +// disconnect( mySelButton, SIGNAL(clicked()), SLOT(activateSelection())); +// connect( mySelButton, SIGNAL(toggled(bool)), SLOT(setActivationStatus(bool))); +// } +// +// void BLSURFPluginGUI_ObjectReferenceParamWdg::setActivationStatus(bool status) +// { +// if (status) +// activateSelection(); +// else +// deactivateSelection(); +// } +// +// void BLSURFPluginGUI_ObjectReferenceParamWdg::activateSelectionOnly() +// { +// if ( !mySelectionActivated && mySelectionMgr ) +// { +// mySelectionActivated = true; +// mySelectionMgr->clearFilters(); +// if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) +// aViewWindow->SetSelectionMode(ActorSelection); +// if ( myFilter ) +// mySelectionMgr->installFilter( myFilter ); +// connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone())); +// } +// emit selectionActivated(); +// } +// +// void BLSURFPluginGUI_ObjectReferenceParamWdg::deactivateSelectionOnly() +// { +// mySelectionActivated = false; +// disconnect(mySelectionMgr, 0, this, 0 ); +// mySelectionMgr->removeFilter( myFilter ); +// } +// +// +// END BLSURFPluginGUI_ObjectReferenceParamWdg +// + +/** + * \brief {BLSURFPluginGUI_HypothesisCreator constructor} + * @param theHypType Name of the hypothesis type (here BLSURF_Parameters) + * + * */ +BLSURFPluginGUI_HypothesisCreator::BLSURFPluginGUI_HypothesisCreator( const QString& theHypType ) + : SMESHGUI_GenericHypothesisCreator( theHypType ) +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::BLSURFPluginGUI_HypothesisCreator"); + this->mySMPMap.clear(); + + GeomToolSelected = NULL; + GeomToolSelected = getGeomSelectionTool(); + + aSel = GeomToolSelected->selectionMgr(); + + /* Initialize the Python interpreter */ + if (! Py_IsInitialized()) + throw ("Error: Python interpreter is not initialized"); + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + main_mod = NULL; + main_mod = PyImport_AddModule("__main__"); + + main_dict = NULL; + main_dict = PyModule_GetDict(main_mod); + + PyRun_SimpleString("from math import *"); + PyGILState_Release(gstate); + +} + +BLSURFPluginGUI_HypothesisCreator::~BLSURFPluginGUI_HypothesisCreator() +{ +} + +/** + * \brief {Get or create the geom selection tool for active study} + * */ +GeomSelectionTools* BLSURFPluginGUI_HypothesisCreator::getGeomSelectionTool() +{ + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + if (that->GeomToolSelected == NULL || that->GeomToolSelected->getMyStudy() != aStudy) { + that->GeomToolSelected = new GeomSelectionTools(aStudy); } + return that->GeomToolSelected; +} + +GEOM::GEOM_Gen_var BLSURFPluginGUI_HypothesisCreator::getGeomEngine() +{ + return GeometryGUI::GetGeomGen(); +} + + +bool BLSURFPluginGUI_HypothesisCreator::checkParams(QString& msg) const +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::checkParams"); + bool ok = true; + + BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = + BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( hypothesis() ); + if ( ok ) { myOptionTable->setFocus(); QApplication::instance()->processEvents(); - BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = - BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() ); - int row = 0, nbRows = myOptionTable->rowCount(); for ( ; row < nbRows; ++row ) { @@ -139,27 +572,81 @@ bool BLSURFPluginGUI_HypothesisCreator::checkParams() const QString value = myOptionTable->item( row, OPTION_VALUE_COLUMN )->text().trimmed(); if ( !value.isEmpty() ) { try { - h->SetOptionValue( name.toLatin1().constData(), value.toLatin1().constData() ); + QString optionType = myOptionTable->item( row, OPTION_TYPE_COLUMN )->text().trimmed(); + if (optionType == "PRECAD") + h->SetPreCADOptionValue( name.toLatin1().constData(), value.toLatin1().constData() ); + else if (optionType == "BLSURF") + h->SetOptionValue( name.toLatin1().constData(), value.toLatin1().constData() ); } catch ( const SALOME::SALOME_Exception& ex ) { - SUIT_MessageBox::critical( dlg(), - tr("SMESH_ERROR"), - ex.details.text.in() ); + msg = ex.details.text.in(); ok = false; } } } + } + if ( !ok ) + { h->SetOptionValues( myOptions ); // restore values + h->SetPreCADOptionValues( myPreCADOptions ); // restore values } + // SizeMap and attractors + if ( ok ) + { + mySizeMapTable->setFocus(); + QApplication::instance()->processEvents(); + + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + int row = 0, nbRows = mySizeMapTable->topLevelItemCount(); + std::string e, s; + for ( ; row < nbRows; ++row ) + { + QString entry = mySizeMapTable->topLevelItem( row )->data(SMP_ENTRY_COLUMN, Qt::EditRole).toString(); + QString sizeMap = mySizeMapTable->topLevelItem( row )->data(SMP_SIZEMAP_COLUMN, Qt::EditRole).toString(); + MESSAGE("entry ="<sizeMapValidationFromRow(row)) + { + try { + MESSAGE("entry ="< setMinimumSize(600,400); QVBoxLayout* lay = new QVBoxLayout( fr ); + // lay->setSizeConstraint(QLayout::SetDefaultConstraint); lay->setMargin( 5 ); lay->setSpacing( 0 ); @@ -175,137 +662,840 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame() aStdLayout->setSpacing( 6 ); aStdLayout->setMargin( 11 ); - int row = 0; myName = 0; - if( isCreation() ) { - aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 ); + if( isCreation() ) myName = new QLineEdit( myStdGroup ); - aStdLayout->addWidget( myName, row++, 1, 1, 1 ); - } - aStdLayout->addWidget( new QLabel( tr( "BLSURF_PHY_MESH" ), myStdGroup ), row, 0, 1, 1 ); + myGradation = new SMESHGUI_SpinBox( myStdGroup ); + myGradation->RangeStepAndValidator(1.1, 2.5, 0.1, "length_precision"); + myPhysicalMesh = new QComboBox( myStdGroup ); - aStdLayout->addWidget( myPhysicalMesh, row++, 1, 1, 1 ); QStringList physicalTypes; - physicalTypes << tr( "BLSURF_DEFAULT_USER" ) << tr( "BLSURF_CUSTOM_USER" ); + physicalTypes << tr( "BLSURF_DEFAULT_USER" ) << tr( "BLSURF_CUSTOM_USER" ) << tr( "BLSURF_SIZE_MAP"); myPhysicalMesh->addItems( physicalTypes ); - aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYDEF" ), myStdGroup), row, 0, 1, 1 ); - myPhySize = new QLineEdit( myStdGroup ); - aStdLayout->addWidget( myPhySize, row++, 1, 1, 1 ); + myPhySize = new SMESHGUI_SpinBox( myStdGroup ); + myPhySize->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); #ifdef WITH_SIZE_BOUNDARIES - aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMIN" ), myStdGroup ), row, 0, 1, 1 ); - myPhyMin = new QLineEdit( myStdGroup ); - aStdLayout->addWidget( myPhyMin, row++, 1, 1, 1 ); - - aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMAX" ), myStdGroup ), row, 0, 1, 1 ); - myPhyMax = new QLineEdit( myStdGroup ); - aStdLayout->addWidget( myPhyMax, row++, 1, 1, 1 ); + myPhyMin = new SMESHGUI_SpinBox( myStdGroup ); + myPhyMin->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); + myPhyMin->setText(""); + myPhyMax = new SMESHGUI_SpinBox( myStdGroup ); + myPhyMax->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); + myPhyMax->setText(""); #endif - aStdLayout->addWidget( new QLabel( tr( "BLSURF_GEOM_MESH" ), myStdGroup ), row, 0, 1, 1 ); myGeometricMesh = new QComboBox( myStdGroup ); - aStdLayout->addWidget( myGeometricMesh, row++, 1, 1, 1 ); QStringList types; types << tr( "BLSURF_DEFAULT_GEOM" ) << tr( "BLSURF_CUSTOM_GEOM" ); myGeometricMesh->addItems( types ); - aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_S" ), myStdGroup ), row, 0, 1, 1 ); - myAngleMeshS = new QtxDoubleSpinBox( myStdGroup ); - aStdLayout->addWidget( myAngleMeshS, row++, 1, 1, 1 ); - myAngleMeshS->setMinimum( 0 ); - myAngleMeshS->setMaximum( 16 ); - myAngleMeshS->setSingleStep( 0.5 ); - - aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_C" ), myStdGroup ), row, 0, 1, 1 ); - myAngleMeshC = new QtxDoubleSpinBox( myStdGroup ); - aStdLayout->addWidget( myAngleMeshC, row++, 1, 1, 1 ); - myAngleMeshC->setMinimum( 0 ); - myAngleMeshC->setMaximum( 16 ); - myAngleMeshC->setSingleStep( 0.5 ); - - aStdLayout->addWidget( new QLabel( tr( "BLSURF_GRADATION" ), myStdGroup ), row, 0, 1, 1 ); - myGradation = new QtxDoubleSpinBox( myStdGroup ); - aStdLayout->addWidget( myGradation, row++, 1, 1, 1 ); - myGradation->setMinimum( 1.1 ); - myGradation->setMaximum( 2.5 ); - myGradation->setSingleStep( 0.1 ); + myAngleMeshS = new SMESHGUI_SpinBox( myStdGroup ); + myAngleMeshS->RangeStepAndValidator(0, 16, 0.5, "angular_precision"); -#ifdef WITH_SIZE_BOUNDARIES - aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMIN" ), myStdGroup ), row, 0, 1, 1 ); - myGeoMin = new QLineEdit( myStdGroup ); - aStdLayout->addWidget( myGeoMin, row++, 1, 1, 1 ); + myAngleMeshC = new SMESHGUI_SpinBox( myStdGroup ); + myAngleMeshC->RangeStepAndValidator(0, 16, 0.5, "angular_precision"); - aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMAX" ), myStdGroup ), row, 0, 1, 1 ); - myGeoMax = new QLineEdit( myStdGroup ); - aStdLayout->addWidget( myGeoMax, row++, 1, 1, 1 ); +#ifdef WITH_SIZE_BOUNDARIES + myGeoMin = new SMESHGUI_SpinBox( myStdGroup ); + myGeoMin->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); + myGeoMin->setText(""); + myGeoMax = new SMESHGUI_SpinBox( myStdGroup ); + myGeoMax->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); + myGeoMax->setText(""); #endif - myAllowQuadrangles = new QCheckBox( tr( "BLSURF_ALLOW_QUADRANGLES" ), myStdGroup ); - aStdLayout->addWidget( myAllowQuadrangles, row++, 0, 1, 2 ); - myDecimesh = new QCheckBox( tr( "BLSURF_DECIMESH" ), myStdGroup ); - aStdLayout->addWidget( myDecimesh, row++, 0, 1, 2 ); - + + // ADD WIDGETS (STANDARD TAB) + int row = 0; + if( isCreation() ) { + aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 ); + aStdLayout->addWidget( myName, row++, 1, 1, 3 ); + } + aStdLayout->addWidget( new QLabel( tr( "BLSURF_PHY_MESH" ), myStdGroup ), row, 0, 1, 1 ); + aStdLayout->addWidget( myPhysicalMesh, row++, 1, 1, 1 ); + aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYDEF" ), myStdGroup), row, 0, 1, 1 ); + aStdLayout->addWidget( myPhySize, row++, 1, 1, 1 ); + aStdLayout->addWidget( new QLabel( tr( "BLSURF_GRADATION" ), myStdGroup ), row, 0, 1, 1 ); + aStdLayout->addWidget( myGradation, row++, 1, 1, 1 ); +#ifdef WITH_SIZE_BOUNDARIES + aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMIN" ), myStdGroup ), row, 0, 1, 1 ); + aStdLayout->addWidget( myPhyMin, row++, 1, 1, 1 ); + aStdLayout->addWidget( new QLabel( tr( "BLSURF_HPHYMAX" ), myStdGroup ), row, 0, 1, 1 ); + aStdLayout->addWidget( myPhyMax, row++, 1, 1, 1 ); +#endif + int maxrow = row; + if( isCreation() ) + row = 1; + else + row = 0; + aStdLayout->addWidget( new QLabel( tr( "BLSURF_GEOM_MESH" ), myStdGroup ), row, 2, 1, 1 ); + aStdLayout->addWidget( myGeometricMesh, row++, 3, 1, 1 ); + aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_S" ), myStdGroup ), row, 2, 1, 1 ); + aStdLayout->addWidget( myAngleMeshS, row++, 3, 1, 1 ); + aStdLayout->addWidget( new QLabel( tr( "BLSURF_ANGLE_MESH_C" ), myStdGroup ), row, 2, 1, 1 ); + aStdLayout->addWidget( myAngleMeshC, row++, 3, 1, 1 ); +#ifdef WITH_SIZE_BOUNDARIES + aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMIN" ), myStdGroup ), row, 2, 1, 1 ); + aStdLayout->addWidget( myGeoMin, row++, 3, 1, 1 ); + aStdLayout->addWidget( new QLabel( tr( "BLSURF_HGEOMAX" ), myStdGroup ), row, 2, 1, 1 ); + aStdLayout->addWidget( myGeoMax, row++, 3, 1, 1 ); +#endif + row = max(row,maxrow)+1; + aStdLayout->addWidget( myAllowQuadrangles, row, 0, 1, 2 ); + aStdLayout->addWidget( myDecimesh, row++, 2, 1, 2 ); + aStdLayout->setRowStretch(row,1); + maxrow = row; + // advanced parameters myAdvGroup = new QWidget(); QGridLayout* anAdvLayout = new QGridLayout( myAdvGroup ); anAdvLayout->setSpacing( 6 ); anAdvLayout->setMargin( 11 ); + anAdvLayout->setRowStretch( 4, 5 ); + anAdvLayout->setColumnStretch( 1, 5 ); - anAdvLayout->addWidget( new QLabel( tr( "BLSURF_TOPOLOGY" ), myAdvGroup ), 0, 0, 1, 1 ); myTopology = new QComboBox( myAdvGroup ); - anAdvLayout->addWidget( myTopology, 0, 1, 1, 1 ); QStringList topologyTypes; - topologyTypes << tr( "BLSURF_TOPOLOGY_CAD" ) << tr( "BLSURF_TOPOLOGY_PROCESS" ) << tr( "BLSURF_TOPOLOGY_PROCESS2" ); + topologyTypes << tr( "BLSURF_TOPOLOGY_CAD" ) + << tr( "BLSURF_TOPOLOGY_PROCESS" ) + << tr( "BLSURF_TOPOLOGY_PROCESS2" ) + << tr( "BLSURF_TOPOLOGY_PRECAD" ); myTopology->addItems( topologyTypes ); - anAdvLayout->addWidget( new QLabel( tr( "BLSURF_VERBOSITY" ), myAdvGroup ), 1, 0, 1, 1 ); myVerbosity = new QSpinBox( myAdvGroup ); - anAdvLayout->addWidget( myVerbosity, 1, 1, 1, 1 ); myVerbosity->setMinimum( 0 ); myVerbosity->setMaximum( 100 ); myVerbosity->setSingleStep( 5 ); myOptionTable = new QTableWidget( 0, NB_COLUMNS, myAdvGroup ); - anAdvLayout->addWidget( myOptionTable, 2, 0, 3, 2 ); QStringList headers; - headers << tr( "OPTION_ID_COLUMN" ) << tr( "OPTION_NAME_COLUMN" ) << tr( "OPTION_VALUE_COLUMN" ); + headers << tr( "OPTION_ID_COLUMN" )<< tr( "OPTION_TYPE_COLUMN" ) << tr( "OPTION_NAME_COLUMN" ) << tr( "OPTION_VALUE_COLUMN" ); myOptionTable->setHorizontalHeaderLabels( headers ); myOptionTable->horizontalHeader()->hideSection( OPTION_ID_COLUMN ); +// myOptionTable->horizontalHeader()->hideSection( OPTION_TYPE_COLUMN ); + myOptionTable->horizontalHeader()->setStretchLastSection(true); + myOptionTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); //myOptionTable->setColumnReadOnly( OPTION_NAME_COLUMN, TRUE );////// //myOptionTable->setColumnReadOnly( OPTION_VALUE_COLUMN, FALSE );///// myOptionTable->verticalHeader()->hide(); //myOptionTable->setSelectionBehavior( QAbstractItemView::SelectRows ); QPushButton* addBtn = new QPushButton( tr( "ADD_OPTION"), myAdvGroup ); - anAdvLayout->addWidget( addBtn, 2, 2, 1, 1 ); addBtn->setMenu( new QMenu() ); - QPushButton* rmBtn = new QPushButton( tr( "REMOVE_OPTION"), myAdvGroup ); - anAdvLayout->addWidget( rmBtn, 3, 2, 1, 1 ); - anAdvLayout->setRowStretch( 4, 5 ); - anAdvLayout->setColumnStretch( 1, 5 ); + myPreCADGroupBox = new QGroupBox(tr("BLSURF_PRECAD_GROUP"), myAdvGroup ); + myPreCADGroupBox->setEnabled(false); + QGridLayout* aPreCADGroupLayout = new QGridLayout(myPreCADGroupBox); + myPreCADMergeEdges = new QCheckBox(tr("BLSURF_PRECAD_MERGE_EDGES"),myPreCADGroupBox); + aPreCADGroupLayout->addWidget(myPreCADMergeEdges,0,0,1,2); + myPreCADRemoveNanoEdges = new QCheckBox(tr("BLSURF_PRECAD_REMOVE_NANO_EDGES"),myPreCADGroupBox); + aPreCADGroupLayout->addWidget(myPreCADRemoveNanoEdges,1,0,1,2); + myPreCADEpsNano = new SMESHGUI_SpinBox(myPreCADGroupBox); + myPreCADEpsNano->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); + myPreCADEpsNano->setText(""); + aPreCADGroupLayout->addWidget( new QLabel( tr( "BLSURF_PRECAD_EPS_NANO" ), myPreCADGroupBox ), 2, 0, 1, 1 ); + aPreCADGroupLayout->addWidget(myPreCADEpsNano, 2, 1, 1, 1 ); + myPreCADDiscardInput = new QCheckBox(tr("BLSURF_PRECAD_DISCARD_INPUT"),myPreCADGroupBox); + aPreCADGroupLayout->addWidget(myPreCADDiscardInput, 3, 0, 1, 2); + + QPushButton* chooseGMFBtn = new QPushButton( tr( "BLSURF_GMF_FILE" ), myAdvGroup ); + myGMFFileName = new QLineEdit(myAdvGroup); +// myGMFFileMode = new QCheckBox(tr("BLSURF_GMF_MODE"),myAdvGroup); + + // ADD WIDGETS (ADVANCED TAB) + anAdvLayout->addWidget( new QLabel( tr( "BLSURF_VERBOSITY" ), myAdvGroup ), 0, 0, 1, 1 ); + anAdvLayout->addWidget( myVerbosity, 0, 1, 1, 1 ); + anAdvLayout->addWidget( new QLabel( tr( "BLSURF_TOPOLOGY" ), myAdvGroup ), 1, 0, 1, 1 ); + anAdvLayout->addWidget( myTopology, 1, 1, 1, 1 ); + anAdvLayout->addWidget( myPreCADGroupBox , 2, 0, 1, 2 ); + anAdvLayout->addWidget( addBtn, 0, 2, 1, 1 ); + anAdvLayout->addWidget( rmBtn, 0, 3, 1, 1 ); + anAdvLayout->addWidget( myOptionTable, 1, 2, 3, 2 ); + anAdvLayout->addWidget( chooseGMFBtn, 3, 0, 1, 1 ); + anAdvLayout->addWidget( myGMFFileName, 3, 1, 1, 1 ); +// anAdvLayout->addWidget( myGMFFileMode, 4, 0, 1, 2 ); + anAdvLayout->setRowStretch(4,1); + + + // Size Maps parameters + + mySmpGroup = new QWidget(); +// mySmpGroup->setMinimumWidth(500); + + //Layout + QGridLayout* anSmpLayout = new QGridLayout(mySmpGroup); + + // Table + mySizeMapTable = new QTreeWidget( mySmpGroup ); + mySizeMapTable ->setMinimumWidth(200); + QStringList sizeMapHeaders; + sizeMapHeaders << tr( "SMP_NAME_COLUMN" )<< tr( "SMP_SIZEMAP_COLUMN" )<< tr( "SMP_ENTRY_COLUMN" );// << tr( "SMP_DIST_COLUMN" ); + mySizeMapTable->setHeaderLabels(sizeMapHeaders); + mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN); + mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); + mySizeMapTable->hideColumn(SMP_ENTRY_COLUMN); + mySizeMapTable->setAlternatingRowColors(true); + + // tab widget + smpTab = new QTabWidget( mySmpGroup ); + smpTab->setTabShape( QTabWidget::Rounded ); + smpTab->setTabPosition( QTabWidget::South ); + lay->addWidget( smpTab ); + + // Filters of selection + TColStd_MapOfInteger SM_ShapeTypes, ATT_ShapeTypes; + + SM_ShapeTypes.Add( TopAbs_VERTEX ); + SM_ShapeTypes.Add( TopAbs_EDGE ); + SM_ShapeTypes.Add( TopAbs_FACE ); + SM_ShapeTypes.Add( TopAbs_COMPOUND ); + + ATT_ShapeTypes.Add( TopAbs_VERTEX ); + ATT_ShapeTypes.Add( TopAbs_EDGE ); + ATT_ShapeTypes.Add( TopAbs_WIRE ); + ATT_ShapeTypes.Add( TopAbs_COMPOUND ); + + SMESH_NumberFilter* myFilter1 = new SMESH_NumberFilter("GEOM", TopAbs_SHAPE, 0, SM_ShapeTypes); + SMESH_NumberFilter* myFilter2 = new SMESH_NumberFilter("GEOM", TopAbs_SHAPE, 0, ATT_ShapeTypes); + SMESH_NumberFilter* myFilter3 = new SMESH_NumberFilter("GEOM", TopAbs_SHAPE, 0, TopAbs_FACE); + + // Standard size map tab + mySmpStdGroup = new QWidget(); + QGridLayout* anSmpStdLayout = new QGridLayout(mySmpStdGroup); + myGeomSelWdg1 = new StdMeshersGUI_ObjectReferenceParamWdg( myFilter1, 0, /*multiSel=*/false,/*stretch=*/false); + myGeomSelWdg1->SetDefaultText(tr("BLS_SEL_SHAPE"), "QLineEdit { color: grey }"); + mySmpSizeSpin = new SMESHGUI_SpinBox(mySmpStdGroup); + mySmpSizeSpin->RangeStepAndValidator(0., COORD_MAX, 1.0, "length_precision"); + QLabel* mySmpSizeLabel = new QLabel(tr("BLSURF_SM_SIZE"),mySmpStdGroup); + + // Attractor tab + myAttractorGroup = new QWidget(); + QGridLayout* anAttLayout = new QGridLayout(myAttractorGroup); + myGeomSelWdg2 = new StdMeshersGUI_ObjectReferenceParamWdg( myFilter3, 0, /*multiSel=*/false,/*stretch=*/false); + myGeomSelWdg2->SetDefaultText(tr("BLS_SEL_FACE"), "QLineEdit { color: grey }"); + myGeomSelWdg2->AvoidSimultaneousSelection(myGeomSelWdg1); + myAttractorCheck = new QCheckBox(tr("BLSURF_ATTRACTOR"),myAttractorGroup); + myConstSizeCheck = new QCheckBox(tr("BLSURF_CONST_SIZE"),myAttractorGroup); + QFrame* attLine = new QFrame(myAttractorGroup); + attLine->setFrameShape(QFrame::HLine); + attLine->setFrameShadow(QFrame::Sunken); + myAttSelWdg = new StdMeshersGUI_ObjectReferenceParamWdg( myFilter2, myAttractorGroup, /*multiSel=*/false,/*stretch=*/false); + myAttSelWdg->SetDefaultText(tr("BLS_SEL_ATTRACTOR"), "QLineEdit { color: grey }"); + myAttSizeSpin = new SMESHGUI_SpinBox(myAttractorGroup); + myAttSizeSpin->RangeStepAndValidator(0., COORD_MAX, 1.0, "length_precision"); + myAttSizeLabel = new QLabel(tr("BLSURF_SM_SIZE"),myAttractorGroup); + myAttDistSpin = new SMESHGUI_SpinBox(myAttractorGroup); + myAttDistSpin->RangeStepAndValidator(0., COORD_MAX, 10.0, "length_precision"); + myAttDistLabel = new QLabel(tr("BLSURF_ATT_DIST"),myAttractorGroup); + myAttDistSpin2 = new SMESHGUI_SpinBox(myAttractorGroup); + myAttDistSpin2->RangeStepAndValidator(0., COORD_MAX, 1.0, "length_precision"); + myAttDistLabel2 = new QLabel(tr("BLSURF_ATT_RADIUS"),myAttractorGroup); + + myAttSelWdg->AvoidSimultaneousSelection(myGeomSelWdg1); + myAttSelWdg->AvoidSimultaneousSelection(myGeomSelWdg2); + + // Push buttons + + addMapButton = new QPushButton(tr("BLSURF_SM_ADD"),mySmpGroup); + removeMapButton = new QPushButton(tr("BLSURF_SM_REMOVE"),mySmpGroup); + modifyMapButton = new QPushButton(tr("BLSURF_SM_MODIFY"),mySmpGroup); + modifyMapButton->setEnabled(false); + + // Init SpinBoxes + myAttSelWdg->setEnabled(false); + myAttSizeSpin->setEnabled(false); + myAttSizeLabel->setEnabled(false); + myAttDistSpin->setEnabled(false); + myAttDistLabel->setEnabled(false); + myAttDistSpin2->setEnabled(false); + myAttDistLabel2->setEnabled(false); + myAttDistSpin->setValue(0.); + myAttDistSpin2->setValue(0.); + myAttSizeSpin->setValue(0.); + mySmpSizeSpin->setValue(0.); + + + // ADD WIDGETS (SIZEMAP TAB) + anSmpLayout->addWidget(mySizeMapTable, 0, 0, SMP_NB_LINES, 1); + anSmpLayout->setColumnStretch(0, 1); +// anSmpLayout->addWidget(line2, SMP_SEPARATOR2, 1, 2, 2); + anSmpLayout->addWidget(smpTab, SMP_TAB_WDG, 1, 1, 3); + anSmpLayout->setRowStretch(SMP_TAB_WDG, 1); + anSmpLayout->addWidget(addMapButton, SMP_ADD_BTN, 1, 1, 1); + anSmpLayout->addWidget(removeMapButton, SMP_ADD_BTN, 2, 1, 1); + anSmpLayout->addWidget(modifyMapButton, SMP_ADD_BTN, 3, 1, 1); + + // STANDARD TAB + anSmpStdLayout->addWidget(myGeomSelWdg1, SMP_GEOM_BTN_1, 1, 1, 2); + anSmpStdLayout->addWidget(mySmpSizeLabel, SMP_SIZE, 1, 1, 1); + anSmpStdLayout->addWidget(mySmpSizeSpin, SMP_SIZE, 2, 1, 1); + anSmpStdLayout->setRowStretch(SMP_SPACE2, 1); + + // ADVANCED TAB + anAttLayout->addWidget(myGeomSelWdg2, SMP_GEOM_BTN_2, 1, 1, 2); + anAttLayout->addWidget(myAttractorCheck, ATT_CHECK, 1, 1, 2); + anAttLayout->addWidget(myConstSizeCheck, CONST_SIZE_CHECK,1, 1, 2); + anAttLayout->addWidget(attLine, SMP_SPACE, 1, 1, 2); + anAttLayout->addWidget(myAttSelWdg, SMP_ATT_SHAPE, 1, 1, 2); + anAttLayout->addWidget(myAttSizeLabel, SMP_ATT_SIZE, 1, 1, 1); + anAttLayout->addWidget(myAttSizeSpin, SMP_ATT_SIZE, 2, 1, 1); + anAttLayout->addWidget(myAttDistLabel, SMP_ATT_DIST, 1, 1, 1); + anAttLayout->addWidget(myAttDistSpin, SMP_ATT_DIST, 2, 1, 1); + anAttLayout->addWidget(myAttDistLabel2, SMP_ATT_RAD, 1, 1, 1); + anAttLayout->addWidget(myAttDistSpin2, SMP_ATT_RAD, 2, 1, 1); + anAttLayout->setRowStretch(SMP_ATT_RAD+1, 1); + + smpTab->insertTab( SMP_STD_TAB, mySmpStdGroup, tr( "BLSURF_SM_STD_TAB" ) ); + smpTab->insertTab( ATT_TAB, myAttractorGroup, tr( "BLSURF_SM_ATT_TAB" ) ); + + smpTab->setCurrentIndex( SMP_STD_TAB ); + + // Enforced vertices parameters + myEnfGroup = new QWidget(); + QGridLayout* anEnfLayout = new QGridLayout(myEnfGroup); +// +// myEnforcedVertexWidget = new DlgBlSurfHyp_Enforced(myEnfGroup); +// anEnfLayout->addWidget(myEnforcedVertexWidget); +// MESSAGE("Creating DlgBlSurfHyp_Enforced widget instance"); +// myEnforcedVertexWidget = new DlgBlSurfHyp_Enforced(); + + myEnforcedTreeWidget = new QTreeWidget(myEnfGroup); + myEnforcedTreeWidget->setColumnCount( ENF_VER_NB_COLUMNS ); + myEnforcedTreeWidget->setSortingEnabled(true); + QStringList enforcedHeaders; + enforcedHeaders << tr("BLSURF_ENF_VER_NAME_COLUMN") << tr("BLSURF_ENF_VER_FACE_ENTRY_COLUMN") + << tr("BLSURF_ENF_VER_X_COLUMN")<< tr("BLSURF_ENF_VER_Y_COLUMN") << tr("BLSURF_ENF_VER_Z_COLUMN") + << tr("BLSURF_ENF_VER_ENTRY_COLUMN") << tr( "BLSURF_ENF_VER_GROUP_COLUMN" ); + + myEnforcedTreeWidget->setHeaderLabels(enforcedHeaders); + myEnforcedTreeWidget->header()->setStretchLastSection(true); + myEnforcedTreeWidget->setAlternatingRowColors(true); + myEnforcedTreeWidget->setUniformRowHeights(true); + myEnforcedTreeWidget->setAnimated(true); + myEnforcedTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); + myEnforcedTreeWidget->setSelectionBehavior(QAbstractItemView::SelectItems); + for (int column = 0; column < ENF_VER_NB_COLUMNS; ++column) { + myEnforcedTreeWidget->header()->setResizeMode(column,QHeaderView::Interactive); + myEnforcedTreeWidget->resizeColumnToContents(column); + } + myEnforcedTreeWidget->hideColumn(ENF_VER_FACE_ENTRY_COLUMN); + myEnforcedTreeWidget->hideColumn(ENF_VER_ENTRY_COLUMN); + myEnforcedTreeWidget->setItemDelegate(new EnforcedTreeWidgetDelegate()); + +// FACE AND VERTEX SELECTION + TColStd_MapOfInteger shapeTypes1, shapeTypes2; + shapeTypes1.Add( TopAbs_FACE ); + shapeTypes1.Add( TopAbs_COMPOUND ); + shapeTypes2.Add( TopAbs_VERTEX ); + shapeTypes2.Add( TopAbs_COMPOUND ); + + SMESH_NumberFilter* faceFilter = new SMESH_NumberFilter("GEOM", TopAbs_FACE, 0, shapeTypes1); + myEnfFaceWdg = new StdMeshersGUI_ObjectReferenceParamWdg( faceFilter, 0, /*multiSel=*/true, /*stretch=*/false); + myEnfFaceWdg->SetDefaultText(tr("BLS_SEL_FACES"), "QLineEdit { color: grey }"); + + SMESH_NumberFilter* vertexFilter = new SMESH_NumberFilter("GEOM", TopAbs_SHAPE, 1, shapeTypes2); + myEnfVertexWdg = new StdMeshersGUI_ObjectReferenceParamWdg( vertexFilter, 0, /*multiSel=*/true, /*stretch=*/false); + myEnfVertexWdg->SetDefaultText(tr("BLS_SEL_VERTICES"), "QLineEdit { color: grey }"); + + myEnfVertexWdg->AvoidSimultaneousSelection(myEnfFaceWdg); + + QLabel* myXCoordLabel = new QLabel( tr( "BLSURF_ENF_VER_X_LABEL" ), myEnfGroup ); + myXCoord = new SMESHGUI_SpinBox(myEnfGroup); + myXCoord->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + + QLabel* myYCoordLabel = new QLabel( tr( "BLSURF_ENF_VER_Y_LABEL" ), myEnfGroup ); + myYCoord = new SMESHGUI_SpinBox(myEnfGroup); + myYCoord->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + + QLabel* myZCoordLabel = new QLabel( tr( "BLSURF_ENF_VER_Z_LABEL" ), myEnfGroup ); + myZCoord = new SMESHGUI_SpinBox(myEnfGroup); + myZCoord->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + + QLabel* myGroupNameLabel = new QLabel( tr( "BLSURF_ENF_VER_GROUP_LABEL" ), myEnfGroup ); + myGroupName = new QLineEdit(myEnfGroup); + + addVertexButton = new QPushButton(tr("BLSURF_ENF_VER_VERTEX"),myEnfGroup); + removeVertexButton = new QPushButton(tr("BLSURF_ENF_VER_REMOVE"),myEnfGroup); + + myInternalEnforcedVerticesAllFaces = new QCheckBox(tr("BLSURF_ENF_VER_INTERNAL_VERTICES"),myEnfGroup); + + QLabel* myInternalEnforcedVerticesAllFacesGroupLabel = new QLabel( tr( "BLSURF_ENF_VER_GROUP_LABEL" ), myEnfGroup ); + myInternalEnforcedVerticesAllFacesGroup = new QLineEdit(myEnfGroup); + +// myGlobalGroupName = new QCheckBox(tr("BLSURF_ENF_VER_GROUPS"), myEnfGroup); +// myGlobalGroupName->setChecked(false); + + anEnfLayout->addWidget(myEnforcedTreeWidget, 0, 0, ENF_VER_NB_LINES, 1); + QGridLayout* anEnfLayout2 = new QGridLayout(myEnfGroup); +// FACE AND VERTEX SELECTION + anEnfLayout2->addWidget(myEnfFaceWdg, ENF_VER_FACE, 0, 1, 2); + anEnfLayout2->addWidget(myEnfVertexWdg, ENF_VER_VERTEX, 0, 1, 2); + anEnfLayout2->addWidget(myXCoordLabel, ENF_VER_X_COORD, 0, 1, 1); + anEnfLayout2->addWidget(myXCoord, ENF_VER_X_COORD, 1, 1, 1); + anEnfLayout2->addWidget(myYCoordLabel, ENF_VER_Y_COORD, 0, 1, 1); + anEnfLayout2->addWidget(myYCoord, ENF_VER_Y_COORD, 1, 1, 1); + anEnfLayout2->addWidget(myZCoordLabel, ENF_VER_Z_COORD, 0, 1, 1); + anEnfLayout2->addWidget(myZCoord, ENF_VER_Z_COORD, 1, 1, 1); + anEnfLayout2->addWidget(myGroupNameLabel, ENF_VER_GROUP, 0, 1, 1); + anEnfLayout2->addWidget(myGroupName, ENF_VER_GROUP, 1, 1, 1); +// anEnfLayout2->addWidget(myGlobalGroupName, ENF_VER_GROUP_CHECK, 0, 1, 2); +// anEnfLayout2->setRowStretch( ENF_VER_SPACE, 1); + anEnfLayout2->addWidget(addVertexButton, ENF_VER_BTN, 0, 1, 1); + anEnfLayout2->addWidget(removeVertexButton, ENF_VER_BTN, 1, 1, 1); + anEnfLayout2->addWidget(myInternalEnforcedVerticesAllFaces, ENF_VER_INTERNAL_ALL_FACES, 0, 1, 2); + anEnfLayout2->addWidget(myInternalEnforcedVerticesAllFacesGroupLabel, ENF_VER_INTERNAL_ALL_FACES_GROUP, 0, 1, 1); + anEnfLayout2->addWidget(myInternalEnforcedVerticesAllFacesGroup, ENF_VER_INTERNAL_ALL_FACES_GROUP, 1, 1, 1); + anEnfLayout2->setRowStretch(ENF_VER_NB_LINES+1, 1); +// anEnfLayout2->addWidget(makeGroupsCheck, ENF_VER_GROUP_CHECK, 0, 1, 2); + anEnfLayout->addLayout(anEnfLayout2, 0,1,ENF_VER_NB_LINES+1,2); +// anEnfLayout->setRowStretch(1, 1); // --- tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) ); - tab->insertTab( ADV_TAB, myAdvGroup, tr( "GHS3D_ADV_ARGS" ) ); + tab->insertTab( ADV_TAB, myAdvGroup, tr( "BLSURF_ADV_ARGS" ) ); + tab->insertTab( SMP_TAB, mySmpGroup, tr( "BLSURF_SIZE_MAP" ) ); + tab->insertTab( ENF_TAB, myEnfGroup, tr( "BLSURF_ENF_VER" ) ); + tab->setCurrentIndex( STD_TAB ); // --- - connect( myGeometricMesh, SIGNAL( activated( int ) ), this, SLOT( onGeometricMeshChanged() ) ); - connect( myPhysicalMesh, SIGNAL( activated( int ) ), this, SLOT( onPhysicalMeshChanged() ) ); - connect( addBtn->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAddOption() ) ); - connect( addBtn->menu(), SIGNAL( triggered( QAction* ) ), this, SLOT( onOptionChosenInPopup( QAction* ) ) ); - connect( rmBtn, SIGNAL( clicked()), this, SLOT( onDeleteOption() ) ); + connect( myGeometricMesh, SIGNAL( activated( int ) ), this, SLOT( onGeometricMeshChanged() ) ); + connect( myPhysicalMesh, SIGNAL( activated( int ) ), this, SLOT( onPhysicalMeshChanged() ) ); + connect( myTopology, SIGNAL( activated( int ) ), this, SLOT( onTopologyChanged( int ) ) ); + connect( addBtn->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAddOption() ) ); + connect( addBtn->menu(), SIGNAL( triggered( QAction* ) ), this, SLOT( onOptionChosenInPopup( QAction* ) ) ); + connect( rmBtn, SIGNAL( clicked()), this, SLOT( onDeleteOption() ) ); + connect( chooseGMFBtn, SIGNAL( clicked()), this, SLOT( onChooseGMFFile() ) ); + + // Size Maps + connect( addMapButton, SIGNAL( clicked()), this, SLOT( onAddMap() ) ); + connect( removeMapButton, SIGNAL( clicked()), this, SLOT( onRemoveMap() ) ); + connect( modifyMapButton, SIGNAL( clicked()), this, SLOT( onModifyMap() ) ); +// connect( mySizeMapTable, SIGNAL( cellChanged ( int, int )), this, SLOT( onSetSizeMap(int,int ) ) ); + connect( mySizeMapTable, SIGNAL( itemClicked (QTreeWidgetItem *, int)),this, SLOT( onSmpItemClicked(QTreeWidgetItem *, int) ) ); + connect( myGeomSelWdg2, SIGNAL( contentModified() ), this, SLOT( onMapGeomContentModified() ) ); + connect( myGeomSelWdg1, SIGNAL( contentModified() ), this, SLOT( onMapGeomContentModified() ) ); +// connect( myAttractorGroup, SIGNAL( clicked(bool) ), this, SLOT( onAttractorGroupClicked(bool) ) ); + connect( mySizeMapTable, SIGNAL( itemChanged (QTreeWidgetItem *, int)),this, SLOT( onSetSizeMap(QTreeWidgetItem *, int) ) ); + connect( myAttractorCheck, SIGNAL( stateChanged ( int )), this, SLOT( onAttractorClicked( int ) ) ); + connect( myConstSizeCheck, SIGNAL( stateChanged ( int )), this, SLOT( onConstSizeClicked( int ) ) ); + connect( smpTab, SIGNAL( currentChanged ( int )), this, SLOT( onSmpTabChanged( int ) ) ); + + // Enforced vertices + connect( myEnforcedTreeWidget,SIGNAL( itemClicked(QTreeWidgetItem *, int)), this, SLOT( synchronizeCoords() ) ); + connect( myEnforcedTreeWidget,SIGNAL( itemChanged(QTreeWidgetItem *, int)), this, SLOT( updateEnforcedVertexValues(QTreeWidgetItem *, int) ) ); +// connect( myEnforcedTreeWidget,SIGNAL( itemChanged(QTreeWidgetItem *, int)), this, SLOT( update(QTreeWidgetItem *, int) ) ); + connect( myEnforcedTreeWidget,SIGNAL( itemSelectionChanged() ), this, SLOT( synchronizeCoords() ) ); + connect( addVertexButton, SIGNAL( clicked()), this, SLOT( onAddEnforcedVertices() ) ); + connect( removeVertexButton, SIGNAL( clicked()), this, SLOT( onRemoveEnforcedVertex() ) ); + connect( myEnfVertexWdg, SIGNAL( contentModified()), this, SLOT( onSelectEnforcedVertex() ) ); + connect( myInternalEnforcedVerticesAllFaces, SIGNAL( stateChanged ( int )), this, SLOT( onInternalVerticesClicked( int ) ) ); +// connect( myEnfVertexWdg, SIGNAL( selectionActivated()), this, SLOT( onVertexSelectionActivated() ) ); +// connect( myEnfFaceWdg, SIGNAL( selectionActivated()), this, SLOT( onFaceSelectionActivated() ) ); return fr; } +/** BLSURFPluginGUI_HypothesisCreator::deactivateSelection(QWidget*, QWidget*) +This method stop the selection of the widgets StdMeshersGUI_ObjectReferenceParamWdg +*/ +// void BLSURFPluginGUI_HypothesisCreator::deactivateSelection(QWidget* old, QWidget* now) +// { +// if ((now == myXCoord) || (now == myYCoord) || (now == myZCoord) +// || (now = myGroupName) || (now = myGlobalGroupName) || (now = myEnforcedTreeWidget)) { +// BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; +// that->getGeomSelectionTool()->selectionMgr()->clearFilters(); +// myEnfFaceWdg->deactivateSelection(); +// myEnfVertexWdg->deactivateSelection(); +// } +// } + +/** + * This method resets the content of the X, Y, Z widgets; +**/ +void BLSURFPluginGUI_HypothesisCreator::clearEnforcedVertexWidgets() +{ + myXCoord->setCleared(true); + myYCoord->setCleared(true); + myZCoord->setCleared(true); + myXCoord->setText(""); + myYCoord->setText(""); + myZCoord->setText(""); +// myGroupName->setText(""); +} + +/** BLSURFPluginGUI_HypothesisCreator::updateEnforcedVertexValues(item, column) +This method updates the tooltip of a modified item. The QLineEdit widgets content +is synchronized with the coordinates of the enforced vertex clicked in the tree widget. +*/ +void BLSURFPluginGUI_HypothesisCreator::updateEnforcedVertexValues(QTreeWidgetItem* item, int column) { +// MESSAGE("BLSURFPluginGUI_HypothesisCreator::updateEnforcedVertexValues"); + QVariant vertexName = item->data(ENF_VER_NAME_COLUMN, Qt::EditRole); + QVariant x = item->data(ENF_VER_X_COLUMN, Qt::EditRole); + QVariant y = item->data(ENF_VER_Y_COLUMN, Qt::EditRole); + QVariant z = item->data(ENF_VER_Z_COLUMN, Qt::EditRole); + QVariant entry = item->data(ENF_VER_ENTRY_COLUMN, Qt::EditRole); + QString groupName = item->data(ENF_VER_GROUP_COLUMN, Qt::EditRole).toString(); + QTreeWidgetItem* parent = item->parent(); + + clearEnforcedVertexWidgets(); + + if (parent && (!x.isNull() || !entry.isNull())) { + QString shapeName = parent->data(ENF_VER_NAME_COLUMN, Qt::EditRole).toString(); + QString toolTip = shapeName + QString(": ") + vertexName.toString(); + if (entry.isNull()) { + toolTip += QString("(") + x.toString(); + toolTip += QString(", ") + y.toString(); + toolTip += QString(", ") + z.toString(); + toolTip += QString(")"); + } + + if (!groupName.isEmpty()) + toolTip += QString(" [") + groupName + QString("]"); + + item->setToolTip(ENF_VER_NAME_COLUMN,toolTip); + + if (!x.isNull()) { + myXCoord->SetValue(x.toDouble()); + myYCoord->SetValue(y.toDouble()); + myZCoord->SetValue(z.toDouble()); + } + + if (!groupName.isEmpty()) + myGroupName->setText(groupName); + } +} + +void BLSURFPluginGUI_HypothesisCreator::onSelectEnforcedVertex() { + int nbSelEnfVertex = myEnfVertexWdg->NbObjects(); + clearEnforcedVertexWidgets(); + if (nbSelEnfVertex == 1) + { + if ( CORBA::is_nil( getGeomEngine() ) && !GeometryGUI::InitGeomGen() ) + return ; + + myEnfVertex = myEnfVertexWdg->GetObject< GEOM::GEOM_Object >(nbSelEnfVertex-1); + if (myEnfVertex->GetShapeType() == GEOM::VERTEX) { + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + GEOM::GEOM_IMeasureOperations_var measureOp = getGeomEngine()->GetIMeasureOperations( that->getGeomSelectionTool()->getMyStudy()->StudyId() ); + if (CORBA::is_nil(measureOp)) + return; + + CORBA::Double x,y,z; + measureOp->PointCoordinates (myEnfVertex, x, y, z); + if ( measureOp->IsDone() ) + { + myXCoord->SetValue(x); + myYCoord->SetValue(y); + myZCoord->SetValue(z); + } + } + } +} + +/** BLSURFPluginGUI_HypothesisCreator::synchronizeCoords() +This method synchronizes the QLineEdit/SMESHGUI_SpinBox widgets content with the coordinates +of the enforced vertex clicked in the tree widget. +*/ +void BLSURFPluginGUI_HypothesisCreator::synchronizeCoords() { + clearEnforcedVertexWidgets(); + QList items = myEnforcedTreeWidget->selectedItems(); + if (! items.isEmpty() && items.size() == 1) { + QTreeWidgetItem *item = items[0]; +// for (int i=0 ; i < items.size() ; i++) { +// item = items[i]; + QVariant x = item->data(ENF_VER_X_COLUMN, Qt::EditRole); + QVariant y = item->data(ENF_VER_Y_COLUMN, Qt::EditRole); + QVariant z = item->data(ENF_VER_Z_COLUMN, Qt::EditRole); + QVariant entry = item->data(ENF_VER_ENTRY_COLUMN, Qt::EditRole); + QVariant group = item->data(ENF_VER_GROUP_COLUMN, Qt::EditRole); + if (!x.isNull()/* && entry.isNull()*/) { + myXCoord->SetValue(x.toDouble()); + myYCoord->SetValue(y.toDouble()); + myZCoord->SetValue(z.toDouble()); +// break; + } + if (!group.isNull() && (!x.isNull() || !entry.isNull())) + myGroupName->setText(group.toString()); +// } + } +} + +/** BLSURFPluginGUI_HypothesisCreator::addEnforcedFace(entry, shapeName, useInternalVertices) +This method adds a face containing enforced vertices in the tree widget. +*/ +QTreeWidgetItem* BLSURFPluginGUI_HypothesisCreator::addEnforcedFace(std::string theFaceEntry, std::string theFaceName) { + // Find theFaceEntry item + QList theItemList = myEnforcedTreeWidget->findItems(QString(theFaceEntry.c_str()),Qt::MatchExactly,ENF_VER_FACE_ENTRY_COLUMN); + QTreeWidgetItem* theItem; + if (theItemList.empty()) { + theItem = new QTreeWidgetItem(); + theItem->setData(ENF_VER_FACE_ENTRY_COLUMN, Qt::EditRole, QVariant(theFaceEntry.c_str())); + theItem->setData(ENF_VER_NAME_COLUMN, Qt::EditRole, QVariant(theFaceName.c_str())); + theItem->setToolTip(ENF_VER_NAME_COLUMN,QString(theFaceEntry.c_str())); + myEnforcedTreeWidget->addTopLevelItem(theItem); + } + else { + theItem = theItemList[0]; + } + return theItem; +} + +/** BLSURFPluginGUI_HypothesisCreator::addEnforcedVertex(entry, shapeName, x, y, z) +This method adds an enforced vertex (x,y,z) to shapeName in the tree widget. +*/ +void BLSURFPluginGUI_HypothesisCreator::addEnforcedVertex(QTreeWidgetItem* theItem, double x, double y, double z, + std::string vertexName, std::string geomEntry, std::string groupName) { + + std::string theFaceName = theItem->data(ENF_VER_NAME_COLUMN,Qt::EditRole).toString().toStdString(); +// MESSAGE("theItemName is " << theItem->text(ENF_VER_NAME_COLUMN).toStdString()); + bool okToCreate = true; + + const int nbVert = theItem->childCount(); +// MESSAGE("Number of child rows: " << nbVert); + if (nbVert >0) { + double childValueX,childValueY,childValueZ; + QString childEntry, childGroupName; + QTreeWidgetItem* child; + for (int row = 0;rowchild(row); + childGroupName = child->data(ENF_VER_GROUP_COLUMN,Qt::EditRole).toString(); + childEntry = child->data(ENF_VER_ENTRY_COLUMN,Qt::EditRole).toString(); + childValueX = child->data(ENF_VER_X_COLUMN,Qt::EditRole).toDouble(); + childValueY = child->data(ENF_VER_Y_COLUMN,Qt::EditRole).toDouble(); + childValueZ = child->data(ENF_VER_Z_COLUMN,Qt::EditRole).toDouble(); + if (((childValueX == x) && (childValueY == y) && (childValueZ == z)) || ( (childEntry.toStdString() != "") && (childEntry.toStdString() == geomEntry))) { + // update group name + if (childGroupName.toStdString() != groupName) { + MESSAGE("Group is updated from \"" << childGroupName.toStdString() << "\" to \"" << groupName << "\""); + child->setData(ENF_VER_GROUP_COLUMN, Qt::EditRole, QVariant(groupName.c_str())); + } + okToCreate = false; + break; + } // if + } // for + } // if + if (!okToCreate) { + if (geomEntry.empty()) { + MESSAGE("In " << theFaceName << " vertex with coords " << x << ", " << y << ", " << z << " already exist: dont create again"); + } + else { + MESSAGE("In " << theFaceName << " vertex with entry " << geomEntry << " already exist: dont create again"); + } + return; + } + + if (geomEntry.empty()) { + MESSAGE("In " << theFaceName << " vertex with coords " << x << ", " << y << ", " << z<< " is created"); + } + else { + MESSAGE("In " << theFaceName << " vertex with geom entry " << geomEntry << " is created"); + } + + QTreeWidgetItem *vertexItem = new QTreeWidgetItem( theItem); + vertexItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); + QPixmap iconSelect (SUIT_Session::session()->resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT"))); + QSize iconSize = iconSelect.size()*0.7; + + int vertexIndex=myEnforcedTreeWidget->indexOfTopLevelItem(theItem); + QString myVertexName; + int indexRef = -1; + while(indexRef != vertexIndex) { + indexRef = vertexIndex; + if (vertexName.empty()) + myVertexName = QString("Vertex #%1").arg(vertexIndex); + else + myVertexName = QString(vertexName.c_str()); + + for (int row = 0;rowchild(row)->data(ENF_VER_NAME_COLUMN,Qt::EditRole).toString(); + if (myVertexName == name) { + vertexIndex++; + break; + } + } + } + vertexItem->setData( ENF_VER_NAME_COLUMN, Qt::EditRole, myVertexName ); + if (geomEntry.empty()) { + vertexItem->setData( ENF_VER_X_COLUMN, Qt::EditRole, QVariant(x) ); + vertexItem->setData( ENF_VER_Y_COLUMN, Qt::EditRole, QVariant(y) ); + vertexItem->setData( ENF_VER_Z_COLUMN, Qt::EditRole, QVariant(z) ); + } + else { + vertexItem->setIcon(ENF_VER_NAME_COLUMN, QIcon(iconSelect.scaled(iconSize,Qt::KeepAspectRatio,Qt::SmoothTransformation))); + vertexItem->setData( ENF_VER_ENTRY_COLUMN, Qt::EditRole, QString(geomEntry.c_str()) ); + } + if (groupName != "") + vertexItem->setData( ENF_VER_GROUP_COLUMN, Qt::EditRole, QVariant(groupName.c_str())); + + QString toolTip = QString(theFaceName.c_str())+QString(": ")+myVertexName; + if (geomEntry.empty()) { + toolTip += QString(" (%1, ").arg(x); + toolTip += QString("%1, ").arg(y); + toolTip += QString("%1)").arg(z); + } + if (groupName != "") + toolTip += QString(" [%1]").arg(groupName.c_str()); + + vertexItem->setToolTip(ENF_VER_NAME_COLUMN,toolTip); + theItem->setExpanded(true); + myEnforcedTreeWidget->setCurrentItem(vertexItem,ENF_VER_NAME_COLUMN); +} + +/** BLSURFPluginGUI_HypothesisCreator::onAddEnforcedVertices() +This method is called when a item is added into the enforced vertices tree widget +*/ +void BLSURFPluginGUI_HypothesisCreator::onAddEnforcedVertices() { +// MESSAGE("BLSURFPluginGUI_HypothesisCreator::onAddEnforcedVertices"); + + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + + that->getGeomSelectionTool()->selectionMgr()->clearFilters(); + myEnfFaceWdg->deactivateSelection(); + myEnfVertexWdg->deactivateSelection(); + + for (int column = 0; column < myEnforcedTreeWidget->columnCount(); ++column) + myEnforcedTreeWidget->resizeColumnToContents(column); + + // Vertex selection + int selEnfFace = myEnfFaceWdg->NbObjects(); + int selEnfVertex = myEnfVertexWdg->NbObjects(); + bool coordsEmpty = (myXCoord->text().isEmpty()) || (myYCoord->text().isEmpty()) || (myZCoord->text().isEmpty()); + + if (selEnfFace == 0) + return; + + if ((selEnfVertex == 0) && coordsEmpty) + return; + + string entry, shapeName; + + for (int i = 0 ; i < selEnfFace ; i++) { + myEnfFace = myEnfFaceWdg->GetObject< GEOM::GEOM_Object >(i); + entry = myEnfFace->GetStudyEntry(); + shapeName = myEnfFace->GetName(); + + QTreeWidgetItem * faceItem = addEnforcedFace(entry, shapeName); + + std::string groupName = myGroupName->text().toStdString(); + + if (boost::trim_copy(groupName).empty()) + groupName = ""; + + if (selEnfVertex == 1) + { + double x,y,z; + x = myXCoord->GetValue(); + y = myYCoord->GetValue(); + z = myZCoord->GetValue(); + if (selEnfVertex == 1) { + myEnfVertex = myEnfVertexWdg->GetObject< GEOM::GEOM_Object >(); + addEnforcedVertex(faceItem, x, y, z, myEnfVertex->GetName(),myEnfVertex->GetStudyEntry(), groupName); + } + else + addEnforcedVertex(faceItem, x, y, z, "", "", groupName); + } + else + { + if ( CORBA::is_nil(getGeomEngine())) + return; + + GEOM::GEOM_IMeasureOperations_var measureOp = getGeomEngine()->GetIMeasureOperations( that->getGeomSelectionTool()->getMyStudy()->StudyId() ); + if (CORBA::is_nil(measureOp)) + return; + + CORBA::Double x,y,z; + x = y = z = 0.; + for (int j = 0 ; j < selEnfVertex ; j++) + { + myEnfVertex = myEnfVertexWdg->GetObject< GEOM::GEOM_Object >(j); + if (myEnfVertex->GetShapeType() == GEOM::VERTEX) { + measureOp->PointCoordinates (myEnfVertex, x, y, z); + if ( measureOp->IsDone() ) + addEnforcedVertex(faceItem, x, y, z, myEnfVertex->GetName(),myEnfVertex->GetStudyEntry(), groupName); + } else if (myEnfVertex->GetShapeType() == GEOM::COMPOUND) { + addEnforcedVertex(faceItem, 0, 0, 0, myEnfVertex->GetName(),myEnfVertex->GetStudyEntry(), groupName); + } + } + } + } + + myEnfFaceWdg->SetObject(GEOM::GEOM_Object::_nil()); + myEnfVertexWdg->SetObject(GEOM::GEOM_Object::_nil()); + + for (int column = 0; column < myEnforcedTreeWidget->columnCount(); ++column) + myEnforcedTreeWidget->resizeColumnToContents(column); + + if ( myPhysicalMesh->currentIndex() != SizeMap ) { + myPhysicalMesh->setCurrentIndex( SizeMap ); + onPhysicalMeshChanged(); + } +} + +/** BLSURFPluginGUI_HypothesisCreator::onRemoveEnforcedVertex() +This method is called when a item is removed from the enforced vertices tree widget +*/ +void BLSURFPluginGUI_HypothesisCreator::onRemoveEnforcedVertex() { +// MESSAGE("BLSURFPluginGUI_HypothesisCreator::onRemoveEnforcedVertex"); + QList selectedItems = myEnforcedTreeWidget->selectedItems(); + QList selectedVertices; + QSet selectedEntries; + QTreeWidgetItem* item; + + foreach( item, selectedItems ) { + QVariant value = item->data(ENF_VER_X_COLUMN, Qt::EditRole); + if (! value.isNull()) + selectedVertices.append(item); + else { + value = item->data(ENF_VER_ENTRY_COLUMN, Qt::EditRole); + if (! value.isNull()) + selectedVertices.append(item); + else + selectedEntries.insert(item); + } + } + + foreach(item,selectedVertices) { + QTreeWidgetItem* parent = item->parent(); +// MESSAGE("From geometry "<< parent->text(ENF_VER_NAME_COLUMN).toStdString()<<" remove " << item->text(ENF_VER_NAME_COLUMN).toStdString()); + parent->removeChild(item); + delete item; + if (parent->childCount() == 0) { + if (selectedEntries.contains(parent)) + selectedEntries.remove(parent); + delete parent; + } + } + + foreach(item,selectedEntries) { +// MESSAGE("Remove " << item->text(ENF_VER_NAME_COLUMN).toStdString()); + delete item; + } + + myEnforcedTreeWidget->selectionModel()->clearSelection(); +} + + +void BLSURFPluginGUI_HypothesisCreator::onInternalVerticesClicked(int state) +{ + if (state == Qt::Checked) { + myInternalEnforcedVerticesAllFacesGroup->setEnabled(true); + } + if (state == Qt::Unchecked) { + myInternalEnforcedVerticesAllFacesGroup->setEnabled(false); + } +} + +/** BLSURFPluginGUI_HypothesisCreator::retrieveParams() +This method updates the GUI widgets with the hypothesis data +*/ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const { + MESSAGE("BLSURFPluginGUI_HypothesisCreator::retrieveParams"); BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; BlsurfHypothesisData data; @@ -317,49 +1507,180 @@ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const myName->setMinimumWidth( metrics.width( data.myName )+5 ); } myTopology->setCurrentIndex( data.myTopology ); + myPreCADGroupBox->setEnabled(data.myTopology == PreCAD); + myPreCADMergeEdges->setChecked( data.myPreCADMergeEdges ); + myPreCADRemoveNanoEdges->setChecked( data.myPreCADRemoveNanoEdges ); + myPreCADDiscardInput->setChecked( data.myPreCADDiscardInput ); + MESSAGE("data.myPreCADEpsNano: "<setText(""); + else + myPreCADEpsNano->SetValue( data.myPreCADEpsNano ); myPhysicalMesh->setCurrentIndex( data.myPhysicalMesh ); - myPhySize->setText( data.myPhySize ); + myPhySize->SetValue( data.myPhySize ); #ifdef WITH_SIZE_BOUNDARIES - myPhyMin->setText( data.myPhyMin ); - myPhyMax->setText( data.myPhyMax ); - myGeoMin->setText( data.myGeoMin ); - myGeoMax->setText( data.myGeoMax ); + MESSAGE("data.myPhyMin: "<setText(""); + else + myPhyMin->SetValue( data.myPhyMin ); + MESSAGE("data.myPhyMax: "<setText(""); + else + myPhyMax->SetValue( data.myPhyMax ); + MESSAGE("data.myGeoMin: "<setText(""); + else + myGeoMin->SetValue( data.myGeoMin ); + MESSAGE("data.myGeoMax: "<setText(""); + else + myGeoMax->SetValue( data.myGeoMax ); #endif myGeometricMesh->setCurrentIndex( data.myGeometricMesh ); - myAngleMeshS->setValue( data.myAngleMeshS ); - myAngleMeshC->setValue( data.myAngleMeshC ); - myGradation->setValue( data.myGradation ); + myAngleMeshS->SetValue( data.myAngleMeshS ); + myAngleMeshC->SetValue( data.myAngleMeshC ); + myGradation->SetValue( data.myGradation ); myAllowQuadrangles->setChecked( data.myAllowQuadrangles ); myDecimesh->setChecked( data.myDecimesh ); myVerbosity->setValue( data.myVerbosity ); if ( myOptions.operator->() ) { - printf("retrieveParams():myOptions->length()=%d\n",myOptions->length()); +// MESSAGE("retrieveParams():myOptions->length() = " << myOptions->length()); for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) { QString option = that->myOptions[i].in(); QStringList name_value = option.split( ":", QString::KeepEmptyParts ); if ( name_value.count() > 1 ) { QString idStr = QString("%1").arg( i ); int row = myOptionTable->rowCount(); - myOptionTable->setRowCount( row+1 ); - myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) ); - myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 ); - myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( name_value[0] ) ); - myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 ); - myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( name_value[1] ) ); - myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable | - Qt::ItemIsEditable | - Qt::ItemIsEnabled ); + myOptionTable->setRowCount( row+1 ); + myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) ); + myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 ); + myOptionTable->setItem( row, OPTION_TYPE_COLUMN, new QTableWidgetItem( "BLSURF" ) ); + myOptionTable->item( row, OPTION_TYPE_COLUMN )->setFlags( 0 ); + myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( name_value[0] ) ); + myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 ); + myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( name_value[1] ) ); + myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable | + Qt::ItemIsEditable | + Qt::ItemIsEnabled ); } - } + } + } + if ( myPreCADOptions.operator->() ) { +// MESSAGE("retrieveParams():myPreCADOptions->length() = " << myPreCADOptions->length()); + for ( int i = 0, nb = myPreCADOptions->length(); i < nb; ++i ) { + QString option = that->myPreCADOptions[i].in(); + QStringList name_value = option.split( ":", QString::KeepEmptyParts ); + if ( name_value.count() > 1 ) { + QString idStr = QString("%1").arg( i ); + int row = myOptionTable->rowCount(); + myOptionTable->setRowCount( row+1 ); + myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) ); + myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 ); + myOptionTable->setItem( row, OPTION_TYPE_COLUMN, new QTableWidgetItem( "PRECAD" ) ); + myOptionTable->item( row, OPTION_TYPE_COLUMN )->setFlags( 0 ); + myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( name_value[0] ) ); + myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 ); + myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( name_value[1] ) ); + myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable | + Qt::ItemIsEditable | + Qt::ItemIsEnabled ); + } + } } myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN ); + myGMFFileName->setText(QString(data.myGMFFileName.c_str())); +// myGMFFileMode->setChecked(data.myGMFFileMode); + + // Sizemaps + MESSAGE("retrieveParams():that->mySMPMap.size() = " << that->mySMPMap.size()); + QMapIterator i(that->mySMPMap); + GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool(); + while (i.hasNext()) { + i.next(); + const QString entry = i.key(); + const QString sizeMap = i.value(); + string shapeName = myGeomToolSelected->getNameFromEntry(entry.toStdString()); + int row = mySizeMapTable->topLevelItemCount(); + QTreeWidgetItem* item = new QTreeWidgetItem(); + mySizeMapTable->addTopLevelItem( item ); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled ); + item->setData(SMP_ENTRY_COLUMN,Qt::DisplayRole, QVariant(entry) ); + item->setData(SMP_NAME_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString(shapeName) ) ); + if (that->myATTMap.contains(entry)){ + const QString attEntry = that->myATTMap[entry]; + std::string attName = myGeomToolSelected->getNameFromEntry(attEntry.toStdString()); + QTreeWidgetItem* child = new QTreeWidgetItem(); + item->addChild( child ); + item->setExpanded(true); + child->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant( sizeMap ) ); + child->setData(SMP_ENTRY_COLUMN, Qt::DisplayRole, QVariant( attEntry ) ); + child->setData(SMP_NAME_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString( attName ) ) ); + + if (that->myAttDistMap[entry] > std::numeric_limits::epsilon()){ + item->setData(SMP_SIZEMAP_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString("Attractor" ) ) ); + } + else{ + item->setData(SMP_SIZEMAP_COLUMN, Qt::DisplayRole, QVariant( QString::fromStdString("Constant Size" ) ) ); + } + } + else + { + item->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant( sizeMap ) ); + } + } + mySizeMapTable->resizeColumnToContents( SMP_ENTRY_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN ); + mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); + + // Enforced vertices + MESSAGE("retrieveParams(): data.entryCoordsListMap.size() = " << data.faceEntryEnfVertexListMap.size()); + TFaceEntryEnfVertexListMap::const_iterator evmIt = data.faceEntryEnfVertexListMap.begin(); + + for ( ; evmIt != data.faceEntryEnfVertexListMap.end() ; ++evmIt) { + TEntry entry = (*evmIt).first; + std::string shapeName = myGeomToolSelected->getNameFromEntry(entry); + MESSAGE("Face entry: " << entry); + MESSAGE("Face name: " << shapeName); + + QTreeWidgetItem* faceItem = that->addEnforcedFace(entry, shapeName); + + TEnfVertexList evs = (*evmIt).second; + + TEnfVertexList::const_iterator evsIt = evs.begin(); + TEnfVertex *enfVertex; + for ( ; evsIt != evs.end() ; ++evsIt) { + enfVertex = (*evsIt); + MESSAGE("Name: " << enfVertex->name); + double x, y, z = 0; + if (enfVertex->coords.size()) { + x = enfVertex->coords[0]; + y = enfVertex->coords[1]; + z = enfVertex->coords[2]; + } + that->addEnforcedVertex(faceItem, x, y, z, enfVertex->name, enfVertex->geomEntry, enfVertex->grpName); + } + } + + for (int column = 0; column < myEnforcedTreeWidget->columnCount(); ++column) + myEnforcedTreeWidget->resizeColumnToContents(column); + + myInternalEnforcedVerticesAllFaces->setChecked(data.myInternalEnforcedVerticesAllFaces); + myInternalEnforcedVerticesAllFacesGroup->setText(QString(data.myInternalEnforcedVerticesAllFacesGroup.c_str())); + myInternalEnforcedVerticesAllFacesGroup->setEnabled(data.myInternalEnforcedVerticesAllFaces); // update widgets that->onPhysicalMeshChanged(); that->onGeometricMeshChanged(); } +/** BLSURFPluginGUI_HypothesisCreator::storeParams() +This method updates the hypothesis data with the GUI widgets content. +*/ QString BLSURFPluginGUI_HypothesisCreator::storeParams() const { BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; @@ -371,45 +1692,194 @@ QString BLSURFPluginGUI_HypothesisCreator::storeParams() const return guiHyp; } +/** BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo(h_data) +Updates the hypothesis data from hypothesis values. +*/ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData& h_data ) const { + MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo"); BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis() ); HypothesisData* data = SMESH::GetHypothesisData( hypType() ); h_data.myName = isCreation() && data ? hypName() : ""; - h_data.myTopology = (int) h->GetTopology(); - h_data.myPhysicalMesh = (int) h->GetPhysicalMesh(); - h_data.myPhySize = QString::number( h->GetPhySize() ); - h_data.myGeometricMesh = (int) h->GetGeometricMesh(); - h_data.myAngleMeshS = h->GetAngleMeshS(); - h_data.myAngleMeshC = h->GetAngleMeshC(); - h_data.myGradation = h->GetGradation(); - h_data.myAllowQuadrangles = h->GetQuadAllowed(); - h_data.myDecimesh = h->GetDecimesh(); - h_data.myVerbosity = h->GetVerbosity(); + h_data.myTopology = (int) h->GetTopology(); + h_data.myPhysicalMesh = (int) h->GetPhysicalMesh(); + h_data.myPhySize = h->GetPhySize(); + h_data.myGeometricMesh = (int) h->GetGeometricMesh(); + h_data.myAngleMeshS = h->GetAngleMeshS(); + h_data.myAngleMeshC = h->GetAngleMeshC(); + h_data.myGradation = h->GetGradation(); + h_data.myAllowQuadrangles = h->GetQuadAllowed(); + h_data.myDecimesh = h->GetDecimesh(); + h_data.myVerbosity = h->GetVerbosity(); + h_data.myPreCADMergeEdges = h->GetPreCADMergeEdges(); + h_data.myPreCADRemoveNanoEdges = h->GetPreCADRemoveNanoEdges(); + h_data.myPreCADDiscardInput = h->GetPreCADDiscardInput(); + double EpsNano = h->GetPreCADEpsNano(); + h_data.myPreCADEpsNano = EpsNano > 0 ? EpsNano : -1.0; #ifdef WITH_SIZE_BOUNDARIES double PhyMin = h->GetPhyMin(); double PhyMax = h->GetPhyMax(); double GeoMin = h->GetGeoMin(); double GeoMax = h->GetGeoMax(); - if ( PhyMin > 0 ) - h_data.myPhyMin = PhyMin > 0 ? QString::number( h->GetPhyMin() ) : QString(""); - h_data.myPhyMax = PhyMax > 0 ? QString::number( h->GetPhyMax() ) : QString(""); - h_data.myGeoMin = GeoMin > 0 ? QString::number( h->GetGeoMin() ) : QString(""); - h_data.myGeoMax = GeoMax > 0 ? QString::number( h->GetGeoMax() ) : QString(""); +// if ( PhyMin > 0 ) +// h_data.myPhyMin = PhyMin > 0 ? QString::number( h->GetPhyMin() ) : QString(""); +// h_data.myPhyMax = PhyMax > 0 ? QString::number( h->GetPhyMax() ) : QString(""); +// h_data.myGeoMin = GeoMin > 0 ? QString::number( h->GetGeoMin() ) : QString(""); +// h_data.myGeoMax = GeoMax > 0 ? QString::number( h->GetGeoMax() ) : QString(""); + h_data.myPhyMin = PhyMin > 0 ? PhyMin : -1.0; + h_data.myPhyMax = PhyMax > 0 ? PhyMax : -1.0; + h_data.myGeoMin = GeoMin > 0 ? GeoMin : -1.0; + h_data.myGeoMax = GeoMax > 0 ? GeoMax : -1.0; #endif BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; that->myOptions = h->GetOptionValues(); + that->myPreCADOptions = h->GetPreCADOptionValues(); + + h_data.myGMFFileName = h->GetGMFFile(); +// h_data.myGMFFileMode = h->GetGMFFileMode(); + + that->mySMPMap.clear(); + that->myATTMap.clear(); + that->myAttDistMap.clear(); + that->myDistMap.clear(); + + // classic size maps + BLSURFPlugin::string_array_var mySizeMaps = h->GetSizeMapEntries(); +// MESSAGE("mySizeMaps->length() = " << mySizeMaps->length()); + QString fullSizeMaps; + QStringList fullSizeMapList; + GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool(); + for ( int i = 0;ilength(); ++i ) { + fullSizeMaps = mySizeMaps[i].in(); +// MESSAGE("fullSizeMaps: " << fullSizeMaps.toStdString()); + fullSizeMapList = fullSizeMaps.split( "|", QString::KeepEmptyParts ); + if ( fullSizeMapList.count() > 1 ) { + string fullSizeMap = fullSizeMapList[1].toStdString(); + int pos = fullSizeMap.find("return")+7; +// MESSAGE("pos:" << pos); + QString sizeMap; + try { + sizeMap = QString::fromStdString(fullSizeMap.substr(pos, fullSizeMap.size()-pos)); + } + catch (...) { + continue; + } + that->mySMPMap[fullSizeMapList[0]] = sizeMap; +// MESSAGE("mySMPMap[" << fullSizeMapList[0].toStdString() << "] = " << sizeMap.toStdString()); + that->mySMPShapeTypeMap[fullSizeMapList[0]] = myGeomToolSelected->entryToShapeType(fullSizeMapList[0].toStdString()); +// MESSAGE("mySMPShapeTypeMap[" << fullSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullSizeMapList[0]]); + } + } + + // custom size maps +/* + BLSURFPlugin::string_array_var myCustomSizeMaps = h->GetCustomSizeMapEntries(); + MESSAGE("myCustomSizeMaps->length() = " << myCustomSizeMaps->length()); + + for ( int i = 0;ilength(); ++i ) { + QString fullCustomSizeMaps = myCustomSizeMaps[i].in(); + QStringList fullCustomSizeMapList = fullCustomSizeMaps.split( "|", QString::KeepEmptyParts ); + if ( fullCustomSizeMapList.count() > 1 ) { + that->mySMPMap[fullCustomSizeMapList[0]] = fullCustomSizeMapList[1]; + that->mySMPShapeTypeMap[fullCustomSizeMapList[0]] = GeomToolSelected->entryToShapeType(fullCustomSizeMapList[0].toStdString()); + MESSAGE("mySMPMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << fullCustomSizeMapList[1].toStdString()); + MESSAGE("mySMPShapeTypeMap[" << fullCustomSizeMapList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[fullCustomSizeMapList[0]]); + } + } +*/ + // attractor + BLSURFPlugin::string_array_var allMyAttractors = h->GetAttractorEntries(); +// MESSAGE("myAttractors->length() = " << allMyAttractors->length()); + + for ( int i = 0;ilength(); ++i ) { + QString myAttractors = allMyAttractors[i].in(); + QStringList myAttractorList = myAttractors.split( "|", QString::KeepEmptyParts ); + if ( myAttractorList.count() > 1 ) { + that->mySMPMap[myAttractorList[0]] = myAttractorList[1]; + that->mySMPShapeTypeMap[myAttractorList[0]] = myGeomToolSelected->entryToShapeType(myAttractorList[0].toStdString()); +// MESSAGE("mySMPMap[" << myAttractorList[0].toStdString() << "] = " << myAttractorList[1].toStdString()); +// MESSAGE("mySMPShapeTypeMap[" << myAttractorList[0].toStdString() << "] = " << that->mySMPShapeTypeMap[myAttractorList[0]]); + } + } + + // attractor new version + MESSAGE("retrieveParams, Attractors") + BLSURFPlugin::TAttParamsMap_var allMyAttractorParams = h->GetAttractorParams(); + for ( int i = 0;ilength(); ++i ) { + BLSURFPlugin::TAttractorParams myAttractorParams = allMyAttractorParams[i]; + QString faceEntry = myAttractorParams.faceEntry.in(); + QString attEntry = myAttractorParams.attEntry.in(); + MESSAGE("attEntry = "<mySMPMap[faceEntry] = QString::number( startSize, 'g', 6 ); // TODO utiliser les préférences ici (cf. sketcher) + that->mySMPShapeTypeMap[faceEntry] = myGeomToolSelected->entryToShapeType(faceEntry.toStdString()); + that->myATTMap[faceEntry] = attEntry; + that->myAttDistMap[faceEntry] = infDist; + that->myDistMap[faceEntry] = constDist; + } + + // Enforced vertices + h_data.enfVertexList.clear(); + h_data.faceEntryEnfVertexListMap.clear(); + /* TODO GROUPS + h_data.groupNameEnfVertexListMap.clear(); + */ + + BLSURFPlugin::TFaceEntryEnfVertexListMap_var faceEntryEnfVertexListMap = h->GetAllEnforcedVerticesByFace(); + MESSAGE("faceEntryEnfVertexListMap->length() = " << faceEntryEnfVertexListMap->length()); + + for ( int i = 0;ilength(); ++i ) { + std::string entry = faceEntryEnfVertexListMap[i].faceEntry.in(); +// BLSURFPlugin::TEnfVertexList vertexList = faceEntryEnfVertexListMap[i].enfVertexList.in(); + BLSURFPlugin::TEnfVertexList vertexList = faceEntryEnfVertexListMap[i].enfVertexList; +// BLSURFPlugin::TEnfVertexList_var vertexList = h->GetEnforcedVerticesEntry(entry.c_str()); + +// TEnfVertexList& enfVertexList = h_data.faceEntryEnfVertexListMap[entry]; + + for (int j=0 ; jname = CORBA::string_dup(vertexList[j].name.in()); + enfVertex->geomEntry = CORBA::string_dup(vertexList[j].geomEntry.in()); + enfVertex->grpName = CORBA::string_dup(vertexList[j].grpName.in()); + for (int k=0 ; k< vertexList[j].coords.length();k++) + enfVertex->coords.push_back(vertexList[j].coords[k]); + + h_data.faceEntryEnfVertexListMap[entry].insert(enfVertex); + + /* TODO GROUPS + if (groupName != "") { + h_data.groupNameEnfVertexListMap[groupName].insert(ev); + } + */ + } +// h_data.enfVertMap[entry] = evs; +// h_data.entryCoordsListMap[entry] = coordsList; + + if (h_data.faceEntryEnfVertexListMap[entry].size() == 0) { + h_data.faceEntryEnfVertexListMap.erase(entry); + } + } + h_data.myInternalEnforcedVerticesAllFaces = h->GetInternalEnforcedVertexAllFaces(); + h_data.myInternalEnforcedVerticesAllFacesGroup = h->GetInternalEnforcedVertexAllFacesGroup(); return true; } +/** BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo(h_data) +Saves the hypothesis data to hypothesis values. +*/ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesisData& h_data ) const { + MESSAGE("BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo"); BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( hypothesis() ); @@ -433,10 +1903,18 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi h->SetDecimesh( h_data.myDecimesh ); if ( h->GetVerbosity() != h_data.myVerbosity ) h->SetVerbosity( h_data.myVerbosity ); - - if( (int) h_data.myPhysicalMesh == PhysicalUserDefined ) { - if ( h->GetPhySize() != h_data.myPhySize.toDouble() ) - h->SetPhySize( h_data.myPhySize.toDouble() ); + if ( h->GetPreCADMergeEdges() != h_data.myPreCADMergeEdges ) + h->SetPreCADMergeEdges( h_data.myPreCADMergeEdges ); + if ( h->GetPreCADRemoveNanoEdges() != h_data.myPreCADRemoveNanoEdges ) + h->SetPreCADRemoveNanoEdges( h_data.myPreCADRemoveNanoEdges ); + if ( h->GetPreCADDiscardInput() != h_data.myPreCADDiscardInput ) + h->SetPreCADDiscardInput( h_data.myPreCADDiscardInput ); + if ( h->GetPreCADEpsNano() != h_data.myPreCADEpsNano && h_data.myPreCADEpsNano > 0) + h->SetPreCADEpsNano( h_data.myPreCADEpsNano ); + + if( ((int) h_data.myPhysicalMesh == PhysicalUserDefined)||((int) h_data.myPhysicalMesh == SizeMap) ) { + if ( h->GetPhySize() != h_data.myPhySize ) + h->SetPhySize( h_data.myPhySize ); } if( (int) h_data.myGeometricMesh == UserDefined ) { if ( h->GetAngleMeshS() != h_data.myAngleMeshS ) @@ -445,112 +1923,291 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi h->SetAngleMeshC( h_data.myAngleMeshC ); } #ifdef WITH_SIZE_BOUNDARIES - if ( !isDouble( h_data.myPhyMin )) - h->SetPhyMin( -1 ); - else if ( h->GetPhyMin() != h_data.myPhyMin.toDouble() ) - h->SetPhyMin( h_data.myPhyMin.toDouble() ); - if ( !isDouble( h_data.myPhyMax )) - h->SetPhyMax( -1 ); - else if ( h->GetPhyMax() != h_data.myPhyMax.toDouble() ) - h->SetPhyMax( h_data.myPhyMax.toDouble() ); - if ( !isDouble( h_data.myGeoMin )) - h->SetGeoMin( -1 ); - else if ( h->GetGeoMin() != h_data.myGeoMin.toDouble() ) - h->SetGeoMin( h_data.myGeoMin.toDouble() ); - if ( !isDouble( h_data.myGeoMax )) - h->SetGeoMax( -1 ); - else if ( h->GetGeoMax() != h_data.myGeoMax.toDouble() ) - h->SetGeoMax( h_data.myGeoMax.toDouble() ); + if (h->GetPhyMin() != h_data.myPhyMin && h_data.myPhyMin > 0) + h->SetPhyMin( h_data.myPhyMin ); + if (h->GetPhyMax() != h_data.myPhyMax && h_data.myPhyMax > 0) + h->SetPhyMax( h_data.myPhyMax ); + if (h->GetGeoMin() != h_data.myGeoMin && h_data.myGeoMin > 0) + h->SetGeoMin( h_data.myGeoMin ); + if (h->GetGeoMax() != h_data.myGeoMax && h_data.myGeoMax > 0) + h->SetGeoMax( h_data.myGeoMax ); #endif - printf("storeParamsToHypo():myOptions->length()=%d\n",myOptions->length()); h->SetOptionValues( myOptions ); // is set in checkParams() + h->SetPreCADOptionValues( myPreCADOptions ); // is set in checkParams() + + if ( h->GetGMFFile() != h_data.myGMFFileName ) +// || ( h->GetGMFFileMode() != h_data.myGMFFileMode ) ) +// h->SetGMFFile( h_data.myGMFFileName.c_str(), h_data.myGMFFileMode ); + h->SetGMFFile( h_data.myGMFFileName.c_str()); + + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + QMapIterator i(that->mySMPMap); + while (i.hasNext()) { + i.next(); + const QString entry = i.key(); + const QString sizeMap = i.value(); + + if (sizeMap == "__TO_DELETE__") { + MESSAGE("Delete entry " << entry.toStdString() << " from engine"); + h->UnsetEntry(entry.toLatin1().constData()); + } + else if (sizeMap.startsWith("ATTRACTOR")) { +// MESSAGE("SetAttractorEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString()); + h->SetAttractorEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData()); + } + else if (sizeMap.startsWith("def")) { +// MESSAGE("SetCustomSizeMapEntry(" << entry.toStdString() << ")= " << sizeMap.toStdString()); +// h->SetCustomSizeMapEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() ); + } + else { + if (!myATTMap[entry].isEmpty()){ + QString att_entry = myATTMap[entry]; + double infDist = myAttDistMap[entry]; + double constDist = myDistMap[entry]; + double phySize = h->GetPhySize(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + h->SetClassAttractorEntry( entry.toLatin1().constData(), att_entry.toLatin1().constData(), sizeMap.toDouble() , phySize, infDist, constDist ); + QApplication::restoreOverrideCursor(); + } + else { + QString fullSizeMap; + fullSizeMap = QString(""); + if (that->mySMPShapeTypeMap[entry] == TopAbs_FACE) + fullSizeMap = QString("def f(u,v): return ") + sizeMap; + else if (that->mySMPShapeTypeMap[entry] == TopAbs_EDGE) + fullSizeMap = QString("def f(t): return ") + sizeMap; + else if (that->mySMPShapeTypeMap[entry] == TopAbs_VERTEX) + fullSizeMap = QString("def f(): return ") + sizeMap; + MESSAGE("SetSizeMapEntry("<SetSizeMapEntry( entry.toLatin1().constData(), fullSizeMap.toLatin1().constData() ); + } + } + } + + // Enforced vertices + bool ret; + double x, y, z = 0; + std::string enfName; + /* TODO GROUPS + std::string groupName = ""; + */ + + TFaceEntryEnfVertexListMap::const_iterator evmIt = h_data.faceEntryEnfVertexListMap.begin(); + // 1. Clear all enforced vertices in hypothesis + // 2. Add new enforced vertex according to h_data + + if ( h->GetAllEnforcedVertices()->length() > 0 ) + h->ClearAllEnforcedVertices(); + TEnfName faceEntry; + TEnfVertexList evs; + TEnfVertexList::const_iterator evsIt; + for ( ; evmIt != h_data.faceEntryEnfVertexListMap.end() ; ++evmIt) + { + faceEntry = evmIt->first; + evs = evmIt->second; + MESSAGE("Number of enforced vertices for face entry " << faceEntry << ": " << evs.size()); + evsIt = evs.begin(); + for ( ; evsIt != evs.end() ; ++evsIt) + { + x =y =z = 0; + if ((*evsIt)->coords.size()) { + x = (*evsIt)->coords[0]; + y = (*evsIt)->coords[1]; + z = (*evsIt)->coords[2]; + } + ret = h->SetEnforcedVertexEntry( faceEntry.c_str(), x, y, z, (*evsIt)->name.c_str(), (*evsIt)->geomEntry.c_str(), (*evsIt)->grpName.c_str()); + } // for + } // for + + if ( h->GetInternalEnforcedVertexAllFaces() != h_data.myInternalEnforcedVerticesAllFaces ) + h->SetInternalEnforcedVertexAllFaces( h_data.myInternalEnforcedVerticesAllFaces ); + if ( h->GetInternalEnforcedVertexAllFacesGroup() != h_data.myInternalEnforcedVerticesAllFacesGroup ) + h->SetInternalEnforcedVertexAllFacesGroup( h_data.myInternalEnforcedVerticesAllFacesGroup.c_str() ); + + } // try + catch(const std::exception& ex) { + std::cout << "Exception: " << ex.what() << std::endl; + throw ex; } - catch(const SALOME::SALOME_Exception& ex) - { - SalomeApp_Tools::QtCatchCorbaException(ex); - ok = false; - } +// catch(const SALOME::SALOME_Exception& ex) +// { +// throw ex; +// // SalomeApp_Tools::QtCatchCorbaException(ex); +// // ok = false; +// } return ok; } +/** BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets(h_data) +Stores the widgets content to the hypothesis data. +*/ QString BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets( BlsurfHypothesisData& h_data ) const { - h_data.myName = myName ? myName->text() : ""; - h_data.myTopology = myTopology->currentIndex(); - h_data.myPhysicalMesh = myPhysicalMesh->currentIndex(); - h_data.myPhySize = myPhySize->text(); + MESSAGE("BLSURFPluginGUI_HypothesisCreator::readParamsFromWidgets"); + h_data.myName = myName ? myName->text() : ""; + h_data.myTopology = myTopology->currentIndex(); + h_data.myPhysicalMesh = myPhysicalMesh->currentIndex(); + h_data.myPhySize = myPhySize->GetValue(); #ifdef WITH_SIZE_BOUNDARIES - h_data.myPhyMin = myPhyMin->text(); - h_data.myPhyMax = myPhyMax->text(); - h_data.myGeoMin = myGeoMin->text(); - h_data.myGeoMax = myGeoMax->text(); + h_data.myPhyMin = myPhyMin->GetValue(); + h_data.myPhyMax = myPhyMax->GetValue(); + h_data.myGeoMin = myGeoMin->GetValue(); + h_data.myGeoMax = myGeoMax->GetValue(); #endif - h_data.myGeometricMesh = myGeometricMesh->currentIndex(); - h_data.myAngleMeshS = myAngleMeshS->value(); - h_data.myAngleMeshC = myAngleMeshC->value(); - h_data.myGradation = myGradation->value(); - h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked(); - h_data.myDecimesh = myDecimesh->isChecked(); - h_data.myVerbosity = myVerbosity->value(); + h_data.myGeometricMesh = myGeometricMesh->currentIndex(); + h_data.myAngleMeshS = myAngleMeshS->GetValue(); + h_data.myAngleMeshC = myAngleMeshC->GetValue(); + h_data.myGradation = myGradation->GetValue(); + h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked(); + h_data.myDecimesh = myDecimesh->isChecked(); + h_data.myVerbosity = myVerbosity->value(); + h_data.myPreCADMergeEdges = myPreCADMergeEdges->isChecked(); + h_data.myPreCADRemoveNanoEdges = myPreCADRemoveNanoEdges->isChecked(); + h_data.myPreCADDiscardInput = myPreCADDiscardInput->isChecked(); + h_data.myPreCADEpsNano = myPreCADEpsNano->GetValue(); QString guiHyp; guiHyp += tr("BLSURF_TOPOLOGY") + " = " + QString::number( h_data.myTopology ) + "; "; guiHyp += tr("BLSURF_PHY_MESH") + " = " + QString::number( h_data.myPhysicalMesh ) + "; "; - guiHyp += tr("BLSURF_HPHYDEF") + " = " + h_data.myPhySize + "; "; + guiHyp += tr("BLSURF_HPHYDEF") + " = " + QString::number( h_data.myPhySize ) + "; "; guiHyp += tr("BLSURF_GEOM_MESH") + " = " + QString::number( h_data.myGeometricMesh ) + "; "; guiHyp += tr("BLSURF_ANGLE_MESH_S") + " = " + QString::number( h_data.myAngleMeshS ) + "; "; guiHyp += tr("BLSURF_GRADATION") + " = " + QString::number( h_data.myGradation ) + "; "; guiHyp += tr("BLSURF_ALLOW_QUADRANGLES") + " = " + QString(h_data.myAllowQuadrangles ? "yes" : "no") + "; "; guiHyp += tr("BLSURF_DECIMESH") + " = " + QString(h_data.myDecimesh ? "yes" : "no") + "; "; #ifdef WITH_SIZE_BOUNDARIES - if ( isDouble( h_data.myPhyMin )) guiHyp += "hphymin = " + h_data.myPhyMin + "; "; - if ( isDouble( h_data.myPhyMax )) guiHyp += "hphymax = " + h_data.myPhyMax + "; "; - if ( isDouble( h_data.myGeoMin )) guiHyp += "hgeomin = " + h_data.myGeoMin + "; "; - if ( isDouble( h_data.myGeoMax )) guiHyp += "hgeomax = " + h_data.myGeoMax + "; "; + guiHyp += "hphymin = " + QString::number( h_data.myPhyMin ) + "; "; + guiHyp += "hphymax = " + QString::number( h_data.myPhyMax ) + "; "; + guiHyp += "hgeomin = " + QString::number( h_data.myGeoMin ) + "; "; + guiHyp += "hgeomax = " + QString::number( h_data.myGeoMax ) + "; "; #endif + guiHyp += tr("BLSURF_PRECAD_MERGE_EDGES") + " = " + QString(h_data.myPreCADMergeEdges ? "yes" : "no") + "; "; + guiHyp += tr("BLSURF_PRECAD_REMOVE_NANO_EDGES") + " = " + QString(h_data.myPreCADRemoveNanoEdges ? "yes" : "no") + "; "; + guiHyp += tr("BLSURF_PRECAD_DISCARD_INPUT") + " = " + QString(h_data.myPreCADDiscardInput ? "yes" : "no") + "; "; + guiHyp += tr("BLSURF_PRECAD_EPS_NANO") + " = " + QString::number( h_data.myPreCADEpsNano ) + "; "; BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; int row = 0, nbRows = myOptionTable->rowCount(); for ( ; row < nbRows; ++row ) { int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt(); - if ( id >= 0 && id < myOptions->length() ) + std::string optionType = myOptionTable->item( row, OPTION_TYPE_COLUMN )->text().toStdString(); + if ( id >= 0 && ( ( optionType == "BLSURF" && id < myOptions->length() ) || ( optionType == "PRECAD" && id < myPreCADOptions->length() ) ) ) { QString name = myOptionTable->item( row, OPTION_NAME_COLUMN )->text(); QString value = myOptionTable->item( row, OPTION_VALUE_COLUMN )->text().trimmed(); if ( value.isNull() ) value = ""; - that->myOptions[ id ] = ( name + ":" + value).toLatin1().constData(); - if ( value != "" ) + if (optionType == "PRECAD") + that->myPreCADOptions[ id ] = ( name + ":" + value).toLatin1().constData(); + else + that->myOptions[ id ] = ( name + ":" + value).toLatin1().constData(); + + if ( value != "" ) { + if (optionType == "PRECAD") + guiHyp += "PRECAD_"; guiHyp += name + " = " + value + "; "; + } } } + + h_data.myGMFFileName = myGMFFileName->text().toStdString(); +// h_data.myGMFFileMode = myGMFFileMode->isChecked(); - cout << "guiHyp : " << guiHyp.toLatin1().data() << endl; + // SizeMap + row = 0, nbRows = mySizeMapTable->topLevelItemCount(); + for ( ; row < nbRows; ++row ) + { + QString entry = mySizeMapTable->topLevelItem(row)->data(SMP_ENTRY_COLUMN ,Qt::EditRole).toString(); + if ( that->mySMPMap.contains(entry) ) + guiHyp += "SetSizeMapEntry(" + entry + ", " + that->mySMPMap[entry] + "); "; + } + // Enforced vertices + h_data.enfVertexList.clear(); + h_data.faceEntryEnfVertexListMap.clear(); + + int nbEnforcedShapes = myEnforcedTreeWidget->topLevelItemCount(); + int nbEnforcedVertices = 0; + std::string groupName = ""; +// MESSAGE("Nb of enforced shapes: " << nbEnforcedShapes); + for (int i=0 ; itopLevelItem(i); + if (shapeItem) { + std::string faceEntry = shapeItem->data(ENF_VER_FACE_ENTRY_COLUMN,Qt::EditRole).toString().toStdString(); + nbEnforcedVertices = shapeItem->childCount(); + if (nbEnforcedVertices >0) { + double childValueX,childValueY,childValueZ; + std::string childName, vertexEntry; + QTreeWidgetItem* child; + TEnfVertexList evs; + evs.clear(); + for (row = 0;rowchild(row); + childName = child->data(ENF_VER_NAME_COLUMN,Qt::EditRole).toString().toStdString(); + childValueX = child->data(ENF_VER_X_COLUMN,Qt::EditRole).toDouble(); + childValueY = child->data(ENF_VER_Y_COLUMN,Qt::EditRole).toDouble(); + childValueZ = child->data(ENF_VER_Z_COLUMN,Qt::EditRole).toDouble(); + vertexEntry = child->data(ENF_VER_ENTRY_COLUMN,Qt::EditRole).toString().toStdString(); +// if (myGlobalGroupName->isChecked()) +// groupName = myGlobalGroupName->text().toStdString(); +// else + groupName = child->data(ENF_VER_GROUP_COLUMN,Qt::EditRole).toString().toStdString(); + + TEnfVertex *enfVertex = new TEnfVertex(); + enfVertex->name = childName; + if (vertexEntry.empty()) { + enfVertex->coords.push_back(childValueX); + enfVertex->coords.push_back(childValueY); + enfVertex->coords.push_back(childValueZ); + } + else + enfVertex->geomEntry = vertexEntry; + enfVertex->grpName = groupName; +// TEnfVertexList::iterator it = h_data.enfVertexList.find(enfVertex); +// if (it == h_data.enfVertexList.end()) + h_data.enfVertexList.insert(enfVertex); + evs.insert(enfVertex); + /* TODO GROUPS + if (groupName != "") + h_data.groupNameEnfVertexListMap[groupName].insert(vertex); + */ + } + h_data.faceEntryEnfVertexListMap[faceEntry] = evs; + } + } + } + + h_data.myInternalEnforcedVerticesAllFaces = myInternalEnforcedVerticesAllFaces->isChecked(); + h_data.myInternalEnforcedVerticesAllFacesGroup = myInternalEnforcedVerticesAllFacesGroup->text().toStdString(); + + MESSAGE("guiHyp : " << guiHyp.toLatin1().data()); return guiHyp; } + +void BLSURFPluginGUI_HypothesisCreator::onTopologyChanged(int index) { + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onTopologyChanged"); + myPreCADGroupBox->setEnabled(index == PreCAD); +} + void BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged() { - bool isCustom = (myPhysicalMesh->currentIndex() == PhysicalUserDefined); + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged"); + bool isPhysicalUserDefined = (myPhysicalMesh->currentIndex() == PhysicalUserDefined); + bool isSizeMap = (myPhysicalMesh->currentIndex() == SizeMap); + bool isCustom = (isPhysicalUserDefined || isSizeMap) ; + bool geomIsCustom = (myGeometricMesh->currentIndex() == UserDefined); + + myGradation->setEnabled(!isPhysicalUserDefined || geomIsCustom); myPhySize->setEnabled(isCustom); myPhyMax->setEnabled(isCustom); myPhyMin->setEnabled(isCustom); + if ( !myGradation->isEnabled()) + myGradation->SetValue( 1.1 ); + if ( !isCustom ) { - QString aPhySize = ""; - switch( myPhysicalMesh->currentIndex() ) { - case DefaultSize: - default: - aPhySize = "10"; - break; - } - myPhySize->setText( aPhySize ); - if ( !isDouble( myPhyMin->text(), true )) - myPhyMin->setText(""); - if ( !isDouble( myPhyMax->text(), true )) - myPhyMax->setText(""); if ( myGeometricMesh->currentIndex() == DefaultGeom ) { myGeometricMesh->setCurrentIndex( UserDefined ); onGeometricMeshChanged(); @@ -559,29 +2216,20 @@ void BLSURFPluginGUI_HypothesisCreator::onPhysicalMeshChanged() { } void BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged() { + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onGeometricMeshChanged"); bool isCustom = (myGeometricMesh->currentIndex() == UserDefined); + bool phyIsSizemap = (myPhysicalMesh->currentIndex() == SizeMap); + myAngleMeshS->setEnabled(isCustom); myAngleMeshC->setEnabled(isCustom); - myGradation->setEnabled(isCustom); + myGradation->setEnabled(isCustom || phyIsSizemap); myGeoMax->setEnabled(isCustom); myGeoMin->setEnabled(isCustom); + if ( !myGradation->isEnabled()) + myGradation->SetValue( 1.1 ); + if ( ! isCustom ) { - double aAngleMeshS, aGradation; - switch( myGeometricMesh->currentIndex() ) { - case DefaultGeom: - default: - aAngleMeshS = 8; - aGradation = 1.1; - break; - } - myAngleMeshS->setValue( aAngleMeshS ); - myAngleMeshC->setValue( aAngleMeshS ); - myGradation->setValue( aGradation ); - if ( !isDouble( myGeoMin->text(), true )) - myGeoMin->setText(""); - if ( !isDouble( myGeoMax->text(), true )) - myGeoMax->setText(""); // hphy_flag = 0 and hgeo_flag = 0 is not allowed (spec) if ( myPhysicalMesh->currentIndex() == DefaultSize ) { myPhysicalMesh->setCurrentIndex( PhysicalUserDefined ); @@ -595,11 +2243,21 @@ void BLSURFPluginGUI_HypothesisCreator::onAddOption() QMenu* menu = (QMenu*)sender(); // fill popup with option names menu->clear(); + QString name_value, name; if ( myOptions.operator->() ) { + QMenu* blsurfMenu = menu->addMenu(tr("OPTION_MENU_BLSURF")); for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) { - QString name_value = myOptions[i].in(); - QString name = name_value.split( ":", QString::KeepEmptyParts )[0]; - menu->addAction( name ); + name_value = myOptions[i].in(); + name = name_value.split( ":", QString::KeepEmptyParts )[0]; + blsurfMenu->addAction( name ); + } + } + if ( myPreCADOptions.operator->() ) { + QMenu* preCADmenu = menu->addMenu(tr("OPTION_MENU_PRECAD")); + for ( int i = 0, nb = myPreCADOptions->length(); i < nb; ++i ) { + name_value = myPreCADOptions[i].in(); + name = name_value.split( ":", QString::KeepEmptyParts )[0]; + preCADmenu->addAction( name ); } } } @@ -608,28 +2266,39 @@ void BLSURFPluginGUI_HypothesisCreator::onOptionChosenInPopup( QAction* a ) { myOptionTable->setFocus(); QMenu* menu = (QMenu*)( a->parent() ); - + int idx = menu->actions().indexOf( a ); QString idStr = QString("%1").arg( idx ); - QString option = myOptions[idx].in(); + QString option, optionType; + if (menu->title() == tr("OPTION_MENU_BLSURF")) { + option = myOptions[idx].in(); + optionType = "BLSURF"; + } + else if (menu->title() == tr("OPTION_MENU_PRECAD")) { + option = myPreCADOptions[idx].in(); + optionType = "PRECAD"; + } QString optionName = option.split( ":", QString::KeepEmptyParts )[0]; // look for a row with optionName int row = 0, nbRows = myOptionTable->rowCount(); for ( ; row < nbRows; ++row ) if ( myOptionTable->item( row, OPTION_ID_COLUMN )->text() == idStr ) - break; + if ( myOptionTable->item( row, OPTION_TYPE_COLUMN )->text() == optionType ) + break; // add a row if not found if ( row == nbRows ) { myOptionTable->setRowCount( row+1 ); myOptionTable->setItem( row, OPTION_ID_COLUMN, new QTableWidgetItem( idStr ) ); myOptionTable->item( row, OPTION_ID_COLUMN )->setFlags( 0 ); + myOptionTable->setItem( row, OPTION_TYPE_COLUMN, new QTableWidgetItem( optionType ) ); + myOptionTable->item( row, OPTION_TYPE_COLUMN )->setFlags( 0 ); myOptionTable->setItem( row, OPTION_NAME_COLUMN, new QTableWidgetItem( optionName ) ); myOptionTable->item( row, OPTION_NAME_COLUMN )->setFlags( 0 ); myOptionTable->setItem( row, OPTION_VALUE_COLUMN, new QTableWidgetItem( "" ) ); - myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable | - Qt::ItemIsEditable | - Qt::ItemIsEnabled ); + myOptionTable->item( row, OPTION_VALUE_COLUMN )->setFlags( Qt::ItemIsSelectable | + Qt::ItemIsEditable | + Qt::ItemIsEnabled ); myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN ); } myOptionTable->clearSelection(); @@ -638,20 +2307,24 @@ void BLSURFPluginGUI_HypothesisCreator::onOptionChosenInPopup( QAction* a ) myOptionTable->setCurrentCell( row, OPTION_VALUE_COLUMN ); //myOptionTable->openPersistentEditor( myOptionTable->item( row, OPTION_VALUE_COLUMN ) ); } - + void BLSURFPluginGUI_HypothesisCreator::onDeleteOption() { // clear option values and remember selected row QList selectedRows; - QList selected = myOptionTable->selectedItems(); + QList selected = myOptionTable->selectedItems(); QTableWidgetItem* item; foreach( item, selected ) { int row = item->row(); if ( !selectedRows.contains( row ) ) { selectedRows.append( row ); int id = myOptionTable->item( row, OPTION_ID_COLUMN )->text().toInt(); - if ( id >= 0 && id < myOptions->length() ) - myOptions[ id ] = myOptionTable->item( row, OPTION_NAME_COLUMN )->text().toLatin1().constData(); + std::string optionType = myOptionTable->item( row, OPTION_TYPE_COLUMN )->text().toStdString(); + if ( id >= 0 ) + if (optionType == "BLSURF" && id < myOptions->length() ) + myOptions[ id ] = myOptionTable->item( row, OPTION_NAME_COLUMN )->text().toLatin1().constData(); + else if (optionType == "PRECAD" && id < myPreCADOptions->length() ) + myPreCADOptions[ id ] = myOptionTable->item( row, OPTION_NAME_COLUMN )->text().toLatin1().constData(); } } qSort( selectedRows ); @@ -661,7 +2334,559 @@ void BLSURFPluginGUI_HypothesisCreator::onDeleteOption() myOptionTable->removeRow( it.previous() ); } - +void BLSURFPluginGUI_HypothesisCreator::onChooseGMFFile() +{ +// QFileDialog dlg(0); +// dlg.selectFile(myGMFFileName->text()); +// dlg.setNameFilter(tr("BLSURF_GMF_FILE_FORMAT")); +// dlg.setDefaultSuffix(QString("mesh")); + myGMFFileName->setText(QFileDialog::getSaveFileName(0, tr("BLSURF_GMF_FILE_DIALOG"), myGMFFileName->text(), tr("BLSURF_GMF_FILE_FORMAT"))); +} + + +// ********************** +// *** BEGIN SIZE MAP *** +// ********************** + +void BLSURFPluginGUI_HypothesisCreator::onMapGeomContentModified() +{ + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + + if ( myGeomSelWdg2->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg2->GetObject< GEOM::GEOM_Object >(0); + } + else if ( myGeomSelWdg1->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg1->GetObject< GEOM::GEOM_Object >(0); + } + std::string entry = (string) mySMapObject->GetStudyEntry(); + QString qEntry = QString::fromStdString(entry); + if (that->mySMPMap.contains(qEntry) && that->mySMPMap[qEntry] != "__TO_DELETE__" ) { + addMapButton->setEnabled(false); + modifyMapButton->setEnabled(true); + } + else{ + addMapButton->setEnabled(true); + modifyMapButton->setEnabled(false); + } + +} + +void BLSURFPluginGUI_HypothesisCreator::onSmpItemClicked(QTreeWidgetItem * item, int col) +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onSmpItemClicked("<data( SMP_ENTRY_COLUMN, Qt::EditRole ).toString(); + if (!mySMPMap.contains(entry)) + return; + QString sizeMap = item->data( SMP_SIZEMAP_COLUMN, Qt::EditRole ).toString(); + CORBA::Object_var obj = entryToObject(entry); + if (sizeMap.startsWith("Attractor") || sizeMap.startsWith("Constant")){ // ADVANCED MAPS + smpTab->setCurrentIndex(ATT_TAB); // Change Tab + double phySize = that->mySMPMap[entry].toDouble(); // Retrieve values of the selected item in the current tab widgets + double infDist = that->myAttDistMap[entry]; + double constDist = that->myDistMap[entry]; + QString attEntry = that->myATTMap[entry]; + CORBA::Object_var attObj = entryToObject(attEntry); + myAttSizeSpin->setValue(phySize); + if (sizeMap.startsWith("Attractor")){ + myAttDistSpin->setValue(infDist); + myAttractorCheck->setChecked(true); + } + else { + myAttractorCheck->setChecked(false); + } + if (sizeMap.startsWith("Constant") || constDist > std::numeric_limits::epsilon()){ + myAttDistSpin2->setValue(constDist); + myConstSizeCheck->setChecked(true); + } + else{ + myConstSizeCheck->setChecked(false); + } + myGeomSelWdg2->SetObject(obj); + myAttSelWdg->SetObject(attObj); + } + else { // CLASSIC MAPS + smpTab->setCurrentIndex(SMP_STD_TAB); // Change Tab + myGeomSelWdg1->SetObject(obj); // Retrieve values of the selected item in the current tab widgets + if (!sizeMap.startsWith("def")){ + mySmpSizeSpin->setValue(that->mySMPMap[entry].toDouble()); + } + } + } +} + +void BLSURFPluginGUI_HypothesisCreator::onSmpTabChanged(int tab) +{ + myAttDistSpin->setValue(0.); // Reinitialize widgets + myAttSizeSpin->setValue(0.); + myAttDistSpin2->setValue(0.); + mySmpSizeSpin->setValue(0.); + myGeomSelWdg1->deactivateSelection(); + myGeomSelWdg2->deactivateSelection(); + myAttSelWdg->deactivateSelection(); + myGeomSelWdg1->SetObject(CORBA::Object::_nil()); + myGeomSelWdg2->SetObject(CORBA::Object::_nil()); + myAttSelWdg->SetObject(CORBA::Object::_nil()); + myAttractorCheck->setChecked(false); + myConstSizeCheck->setChecked(false); +} + +void BLSURFPluginGUI_HypothesisCreator::onAttractorClicked(int state) +{ + if (state == Qt::Checked){ + myAttSelWdg->setEnabled(true); + myAttSizeSpin->setEnabled(true); + myAttSizeLabel->setEnabled(true); + myAttDistSpin->setEnabled(true); + myAttDistLabel->setEnabled(true); + if (!myAttSelWdg->IsObjectSelected()){ + myAttSelWdg->SetDefaultText(tr("BLS_SEL_ATTRACTOR"), "QLineEdit { color: grey }"); + } + } + if (state == Qt::Unchecked){ + myAttDistSpin->setEnabled(false); + myAttDistLabel->setEnabled(false); + myAttDistSpin->setValue(0.); + if(myConstSizeCheck->checkState() == Qt::Unchecked){ // No predefined map selected + myAttSelWdg->setEnabled(false); + myAttSizeSpin->setEnabled(false); + myAttSizeLabel->setEnabled(false); + myAttDistSpin2->setEnabled(false); + myAttDistLabel2->setEnabled(false); + } + else if (!myAttSelWdg->IsObjectSelected()){ // Only constant size selected + myAttSelWdg->SetDefaultText(tr("BLS_SEL_SHAPE"), "QLineEdit { color: grey }"); + } + } +} + +void BLSURFPluginGUI_HypothesisCreator::onConstSizeClicked(int state) +{ + if (state == Qt::Checked){ + myAttSelWdg->setEnabled(true); + myAttSizeSpin->setEnabled(true); + myAttSizeLabel->setEnabled(true); + myAttDistSpin2->setEnabled(true); + myAttDistLabel2->setEnabled(true); + if (myAttractorCheck->checkState() == Qt::Unchecked && + !myAttSelWdg->IsObjectSelected()){ + myAttSelWdg->SetDefaultText(tr("BLS_SEL_SHAPE"), "QLineEdit { color: grey }"); + } + } + if (state == Qt::Unchecked){ + myAttDistSpin2->setEnabled(false); + myAttDistLabel2->setEnabled(false); + myAttDistSpin2->setValue(0.); + if(myAttractorCheck->checkState() == Qt::Unchecked){ // No predefined map selected + myAttSelWdg->setEnabled(false); + myAttSizeSpin->setEnabled(false); + myAttSizeLabel->setEnabled(false); + myAttDistSpin->setEnabled(false); + myAttDistLabel->setEnabled(false); + } + else if (!myAttSelWdg->IsObjectSelected()){ // Only constant size selected + myAttSelWdg->SetDefaultText(tr("BLS_SEL_ATTRACTOR"), "QLineEdit { color: grey }"); + } + } +} + +void BLSURFPluginGUI_HypothesisCreator::onRemoveMap() +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onRemoveMap()"); + QList selectedRows; + QList selected = mySizeMapTable->selectedItems(); + QTreeWidgetItem* item; + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + + qSort( selectedRows ); + QListIterator it( selected ); + it.toBack(); + while ( it.hasPrevious() ) { + item = it.previous(); + QString entry = item->data(SMP_ENTRY_COLUMN, Qt::EditRole).toString(); + if (that->mySMPMap.contains(entry)) + that->mySMPMap[entry] = "__TO_DELETE__"; + if (that->mySMPShapeTypeMap.contains(entry)) + that->mySMPShapeTypeMap.remove(entry); + if (that->myATTMap.contains(entry)) + that->myATTMap.remove(entry); + if (that->myDistMap.contains(entry)) + that->myDistMap.remove(entry); + if (that->myAttDistMap.contains(entry)) + that->myAttDistMap.remove(entry); + delete item; + } + mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN); + mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); +} + +void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(QTreeWidgetItem* item, int col) +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onSetSizeMap("<< col << ")"); + MESSAGE("mySMPMap.size() = "<data(SMP_ENTRY_COLUMN, Qt::EditRole).toString(); + QString sizeMap = item->data(SMP_SIZEMAP_COLUMN, Qt::EditRole).toString(); + MESSAGE("entry: " << entry.toStdString() << ", sizeMap: " << sizeMap.toStdString()); + if (! that->mySMPShapeTypeMap.contains(entry)) + MESSAGE("no such entry in mySMPShapeTypeMap") + return; + if (that->mySMPMap.contains(entry)) + if (that->mySMPMap[entry] == sizeMap + || sizeMap.startsWith("Attractor") + || sizeMap.startsWith("Constant") ){ + return; + } + if (! sizeMap.isEmpty()) { + that->mySMPMap[entry] = sizeMap; + sizeMapValidationFromEntry(entry); + } + else { + MESSAGE("Size map empty: reverse to precedent value" ); + item->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant(that->mySMPMap[entry]) ); + } + mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); + } +} + +void BLSURFPluginGUI_HypothesisCreator::onAddMap() +{ + if ( smpTab->currentIndex() == ATT_TAB ){ + if ( myGeomSelWdg2->IsObjectSelected() && myAttSelWdg->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg2->GetObject< GEOM::GEOM_Object >(0); + myAttObject = myAttSelWdg->GetObject< GEOM::GEOM_Object >(0); + insertAttractor(mySMapObject, myAttObject); + } + } + if (smpTab->currentIndex() == SMP_STD_TAB ){ + if ( myGeomSelWdg1->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg1->GetObject< GEOM::GEOM_Object >(0); + insertElement(mySMapObject); + } + } + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + that->getGeomSelectionTool()->selectionMgr()->clearFilters(); + myAttDistSpin->setValue(0.); + myAttSizeSpin->setValue(0.); + myAttDistSpin2->setValue(0.); + mySmpSizeSpin->setValue(0.); + myConstSizeCheck->setChecked(false); + myAttractorCheck->setChecked(false); + myGeomSelWdg1->deactivateSelection(); + myGeomSelWdg2->deactivateSelection(); + myAttSelWdg->deactivateSelection(); + myGeomSelWdg1->SetObject(CORBA::Object::_nil()); + myGeomSelWdg2->SetObject(CORBA::Object::_nil()); + myAttSelWdg->SetObject(CORBA::Object::_nil()); +} + +void BLSURFPluginGUI_HypothesisCreator::onModifyMap() +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onModifyMap()"); + if ( smpTab->currentIndex() == ATT_TAB ){ + if ( myGeomSelWdg2->IsObjectSelected() && myAttSelWdg->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg2->GetObject< GEOM::GEOM_Object >(0); + myAttObject = myAttSelWdg->GetObject< GEOM::GEOM_Object >(0); + insertAttractor(mySMapObject, myAttObject, /*modify = */true); + } + } + if (smpTab->currentIndex() == SMP_STD_TAB ){ + if ( myGeomSelWdg1->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg1->GetObject< GEOM::GEOM_Object >(0); + insertElement(mySMapObject, /*modify = */true); + } + } + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + that->getGeomSelectionTool()->selectionMgr()->clearFilters(); + myAttDistSpin->setValue(0.); + myAttSizeSpin->setValue(0.); + myAttDistSpin2->setValue(0.); + mySmpSizeSpin->setValue(0.); + myConstSizeCheck->setChecked(false); + myAttractorCheck->setChecked(false); + myGeomSelWdg1->deactivateSelection(); + myGeomSelWdg2->deactivateSelection(); + myAttSelWdg->deactivateSelection(); + myGeomSelWdg1->SetObject(CORBA::Object::_nil()); + myGeomSelWdg2->SetObject(CORBA::Object::_nil()); + myAttSelWdg->SetObject(CORBA::Object::_nil()); +} + +void BLSURFPluginGUI_HypothesisCreator::insertElement(GEOM::GEOM_Object_var anObject, bool modify) +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElement()"); + BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = + BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis()); + + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + + TopAbs_ShapeEnum shapeType; + string entry, shapeName; + entry = (string) anObject->GetStudyEntry(); + MESSAGE("entry = "<GetName(); + shapeType = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( anObject ).ShapeType(); + // Group management : the type of entities in the group is stored in the SMPShapeTypeMap + // in order to write the size map with the right syntax in StoreParamsToHypo + // (f(t) for edges, f(u,v) for faces ...) + if (shapeType == TopAbs_COMPOUND){ + TopoDS_Shape theShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( anObject ); + TopoDS_Shape childShape; + TopoDS_Iterator anIt(theShape); + for(;anIt.More();anIt.Next()){ + childShape = anIt.Value(); + shapeType = childShape.ShapeType(); + if(!childShape.IsNull()){ + break; + } + } + } + mySizeMapTable->setFocus(); + QString shapeEntry; + shapeEntry = QString::fromStdString(entry); + double phySize = mySmpSizeSpin->value(); + std::ostringstream oss; + oss << phySize; + QString sizeMap; + sizeMap = QString::fromStdString(oss.str()); + QTreeWidgetItem* item = new QTreeWidgetItem(); + if (modify){ + int rowToChange = findRowFromEntry(shapeEntry); + item = mySizeMapTable->topLevelItem( rowToChange ); + } + else{ + if (that->mySMPMap.contains(shapeEntry)) { + if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") { + // MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")"); + return; + } + } + mySizeMapTable->addTopLevelItem(item); + } + that->mySMPMap[shapeEntry] = sizeMap; + that->myDistMap[shapeEntry] = 0. ; + that->mySMPShapeTypeMap[shapeEntry] = shapeType; + item->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable |Qt::ItemIsEnabled ); + item->setData(SMP_ENTRY_COLUMN, Qt::EditRole, QVariant(shapeEntry) ); + item->setData(SMP_NAME_COLUMN, Qt::EditRole, QVariant(QString::fromStdString(shapeName)) ); + item->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant(sizeMap) ); + mySizeMapTable->resizeColumnToContents( SMP_SIZEMAP_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_ENTRY_COLUMN ); + mySizeMapTable->clearSelection(); + + if ( myPhysicalMesh->currentIndex() != SizeMap ) { + myPhysicalMesh->setCurrentIndex( SizeMap ); + onPhysicalMeshChanged(); + } +} + +void BLSURFPluginGUI_HypothesisCreator::insertAttractor(GEOM::GEOM_Object_var aFace, GEOM::GEOM_Object_var anAttractor, bool modify) +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertAttractor()"); + BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = + BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis()); + + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + + TopAbs_ShapeEnum shapeType; + string entry, attEntry, faceName, attName; + entry = (string) aFace->GetStudyEntry(); + attEntry = (string) anAttractor->GetStudyEntry(); + faceName = aFace->GetName(); + attName = anAttractor->GetName(); + shapeType = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( aFace ).ShapeType(); + mySizeMapTable->setFocus(); + QString shapeEntry = QString::fromStdString(entry); + QString qAttEntry = QString::fromStdString(attEntry); + + double phySize = h->GetPhySize(); + double infDist = 0. ; + double constDist = 0. ; + phySize = myAttSizeSpin->value(); + if (myAttractorCheck->isChecked()){ + infDist = myAttDistSpin->value(); + } + if (myConstSizeCheck->isChecked()){ + constDist = myAttDistSpin2->value(); + } + std::ostringstream oss; + std::ostringstream oss2; + std::ostringstream oss3; + oss << phySize; + oss2 << infDist; + oss3 << constDist; + QString sizeMap = QString::fromStdString(oss.str()); + QString infDistString = QString::fromStdString(oss2.str()); + QString constDistString = QString::fromStdString(oss3.str()); + + QTreeWidgetItem* item; + QTreeWidgetItem* child; + if (modify){ + int rowToChange = findRowFromEntry(shapeEntry); + item = mySizeMapTable->topLevelItem( rowToChange ); + child = item->child( 0 ); + } + else{ + if (that->mySMPMap.contains(shapeEntry)) { + if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") { + // MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")"); + return; + } + } + item = new QTreeWidgetItem(); + child = new QTreeWidgetItem(); + mySizeMapTable->addTopLevelItem(item); + item->addChild(child); + } + that->mySMPMap.insert(shapeEntry,sizeMap); + that->myATTMap.insert(shapeEntry,qAttEntry); + that->myAttDistMap.insert(shapeEntry,infDist); + that->myDistMap.insert(shapeEntry,constDist); + that->mySMPShapeTypeMap.insert(shapeEntry,shapeType); + item->setExpanded(true); + item->setData(SMP_ENTRY_COLUMN, Qt::EditRole, QVariant(shapeEntry) ); + item->setData(SMP_NAME_COLUMN, Qt::EditRole, QVariant(QString::fromStdString(faceName)) ); + if (infDist > std::numeric_limits::epsilon()){ + item->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant(QString::fromStdString("Attractor")) ); + } + else if (constDist > std::numeric_limits::epsilon()){ + item->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant(QString::fromStdString("Constant Size")) ); + } + item->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable |Qt::ItemIsEnabled ); + + child->setData(SMP_ENTRY_COLUMN, Qt::EditRole, QVariant(qAttEntry) ); + child->setData(SMP_NAME_COLUMN, Qt::EditRole, QVariant(QString::fromStdString(attName)) ); + child->setData(SMP_SIZEMAP_COLUMN, Qt::EditRole, QVariant(sizeMap) ); + + mySizeMapTable->resizeColumnToContents( SMP_ENTRY_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_SIZEMAP_COLUMN ); + + if ( myPhysicalMesh->currentIndex() != SizeMap ) { + myPhysicalMesh->setCurrentIndex( SizeMap ); + onPhysicalMeshChanged(); + } + MESSAGE("mySMPMap.size() = "<topLevelItemCount(); + for ( ; row < nbRows; ++row ) + if (! sizeMapValidationFromRow(row)) + return false; + return true; +} + +bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(int myRow, bool displayError) +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(), row = "<topLevelItem( myRow )->data( SMP_ENTRY_COLUMN, Qt::EditRole ).toString(); + bool res = sizeMapValidationFromEntry(myEntry,displayError); + mySizeMapTable->setFocus(); + return res; +} + +bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry(QString myEntry, bool displayError) +{ + MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromEntry()"); + MESSAGE("myEntry = "<mySMPMap.contains(myEntry)) { +// MESSAGE("Geometry with entry "<mySMPShapeTypeMap.contains(myEntry)) { +// MESSAGE("Shape type with entry "<mySMPMap[myEntry].startsWith("def")) { +// MESSAGE("custom function" ); + expr = that->mySMPMap[myEntry].toStdString(); + } + else if (that->mySMPMap[myEntry].startsWith("ATTRACTOR")) { +// MESSAGE("Attractor" ); + if ((that->mySMPMap[myEntry].count(QRegExp("^ATTRACTOR\\((?:(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+);){5}(True|False)(?:;(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+))?\\)$")) != 1)) { + + if (displayError) + SUIT_MessageBox::warning( dlg(),"Definition of attractor : Error" ,"An attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b;True|False[;d])" ); + return false; + } + return true; + } + else { + // case size map is empty + if (that->mySMPMap[myEntry].isEmpty()) { + if (displayError) + SUIT_MessageBox::warning( dlg(),"Definition of size map : Error" , "Size map can't be empty"); + return false; + } + else { + if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_FACE) + expr = "def f(u,v) : return " + that->mySMPMap[myEntry].toStdString(); + else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_EDGE) + expr = "def f(t) : return " + that->mySMPMap[myEntry].toStdString(); + else if ( that->mySMPShapeTypeMap[myEntry] == TopAbs_VERTEX) + expr = "def f() : return " + that->mySMPMap[myEntry].toStdString(); + } + } + //assert(Py_IsInitialized()); + if (! Py_IsInitialized()) + throw ("Erreur: Python interpreter is not initialized"); + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + + PyObject * obj = NULL; + PyObject* new_stderr = NULL; + string err_description=""; + obj= PyRun_String(expr.c_str(), Py_file_input, main_dict, NULL); + if (obj == NULL){ + fflush(stderr); + err_description=""; + new_stderr=newPyStdOut(err_description); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + if (displayError) + SUIT_MessageBox::warning( dlg(),"Definition of Python Function : Error" ,err_description.c_str() ); + PyGILState_Release(gstate); + return false; + } + Py_DECREF(obj); + + PyObject * func = NULL; + func = PyObject_GetAttrString(main_mod, "f"); + if ( func == NULL){ + fflush(stderr); + err_description=""; + new_stderr=newPyStdOut(err_description); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + if (displayError) + SUIT_MessageBox::warning( dlg(),"Python Error" ,err_description.c_str() ); + PyGILState_Release(gstate); + return false; + } + + PyGILState_Release(gstate); + +// MESSAGE("SizeMap expression "<( SUIT_Session::session()->activeApplication() ); + if( anApp ) + return dynamic_cast( anApp->selectionMgr() ); + else + return 0; +} + +CORBA::Object_var BLSURFPluginGUI_HypothesisCreator::entryToObject(QString entry) +{ + SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_ptr myStudy = smeshGen_i->GetCurrentStudy(); + CORBA::Object_var obj; + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.toStdString().c_str() ); + if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) { + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var aVal = anIOR->Value(); + obj = myStudy->ConvertIORToObject(aVal); + } + return obj; +} + +int BLSURFPluginGUI_HypothesisCreator::findRowFromEntry(QString entry){ + QString entryForChecking; + int endRow = mySizeMapTable->topLevelItemCount()-1; + int row = 0; + entryForChecking = mySizeMapTable->topLevelItem( row )->data( SMP_ENTRY_COLUMN, Qt::EditRole ).toString(); + while (entry != entryForChecking && row <= endRow){ + row++; + entryForChecking = mySizeMapTable->topLevelItem( row )->data( SMP_ENTRY_COLUMN, Qt::EditRole ).toString(); + } + MESSAGE("BLSURFPluginGUI_HypothesisCreator::findRowFromEntry; row = "< +#include +#include +#include +#include +#include +#include +#include #include CORBA_SERVER_HEADER(BLSURFPlugin_Algorithm) class QGroupBox; -class QtxDoubleSpinBox; class QComboBox; class QCheckBox; class QLineEdit; class QTableWidget; +class QTreeWidget; +class QModelIndex; class QSpinBox; +class QDoubleSpinBox; class QMenu; class QAction; +class QTreeWidgetItem; +class QTableWidgetItem; +class QObject; + +class SMESHGUI_SpinBox; +class LightApp_SelectionMgr; +// class DlgBlSurfHyp_Enforced; + +// Name +typedef std::string TEnfName; +// Entry +typedef std::string TEntry; +// List of entries +typedef std::set TEntryList; +// Enforced vertex = 3 coordinates +typedef std::vector TEnfVertexCoords; +// List of enforced vertices +typedef std::set< TEnfVertexCoords > TEnfVertexCoordsList; +// Enforced vertex +struct TEnfVertex{ + TEnfName name; + TEntry geomEntry; + TEnfVertexCoords coords; + TEnfName grpName; +}; + + +struct CompareEnfVertices +{ + bool operator () (const TEnfVertex* e1, const TEnfVertex* e2) const { + if (e1 && e2) { + if (e1->coords.size() && e2->coords.size()) + return (e1->coords < e2->coords); + else + return (e1->geomEntry < e2->geomEntry); + } + return false; + } +}; + +// List of enforced vertices +typedef std::set< TEnfVertex*, CompareEnfVertices > TEnfVertexList; + +// Map Face Entry / List of enforced vertices +typedef std::map< TEntry, TEnfVertexList > TFaceEntryEnfVertexListMap; + +// Map Face Entry / InternalEnforcedVertices +typedef std::map< TEntry, bool > TFaceEntryInternalVerticesMap; typedef struct { int myTopology, myVerbosity; int myPhysicalMesh, myGeometricMesh; double myAngleMeshS, myAngleMeshC, myGradation; - QString myPhySize, myGeoMin, myGeoMax, myPhyMin, myPhyMax; - bool myAllowQuadrangles, myDecimesh; + double myPhySize, myGeoMin, myGeoMax, myPhyMin,myPhyMax; + bool myAllowQuadrangles, myDecimesh,mySmpsurface,mySmpedge,mySmppoint,myEnforcedVertex,myInternalEnforcedVerticesAllFaces; + bool myPreCADMergeEdges, myPreCADRemoveNanoEdges, myPreCADDiscardInput; + double myPreCADEpsNano; +// bool myGMFFileMode; + std::string myGMFFileName, myInternalEnforcedVerticesAllFacesGroup; + TEnfVertexList enfVertexList; + TFaceEntryEnfVertexListMap faceEntryEnfVertexListMap; + /* TODO GROUPS + TGroupNameEnfVertexListMap groupNameEnfVertexListMap; + */ QString myName; - } BlsurfHypothesisData; + + +// class BLSURFPluginGUI_ObjectReferenceParamWdg: public StdMeshersGUI_ObjectReferenceParamWdg +// { +// Q_OBJECT +// public: +// BLSURFPluginGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, +// QWidget* parent, +// bool multiSelection=false); +// BLSURFPluginGUI_ObjectReferenceParamWdg( MeshObjectType objType, +// QWidget* parent, +// bool multiSelection=false); +// ~BLSURFPluginGUI_ObjectReferenceParamWdg(); +// +// private: +// void init(); +// +// public slots: +// void activateSelectionOnly(); +// void deactivateSelectionOnly(); +// void setActivationStatus(bool status); +// }; + /*! * \brief Class for creation of BLSURF hypotheses */ @@ -71,52 +174,184 @@ public: BLSURFPluginGUI_HypothesisCreator( const QString& ); virtual ~BLSURFPluginGUI_HypothesisCreator(); - virtual bool checkParams() const; - virtual QString helpPage() const; + virtual bool checkParams(QString& msg) const; + virtual QString helpPage() const; protected: - virtual QFrame* buildFrame (); - virtual void retrieveParams() const; - virtual QString storeParams () const; - - virtual QString caption() const; - virtual QPixmap icon() const; - virtual QString type() const; + virtual QFrame* buildFrame (); + virtual void retrieveParams() const; + virtual QString storeParams () const; + + virtual QString caption() const; + virtual QPixmap icon() const; + virtual QString type() const; protected slots: - void onPhysicalMeshChanged(); - void onGeometricMeshChanged(); - void onAddOption(); - void onDeleteOption(); - void onOptionChosenInPopup( QAction* ); + void onPhysicalMeshChanged(); + void onGeometricMeshChanged(); + void onAddOption(); + void onDeleteOption(); + void onChooseGMFFile(); + void onOptionChosenInPopup( QAction* ); + void onTopologyChanged( int ); + void onMapGeomContentModified(); + void onSmpItemClicked( QTreeWidgetItem *, int ); + void onSmpTabChanged(int); + void onAttractorClicked(int); + void onConstSizeClicked(int); + void onAddMap(); + void onRemoveMap(); + void onModifyMap(); + void onSetSizeMap(QTreeWidgetItem *, int); + + QTreeWidgetItem* addEnforcedFace(std::string theFaceEntry, std::string theFaceName); + + void addEnforcedVertex(QTreeWidgetItem * theFaceItem, double x=0, double y=0, double z=0, + std::string vertexName = "", std::string geomEntry = "", std::string groupName = ""); + + void onAddEnforcedVertices(); + void onRemoveEnforcedVertex(); + void synchronizeCoords(); + void updateEnforcedVertexValues(QTreeWidgetItem* , int ); + void onSelectEnforcedVertex(); +// void deactivateSelection(QWidget*, QWidget*); + void clearEnforcedVertexWidgets(); + void onInternalVerticesClicked(int); private: - bool readParamsFromHypo( BlsurfHypothesisData& ) const; - QString readParamsFromWidgets( BlsurfHypothesisData& ) const; - bool storeParamsToHypo( const BlsurfHypothesisData& ) const; + bool readParamsFromHypo( BlsurfHypothesisData& ) const; + QString readParamsFromWidgets( BlsurfHypothesisData& ) const; + bool storeParamsToHypo( const BlsurfHypothesisData& ) const; + bool sizeMapsValidation(); + bool sizeMapValidationFromRow(int,bool displayError = true); + bool sizeMapValidationFromEntry(QString,bool displayError = true); + GeomSelectionTools* getGeomSelectionTool(); + GEOM::GEOM_Gen_var getGeomEngine(); + //void insertElementType( TopAbs_ShapeEnum ); + void insertElement( GEOM::GEOM_Object_var, bool modify = false ); + void insertAttractor(GEOM::GEOM_Object_var, GEOM::GEOM_Object_var, bool modify = false); + int findRowFromEntry(QString entry); + CORBA::Object_var entryToObject(QString entry); + static LightApp_SelectionMgr* selectionMgr(); private: QWidget* myStdGroup; QLineEdit* myName; QComboBox* myPhysicalMesh; - QLineEdit* myPhySize; - QLineEdit* myPhyMin; - QLineEdit* myPhyMax; + SMESHGUI_SpinBox* myPhySize; + SMESHGUI_SpinBox* myPhyMin; + SMESHGUI_SpinBox* myPhyMax; QComboBox* myGeometricMesh; - QtxDoubleSpinBox* myAngleMeshS; - QtxDoubleSpinBox* myAngleMeshC; - QLineEdit* myGeoMin; - QLineEdit* myGeoMax; - QtxDoubleSpinBox* myGradation; + SMESHGUI_SpinBox* myAngleMeshS; + SMESHGUI_SpinBox* myAngleMeshC; + SMESHGUI_SpinBox* myGeoMin; + SMESHGUI_SpinBox* myGeoMax; + SMESHGUI_SpinBox* myGradation; QCheckBox* myAllowQuadrangles; QCheckBox* myDecimesh; QWidget* myAdvGroup; QComboBox* myTopology; + QGroupBox* myPreCADGroupBox; + QCheckBox* myPreCADMergeEdges; + QCheckBox* myPreCADRemoveNanoEdges; + QCheckBox* myPreCADDiscardInput; + SMESHGUI_SpinBox* myPreCADEpsNano; QSpinBox* myVerbosity; QTableWidget* myOptionTable; + QLineEdit* myGMFFileName; +// QCheckBox* myGMFFileMode; + + // Sizemap widgets + QWidget *mySmpGroup; + QTreeWidget *mySizeMapTable; + QPushButton *addMapButton; + QPushButton *removeMapButton; + QPushButton *modifyMapButton; + QTabWidget *smpTab; + QWidget *myAttractorGroup; + QWidget *mySmpStdGroup; + QCheckBox *myAttractorCheck; + QCheckBox *myConstSizeCheck; + QGroupBox *myDistanceGroup; +// QGroupBox *myParamsGroup; +// QWidget *myParamsGroup; + SMESHGUI_SpinBox *myAttSizeSpin; + SMESHGUI_SpinBox *myAttDistSpin; + SMESHGUI_SpinBox *myAttDistSpin2; + SMESHGUI_SpinBox *mySmpSizeSpin; + QLabel *myAttDistLabel; + QLabel *myAttDistLabel2; + QLabel *myAttSizeLabel; + // Selection widgets for size maps + StdMeshersGUI_ObjectReferenceParamWdg *myGeomSelWdg1; + StdMeshersGUI_ObjectReferenceParamWdg *myGeomSelWdg2; + StdMeshersGUI_ObjectReferenceParamWdg *myAttSelWdg; + StdMeshersGUI_ObjectReferenceParamWdg *myDistSelWdg; + GEOM::GEOM_Object_var mySMapObject; + GEOM::GEOM_Object_var myAttObject; + GEOM::GEOM_Object_var myDistObject; + + + + + QWidget* myEnfGroup; +// TODO FACE AND VERTEX SELECTION + StdMeshersGUI_ObjectReferenceParamWdg *myEnfFaceWdg; + GEOM::GEOM_Object_var myEnfFace; + StdMeshersGUI_ObjectReferenceParamWdg *myEnfVertexWdg; + GEOM::GEOM_Object_var myEnfVertex; + +// DlgBlSurfHyp_Enforced* myEnforcedVertexWidget; + QTreeWidget* myEnforcedTreeWidget; + SMESHGUI_SpinBox* myXCoord; + SMESHGUI_SpinBox* myYCoord; + SMESHGUI_SpinBox* myZCoord; + + QLineEdit* myGroupName; +// QGroupBox* makeGroupsCheck; +// QCheckBox* myGlobalGroupName; + + QPushButton* addVertexButton; + QPushButton* removeVertexButton; + + QCheckBox *myInternalEnforcedVerticesAllFaces; + QLineEdit *myInternalEnforcedVerticesAllFacesGroup; + + // map = entry , size map + QMap mySMPMap; // Map + QMap myATTMap; // Map + QMap myDistMap; // Map + QMap myAttDistMap; // Map + QMap mySMPShapeTypeMap; + GeomSelectionTools* GeomToolSelected; + LightApp_SelectionMgr* aSel; + + BLSURFPlugin::string_array_var myOptions, myPreCADOptions; + + PyObject * main_mod; + PyObject * main_dict; +}; + + +class EnforcedTreeWidgetDelegate : public QItemDelegate +{ + Q_OBJECT + +public: + EnforcedTreeWidgetDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const; - BLSURFPlugin::string_array_var myOptions; + bool vertexExists(QAbstractItemModel *model, const QModelIndex &index, QString value) const; }; #endif // BLSURFPLUGINGUI_HypothesisCreator_H diff --git a/src/GUI/BLSURFPlugin_images.ts b/src/GUI/BLSURFPlugin_images.ts index 1ccb479..62c3f59 100644 --- a/src/GUI/BLSURFPlugin_images.ts +++ b/src/GUI/BLSURFPlugin_images.ts @@ -1,27 +1,12 @@ + - - + @default + + BLSURF_ICON_SELECT + mesh_select_BLSURF.png + ICON_DLG_BLSURF_PARAMETERS mesh_hypo_BLSURF.png diff --git a/src/GUI/BLSURFPlugin_msg_en.ts b/src/GUI/BLSURFPlugin_msg_en.ts index 0e4e862..e533c0a 100644 --- a/src/GUI/BLSURFPlugin_msg_en.ts +++ b/src/GUI/BLSURFPlugin_msg_en.ts @@ -1,138 +1,355 @@ + - - - - @default - - ADD_OPTION - Add option - - - BLSURF_ALLOW_QUADRANGLES - Allow Quadrangles (Test) - - - BLSURF_ANGLE_MESH_C - Angle Mesh C - - - BLSURF_ANGLE_MESH_S - Angle Mesh S - - - BLSURF_CUSTOM_GEOM - Custom - - - BLSURF_CUSTOM_USER - Custom - - - BLSURF_DECIMESH - Patch independent - - - BLSURF_DEFAULT_GEOM - None - - - BLSURF_DEFAULT_USER - None - - - BLSURF_GEOM_MESH - Geometrical Mesh - - - BLSURF_GRADATION - Gradation - - - BLSURF_HGEOMAX - Max Geometrical Size - - - BLSURF_HGEOMIN - Min Geometrical Size - - - BLSURF_HPHYDEF - User Size - - - BLSURF_HPHYMAX - Max Physical Size - - - BLSURF_HPHYMIN - Min Physical Size - - - BLSURF_HYPOTHESIS - BLSURF 2D - - - BLSURF_PHY_MESH - Physical Mesh - - - BLSURF_TITLE - Hypothesis Construction - - - BLSURF_TOPOLOGY - Topology - - - BLSURF_TOPOLOGY_CAD - From CAD - - - BLSURF_TOPOLOGY_PROCESS - Pre-process - - - BLSURF_TOPOLOGY_PROCESS2 - Pre-process++ - - - BLSURF_VERBOSITY - Verbosity level - - - OBLIGATORY_VALUE - (Obligatory value) - - - OPTION_NAME_COLUMN - Option - - - OPTION_VALUE_COLUMN - Value - - - REMOVE_OPTION - Clear option - - + + + @default + + ADD_OPTION + Add option + + + BLSURF_ALLOW_QUADRANGLES + Allow Quadrangles (Test) + + + BLSURF_ANGLE_MESH_C + Angle Mesh C + + + BLSURF_ANGLE_MESH_S + Angle Mesh S + + + BLSURF_CUSTOM_GEOM + Custom + + + BLSURF_CUSTOM_USER + Custom + + + BLSURF_DECIMESH + Patch independent + + + BLSURF_DEFAULT_GEOM + None + + + BLSURF_DEFAULT_USER + None + + + BLSURF_GEOM_MESH + Geometrical Mesh + + + BLSURF_GRADATION + Gradation + + + BLSURF_HGEOMAX + Max Geometrical Size + + + BLSURF_HGEOMIN + Min Geometrical Size + + + BLSURF_HPHYDEF + User Size + + + BLSURF_HPHYMAX + Max Physical Size + + + BLSURF_HPHYMIN + Min Physical Size + + + BLSURF_HYPOTHESIS + BLSURF 2D + + + BLSURF_PHY_MESH + Physical Mesh + + + BLSURF_ADV_ARGS + Advanced + + + BLSURF_TITLE + Hypothesis Construction + + + BLSURF_TOPOLOGY + Topology + + + BLSURF_TOPOLOGY_CAD + From CAD + + + BLSURF_TOPOLOGY_PROCESS + Pre-process + + + BLSURF_TOPOLOGY_PROCESS2 + Pre-process++ + + + BLSURF_TOPOLOGY_PRECAD + PreCAD + + + BLSURF_VERBOSITY + Verbosity level + + + OBLIGATORY_VALUE + (Obligatory value) + + + OPTION_TYPE_COLUMN + Type + + + OPTION_NAME_COLUMN + Option + + + OPTION_VALUE_COLUMN + Value + + + OPTION_MENU_BLSURF + BLSURF + + + OPTION_MENU_PRECAD + PreCAD + + + REMOVE_OPTION + Clear option + + + BLSURF_GMF_FILE + Export GMF + + + BLSURF_GMF_MODE + Binary + + + BLSURF_GMF_FILE_DIALOG + Select GMF file... + + + BLSURF_GMF_FILE_FORMAT + GMF File (*.mesh *.meshb) + + + BLSURF_PRECAD_GROUP + PreCAD options + + + BLSURF_PRECAD_MERGE_EDGES + Merge edges + + + BLSURF_PRECAD_REMOVE_NANO_EDGES + Remove nano edges + + + BLSURF_PRECAD_DISCARD_INPUT + Discard input topology + + + BLSURF_PRECAD_EPS_NANO + Nano edge length + + + BLSURF_SIZE_MAP + Local Size + + + SMP_ENTRY_COLUMN + Entry + + + SMP_NAME_COLUMN + Name + + + SMP_SIZEMAP_COLUMN + Local size + + + BLSURF_SM_SURFACE + On face (or group) + + + BLSURF_SM_EDGE + On edge (or group) + + + BLSURF_SM_POINT + On point (or group) + + + BLSURF_SM_ATTRACTOR + Add Attractor + + + BLSURF_SM_STD_TAB + Simple map + + + BLSURF_SM_ATT_TAB + Advanced + + + BLSURF_SM_PARAMS + Parameters + + + BLSURF_ATTRACTOR + Attractor + + + BLSURF_CONST_SIZE + Constant size near shape + + + BLSURF_ATT_DIST + Influence dist. + + + BLSURF_ATT_RADIUS + Constant over + + + BLSURF_SM_SIZE + Local Size + + + BLSURF_SM_DIST + Distance + + + BLS_SEL_SHAPE + Select a shape + + + BLS_SEL_VERTICES + Select vertices + + + BLS_SEL_FACE + Select a face + + + BLS_SEL_FACES + Select faces + + + BLS_SEL_ATTRACTOR + Select the attractor + + + BLSURF_SM_ADD + Add + + + BLSURF_SM_MODIFY + Modify + + + BLSURF_SM_REMOVE + Remove + + + BLSURF_SM_SURF_VALUE + Size on face(s) + + + BLSURF_SM_EDGE_VALUE + Size on edge(s) + + + BLSURF_SM_POINT_VALUE + Size on point(s) + + + BLSURF_ENF_VER + Enforced vertices + + + BLSURF_ENF_VER_FACE_ENTRY_COLUMN + Face Entry + + + BLSURF_ENF_VER_NAME_COLUMN + Name + + + BLSURF_ENF_VER_X_COLUMN + X + + + BLSURF_ENF_VER_Y_COLUMN + Y + + + BLSURF_ENF_VER_Z_COLUMN + Z + + + BLSURF_ENF_VER_ENTRY_COLUMN + Vertex Entry + + + BLSURF_ENF_VER_GROUP_COLUMN + Group + + + BLSURF_ENF_SELECT_FACE + Select a face + + + BLSURF_ENF_SELECT_VERTEX + Select a vertex + + + BLSURF_ENF_VER_X_LABEL + X: + + + BLSURF_ENF_VER_Y_LABEL + Y: + + + BLSURF_ENF_VER_Z_LABEL + Z: + + + BLSURF_ENF_VER_GROUP_LABEL + Group: + + + BLSURF_ENF_VER_VERTEX + Add + + + BLSURF_ENF_VER_REMOVE + Remove + + + BLSURF_ENF_VER_INTERNAL_VERTICES + Use internal vertices of all faces + + diff --git a/src/GUI/BLSURFPlugin_msg_fr.ts b/src/GUI/BLSURFPlugin_msg_fr.ts new file mode 100755 index 0000000..6a8bde3 --- /dev/null +++ b/src/GUI/BLSURFPlugin_msg_fr.ts @@ -0,0 +1,355 @@ + + + + + @default + + ADD_OPTION + Ajouter l'option + + + BLSURF_ALLOW_QUADRANGLES + Autoriser les quadrangles (Test) + + + BLSURF_ANGLE_MESH_C + Angle de maillage C + + + BLSURF_ANGLE_MESH_S + Angle de maillage S + + + BLSURF_CUSTOM_GEOM + Personnalisé + + + BLSURF_CUSTOM_USER + Personnalisé + + + BLSURF_DECIMESH + S'affranchir des frontières des surfaces + + + BLSURF_DEFAULT_GEOM + Inactif + + + BLSURF_DEFAULT_USER + Inactif + + + BLSURF_GEOM_MESH + Maillage géométrique + + + BLSURF_GRADATION + Taux d'accroissement + + + BLSURF_HGEOMAX + Taille géométrique maximale + + + BLSURF_HGEOMIN + Taille géométrique minimale + + + BLSURF_HPHYDEF + Taille d'utilisateur + + + BLSURF_HPHYMAX + Taille physique maximale + + + BLSURF_HPHYMIN + Taille physique minimale + + + BLSURF_HYPOTHESIS + BLSURF 2D + + + BLSURF_PHY_MESH + Maillage physique + + + BLSURF_ADV_ARGS + Avancé + + + BLSURF_TITLE + Construction d'une hypothèse + + + BLSURF_TOPOLOGY + Topologie + + + BLSURF_TOPOLOGY_CAD + A partir de la CAO + + + BLSURF_TOPOLOGY_PROCESS + Prétraitement + + + BLSURF_TOPOLOGY_PROCESS2 + Prétraitement++ + + + BLSURF_TOPOLOGY_PRECAD + PreCAD + + + BLSURF_VERBOSITY + Niveau de verbosité + + + OBLIGATORY_VALUE + (Valeur obligatoire) + + + OPTION_TYPE_COLUMN + Type + + + OPTION_NAME_COLUMN + Option + + + OPTION_VALUE_COLUMN + Valeur + + + OPTION_MENU_BLSURF + BLSURF + + + OPTION_MENU_PRECAD + PreCAD + + + REMOVE_OPTION + Effacer l'option + + + BLSURF_GMF_FILE + Export GMF + + + BLSURF_GMF_MODE + Binaire + + + BLSURF_GMF_FILE_DIALOG + Choisir un fichier au format GMF... + + + BLSURF_GMF_FILE_FORMAT + Fichier GMF (*.mesh *.meshb) + + + BLSURF_PRECAD_GROUP + Options PreCAD + + + BLSURF_PRECAD_MERGE_EDGES + Fusionner des arêtes + + + BLSURF_PRECAD_REMOVE_NANO_EDGES + Supprimer les petites arêtes + + + BLSURF_PRECAD_DISCARD_INPUT + Ignorer la topologie + + + BLSURF_PRECAD_EPS_NANO + Longueur max des petites arêtes + + + BLSURF_SIZE_MAP + Tailles locales + + + SMP_ENTRY_COLUMN + Entrée + + + SMP_NAME_COLUMN + Nom + + + SMP_SIZEMAP_COLUMN + Taille locale + + + BLSURF_SM_SURFACE + Sur une face (ou groupe) + + + BLSURF_SM_EDGE + Sur une arête (ou groupe) + + + BLSURF_SM_POINT + Sur un point (ou groupe) + + + BLSURF_SM_ATTRACTOR + Ajouter un attracteur + + + BLSURF_SM_STD_TAB + Simple + + + BLSURF_SM_ATT_TAB + Avancé + + + BLSURF_SM_REMOVE + Supprimer + + + BLSURF_SM_ADD + Ajouter + + + BLSURF_SM_MODIFY + Modifier + + + BLSURF_SM_PARAMS + Paramètres + + + BLSURF_ATTRACTOR + Attracteur + + + BLSURF_CONST_SIZE + Taille constante autour d'un objet + + + BLSURF_ATT_DIST + Dist. d'influence : + + + BLSURF_ATT_RADIUS + Constant sur : + + + BLSURF_SM_SIZE + Taille Locale : + + + BLSURF_SM_DIST + Distance + + + BLS_SEL_SHAPE + Sélectionnez un objet + + + BLS_SEL_VERTICES + Sélectionnez une/des point(s) + + + BLS_SEL_FACE + Sélectionnez une face + + + BLS_SEL_FACES + Sélectionnez une/des face(s) + + + BLS_SEL_ATTRACTOR + Sélectionnez l'attracteur + + + BLSURF_SM_SURF_VALUE + Taille sur les/la face(s) + + + BLSURF_SM_EDGE_VALUE + Taille sur les/l'arête(s) + + + BLSURF_SM_POINT_VALUE + Taille sur les/le point(s) + + + BLSURF_ENF_VER + Points de passage + + + BLSURF_ENF_VER_FACE_ENTRY_COLUMN + ID de face + + + BLSURF_ENF_VER_NAME_COLUMN + Nom + + + BLSURF_ENF_VER_X_COLUMN + X + + + BLSURF_ENF_VER_Y_COLUMN + Y + + + BLSURF_ENF_VER_Z_COLUMN + Z + + + BLSURF_ENF_VER_ENTRY_COLUMN + ID de point + + + BLSURF_ENF_VER_GROUP_COLUMN + Groupe + + + BLSURF_ENF_SELECT_FACE + Sélectionner une face + + + BLSURF_ENF_SELECT_VERTEX + Sélectionner un point + + + BLSURF_ENF_VER_X_LABEL + X: + + + BLSURF_ENF_VER_Y_LABEL + Y: + + + BLSURF_ENF_VER_Z_LABEL + Z: + + + BLSURF_ENF_VER_GROUP_LABEL + Groupe: + + + BLSURF_ENF_VER_VERTEX + Ajouter + + + BLSURF_ENF_VER_REMOVE + Supprimer + + + BLSURF_ENF_VER_INTERNAL_VERTICES + Utiliser les points internes de toutes les faces + + + diff --git a/src/GUI/Makefile.am b/src/GUI/Makefile.am index 20136b4..8f0b6a0 100644 --- a/src/GUI/Makefile.am +++ b/src/GUI/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -24,14 +25,14 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files -salomeinclude_HEADERS = +salomeinclude_HEADERS = \ + BLSURFPluginGUI_HypothesisCreator.h # Libraries targets lib_LTLIBRARIES = libBLSURFPluginGUI.la -dist_libBLSURFPluginGUI_la_SOURCES = \ - BLSURFPluginGUI.cxx \ - BLSURFPluginGUI_HypothesisCreator.h \ +dist_libBLSURFPluginGUI_la_SOURCES = \ + BLSURFPluginGUI.cxx \ BLSURFPluginGUI_HypothesisCreator.cxx MOC_FILES = \ @@ -51,20 +52,24 @@ libBLSURFPluginGUI_la_CPPFLAGS = \ $(GEOM_CXXFLAGS) \ $(MED_CXXFLAGS) \ $(SMESH_CXXFLAGS) \ + $(VTK_INCLUDES) \ $(BOOST_CPPFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ $(BLSURF_INCLUDES) \ -I$(srcdir)/../BLSURFPlugin \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix + -I$(top_builddir)/idl libBLSURFPluginGUI_la_LDFLAGS = \ + $(QT_LIBS) \ ../BLSURFPlugin/libBLSURFEngine.la \ - ${SMESH_LDFLAGS} -lSMESH \ + $(GUI_LDFLAGS) -lqtx -lSalomeApp -lsuit -lSalomeObject -lLightApp \ + $(GEOM_LDFLAGS) -lGEOM \ + ${SMESH_LDFLAGS} -lSMESH -lGeomSelectionTools -lStdMeshersGUI -lSMESHFiltersSelection \ $(CAS_KERNEL) $(BLSURF_LIBS) # resources files nodist_salomeres_DATA = \ BLSURFPlugin_images.qm \ - BLSURFPlugin_msg_en.qm + BLSURFPlugin_msg_en.qm \ + BLSURFPlugin_msg_fr.qm diff --git a/src/Makefile.am b/src/Makefile.am index 5768f50..55f2b5c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,21 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D +# 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 free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# 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.am # Author : Vadim SANDLER, Open CASCADE S.A.S (vadim.sandler@opencascade.com) @@ -29,4 +30,4 @@ if BLSURFPLUGIN_ENABLE_GUI SUBDIRS += GUI endif -DIST_SUBDIRS = BLSURFPlugin GUI \ No newline at end of file +DIST_SUBDIRS = BLSURFPlugin GUI -- 2.30.2